/* Copyright (C) 2008-2009 Christian Dywan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See the file COPYING for the full license text. */ #include "katze-item.h" #include "katze-utils.h" #include /** * SECTION:katze-item * @short_description: A useful item * @see_also: #KatzeArray * * #KatzeItem is a particularly useful item that provides * several commonly needed properties. */ G_DEFINE_TYPE (KatzeItem, katze_item, G_TYPE_OBJECT); enum { PROP_0, PROP_NAME, PROP_TEXT, PROP_URI, PROP_ICON, PROP_TOKEN, PROP_ADDED, PROP_PARENT }; enum { META_DATA_CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL]; static void katze_item_finalize (GObject* object); static void katze_item_set_property (GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); static void katze_item_get_property (GObject* object, guint prop_id, GValue* value, GParamSpec* pspec); static void katze_item_class_init (KatzeItemClass* class) { GObjectClass* gobject_class; GParamFlags flags; /** * KatzeItem::meta-data-changed: * @item: the object on which the signal is emitted * @key: the key that changed * * Emitted when a meta data value was changed. * * Since 0.2.2 details according to keys are supported. * * Since: 0.1.9 */ signals[META_DATA_CHANGED] = g_signal_new ( "meta-data-changed", G_TYPE_FROM_CLASS (class), (GSignalFlags)(G_SIGNAL_RUN_LAST |G_SIGNAL_DETAILED), 0, 0, NULL, g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); gobject_class = G_OBJECT_CLASS (class); gobject_class->finalize = katze_item_finalize; gobject_class->set_property = katze_item_set_property; gobject_class->get_property = katze_item_get_property; flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT; g_object_class_install_property (gobject_class, PROP_NAME, g_param_spec_string ( "name", "Name", "The name of the item", NULL, flags)); g_object_class_install_property (gobject_class, PROP_TEXT, g_param_spec_string ( "text", "Text", "The descriptive text of the item", NULL, flags)); g_object_class_install_property (gobject_class, PROP_URI, g_param_spec_string ( "uri", "URI", "The URI of the item", NULL, flags)); g_object_class_install_property (gobject_class, PROP_ICON, g_param_spec_string ( "icon", "Icon", "The icon of the item", NULL, flags)); g_object_class_install_property (gobject_class, PROP_TOKEN, g_param_spec_string ( "token", "Token", "The token of the item", NULL, flags)); g_object_class_install_property (gobject_class, PROP_ADDED, g_param_spec_int64 ( "added", "Added", "When the item was added", G_MININT64, G_MAXINT64, 0, flags)); /** * KatzeItem:parent: * * The parent of the item. * * Since: 0.1.2 */ g_object_class_install_property (gobject_class, PROP_PARENT, g_param_spec_object ( "parent", "Parent", "The parent of the item", G_TYPE_OBJECT, flags)); class->copy = NULL; } static void katze_item_init (KatzeItem* item) { item->metadata = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } static void katze_item_finalize (GObject* object) { KatzeItem* item = KATZE_ITEM (object); g_free (item->name); g_free (item->text); g_free (item->uri); g_free (item->icon); g_free (item->token); g_hash_table_unref (item->metadata); G_OBJECT_CLASS (katze_item_parent_class)->finalize (object); } static void katze_item_set_property (GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { KatzeItem* item = KATZE_ITEM (object); switch (prop_id) { case PROP_NAME: katze_assign (item->name, g_value_dup_string (value)); break; case PROP_TEXT: katze_assign (item->text, g_value_dup_string (value)); break; case PROP_URI: katze_assign (item->uri, g_value_dup_string (value)); break; case PROP_ICON: katze_assign (item->icon, g_value_dup_string (value)); break; case PROP_TOKEN: katze_assign (item->token, g_value_dup_string (value)); break; case PROP_ADDED: item->added = g_value_get_int64 (value); break; case PROP_PARENT: katze_item_set_parent (item, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void katze_item_get_property (GObject* object, guint prop_id, GValue* value, GParamSpec* pspec) { KatzeItem* item = KATZE_ITEM (object); switch (prop_id) { case PROP_NAME: g_value_set_string (value, item->name); break; case PROP_TEXT: g_value_set_string (value, item->text); break; case PROP_URI: g_value_set_string (value, item->uri); break; case PROP_ICON: g_value_set_string (value, item->icon); break; case PROP_TOKEN: g_value_set_string (value, item->token); break; case PROP_ADDED: g_value_set_int64 (value, item->added); break; case PROP_PARENT: g_value_set_object (value, item->parent); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /** * katze_item_new: * * Creates a new #KatzeItem. * * Return value: a new #KatzeItem **/ KatzeItem* katze_item_new (void) { KatzeItem* item = g_object_new (KATZE_TYPE_ITEM, NULL); return item; } /** * katze_item_get_name: * @item: a #KatzeItem * * Retrieves the name of @item. * * Return value: the name of the item **/ const gchar* katze_item_get_name (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); return item->name; } /** * katze_item_set_name: * @item: a #KatzeItem * @name: a string * * Sets the name of @item. **/ void katze_item_set_name (KatzeItem* item, const gchar* name) { g_return_if_fail (KATZE_IS_ITEM (item)); katze_assign (item->name, g_strdup (name)); g_object_notify (G_OBJECT (item), "name"); } /** * katze_item_get_text: * @item: a #KatzeItem * * Retrieves the descriptive text of @item. * * Return value: the text of the item **/ const gchar* katze_item_get_text (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); return item->text; } /** * katze_item_set_text: * @item: a #KatzeItem * @description: a string * * Sets the descriptive text of @item. **/ void katze_item_set_text (KatzeItem* item, const gchar* text) { g_return_if_fail (KATZE_IS_ITEM (item)); katze_assign (item->text, g_strdup (text)); g_object_notify (G_OBJECT (item), "text"); } /** * katze_item_get_uri: * @item: a #KatzeItem * * Retrieves the URI of @item. * * Return value: the URI of the item **/ const gchar* katze_item_get_uri (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); return item->uri; } /** * katze_item_set_uri: * @item: a #KatzeItem * @uri: a string * * Sets the URI of @item. **/ void katze_item_set_uri (KatzeItem* item, const gchar* uri) { g_return_if_fail (KATZE_IS_ITEM (item)); katze_assign (item->uri, g_strdup (uri)); g_object_notify (G_OBJECT (item), "uri"); } /** * katze_item_get_icon: * @item: a #KatzeItem * * Retrieves the icon of @item. * * Return value: the icon of the item **/ const gchar* katze_item_get_icon (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); return item->icon; } /** * katze_item_set_icon: * @item: a #KatzeItem * @icon: a string * * Sets the icon of @item. **/ void katze_item_set_icon (KatzeItem* item, const gchar* icon) { g_return_if_fail (KATZE_IS_ITEM (item)); katze_assign (item->icon, g_strdup (icon)); g_object_notify (G_OBJECT (item), "icon"); } /** * katze_item_get_token: * @item: a #KatzeItem * * Retrieves the token of @item. * * Return value: the token of the item **/ const gchar* katze_item_get_token (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); return item->token; } /** * katze_item_set_token: * @item: a #KatzeItem * @token: a string * * Sets the token of @item. **/ void katze_item_set_token (KatzeItem* item, const gchar* token) { g_return_if_fail (KATZE_IS_ITEM (item)); katze_assign (item->token, g_strdup (token)); g_object_notify (G_OBJECT (item), "token"); } /** * katze_item_get_added: * @item: a #KatzeItem * * Determines when @item was added. * * Return value: a timestamp **/ gint64 katze_item_get_added (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), 0); return item->added; } /** * katze_item_set_added: * @item: a #KatzeItem * @added: a timestamp * * Sets when @item was added. **/ void katze_item_set_added (KatzeItem* item, gint64 added) { g_return_if_fail (KATZE_IS_ITEM (item)); item->added = added; g_object_notify (G_OBJECT (item), "added"); } /** * katze_item_get_meta_keys: * @item: a #KatzeItem * * Retrieves a list of all meta keys. * * Return value: a newly allocated #GList of constant strings * * Since: 0.1.8 **/ GList* katze_item_get_meta_keys (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); return g_hash_table_get_keys (item->metadata); } static void katze_item_set_meta_data_value (KatzeItem* item, const gchar* key, gchar* value) { /* FIXME: Make the default namespace configurable */ if (g_str_has_prefix (key, "midori:")) g_hash_table_insert (item->metadata, g_strdup (&key[7]), value); else g_hash_table_insert (item->metadata, g_strdup (key), value); g_signal_emit (item, signals[META_DATA_CHANGED], g_quark_from_string (key), key); } /** * katze_item_get_meta_string: * @item: a #KatzeItem * @key: the name of an integer value * * Retrieves a string value by the specified key from the * meta data of the item. * * Specify "namespace:key" or "key" to use the default namespace. * * Return value: a string, or %NULL * * Since: 0.1.8 **/ const gchar* katze_item_get_meta_string (KatzeItem* item, const gchar* key) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); g_return_val_if_fail (key != NULL, NULL); if (g_str_has_prefix (key, "midori:")) key = &key[7]; return g_hash_table_lookup (item->metadata, key); } /** * katze_item_set_meta_string: * @item: a #KatzeItem * @key: the name of a string value * @value: the value as a string * * Saves the specified string value in the meta data of * the item under the specified key. * * Specify "namespace:key" or "key" to use the default namespace. * * Since: 0.1.8 **/ void katze_item_set_meta_string (KatzeItem* item, const gchar* key, const gchar* value) { g_return_if_fail (KATZE_IS_ITEM (item)); g_return_if_fail (key != NULL); katze_item_set_meta_data_value (item, key, g_strdup (value)); } /** * katze_item_get_meta_integer: * @item: a #KatzeItem * @key: the name of an integer value * * Retrieves an integer value by the specified key from the * meta data of the item. * * If the key is present but not representable as an * integer, -1 is returned. * * Return value: an integer value, or -1 * * Since: 0.1.8 **/ gint64 katze_item_get_meta_integer (KatzeItem* item, const gchar* key) { gpointer value; g_return_val_if_fail (KATZE_IS_ITEM (item), -1); g_return_val_if_fail (key != NULL, -1); if (g_str_has_prefix (key, "midori:")) key = &key[7]; if (g_hash_table_lookup_extended (item->metadata, key, NULL, &value)) return value ? g_ascii_strtoll (value, NULL, 0) : -1; return -1; } /** * katze_item_set_meta_integer: * @item: a #KatzeItem * @key: the name of an integer value * * Saves the specified integer value in the meta data of * the item under the specified key. * * A value of -1 is intepreted as unset. * * Since: 0.1.8 **/ void katze_item_set_meta_integer (KatzeItem* item, const gchar* key, gint64 value) { g_return_if_fail (KATZE_IS_ITEM (item)); g_return_if_fail (key != NULL); if (value == -1) katze_item_set_meta_data_value (item, key, NULL); else { katze_item_set_meta_data_value (item, key, #ifdef G_GINT64_FORMAT g_strdup_printf ("%" G_GINT64_FORMAT, value)); #else g_strdup_printf ("%li", value)); #endif } } /** * katze_item_get_parent: * @item: a #KatzeItem * * Determines the parent of @item. * * Since 0.1.2 you can monitor the "parent" property. * * Return value: the parent of the item **/ gpointer katze_item_get_parent (KatzeItem* item) { g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); return item->parent; } /** * katze_item_set_parent: * @item: a #KatzeItem * @parent: the new parent * * Sets the parent of @item. * * This is intended for item container implementations. Notably * the new parent will not be notified of the change. * * Since 0.1.2 you can monitor the "parent" property, so unsetting * the parent is actually safe if the parent supports it. **/ void katze_item_set_parent (KatzeItem* item, gpointer parent) { g_return_if_fail (KATZE_IS_ITEM (item)); g_return_if_fail (!parent || G_IS_OBJECT (parent)); if (parent) g_object_ref (parent); katze_object_assign (item->parent, parent); g_object_notify (G_OBJECT (item), "parent"); } /** * katze_item_copy: * @item: a #KatzeItem * * Creates an exact copy of @item. * * Note that subclass specific features will only * be preserved if the class implements it. * * Return value: a new #KatzeItem * * Since: 0.1.3 **/ KatzeItem* katze_item_copy (KatzeItem* item) { KatzeItem* copy; KatzeItemClass* class; g_return_val_if_fail (KATZE_IS_ITEM (item), NULL); copy = g_object_new (G_OBJECT_TYPE (item), "name", item->name, "text", item->text, "uri", item->uri, "icon", item->icon, "token", item->token, "added", item->added, "parent", item->parent, NULL); class = KATZE_ITEM_GET_CLASS (item); return class->copy ? class->copy (copy) : copy; }