No issues found
1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with the program; if not, see <http://www.gnu.org/licenses/>
14 *
15 *
16 * Authors:
17 * Damon Chaplin <damon@ximian.com>
18 * Rodrigo Moya <rodrigo@ximian.com>
19 *
20 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
21 *
22 */
23
24 /*
25 * calendar-config.c - functions to load/save/get/set user settings.
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include <time.h>
33 #include <string.h>
34 #include <gio/gio.h>
35 #include <e-util/e-util.h>
36 #include <widgets/e-timezone-dialog/e-timezone-dialog.h>
37 #include <shell/e-shell.h>
38
39 #include "calendar-config-keys.h"
40 #include "calendar-config.h"
41
42 static GSettings *config = NULL;
43
44 static void
45 do_cleanup (void)
46 {
47 g_object_unref (config);
48 config = NULL;
49 }
50
51 static void
52 calendar_config_init (void)
53 {
54 if (config)
55 return;
56
57 config = g_settings_new ("org.gnome.evolution.calendar");
58 g_atexit ((GVoidFunc) do_cleanup);
59 }
60
61 void
62 calendar_config_remove_notification (CalendarConfigChangedFunc func,
63 gpointer data)
64 {
65 calendar_config_init ();
66
67 g_signal_handlers_disconnect_by_func (config, G_CALLBACK (func), data);
68 }
69
70 /* Returns TRUE if the locale has 'am' and 'pm' strings defined, in which
71 * case the user can choose between 12 and 24-hour time formats. */
72 gboolean
73 calendar_config_locale_supports_12_hour_format (void)
74 {
75 gchar s[16];
76 time_t t = 0;
77
78 calendar_config_init ();
79
80 e_utf8_strftime (s, sizeof s, "%p", gmtime (&t));
81 return s[0] != '\0';
82 }
83
84 /*
85 * Calendar Settings.
86 */
87
88 static gchar *
89 calendar_config_get_timezone_stored (void)
90 {
91 calendar_config_init ();
92
93 return g_settings_get_string (config, "timezone");
94 }
95
96 static gchar *
97 calendar_config_get_timezone (void)
98 {
99 EShell *shell;
100 EShellSettings *shell_settings;
101 gboolean use_system_timezone;
102
103 shell = e_shell_get_default ();
104 shell_settings = e_shell_get_shell_settings (shell);
105
106 use_system_timezone = e_shell_settings_get_boolean (
107 shell_settings, "cal-use-system-timezone");
108
109 if (use_system_timezone)
110 return e_cal_util_get_system_timezone_location ();
111
112 return calendar_config_get_timezone_stored ();
113 }
114
115 icaltimezone *
116 calendar_config_get_icaltimezone (void)
117 {
118 gchar *location;
119 icaltimezone *zone = NULL;
120
121 calendar_config_init ();
122
123 location = calendar_config_get_timezone ();
124 if (location) {
125 zone = icaltimezone_get_builtin_timezone (location);
126
127 g_free (location);
128 }
129 return zone;
130 }
131
132 /* Whether we use 24-hour format or 12-hour format (AM/PM). */
133 gboolean
134 calendar_config_get_24_hour_format (void)
135 {
136 calendar_config_init ();
137
138 /* If the locale defines 'am' and 'pm' strings then the user has the
139 * choice of 12-hour or 24-hour time format, with 12-hour as the
140 * default. If the locale doesn't have 'am' and 'pm' strings we have
141 * to use 24-hour format, or strftime ()/strptime () won't work. */
142 if (calendar_config_locale_supports_12_hour_format ())
143 return g_settings_get_boolean (config, "use-24hour-format");
144
145 return TRUE;
146 }
147
148 /* Scroll in a month view by a week, not by a month */
149 gboolean
150 calendar_config_get_month_scroll_by_week (void)
151 {
152 calendar_config_init ();
153
154 return g_settings_get_boolean (config, "month-scroll-by-week");
155 }
156
157 void
158 calendar_config_add_notification_month_scroll_by_week (CalendarConfigChangedFunc func,
159 gpointer data)
160 {
161 calendar_config_init ();
162
163 g_signal_connect (
164 config, "changed::month-scroll-by-week",
165 G_CALLBACK (func), data);
166 }
167
168 /***************************************/
169
170 /* The working days of the week, a bit-wise combination of flags. */
171 CalWeekdays
172 calendar_config_get_working_days (void)
173 {
174 calendar_config_init ();
175
176 return g_settings_get_int (config, "working-days");
177 }
178
179 /* Settings to hide completed tasks. */
180 gboolean
181 calendar_config_get_hide_completed_tasks (void)
182 {
183 calendar_config_init ();
184
185 return g_settings_get_boolean (config, "hide-completed-tasks");
186 }
187
188 static EDurationType
189 calendar_config_get_hide_completed_tasks_units (void)
190 {
191 gchar *units;
192 EDurationType cu;
193
194 calendar_config_init ();
195
196 units = g_settings_get_string (config, "hide-completed-tasks-units");
197
198 if (units && !strcmp (units, "minutes"))
199 cu = E_DURATION_MINUTES;
200 else if (units && !strcmp (units, "hours"))
201 cu = E_DURATION_HOURS;
202 else
203 cu = E_DURATION_DAYS;
204
205 g_free (units);
206
207 return cu;
208 }
209
210 /**
211 * calendar_config_get_hide_completed_tasks_sexp:
212 *
213 * @get_completed: Whether to form subexpression that
214 * gets completed or not completed tasks.
215 * Returns the subexpression to use to filter out completed tasks according
216 * to the config settings. The returned sexp should be freed.
217 **/
218 gchar *
219 calendar_config_get_hide_completed_tasks_sexp (gboolean get_completed)
220 {
221 gchar *sexp = NULL;
222
223 if (calendar_config_get_hide_completed_tasks ()) {
224 EDurationType units;
225 gint value;
226
227 units = calendar_config_get_hide_completed_tasks_units ();
228 value = g_settings_get_int (config, "hide-completed-tasks-value");
229
230 if (value == 0) {
231 /* If the value is 0, we want to hide completed tasks
232 * immediately, so we filter out all complete/incomplete tasks.*/
233 if (!get_completed)
234 sexp = g_strdup ("(not is-completed?)");
235 else
236 sexp = g_strdup ("(is-completed?)");
237 } else {
238 gchar *isodate;
239 icaltimezone *zone;
240 struct icaltimetype tt;
241 time_t t;
242
243 /* Get the current time, and subtract the appropriate
244 * number of days/hours/minutes. */
245 zone = calendar_config_get_icaltimezone ();
246 tt = icaltime_current_time_with_zone (zone);
247
248 switch (units) {
249 case E_DURATION_DAYS:
250 icaltime_adjust (&tt, -value, 0, 0, 0);
251 break;
252 case E_DURATION_HOURS:
253 icaltime_adjust (&tt, 0, -value, 0, 0);
254 break;
255 case E_DURATION_MINUTES:
256 icaltime_adjust (&tt, 0, 0, -value, 0);
257 break;
258 default:
259 g_return_val_if_reached (NULL);
260 }
261
262 t = icaltime_as_timet_with_zone (tt, zone);
263
264 /* Convert the time to an ISO date string, and build
265 * the query sub-expression. */
266 isodate = isodate_from_time_t (t);
267 if (!get_completed)
268 sexp = g_strdup_printf (
269 "(not (completed-before? "
270 "(make-time \"%s\")))", isodate);
271 else
272 sexp = g_strdup_printf (
273 "(completed-before? "
274 "(make-time \"%s\"))", isodate);
275 g_free (isodate);
276 }
277 }
278
279 return sexp;
280 }
281
282 void
283 calendar_config_set_dir_path (const gchar *path)
284 {
285 calendar_config_init ();
286
287 g_settings_set_string (config, "audio-dir", path);
288 }
289
290 gchar *
291 calendar_config_get_dir_path (void)
292 {
293 gchar *path;
294
295 calendar_config_init ();
296
297 path = g_settings_get_string (config, "audio-dir");
298
299 return path;
300 }
301
302 /* contains list of strings, locations, recently used as the second timezone
303 * in a day view. Free with calendar_config_free_day_second_zones. */
304 GSList *
305 calendar_config_get_day_second_zones (void)
306 {
307 GSList *res = NULL;
308 gchar **strv;
309 gint i;
310
311 calendar_config_init ();
312
313 strv = g_settings_get_strv (config, "day-second-zones");
314 for (i = 0; i < g_strv_length (strv); i++) {
315 if (strv[i] != NULL)
316 res = g_slist_append (res, g_strdup (strv[i]));
317 }
318
319 g_strfreev (strv);
320
321 return res;
322 }
323
324 /* frees list from calendar_config_get_day_second_zones */
325 void
326 calendar_config_free_day_second_zones (GSList *zones)
327 {
328 if (zones) {
329 g_slist_foreach (zones, (GFunc) g_free, NULL);
330 g_slist_free (zones);
331 }
332 }
333
334 /* keeps max 'day_second_zones_max' zones, if 'location'
335 * is already in a list, then it'll became first there */
336 void
337 calendar_config_set_day_second_zone (const gchar *location)
338 {
339 calendar_config_init ();
340
341 if (location && *location) {
342 GSList *lst, *l;
343 gint max_zones;
344 GPtrArray *array;
345 gint i;
346
347 /* configurable max number of timezones to remember */
348 max_zones = g_settings_get_int (config, "day-second-zones-max");
349
350 if (max_zones <= 0)
351 max_zones = 5;
352
353 lst = calendar_config_get_day_second_zones ();
354 for (l = lst; l; l = l->next) {
355 if (l->data && g_str_equal (l->data, location)) {
356 if (l != lst) {
357 /* isn't first in the list */
358 gchar *val = l->data;
359
360 lst = g_slist_remove (lst, val);
361 lst = g_slist_prepend (lst, val);
362 }
363 break;
364 }
365 }
366
367 if (!l) {
368 /* not in the list yet */
369 lst = g_slist_prepend (lst, g_strdup (location));
370 }
371
372 array = g_ptr_array_new ();
373 for (i = 0, l = lst; i < max_zones && l != NULL; i++, l = l->next)
374 g_ptr_array_add (array, l->data);
375 g_ptr_array_add (array, NULL);
376
377 g_settings_set_strv (
378 config, "day-second-zones",
379 (const gchar * const *) array->pdata);
380
381 calendar_config_free_day_second_zones (lst);
382 g_ptr_array_free (array, FALSE);
383 }
384
385 g_settings_set_string (
386 config, "day-second-zone",
387 (location != NULL) ? location : "");
388 }
389
390 /* location of the second time zone user has selected. Free with g_free. */
391 gchar *
392 calendar_config_get_day_second_zone (void)
393 {
394 calendar_config_init ();
395
396 return g_settings_get_string (config, "day-second-zone");
397 }
398
399 void
400 calendar_config_select_day_second_zone (void)
401 {
402 icaltimezone *zone = NULL;
403 ETimezoneDialog *tzdlg;
404 GtkWidget *dialog;
405 gchar *second_location;
406
407 second_location = calendar_config_get_day_second_zone ();
408 if (second_location && *second_location)
409 zone = icaltimezone_get_builtin_timezone (second_location);
410 g_free (second_location);
411
412 if (!zone)
413 zone = calendar_config_get_icaltimezone ();
414
415 tzdlg = e_timezone_dialog_new ();
416 e_timezone_dialog_set_timezone (tzdlg, zone);
417
418 dialog = e_timezone_dialog_get_toplevel (tzdlg);
419
420 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
421 const gchar *location = NULL;
422
423 zone = e_timezone_dialog_get_timezone (tzdlg);
424 if (zone == icaltimezone_get_utc_timezone ()) {
425 location = "UTC";
426 } else if (zone) {
427 location = icaltimezone_get_location (zone);
428 }
429
430 calendar_config_set_day_second_zone (location);
431 }
432
433 g_object_unref (tzdlg);
434 }
435
436 void
437 calendar_config_add_notification_day_second_zone (CalendarConfigChangedFunc func,
438 gpointer data)
439 {
440 calendar_config_init ();
441
442 g_signal_connect (
443 config, "changed::day-second-zone",
444 G_CALLBACK (func), data);
445 }
446
447 gboolean
448 calendar_config_get_prefer_meeting (void)
449 {
450 EShell *shell;
451 EShellSettings *shell_settings;
452 gchar *prefer_new_item;
453 gboolean prefer_meeting;
454
455 shell = e_shell_get_default ();
456 shell_settings = e_shell_get_shell_settings (shell);
457
458 prefer_new_item = e_shell_settings_get_string (
459 shell_settings, "cal-prefer-new-item");
460 prefer_meeting = g_strcmp0 (prefer_new_item, "event-meeting-new") == 0;
461
462 g_free (prefer_new_item);
463
464 return prefer_meeting;
465 }