grim/guifications3

added the install prefix to gflib-genheader
cmake
2010-12-13, Gary Kramlich
999ee3e165df
added the install prefix to gflib-genheader
/*
* Guifications - The end-all, be-all notification framework
* Copyright (C) 2003-2009 Gary Kramlich <grim@reaperworld.com>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#include <gflib/gf_feed.h>
#include <gflib/gf_intl.h>
#include <gflib/gf_log.h>
#define GF_FEED_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GF_TYPE_FEED, GfFeedPrivate))
/******************************************************************************
* Structs
*****************************************************************************/
typedef struct {
gchar *name;
GfImage *image;
gchar *i18n;
gchar *description;
GfFeedManager *manager;
GHashTable *events;
} GfFeedPrivate;
/******************************************************************************
* Enums
*****************************************************************************/
enum {
PROP_ZERO = 0,
PROP_NAME,
PROP_IMAGE,
PROP_I18N,
PROP_DESCRIPTION,
PROP_MANAGER,
PROP_LAST
};
enum {
SIG_ADD,
SIG_REMOVE,
SIG_LAST
};
/******************************************************************************
* Globals
*****************************************************************************/
static GfObjectClass *parent_class = NULL;
static guint signals[SIG_LAST] = { 0, };
/******************************************************************************
* Private API
*****************************************************************************/
void
gf_feed_set_feed_manager(GfFeed *feed, GfFeedManager *feed_manager) {
GfFeedPrivate *priv = NULL;
priv = GF_FEED_GET_PRIVATE(feed);
if(GF_IS_FEED_MANAGER(priv->manager))
g_object_unref(G_OBJECT(priv->manager));
priv->manager =
GF_IS_FEED_MANAGER(feed_manager) ? g_object_ref(feed_manager) : NULL;
}
/******************************************************************************
* Feed Stuff
*****************************************************************************/
static void
gf_feed_set_name(GfFeed *feed, const gchar *name) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
priv->name = (name) ? g_strdup(name) : NULL;
}
static void
gf_feed_set_image(GfFeed *feed, GfImage *image) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
priv->image = (GF_IS_IMAGE(image)) ? g_object_ref(image) : NULL;
}
static void
gf_feed_set_i18n(GfFeed *feed, const gchar *i18n) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
priv->i18n = (i18n) ? g_strdup(i18n) : NULL;
}
static void
gf_feed_set_description(GfFeed *feed, const gchar *description) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
priv->description = (description) ? g_strdup(description) : NULL;
}
static gchar *
gf_feed_real_get_name(const GfFeed *feed) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
return (priv->name) ? g_strdup(priv->name) : NULL;
}
static GfImage *
gf_feed_real_get_image(const GfFeed *feed) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
return priv->image;
}
static gchar *
gf_feed_real_get_i18n(const GfFeed *feed) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
return (priv->i18n) ? g_strdup(priv->i18n) : NULL;
}
static gchar *
gf_feed_real_get_description(const GfFeed *feed) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
return (priv->description) ? g_strdup(priv->description) : NULL;
}
static GfEvent *
gf_feed_real_add_event(GfFeed *feed, GfEvent *event) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
const gchar *name = gf_event_get_name(event);
if(!name) {
gf_log_warning("GfFeed",
"Failed to add the event because it does not have a "
"name.\n");
return FALSE;
}
if(g_hash_table_lookup(priv->events, name)) {
gf_log_warning("GfFeed",
"Failed to add the event '%s' because it has already "
"beend added.\n", name);
return FALSE;
}
/* ref it for the hash table */
g_object_ref(event);
g_hash_table_insert(priv->events, g_strdup(name), event);
/* ref it to work like a subclassed feed, that would return a new remote
* event.
*/
g_object_ref(event);
return event;
}
static gboolean
gf_feed_real_remove_event(GfFeed *feed, GfEvent *event) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(feed);
const gchar *name = gf_event_get_name(event);
if(!name) {
gf_log_warning("GfFeed",
"Failed to remove the event because it does not have "
" a name.\n");
return FALSE;
}
if(!g_hash_table_lookup(priv->events, name)) {
gf_log_warning("GfFeed",
"Failed to remove the event '%s' because it has not "
"beed added.\n", name);
return FALSE;
}
g_hash_table_remove(priv->events, name);
return TRUE;
}
/******************************************************************************
* Object stuff
*****************************************************************************/
static void
gf_feed_get_property(GObject *obj, guint param_id, GValue *value,
GParamSpec *psec)
{
GfFeed *feed = GF_FEED(obj);
switch(param_id) {
case PROP_NAME:
g_value_set_string(value, gf_feed_get_name(feed));
break;
case PROP_IMAGE:
g_value_set_object(value, gf_feed_get_image(feed));
break;
case PROP_I18N:
g_value_set_string(value, gf_feed_get_i18n(feed));
break;
case PROP_DESCRIPTION:
g_value_set_string(value, gf_feed_get_description(feed));
break;
case PROP_MANAGER:
g_value_set_object(value, gf_feed_get_feed_manager(feed));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec);
break;
}
}
static void
gf_feed_set_property(GObject *obj, guint param_id, const GValue *value,
GParamSpec *psec)
{
GfFeed *feed = GF_FEED(obj);
switch(param_id) {
case PROP_NAME:
gf_feed_set_name(feed, g_value_get_string(value));
break;
case PROP_IMAGE:
gf_feed_set_image(feed, g_value_get_object(value));
break;
case PROP_I18N:
gf_feed_set_i18n(feed, g_value_get_string(value));
break;
case PROP_DESCRIPTION:
gf_feed_set_description(feed, g_value_get_string(value));
break;
case PROP_MANAGER:
gf_feed_set_feed_manager(feed, g_value_get_object(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, psec);
break;
}
}
static void
gf_feed_finalize(GObject *obj) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(obj);
g_free(priv->name);
if(GF_IS_IMAGE(priv->image))
g_object_unref(priv->image);
g_free(priv->i18n);
g_free(priv->description);
g_hash_table_destroy(priv->events);
G_OBJECT_CLASS(parent_class)->finalize(obj);
}
static void
gf_feed_class_init(GfFeedClass *klass) {
GObjectClass *obj_class = G_OBJECT_CLASS(klass);
parent_class = g_type_class_peek_parent(klass);
g_type_class_add_private(klass, sizeof(GfFeedPrivate));
obj_class->finalize = gf_feed_finalize;
obj_class->get_property = gf_feed_get_property;
obj_class->set_property = gf_feed_set_property;
klass->get_name = gf_feed_real_get_name;
klass->get_image = gf_feed_real_get_image;
klass->get_i18n = gf_feed_real_get_i18n;
klass->get_description = gf_feed_real_get_description;
klass->add_event = gf_feed_real_add_event;
klass->remove_event = gf_feed_real_remove_event;
g_object_class_install_property(
obj_class,
PROP_NAME,
g_param_spec_string(
"name",
P_("Name"),
P_("The name of this feed."),
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(
obj_class,
PROP_IMAGE,
g_param_spec_object(
"image",
P_("image"),
P_("The image for the feed."),
GF_TYPE_IMAGE,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(
obj_class,
PROP_I18N,
g_param_spec_string(
"i18n",
P_("i18n"),
P_("The translated name of this feed."),
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(
obj_class,
PROP_DESCRIPTION,
g_param_spec_string(
"description",
P_("Description"),
P_("The description of this feed."),
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(
obj_class,
PROP_MANAGER,
g_param_spec_object(
"manager",
P_("Manager"),
P_("The manager this feed is in."),
GF_TYPE_FEED_MANAGER,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
signals[SIG_ADD] =
g_signal_new("event-added",
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GfFeedClass, event_added),
NULL, NULL,
gf_marshal_VOID__OBJECT,
G_TYPE_NONE,
1, GF_TYPE_EVENT);
signals[SIG_REMOVE] =
g_signal_new("event-removed",
G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GfFeedClass, event_removed),
NULL, NULL,
gf_marshal_VOID__OBJECT,
G_TYPE_NONE,
1, GF_TYPE_EVENT);
}
static void
gf_feed_init(GTypeInstance *instance, gpointer g_class) {
GfFeedPrivate *priv = GF_FEED_GET_PRIVATE(instance);
priv->events = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_object_unref);
}
/******************************************************************************
* Feed API
*****************************************************************************/
GType
gf_feed_get_type(void) {
static GType type = 0;
if(type == 0) {
static const GTypeInfo info = {
sizeof(GfFeedClass),
NULL,
NULL,
(GClassInitFunc)gf_feed_class_init,
NULL,
NULL,
sizeof(GfFeed),
0,
gf_feed_init,
};
type = g_type_register_static(GF_TYPE_OBJECT,
"GfFeed",
&info, 0);
}
return type;
}
/**
* gf_feed_new:
* @name : The name of the feed.
* @image : The image the feed should use.
* @i18n : The translated name of the feed.
* @description : A short description of the feed.
*
* Creates a new #GfFeed Object.
*
* Return value: A newly created #GfFeed Object or #NULL.
*/
GfFeed *
gf_feed_new(const gchar *name, GfImage *image, const gchar *i18n,
const gchar *description)
{
g_return_val_if_fail(name, NULL);
g_return_val_if_fail(i18n, NULL);
return g_object_new(GF_TYPE_FEED,
"name", name,
"image", image,
"i18n", i18n,
"description", description,
NULL);
}
/**
* gf_feed_get_name:
* @feed : The #GfFeed.
*
* Gets the name from @feed.
*
* Note: This value must be freed.
*
* Return Value: The name of @feed or NULL.
*/
gchar *
gf_feed_get_name(const GfFeed *feed) {
GfFeedClass *klass;
g_return_val_if_fail(GF_IS_FEED(feed), NULL);
klass = GF_FEED_GET_CLASS(feed);
g_return_val_if_fail(GF_IS_FEED_CLASS(klass), NULL);
if(klass->get_name)
return klass->get_name(feed);
return NULL;
}
/**
* gf_feed_get_image:
* @feed: The #GfFeed Object.
*
* Gets the #GfImage associated with @feed.
*
* Return Value: The #GfImage associated with @feed or NULL.
*/
GfImage *
gf_feed_get_image(const GfFeed *feed) {
GfFeedClass *klass;
g_return_val_if_fail(GF_IS_FEED(feed), NULL);
klass = GF_FEED_GET_CLASS(feed);
g_return_val_if_fail(GF_IS_FEED_CLASS(klass), NULL);
if(klass->get_image)
return klass->get_image(feed);
return NULL;
}
/**
* gf_feed_get_i18n:
* @feed: The #GfFeed Object.
*
* Gets the translated name for @feed.
*
* Note: This value must be freed.
*
* Return Value: The translated name of @feed.
*/
gchar *
gf_feed_get_i18n(const GfFeed *feed) {
GfFeedClass *klass;
g_return_val_if_fail(GF_IS_FEED(feed), NULL);
klass = GF_FEED_GET_CLASS(feed);
g_return_val_if_fail(GF_IS_FEED_CLASS(klass), NULL);
if(klass->get_i18n)
return klass->get_i18n(feed);
return NULL;
}
/**
* gf_feed_get_description:
* @feed: The #GfFeed Object.
*
* Gets the description for @feed.
*
* Note: This value must be freed.
*
* Return Value: The description of @feed.
*/
gchar *
gf_feed_get_description(const GfFeed *feed) {
GfFeedClass *klass;
g_return_val_if_fail(GF_IS_FEED(feed), NULL);
klass = GF_FEED_GET_CLASS(feed);
g_return_val_if_fail(GF_IS_FEED_CLASS(klass), NULL);
if(klass->get_description)
return klass->get_description(feed);
return NULL;
}
/**
* gf_feed_add_event:
* @feed : The #GfFeed Object.
* @event: The #GfEvent to add.
*
* Adds @event to @feed.
*
* Return Value: Either a new #GfEvent for the original event with an extra
* reference or #NULL.
*/
GfEvent *
gf_feed_add_event(GfFeed *feed, GfEvent *event) {
GfFeedClass *klass = NULL;
GfEvent *ret = NULL;
g_return_val_if_fail(GF_IS_FEED(feed), NULL);
g_return_val_if_fail(GF_IS_EVENT(event), NULL);
klass = GF_FEED_GET_CLASS(feed);
g_return_val_if_fail(GF_IS_FEED_CLASS(klass), NULL);
g_object_ref(event);
if(klass->add_event)
ret = klass->add_event(feed, event);
if(GF_IS_EVENT(ret))
g_signal_emit_by_name(feed, "event-added", ret);
g_object_unref(event);
return ret;
}
/**
* gf_feed_remove_event:
* @feed : The #GfFeed Object.
* @event: The #GfEvent to remove.
*
* Removes @event from @feed.
*
* Return Value: TRUE on success, FALSE on failure.
*/
gboolean
gf_feed_remove_event(GfFeed *feed, GfEvent *event) {
GfFeedClass *klass = NULL;
gboolean ret = FALSE;
g_return_val_if_fail(GF_IS_FEED(feed), FALSE);
g_return_val_if_fail(GF_IS_EVENT(event), FALSE);
klass = GF_FEED_GET_CLASS(feed);
g_return_val_if_fail(GF_IS_FEED_CLASS(klass), FALSE);
g_object_ref(event);
if(klass->remove_event)
ret = klass->remove_event(feed, event);
if(ret)
g_signal_emit_by_name(feed, "event-removed", event);
g_object_unref(event);
return TRUE;
}
/**
* gf_feed_emit_event:
* @feed : The #GfFeed Object.
* @event_name: The name of the event.
* @event_info: The #GfEventInfo to use.
*
* Emits the #GfEvent named @event_name for @feed with the information in
* @event_info.
*/
void
gf_feed_emit_event(const GfFeed *feed, const gchar *event_name,
const GfEventInfo *event_info)
{
GfFeedPrivate *priv = NULL;
GfEvent *event = NULL;
g_return_if_fail(GF_IS_FEED(feed));
g_return_if_fail(event);
g_return_if_fail(GF_IS_EVENT_INFO(event_info));
priv = GF_FEED_GET_PRIVATE(feed);
event = g_hash_table_lookup(priv->events, event);
if(!GF_IS_EVENT(event)) {
gf_log_warning("GfFeed",
"Failed to emit event %s, "
"feed %s does not have this event.\n",
event_name, priv->name);
return;
}
if(!GF_IS_FEED_MANAGER(priv->manager)) {
gf_log_warning("GfFeed",
"Failed to emit event %s, "
"feed %s is not registered in a feed manager",
event_name, priv->name);
return;
}
gf_feed_manager_emit_event(priv->manager, feed, event, event_info);
}
typedef struct {
GfEvent **array;
guint index;
} ListData;
static void
gf_feed_list_events_helper(gpointer key, gpointer value, gpointer data) {
ListData *ld = (ListData *)data;
ld->array[ld->index++] = g_object_ref(value);
}
/**
* gf_feed_list_events:
* @feed : The #GfFeed instance.
* @nevents : The return address for the number of events.
*
* Returns a newly allocated array of #GfEvent's for the events in @feed.
*
* Return Value: A newly allocated array of #GfEvent's.
*/
GfEvent **
gf_feed_list_events(const GfFeed *feed, guint *nevents) {
GfFeedPrivate *priv = NULL;
ListData ld;
GfEvent **ret;
guint size;
g_return_val_if_fail(GF_IS_FEED(feed), NULL);
priv = GF_FEED_GET_PRIVATE(feed);
size = g_hash_table_size(priv->events);
ret = g_new0(GfEvent *, size + 1);
ld.array = ret;
ld.index = 0;
g_hash_table_foreach(priv->events, gf_feed_list_events_helper, &ld);
if(nevents)
*nevents = size;
return ret;
}
/**
* gf_feed_freev:
* @feeds: An array of #GfFeed's
*
* Free's an array of #GfFeed's
*/
void
gf_feed_freev(GfFeed **feeds) {
gint i;
g_return_if_fail(feeds);
for(i = 0; feeds[i]; i++)
g_object_unref(G_OBJECT(feeds[i]));
g_free(feeds);
}
/**
* gf_feed_get_feed_manager:
* @feed: The #GfFeed Object.
*
* Gets the #GfFeedManager to which @feed is registered.
*
* Return Value: The #GfFeedManager or NULL.
*/
GfFeedManager *
gf_feed_get_feed_manager(const GfFeed *feed) {
GfFeedPrivate *priv = NULL;
g_return_val_if_fail(GF_IS_FEED(feed), NULL);
priv = GF_FEED_GET_PRIVATE(feed);
return priv->manager;
}