Browse Source

Add xfconf xml importer and default config.

Add a parser to import an xml channel file into a
channel and add a default configuration.

The migration utility will now prompt with a
question dialog whether to import the olf 4.6
config or use the default setup.
upstream/xfce4-panel-4.10.1
Nick Schermer 13 years ago
parent
commit
faa9d0e20a
  1. 20
      migrate/Makefile.am
  2. 64
      migrate/default.xml
  3. 60
      migrate/main.c
  4. 15
      migrate/migrate-46.c
  5. 5
      migrate/migrate-46.h
  6. 379
      migrate/migrate-default.c
  7. 32
      migrate/migrate-default.h

20
migrate/Makefile.am

@ -3,25 +3,29 @@ INCLUDES = \
-I$(top_srcdir) \
-I$(top_builddir) \
-DG_LOG_DOMAIN=\"xfce4-panel-migrate\" \
-DDATADIR=\"$(datadir)\" \
-DLIBDIR=\"$(libdir)/xfce4\" \
-DLIBEXECDIR=\"$(libexecdir)/xfce4\" \
-DSYSCONFDIR=\"$(sysconfdir)\" \
-DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
-DDEFAULT_CONFIG=\"$(sysconfdir)/xdg/xfce4/panel/default.xml\" \
$(PLATFORM_CPPFLAGS)
confdir = $(sysconfdir)/xdg/xfce4/panel
conf_DATA = \
default.xml
libexec_PROGRAMS = \
xfce4-panel-migrate
xfce4_panel_migrate_SOURCES = \
main.c \
migrate-46.c \
migrate-46.h
migrate-46.h \
migrate-default.c \
migrate-default.h
xfce4_panel_migrate_CFLAGS = \
$(GTK_CFLAGS) \
$(XFCONF_CFLAGS) \
$(LIBXFCE4UTIL_CFLAGS) \
$(LIBXFCE4UI_CFLAGS) \
$(PLATFORM_CFLAGS)
xfce4_panel_migrate_LDFLAGS = \
@ -31,6 +35,10 @@ xfce4_panel_migrate_LDFLAGS = \
xfce4_panel_migrate_LDADD = \
$(GTK_LIBS) \
$(XFCONF_LIBS) \
$(LIBXFCE4UTIL_LIBS)
$(LIBXFCE4UTIL_LIBS) \
$(LIBXF CE4UI_LIBS)
EXTRA_DIST = \
default.xml
# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:

64
migrate/default.xml

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<channel name="xfce4-panel" version="1.0">
<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"/>
<property name="length" type="uint" value="100"/>
<property name="plugin-ids" type="array">
<value type="int" value="1"/>
<value type="int" value="2"/>
<value type="int" value="3"/>
<value type="int" value="4"/>
<value type="int" value="5"/>
</property>
</property>
<property name="panel-1" type="empty">
<property name="position" type="string" value="p=10;x=0;y=0"/>
<property name="size" type="uint" value="40"/>
<property name="plugin-ids" type="array">
<value type="int" value="6"/>
<value type="int" value="7"/>
<value type="int" value="8"/>
<value type="int" value="9"/>
<value type="int" value="10"/>
<value type="int" value="11"/>
<value type="int" value="12"/>
</property>
</property>
</property>
<property name="plugins" type="empty">
<property name="plugin-1" type="string" value="actions"/>
<property name="plugin-2" type="string" value="tasklist"/>
<property name="plugin-3" type="string" value="pager"/>
<property name="plugin-4" type="string" value="clock"/>
<property name="plugin-5" type="string" value="systray"/>
<property name="plugin-6" type="string" value="showdesktop"/>
<property name="plugin-7" type="string" value="separator"/>
<property name="plugin-8" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="xfce4-terminal.desktop"/>
</property>
</property>
<property name="plugin-9" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="xfce4-file-manager.desktop"/>
</property>
</property>
<property name="plugin-10" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="xfce4-web-browser.desktop"/>
</property>
</property>
<property name="plugin-11" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="xfce-settings-manager.desktop"/>
</property>
</property>
<property name="plugin-12" type="string" value="launcher">
<property name="items" type="array">
<value type="string" value="xfce4-appfinder.desktop"/>
</property>
</property>
</property>
</channel>

60
migrate/main.c

@ -33,17 +33,22 @@
#include <gtk/gtk.h>
#include <xfconf/xfconf.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4ui/libxfce4ui.h>
#include <migrate/migrate-46.h>
#include <migrate/migrate-default.h>
gint
main (gint argc, gchar **argv)
{
gchar *file;
XfconfChannel *channel;
GError *error = NULL;
gchar *file;
GError *error = NULL;
GtkWidget *dialog;
GtkWidget *button;
gint result;
gint retval = EXIT_SUCCESS;
/* set translation domain */
xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
@ -58,21 +63,54 @@ main (gint argc, gchar **argv)
if (!xfconf_init (&error))
{
g_critical ("%s", error->message);
g_critical ("Failed to initialize Xfconf: %s", error->message);
g_error_free (error);
return EXIT_FAILURE;
}
channel = xfconf_channel_get (CHANNEL_NAME);
/* lookup the old 4.6 config file */
file = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, XFCE_46_CONFIG);
if (file != NULL)
/* create question dialog */
dialog = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
_("Welcome to the first start of the Xfce Panel"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("Click one of the options below for the "
"initial configuration of the Xfce Panel"));
gtk_window_set_title (GTK_WINDOW (dialog), "Xfce 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, _("The panel will migrate your existing 4.6 panel configuration"));
gtk_widget_set_sensitive (button, file != NULL);
button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Use default config"), GTK_RESPONSE_YES);
gtk_widget_set_tooltip_text (button, _("The default configuration will be loaded"));
gtk_widget_set_sensitive (button, g_file_test (DEFAULT_CONFIG, G_FILE_TEST_IS_REGULAR));
button = gtk_dialog_add_button (GTK_DIALOG (dialog), _("Cancel"), GTK_RESPONSE_CANCEL);
gtk_widget_set_tooltip_text (button, _("Xfce Panel will start with one empty panel"));
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))
{
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)
{
g_message ("found old config file: %s", file);
if (!migrate_46 (file, channel, &error))
/* apply default config */
if (!migrate_default (DEFAULT_CONFIG, &error))
{
g_critical ("%s", error->message);
xfce_dialog_show_error (NULL, error, _("Failed to load the default configuration"));
g_error_free (error);
retval = EXIT_FAILURE;
}
}
@ -80,5 +118,5 @@ main (gint argc, gchar **argv)
xfconf_shutdown ();
return EXIT_SUCCESS;
return retval;
}

15
migrate/migrate-46.c

@ -33,6 +33,12 @@
#include <migrate/migrate-46.h>
#define CHANNEL_NAME "xfce4-panel"
#define LAUNCHER_FOLDER "launcher"
typedef enum
{
START,
@ -878,9 +884,8 @@ static GMarkupParser markup_parser =
gboolean
migrate_46 (const gchar *filename,
XfconfChannel *channel,
GError **error)
migrate_46 (const gchar *filename,
GError **error)
{
gsize length;
gchar *contents;
@ -889,7 +894,6 @@ migrate_46 (const gchar *filename,
gboolean succeed = FALSE;
g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (XFCONF_IS_CHANNEL (channel), FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (!g_file_get_contents (filename, &contents, &length, error))
@ -899,7 +903,7 @@ migrate_46 (const gchar *filename,
parser->state = START;
parser->plugin_id_counter = 0;
parser->panel_id_counter = 0;
parser->channel = channel;
parser->channel = xfconf_channel_new (CHANNEL_NAME);
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
@ -912,6 +916,7 @@ 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;

5
migrate/migrate-46.h

@ -20,15 +20,12 @@
#define __MIGRATE_46_H__
#include <gtk/gtk.h>
#include <xfconf/xfconf.h>
G_BEGIN_DECLS
#define XFCE_46_CONFIG "xfce4" G_DIR_SEPARATOR_S "panel" G_DIR_SEPARATOR_S "panels.xml"
#define CHANNEL_NAME "xfce4-panel-test"
#define LAUNCHER_FOLDER "launcher-test"
gboolean migrate_46 (const gchar *filename, XfconfChannel *channel, GError **error);
gboolean migrate_46 (const gchar *filename, GError **error);
G_END_DECLS

379
migrate/migrate-default.c

@ -0,0 +1,379 @@
/*
* Copyright (C) 2009 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 <libxfce4util/libxfce4util.h>
#include <migrate/migrate-default.h>
typedef struct
{
XfconfChannel *channel;
GSList *path;
GPtrArray *array;
}
ConfigParser;
static GType
migrate_default_gtype_from_string (const gchar *type)
{
if (strcmp (type, "string") == 0)
return G_TYPE_STRING;
else if (strcmp (type, "uint") == 0)
return G_TYPE_UINT;
else if (strcmp (type, "int") == 0)
return G_TYPE_INT;
else if (strcmp (type, "double") == 0)
return G_TYPE_DOUBLE;
else if (strcmp (type, "bool") == 0)
return G_TYPE_BOOLEAN;
else if (strcmp (type, "array") == 0)
return G_TYPE_BOXED;
else if (strcmp (type, "empty") == 0)
return G_TYPE_NONE;
return G_TYPE_INVALID;
}
static void
migrate_default_set_value (GValue *value,
const gchar *string)
{
switch (G_VALUE_TYPE (value))
{
case G_TYPE_STRING:
g_value_set_string (value, string);
break;
case G_TYPE_UINT:
g_value_set_uint (value, strtol (string, NULL, 0));
break;
case G_TYPE_INT:
g_value_set_int (value, strtoul (string, NULL, 0));
break;
case G_TYPE_DOUBLE:
g_value_set_double (value, g_ascii_strtod (string, NULL));
break;
case G_TYPE_BOOLEAN:
g_value_set_boolean (value, strcmp (string, "true") == 0);
break;
}
}
static gchar *
migrate_default_property_path (ConfigParser *parser)
{
GSList *li;
GString *path;
path = g_string_new (NULL);
for (li = parser->path; li != NULL; li = li->next)
{
g_string_append_c (path, '/');
g_string_append (path, (const gchar *) li->data);
}
return g_string_free (path, FALSE);
}
static void
migrate_default_start_element_handler (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error)
{
ConfigParser *parser = user_data;
guint i;
const gchar *channel_name;
const gchar *prop_name, *prop_value, *prop_type;
GType type;
gchar *prop_path;
GValue value = { 0, };
const gchar *value_value, *value_type;
GValue *value2;
if (strcmp (element_name, "channel") == 0)
{
channel_name = NULL;
if (G_LIKELY (attribute_names != NULL))
{
for (i = 0; attribute_names[i] != NULL; i++)
{
if (strcmp (attribute_names[i], "name") == 0)
channel_name = attribute_values[i];
}
}
if (channel_name != NULL)
{
/* open the xfconf channel */
parser->channel = xfconf_channel_new (channel_name);
}
else
{
g_set_error_literal (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
"The channel element has no name attribute");
}
}
else if (strcmp (element_name, "property") == 0)
{
prop_name = NULL;
prop_value = NULL;
prop_type = NULL;
if (G_LIKELY (attribute_names != NULL))
{
for (i = 0; attribute_names[i] != NULL; i++)
{
if (strcmp (attribute_names[i], "name") == 0)
prop_name = attribute_values[i];
else if (strcmp (attribute_names[i], "value") == 0)
prop_value = attribute_values[i];
else if (strcmp (attribute_names[i], "type") == 0)
prop_type = attribute_values[i];
}
}
if (prop_name != NULL && prop_type != NULL)
{
type = migrate_default_gtype_from_string (prop_type);
parser->path = g_slist_append (parser->path, g_strdup (prop_name));
if (type == G_TYPE_INVALID)
{
g_set_error (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
"Property \"%s\" has invalid type \"%s\"",
prop_name, prop_type);
}
if (type == G_TYPE_BOXED)
{
parser->array = g_ptr_array_new ();
}
else if (type != G_TYPE_NONE && prop_value != NULL)
{
g_value_init (&value, type);
migrate_default_set_value (&value, prop_value);
prop_path = migrate_default_property_path (parser);
xfconf_channel_set_property (parser->channel, prop_path, &value);
g_free (prop_path);
g_value_unset (&value);
}
}
else
{
g_set_error (error, G_MARKUP_ERROR_INVALID_CONTENT, G_MARKUP_ERROR,
"Found property without name (%s), type (%s) or value (%s)",
prop_name, prop_type, prop_value);
}
}
else if (strcmp (element_name, "value") == 0)
{
if (parser->array != NULL)
{
value_type = NULL;
value_value = NULL;
if (G_LIKELY (attribute_names != NULL))
{
for (i = 0; attribute_names[i] != NULL; i++)
{
if (strcmp (attribute_names[i], "type") == 0)
value_type = attribute_values[i];
else if (strcmp (attribute_names[i], "value") == 0)
value_value = attribute_values[i];
}
}
if (value_type != NULL && value_value != NULL)
{
type = migrate_default_gtype_from_string (value_type);
if (type != G_TYPE_INVALID && type != G_TYPE_NONE && type != G_TYPE_BOXED)
{
value2 = g_new0 (GValue, 1);
g_value_init (value2, type);
migrate_default_set_value (value2, value_value);
g_ptr_array_add (parser->array, value2);
}
else
{
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
"Found value has unknown type \"%s\"", value_type);
}
}
else
{
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
"Found value element with missing type (%s) or value (%s)",
value_type, value_value);
}
}
else
{
g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
"Found value element without an array property");
}
}
else
{
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
"Unknown start element \"%s\"", element_name);
}
}
static void
migrate_default_end_element_handler (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error)
{
ConfigParser *parser = user_data;
GSList *li;
gchar *prop_path;
if (strcmp (element_name, "channel") == 0)
{
if (G_LIKELY (parser->channel != NULL))
{
g_object_unref (G_OBJECT (parser->channel));
parser->channel = NULL;
}
if (parser->path != NULL)
{
g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
"Property path still contains items");
}
}
else if (strcmp (element_name, "property") == 0)
{
if (parser->array != NULL)
{
prop_path = migrate_default_property_path (parser);
xfconf_channel_set_arrayv (parser->channel, prop_path, parser->array);
g_free (prop_path);
xfconf_array_free (parser->array);
parser->array = NULL;
}
li = g_slist_last (parser->path);
if (li != NULL)
{
g_free (li->data);
parser->path = g_slist_delete_link (parser->path, li);
}
else
{
g_set_error_literal (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
"Element could no be popped from the path");
}
}
else if (strcmp (element_name, "value") == 0)
{
/* nothing to do */
}
else
{
g_set_error (error, G_MARKUP_ERROR_UNKNOWN_ELEMENT, G_MARKUP_ERROR,
"Unknown end element \"%s\"", element_name);
}
}
static GMarkupParser markup_parser =
{
migrate_default_start_element_handler,
migrate_default_end_element_handler,
NULL,
NULL,
NULL
};
gboolean
migrate_default (const gchar *filename,
GError **error)
{
gsize length;
gchar *contents;
GMarkupParseContext *context;
ConfigParser *parser;
gboolean succeed = FALSE;
g_return_val_if_fail (filename != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
if (!g_file_get_contents (filename, &contents, &length, error))
return FALSE;
parser = g_slice_new0 (ConfigParser);
parser->path = NULL;
context = g_markup_parse_context_new (&markup_parser, 0, parser, NULL);
if (g_markup_parse_context_parse (context, contents, length, error))
{
/* check if the entire file is parsed */
if (g_markup_parse_context_end_parse (context, error))
succeed = TRUE;
}
g_free (contents);
g_markup_parse_context_free (context);
g_slice_free (ConfigParser, parser);
return succeed;
}

32
migrate/migrate-default.h

@ -0,0 +1,32 @@
/*
* Copyright (C) 2009 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 __XFCE_DEFAULT_H__
#define __XFCE_DEFAULT_H__
#include <gtk/gtk.h>
#include <xfconf/xfconf.h>
G_BEGIN_DECLS
gboolean migrate_default (const gchar *filename, GError **error);
G_END_DECLS
#endif /* !__XFCE_DEFAULT_H__ */
Loading…
Cancel
Save