summaryrefslogtreecommitdiff
path: root/src/tracker-store/tracker-locale-change.c
blob: 46f1477d401687cbb16397b2c4dd0f28985f46f8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * Copyright (C) 2010 Nokia <ivan.frade@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301, USA.
 */

#include "config.h"

#include <stdlib.h>
#include <string.h>
#include <locale.h>

#include <glib.h>
#include <glib/gi18n.h>
#include <glib/gstdio.h>

#include <libtracker-common/tracker-locale.h>
#include <libtracker-data/tracker-data-manager.h>

#include "tracker-store.h"
#include "tracker-events.h"
#include "tracker-locale-change.h"

typedef struct {
	gpointer resources;
} TrackerLocaleChangeContext;

/* Private */
static gpointer locale_notification_id;
static gboolean locale_change_notified;

static void
locale_change_process_cb (GObject      *source,
                          GAsyncResult *res,
                          gpointer      user_data)
{
	TrackerStatus *notifier;
	TrackerBusyCallback busy_callback;
	gpointer busy_user_data;
	GDestroyNotify busy_destroy_notify;
	TrackerLocaleChangeContext *ctxt = user_data;
	GError *error = NULL;

	notifier = TRACKER_STATUS (tracker_dbus_get_object (TRACKER_TYPE_STATUS));

	busy_callback = tracker_status_get_callback (notifier,
	                                             &busy_user_data,
	                                             &busy_destroy_notify);

	g_message ("Processing locale change...");
	/* Reload! This will regenerate indexes with the new locale */
	tracker_data_manager_reload (busy_callback,
	                             busy_user_data,
	                             "Changing locale",
	                             &error);

	if (error) {
		g_critical ("Error reloading database for locale change: %s",
		            error->message);
		g_error_free (error);
	}

	busy_destroy_notify (busy_user_data);

	if (ctxt->resources) {
		tracker_events_init ();
		tracker_resources_enable_signals (ctxt->resources);
		g_object_unref (ctxt->resources);
	}
	g_free (ctxt);

	tracker_store_resume ();

	locale_change_notified = FALSE;
}

static gboolean
locale_change_process_idle_cb (gpointer data)
{
	TrackerLocaleChangeContext *ctxt;

	ctxt = g_new0 (TrackerLocaleChangeContext, 1);
	ctxt->resources = tracker_dbus_get_object (TRACKER_TYPE_RESOURCES);
	if (ctxt->resources) {
		g_object_ref (ctxt->resources);
		tracker_resources_disable_signals (ctxt->resources);
		tracker_events_shutdown ();
	}

	/* Note: Right now, the passed callback may be called instantly and not
	 * in an idle. */
	g_message ("Setting tracker-store as inactive...");
	tracker_store_pause (locale_change_process_cb, ctxt);

	return FALSE;
}

static void
locale_notify_cb (TrackerLocaleID id,
                  gpointer        user_data)
{
	if (locale_change_notified) {
		g_message ("Locale change was already notified, not doing it again");
	} else {
		locale_change_notified = TRUE;
		/* Set an idle callback to process the locale change.
		 * NOTE: We cannot process it right here because we will be
		 * closing and opening new connections to the DB while doing it,
		 * and the DB connections are also part of the subscriber list
		 * for locale changes, so we may end up waiting to acquire an
		 * already locked mutex.
		 */
		g_message ("Locale change notified, preparing to rebuild indexes...");
		g_idle_add (locale_change_process_idle_cb, NULL);
	}
}

void
tracker_locale_change_initialize_subscription (void)
{
	gchar *collation_locale;

	collation_locale = tracker_locale_get (TRACKER_LOCALE_COLLATE);

	g_debug ("Initial collation locale is '%s', subscribing for updates...",
	         collation_locale);

	locale_notification_id = tracker_locale_notify_add (TRACKER_LOCALE_COLLATE,
	                                                    locale_notify_cb,
	                                                    NULL,
	                                                    NULL);
	g_free (collation_locale);
}

void
tracker_locale_change_shutdown_subscription (void)
{
	tracker_locale_notify_remove (locale_notification_id);
}