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