[gnome-software] Redo app folder storage
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Redo app folder storage
- Date: Fri, 10 Jan 2014 19:44:00 +0000 (UTC)
commit 4866da61275552db48d2b4d5061ad6c0973f1632
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Jan 10 00:36:56 2014 -0500
Redo app folder storage
Use a shared setting in the org.gnome.desktop namespace, since
we are going to share this setting with gnome-shell.
We now store each folder in its own settings instance, using
a schema that allows for separate specification of the name
and the apps contained in a folder.
data/org.gnome.software.gschema.xml | 7 --
src/gs-app-folder-dialog.c | 8 +-
src/gs-app-widget.c | 2 +-
src/gs-folders.c | 183 ++++++++++++++++++++++------------
src/gs-folders.h | 2 +-
5 files changed, 125 insertions(+), 77 deletions(-)
---
diff --git a/data/org.gnome.software.gschema.xml b/data/org.gnome.software.gschema.xml
index 8ff0929..e182d99 100644
--- a/data/org.gnome.software.gschema.xml
+++ b/data/org.gnome.software.gschema.xml
@@ -18,12 +18,5 @@
<default>0</default>
<summary>The last update timestamp</summary>
</key>
- <key name="app-folders" type="a{sas}">
- <default>{}</default>
- <summary>Application folders. Maps folder ids to lists of
- application ids. If the folder id is of the form 'Name.directory',
- users are expected to look for a translated name in the file
- of the same name in the XDG_DATA_DIRS/desktop-directories.</summary>
- </key>
</schema>
</schemalist>
diff --git a/src/gs-app-folder-dialog.c b/src/gs-app-folder-dialog.c
index f40a6ba..698f4c7 100644
--- a/src/gs-app-folder-dialog.c
+++ b/src/gs-app-folder-dialog.c
@@ -93,7 +93,7 @@ apply_changes (GsAppFolderDialog *dialog)
for (l = priv->apps; l; l = l->next) {
GsApp *app = l->data;
- gs_folders_set_app_folder (priv->folders, gs_app_get_id (app), folder);
+ gs_folders_set_app_folder (priv->folders, gs_app_get_id_full (app), folder);
}
gs_folders_save (priv->folders);
@@ -129,6 +129,7 @@ done_editing (GtkEntry *entry, GsAppFolderDialog *dialog)
GsAppFolderDialogPrivate *priv = PRIVATE (dialog);
GtkWidget *row;
gchar *folder;
+ const gchar *id;
GtkWidget *label;
GtkWidget *parent;
@@ -147,8 +148,9 @@ done_editing (GtkEntry *entry, GsAppFolderDialog *dialog)
gtk_container_add (GTK_CONTAINER (parent), label);
g_object_set (parent, "margin", 10, NULL);
- g_object_set_data_full (G_OBJECT (row), "folder", folder, g_free);
- gs_folders_add_folder (priv->folders, folder);
+ id = gs_folders_add_folder (priv->folders, folder);
+ g_object_set_data (G_OBJECT (row), "folder", (gpointer)id);
+ g_free (folder);
gtk_widget_show (GTK_WIDGET (priv->new_folder_button));
}
diff --git a/src/gs-app-widget.c b/src/gs-app-widget.c
index d825634..4f41e91 100644
--- a/src/gs-app-widget.c
+++ b/src/gs-app-widget.c
@@ -163,7 +163,7 @@ gs_app_widget_refresh (GsAppWidget *app_widget)
gtk_widget_hide (priv->folder_label);
} else {
folders = gs_folders_get ();
- folder = gs_folders_get_app_folder (folders, gs_app_get_id (priv->app));
+ folder = gs_folders_get_app_folder (folders, gs_app_get_id_full (priv->app));
if (folder)
folder = gs_folders_get_folder_name (folders, folder);
gtk_label_set_label (GTK_LABEL (priv->folder_label), folder);
diff --git a/src/gs-folders.c b/src/gs-folders.c
index e9bc038..c6962e1 100644
--- a/src/gs-folders.c
+++ b/src/gs-folders.c
@@ -27,6 +27,9 @@
#include "gs-folders.h"
+#define APP_FOLDER_SCHEMA "org.gnome.desktop.app-folders"
+#define APP_FOLDER_CHILD_SCHEMA "org.gnome.desktop.app-folders.folder"
+
static void gs_folders_finalize (GObject *object);
#define GS_FOLDERS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_FOLDERS, GsFoldersPrivate))
@@ -43,6 +46,8 @@ typedef struct
{
gchar *id;
gchar *name;
+ gchar *translated;
+ gboolean translate;
GPtrArray *apps;
} GsFolder;
@@ -55,16 +60,40 @@ struct GsFoldersPrivate
G_DEFINE_TYPE (GsFolders, gs_folders, G_TYPE_OBJECT)
+static gchar *
+lookup_folder_name (const gchar *id)
+{
+ gchar *name = NULL;
+ GKeyFile *key_file;
+ gchar *file;
+
+ file = g_build_filename ("desktop-directories", id, NULL);
+ key_file = g_key_file_new ();
+ if (g_key_file_load_from_data_dirs (key_file, file, NULL, G_KEY_FILE_NONE, NULL)) {
+ name = g_key_file_get_locale_string (key_file, "Desktop Entry", "Name", NULL, NULL);
+ }
+
+ g_free (file);
+ g_key_file_unref (key_file);
+
+ return name;
+}
+
static GsFolder *
-gs_folder_new (const gchar *id, const gchar *name)
+gs_folder_new (const gchar *id, const gchar *name, gboolean translate)
{
GsFolder *folder;
folder = g_new0 (GsFolder, 1);
folder->id = g_strdup (id);
- folder->name = g_strdup (name ? name : id);
+ folder->name = g_strdup (name);
+ folder->translate = translate;
+ if (translate) {
+ folder->translated = lookup_folder_name (name);
+ }
folder->apps = g_ptr_array_new_with_free_func (g_free);
+
return folder;
}
@@ -73,6 +102,7 @@ gs_folder_free (GsFolder *folder)
{
g_free (folder->id);
g_free (folder->name);
+ g_free (folder->translated);
g_ptr_array_free (folder->apps, TRUE);
g_free (folder);
}
@@ -85,87 +115,78 @@ gs_folders_class_init (GsFoldersClass *klass)
g_type_class_add_private (klass, sizeof (GsFoldersPrivate));
}
-static gchar *
-lookup_folder_name (GsFolders *folders, const gchar *id)
-{
- gchar *name = NULL;
-
- if (g_str_has_suffix (id, ".directory")) {
- GKeyFile *key_file;
- gchar *file;
- gchar *path;
-
- file = g_build_filename ("desktop-directories", id, NULL);
- key_file = g_key_file_new ();
- if (g_key_file_load_from_data_dirs (key_file, file, &path, G_KEY_FILE_NONE, NULL)) {
- name = g_key_file_get_locale_string (key_file, "Desktop Entry", "Name", NULL, NULL);
- g_free (path);
- }
-
- g_free (file);
- g_key_file_unref (key_file);
- }
-
- return name;
-}
-
static void
load (GsFolders *folders)
{
- GVariant *v;
- GVariantIter iter;
- const gchar *id;
- GVariantIter *apps;
GsFolder *folder;
- gchar *app;
- guint i;
+ gchar **ids;
+ gchar **apps;
+ guint i, j;
gchar *name;
+ gchar *path;
+ gchar *child_path;
+ GSettings *settings;
+ gboolean translate;
folders->priv->folders = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
(GDestroyNotify)gs_folder_free);
folders->priv->apps = g_hash_table_new (g_str_hash, g_str_equal);
- v = g_settings_get_value (folders->priv->settings, "app-folders");
- g_variant_iter_init (&iter, v);
- while (g_variant_iter_next (&iter, "{&sas}", &id, &apps)) {
-
- if (g_variant_iter_n_children (apps) > 0) {
- name = lookup_folder_name (folders, id);
- folder = gs_folder_new (id, name ? name : id);
- g_free (name);
- while (g_variant_iter_next (apps, "s", &app)) {
- g_ptr_array_add (folder->apps, app);
- }
+ ids = g_settings_get_strv (folders->priv->settings, "folder-children");
+ g_object_get (folders->priv->settings, "path", &path, NULL);
+ for (i = 0; ids[i]; i++) {
+ child_path = g_strconcat (path, "folders/", ids[i], "/", NULL);
+ settings = g_settings_new_with_path (APP_FOLDER_CHILD_SCHEMA, child_path);
+ name = g_settings_get_string (settings, "name");
+ translate = g_settings_get_boolean (settings, "translate");
+ apps = g_settings_get_strv (settings, "apps");
+ folder = gs_folder_new (ids[i], name, translate);
+ for (j = 0; apps[j]; j++) {
+ g_ptr_array_add (folder->apps, apps[j]);
+ }
- g_hash_table_insert (folders->priv->folders, (gpointer)folder->id, folder);
- for (i = 0; i < folder->apps->len; i++) {
- g_hash_table_insert (folders->priv->apps, g_ptr_array_index (folder->apps,
i), folder);
- }
+ g_hash_table_insert (folders->priv->folders, (gpointer)folder->id, folder);
+ for (j = 0; j < folder->apps->len; j++) {
+ g_hash_table_insert (folders->priv->apps, g_ptr_array_index (folder->apps, j),
folder);
}
- g_variant_iter_free (apps);
+
+ g_free (apps);
+ g_free (name);
+ g_object_unref (settings);
+ g_free (child_path);
}
- g_variant_unref (v);
+ g_strfreev (ids);
}
static void
save (GsFolders *folders)
{
GHashTableIter iter;
- GVariantBuilder builder;
GsFolder *folder;
-
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sas}"));
+ gpointer apps;
+ gchar *path;
+ gchar *child_path;
+ GSettings *settings;
+
+ g_object_get (folders->priv->settings, "path", &path, NULL);
g_hash_table_iter_init (&iter, folders->priv->folders);
while (g_hash_table_iter_next (&iter, NULL, (gpointer *)&folder)) {
- if (folder->apps->len > 0) {
- g_ptr_array_add (folder->apps, NULL);
- g_variant_builder_add (&builder, "{s^as}",
- folder->id, folder->apps->pdata);
- g_ptr_array_remove (folder->apps, NULL);
- }
+ child_path = g_strconcat (path, "folders/", folder->id, "/", NULL);
+ settings = g_settings_new_with_path (APP_FOLDER_CHILD_SCHEMA, child_path);
+ g_settings_set_string (settings, "name", folder->name);
+ g_settings_set_boolean (settings, "translate", folder->translate);
+ g_ptr_array_add (folder->apps, NULL);
+ g_settings_set_strv (settings, "apps", (const gchar * const *)folder->apps->pdata);
+ g_ptr_array_remove (folder->apps, NULL);
+
+ g_object_unref (settings);
+ g_free (child_path);
}
+ g_free (path);
- g_settings_set_value (folders->priv->settings, "app-folders", g_variant_builder_end (&builder));
-
+ apps = g_hash_table_get_keys_as_array (folders->priv->folders, NULL);
+ g_settings_set_strv (folders->priv->settings, "folder-children",
+ (const gchar * const *)apps);
+ g_free (apps);
}
static void
@@ -183,7 +204,7 @@ gs_folders_init (GsFolders *folders)
{
folders->priv = GS_FOLDERS_GET_PRIVATE (folders);
- folders->priv->settings = g_settings_new ("org.gnome.software");
+ folders->priv->settings = g_settings_new (APP_FOLDER_SCHEMA);
load (folders);
}
@@ -231,16 +252,39 @@ gs_folders_get_apps (GsFolders *folders, const gchar *id)
return folder ? (const gchar**)folder->apps->pdata : NULL;
}
-void
+static void
+canonicalize_key (gchar *key)
+{
+ gchar *p;
+
+ for (p = key; *p != 0; p++)
+ {
+ gchar c = *p;
+
+ if (c != '-' &&
+ (c < '0' || c > '9') &&
+ (c < 'A' || c > 'Z') &&
+ (c < 'a' || c > 'z'))
+ *p = '-';
+ }
+}
+
+const gchar *
gs_folders_add_folder (GsFolders *folders, const gchar *id)
{
GsFolder *folder;
+ gchar *key;
- folder = g_hash_table_lookup (folders->priv->folders, id);
+ key = g_strdup (id);
+ canonicalize_key (key);
+ folder = g_hash_table_lookup (folders->priv->folders, key);
if (!folder) {
- folder = gs_folder_new (id, id);
+ folder = gs_folder_new (key, id, FALSE);
g_hash_table_insert (folders->priv->folders, folder->id, folder);
}
+ g_free (key);
+
+ return folder->id;
}
void
@@ -268,7 +312,14 @@ gs_folders_get_folder_name (GsFolders *folders, const gchar *id)
folder = g_hash_table_lookup (folders->priv->folders, id);
- return folder ? folder->name : NULL;
+ if (folder) {
+ if (folder->translated)
+ return folder->translated;
+
+ return folder->name;
+ }
+
+ return NULL;
}
void
@@ -279,7 +330,9 @@ gs_folders_set_folder_name (GsFolders *folders, const gchar *id, const gchar *na
folder = g_hash_table_lookup (folders->priv->folders, id);
if (folder) {
g_free (folder->name);
+ g_free (folder->translated);
folder->name = g_strdup (name);
+ folder->translate = FALSE;
}
}
diff --git a/src/gs-folders.h b/src/gs-folders.h
index 41f447f..3761b5d 100644
--- a/src/gs-folders.h
+++ b/src/gs-folders.h
@@ -54,7 +54,7 @@ GsFolders *gs_folders_get (void);
gchar **gs_folders_get_folders (GsFolders *folders);
const gchar **gs_folders_get_apps (GsFolders *folders,
const gchar *id);
-void gs_folders_add_folder (GsFolders *folders,
+const gchar *gs_folders_add_folder (GsFolders *folders,
const gchar *id);
void gs_folders_remove_folder (GsFolders *folders,
const gchar *id);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]