The Controlling Application: KBI

only for RuBoard - do not distribute or recompile

The Controlling Application: KBI

Here are some notes regarding building the KBI application as it is shown in Figure 12.1.

Figure 12.1. The KBI application launches other applications under development with Glade.
graphics/12fig01.gif
  • Remember to deselect the Enable GNOME Support option and the Gettext Support option from the project options.

  • Set the name ( frm_kbi ) and the title, and then insert a three-row vertical packing box. Place a List widget in the top, a horizontal packing box with two columns in the middle, and a status bar in the bottom row of the vertical packing box. Place a button in each of the cells of the horizontal packing box.

  • Call the List widget lst_reports . For the name of the horizontal packing box, use hbox_buttons. The button on the left is cmd_close , and the one on the right is cmd_open . Their labels should be Close and Open , respectively.

  • For hbox_buttons, Homogenous should be set to No , Expand should be No , and both Fill and Pack Start should be Yes . For both command buttons , set Expand and Pack Start to Yes, as well as Fill .

  • Finally, set the clicked signal for each of the two command buttons, as well as the show event for the form. Set the delete_event on the form as the place for the gtk_main_quit() call (and you might as well put it there at this time).

If you want to do a quick compile at this point, don t forget to comment out lines 23 and 24 in main.c (the lines with PACKAGE_DATA_DIR and PACKAGE_SRC_DIR ). Also, move frm_kbi to be global in scope in main.c .

Figure 12.1 shows the KBI application being built via Glade.

Listing 12.1 is the kbi_utils.c file. It contains the code for functions that authenticate the user , provide him/her with a pick-list of available reports , and launch the selected report.

Listing 12.1 kbi_utils.c
 #include <gtk/gtk.h>  #include <mysql.h>  #include "support.h"  /*  stdio.h  is needed for the file read operation. */  #include <stdio.h>  #define        SERVER   "einstein"  #define        LOGIN    "kbi_user"  #define PASS   "dengissa"  #define DB     "kbi"  GtkWidget *frm_kbi;  /* The following generic variables have worked fine in the past.   * So, to keep things simple, use them again.   */  MYSQL          *conx;  MYSQL_RES      *result_set;  MYSQL_ROW      row;  gchar          *sql;  gchar          *user_login;  /* Begin Function Code... */  gboolean authenticate_user()  {  /* This function will query the operating system for the currently   * logged in user and then query the database for that user.   * This is primitive security that's completely hidden from the user,   * and it is a simple form of authentication.   */  g_print("Starting authenticate_user.\n");     conx = mysql_init((MYSQL *)0L);     if (conx == 0L)       {         gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1,"mysql_init problem");           return FALSE;      }     gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                     "statusbar1")), 1, "mysql_init ok");     conx = mysql_real_connect(conx, SERVER, LOGIN, PASS, DB, 0, 0L, 0);     if (conx == 0L)       {         gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1,"mysql_real_connect problem");          return FALSE;       }     gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                   "statusbar1")), 1, "mysql_real_connect ok");  /* Create the sql string to query the database for the   * current user.   */  sql = g_strconcat("select * from tbl_authorized_users ",                       "where user_name = '",                       g_get_user_name(), "'", 0L);     g_print("sql is %s\n", sql);  /* Next, query  tbl_authorized_users  to see if the currently   * logged-in person is on the list.   */  if (mysql_query (conx, sql) != 0)        {         gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1,"mysql_query problem");          return FALSE;        }     gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1, "mysql_query ok");     result_set = mysql_store_result(conx);     if (mysql_num_rows(result_set) != 1)        {  /* Something is wrong here */  gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                         "statusbar1")), 1,"mysql_num_rows problem");          return FALSE;        }     gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1, "mysql_num_rows ok");  /* If the code reaches this point, the user   * is authorized to run this application.   */  gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1, "user authenticated");     mysql_free_result (result_set);     mysql_close (conx);     return TRUE;  }  void fill_lst_reports()  {  /* This routine will fill the list box of the KBI application   * with the reports that are authorized for the currently   * logged-in user.   */  GList *list_of_reports = 0L;     conx = mysql_init((MYSQL *)0L);     if (conx == 0L)       {         gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1,"mysql_init problem");          return;  }     gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1, "mysql_init ok");     conx = mysql_real_connect(conx, SERVER, LOGIN, PASS, DB, 0, 0L, 0);     if (conx == 0L)       {         gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1,"mysql_real_connect problem");          return;       }       gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1, "mysql_real_connect ok");     sql = "select * from tbl_reports";     if (mysql_query (conx, sql) != 0)       {         gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1,"mysql_query problem");          mysql_close(conx);          return;       }     gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1, "mysql_query ok");     result_set = mysql_store_result(conx);  /* At this point,  result_set  holds a list of the reports that   * are available to be viewed. Create a GList structure to   * hold that list.   */  while ((row = mysql_fetch_row (result_set)) != 0)       {          GtkWidget *list_item;           //g_print("Report name is %s\n", row[0]);           list_item = gtk_list_item_new_with_label(row[0]);  /* This next call is used to associate the   * name of the report with the list item in the GtkList   * widget  lst_reports  . The three parameters are the   * list item, the "key," and the data to be retrieved   * when this object is queried for the key. This is   * done so the user will be able to retrieve the text of the item   * selected in  lst_reports  . See  get_report_name()  below   * for the retrieval procedures.   */  gtk_object_set_data(GTK_OBJECT(list_item), "rept_name", row[0]);           list_of_reports = g_list_append(list_of_reports,                  list_item);       }  /* Now a GList object called  list_of_reports  contains all the   * report names returned by the sql statement. Insert that   * list into  lst_reports  .   */  gtk_list_append_items(GTK_LIST(lookup_widget(frm_kbi, "lst_reports")),               list_of_reports);     mysql_close(conx);  /* Refresh the form. */  gtk_widget_show_all(frm_kbi);  }  gchar *get_report_name()  {  /* When the user clicks the Open command button on  frm_kbi  ,   * this routine is called to determine which value was selected   * in the list widget at the time.   */  GtkWidget *target_list;      GList     *target_GList;      GtkObject *list_item;      g_print("starting get_report_name.\n");      target_list = lookup_widget(frm_kbi, "lst_reports");      target_GList = GTK_LIST(target_list)->selection;      if (target_GList)        {        g_print("target_GList populated.\n");        }     else       {       g_print("target_GList not populated.\n");        return "";       }      g_print("target_label identified.\n");      list_item = GTK_OBJECT(target_GList->data);      g_print("data item identified.\n");  /* Now that there is a pointer to the selected list item,   * query that object for the data associated with the   * objectin this case the report name. In the following   * call, rept_data acts as a key that allows the user to retrieve   * a specific piece of data from  list_item  . See fill  _list_reports()  * above for the specifics of attaching data to an object.   */  return gtk_object_get_data(list_item, "rept_name");  }  gchar *get_exe_name(gchar *rept_name)  {  /* When the application knows the name of the target report,   * the database can be queried for the name of the   * executable.   */  g_print("Starting get_exe_name\n");     sql = g_strconcat("select exe_name "                       "from tbl_reports "                       "where report_name = '", rept_name, "'", 0L);     conx = mysql_init((MYSQL *)0L);     conx = mysql_real_connect(conx, SERVER, LOGIN, PASS, DB, 0, 0L, 0);     if (mysql_query (conx, sql) != 0)         {  /* Error, malformed sql... */  gtk_statusbar_push(GTK_STATUSBAR(lookup_widget(frm_kbi,                        "statusbar1")), 1,                        "mysql_query problem in get_exe_name");          mysql_close(conx);          return "";         }     result_set = mysql_store_result(conx);     row = mysql_fetch_row (result_set);     mysql_free_result(result_set);     mysql_close(conx);     return row[0];  }  gboolean check_file_exists(target_file)  {  /* This function checks to see if a file exists on the   * user's machine; there is not much point in   * trying to open the report selected by the user if the   * executable has not been loaded onto the user's machine.   *   * If a file does not exist, the  fopen  call returns   * Null (0L). The r parameter stands for "read only."   */  g_print("Starting check_file_exists.\n");     if (fopen((char*) target_file, "r") == 0L)        {          g_print("File does not exist.\n");           return FALSE;        }     else  /* File does exist. */  g_print("File does exist.\n");     return TRUE;  } 

Listing 12.2 lists the callbacks as they re filled in after Glade has created them.

Listing 12.2 callbacks.c from KBI
 #ifdef HAVE_CONFIG_H  #  include <config.h>  #endif  #include <gtk/gtk.h>  /*  unistd.h  is needed for the  execl()  command in   *  on_cmd_open_click()  .   */  #include <unistd.h>  /*  stdlib.h  is needed for the pid_t type (process   * identifier) in  on_cmd_open_click()  .   */  #include <stdlib.h>  #include "callbacks.h"  #include "interface.h"  #include "support.h"  #include "kbi_utils.h"  void  on_cmd_close_clicked                   (GtkButton       *button,                                          gpointer         user_data)  {    g_print("on_cmd_close_clicked\n");     gtk_main_quit();  }    void  on_cmd_open_clicked                    (GtkButton       *button,                                          gpointer        user_data)  {    pid_t pid;     gchar *exe_name = "./kbi";     gchar *report_name = "another kbi";  /* This function creates a separate executable for the   * target application, as selected in the list box on   * frm_kbi.   */  g_print("on_cmd_open_clicked\n");  /* Get the exe name and the   * report name for the  execl  () call below.   */  report_name = get_report_name();     g_print("report_name is %s\n", report_name);     if (g_strcasecmp(report_name, "") == 0)       {         g_print("No report selected.");          return;       }     exe_name = get_exe_name(report_name);     g_print("exe_name is %s\n", exe_name);     if (g_strcasecmp(exe_name, "") == 0)       {         g_print("No executable returned.\n");          return;       }  /* The following function call assumes that the executables   * have been installed to the /usr/local/bin/ directory.   * Obviously, they could be in a different location, or   * it might be necessary to include the path information   * in the database table that lists the executable name.   */  exe_name = g_strconcat("/usr/local/bin/", exe_name, 0L);  /* Confirm that the target executable is on this machine   * in the place that it should be: /usr/local/bin/.   */  g_print("Check that file exists.\n");      if (check_file_exists(exe_name) == FALSE)         {  /* The target executable doesn't exist... *  /            g_print("Target exe not found.\n");            return;         }  /* This section requires a bit of an explanation. The  fork  (  )  call   * creates a copy of the running program in a separate process   * space. That is, itthe "child" processhas its own   * copy of the program, including variables, memory, and so on.   *   * Following that is the ex  ecl  () call inside the  if  statement.   * This changes the existing program by replacing it with the   * program called in the first parameter.   */  g_print("Fork off a new process.\n");        pid = fork();        if (pid == 0)          {  /* If you have entered this  if  statement, then this must   * be the child process that was  fork  ()-ed off in the   * previous statements. Therefore, this (child) process   * should change itself to become the "targ  et  " process,   * that is, the program that needs to be run.   */  g_print("initiating child process.\n");             execl (exe_name, report_name);             g_print("child process launched.\n");          }  }  gboolean  on_frm_kbi_delete_event                (GtkWidget       *widget,                                          GdkEvent        *event,                                          gpointer         user_data)  {   g_print("on_frm_kbi_delete_event\n");    gtk_main_quit();    return FALSE;  }    void  on_frm_kbi_show                         (GtkWidget       *widget,                                           gpointer         user_data)  {   g_print("on_frm_kbi_show\n");    if (authenticate_user())      {         fill_lst_reports();      }  }  void  on_frm_kbi_realize                    (GtkWidget       *widget,                                         gpointer         user_data)  {   g_print("on_frm_kbi_realize\n");  } 

Listing 12.3 is main.c for KBI. All the following reports in this chapter will have very similar main.c files, so those will not be listed. (They are, of course, posted at this book s companion Web site.)

Listing 12.3 main.c from KBI
  /*   * Initial  main.c  file generated by Glade. Edit as required.   * Glade will not overwrite this file.   */  #ifdef HAVE_CONFIG_H  #  include <config.h>  #endif  #include <gtk/gtk.h>  #include "interface.h"  #include "support.h"  GtkWidget *frm_kbi;  int  main (int argc, char *argv[])  {   gtk_set_locale ();    gtk_init (&argc, &argv);  //  add_pixmap_directory (PACKAGE_DATA_DIR "/pixmaps");  //  add_pixmap_directory (PACKAGE_SOURCE_DIR "/pixmaps");  /*   * The following code was added by Glade to create one of each component   * (except popup menus), just so that you can see something after building   * the project. Delete any components that you don't want shown initially.   * /  frm_kbi = create_frm_kbi ();    gtk_widget_show (frm_kbi);    gtk_main ();    return 0;  } 
only for RuBoard - do not distribute or recompile


MySQL Building User Interfaces
MySQL: Building User Interfaces (Landmark)
ISBN: 073571049X
EAN: 2147483647
Year: 2001
Pages: 119

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net