soc.2008.themes: 12ae7a21: Added the theme-manager and basic functi...
ffdragon at soc.pidgin.im
ffdragon at soc.pidgin.im
Tue Jun 10 17:45:49 EDT 2008
-----------------------------------------------------------------
Revision: 12ae7a2153deb69daa4c2bd574cc87dc70b6787b
Ancestor: db6aa707aabb11e7931c3b30b0e3eb5b740f91c3
Author: ffdragon at soc.pidgin.im
Date: 2008-06-10T21:39:35
Branch: im.pidgin.soc.2008.themes
URL: http://d.pidgin.im/viewmtn/revision/info/12ae7a2153deb69daa4c2bd574cc87dc70b6787b
Added files:
libpurple/theme-manager.c libpurple/theme-manager.h
Modified files:
libpurple/Makefile.am libpurple/theme-loader.c
ChangeLog:
Added the theme-manager and basic functionality (needs to be given proper directories to find themes)
-------------- next part --------------
============================================================
--- libpurple/theme-manager.c 28908a38ae455f677383986255ed88c588315e1b
+++ libpurple/theme-manager.c 28908a38ae455f677383986255ed88c588315e1b
@@ -0,0 +1,339 @@
+/*
+ * Themes for LibPurple
+ *
+ * Pidgin is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 02111-1301 USA
+ *
+ */
+
+#include <stdarg.h>
+#include "theme-manager.h"
+
+#define PURPLE_THEME_MANAGER_GET_PRIVATE(Gobject) \
+ ((PurpleThemeManagerPrivate *) ((PURPLE_THEME_MANAGER(Gobject))->priv))
+
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+typedef struct {
+ GHashTable *theme_table;
+} PurpleThemeManagerPrivate;
+
+/*****************************************************************************
+ * GObject Stuff
+ ****************************************************************************/
+
+static void
+purple_theme_manager_finalize (GObject *obj)
+{
+ PurpleThemeManagerPrivate *priv;
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(obj);
+
+ g_hash_table_destroy(priv->theme_table);
+}
+
+static void
+purple_theme_manager_class_init (PurpleThemeManagerClass *klass)
+{
+ /*PurpleThemeManagerClass *theme_manager_class = PURPLE_THEME_MANAGER_CLASS(klass);*/
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ /* 2.4 g_type_class_add_private(klass, sizeof(PurpleThemeManagerPrivate));*/
+
+ obj_class->finalize = purple_theme_manager_finalize;
+
+}
+
+GType
+purple_theme_manager_get_type (void)
+{
+ static GType type = 0;
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof (PurpleThemeManagerClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc)purple_theme_manager_class_init, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PurpleThemeManager),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ NULL, /* Value Table */
+ };
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "PurpleThemeManagerType",
+ &info, 0);
+ }
+ return type;
+}
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+/* makes a key of <type> + '/' + <name> */
+static gchar *
+purple_theme_manager_make_key(const gchar *name, const gchar *type)
+{
+ g_return_val_if_fail(name, NULL);
+ g_return_val_if_fail(type, NULL);
+ return g_strconcat(type, '/', name, NULL);
+}
+
+/* returns TRUE if theme is of type "user_data" */
+static gboolean
+purple_theme_manager_is_theme_type(gchar *key,
+ gpointer value,
+ gchar *user_data)
+{
+ return g_str_has_prefix (key, g_strconcat(user_data, '/', NULL));
+}
+
+static gboolean
+purple_theme_manager_is_theme(gchar *key,
+ gpointer value,
+ gchar *user_data)
+{
+ return PURPLE_IS_THEME(value);
+}
+
+static void
+purple_theme_manager_function_wrapper(gchar *key,
+ gpointer value,
+ PTFunc user_data)
+{
+ if(PURPLE_IS_THEME(value))
+ (* user_data) (value);
+}
+
+static void
+purple_theme_manager_build(PurpleThemeManager *self, const gchar *root)
+{
+ PurpleThemeManagerPrivate *priv;
+ GDir *rdir;
+ gchar *name, *type;
+ GDir *dir;
+ PurpleThemeLoader *loader;
+
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ rdir = g_dir_open(root, 0, NULL);/*TODO: should have debug error?*/
+
+ g_return_if_fail(rdir);
+
+ /*TODO: This looks messy*/
+ /* Parses directory by root/name/purple/type */
+ while((name = g_strdup(g_dir_read_name (rdir)))){
+
+ dir = g_dir_open(g_strconcat(root, '/', name,
+ '/', "purple", NULL), 0, NULL);
+
+ if(dir) {
+ while((type = g_strdup(g_dir_read_name (dir)))) {
+ if((loader = g_hash_table_lookup (priv->theme_table, type)))
+ purple_theme_manager_add_theme(self,
+ purple_theme_loader_build(loader, g_strconcat(root, '/', name, '/',
+ "purple", '/', type, NULL)));
+
+ g_free(type);
+ }
+
+ g_dir_close(dir);
+ }
+
+ g_free(name);
+ }
+
+ g_dir_close(rdir);
+
+}
+
+/*****************************************************************************
+ * Public API functions *
+ *****************************************************************************/
+
+PurpleThemeManager *
+purple_theme_manager_new (PurpleThemeLoader *loader1, ...)
+{
+ PurpleThemeManager *self;
+ PurpleThemeManagerPrivate *priv;
+ va_list args;
+ PurpleThemeLoader *loader;
+
+ self = g_object_new(PURPLE_TYPE_THEME_MANAGER, NULL, NULL, NULL);
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ priv->theme_table = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ g_object_unref); /* purple_theme_finalize() ?*/
+
+ va_start(args, loader1);
+ for (loader = loader1; loader != NULL; loader = va_arg(args, PurpleThemeLoader *))
+ purple_theme_manager_register_type(self, loader);
+ va_end(args);
+
+ /* TODO: add themes properly */
+ purple_theme_manager_build(self, NULL);
+ return self;
+}
+
+
+void
+purple_theme_manager_register_type(PurpleThemeManager *self,
+ PurpleThemeLoader *loader)
+{
+ PurpleThemeManagerPrivate *priv = NULL;
+ gchar *type;
+
+ g_return_if_fail(PURPLE_IS_THEME_MANAGER(self));
+ g_return_if_fail(PURPLE_IS_THEME_LOADER(loader));
+
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ type = purple_theme_loader_get_type_string(loader);
+ g_return_if_fail(type);
+
+ /* if something is already there do nothing */
+ if(! g_hash_table_lookup (priv->theme_table, type))
+ g_hash_table_insert(priv->theme_table, type, loader);
+
+ g_free(type);
+}
+
+void
+purple_theme_manager_unregister_type(PurpleThemeManager *self,
+ PurpleThemeLoader *loader)
+{
+ PurpleThemeManagerPrivate *priv = NULL;
+ gchar *type;
+
+ g_return_if_fail(PURPLE_IS_THEME_MANAGER(self));
+ g_return_if_fail(PURPLE_IS_THEME_LOADER(loader));
+
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ type = purple_theme_loader_get_type_string(loader);
+ g_return_if_fail(type);
+
+ if(g_hash_table_lookup (priv->theme_table, type) == loader){
+
+ g_hash_table_remove (priv->theme_table, type);
+
+ g_hash_table_foreach_remove (priv->theme_table,
+ (GHRFunc) purple_theme_manager_is_theme_type,
+ type);
+ }/* only free if given registered loader */
+
+ g_free(type);
+}
+
+PurpleTheme *
+purple_theme_manager_find_theme(PurpleThemeManager *self,
+ const gchar *name,
+ const gchar *type)
+{
+ PurpleThemeManagerPrivate *priv = NULL;
+ g_return_val_if_fail(PURPLE_IS_THEME_MANAGER(self), NULL);
+ g_return_val_if_fail(name, NULL);
+ g_return_val_if_fail(type, NULL);
+
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+ return g_hash_table_lookup (priv->theme_table,
+ purple_theme_manager_make_key(name, type));
+}
+
+
+void
+purple_theme_manager_add_theme(PurpleThemeManager *self,
+ PurpleTheme *theme)
+{
+ PurpleThemeManagerPrivate *priv;
+ gchar *key;
+
+ g_return_if_fail(PURPLE_IS_THEME_MANAGER(self));
+ g_return_if_fail(PURPLE_IS_THEME(theme));
+
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ key = purple_theme_manager_make_key(purple_theme_get_name(theme),
+ purple_theme_get_type_string(theme));
+
+ g_return_if_fail(key);
+
+ /* if something is already there do nothing */
+ if(! g_hash_table_lookup (priv->theme_table, key))
+ g_hash_table_insert(priv->theme_table, key, theme);
+
+ g_free(key);
+}
+
+void
+purple_theme_manager_remove_theme(PurpleThemeManager *self,
+ PurpleTheme *theme)
+{
+ PurpleThemeManagerPrivate *priv = NULL;
+ gchar *key;
+
+ g_return_if_fail(PURPLE_IS_THEME_MANAGER(self));
+ g_return_if_fail(PURPLE_IS_THEME(theme));
+
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ key = purple_theme_manager_make_key(purple_theme_get_name(theme),
+ purple_theme_get_type_string(theme));
+
+ g_return_if_fail(key);
+
+ g_hash_table_remove(priv->theme_table, key);
+
+ g_free(key);
+}
+
+void
+purple_theme_manager_rebuild(PurpleThemeManager *self)
+{
+ PurpleThemeManagerPrivate *priv;
+
+ g_return_if_fail(PURPLE_IS_THEME_MANAGER(self));
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ g_hash_table_foreach_remove (priv->theme_table,
+ (GHRFunc) purple_theme_manager_is_theme,
+ NULL);
+
+ /* TODO: this also needs to be fixed the same as new */
+ purple_theme_manager_build(self, NULL);
+
+}
+
+void
+purple_theme_manager_for_each_theme(PurpleThemeManager *self, PTFunc func)
+{
+ PurpleThemeManagerPrivate *priv;
+
+ g_return_if_fail(PURPLE_IS_THEME_MANAGER(self));
+ g_return_if_fail(func);
+
+ priv = PURPLE_THEME_MANAGER_GET_PRIVATE(self);
+
+ g_hash_table_foreach(priv->theme_table,
+ (GHFunc) purple_theme_manager_function_wrapper,
+ func);
+}
+
============================================================
--- libpurple/theme-manager.h 0bb2b69f79597cb8e387533b2741db21128798d4
+++ libpurple/theme-manager.h 0bb2b69f79597cb8e387533b2741db21128798d4
@@ -0,0 +1,123 @@
+/**
+ * @file thememanager.h Theme Manager API
+ */
+
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 02111-1301 USA
+ */
+
+#ifndef __PURPLE_THEME_MANAGER_H__
+#define __PURPLE_THEME_MANAGER_H__
+
+#include <glib-object.h>
+#include <glib.h>
+#include "theme.h"
+#include "theme-loader.h"
+
+typedef void (*PTFunc) (PurpleTheme *theme);
+
+typedef struct _PurpleThemeManager PurpleThemeManager;
+typedef struct _PurpleThemeManagerClass PurpleThemeManagerClass;
+
+#define PURPLE_TYPE_THEME_MANAGER (purple_theme_manager_get_type ())
+#define PURPLE_THEME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_THEME_MANAGER, PurpleThemeManager))
+#define PURPLE_THEME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PURPLE_TYPE_THEME_MANAGER, PurpleThemeManagerClass))
+#define PURPLE_IS_THEME_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PURPLE_TYPE_THEME_MANAGER))
+#define PURPLE_IS_THEME_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PURPLE_TYPE_THEME_MANAGER))
+#define PURPLE_GET_THEME_MANAGER_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PURPLE_TYPE_THEME_MANAGER, PurpleThemeManagerClass))
+
+struct _PurpleThemeManager {
+ GObject parent;
+ gpointer priv;
+};
+
+struct _PurpleThemeManagerClass {
+ GObjectClass parent_class;
+};
+
+/**************************************************************************/
+/** @name Purple Theme Manager API */
+/**************************************************************************/
+G_BEGIN_DECLS
+
+/**
+ * GObject foo.
+ * @internal.
+ */
+GType purple_theme_manager_get_type (void);
+
+/**
+ * Creates a new ThemeManager object
+ * @param the loaders to initalize the manager with and use for first build
+ *
+ * @returns a new ThemeManager object
+ */
+PurpleThemeManager* purple_theme_manager_new (PurpleThemeLoader *loader1, ...);
+
+/**
+ * Finds the PurpleTheme object stored by the theme manager
+ *
+ * @param name the name of the PurpleTheme
+ * @param type the type of the PurpleTheme
+ *
+ * @returns The PurpleTheme or NULL if it wasn't found
+ */
+PurpleTheme *purple_theme_manager_find_theme(PurpleThemeManager *self, const gchar *name, const gchar *type);
+
+/**
+ * Adds a PurpleTheme to the theme manager, if the theme already exits it does nothing
+ *
+ * @param theme the PurpleTheme to add to the manager
+ */
+void purple_theme_manager_add_theme(PurpleThemeManager *self, PurpleTheme *theme);
+
+/**
+ * Removes a PurpleTheme from the theme manager, and frees the theme
+ * @param theme the PurpleTheme to remove from the manager
+ */
+void purple_theme_manager_remove_theme(PurpleThemeManager *self, PurpleTheme *theme);
+
+/**
+ * Addes a Loader to the theme manager so it knows how to build themes
+ * @param loader the PurpleThemeLoader to add
+ */
+void purple_theme_manager_register_type(PurpleThemeManager *self, PurpleThemeLoader *loader);
+
+/**
+ * Removes the loader and all themes of the same type from the loader
+ * @param loader the PurpleThemeLoader to be removed
+ */
+void purple_theme_manager_unregister_type(PurpleThemeManager *self, PurpleThemeLoader *loader);
+
+/**
+ * Rebuilds all the themes in the theme manaer
+ */
+void purple_theme_manager_rebuild(PurpleThemeManager *self);
+
+/**
+ * Calles the given function on each purple theme
+ *
+ * @param func the PTFunc to be applied to each theme
+ */
+void purple_theme_manager_for_each_theme(PurpleThemeManager *self, PTFunc func);
+
+G_END_DECLS
+#endif /* __PURPLE_THEME_MANAGER_H__ */
+
============================================================
--- libpurple/Makefile.am 67237da0a4b422fdb6f3dcf55e606567991557c6
+++ libpurple/Makefile.am f303c4628d63582dea49b767ac566ba9084b4f7c
@@ -79,6 +79,7 @@ purple_coresources = \
upnp.c \
theme.c \
theme-loader.c \
+ theme-manager.c \
util.c \
value.c \
version.c \
@@ -134,6 +135,7 @@ purple_coreheaders = \
upnp.h \
theme.h \
theme-loader.h \
+ theme-manager.h \
util.h \
value.h \
xmlnode.h \
============================================================
--- libpurple/theme-loader.c 5c8f63b790b05a81502e5cca758ee5d070ccdd35
+++ libpurple/theme-loader.c 5541acf5cb4e37ea4d02082297e1316b9e2c9b46
@@ -75,6 +75,7 @@ purple_theme_loader_class_init (PurpleTh
/* 2.4
* g_type_class_add_private(klass, sizeof(PurpleThemePrivate)); */
+
obj_class->get_property = purple_theme_loader_get_property;
More information about the Commits
mailing list