Bug 793125 - Crash due to popup menus left attached too long
[evolution.git] / src / calendar / gui / calendar-config.c
blobb79784bcae97d8ca6287460f1e2047616d6e0e6a
1 /*
2 * This program is free software; you can redistribute it and/or modify it
3 * under the terms of the GNU Lesser General Public License as published by
4 * the Free Software Foundation.
6 * This program is distributed in the hope that it will be useful, but
7 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
9 * for more details.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, see <http://www.gnu.org/licenses/>.
15 * Authors:
16 * Damon Chaplin <damon@ximian.com>
17 * Rodrigo Moya <rodrigo@ximian.com>
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
24 * calendar-config.c - functions to load/save/get/set user settings.
27 #include "evolution-config.h"
29 #include <time.h>
30 #include <string.h>
31 #include <gio/gio.h>
33 #include <shell/e-shell.h>
35 #include "calendar-config-keys.h"
36 #include "calendar-config.h"
38 static GSettings *config = NULL;
40 static void
41 do_cleanup (void)
43 g_object_unref (config);
44 config = NULL;
47 static void
48 calendar_config_init (void)
50 if (config)
51 return;
53 config = e_util_ref_settings ("org.gnome.evolution.calendar");
55 /* will be freed together with EShell */
56 g_object_set_data_full (
57 G_OBJECT (e_shell_get_default ()),
58 "calendar-config-config-cleanup", (gpointer) "1",
59 (GDestroyNotify) do_cleanup);
62 void
63 calendar_config_remove_notification (CalendarConfigChangedFunc func,
64 gpointer data)
66 calendar_config_init ();
68 g_signal_handlers_disconnect_by_func (config, G_CALLBACK (func), data);
71 /* Returns TRUE if the locale has 'am' and 'pm' strings defined, in which
72 * case the user can choose between 12 and 24-hour time formats. */
73 gboolean
74 calendar_config_locale_supports_12_hour_format (void)
76 gchar s[16];
77 time_t t = 0;
79 calendar_config_init ();
81 e_utf8_strftime (s, sizeof s, "%p", gmtime (&t));
82 return s[0] != '\0';
86 * Calendar Settings.
89 static gchar *
90 calendar_config_get_timezone_stored (void)
92 calendar_config_init ();
94 return g_settings_get_string (config, "timezone");
97 static gchar *
98 calendar_config_get_timezone (void)
100 GSettings *settings;
101 gboolean use_system_timezone;
103 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
105 use_system_timezone =
106 g_settings_get_boolean (settings, "use-system-timezone");
108 g_object_unref (settings);
110 if (use_system_timezone)
111 return e_cal_util_get_system_timezone_location ();
113 return calendar_config_get_timezone_stored ();
116 icaltimezone *
117 calendar_config_get_icaltimezone (void)
119 gchar *location;
120 icaltimezone *zone = NULL;
122 calendar_config_init ();
124 location = calendar_config_get_timezone ();
125 if (location) {
126 zone = icaltimezone_get_builtin_timezone (location);
128 g_free (location);
130 return zone;
133 /* Whether we use 24-hour format or 12-hour format (AM/PM). */
134 gboolean
135 calendar_config_get_24_hour_format (void)
137 calendar_config_init ();
139 /* If the locale defines 'am' and 'pm' strings then the user has the
140 * choice of 12-hour or 24-hour time format, with 12-hour as the
141 * default. If the locale doesn't have 'am' and 'pm' strings we have
142 * to use 24-hour format, or strftime ()/strptime () won't work. */
143 if (calendar_config_locale_supports_12_hour_format ())
144 return g_settings_get_boolean (config, "use-24hour-format");
146 return TRUE;
149 /* Scroll in a month view by a week, not by a month */
150 gboolean
151 calendar_config_get_month_scroll_by_week (void)
153 calendar_config_init ();
155 return g_settings_get_boolean (config, "month-scroll-by-week");
158 void
159 calendar_config_add_notification_month_scroll_by_week (CalendarConfigChangedFunc func,
160 gpointer data)
162 calendar_config_init ();
164 g_signal_connect (
165 config, "changed::month-scroll-by-week",
166 G_CALLBACK (func), data);
169 /***************************************/
171 /* Settings to hide completed tasks. */
172 gboolean
173 calendar_config_get_hide_completed_tasks (void)
175 calendar_config_init ();
177 return g_settings_get_boolean (config, "hide-completed-tasks");
180 static EDurationType
181 calendar_config_get_hide_completed_tasks_units (void)
183 gchar *units;
184 EDurationType cu;
186 calendar_config_init ();
188 units = g_settings_get_string (config, "hide-completed-tasks-units");
190 if (units && !strcmp (units, "minutes"))
191 cu = E_DURATION_MINUTES;
192 else if (units && !strcmp (units, "hours"))
193 cu = E_DURATION_HOURS;
194 else
195 cu = E_DURATION_DAYS;
197 g_free (units);
199 return cu;
203 * calendar_config_get_hide_completed_tasks_sexp:
205 * @get_completed: Whether to form subexpression that
206 * gets completed or not completed tasks.
207 * Returns the subexpression to use to filter out completed tasks according
208 * to the config settings. The returned sexp should be freed.
210 gchar *
211 calendar_config_get_hide_completed_tasks_sexp (gboolean get_completed)
213 gchar *sexp = NULL;
215 if (calendar_config_get_hide_completed_tasks ()) {
216 EDurationType units;
217 gint value;
219 units = calendar_config_get_hide_completed_tasks_units ();
220 value = g_settings_get_int (config, "hide-completed-tasks-value");
222 if (value == 0) {
223 /* If the value is 0, we want to hide completed tasks
224 * immediately, so we filter out all complete/incomplete tasks.*/
225 if (!get_completed)
226 sexp = g_strdup ("(not is-completed?)");
227 else
228 sexp = g_strdup ("(is-completed?)");
229 } else {
230 gchar *isodate;
231 icaltimezone *zone;
232 struct icaltimetype tt;
233 time_t t;
235 /* Get the current time, and subtract the appropriate
236 * number of days/hours/minutes. */
237 zone = calendar_config_get_icaltimezone ();
238 tt = icaltime_current_time_with_zone (zone);
240 switch (units) {
241 case E_DURATION_DAYS:
242 icaltime_adjust (&tt, -value, 0, 0, 0);
243 break;
244 case E_DURATION_HOURS:
245 icaltime_adjust (&tt, 0, -value, 0, 0);
246 break;
247 case E_DURATION_MINUTES:
248 icaltime_adjust (&tt, 0, 0, -value, 0);
249 break;
250 default:
251 g_return_val_if_reached (NULL);
254 t = icaltime_as_timet_with_zone (tt, zone);
256 /* Convert the time to an ISO date string, and build
257 * the query sub-expression. */
258 isodate = isodate_from_time_t (t);
259 if (!get_completed)
260 sexp = g_strdup_printf (
261 "(not (completed-before? "
262 "(make-time \"%s\")))", isodate);
263 else
264 sexp = g_strdup_printf (
265 "(completed-before? "
266 "(make-time \"%s\"))", isodate);
267 g_free (isodate);
271 return sexp;
274 void
275 calendar_config_set_dir_path (const gchar *path)
277 calendar_config_init ();
279 g_settings_set_string (config, "audio-dir", path);
282 gchar *
283 calendar_config_get_dir_path (void)
285 gchar *path;
287 calendar_config_init ();
289 path = g_settings_get_string (config, "audio-dir");
291 return path;
294 /* contains list of strings, locations, recently used as the second timezone
295 * in a day view. Free with calendar_config_free_day_second_zones. */
296 GSList *
297 calendar_config_get_day_second_zones (void)
299 GSList *res = NULL;
300 gchar **strv;
301 gint i;
303 calendar_config_init ();
305 strv = g_settings_get_strv (config, "day-second-zones");
306 for (i = 0; i < g_strv_length (strv); i++) {
307 if (strv[i] != NULL)
308 res = g_slist_append (res, g_strdup (strv[i]));
311 g_strfreev (strv);
313 return res;
316 /* frees list from calendar_config_get_day_second_zones */
317 void
318 calendar_config_free_day_second_zones (GSList *zones)
320 if (zones) {
321 g_slist_foreach (zones, (GFunc) g_free, NULL);
322 g_slist_free (zones);
326 /* keeps max 'day_second_zones_max' zones, if 'location'
327 * is already in a list, then it'll became first there */
328 void
329 calendar_config_set_day_second_zone (const gchar *location)
331 calendar_config_init ();
333 if (location && *location) {
334 GSList *lst, *l;
335 gint max_zones;
336 GPtrArray *array;
337 gint i;
339 /* configurable max number of timezones to remember */
340 max_zones = g_settings_get_int (config, "day-second-zones-max");
342 if (max_zones <= 0)
343 max_zones = 5;
345 lst = calendar_config_get_day_second_zones ();
346 for (l = lst; l; l = l->next) {
347 if (l->data && g_str_equal (l->data, location)) {
348 if (l != lst) {
349 /* isn't first in the list */
350 gchar *val = l->data;
352 lst = g_slist_remove (lst, val);
353 lst = g_slist_prepend (lst, val);
355 break;
359 if (!l) {
360 /* not in the list yet */
361 lst = g_slist_prepend (lst, g_strdup (location));
364 array = g_ptr_array_new ();
365 for (i = 0, l = lst; i < max_zones && l != NULL; i++, l = l->next)
366 g_ptr_array_add (array, l->data);
367 g_ptr_array_add (array, NULL);
369 g_settings_set_strv (
370 config, "day-second-zones",
371 (const gchar * const *) array->pdata);
373 calendar_config_free_day_second_zones (lst);
374 g_ptr_array_free (array, FALSE);
377 g_settings_set_string (
378 config, "day-second-zone",
379 (location != NULL) ? location : "");
382 /* location of the second time zone user has selected. Free with g_free. */
383 gchar *
384 calendar_config_get_day_second_zone (void)
386 calendar_config_init ();
388 return g_settings_get_string (config, "day-second-zone");
391 void
392 calendar_config_select_day_second_zone (void)
394 icaltimezone *zone = NULL;
395 ETimezoneDialog *tzdlg;
396 GtkWidget *dialog;
397 gchar *second_location;
399 second_location = calendar_config_get_day_second_zone ();
400 if (second_location && *second_location)
401 zone = icaltimezone_get_builtin_timezone (second_location);
402 g_free (second_location);
404 if (!zone)
405 zone = calendar_config_get_icaltimezone ();
407 tzdlg = e_timezone_dialog_new ();
408 e_timezone_dialog_set_timezone (tzdlg, zone);
410 dialog = e_timezone_dialog_get_toplevel (tzdlg);
412 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
413 const gchar *location = NULL;
415 zone = e_timezone_dialog_get_timezone (tzdlg);
416 if (zone == icaltimezone_get_utc_timezone ()) {
417 location = "UTC";
418 } else if (zone) {
419 location = icaltimezone_get_location (zone);
422 calendar_config_set_day_second_zone (location);
425 g_object_unref (tzdlg);
428 void
429 calendar_config_add_notification_day_second_zone (CalendarConfigChangedFunc func,
430 gpointer data)
432 calendar_config_init ();
434 g_signal_connect (
435 config, "changed::day-second-zone",
436 G_CALLBACK (func), data);
439 gboolean
440 calendar_config_get_prefer_meeting (void)
442 GSettings *settings;
443 gchar *prefer_new_item;
444 gboolean prefer_meeting;
446 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
448 prefer_new_item = g_settings_get_string (settings, "prefer-new-item");
449 prefer_meeting = g_strcmp0 (prefer_new_item, "event-meeting-new") == 0;
450 g_free (prefer_new_item);
452 g_object_unref (settings);
454 return prefer_meeting;
457 GDateWeekday
458 calendar_config_get_week_start_day (void)
460 GSettings *settings;
461 GDateWeekday res;
463 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
465 res = g_settings_get_enum (settings, "week-start-day-name");
467 g_object_unref (settings);
469 return res;
472 gint
473 calendar_config_get_default_reminder_interval (void)
475 GSettings *settings;
476 gint res;
478 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
480 res = g_settings_get_int (settings, "default-reminder-interval");
482 g_object_unref (settings);
484 return res;
487 EDurationType
488 calendar_config_get_default_reminder_units (void)
490 GSettings *settings;
491 EDurationType res;
493 settings = e_util_ref_settings ("org.gnome.evolution.calendar");
495 res = g_settings_get_enum (settings, "default-reminder-units");
497 g_object_unref (settings);
499 return res;