only for RuBoard - do not distribute or recompile |
This report in Listing 12.4 is a simple tabular report that uses a modified version of the The Data Display Control (DDC) from Chapters 8, Commission Calculations Abstract and Design, 9, Constructing the Commissions Application, and 10, Commission Calculations Deployment. In this incarnation, it will not be dynamically created and destroyed as it was in the WCA application, but instead it will query and display the data once as stated by the report definition (show top salespeople).
/* The following line is needed for compilation * on Windows - comment the line out for Linux gcc. */ //#include <windows.h> #ifdef HAVE_CONFIG_H # include <config.h> #endif #include <gdk/gdkkeysyms.h> #include <gtk/gtk.h> #include <mysql.h> #include "callbacks.h" #include "interface.h" #include "support.h" /* The following is the updated version of the ddc. The * added parameters allow it to be much more flexible and * portable to other applications . * / GtkWidget *create_ddc (gchar *table_name, gchar *server_name, gchar *user_name, gchar *user_pwd, gchar *db_name, GtkWidget *frm_target) { MYSQL *conx; GtkWidget *scrolledwindow1; GtkWidget *clist_table; GtkWidget *label; gint counter; gint cols = 3; gchar *sql; MYSQL_RES *result_set; MYSQL_ROW db_row; MYSQL_FIELD *field; gchar *row[20] = {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}; scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_show (scrolledwindow1); conx = mysql_init((MYSQL *)0L); if (conx == 0L) { g_print("mysql_init failure...\n"); return 0L; } mysql_real_connect (conx, server_name, user_name, user_pwd, db_name, 0, 0L, 0); if (conx == 0L) { g_print("mysql_real_connect failure...\n"); return 0L; } sql = g_strconcat("select * from ", table_name, 0L); g_print("sql is: %s\n", sql); if (mysql_query (conx, sql) != 0) { g_print("query failure...\n"); return 0L; } result_set = mysql_store_result (conx); cols = mysql_num_fields (result_set); clist_table = gtk_clist_new (cols); gtk_object_set_data_full(GTK_OBJECT(frm_target), "clist_table", clist_table, 0L); gtk_widget_show (clist_table); gtk_container_add (GTK_CONTAINER (scrolledwindow1), clist_table); gtk_clist_column_titles_show (GTK_CLIST (clist_table); /* First iterate through the columns. */ for (counter = 0; counter < cols; counter++) { mysql_field_seek(result_set, counter); field = mysql_fetch_field(result_set); label = gtk_label_new (field->name); gtk_widget_show (label); gtk_clist_set_column_widget (GTK_CLIST (clist_table), counter, label); gtk_clist_set_column_width (GTK_CLIST (clist_table), counter, 80); } /* Then iterate through the rows. */ while ((db_row = mysql_fetch_row (result_set)) != 0L) { for (counter = 0; counter < cols; counter++) { row[counter] = db_row[counter]; } gtk_clist_append(GTK_CLIST(clist_table), row); } mysql_close(conx); return scrolledwindow1; }
Listing 12.5 contains the callbacks for the tabular form. Listings 12.4 and 12.5 are the most important parts of the tabular report for the KBI application (although other support files are listed in Appendix C).
#ifdef HAVE_CONFIG_H # include <config.h> #endif #include <gtk/gtk.h> #include <mysql.h> #include "callbacks.h" #include "interface.h" #include "support.h" #include "ddc.h" GtkWidget *frm_tabular; void on_frm_tabular_show (GtkWidget *widget, gpointer user_data) { gchar *sql; MYSQL *conx; GtkWidget *scrolledwindow1; GtkWidget *statusbar1; /* When frm_tabular opens, it needs to show the top salespeople * in descending order of commissions paid. * For it to do that, this routine must do the following things * in this order: * * In the "commish" database: * 1. Drop table tbl_top_salespeople if it exists. * 2. Create tbl_top_salespeople by drawing data from tbl_commissions . * 3. Select from the recently created tbl_top_salespeople . * * Of course, the first two steps could be added to * the WCA application of Chapters 8, 9, and 10 as a final * step, and then it wouldn't be needed here. */ g_print("on_frm_tabular_show.\n"); /* First, connect to the database. */ conx = mysql_init((MYSQL *)0L); /* The same connection parameters that * were used for the WCA application in Chapter 9 can be used here. */ conx = mysql_real_connect(conx, "einstein", "com_user", "syL0U812", "commish", 0, 0L, 0); if (conx == 0L) { g_print("Unable to connect to database.\n"); gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_tabular, "statusbar1")), 1, "Unable to Connect to database."); return; } g_print("connected to commish db.\n"); sql = "drop table if exists tbl_top_salespeople"; if (mysql_query (conx, sql) != 0) { g_print("Error dropping table.\n"); g_print("Error number is %i\n", mysql_errno (conx)); g_print("Error msg is %s\n", mysql_error (conx)); gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_tabular, "statusbar1")), 1, "Error dropping table."); mysql_close (conx); return; } g_print("table dropped.\n"); sql = g_strconcat("create table tbl_top_salespeople ", "select distinct salesperson, ", "sum(commission) as commission, " "count(*) as Count_rows " "from tbl_commissions " "group by salesperson", 0L); if (mysql_query (conx, sql) != 0) { g_print("Error creating table.\n"); g_print("Error number is %i\n", mysql_errno (conx)); g_print("Error msg is %s\n", mysql_error (conx)); gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_tabular, "statusbar1")), 1, "Error creating table."); mysql_close (conx); return; } g_print("table created.\n"); mysql_close (conx); g_print("First connection closed.\n"); sql = "tbl_top_salespeople order by commission DESC"; gtk_widget_destroy(GTK_WIDGET(lookup_widget(frm_tabular, "scrolledwindow1"))); g_print("Calling create_ddc.\n"); scrolledwindow1 = create_ddc(sql, "einstein", "com_user", "syL0U812", "commish", frm_tabular); g_print("Returned from create_ddc.\n"); gtk_widget_ref(scrolledwindow1); gtk_object_set_data_full(GTK_OBJECT(frm_tabular), "scrolledwindow1", scrolledwindow1, 0L); gtk_box_pack_start(GTK_BOX(lookup_widget(frm_tabular, "vbox1")), scrolledwindow1, TRUE, TRUE, 0); gtk_widget_show(scrolledwindow1); /* Unfortunately, the packing box widgets don't have any * way to insert a child widget at a certain positiononly * at the start and end. Therefore, destroy the statusbar widget * created in Glade and create a new one. * * Remember, however, that the statusbar was needed prior * to this point to communicate with the user. */ gtk_widget_destroy(GTK_WIDGET(lookup_widget(frm_tabular, "statusbar1"))); statusbar1 = gtk_statusbar_new(); gtk_box_pack_start(GTK_BOX(lookup_widget(frm_tabular, "vbox1")), statusbar1, FALSE, FALSE, 0); gtk_widget_show(statusbar1); gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_tabular, "statusbar1")), 1, "Done."); } gboolean on_frm_tabular_delete_event (GtkWidget *widget, GdkEvent *event, gpointer user_data) { g_print("on_frm_delete_event.\n"); gtk_main_quit(); return FALSE; }
Figure 12.2 shows the finished tabular report. It is running in its own process space. The KBI controlling form can be closed before the tabular form.
only for RuBoard - do not distribute or recompile |