1 /*
2 * Copyright (C) 2011 Nick Schermer <nick@xfce.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundatoin; either version 2 of the License, or
7 * (at your option) any later version.
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
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundatoin, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22
23 #ifdef HAVE_STDLIB_H
24 #include <stdlib.h>
25 #endif
26 #ifdef HAVE_STRING_H
27 #include <string.h>
28 #endif
29
30 #include <gtk/gtk.h>
31 #include <xfconf/xfconf.h>
32 #include <migrate/migrate-config.h>
33
34
35
36 static guint
migrate_config_strchr_count(const gchar * haystack,const gchar needle)37 migrate_config_strchr_count (const gchar *haystack,
38 const gchar needle)
39 {
40 const gchar *p;
41 guint count = 0;
42
43 if (G_UNLIKELY (haystack != NULL))
44 {
45 for (p = haystack; *p != '\0'; ++p)
46 if (*p == needle)
47 count++;
48 }
49
50 return count;
51 }
52
53
54
55 static void
migrate_config_session_menu(gpointer key,gpointer value,gpointer channel)56 migrate_config_session_menu (gpointer key,
57 gpointer value,
58 gpointer channel)
59 {
60 const GValue *gvalue = value;
61 const gchar *prop = key;
62
63 /* skip non root plugin properties */
64 if (!G_VALUE_HOLDS_STRING (gvalue)
65 || migrate_config_strchr_count (prop, G_DIR_SEPARATOR) != 2
66 || g_strcmp0 (g_value_get_string (gvalue), "xfsm-logout-plugin") != 0)
67 return;
68
69 /* this plugin never had any properties and matches the default
70 * settings of the new actions plugin */
71 xfconf_channel_set_string (XFCONF_CHANNEL (channel), prop, "actions");
72 }
73
74
75
76 static const gchar *
migrate_config_action_48_convert(gint action)77 migrate_config_action_48_convert (gint action)
78 {
79 switch (action)
80 {
81 case 1: /* ACTION_LOG_OUT_DIALOG */
82 return "+logout-dialog";
83
84 case 2: /* ACTION_LOG_OUT */
85 return "+logout";
86
87 case 3: /* ACTION_LOCK_SCREEN */
88 return "+lock-screen";
89
90 case 4: /* ACTION_SHUT_DOWN */
91 return "+shutdown";
92
93 case 5: /* ACTION_RESTART */
94 return "+restart";
95
96 case 6: /* ACTION_SUSPEND */
97 return "+suspend";
98
99 case 7: /* ACTION_HIBERNATE */
100 return "+hibernate";
101
102 case 8: /* ACTION_HYBRID_SLEEP */
103 return "+hybrid-sleep";
104
105 default: /* ACTION_DISABLED */
106 return "-switch-user"; /* something else */
107 }
108 }
109
110
111
112 static void
migrate_config_action_48(gpointer key,gpointer value,gpointer channel)113 migrate_config_action_48 (gpointer key,
114 gpointer value,
115 gpointer channel)
116 {
117 const GValue *gvalue = value;
118 const gchar *prop = key;
119 gchar str[64];
120 gint first_action_int;
121 gint second_action_int;
122 const gchar *first_action;
123 const gchar *second_action;
124
125 /* skip non root plugin properties */
126 if (!G_VALUE_HOLDS_STRING (gvalue)
127 || migrate_config_strchr_count (prop, G_DIR_SEPARATOR) != 2
128 || g_strcmp0 (g_value_get_string (gvalue), "actions") != 0)
129 return;
130
131 /* this is a bug that affects pre users: don't try to migrate
132 * when the appearance property is already set */
133 g_snprintf (str, sizeof (str), "%s/appearance", prop);
134 if (xfconf_channel_has_property (channel, str))
135 return;
136
137 /* set appearance to button mode */
138 xfconf_channel_set_uint (channel, str, 0);
139
140 /* read and remove the old properties */
141 g_snprintf (str, sizeof (str), "%s/first-action", prop);
142 first_action_int = xfconf_channel_get_uint (channel, str, 0) + 1;
143 xfconf_channel_reset_property (channel, str, FALSE);
144
145 g_snprintf (str, sizeof (str), "%s/second-action", prop);
146 second_action_int = xfconf_channel_get_uint (channel, str, 0);
147 xfconf_channel_reset_property (channel, str, FALSE);
148
149 /* corrections for new plugin */
150 if (first_action_int == 0)
151 first_action_int = 1;
152 if (first_action_int == second_action_int)
153 second_action_int = 0;
154
155 /* set orientation */
156 g_snprintf (str, sizeof (str), "%s/invert-orientation", prop);
157 xfconf_channel_set_bool (channel, str, second_action_int > 0);
158
159 /* convert the old value to new ones */
160 first_action = migrate_config_action_48_convert (first_action_int);
161 second_action = migrate_config_action_48_convert (second_action_int);
162
163 /* set the visible properties */
164 g_snprintf (str, sizeof (str), "%s/items", prop);
165 xfconf_channel_set_array (channel, str,
166 G_TYPE_STRING, first_action,
167 G_TYPE_STRING, second_action,
168 G_TYPE_INVALID);
169 }
170
171
172
173 gboolean
migrate_config(XfconfChannel * channel,gint configver,GError ** error)174 migrate_config (XfconfChannel *channel,
175 gint configver,
176 GError **error)
177 {
178 GHashTable *plugins;
179 guint n, n_panels;
180 gchar buf[50];
181 gboolean horizontal;
182
183 plugins = xfconf_channel_get_properties (channel, "/plugins");
184
185 /* migrate plugins to the new actions plugin */
186 if (configver < 1)
187 {
188 /* migrate xfsm-logout-plugin */
189 g_hash_table_foreach (plugins, migrate_config_session_menu, channel);
190
191 /* migrate old action plugins */
192 g_hash_table_foreach (plugins, migrate_config_action_48, channel);
193 }
194
195 /* migrate horizontal to mode property */
196 if (configver < 2)
197 {
198 n_panels = xfconf_channel_get_uint (channel, "/panels", 0);
199 for (n = 0; n < n_panels; n++)
200 {
201 /* read and remove old property */
202 g_snprintf (buf, sizeof (buf), "/panels/panel-%u/horizontal", n);
203 horizontal = xfconf_channel_get_bool (channel, buf, TRUE);
204 xfconf_channel_reset_property (channel, buf, FALSE);
205
206 /* set new mode */
207 g_snprintf (buf, sizeof (buf), "/panels/panel-%u/mode", n);
208 xfconf_channel_set_uint (channel, buf, horizontal ? 0 : 1);
209 }
210 }
211
212 g_hash_table_destroy (plugins);
213
214 return TRUE;
215 }
216