No issues found
1 /*
2 * Copyright (C) 2010 Nokia <ivan.frade@nokia.com>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library 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 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include "config.h"
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <locale.h>
25
26 #include <glib.h>
27 #include <glib/gi18n.h>
28 #include <glib/gstdio.h>
29
30 #include <libtracker-common/tracker-locale.h>
31 #include <libtracker-data/tracker-data-manager.h>
32
33 #include "tracker-store.h"
34 #include "tracker-events.h"
35 #include "tracker-locale-change.h"
36
37 typedef struct {
38 gpointer resources;
39 } TrackerLocaleChangeContext;
40
41 /* Private */
42 static gpointer locale_notification_id;
43 static gboolean locale_change_notified;
44
45 static void
46 locale_change_process_cb (GObject *source,
47 GAsyncResult *res,
48 gpointer user_data)
49 {
50 TrackerStatus *notifier;
51 TrackerBusyCallback busy_callback;
52 gpointer busy_user_data;
53 GDestroyNotify busy_destroy_notify;
54 TrackerLocaleChangeContext *ctxt = user_data;
55 GError *error = NULL;
56
57 notifier = TRACKER_STATUS (tracker_dbus_get_object (TRACKER_TYPE_STATUS));
58
59 busy_callback = tracker_status_get_callback (notifier,
60 &busy_user_data,
61 &busy_destroy_notify);
62
63 g_message ("Processing locale change...");
64 /* Reload! This will regenerate indexes with the new locale */
65 tracker_data_manager_reload (busy_callback,
66 busy_user_data,
67 "Changing locale",
68 &error);
69
70 if (error) {
71 g_critical ("Error reloading database for locale change: %s",
72 error->message);
73 g_error_free (error);
74 }
75
76 busy_destroy_notify (busy_user_data);
77
78 if (ctxt->resources) {
79 tracker_events_init ();
80 tracker_resources_enable_signals (ctxt->resources);
81 g_object_unref (ctxt->resources);
82 }
83 g_free (ctxt);
84
85 tracker_store_resume ();
86
87 locale_change_notified = FALSE;
88 }
89
90 static gboolean
91 locale_change_process_idle_cb (gpointer data)
92 {
93 TrackerLocaleChangeContext *ctxt;
94
95 ctxt = g_new0 (TrackerLocaleChangeContext, 1);
96 ctxt->resources = tracker_dbus_get_object (TRACKER_TYPE_RESOURCES);
97 if (ctxt->resources) {
98 g_object_ref (ctxt->resources);
99 tracker_resources_disable_signals (ctxt->resources);
100 tracker_events_shutdown ();
101 }
102
103 /* Note: Right now, the passed callback may be called instantly and not
104 * in an idle. */
105 g_message ("Setting tracker-store as inactive...");
106 tracker_store_pause (locale_change_process_cb, ctxt);
107
108 return FALSE;
109 }
110
111 static void
112 locale_notify_cb (TrackerLocaleID id,
113 gpointer user_data)
114 {
115 if (locale_change_notified) {
116 g_message ("Locale change was already notified, not doing it again");
117 } else {
118 locale_change_notified = TRUE;
119 /* Set an idle callback to process the locale change.
120 * NOTE: We cannot process it right here because we will be
121 * closing and opening new connections to the DB while doing it,
122 * and the DB connections are also part of the subscriber list
123 * for locale changes, so we may end up waiting to acquire an
124 * already locked mutex.
125 */
126 g_message ("Locale change notified, preparing to rebuild indexes...");
127 g_idle_add (locale_change_process_idle_cb, NULL);
128 }
129 }
130
131 void
132 tracker_locale_change_initialize_subscription (void)
133 {
134 gchar *collation_locale;
135
136 collation_locale = tracker_locale_get (TRACKER_LOCALE_COLLATE);
137
138 g_debug ("Initial collation locale is '%s', subscribing for updates...",
139 collation_locale);
140
141 locale_notification_id = tracker_locale_notify_add (TRACKER_LOCALE_COLLATE,
142 locale_notify_cb,
143 NULL,
144 NULL);
145 g_free (collation_locale);
146 }
147
148 void
149 tracker_locale_change_shutdown_subscription (void)
150 {
151 tracker_locale_notify_remove (locale_notification_id);
152 }