diff options
author | Stefano Karapetsas <[email protected]> | 2012-10-11 00:01:30 +0200 |
---|---|---|
committer | Stefano Karapetsas <[email protected]> | 2012-10-11 00:01:30 +0200 |
commit | 876f39364e2106c8cb96fa4a9067359e5a350583 (patch) | |
tree | 2936001f23a62397065495e3fd065cb260eff4d7 /mate-panel/panel-layout.c | |
parent | 66916b20f16f9f0aad4c527519b70ac3a72bbec7 (diff) | |
download | mate-panel-876f39364e2106c8cb96fa4a9067359e5a350583.tar.bz2 mate-panel-876f39364e2106c8cb96fa4a9067359e5a350583.tar.xz |
migrate mate-panel to gsettings
Diffstat (limited to 'mate-panel/panel-layout.c')
-rw-r--r-- | mate-panel/panel-layout.c | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/mate-panel/panel-layout.c b/mate-panel/panel-layout.c new file mode 100644 index 00000000..76e7747a --- /dev/null +++ b/mate-panel/panel-layout.c @@ -0,0 +1,353 @@ +/* + * panel-layout.c: methods to load default panels from file + * + * Copyright (C) 2011 Novell, Inc. + * 2012 Stefano Karapetsas + * + * 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., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + * Authors: + * Stefano Karapetsas <[email protected]> + */ + +#include <config.h> +#include <string.h> + +#include <glib.h> +#include <gio/gio.h> + +#include <libpanel-util/panel-dconf.h> + +#include "panel-layout.h" +#include "panel-profile.h" +#include "panel-gsettings.h" +#include "panel-schemas.h" +#include "panel-enums.h" + +#define PANEL_LAYOUT_MATE_FILE PANELDATADIR "/panel-default-layout.mate" +#define PANEL_LAYOUT_DIST_FILE PANELDATADIR "/panel-default-layout.dist" + +typedef struct { + const char *name; + GType type; +} PanelLayoutKeyDefinition; + +static PanelLayoutKeyDefinition panel_layout_toplevel_keys[] = { + { PANEL_TOPLEVEL_NAME_KEY, G_TYPE_STRING }, + { PANEL_TOPLEVEL_SCREEN_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_MONITOR_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_EXPAND_KEY, G_TYPE_BOOLEAN }, + { PANEL_TOPLEVEL_ORIENTATION_KEY, G_TYPE_STRING }, + { PANEL_TOPLEVEL_SIZE_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_X_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_Y_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_X_RIGHT_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_Y_BOTTOM_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_X_CENTERED_KEY, G_TYPE_BOOLEAN }, + { PANEL_TOPLEVEL_Y_CENTERED_KEY, G_TYPE_BOOLEAN }, + { PANEL_TOPLEVEL_AUTO_HIDE_KEY, G_TYPE_BOOLEAN }, + { PANEL_TOPLEVEL_ENABLE_ANIMATIONS_KEY, G_TYPE_BOOLEAN }, + { PANEL_TOPLEVEL_ENABLE_BUTTONS_KEY, G_TYPE_BOOLEAN }, + { PANEL_TOPLEVEL_ENABLE_ARROWS_KEY, G_TYPE_BOOLEAN }, + { PANEL_TOPLEVEL_HIDE_DELAY_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_UNHIDE_DELAY_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_AUTO_HIDE_SIZE_KEY, G_TYPE_INT }, + { PANEL_TOPLEVEL_ANIMATION_SPEED_KEY, G_TYPE_STRING } +}; + +static PanelLayoutKeyDefinition panel_layout_object_keys[] = { + { PANEL_OBJECT_TYPE_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_TOPLEVEL_ID_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_POSITION_KEY, G_TYPE_INT }, + { PANEL_OBJECT_PANEL_RIGHT_STICK_KEY, G_TYPE_BOOLEAN }, + { PANEL_OBJECT_LOCKED_KEY, G_TYPE_BOOLEAN }, + { PANEL_OBJECT_APPLET_IID_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_ATTACHED_TOPLEVEL_ID_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_TOOLTIP_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_USE_CUSTOM_ICON_KEY, G_TYPE_BOOLEAN }, + { PANEL_OBJECT_CUSTOM_ICON_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_USE_MENU_PATH_KEY, G_TYPE_BOOLEAN }, + { PANEL_OBJECT_MENU_PATH_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_HAS_ARROW_KEY, G_TYPE_BOOLEAN }, + { PANEL_OBJECT_LAUNCHER_LOCATION_KEY, G_TYPE_STRING }, + { PANEL_OBJECT_ACTION_TYPE_KEY, G_TYPE_STRING } +}; + +/* + * return the default layout file path, making it overridable by + * distributions + */ +static gchar * +panel_layout_filename () { + + if (g_file_test (PANEL_LAYOUT_DIST_FILE, G_FILE_TEST_IS_REGULAR)) { + return g_strdup (PANEL_LAYOUT_DIST_FILE); + } + else if (g_file_test (PANEL_LAYOUT_MATE_FILE, G_FILE_TEST_IS_REGULAR)) { + return g_strdup (PANEL_LAYOUT_MATE_FILE); + } + else { + return NULL; + } +} + +static gboolean +panel_layout_append_group_helper (GKeyFile *keyfile, + const char *group, + int set_screen_to, + const char *group_prefix, + char *id_list_key, + const char *schema, + const char *path_prefix, + const char *default_prefix, + PanelLayoutKeyDefinition *key_definitions, + int key_definitions_len, + const char *type_for_error_message) +{ + gboolean retval = FALSE; + const char *id; + char *unique_id = NULL; + char *path = NULL; + GSettings *settings = NULL; + char **keyfile_keys = NULL; + char *value_str; + int value_int; + gboolean value_boolean; + int i, j; + GError *error = NULL; + gchar **existing_ids; + gboolean existing_id = FALSE; + gchar *dir = NULL; + gchar *dconf_path = NULL; + PanelGSettingsKeyType type; + + /* Try to extract an id from the group, by stripping the prefix, + * and create a unique id out of that */ + id = group + strlen (group_prefix); + while (g_ascii_isspace (*id)) + id++; + + if (!*id) + id = NULL; + + if (id && !panel_gsettings_is_valid_keyname (id, &error)) { + g_warning ("Invalid id name in layout '%s' (%s)", id, error->message); + g_error_free (error); + return FALSE; + } + + if (g_strcmp0 (id_list_key, PANEL_TOPLEVEL_ID_LIST_KEY) == 0) { + dir = "toplevels"; + type = PANEL_GSETTINGS_TOPLEVELS; + } + if (g_strcmp0 (id_list_key, PANEL_OBJECT_ID_LIST_KEY) == 0) { + dir = "objects"; + type = PANEL_GSETTINGS_OBJECTS; + } + + dconf_path = g_strdup_printf (PANEL_RESOURCE_PATH "/%s", dir); + existing_ids = panel_dconf_list_subdirs (dconf_path, TRUE); + + if (id) { + for (i = 0; existing_ids[i]; i) { + if (!strcmp (existing_ids[i], id)) { + existing_id = TRUE; + } + } + } + g_strfreev (existing_ids); + g_free (dconf_path); + + if (existing_id || !id) + unique_id = panel_profile_find_new_id (type); + else + unique_id = g_strdup (id); + + path = g_strdup_printf ("%s%s/", path_prefix, unique_id); + settings = g_settings_new_with_path (schema, path); + g_free (path); + + keyfile_keys = g_key_file_get_keys (keyfile, group, NULL, NULL); + + if (keyfile_keys) { + + /* validate/add keys from the keyfile */ + for (i = 0; keyfile_keys[i] != NULL; i++) { + gboolean found = FALSE; + + for (j = 0; j < key_definitions_len; j++) { + if (g_strcmp0 (keyfile_keys[i], + key_definitions[j].name) == 0) { + found = TRUE; + break; + } + } + + if (!found) { + g_warning ("Unknown key '%s' for %s", + keyfile_keys[i], + unique_id); + return FALSE; + } + + switch (key_definitions[j].type) { + case G_TYPE_STRING: + value_str = g_key_file_get_string (keyfile, + group, keyfile_keys[i], + NULL); + if (value_str) + g_settings_set_string (settings, + key_definitions[j].name, + value_str); + g_free (value_str); + break; + + case G_TYPE_INT: + value_int = g_key_file_get_integer (keyfile, + group, keyfile_keys[i], + NULL); + g_settings_set_int (settings, + key_definitions[j].name, + value_int); + break; + + case G_TYPE_BOOLEAN: + value_boolean = g_key_file_get_boolean (keyfile, + group, keyfile_keys[i], + NULL); + g_settings_set_boolean (settings, + key_definitions[j].name, + value_boolean); + break; + default: + g_assert_not_reached (); + break; + } + } + + if (set_screen_to != -1 && + g_strcmp0 (schema, PANEL_TOPLEVEL_SCHEMA) == 0) + g_settings_set_int (settings, + PANEL_TOPLEVEL_SCREEN_KEY, + set_screen_to); + + GSettings *panel_settings; + panel_settings = g_settings_new (PANEL_SCHEMA); + panel_gsettings_append_strv (panel_settings, + id_list_key, + unique_id); + g_object_unref (panel_settings); + + retval = TRUE; + } + + if (keyfile_keys) + g_strfreev (keyfile_keys); + + if (settings) + g_object_unref (settings); + + if (unique_id) + g_free (unique_id); + + return retval; +} + +void +panel_layout_apply_default_from_gkeyfile (GdkScreen *screen) +{ + int screen_n; + gchar *layout_file = NULL; + GKeyFile *keyfile = NULL; + gchar **groups = NULL; + GError *error = NULL; + int i; + + screen_n = gdk_screen_get_number (screen); + layout_file = panel_layout_filename(); + + if (layout_file) + { + keyfile = g_key_file_new (); + if (g_key_file_load_from_file (keyfile, + layout_file, + G_KEY_FILE_NONE, + &error)) + { + groups = g_key_file_get_groups (keyfile, NULL); + + for (i = 0; groups[i] != NULL; i++) { + + if (g_strcmp0 (groups[i], "Toplevel") == 0 || + g_str_has_prefix (groups[i], "Toplevel ")) + + panel_layout_append_group_helper ( + keyfile, groups[i], + screen_n, + "Toplevel", + PANEL_TOPLEVEL_ID_LIST_KEY, + PANEL_TOPLEVEL_SCHEMA, + PANEL_TOPLEVEL_PATH, + PANEL_TOPLEVEL_DEFAULT_PREFIX, + panel_layout_toplevel_keys, + G_N_ELEMENTS (panel_layout_toplevel_keys), + "toplevel"); + + else if (g_strcmp0 (groups[i], "Object") == 0 || + g_str_has_prefix (groups[i], "Object ")) + + panel_layout_append_group_helper ( + keyfile, groups[i], + -1, + "Object", + PANEL_OBJECT_ID_LIST_KEY, + PANEL_OBJECT_SCHEMA, + PANEL_OBJECT_PATH, + PANEL_OBJECT_DEFAULT_PREFIX, + panel_layout_object_keys, + G_N_ELEMENTS (panel_layout_object_keys), + "object"); + + else + + g_warning ("Unknown group in default layout: '%s'", + groups[i]); + + } + + } + else + { + g_warning ("Error while parsing default layout from '%s': %s\n", + layout_file, error->message); + g_error_free (error); + } + + } + else { + g_warning ("Cant find a default layout file!"); + /* FIXME implement a fallback panel */ + } + + if (groups) + g_strfreev (groups); + + if (keyfile) + g_key_file_free (keyfile); + + if (layout_file) + g_free (layout_file); +} |