grim/guifications3
Clone
Summary
Browse
Changes
Graph
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
;
}