From 42daac62c6ac1541212085e31bcc7e2e284e7207 Mon Sep 17 00:00:00 2001 From: Andrea Zagli Date: Tue, 30 Aug 2011 09:38:59 +0200 Subject: [PATCH] Ended printing from as GtkTreeModel. closes #35 --- .gitignore | 1 + configure.ac | 7 +- src/Makefile.am | 6 + src/reptool_marshal.list | 2 +- src/rptmarshal.c | 36 +-- src/rptmarshal.h | 14 +- src/rptreport.c | 383 ++++++++++++++++++++++--------- src/rptreport.h | 6 +- tests/Makefile.am | 6 +- tests/test_rptreport.c | 6 +- tests/test_rptreport_liststore.c | 121 ++++++++++ 11 files changed, 450 insertions(+), 138 deletions(-) create mode 100644 tests/test_rptreport_liststore.c diff --git a/.gitignore b/.gitignore index e1ac3ef..419f8c1 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ tests/test_report.rptr tests/test_rptprint tests/test_rptreport tests/test_rptreport_creation +tests/test_rptreport_liststore tests/test_report_created* tests/test_rptprint_mm.rptr tests/test_report_newline.rpt diff --git a/configure.ac b/configure.ac index 919e9e9..1ecd6c2 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT([libreptool], [0.2.0], [azagli@libero.it]) +AC_INIT([libreptool], [0.2.1], [azagli@libero.it]) AC_CONFIG_SRCDIR([src/rptprint.c]) AC_CONFIG_HEADER([config.h]) @@ -31,6 +31,11 @@ AC_PROG_LEX AC_PROG_LIBTOOL GTK_DOC_CHECK +dnl ****************************** +dnl glib-genmarshal +dnl ****************************** +AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal) + # Checks for libraries. PKG_CHECK_MODULES([REPTOOL], [gtk+-2.0 >= 2.10.0 libxml-2.0 >= 2.6.0 diff --git a/src/Makefile.am b/src/Makefile.am index 15c0e60..9f58721 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,6 +13,12 @@ lib_LTLIBRARIES = libreptool.la libreptool_la_LDFLAGS = -no-undefined +rptmarshal.c: rptmarshal.h reptool_marshal.list $(GLIB_GENMARSHAL) + $(GLIB_GENMARSHAL) reptool_marshal.list --body --prefix=_rpt_marshal > $@ + +rptmarshal.h: reptool_marshal.list $(GLIB_GENMARSHAL) + $(GLIB_GENMARSHAL) reptool_marshal.list --header --prefix=_rpt_marshal > $@ + libreptool_la_SOURCES = \ rptobject.c \ rptobjecttext.c \ diff --git a/src/reptool_marshal.list b/src/reptool_marshal.list index 2f8088f..e24fac2 100644 --- a/src/reptool_marshal.list +++ b/src/reptool_marshal.list @@ -1 +1 @@ -STRING:STRING,POINTER,INT +STRING:STRING,POINTER,INT,POINTER,POINTER diff --git a/src/rptmarshal.c b/src/rptmarshal.c index 3664552..803b1f0 100644 --- a/src/rptmarshal.c +++ b/src/rptmarshal.c @@ -21,6 +21,7 @@ #define g_marshal_value_peek_boxed(v) g_value_get_boxed (v) #define g_marshal_value_peek_pointer(v) g_value_get_pointer (v) #define g_marshal_value_peek_object(v) g_value_get_object (v) +#define g_marshal_value_peek_variant(v) g_value_get_variant (v) #else /* !G_ENABLE_DEBUG */ /* WARNING: This code accesses GValues directly, which is UNSUPPORTED API. * Do not access GValues directly in your code. Instead, use the @@ -44,30 +45,33 @@ #define g_marshal_value_peek_boxed(v) (v)->data[0].v_pointer #define g_marshal_value_peek_pointer(v) (v)->data[0].v_pointer #define g_marshal_value_peek_object(v) (v)->data[0].v_pointer +#define g_marshal_value_peek_variant(v) (v)->data[0].v_pointer #endif /* !G_ENABLE_DEBUG */ -/* STRING:STRING,POINTER,INT (reptool_marshal.list:1) */ +/* STRING:STRING,POINTER,INT,POINTER,POINTER (reptool_marshal.list:1) */ void -_rpt_marshal_STRING__STRING_POINTER_INT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data) +_rpt_marshal_STRING__STRING_POINTER_INT_POINTER_POINTER (GClosure *closure, + GValue *return_value G_GNUC_UNUSED, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint G_GNUC_UNUSED, + gpointer marshal_data) { - typedef gchar* (*GMarshalFunc_STRING__STRING_POINTER_INT) (gpointer data1, - gpointer arg_1, - gpointer arg_2, - gint arg_3, - gpointer data2); - register GMarshalFunc_STRING__STRING_POINTER_INT callback; + typedef gchar* (*GMarshalFunc_STRING__STRING_POINTER_INT_POINTER_POINTER) (gpointer data1, + gpointer arg_1, + gpointer arg_2, + gint arg_3, + gpointer arg_4, + gpointer arg_5, + gpointer data2); + register GMarshalFunc_STRING__STRING_POINTER_INT_POINTER_POINTER callback; register GCClosure *cc = (GCClosure*) closure; register gpointer data1, data2; gchar* v_return; g_return_if_fail (return_value != NULL); - g_return_if_fail (n_param_values == 4); + g_return_if_fail (n_param_values == 6); if (G_CCLOSURE_SWAP_DATA (closure)) { @@ -79,12 +83,14 @@ _rpt_marshal_STRING__STRING_POINTER_INT (GClosure *closure, data1 = g_value_peek_pointer (param_values + 0); data2 = closure->data; } - callback = (GMarshalFunc_STRING__STRING_POINTER_INT) (marshal_data ? marshal_data : cc->callback); + callback = (GMarshalFunc_STRING__STRING_POINTER_INT_POINTER_POINTER) (marshal_data ? marshal_data : cc->callback); v_return = callback (data1, g_marshal_value_peek_string (param_values + 1), g_marshal_value_peek_pointer (param_values + 2), g_marshal_value_peek_int (param_values + 3), + g_marshal_value_peek_pointer (param_values + 4), + g_marshal_value_peek_pointer (param_values + 5), data2); g_value_take_string (return_value, v_return); diff --git a/src/rptmarshal.h b/src/rptmarshal.h index 56bb519..665942c 100644 --- a/src/rptmarshal.h +++ b/src/rptmarshal.h @@ -6,13 +6,13 @@ G_BEGIN_DECLS -/* STRING:STRING,POINTER,INT (reptool_marshal.list:1) */ -extern void _rpt_marshal_STRING__STRING_POINTER_INT (GClosure *closure, - GValue *return_value, - guint n_param_values, - const GValue *param_values, - gpointer invocation_hint, - gpointer marshal_data); +/* STRING:STRING,POINTER,INT,POINTER,POINTER (reptool_marshal.list:1) */ +extern void _rpt_marshal_STRING__STRING_POINTER_INT_POINTER_POINTER (GClosure *closure, + GValue *return_value, + guint n_param_values, + const GValue *param_values, + gpointer invocation_hint, + gpointer marshal_data); G_END_DECLS diff --git a/src/rptreport.c b/src/rptreport.c index 5545421..7358297 100644 --- a/src/rptreport.c +++ b/src/rptreport.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 Andrea Zagli + * Copyright (C) 2007-2011 Andrea Zagli * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -51,6 +51,7 @@ typedef struct GdaDataModel *gda_datamodel; GtkTreeModel *treemodel; + GHashTable *columns_names; } Database; typedef struct @@ -192,6 +193,8 @@ rpt_report_class_init (RptReportClass *klass) * @field_name: the name of the field requested. * @data_model: a #GdaDataModel; or NULL if there's no database source. * @row: the current @data_model's row; -1 if @data_model is NULL. + * @treemodel: a #GtkTreeModel; or NULL if there's no #GtkTreeModel source. + * @iter: a #GtkTreeIter; or NULL if @treemodel is NULL. * * The signal is emitted each time there's into text's attribute source * a field that doesn't exists. @@ -202,12 +205,14 @@ rpt_report_class_init (RptReportClass *klass) 0, NULL, NULL, - _rpt_marshal_STRING__STRING_POINTER_INT, + _rpt_marshal_STRING__STRING_POINTER_INT_POINTER_POINTER, G_TYPE_STRING, - 3, + 5, G_TYPE_STRING, G_TYPE_POINTER, - G_TYPE_INT); + G_TYPE_INT, + G_TYPE_POINTER, + G_TYPE_POINTER); } static void @@ -648,7 +653,7 @@ rpt_report_set_database (RptReport *rpt_report, { g_free (priv->db); } - priv->db = (Database *)g_malloc0 (sizeof (Database)); + priv->db = (Database *)g_new0 (Database, 1); priv->db->provider_id = g_strstrip (g_strdup (provider_id)); priv->db->connection_string = g_strstrip (g_strdup (connection_string)); @@ -656,6 +661,7 @@ rpt_report_set_database (RptReport *rpt_report, priv->db->gda_conn = NULL; priv->db->gda_datamodel = NULL; priv->db->treemodel = NULL; + priv->db->columns_names = NULL; } /** @@ -674,6 +680,11 @@ rpt_report_set_database_from_datamodel (RptReport *rpt_report, GdaDataModel *dat if (priv->db != NULL) { + if (priv->db->columns_names != NULL) + { + g_hash_table_destroy (priv->db->columns_names); + } + g_free (priv->db); } priv->db = (Database *)g_new0 (Database, 1); @@ -684,26 +695,40 @@ rpt_report_set_database_from_datamodel (RptReport *rpt_report, GdaDataModel *dat priv->db->gda_conn = NULL; priv->db->gda_datamodel = data_model; priv->db->treemodel = NULL; + priv->db->columns_names = NULL; } /** * rpt_report_set_database_as_gtktreemodel: * @rpt_report: an #RptReport object. * @model: a #GtkTreeModel (for now only #GtkListStore is supported). + * @columns_names: * */ void -rpt_report_set_database_as_gtktreemodel (RptReport *rpt_report, GtkTreeModel *model) +rpt_report_set_database_as_gtktreemodel (RptReport *rpt_report, + GtkTreeModel *model, + GHashTable *columns_names) { g_return_if_fail (IS_RPT_REPORT (rpt_report)); - g_return_if_fail (GTK_IS_TREE_MODEL (rpt_report)); + g_return_if_fail (GTK_IS_TREE_MODEL (model)); + g_return_if_fail (columns_names != NULL); - g_return_if_fail (GTK_IS_LIST_STORE (rpt_report)); + g_return_if_fail (GTK_IS_LIST_STORE (model)); RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report); if (priv->db != NULL) { + if (priv->db->gda_datamodel != NULL) + { + g_object_unref (priv->db->gda_datamodel); + } + if (priv->db->gda_conn != NULL) + { + gda_connection_close_no_warning (priv->db->gda_conn); + } + g_free (priv->db); } priv->db = (Database *)g_new0 (Database, 1); @@ -714,6 +739,7 @@ rpt_report_set_database_as_gtktreemodel (RptReport *rpt_report, GtkTreeModel *mo priv->db->gda_conn = NULL; priv->db->gda_datamodel = NULL; priv->db->treemodel = model; + priv->db->columns_names = g_hash_table_ref (columns_names); } /** @@ -1342,128 +1368,225 @@ xmlDoc if (priv->db != NULL) { gint row; - gint rows; - /* database connection */ - gda_init (); - if (priv->db->gda_datamodel == NULL) + if (priv->db->treemodel != NULL) { - error = NULL; - priv->db->gda_conn = gda_connection_open_from_string (priv->db->provider_id, - priv->db->connection_string, - NULL, - GDA_CONNECTION_OPTIONS_NONE, - &error); - if (priv->db->gda_conn == NULL) + GtkTreeIter *iter_prec; + GtkTreeIter iter; + + if (!gtk_tree_model_get_iter_first (priv->db->treemodel, &iter)) { - /* TO DO */ - g_warning ("Unable to establish the connection: %s.", - error != NULL && error->message != NULL ? error->message : "no details"); + g_warning ("GtkTreeModel is empty."); return NULL; } - else - { - GdaSqlParser *parser = gda_sql_parser_new (); - error = NULL; - GdaStatement *stmt = gda_sql_parser_parse_string (parser, priv->db->sql, NULL, &error); - error = NULL; - priv->db->gda_datamodel = gda_connection_statement_execute_select (priv->db->gda_conn, stmt, NULL, &error); - if (priv->db->gda_datamodel == NULL) + row = 0; + do + { + priv->cur_iter = &iter; + if (row == 0 || + priv->body->new_page_after || + (priv->page_footer != NULL && (cur_y + priv->body->height > priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height)) || + cur_y > (priv->page->size->height - priv->page->margin->bottom)) { - /* TO DO */ - g_warning ("Unable to create the datamodel: %s", - error != NULL && error->message != NULL ? error->message : "no details"); - return NULL; + if (priv->cur_page > 0 && priv->page_footer != NULL) + { + if ((priv->cur_page == 1 && priv->page_footer->first_page) || + priv->cur_page > 1) + { + cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; + priv->cur_iter = iter_prec; + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); + priv->cur_iter = &iter; + } + } + + cur_y = priv->page->margin->top; + xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + + if (priv->page_header != NULL) + { + if ((priv->cur_page == 1 && priv->page_header->first_page) || + priv->cur_page > 1) + { + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_HEADER); + } + } + if (priv->cur_page == 1 && priv->report_header != NULL) + { + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_REPORT_HEADER); + if (priv->report_header->new_page_after) + { + cur_y = 0.0; + xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + } + } } - } - } - rows = gda_data_model_get_n_rows (priv->db->gda_datamodel); - for (row = 0; row < rows; row++) - { - priv->cur_row = row; - if (row == 0 || - priv->body->new_page_after || - (priv->page_footer != NULL && (cur_y + priv->body->height > priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height)) || - cur_y > (priv->page->size->height - priv->page->margin->bottom)) + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_BODY); + + iter_prec = g_memdup (&iter, sizeof (GtkTreeIter)); + row++; + } while (gtk_tree_model_iter_next (priv->db->treemodel, &iter)); + + priv->cur_iter = iter_prec; + if (priv->cur_page > 0 && priv->report_footer != NULL) { - if (priv->cur_page > 0 && priv->page_footer != NULL) + if ((cur_y + priv->report_footer->height > priv->page->size->height - priv->page->margin->bottom - (priv->page_footer != NULL ? priv->page_footer->height : 0.0)) || + priv->report_footer->new_page_before) { - if ((priv->cur_page == 1 && priv->page_footer->first_page) || - priv->cur_page > 1) + if (priv->page_header != NULL) + { + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_HEADER); + } + + cur_y = priv->page->margin->top; + xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + + if (priv->cur_page > 0 && priv->page_footer != NULL) { cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; - priv->cur_row = row - 1; rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); - priv->cur_row = row; } } - cur_y = priv->page->margin->top; - xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_REPORT_FOOTER); + } - if (priv->page_header != NULL) + if (priv->cur_page > 0 && priv->page_footer != NULL && priv->page_footer->last_page) + { + cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); + } + } + else + { + gint rows; + + /* database connection */ + gda_init (); + if (priv->db->gda_datamodel == NULL) + { + error = NULL; + priv->db->gda_conn = gda_connection_open_from_string (priv->db->provider_id, + priv->db->connection_string, + NULL, + GDA_CONNECTION_OPTIONS_NONE, + &error); + if (priv->db->gda_conn == NULL || error != NULL) { - if ((priv->cur_page == 1 && priv->page_header->first_page) || - priv->cur_page > 1) - { - rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_HEADER); - } + /* TO DO */ + g_warning ("Unable to establish the connection: %s.", + error != NULL && error->message != NULL ? error->message : "no details"); + return NULL; } - if (priv->cur_page == 1 && priv->report_header != NULL) + else { - rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_REPORT_HEADER); - if (priv->report_header->new_page_after) + GdaSqlParser *parser = gda_sql_parser_new (); + error = NULL; + GdaStatement *stmt = gda_sql_parser_parse_string (parser, priv->db->sql, NULL, &error); + + error = NULL; + priv->db->gda_datamodel = gda_connection_statement_execute_select (priv->db->gda_conn, stmt, NULL, &error); + if (priv->db->gda_datamodel == NULL || error != NULL) { - cur_y = 0.0; - xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + /* TO DO */ + g_warning ("Unable to create the datamodel: %s", + error != NULL && error->message != NULL ? error->message : "no details"); + return NULL; } } } - rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_BODY); - } - - if (priv->cur_page > 0 && priv->report_footer != NULL) - { - if ((cur_y + priv->report_footer->height > priv->page->size->height - priv->page->margin->bottom - (priv->page_footer != NULL ? priv->page_footer->height : 0.0)) || - priv->report_footer->new_page_before) + rows = gda_data_model_get_n_rows (priv->db->gda_datamodel); + for (row = 0; row < rows; row++) { - if (priv->page_header != NULL) + priv->cur_row = row; + if (row == 0 || + priv->body->new_page_after || + (priv->page_footer != NULL && (cur_y + priv->body->height > priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height)) || + cur_y > (priv->page->size->height - priv->page->margin->bottom)) { - priv->cur_row = row - 1; - rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_HEADER); - priv->cur_row = row; + if (priv->cur_page > 0 && priv->page_footer != NULL) + { + if ((priv->cur_page == 1 && priv->page_footer->first_page) || + priv->cur_page > 1) + { + cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; + priv->cur_row = row - 1; + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); + priv->cur_row = row; + } + } + + cur_y = priv->page->margin->top; + xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + + if (priv->page_header != NULL) + { + if ((priv->cur_page == 1 && priv->page_header->first_page) || + priv->cur_page > 1) + { + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_HEADER); + } + } + if (priv->cur_page == 1 && priv->report_header != NULL) + { + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_REPORT_HEADER); + if (priv->report_header->new_page_after) + { + cur_y = 0.0; + xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + } + } } - cur_y = priv->page->margin->top; - xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_BODY); + } - if (priv->cur_page > 0 && priv->page_footer != NULL) + if (priv->cur_page > 0 && priv->report_footer != NULL) + { + if ((cur_y + priv->report_footer->height > priv->page->size->height - priv->page->margin->bottom - (priv->page_footer != NULL ? priv->page_footer->height : 0.0)) || + priv->report_footer->new_page_before) { - cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; - priv->cur_row = row - 1; - rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); - priv->cur_row = row; + if (priv->page_header != NULL) + { + priv->cur_row = row - 1; + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_HEADER); + priv->cur_row = row; + } + + cur_y = priv->page->margin->top; + xpage = rpt_report_rptprint_new_page (rpt_report, xdoc); + + if (priv->cur_page > 0 && priv->page_footer != NULL) + { + cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; + priv->cur_row = row - 1; + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); + priv->cur_row = row; + } } + + priv->cur_row = row - 1; + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_REPORT_FOOTER); + priv->cur_row = row; + } + + if (priv->cur_page > 0 && priv->page_footer != NULL && priv->page_footer->last_page) + { + cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; + priv->cur_row = row - 1; + rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); + priv->cur_row = row; } - priv->cur_row = row - 1; - rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_REPORT_FOOTER); - priv->cur_row = row; - } - if (priv->cur_page > 0 && priv->page_footer != NULL && priv->page_footer->last_page) - { - cur_y = priv->page->size->height - priv->page->margin->bottom - priv->page_footer->height; - priv->cur_row = row - 1; - rpt_report_rptprint_section (rpt_report, xpage, &cur_y, RPTREPORT_SECTION_PAGE_FOOTER); - priv->cur_row = row; } /* change @Pages */ rpt_report_change_specials (rpt_report, xdoc); priv->cur_row = -1; + priv->cur_iter = NULL; } else { @@ -2458,40 +2581,68 @@ gchar const gchar *field_name) { GError *error; + gint col; + GValue *gval; + gchar *ret = NULL; RptReportPrivate *priv = RPT_REPORT_GET_PRIVATE (rpt_report); - if (priv->db != NULL && priv->db->gda_datamodel != NULL) + if (priv->db != NULL) { - col = gda_data_model_get_column_index (priv->db->gda_datamodel, field_name); - - if (col > -1) + if (priv->db->treemodel != NULL + && priv->db->columns_names != NULL) { - GValue *gval; + gchar *str_col; - error = NULL; - gval = (GValue *)gda_data_model_get_value_at (priv->db->gda_datamodel, col, priv->cur_row, &error); - if (error != NULL) + str_col = (gchar *)g_hash_table_lookup (priv->db->columns_names, field_name); + if (str_col != NULL) { - g_warning ("Error on retrieving field «%s» value: %s.", - field_name, - error->message != NULL ? error->message : "no details"); + str_col = g_strstrip (g_strdup (str_col)); + if (g_strcmp0 (str_col, "") != 0) + { + gval = g_new0 (GValue, 1); + + col = strtol (str_col, NULL, 10); + gtk_tree_model_get_value (priv->db->treemodel, priv->cur_iter, + col, gval); + + ret = (gchar *)gda_value_stringify (gval); + + g_value_unset (gval); + g_free (str_col); + } } - else + } + else if (priv->db->gda_datamodel != NULL) + { + col = gda_data_model_get_column_index (priv->db->gda_datamodel, field_name); + + if (col > -1) { - if (gda_value_is_null (gval)) + error = NULL; + gval = (GValue *)gda_data_model_get_value_at (priv->db->gda_datamodel, col, priv->cur_row, &error); + if (error != NULL) { - ret = g_strdup (""); + g_warning ("Error on retrieving field «%s» value: %s.", + field_name, + error->message != NULL ? error->message : "no details"); } else { - ret = (gchar *)gda_value_stringify (gval); - if (ret == NULL) + if (gda_value_is_null (gval)) { ret = g_strdup (""); } + else + { + ret = (gchar *)gda_value_stringify (gval); + if (ret == NULL) + { + ret = g_strdup (""); + } + } } } } @@ -2519,10 +2670,24 @@ gchar RptReportClass *klass = RPT_REPORT_GET_CLASS (rpt_report); - if (priv->db != NULL && priv->db->gda_datamodel != NULL) + if (priv->db != NULL) { - g_signal_emit (rpt_report, klass->field_request_signal_id, - 0, field, priv->db->gda_datamodel, priv->cur_row, &ret); + if (priv->db->gda_datamodel != NULL) + { + g_signal_emit (rpt_report, klass->field_request_signal_id, + 0, field, + priv->db->gda_datamodel, priv->cur_row, + NULL, NULL, + &ret); + } + else if (priv->db->treemodel != NULL) + { + g_signal_emit (rpt_report, klass->field_request_signal_id, + 0, field, + NULL, NULL, + priv->db->treemodel, priv->cur_iter, + &ret); + } } else { diff --git a/src/rptreport.h b/src/rptreport.h index 9b27daa..0f38a3a 100644 --- a/src/rptreport.h +++ b/src/rptreport.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 Andrea Zagli + * Copyright (C) 2007-2011 Andrea Zagli * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -86,7 +86,9 @@ void rpt_report_set_database (RptReport *rpt_report, void rpt_report_set_database_from_datamodel (RptReport *rpt_report, GdaDataModel *data_model); -void rpt_report_set_database_as_gtktreemodel (RptReport *rpt_report, GtkTreeModel *model); +void rpt_report_set_database_as_gtktreemodel (RptReport *rpt_report, + GtkTreeModel *model, + GHashTable *columns_names); RptSize *rpt_report_get_page_size (RptReport *rpt_report); void rpt_report_set_page_size (RptReport *rpt_report, diff --git a/tests/Makefile.am b/tests/Makefile.am index b491e5a..6f43e57 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -8,11 +8,13 @@ libreptool = $(top_builddir)/src/libreptool.la noinst_PROGRAMS = \ test_rptreport \ test_rptprint \ - test_rptreport_creation + test_rptreport_creation \ + test_rptreport_liststore LDADD = $(libreptool) EXTRA_DIST = \ test_report.rpt \ test_report_db.rpt \ - test_rptprint.rptr + test_rptprint.rptr \ + db_test.db diff --git a/tests/test_rptreport.c b/tests/test_rptreport.c index 98ad740..035ad3a 100644 --- a/tests/test_rptreport.c +++ b/tests/test_rptreport.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2011 Andrea Zagli + * Copyright (C) 2007-2011 Andrea Zagli * * 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 @@ -24,6 +24,8 @@ gchar gchar *field_name, GdaDataModel *data_model, gint row, + GtkTreeModel *treemodel, + GtkTreeIter *iter, gpointer user_data) { gchar *ret = NULL; @@ -67,6 +69,8 @@ main (int argc, char **argv) rptp = rpt_print_new_from_xml (rptprint); if (rptp != NULL) { + g_object_set (G_OBJECT (rptp), "path-relatives-to", "..", NULL); + rpt_print_set_output_type (rptp, RPT_OUTPUT_PDF); rpt_print_set_output_filename (rptp, "test.pdf"); rpt_print_print (rptp, NULL); diff --git a/tests/test_rptreport_liststore.c b/tests/test_rptreport_liststore.c new file mode 100644 index 0000000..cc9e22c --- /dev/null +++ b/tests/test_rptreport_liststore.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2011 Andrea Zagli + * + * 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 2 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 Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA + */ + +#include +#include + +gchar +*field_request (RptReport *rpt_report, + gchar *field_name, + GdaDataModel *data_model, + gint row, + GtkTreeModel *treemodel, + GtkTreeIter *iter, + gpointer user_data) +{ + gchar *ret = NULL; + + if (g_strcmp0 (field_name, "nonexistent") == 0 && + treemodel != NULL && + iter != NULL) + { + gint id; + gchar *name; + + gtk_tree_model_get (treemodel, iter, + 0, &id, + 1, &name, + -1); + + ret = g_strdup_printf ("%d - %s", id, name); + } + + return ret; +} + +int +main (int argc, char **argv) +{ + RptReport *rptr; + RptPrint *rptp; + + GtkListStore *model; + GtkTreeIter iter; + GHashTable *columns_names; + + g_type_init (); + + rptr = rpt_report_new_from_file (argv[1]); + + model = gtk_list_store_new (2, + G_TYPE_INT, + G_TYPE_STRING); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, 1, + 1, "Mary Jane Red", + -1); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, 2, + 1, "John Doe", + -1); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, 3, + 1, "Elene McArty", + -1); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + 0, 4, + 1, "Raul Bread", + -1); + + columns_names = g_hash_table_new (g_str_hash, g_str_equal); + g_hash_table_insert (columns_names, "id", "0"); + g_hash_table_insert (columns_names, "name", "1"); + + rpt_report_set_database_as_gtktreemodel (rptr, GTK_TREE_MODEL (model), columns_names); + + g_signal_connect (rptr, "field-request", G_CALLBACK (field_request), NULL); + + if (rptr != NULL) + { + xmlDoc *report = rpt_report_get_xml (rptr); + xmlSaveFormatFile ("test_report.rpt", report, 2); + + xmlDoc *rptprint = rpt_report_get_xml_rptprint (rptr); + xmlSaveFormatFile ("test_report.rptr", rptprint, 2); + + rptp = rpt_print_new_from_xml (rptprint); + if (rptp != NULL) + { + g_object_set (G_OBJECT (rptp), "path-relatives-to", "..", NULL); + + rpt_print_set_output_type (rptp, RPT_OUTPUT_PDF); + rpt_print_set_output_filename (rptp, "test.pdf"); + rpt_print_print (rptp, NULL); + } + } + + return 0; +} -- 2.49.0