summaryrefslogtreecommitdiff
path: root/mate-panel/panel-layout.c
diff options
context:
space:
mode:
authorStefano Karapetsas <[email protected]>2012-10-11 00:01:30 +0200
committerStefano Karapetsas <[email protected]>2012-10-11 00:01:30 +0200
commit876f39364e2106c8cb96fa4a9067359e5a350583 (patch)
tree2936001f23a62397065495e3fd065cb260eff4d7 /mate-panel/panel-layout.c
parent66916b20f16f9f0aad4c527519b70ac3a72bbec7 (diff)
downloadmate-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.c353
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);
+}