/* * Copyright (C) 2012 - Juan Ferrer Toribio * * 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 . */ #include "sql-list.h" #include "sql-holder.h" /** * SECTION: sql-list * @Short_description: Container for a list of #SqlObject of a certain type * @Title: SqlList **/ G_DEFINE_TYPE (SqlList, sql_list, SQL_TYPE_OBJECT); SqlList * sql_list_new (GType gtype) { return g_object_new (SQL_TYPE_LIST, "gtype", gtype, NULL); } SqlList * sql_list_new_with_items (GType gtype, ...) { va_list vl; SqlObject * item; SqlList * obj = g_object_new (SQL_TYPE_LIST, "gtype", gtype, NULL); va_start (vl, gtype); while ((item = va_arg (vl, SqlObject *))) sql_list_add (obj, item); return obj; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void sql_list_render (SqlList * obj, SqlRender * render) { GList * i; for (i = obj->items.head; i; i = i->next) { sql_render_add_object (render, i->data); if (i->next) sql_render_append (render, ", "); } } static gboolean sql_list_is_ready (SqlList * obj) { GList * i; for (i = obj->items.head; i; i = i->next) if (!sql_object_is_ready (i->data)) return FALSE; return TRUE; } static void sql_list_find_holders (SqlList * obj, SqlBatch * batch) { GList * i; for (i = obj->items.head; i; i = i->next) sql_object_get_holders (i->data, batch); } static void sql_list_item_changed (SqlObject * item, SqlObject * obj) { sql_object_changed (obj); } static void sql_list_item_unref (SqlList * obj, SqlObject * item) { g_signal_handlers_disconnect_by_func (item, sql_list_item_changed, obj); g_object_unref (item); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Public /** * sql_list_add: * @obj: the #SqlList * @item: (allow-none): the #SqlObject * * Adds an item to the end of the list. **/ void sql_list_add (SqlList * obj, gpointer item) { g_return_if_fail (SQL_IS_LIST (obj)); sql_list_insert (obj, item, -1); } /** * sql_list_insert: * @obj: the #SqlList * @item: (allow-none): the #SqlObject * @index: the position in which to place the item * * Adds an item to the list. If position is a negative number the element will * be added to the end of the list. **/ void sql_list_insert (SqlList * obj, gpointer item, guint index) { g_return_if_fail (SQL_IS_LIST (obj)); g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (item, obj->gtype) || SQL_IS_HOLDER (item) || !item); if (!g_queue_find (&obj->items, item)) g_signal_connect (item, "changed", G_CALLBACK (sql_list_item_changed), obj); if (index > 0) g_queue_push_nth (&obj->items, g_object_ref_sink (item), index); else g_queue_push_tail (&obj->items, g_object_ref_sink (item)); } /** * sql_list_get: * @obj: the #SqlList * @index: the index of the item * * Gets an item from the list. * * Return value: (transfer none) (allow-none): the selected #SqlObject **/ gpointer sql_list_get (SqlList * obj, guint index) { g_return_val_if_fail (SQL_IS_LIST (obj), NULL); return g_queue_peek_nth (&obj->items, index); } /** * sql_list_remove: * @obj: the #SqlList * @index: the index of the item to remove * * Removes an item from the list. **/ void sql_list_remove (SqlList * obj, guint index) { SqlObject * item; g_return_val_if_fail (SQL_IS_LIST (obj), NULL); item = g_queue_pop_nth (&obj->items, index); if (!g_queue_find (&obj->items, item)) sql_list_item_unref (obj, item); } /** * sql_list_remove_item: * @obj: the #SqlList * @item: the item to remove * * Removes an item from the list. **/ void sql_list_remove_item (SqlList * obj, SqlObject * item) { g_return_if_fail (SQL_IS_LIST (obj)); g_return_if_fail (SQL_IS_OBJECT (item)); g_queue_remove_all (&obj->items, item); sql_list_item_unref (obj, item); } /** * sql_list_get_items: * @obj: the #SqlList * * Gets all list elements. * * Return value: (transfer none) (allow-none) (element-type Sql.Object): the * list items **/ GList * sql_list_get_items (SqlList * obj) { g_return_val_if_fail (SQL_IS_LIST (obj), NULL); return obj->items.head; } /** * sql_list_get_items_type: * @obj: the #SqlList * * Gets the allowed type for the list elements. * * Return value: the #GType **/ GType sql_list_get_items_type (SqlList * obj) { g_return_val_if_fail (SQL_IS_LIST (obj), 0); return obj->gtype; } /** * sql_list_lenght: * @obj: the #SqlList * * Gets the number of items in the list. * * Return value: the number of items **/ guint sql_list_length (SqlList * obj) { g_return_val_if_fail (SQL_IS_LIST (obj), 0); return obj->items.length; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Properties enum { PROP_GTYPE = 1 ,PROP_LENGTH }; static void sql_list_set_property (SqlList * obj, guint id, const GValue * value, GParamSpec * pspec) { switch (id) { case PROP_GTYPE: obj->gtype = g_value_get_gtype (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } } static void sql_list_get_property (SqlList * obj, guint id, GValue * value, GParamSpec * pspec) { switch (id) { case PROP_GTYPE: g_value_set_gtype (value, obj->gtype); break; case PROP_LENGTH: g_value_set_uint (value, sql_list_length (obj)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, id, pspec); } } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void sql_list_init (SqlList * obj) { g_queue_init (&obj->items); } static void sql_list_finalize (SqlList * obj) { GList * i; for (i = obj->items.head; i; i = i->next) { g_signal_handlers_disconnect_by_func (i->data, sql_list_item_changed, obj); g_object_unref (i->data); } g_queue_clear (&obj->items); G_OBJECT_CLASS (sql_list_parent_class)->finalize (G_OBJECT (obj)); } static void sql_list_class_init (SqlListClass * k) { GObjectClass * klass = G_OBJECT_CLASS (k); klass->finalize = (GObjectFinalizeFunc) sql_list_finalize; klass->set_property = (GObjectSetPropertyFunc) sql_list_set_property; klass->get_property = (GObjectGetPropertyFunc) sql_list_get_property; SQL_OBJECT_CLASS (klass)->render = (SqlRenderFunc) sql_list_render; SQL_OBJECT_CLASS (klass)->is_ready = (SqlObjectIsReadyFunc) sql_list_is_ready; SQL_OBJECT_CLASS (klass)->find_holders = (SqlObjectFindHoldersFunc) sql_list_find_holders; g_object_class_install_property (klass, PROP_LENGTH, g_param_spec_uint ("length" ,_("Length") ,_("The length of the list") ,0, G_MAXUINT, 0 ,G_PARAM_READABLE )); g_object_class_install_property (klass, PROP_GTYPE, g_param_spec_gtype ("gtype" ,_("GType") ,_("The allowed type for the items") ,SQL_TYPE_OBJECT ,G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY )); }