Browse Source

Migrate: Add version based config migration.

This allows to update the configuration for new plugins.
tags/xfce4-panel-4.10.0
Nick Schermer 10 years ago
parent
commit
5385d9914b
10 changed files with 345 additions and 86 deletions
  1. +9
    -0
      configure.ac.in
  2. +2
    -0
      migrate/Makefile.am
  3. +1
    -0
      migrate/default.xml.in
  4. +102
    -74
      migrate/main.c
  5. +5
    -4
      migrate/migrate-46.c
  6. +3
    -1
      migrate/migrate-46.h
  7. +184
    -0
      migrate/migrate-config.c
  8. +33
    -0
      migrate/migrate-config.h
  9. +2
    -5
      migrate/migrate-default.c
  10. +4
    -2
      panel/panel-application.c

+ 9
- 0
configure.ac.in View File

@@ -10,6 +10,7 @@ dnl *** Version information ***
dnl ***************************
m4_define([libxfce4panel_verinfo], [3:0:0]) dnl current:revision:age
m4_define([libxfce4panel_version_api], [1.0])
m4_define([xfce4_panel_config_version], [1])
m4_define([xfce4_panel_version_major], [4])
m4_define([xfce4_panel_version_minor], [9])
m4_define([xfce4_panel_version_micro], [0])
@@ -96,6 +97,13 @@ AC_SUBST([LIBXFCE4PANEL_VERSION_MAJOR])
AC_SUBST([LIBXFCE4PANEL_VERSION_MINOR])
AC_SUBST([LIBXFCE4PANEL_VERSION_MICRO])

dnl *********************************
dnl *** Substitute config version ***
dnl *********************************
XFCE4_PANEL_CONFIG_VERSION=xfce4_panel_config_version()
AC_DEFINE([XFCE4_PANEL_CONFIG_VERSION], xfce4_panel_config_version(), [config migration version])
AC_SUBST([XFCE4_PANEL_CONFIG_VERSION])

dnl **********************************
dnl *** Check for standard headers ***
dnl **********************************
@@ -254,6 +262,7 @@ libxfce4panel/Makefile
libxfce4panel/libxfce4panel-1.0.pc
libxfce4panel/libxfce4panel-config.h
migrate/Makefile
migrate/default.xml
panel/Makefile
wrapper/Makefile
plugins/Makefile


+ 2
- 0
migrate/Makefile.am View File

@@ -19,6 +19,8 @@ migrate_SOURCES = \
main.c \
migrate-46.c \
migrate-46.h \
migrate-config.c \
migrate-config.h \
migrate-default.c \
migrate-default.h



migrate/default.xml → migrate/default.xml.in View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>

<channel name="xfce4-panel" version="1.0">
<property name="configver" type="int" value="@XFCE4_PANEL_CONFIG_VERSION@">
<property name="panels" type="uint" value="2">
<property name="panel-0" type="empty">
<property name="position" type="string" value="p=6;x=0;y=0"/>

+ 102
- 74
migrate/main.c View File

@@ -34,8 +34,10 @@
#include <xfconf/xfconf.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include <libxfce4panel/xfce-panel-macros.h>

#include <migrate/migrate-46.h>
#include <migrate/migrate-config.h>
#include <migrate/migrate-default.h>


@@ -43,14 +45,16 @@
gint
main (gint argc, gchar **argv)
{
gchar *file;
GError *error = NULL;
GtkWidget *dialog;
GtkWidget *button;
gint result;
gint retval = EXIT_SUCCESS;
gboolean default_config_exists;
gint default_response = GTK_RESPONSE_CANCEL;
gchar *file;
GError *error = NULL;
GtkWidget *dialog;
GtkWidget *button;
gint result;
gint retval = EXIT_SUCCESS;
gboolean default_config_exists;
gint default_response = GTK_RESPONSE_CANCEL;
XfconfChannel *channel;
gint configver;

/* set translation domain */
xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
@@ -60,15 +64,6 @@ main (gint argc, gchar **argv)
g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
#endif

/* lookup the possible configuration files */
file = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, XFCE_46_CONFIG);
default_config_exists = g_file_test (DEFAULT_CONFIG, G_FILE_TEST_IS_REGULAR);
if (file == NULL && !default_config_exists)
{
g_warning ("No default or old configuration found");
return EXIT_FAILURE;
}

gtk_init (&argc, &argv);

if (!xfconf_init (&error))
@@ -78,76 +73,109 @@ main (gint argc, gchar **argv)
return EXIT_FAILURE;
}

/* check if we auto-migrate the default configuration */
if (g_getenv ("XFCE_PANEL_MIGRATE_DEFAULT") != NULL)
channel = xfconf_channel_get (XFCE_PANEL_CHANNEL_NAME);
if (!xfconf_channel_has_property (channel, "/panels"))
{
/* lookup the possible configuration files */
file = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, XFCE_46_CONFIG);
default_config_exists = g_file_test (DEFAULT_CONFIG, G_FILE_TEST_IS_REGULAR);
if (file == NULL && !default_config_exists)
{
g_warning ("No default or old configuration found");
return EXIT_FAILURE;
}

/* check if we auto-migrate the default configuration */
if (g_getenv ("XFCE_PANEL_MIGRATE_DEFAULT") != NULL)
{
if (file != NULL)
g_message ("Tried to auto-migrate, but old configuration found");
else if (!!default_config_exists)
g_message ("Tried to auto-migrate, but no default configuration found");
else
goto migrate_default;
}

/* create question dialog */
dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
_("Welcome to the first start of the panel"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s%s%s",
file != NULL ? _("Because the panel moved to a new system for storing the "
"settings, it has to load a fresh initial configuration.") : "",
file != NULL ? " " : "",
_("Choose below which setup you want for the first startup."));
gtk_window_set_title (GTK_WINDOW (dialog), _("Panel"));
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_PREFERENCES);
gtk_window_stick (GTK_WINDOW (dialog));
gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);

button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Migrate old config"), GTK_RESPONSE_OK);
gtk_widget_set_tooltip_text (button, _("Migrate the old 4.6 configuration to Xfconf"));
gtk_widget_set_sensitive (button, file != NULL);
if (file != NULL)
g_message ("Tried to auto-migrate, but old configuration found");
else if (!!default_config_exists)
g_message ("Tried to auto-migrate, but no default configuration found");
else
goto migrate_default;
}
default_response = GTK_RESPONSE_OK;

/* create question dialog */
dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
_("Welcome to the first start of the panel"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s%s%s",
file != NULL ? _("Because the panel moved to a new system for storing the "
"settings, it has to load a fresh initial configuration.") : "",
file != NULL ? " " : "",
_("Choose below which setup you want for the first startup."));
gtk_window_set_title (GTK_WINDOW (dialog), _("Panel"));
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_PREFERENCES);
gtk_window_stick (GTK_WINDOW (dialog));
gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE);

button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Migrate old config"), GTK_RESPONSE_OK);
gtk_widget_set_tooltip_text (button, _("Migrate the old 4.6 configuration to Xfconf"));
gtk_widget_set_sensitive (button, file != NULL);
if (file != NULL)
default_response = GTK_RESPONSE_OK;

button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Use default config"), GTK_RESPONSE_YES);
gtk_widget_set_tooltip_text (button, _("Load the default configuration"));
gtk_widget_set_sensitive (button, default_config_exists);
if (default_config_exists && file == NULL)
default_response = GTK_RESPONSE_YES;

button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("One empty panel"), GTK_RESPONSE_CANCEL);
gtk_widget_set_tooltip_text (button, _("Start with one empty panel"));

gtk_dialog_set_default_response (GTK_DIALOG (dialog), default_response);

result = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);

if (result == GTK_RESPONSE_OK
&& file != NULL)
{
/* restore 4.6 config */
if (!migrate_46 (file, &error))
button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Use default config"), GTK_RESPONSE_YES);
gtk_widget_set_tooltip_text (button, _("Load the default configuration"));
gtk_widget_set_sensitive (button, default_config_exists);
if (default_config_exists && file == NULL)
default_response = GTK_RESPONSE_YES;

button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("One empty panel"), GTK_RESPONSE_CANCEL);
gtk_widget_set_tooltip_text (button, _("Start with one empty panel"));

gtk_dialog_set_default_response (GTK_DIALOG (dialog), default_response);

result = gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);

if (result == GTK_RESPONSE_OK
&& file != NULL)
{
xfce_dialog_show_error (NULL, error, _("Failed to migrate the old panel configuration"));
g_error_free (error);
retval = EXIT_FAILURE;
/* restore 4.6 config */
if (!migrate_46 (file, channel, &error))
{
xfce_dialog_show_error (NULL, error, _("Failed to migrate the old panel configuration"));
g_error_free (error);
retval = EXIT_FAILURE;
}
}
else if (result == GTK_RESPONSE_YES
&& default_config_exists)
{
migrate_default:

/* apply default config */
if (!migrate_default (DEFAULT_CONFIG, &error))
{
xfce_dialog_show_error (NULL, error, _("Failed to load the default configuration"));
g_error_free (error);
retval = EXIT_FAILURE;
}
}

g_free (file);
}
else if (result == GTK_RESPONSE_YES
&& default_config_exists)

configver = xfconf_channel_get_int (channel, "/configver", -1);
if (configver < XFCE4_PANEL_CONFIG_VERSION)
{
migrate_default:
g_message (_("Panel config needs migration..."));

/* apply default config */
if (!migrate_default (DEFAULT_CONFIG, &error))
if (!migrate_config (channel, configver, &error))
{
xfce_dialog_show_error (NULL, error, _("Failed to load the default configuration"));
xfce_dialog_show_error (NULL, error, _("Failed to migrate the existing configuration"));
g_error_free (error);
retval = EXIT_FAILURE;
}
}
else
{
g_message (_("Panel configuration has been updated."));
}

g_free (file);
/* migration complete, set new version */
xfconf_channel_set_int (channel, "/configver", XFCE4_PANEL_CONFIG_VERSION);
}

xfconf_shutdown ();



+ 5
- 4
migrate/migrate-46.c View File

@@ -899,8 +899,9 @@ static GMarkupParser markup_parser =


gboolean
migrate_46 (const gchar *filename,
GError **error)
migrate_46 (const gchar *filename,
XfconfChannel *channel,
GError **error)
{
gsize length;
gchar *contents;
@@ -910,6 +911,7 @@ migrate_46 (const gchar *filename,

g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
g_return_val_if_fail (XFCONF_IS_CHANNEL (channel), FALSE);

if (!g_file_get_contents (filename, &contents, &length, error))
return FALSE;
@@ -918,7 +920,7 @@ migrate_46 (const gchar *filename,
parser->state = START;
parser->plugin_id_counter = 0;
parser->panel_id_counter = 0;
parser->channel = xfconf_channel_new (XFCE_PANEL_CHANNEL_NAME);
parser->channel = channel;

context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);

@@ -935,7 +937,6 @@ migrate_46 (const gchar *filename,

g_free (contents);
g_markup_parse_context_free (context);
g_object_unref (G_OBJECT (parser->channel));
g_slice_free (ConfigParser, parser);

return succeed;


+ 3
- 1
migrate/migrate-46.h View File

@@ -25,7 +25,9 @@ G_BEGIN_DECLS

#define XFCE_46_CONFIG "xfce4" G_DIR_SEPARATOR_S "panel" G_DIR_SEPARATOR_S "panels.xml"

gboolean migrate_46 (const gchar *filename, GError **error);
gboolean migrate_46 (const gchar *filename,
XfconfChannel *channel,
GError **error);

G_END_DECLS



+ 184
- 0
migrate/migrate-config.c View File

@@ -0,0 +1,184 @@
/*
* Copyright (C) 2011 Nick Schermer <nick@xfce.org>
*
* This program 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 Foundatoin; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 program; if not, write to the Free Software Foundatoin, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif

#include <gtk/gtk.h>
#include <xfconf/xfconf.h>
#include <migrate/migrate-config.h>



static guint
migrate_config_strchr_count (const gchar *haystack,
const gchar needle)
{
const gchar *p;
guint count;

if (G_UNLIKELY (haystack != NULL))
{
for (p = haystack, count = 0; *p != '\0'; ++p)
if (*p == needle)
count++;
}

return count;
}



static void
migrate_config_session_menu (gpointer key,
gpointer value,
gpointer channel)
{
const GValue *gvalue = value;
const gchar *prop = key;

/* skip non root plugin properties */
if (!G_VALUE_HOLDS_STRING (gvalue)
|| migrate_config_strchr_count (prop, G_DIR_SEPARATOR) != 2
|| g_strcmp0 (g_value_get_string (gvalue), "xfsm-logout-plugin") != 0)
return;

/* this plugin never had any properties and matches the default
* settings of the new actions plugin */
xfconf_channel_set_string (XFCONF_CHANNEL (channel), prop, "actions");
}



static gint
migrate_config_action_48_convert (gint action)
{
switch (action)
{
case 1: /* ACTION_LOG_OUT_DIALOG */
return 3; /* ACTION_TYPE_LOGOUT_DIALOG */

case 2: /* ACTION_LOG_OUT */
return 2; /* ACTION_TYPE_LOGOUT */

case 3: /* ACTION_LOCK_SCREEN */
return 5; /* ACTION_TYPE_LOCK_SCREEN */

case 4: /* ACTION_SHUT_DOWN */
return 9; /* ACTION_TYPE_SHUTDOWN */

case 5: /* ACTION_RESTART */
return 8; /* ACTION_TYPE_RESTART */

case 6: /* ACTION_SUSPEND */
return 7; /* ACTION_TYPE_SUSPEND */

case 7: /* ACTION_HIBERNATE */
return 6; /* ACTION_TYPE_HIBERNATE */

default: /* ACTION_DISABLED */
return -4; /* ACTION_TYPE_SWITCH_USER */
}
}



static void
migrate_config_action_48 (gpointer key,
gpointer value,
gpointer channel)
{
const GValue *gvalue = value;
const gchar *prop = key;
gchar str[64];
gint first_action;
gint second_action;


/* skip non root plugin properties */
if (!G_VALUE_HOLDS_STRING (gvalue)
|| migrate_config_strchr_count (prop, G_DIR_SEPARATOR) != 2
|| g_strcmp0 (g_value_get_string (gvalue), "actions") != 0)
return;

/* read and remove the old properties */
g_snprintf (str, sizeof (str), "%s/first-action", prop);
first_action = xfconf_channel_get_uint (channel, str, 0) + 1;
xfconf_channel_reset_property (channel, str, FALSE);

g_snprintf (str, sizeof (str), "%s/second-action", prop);
second_action = xfconf_channel_get_uint (channel, str, 0);
xfconf_channel_reset_property (channel, str, FALSE);

/* corrections for new plugin */
if (first_action == 0)
first_action = 1;
if (first_action == second_action)
second_action = 0;

/* set appearance to button mode */
g_snprintf (str, sizeof (str), "%s/appearance", prop);
xfconf_channel_set_uint (channel, str, 0);

/* set orientation */
g_snprintf (str, sizeof (str), "%s/invert-orientation", prop);
xfconf_channel_set_bool (channel, str, second_action > 0);

/* convert the old value to new ones */
first_action = migrate_config_action_48_convert (first_action);
second_action = migrate_config_action_48_convert (second_action);

/* set the visible properties */
g_snprintf (str, sizeof (str), "%s/items", prop);
xfconf_channel_set_array (channel, str,
G_TYPE_INT, &first_action,
G_TYPE_INT, &second_action,
G_TYPE_INVALID);
}



gboolean
migrate_config (XfconfChannel *channel,
gint configver,
GError **error)
{
GHashTable *plugins;

plugins = xfconf_channel_get_properties (channel, "/plugins");

/* migrate plugins to the new actions plugin */
if (configver < 1)
{
/* migrate xfsm-logout-plugin */
g_hash_table_foreach (plugins, migrate_config_session_menu, channel);

/* migrate old action plugins */
g_hash_table_foreach (plugins, migrate_config_action_48, channel);
}

return TRUE;
}

+ 33
- 0
migrate/migrate-config.h View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2011 Nick Schermer <nick@xfce.org>
*
* This program 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 program 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 program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef __MIGRATE_CONFIG_H__
#define __MIGRATE_CONFIG_H__

#include <gtk/gtk.h>

G_BEGIN_DECLS

gboolean migrate_config (XfconfChannel *channel,
gint configver,
GError **error);

G_END_DECLS

#endif /* !__MIGRATE_CONFIG_H__ */


+ 2
- 5
migrate/migrate-default.c View File

@@ -158,7 +158,7 @@ migrate_default_start_element_handler (GMarkupParseContext *context,
if (channel_name != NULL)
{
/* open the xfconf channel */
parser->channel = xfconf_channel_new (channel_name);
parser->channel = xfconf_channel_get (channel_name);
}
else
{
@@ -292,10 +292,7 @@ migrate_default_end_element_handler (GMarkupParseContext *context,
if (strcmp (element_name, "channel") == 0)
{
if (G_LIKELY (parser->channel != NULL))
{
g_object_unref (G_OBJECT (parser->channel));
parser->channel = NULL;
}
parser->channel = NULL;

if (parser->path != NULL)
{


+ 4
- 2
panel/panel-application.c View File

@@ -198,6 +198,7 @@ static void
panel_application_init (PanelApplication *application)
{
GError *error = NULL;
gint configver;

application->windows = NULL;
application->dialogs = NULL;
@@ -209,8 +210,9 @@ panel_application_init (PanelApplication *application)
/* get the xfconf channel (singleton) */
application->xfconf = panel_properties_get_channel (G_OBJECT (application));

/* check if we need to launch the migration application */
if (!xfconf_channel_has_property (application->xfconf, "/panels"))
/* check if we need to migrate configuration */
configver = xfconf_channel_get_int (application->xfconf, "/configver", -1);
if (G_UNLIKELY (configver < XFCE4_PANEL_CONFIG_VERSION))
{
if (!g_spawn_command_line_sync (MIGRATE_BIN, NULL, NULL, NULL, &error))
{


Loading…
Cancel
Save