[gnome-db] Source Code - GdaDataModel to GtkTreeModel



Hi all, 

Yesterday, i created this source code, to convert a GdaDataModel to a
GtkTreeModel (based on a GtkListStore). This code is a draft :-) and it's
for my project (gcontacts on savannah.nongnu.org)

What do you think of my idea ?

If you want to use my example, you have to install MySQL with my
gcontacts.sql file.

I send you my ~/.libgda/config, my gcontacts.sql and the source code.

Thanks, 


Stephane.
#include <glib.h>
#include <gtk/gtk.h>
#include <libgda/libgda.h>
#include <libgnomedb/libgnomedb.h>

typedef struct _interface Interface;
typedef struct _field Field;
typedef struct _main_struct MainStruct;
typedef struct _query Query;


struct _interface {
	GtkWidget *treeview_groups;
	GtkWidget *treeview_contacts;
};

struct _query {
};

struct _main_struct {
	GdaClient *gda_client;
	GdaConnection *gda_connection;
	Interface *interface;
};

struct _field {
	gchar *name;
	gchar *alias;
	guint column;
	gboolean visible;
};

void selection_changed_cb (GtkTreeSelection *selection, MainStruct *main_struct);
void window_destroy_cb (GtkWidget *widget, MainStruct *main_struct);
void treeview_groups_create_columns (GtkTreeView *treeview);
void treeview_clear_model (GtkTreeView *treeview);
void treeview_update_model (GtkTreeView *treeview, GtkTreeModel *model);
GtkTreeModel *gda_model_to_gtk_tree_model (GdaDataModel *data_model);
void treeview_contacts_create_columns (GtkTreeView *treeview);
GdaDataModel *execute_query_select (GdaConnection *connection, gchar *query);
void do_stuff (MainStruct *main_struct);

Field *new_field (gchar *name, gchar *alias, guint column, gboolean visible)
{
	Field *field = NULL;
	field = g_try_malloc (sizeof (Field));
	if (field) {
		field->name = g_strdup (name);
		field->alias = ( alias ? g_strdup (alias) : NULL);
		field->column = column;
		field->visible = visible;
	}
	return field;
}

GSList *get_list_fields_groups (void)
{
	GSList *list = NULL;
	list = g_slist_append (list, (Field*) new_field ("id", "Identification", 0, FALSE));
	list = g_slist_append (list, (Field*) new_field ("name", "Group", 1, TRUE));
	list = g_slist_append (list, (Field*) new_field ("description", "Description", 2, TRUE));
	return list;
}

GSList *get_list_fields_contacts (void)
{
	GSList *list = NULL;
	list = g_slist_append (list, (Field*) new_field ("id_contact", "Identification", 0, FALSE));
	list = g_slist_append (list, (Field*) new_field ("firstname", "Firstname", 1, TRUE));
	list = g_slist_append (list, (Field*) new_field ("lastname", "Lastname", 2, TRUE));
	list = g_slist_append (list, (Field*) new_field ("email", "Email", 3, TRUE));
	return list;
}

void selection_changed_cb (GtkTreeSelection *selection, MainStruct *main_struct)
{
	GtkTreeIter iter;
	GtkTreeModel *model;
	gint id;
	gchar *query;

	if (! gtk_tree_selection_get_selected (selection, NULL, &iter)) 
		return; 

	model = gtk_tree_view_get_model (GTK_TREE_VIEW (main_struct->interface->treeview_groups));

	gtk_tree_model_get (model, &iter, 0, &id, -1);

	query = g_strdup_printf ("SELECT id_contact, firstname, lastname, email FROM contacts WHERE contacts.id_group = %d", id);
	if (query) {
		GdaDataModel *data_model_contacts = execute_query_select (main_struct->gda_connection, query);
		GtkTreeModel *model_contacts = gda_model_to_gtk_tree_model (data_model_contacts);
		g_object_unref (G_OBJECT (data_model_contacts));
		treeview_update_model (GTK_TREE_VIEW (main_struct->interface->treeview_contacts), model_contacts);
		g_object_unref (G_OBJECT (model_contacts));
	}
}

void window_destroy_cb (GtkWidget *widget, MainStruct *main_struct)
{
	if (GDA_IS_CLIENT (main_struct->gda_client)) {
		gda_client_close_all_connections (main_struct->gda_client);
		g_object_unref (G_OBJECT (main_struct->gda_client));
	}
	gnome_db_main_quit ();
}

void treeview_clear_model (GtkTreeView *treeview) 
{
	GtkTreeModel *model;
	g_return_if_fail (GTK_IS_TREE_VIEW (treeview));

	model = gtk_tree_view_get_model (treeview);
	if (model) 
		gtk_list_store_clear (GTK_LIST_STORE (model));
}

void treeview_update_model (GtkTreeView *treeview, GtkTreeModel *model) 
{
	g_return_if_fail (GTK_IS_TREE_VIEW (treeview));
	g_return_if_fail (GTK_IS_TREE_MODEL (model));
	treeview_clear_model (treeview);
	gtk_tree_view_set_model (treeview, model);
}

GType gda_value_type_to_gtype (GdaValueType gda_value_type)
{
	switch (gda_value_type) {
	case GDA_VALUE_TYPE_BIGINT:
	case GDA_VALUE_TYPE_BIGUINT:
		return G_TYPE_INT;
	case GDA_VALUE_TYPE_STRING:
		return G_TYPE_STRING;
	case GDA_VALUE_TYPE_BOOLEAN:
		return G_TYPE_BOOLEAN;
	default:
		return G_TYPE_NONE;
	}
}

GtkTreeModel *gda_model_to_gtk_tree_model (GdaDataModel *data_model)
{
	GtkListStore *store = NULL;
	GtkTreeIter iter;
	GdaFieldAttributes *field;
	const GdaValue *value;
	gchar *value_string;
	gint value_integer;
	gint count_row, count_column, nbr_max_rows, nbr_max_columns;

	g_return_val_if_fail (GDA_IS_DATA_MODEL (data_model), NULL);
	
	if (data_model) {
		GType *lst_type = NULL;
		guint nbr_max_columns;
		nbr_max_columns = gda_data_model_get_n_columns (data_model);
		
		lst_type = g_try_malloc (sizeof (GType) * nbr_max_columns);
		if (lst_type) {
			memset (lst_type, 0, sizeof (GType) * nbr_max_columns);
			for (count_column = 0; count_column < nbr_max_columns; count_column++) {
				field = gda_data_model_describe_column (data_model, count_column);
				if (field) 
					lst_type[count_column] = gda_value_type_to_gtype (field->gda_type);
			}
			store = gtk_list_store_newv (nbr_max_columns, lst_type);
			if (store) 
			{
				nbr_max_rows = gda_data_model_get_n_rows (data_model);
				for ( count_row = 0; count_row < nbr_max_rows; count_row++ ) {
					gtk_list_store_append (store, &iter);
					for ( count_column = 0; count_column < nbr_max_columns; count_column++) {
						value = gda_data_model_get_value_at (data_model, count_column, count_row);
						if (lst_type[count_column] == G_TYPE_STRING)
							gtk_list_store_set (store, &iter, count_column, (gchar*) gda_value_get_string (value), -1);
						if (lst_type[count_column] == G_TYPE_INT) 
							gtk_list_store_set (store, &iter, count_column, (gint) gda_value_get_bigint (value), -1);
						if (lst_type[count_column] == G_TYPE_BOOLEAN)
							gtk_list_store_set (store, &iter, count_column, (gboolean) gda_value_get_boolean (value), -1);
					}
				}
			}
			g_free (lst_type);
		}
	}

	return GTK_TREE_MODEL (store);
}


void treeview_create_columns (GtkTreeView *treeview, GSList *list_field)
{
	GtkTreeViewColumn *column;
	GtkCellRenderer *renderer;
	GSList *node;
	Field *field;

	g_return_if_fail (treeview);
	g_return_if_fail (list_field);

	for (node = list_field; node; node = g_slist_next (node)) {
		if (node->data) {
			field = (Field *) node->data; 
			renderer = gtk_cell_renderer_text_new ();
			if (renderer) {
				column = gtk_tree_view_column_new_with_attributes (field->alias, renderer, "text", field->column, NULL);
				if (column) {
					gtk_tree_view_append_column (treeview, column);
					gtk_tree_view_column_set_visible (column, field->visible);
				}
				
			}
		}
	}
}

GdaDataModel *execute_query_select (GdaConnection *connection, gchar *query)
{
	GdaDataModel *model = NULL;
	GdaCommand *command = NULL;

	g_return_val_if_fail (GDA_IS_CONNECTION (connection), NULL);

	command = gda_command_new (query, GDA_COMMAND_TYPE_SQL, GDA_COMMAND_OPTION_STOP_ON_ERRORS);
	if (command) {
		g_printf ("command : %s\n", gda_command_get_text (command));
		model = gda_connection_execute_single_command (connection, command, NULL);
		if (!model) 
		{
			g_warning ("Error avec gda_connection_execute_single_command");
		}
		gda_command_free (command);
	} 
	return GDA_DATA_MODEL (model);
}

void do_stuff (MainStruct *main_struct)
{
	GtkWidget *window;
	GtkWidget *vbox_main;
	GtkWidget *hbox;
	GtkWidget *sw;
	GtkTreeViewColumn *column;
	GtkCellRenderer *renderer;
	GtkTreeModel *model_groups;
	GtkTreeModel *model_contacts;
	GdaDataModel *data_model;
	GSList *list_field_group = NULL;
	GSList *list_field_contact = NULL;

	main_struct->gda_client = gda_client_new ();
	if (main_struct->gda_client) {
		main_struct->gda_connection = gda_client_open_connection (main_struct->gda_client, "gcontacts-localhost", NULL, NULL, GDA_CONNECTION_OPTIONS_READ_ONLY);
		if (main_struct->gda_connection) {
			data_model = execute_query_select (main_struct->gda_connection, "SELECT * FROM groups");
			if (data_model) {
				model_groups = gda_model_to_gtk_tree_model (data_model);
				g_object_unref (data_model);
			}
		}

		window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
		if (window) {
			gtk_widget_set_size_request (window, 800, 600);
			g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (window_destroy_cb), main_struct);
			
			vbox_main = gtk_vbox_new (FALSE, 10);
			if (vbox_main) {
				gtk_container_add (GTK_CONTAINER (window), vbox_main);
				
				hbox = gtk_hbox_new (FALSE, 10);
				if (hbox) {
					gtk_box_pack_start (GTK_BOX (vbox_main), hbox, TRUE, TRUE, 0);
					
					sw = gtk_scrolled_window_new (NULL, NULL);
					if (sw) {
						gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0);
						gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
						gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
						
						
						main_struct->interface->treeview_groups = gtk_tree_view_new ();
						if ( main_struct->interface->treeview_groups ) {
							gtk_container_add (GTK_CONTAINER (sw), main_struct->interface->treeview_groups);
//							model = treeview_groups_create_model ();
							if (model_groups) {
								treeview_update_model (GTK_TREE_VIEW (main_struct->interface->treeview_groups), model_groups);
								list_field_group = get_list_fields_groups ();
								treeview_create_columns (GTK_TREE_VIEW (main_struct->interface->treeview_groups), list_field_group);
							}

							GtkTreeSelection *selection;
							selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (main_struct->interface->treeview_groups));
							if (selection) {
								g_signal_connect (G_OBJECT (selection), "changed", G_CALLBACK (selection_changed_cb), main_struct);
								gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
							}
						}
					}
					
					sw = gtk_scrolled_window_new (NULL, NULL);
					if (sw) {
						gtk_box_pack_start (GTK_BOX (hbox), sw, TRUE, TRUE, 0);
						gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
						gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
						
						main_struct->interface->treeview_contacts = gtk_tree_view_new ();
						if (main_struct->interface->treeview_contacts) {
							gtk_container_add (GTK_CONTAINER (sw), main_struct->interface->treeview_contacts);
							list_field_contact = get_list_fields_contacts();
							treeview_create_columns (GTK_TREE_VIEW (main_struct->interface->treeview_contacts), list_field_contact);
						}
					}
				}
				GtkWidget *button;
				button = gtk_button_new_from_stock (GTK_STOCK_QUIT);
				g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (window_destroy_cb), main_struct);
				gtk_box_pack_start (GTK_BOX (vbox_main), button, FALSE, FALSE, 0);
			}
			gtk_widget_show_all (window);
		} else {
			gnome_db_main_quit ();
		} 
	} else {
		gnome_db_main_quit ();
	}
}

int main (int argc, char **argv)
{
	MainStruct *main_struct = NULL;
	main_struct = g_try_malloc (sizeof (MainStruct));
	if (main_struct) {
		memset (main_struct, 0, sizeof (MainStruct));
		main_struct->interface = g_try_malloc (sizeof (Interface));
		if (main_struct->interface) {
			memset (main_struct->interface, 0, sizeof (Interface));
			gnome_db_init ("test", "0.1", argc, argv);
			gnome_db_main_run ((GdaInitFunc) do_stuff, (MainStruct *) main_struct);
		}
	}
	return 0;
}
-- MySQL dump 9.10
--
-- Host: localhost    Database: gcontacts
-- ------------------------------------------------------
-- Server version	4.0.17

--
-- Table structure for table `contacts`
--

CREATE TABLE contacts (
  id_contact bigint(20) NOT NULL auto_increment,
  id_group bigint(20) NOT NULL default '0',
  firstname varchar(100) NOT NULL default '',
  lastname varchar(100) NOT NULL default '',
  sexe tinyint(1) NOT NULL default '0',
  email varchar(50) default NULL,
  PRIMARY KEY  (id_contact)
) TYPE=MyISAM;

--
-- Dumping data for table `contacts`
--

INSERT INTO contacts VALUES (1,1,'Gaetan','Guelette',1,'gaetan guelette ath cx');
INSERT INTO contacts VALUES (2,3,'Isabelle','Wirtel',0,'zaza_belle_9 hotmail com');
INSERT INTO contacts VALUES (3,4,'Michael','Simon',1,'simon mic tiscali be');
INSERT INTO contacts VALUES (4,3,'Laurent','Wirtel',1,'laurent_wirtel hotmail com');
INSERT INTO contacts VALUES (5,3,'Sarah','Damien',0,'sarah_dam_dam hotmail com');

--
-- Table structure for table `countries`
--

CREATE TABLE countries (
  id_num int(4) NOT NULL default '0',
  name varchar(50) NOT NULL default '',
  PRIMARY KEY  (id_num)
) TYPE=MyISAM;

--
-- Dumping data for table `countries`
--


--
-- Table structure for table `groups`
--

CREATE TABLE groups (
  id bigint(5) NOT NULL auto_increment,
  name varchar(25) NOT NULL default '',
  description varchar(200) default NULL,
  PRIMARY KEY  (id)
) TYPE=MyISAM;

--
-- Dumping data for table `groups`
--

INSERT INTO groups VALUES (1,'Friend','My list of friends');
INSERT INTO groups VALUES (2,'Work',NULL);
INSERT INTO groups VALUES (3,'Familly',NULL);
INSERT INTO groups VALUES (4,'School',NULL);
INSERT INTO groups VALUES (5,'Linux Users Groups',NULL);
INSERT INTO groups VALUES (6,'Linux-Mons','http://www.linux-mons.be');

--
-- Table structure for table `locations`
--

CREATE TABLE locations (
  id_localite bigint(20) NOT NULL default '0',
  zip_code bigint(20) NOT NULL default '0',
  name varchar(50) NOT NULL default '',
  id_country bigint(20) NOT NULL default '0',
  PRIMARY KEY  (id_localite)
) TYPE=MyISAM;

--
-- Dumping data for table `locations`
--


<?xml version="1.0"?>
<libgda-config>
  <section path="/apps/libgda/Datasources/gcontacts-localhost">
    <entry name="DSN" type="string" value="DATABASE=gcontacts"/>
    <entry name="Description" type="string" value="Database for gContacts"/>
    <entry name="Password" type="string" value="PASSWORD"/>
    <entry name="Provider" type="string" value="MySQL"/>
    <entry name="Username" type="string" value="USERNAME"/>
  </section>
</libgda-config>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]