[anjuta/symbol-db-model: 1/4] symbol-db: Added initial implementation of symbol-db tree model
- From: Naba Kumar <naba src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta/symbol-db-model: 1/4] symbol-db: Added initial implementation of symbol-db tree model
- Date: Thu, 11 Mar 2010 23:48:34 +0000 (UTC)
commit 4c1be5509d4dac89c65ad4d4a24ddd0347844cc8
Author: Naba Kumar <naba gnome org>
Date: Fri Mar 12 00:46:19 2010 +0200
symbol-db: Added initial implementation of symbol-db tree model
plugins/symbol-db/symbol-db-model.c | 826 +++++++++++++++++++++++++++++++++++
plugins/symbol-db/symbol-db-model.h | 89 ++++
2 files changed, 915 insertions(+), 0 deletions(-)
---
diff --git a/plugins/symbol-db/symbol-db-model.c b/plugins/symbol-db/symbol-db-model.c
new file mode 100644
index 0000000..e92369d
--- /dev/null
+++ b/plugins/symbol-db/symbol-db-model.c
@@ -0,0 +1,826 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * symbol-db-model.c
+ * Copyright (C) Naba Kumar 2010 <naba gnome org>
+ *
+ * anjuta 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.
+ *
+ * anjuta 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/>.
+ */
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <libgda/libgda.h>
+#include <libanjuta/anjuta-marshal.h>
+#include "symbol-db-model.h"
+
+#define SYMBOL_DB_MODEL_STAMP 5364558
+
+#define GET_PRIV(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), SYMBOL_DB_TYPE_MODEL, SymbolDBModelPriv))
+
+/* Constants */
+
+#define SYMBOL_DB_MODEL_PAGE_SIZE 100
+
+typedef struct _SymbolDBModelPage SymbolDBModelPage;
+struct _SymbolDBModelPage
+{
+ gint ref_count;
+ gint begin_offset, end_offset;
+ SymbolDBModelPage *next;
+};
+
+typedef struct _SymbolDBModelNode SymbolDBModelNode;
+struct _SymbolDBModelNode {
+ guint ref_count;
+
+ GValue *values;
+ SymbolDBModelPage *page_refs;
+
+ /* Data structure */
+ gint level;
+ SymbolDBModelNode *parent;
+ gint offset;
+ guint n_children;
+ SymbolDBModelNode **children;
+};
+
+typedef struct {
+ gint n_columns; /* Number of columns in the model */
+ GType *column_types; /* Type of each column in the model */
+ gint *query_columns; /* Corresponding GdaDataModel column */
+ gint node_id_column;
+ GHashTable *refed_nodes;
+ SymbolDBModelNode *root;
+} SymbolDBModelPriv;
+
+enum {
+ SIGNAL_GET_HAS_CHILD,
+ SIGNAL_GET_N_CHILDREN,
+ SIGNAL_GET_CHILDREN,
+ LAST_SIGNAL
+};
+
+static guint symbol_db_model_signals[LAST_SIGNAL] = { 0 };
+
+/* Declarations */
+
+static void symbol_db_model_tree_model_init (GtkTreeModelIface *iface);
+
+static gboolean symbol_db_model_get_query_value_at (SymbolDBModel *model,
+ GdaDataModel *data_model,
+ gint position, gint column,
+ GValue *value);
+
+static gboolean symbol_db_model_get_query_value (SymbolDBModel *model,
+ GdaDataModel *data_model,
+ GdaDataModelIter *iter,
+ gint column,
+ GValue *value);
+
+static void symbol_db_model_ensure_node_children (SymbolDBModel *model,
+ SymbolDBModelNode *parent);
+
+/* Class definition */
+G_DEFINE_TYPE_WITH_CODE (SymbolDBModel, symbol_db_model, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
+ symbol_db_model_tree_model_init))
+/* Node */
+
+#define symbol_db_model_node_get_child(node, offset) ((node)->children[(offset)])
+
+static SymbolDBModelNode *
+symbol_db_model_node_new (SymbolDBModel *model, SymbolDBModelNode *parent,
+ gint child_offset, GdaDataModel *data_model,
+ GdaDataModelIter *data_iter)
+{
+ gint i;
+ SymbolDBModelPriv *priv = GET_PRIV (model);
+ SymbolDBModelNode* node = g_new0 (SymbolDBModelNode, 1);
+ node->values = g_new0 (GValue, priv->n_columns);
+ for (i = 0; i < priv->n_columns; i++)
+ {
+ g_value_init (&(node->values[i]), priv->column_types[i]);
+ symbol_db_model_get_query_value (model,
+ data_model,
+ data_iter,
+ i, &(node->values[i]));
+ }
+ node->offset = child_offset;
+ node->parent = parent;
+ node->level = parent->level + 1;
+ return node;
+}
+
+/* SymbolDBModel implementation */
+
+static gboolean
+symbol_db_model_iter_is_valid (GtkTreeModel *model, GtkTreeIter *iter)
+{
+ SymbolDBModelNode *parent_node;
+ gint offset;
+
+ g_return_val_if_fail (SYMBOL_DB_IS_MODEL (model), FALSE);
+ g_return_val_if_fail (iter->stamp == SYMBOL_DB_MODEL_STAMP, FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ parent_node = (SymbolDBModelNode*) iter->user_data;
+ offset = GPOINTER_TO_INT (iter->user_data2);
+
+ g_return_val_if_fail (parent_node != NULL, FALSE);
+ g_return_val_if_fail (parent_node->children != NULL, FALSE);
+ g_return_val_if_fail (offset >= 0 && offset < parent_node->n_children,
+ FALSE);
+ return TRUE;
+}
+
+static SymbolDBModelPage*
+symbol_db_model_page_fault (SymbolDBModel *model,
+ SymbolDBModelNode *parent_node,
+ gint child_offset)
+{
+ SymbolDBModelPage *page, *prev_page;
+ gint i;
+ GdaDataModelIter *data_iter;
+ GdaDataModel *data_model = NULL;
+
+ page = parent_node->page_refs;
+
+ prev_page = NULL;
+
+ /* Find the page which holds result for given child_offset */
+ while (page)
+ {
+ if (child_offset >= page->begin_offset &&
+ child_offset < page->end_offset)
+ {
+ /* child_offset has associated page */
+ return page;
+ }
+ if (child_offset < page->begin_offset)
+ {
+ /* Insert point is here */
+ break;
+ }
+ prev_page = page;
+ page = page->next;
+ }
+
+ /* Insert after prev_page */
+
+ /* New page to cover current child_offset */
+ page = g_new0 (SymbolDBModelPage, 1);
+
+ /* Define page range */
+ page->begin_offset = child_offset - SYMBOL_DB_MODEL_PAGE_SIZE;
+ page->end_offset = child_offset + SYMBOL_DB_MODEL_PAGE_SIZE;
+
+ /* Insert the new page after prev_page */
+ if (prev_page)
+ {
+ page->next = prev_page->next;
+ prev_page->next = page;
+ }
+ else /* Insert at head */
+ {
+ page->next = parent_node->page_refs;
+ parent_node->page_refs = page;
+ }
+
+ /* Adjust boundries not to overlap with preceeding or following page */
+ if (prev_page && prev_page->end_offset > page->begin_offset)
+ page->begin_offset = prev_page->end_offset;
+
+ if (page->next && page->end_offset >= page->next->begin_offset)
+ page->end_offset = page->next->begin_offset;
+
+ /* Adjust boundries not to preceed 0 index */
+ if (page->begin_offset < 0)
+ page->begin_offset = 0;
+
+ /* Loada page from database */
+ g_signal_emit_by_name (model, "get-children", parent_node->level,
+ parent_node->values, page->begin_offset,
+ page->end_offset - page->begin_offset,
+ &data_model);
+
+ /* Fill up the page */
+ data_iter = gda_data_model_create_iter (data_model);
+ if (gda_data_model_iter_move_to_row (data_iter, 0))
+ {
+ for (i = page->begin_offset; i < page->end_offset; i++)
+ {
+ if (i >= parent_node->n_children)
+ {
+ /* FIXME: There are more rows in DB. Extend node */
+ break;
+ }
+ SymbolDBModelNode *node =
+ symbol_db_model_node_new (model, parent_node, i,
+ data_model, data_iter);
+ g_assert (symbol_db_model_node_get_child (parent_node, i) == NULL);
+ symbol_db_model_node_get_child (parent_node, i) = node;
+ if (!gda_data_model_iter_move_next (data_iter))
+ {
+ if (i < (page->end_offset - 1))
+ {
+ /* FIXME: There are fewer rows in DB. Shrink node */
+ }
+ break;
+ }
+ }
+ }
+
+ g_object_unref (data_iter);
+ g_object_unref (data_model);
+ return page;
+}
+
+/* GtkTreeModel implementation */
+
+static GtkTreeModelFlags
+symbol_db_model_get_flags (GtkTreeModel *tree_model)
+{
+ return GTK_TREE_MODEL_ITERS_PERSIST;
+}
+
+static GType
+symbol_db_model_get_column_type (GtkTreeModel *tree_model,
+ gint index)
+{
+ SymbolDBModelPriv *priv = GET_PRIV (tree_model);
+ g_return_val_if_fail (index < priv->n_columns, G_TYPE_INVALID);
+ return priv->column_types [index];
+}
+
+static gint
+symbol_db_model_get_n_columns (GtkTreeModel *tree_model)
+{
+ SymbolDBModelPriv *priv;
+ priv = GET_PRIV (tree_model);
+ return priv->n_columns;
+}
+
+static gboolean
+symbol_db_model_get_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ gint i;
+ SymbolDBModelNode *node, *parent_node;
+ gint depth, *indx;
+ SymbolDBModelPriv *priv;
+
+ g_return_val_if_fail (SYMBOL_DB_IS_MODEL(tree_model), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
+
+ depth = gtk_tree_path_get_depth (path);
+ g_return_val_if_fail (depth > 0, FALSE);
+
+ priv = GET_PRIV (tree_model);
+ indx = gtk_tree_path_get_indices (path);
+
+ /* Ensure root expansion */
+ if (priv->root->n_children == 0)
+ symbol_db_model_ensure_node_children (SYMBOL_DB_MODEL (tree_model),
+ priv->root);
+ if (priv->root->n_children == 0)
+ return FALSE;
+
+ parent_node = NULL;
+ node = priv->root;
+ for (i = 0; i < depth; i++)
+ {
+ parent_node = node;
+ if (node->children == NULL || node->n_children <= 0)
+ {
+ /* No child available */
+
+ /* FIXME: Do something more graceful like actually
+ * expanding the node and proceeding further.
+ */
+ break;
+ }
+ if (indx[i] >= node->n_children)
+ {
+ g_warning ("Invalid path to iter conversion; no children list found at depth %d", i);
+ break;
+ }
+ node = symbol_db_model_node_get_child (node, indx[i]);
+ }
+ if (i != depth)
+ {
+ g_warning ("Invalid path to iter conversion; no child found");
+ return FALSE;
+ }
+ iter->stamp = SYMBOL_DB_MODEL_STAMP;
+ iter->user_data = parent_node;
+ iter->user_data2 = GINT_TO_POINTER (indx[i-1]);
+
+ g_assert (symbol_db_model_iter_is_valid (tree_model, iter));
+
+ return TRUE;
+}
+
+static GtkTreePath*
+symbol_db_model_get_path (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ SymbolDBModelNode *node;
+ GtkTreePath* path;
+ SymbolDBModelPriv *priv;
+ gint offset;
+
+ g_return_val_if_fail (symbol_db_model_iter_is_valid (tree_model, iter),
+ NULL);
+
+ priv = GET_PRIV (tree_model);
+ path = gtk_tree_path_new ();
+
+ node = (SymbolDBModelNode*)iter->user_data;
+ offset = GPOINTER_TO_INT (iter->user_data);
+ do {
+ gtk_tree_path_prepend_index (path, offset);
+ node = node->parent;
+ offset = node->offset;
+ } while (node);
+ return path;
+}
+
+static void
+symbol_db_model_get_value (GtkTreeModel *tree_model,
+ GtkTreeIter *iter, gint column,
+ GValue *value)
+{
+ SymbolDBModelPriv *priv;
+ SymbolDBModelNode *parent_node, *node;
+ SymbolDBModelPage *page;
+ gint offset;
+
+ g_return_if_fail (symbol_db_model_iter_is_valid (tree_model, iter));
+
+ priv = GET_PRIV (tree_model);
+
+ g_return_if_fail (column >= 0);
+ g_return_if_fail (column < priv->n_columns);
+
+ parent_node = (SymbolDBModelNode*) iter->user_data;
+ offset = GPOINTER_TO_INT (iter->user_data2);
+
+ if (symbol_db_model_node_get_child (parent_node, offset) == NULL)
+ page = symbol_db_model_page_fault (SYMBOL_DB_MODEL (tree_model),
+ parent_node, offset);
+ node = symbol_db_model_node_get_child (parent_node, offset);
+ g_value_init (value, priv->column_types[column]);
+ g_return_if_fail (node != NULL);
+ g_value_copy (&(node->values[column]), value);
+}
+
+static gboolean
+symbol_db_model_iter_next (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ SymbolDBModelNode *node;
+ gint offset;
+
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (iter->stamp == SYMBOL_DB_MODEL_STAMP, FALSE);
+ g_return_val_if_fail (iter->user_data != NULL, FALSE);
+
+
+ node = (SymbolDBModelNode*)(iter->user_data);
+ offset = GPOINTER_TO_INT (iter->user_data2);
+ offset++;
+
+ if (offset >= node->n_children)
+ return FALSE;
+ iter->user_data2 = GINT_TO_POINTER (offset);
+
+ g_assert (symbol_db_model_iter_is_valid (tree_model, iter));
+
+ return TRUE;
+}
+
+static gboolean
+symbol_db_model_iter_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent)
+{
+ SymbolDBModelNode *node, *parent_node;
+ SymbolDBModelPriv *priv;
+
+ if (parent)
+ {
+ g_return_val_if_fail (symbol_db_model_iter_is_valid (tree_model,
+ parent),
+ FALSE);
+ }
+
+ g_return_val_if_fail (SYMBOL_DB_IS_MODEL(tree_model), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ priv = GET_PRIV (tree_model);
+ if (parent == NULL)
+ {
+ node = priv->root;
+ }
+ else
+ {
+ gint offset;
+ parent_node = (SymbolDBModelNode*) parent->user_data;
+ offset = GPOINTER_TO_INT (parent->user_data2);
+ node = symbol_db_model_node_get_child (parent_node, offset);
+ g_return_val_if_fail (node != NULL, FALSE);
+ }
+ g_return_val_if_fail (node->children != NULL, FALSE);
+ g_return_val_if_fail (node->n_children > 0, FALSE);
+
+ iter->user_data = node;
+ iter->user_data2 = GINT_TO_POINTER (0);
+ iter->stamp = SYMBOL_DB_MODEL_STAMP;
+
+ g_assert (symbol_db_model_iter_is_valid (tree_model, iter));
+
+ return TRUE;
+}
+
+static gboolean
+symbol_db_model_iter_has_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ gint offset;
+ SymbolDBModelNode *node, *parent_node;
+
+ g_return_val_if_fail (symbol_db_model_iter_is_valid (tree_model, iter),
+ FALSE);
+
+ parent_node = (SymbolDBModelNode*) iter->user_data;
+ offset = GPOINTER_TO_INT (iter->user_data2);
+
+ node = symbol_db_model_node_get_child (parent_node, offset);
+ if (node == NULL)
+ {
+ symbol_db_model_page_fault (SYMBOL_DB_MODEL (tree_model),
+ parent_node, offset);
+ node = symbol_db_model_node_get_child (parent_node, offset);
+ if (node == NULL)
+ return FALSE;
+ }
+
+ if (node->n_children <= 0)
+ symbol_db_model_ensure_node_children (SYMBOL_DB_MODEL (tree_model),
+ node);
+ return (node->n_children > 0);
+}
+
+static gint
+symbol_db_model_iter_n_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ gint offset;
+ SymbolDBModelNode *node, *parent_node;
+
+ g_return_val_if_fail (symbol_db_model_iter_is_valid (tree_model, iter),
+ FALSE);
+
+ parent_node = (SymbolDBModelNode*) iter->user_data;
+ offset = GPOINTER_TO_INT (iter->user_data2);
+
+ node = symbol_db_model_node_get_child (parent_node, offset);
+ if (node == NULL)
+ return 0;
+ return node->n_children;
+}
+
+static gboolean
+symbol_db_model_iter_nth_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ gint n)
+{
+ SymbolDBModelNode *node;
+ SymbolDBModelPriv *priv;
+
+ g_return_val_if_fail (SYMBOL_DB_IS_MODEL(tree_model), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (n >= 0, FALSE);
+
+ if (!symbol_db_model_iter_children (tree_model, iter, parent))
+ return FALSE;
+
+ priv = GET_PRIV (tree_model);
+ node = (SymbolDBModelNode*) (iter->user_data);
+
+ g_return_val_if_fail (n < node->n_children, FALSE);
+
+ iter->user_data2 = GINT_TO_POINTER (n);
+
+ g_assert (symbol_db_model_iter_is_valid (tree_model, iter));
+
+ return TRUE;
+}
+
+static gboolean
+symbol_db_model_iter_parent (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child)
+{
+ SymbolDBModelNode *parent_node;
+
+ g_return_val_if_fail (symbol_db_model_iter_is_valid (tree_model, child),
+ FALSE);
+
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ parent_node = (SymbolDBModelNode*) child->user_data;
+ g_return_val_if_fail (parent_node->parent != NULL, FALSE);
+
+ iter->user_data = parent_node->parent;
+ iter->user_data2 = GINT_TO_POINTER (parent_node->offset);
+ iter->stamp = SYMBOL_DB_MODEL_STAMP;
+
+ g_assert (symbol_db_model_iter_is_valid (tree_model, iter));
+
+ return TRUE;
+}
+
+static void
+symbol_db_model_ref_node (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+}
+
+static void
+symbol_db_model_unref_node (GtkTreeModel *tree_model, GtkTreeIter *iter)
+{
+}
+
+static void
+symbol_db_model_tree_model_init (GtkTreeModelIface *iface)
+{
+ iface->get_flags = symbol_db_model_get_flags;
+ iface->get_n_columns = symbol_db_model_get_n_columns;
+ iface->get_column_type = symbol_db_model_get_column_type;
+ iface->get_iter = symbol_db_model_get_iter;
+ iface->get_path = symbol_db_model_get_path;
+ iface->get_value = symbol_db_model_get_value;
+ iface->iter_next = symbol_db_model_iter_next;
+ iface->iter_children = symbol_db_model_iter_children;
+ iface->iter_has_child = symbol_db_model_iter_has_child;
+ iface->iter_n_children = symbol_db_model_iter_n_children;
+ iface->iter_nth_child = symbol_db_model_iter_nth_child;
+ iface->iter_parent = symbol_db_model_iter_parent;
+ iface->ref_node = symbol_db_model_ref_node;
+ iface->ref_node = symbol_db_model_unref_node;
+}
+
+/* SymbolDBModel implementation */
+
+static void
+symbol_db_model_ensure_node_children (SymbolDBModel *model,
+ SymbolDBModelNode *potential_parent)
+{
+ gint n_children;
+
+ /* FIXME: Should we free (properly) existing children instead? */
+ g_return_if_fail (potential_parent->children == NULL);
+ g_return_if_fail (potential_parent->n_children == 0);
+
+ g_signal_emit_by_name (model, "get-n-children",
+ potential_parent->level,
+ potential_parent->values,
+ &n_children);
+
+ potential_parent->n_children = n_children;
+ potential_parent->children = g_new0 (SymbolDBModelNode*, n_children);
+}
+
+static gboolean
+symbol_db_model_get_query_value_real (SymbolDBModel *model,
+ GdaDataModel *data_model,
+ GdaDataModelIter *iter, gint column,
+ GValue *value)
+{
+ const GValue *ret;
+ SymbolDBModelPriv *priv = GET_PRIV (model);
+ gint query_column = priv->query_columns[column];
+
+ if (query_column < 0)
+ return FALSE;
+
+ ret = gda_data_model_iter_get_value_at (iter, query_column);
+ if (!ret)
+ return FALSE;
+
+ g_value_copy (ret, value);
+ return FALSE;
+}
+
+static gboolean
+symbol_db_model_get_query_value (SymbolDBModel *model,
+ GdaDataModel *data_model,
+ GdaDataModelIter *iter, gint column,
+ GValue *value)
+{
+ return SYMBOL_DB_MODEL_GET_CLASS(model)->get_query_value(model, data_model,
+ iter, column,
+ value);
+}
+
+static gboolean
+symbol_db_model_get_query_value_at_real (SymbolDBModel *model,
+ GdaDataModel *data_model,
+ gint position, gint column,
+ GValue *value)
+{
+ const GValue *ret;
+ SymbolDBModelPriv *priv = GET_PRIV (model);
+ gint query_column = priv->query_columns[column];
+ g_value_init (value, priv->column_types[column]);
+
+ if (query_column < 0)
+ return FALSE;
+
+ ret = gda_data_model_get_value_at (data_model, query_column, position,
+ NULL);
+ if (!ret)
+ return FALSE;
+
+ g_value_copy (ret, value);
+ return FALSE;
+}
+
+static gboolean
+symbol_db_model_get_query_value_at (SymbolDBModel *model,
+ GdaDataModel *data_model,
+ gint position, gint column, GValue *value)
+{
+ return SYMBOL_DB_MODEL_GET_CLASS(model)->get_query_value_at (model,
+ data_model,
+ position,
+ column,
+ value);
+}
+
+/* Object implementation */
+
+static void
+symbol_db_model_finalize (GObject *object)
+{
+ /* FIXME */
+ G_OBJECT_CLASS (symbol_db_model_parent_class)->finalize (object);
+}
+
+static void
+symbol_db_model_set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ g_return_if_fail (SYMBOL_DB_IS_MODEL (object));
+ SymbolDBModel* model = SYMBOL_DB_MODEL(object);
+ SymbolDBModelPriv* priv = GET_PRIV (model);
+
+ switch (prop_id)
+ {
+ }
+}
+
+static void
+symbol_db_model_get_property (GObject *object, guint prop_id, GValue *value,
+ GParamSpec *pspec)
+{
+ g_return_if_fail (SYMBOL_DB_IS_MODEL (object));
+ SymbolDBModel* model = SYMBOL_DB_MODEL(object);
+ SymbolDBModelPriv* priv = GET_PRIV (model);
+
+ switch (prop_id)
+ {
+ }
+}
+
+static void
+symbol_db_model_init (SymbolDBModel *object)
+{
+ SymbolDBModelPriv *priv = GET_PRIV (object);
+ priv->root = g_new0 (SymbolDBModelNode, 1);
+ priv->n_columns = 0;
+ priv->column_types = NULL;
+ priv->query_columns = NULL;
+}
+
+static void
+symbol_db_model_class_init (SymbolDBModelClass *klass)
+{
+ GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+ klass->get_query_value = symbol_db_model_get_query_value_real;
+ klass->get_query_value_at = symbol_db_model_get_query_value_at_real;
+ object_class->finalize = symbol_db_model_finalize;
+ object_class->set_property = symbol_db_model_set_property;
+ object_class->get_property = symbol_db_model_get_property;
+
+ g_type_class_add_private (object_class, sizeof(SymbolDBModelPriv));
+
+ /* Signals */
+ symbol_db_model_signals[SIGNAL_GET_HAS_CHILD] =
+ g_signal_new ("get-has-child",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ anjuta_cclosure_marshal_BOOLEAN__INT_POINTER,
+ G_TYPE_BOOLEAN,
+ 2,
+ G_TYPE_INT,
+ G_TYPE_POINTER);
+ symbol_db_model_signals[SIGNAL_GET_N_CHILDREN] =
+ g_signal_new ("get-n-children",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ anjuta_cclosure_marshal_INT__INT_POINTER,
+ G_TYPE_INT,
+ 2,
+ G_TYPE_INT,
+ G_TYPE_POINTER);
+ symbol_db_model_signals[SIGNAL_GET_CHILDREN] =
+ g_signal_new ("get-children",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0, NULL, NULL,
+ anjuta_cclosure_marshal_OBJECT__INT_POINTER_INT_INT,
+ GDA_TYPE_DATA_MODEL,
+ 4,
+ G_TYPE_INT,
+ G_TYPE_POINTER,
+ G_TYPE_INT,
+ G_TYPE_INT);
+}
+
+void
+symbol_db_model_set_columns (SymbolDBModel *model, gint n_columns,
+ GType *types, gint *query_columns)
+{
+ SymbolDBModelPriv *priv;
+
+ g_return_if_fail (n_columns > 0);
+ priv = GET_PRIV (model);
+
+ g_return_if_fail (priv->n_columns <= 0);
+ g_return_if_fail (priv->column_types == NULL);
+ g_return_if_fail (priv->query_columns == NULL);
+
+ priv->n_columns = n_columns;
+ priv->column_types = g_new0(GType, n_columns);
+ priv->query_columns = g_new0(gint, n_columns);
+ memcpy (priv->column_types, types, n_columns * sizeof (GType));
+ memcpy (priv->query_columns, query_columns, n_columns * sizeof (gint));
+}
+
+GtkTreeModel *
+symbol_db_model_new (gint n_columns, ...)
+{
+ GtkTreeModel *model;
+ SymbolDBModelPriv *priv;
+ va_list args;
+ gint i;
+
+ g_return_val_if_fail (n_columns > 0, NULL);
+
+ model = g_object_new (SYMBOL_DB_TYPE_MODEL, NULL);
+ priv = GET_PRIV (model);
+
+ priv->n_columns = n_columns;
+ priv->column_types = g_new0(GType, n_columns);
+ priv->query_columns = g_new0(gint, n_columns);
+
+ va_start (args, n_columns);
+
+ for (i = 0; i < n_columns; i++)
+ {
+ priv->column_types[i] = va_arg (args, GType);
+ priv->query_columns[i] = va_arg (args, gint);
+ }
+ va_end (args);
+
+ return model;
+}
+
+GtkTreeModel*
+symbol_db_model_newv (gint n_columns, GType *types, gint *query_columns)
+{
+ GtkTreeModel *model;
+ g_return_val_if_fail (n_columns > 0, NULL);
+ model = g_object_new (SYMBOL_DB_TYPE_MODEL, NULL);
+ symbol_db_model_set_columns (SYMBOL_DB_MODEL (model), n_columns,
+ types, query_columns);
+ return model;
+}
+
diff --git a/plugins/symbol-db/symbol-db-model.h b/plugins/symbol-db/symbol-db-model.h
new file mode 100644
index 0000000..de6a8e7
--- /dev/null
+++ b/plugins/symbol-db/symbol-db-model.h
@@ -0,0 +1,89 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * symbol-db-model.h
+ * Copyright (C) Naba Kumar 2010 <naba gnome org>
+ *
+ * anjuta 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.
+ *
+ * anjuta 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/>.
+ */
+
+#ifndef _SYMBOL_DB_MODEL_H_
+#define _SYMBOL_DB_MODEL_H_
+
+#include <glib-object.h>
+#include <gtk/gtktreemodel.h>
+#include <libgda/gda-data-model.h>
+#include "symbol-db-engine.h"
+
+G_BEGIN_DECLS
+
+#define SYMBOL_DB_TYPE_MODEL (symbol_db_model_get_type ())
+#define SYMBOL_DB_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SYMBOL_DB_TYPE_MODEL, SymbolDBModel))
+#define SYMBOL_DB_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SYMBOL_DB_TYPE_MODEL, SymbolDBModelClass))
+#define SYMBOL_DB_IS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SYMBOL_DB_TYPE_MODEL))
+#define SYMBOL_DB_IS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SYMBOL_DB_TYPE_MODEL))
+#define SYMBOL_DB_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SYMBOL_DB_TYPE_MODEL, SymbolDBModelClass))
+
+typedef struct _SymbolDBModelClass SymbolDBModelClass;
+typedef struct _SymbolDBModel SymbolDBModel;
+
+struct _SymbolDBModelClass
+{
+ GObjectClass parent_class;
+
+ /* Virtual methods */
+ gboolean (*get_query_value) (SymbolDBModel *model,
+ GdaDataModel *data_model,
+ GdaDataModelIter *iter, gint column,
+ GValue *value);
+
+ gboolean (*get_query_value_at) (SymbolDBModel *model,
+ GdaDataModel *data_model, gint position,
+ gint column, GValue *value);
+
+ /* Pure virtual methods; alternatives to signals */
+
+ gboolean (*get_has_child) (SymbolDBModel *model, gint tree_level,
+ GValue column_values[]);
+
+ gint (*get_n_children) (SymbolDBModel *model, gint tree_level,
+ GValue column_values[]);
+
+ GdaDataModel* (*get_children) (SymbolDBModel *model, gint tree_level,
+ GValue column_values[],
+ gint offset, gint limit);
+};
+
+struct _SymbolDBModel
+{
+ GObject parent_instance;
+};
+
+GType symbol_db_model_get_type (void) G_GNUC_CONST;
+
+/* Use this to create the model normally. The "..." part is alternatively GType
+ * and gint for column type and corresponding GdaDataModel column.
+ */
+GtkTreeModel* symbol_db_model_new (gint n_columns, ...);
+
+/* Normally used by bindings */
+GtkTreeModel* symbol_db_model_newv (gint n_columns, GType *types,
+ gint *data_cols);
+
+/* Used by derived classes */
+void symbol_db_model_set_columns (SymbolDBModel *model, gint n_columns,
+ GType *types, gint *data_cols);
+
+G_END_DECLS
+
+#endif /* _SYMBOL_DB_MODEL_H_ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]