/*------------------------------------------------------------------------- * Copyright (c) 2000-2005 Kenneth W. Sodemann (stuffle@mac.com) *------------------------------------------------------------------------- * prj_rpt_dlg * * Synopsis: * Gather the information needed to generate the basic project related * reports, and then generate the appropriate report. * * $Id: prj_rpt_dlg.c,v 1.24 2005/02/22 02:12:14 stuffle Exp $ * * 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 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 * Free Software Foundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * *------------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H # include #endif #include #include #ifdef HAVE_STATBUF_H # include #endif #include #include #include #include #include #include #include #include #include "change_log.h" #include "defs.h" #include "error_chks.h" #include "gtkutils.h" #include "prj_rpt_dlg.h" #include "prj_rpts_html.h" #include "props.h" #include "sqlstr.h" #include "util.h" /* * Data labels for data stored with the main widget. */ #define RPT_TYPE "report_type" #define PROJECT_LIST_VIEW "project_list_view" #define SHOW_ALL_CB "show_all_cb" #define SEL_ALL_BTN "sel_all_btn" #define UNSEL_ALL_BTN "unsel_all_btn" #define PATH_ENTRY "path_entry" #define FILE_SEL_BTN "file_sel_button" #define DIR_MAX 2047 #define INVALID_DIR -3 #define INVALID_FILE -4 #define RESPONSE_GEN 0 #define RESPONSE_VIEW 1 enum { PROJECT_NAME = 0, PROJECT_ACTIVE, PROJECT_PK, NUM_PROJECT_COLS }; typedef struct FileSelStruct { GtkFileSelection *file_sel_dlg; GtkEntry *file_entry; } FileSelStruct; static void on_file_sel_destroy (GtkWidget *widget, gpointer user_data) { g_assert (user_data); g_free (user_data); gtk_main_quit (); } static void on_file_sel_cancel (GtkButton *button, gpointer user_data) { g_assert (user_data); gtk_widget_destroy (GTK_WIDGET (((FileSelStruct *)user_data)->file_sel_dlg)); } static void on_file_sel_ok (GtkButton *button, gpointer user_data) { GtkFileSelection *fsd; GtkEntry *entry; GString *file_name; g_assert (user_data); fsd = ((FileSelStruct *)user_data)->file_sel_dlg; entry = ((FileSelStruct *)user_data)->file_entry; file_name = g_string_new (gtk_file_selection_get_filename (fsd)); gtk_entry_set_text (entry, file_name->str); gtk_widget_destroy (GTK_WIDGET (fsd)); g_string_free (file_name, TRUE); } static void draw_project_list (GtkWidget *main_widget) { PGconn *conn; GtkTreeView *tree; GtkListStore *store; GtkTreeIter iter; GtkToggleButton *show_all_cb; gboolean show_inactive; PGresult *res; GString *sql_buffer; gint pk; gint i, n; gboolean active; GConfClient *client; tree = GTK_TREE_VIEW (lookup_widget (main_widget, PROJECT_LIST_VIEW)); g_assert (tree != NULL); conn = g_object_get_data (G_OBJECT (main_widget), MY_DB_CONN); g_assert (conn != NULL); show_all_cb = GTK_TOGGLE_BUTTON (lookup_widget (main_widget, SHOW_ALL_CB)); g_assert (show_all_cb != NULL); client = g_object_get_data (G_OBJECT (main_widget), MY_GCONF_CLIENT); g_assert (client != NULL); store = GTK_LIST_STORE (gtk_tree_view_get_model (tree)); show_inactive = gtk_toggle_button_get_active (show_all_cb); sql_buffer = g_string_new (""); prj_sql_str (sql_buffer, (show_inactive ? ALL_ITEMS : ACTIVE_ITEMS_ONLY), TRUE, TRUE, TRUE, FALSE, client, 0); res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("filling project list on report dlg"))) { gtk_list_store_clear (store); n = PQntuples (res); for (i = 0; i < n; i++) { active = (toupper ((PQgetvalue (res, i, SQLSTR_ACTIVE_POS))[0]) == 'T'); pk = atoi (PQgetvalue (res, i, SQLSTR_PK_POS)); gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, PROJECT_NAME, PQgetvalue (res, i, SQLSTR_NAME_POS), PROJECT_ACTIVE, active, PROJECT_PK, pk, -1); } } PQclear (res); g_string_free (sql_buffer, TRUE); return; } static void on_prj_rpt_dlg_show (GtkWidget *widget, gpointer user_data) { GtkToggleButton *cb; GtkEntry *entry; GString *shall_key; GString *dirfile_key; gint rpt_type; gboolean flag; gchar *buffer; gchar curr_work_dir[DIR_MAX + 1]; GConfClient *client; GError *error = NULL; rpt_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), RPT_TYPE)); entry = GTK_ENTRY (lookup_widget (widget, PATH_ENTRY)); g_assert (entry != NULL); cb = GTK_TOGGLE_BUTTON (lookup_widget (widget, SHOW_ALL_CB)); g_assert (cb != NULL); client = g_object_get_data (G_OBJECT (widget), MY_GCONF_CLIENT); g_assert (client != NULL); /* * Build the keys that we will need to check. */ shall_key = g_string_new (""); dirfile_key = g_string_new (""); switch (rpt_type) { case StatusRpt: g_string_printf (shall_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, STAT_RPT_SEC, SHOW_ALL); g_string_printf (dirfile_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, STAT_RPT_SEC, DIR_NAME); break; case VersionRpt: g_string_printf (shall_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, VER_RPT_SEC, SHOW_ALL); g_string_printf (dirfile_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, VER_RPT_SEC, DIR_NAME); break; case ChangeLog: g_string_printf (shall_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, CHLG_RPT_SEC, SHOW_ALL); g_string_printf (dirfile_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, CHLG_RPT_SEC, DIR_NAME); break; default: g_assert_not_reached(); } /* * Set the show_all_cb appropriatly, then draw the project list. */ flag = gconf_client_get_bool (client, shall_key->str, &error); if (error != NULL) { g_warning (error->message); g_error_free (error); error = NULL; flag = FALSE; } gtk_toggle_button_set_active (cb, flag); draw_project_list (widget); /* * Set the dir/file name entry to whatever was used last time, CWD if * there is no defined "last time". */ buffer = gconf_client_get_string (client, dirfile_key->str, &error); if (error != NULL) { g_warning (error->message); g_error_free (error); error = NULL; } if (buffer != NULL && buffer[0] != '\000') { gtk_entry_set_text (entry, buffer); } else if (getcwd (curr_work_dir, DIR_MAX)) { gtk_entry_set_text (entry, curr_work_dir); } if (buffer != NULL) { g_free (buffer); } /* * general clean up */ g_string_free (shall_key, TRUE); g_string_free (dirfile_key, TRUE); } static void on_prj_rpt_dlg_destroy (GtkWidget *widget, gpointer user_data) { GtkToggleButton *cb; GtkEntry *entry; GString *shall_key; GString *dirfile_key; gint rpt_type; GConfClient *client; rpt_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), RPT_TYPE)); entry = GTK_ENTRY (lookup_widget (widget, PATH_ENTRY)); g_assert (entry != NULL); cb = GTK_TOGGLE_BUTTON (lookup_widget (widget, SHOW_ALL_CB)); g_assert (cb != NULL); client = g_object_get_data (G_OBJECT (widget), MY_GCONF_CLIENT); g_assert (client != NULL); /* * build the keys for the data that we will be saving */ shall_key = g_string_new (""); dirfile_key = g_string_new (""); switch (rpt_type) { case StatusRpt: g_string_printf (shall_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, STAT_RPT_SEC, SHOW_ALL); g_string_printf (dirfile_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, STAT_RPT_SEC, DIR_NAME); break; case VersionRpt: g_string_printf (shall_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, VER_RPT_SEC, SHOW_ALL); g_string_printf (dirfile_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, VER_RPT_SEC, DIR_NAME); break; case ChangeLog: g_string_printf (shall_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, CHLG_RPT_SEC, SHOW_ALL); g_string_printf (dirfile_key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, CHLG_RPT_SEC, FILE_NAME); break; default: g_assert_not_reached(); } /* * Save the data, sync the file, and clean up. */ gconf_client_set_bool (client, shall_key->str, gtk_toggle_button_get_active (cb), NULL); gconf_client_set_string (client, dirfile_key->str, gtk_entry_get_text (entry), NULL); g_string_free (shall_key, TRUE); g_string_free (dirfile_key, TRUE); /* * Check the main widget, and see if we are running * modally. It is assumed that we were started via the * execute_xxx function in this case, so we need to quit * the main loop created there. */ if (GTK_WINDOW (widget)->modal) { gtk_main_quit (); } return; } static void on_show_all_cb_toggled (GtkToggleButton *btn, gpointer user_data) { draw_project_list (GTK_WIDGET (user_data)); } static void on_sel_all_button_clicked (GtkButton *button, gpointer user_data) { GtkTreeView *tree; GtkTreeSelection *sel; tree = GTK_TREE_VIEW (lookup_widget (GTK_WIDGET (user_data), PROJECT_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_select_all (sel); } static void on_unsel_all_button_clicked (GtkButton *button, gpointer user_data) { GtkTreeView *tree; GtkTreeSelection *sel; tree = GTK_TREE_VIEW (lookup_widget (GTK_WIDGET (user_data), PROJECT_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_unselect_all (sel); } static void on_file_sel_btn_clicked (GtkButton *button, gpointer user_data) { GtkWidget *filewin; GtkEntry *entry; FileSelStruct *data; GString *buffer; struct stat stat_buf; PrjRptType rpt_type; entry = GTK_ENTRY (lookup_widget (GTK_WIDGET (user_data), PATH_ENTRY)); g_assert (entry != NULL); rpt_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (user_data), RPT_TYPE)); if (rpt_type != ChangeLog) { filewin = gtk_file_selection_new (_("Select Output Directory...")); /* * We only want to get directories. Disable all "file" selection * stuff, and only allow for selecting directories. */ gtk_widget_set_sensitive (GTK_FILE_SELECTION (filewin)->file_list, FALSE); gtk_widget_set_sensitive (GTK_FILE_SELECTION (filewin)->selection_entry, FALSE); } else { filewin = gtk_file_selection_new (_("Select Output File...")); } data = g_malloc (sizeof (FileSelStruct)); data->file_sel_dlg = GTK_FILE_SELECTION (filewin); data->file_entry = entry; g_signal_connect (filewin, "destroy", G_CALLBACK (on_file_sel_destroy), data); g_signal_connect (GTK_FILE_SELECTION (filewin)->ok_button, "clicked", G_CALLBACK (on_file_sel_ok), data); g_signal_connect (GTK_FILE_SELECTION (filewin)->cancel_button, "clicked", G_CALLBACK (on_file_sel_cancel), data); buffer = g_string_new (gtk_entry_get_text (entry)); if (buffer->len > 0) { if (stat (buffer->str, &stat_buf) == 0) { if (S_ISDIR (stat_buf.st_mode)) { if (buffer->str[buffer->len - 1] != '/') { buffer = g_string_append_c (buffer, '/'); } gtk_file_selection_set_filename (GTK_FILE_SELECTION (filewin), buffer->str); } } } g_string_free (buffer, TRUE); gtk_widget_show (filewin); gtk_window_set_modal (GTK_WINDOW (filewin), TRUE); gtk_main (); } static void set_view_button_status (GtkDialog *dlg, const gchar *path) { PrjRptType rpt_type; GString *file_name; struct stat stat_buf; gboolean btn_active = FALSE; rpt_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dlg), RPT_TYPE)); file_name = g_string_new (path); if (rpt_type != ChangeLog) { file_name = g_string_append (file_name, "/index.html"); } if (stat (file_name->str, &stat_buf) == 0) { if (S_ISREG (stat_buf.st_mode)) { btn_active = TRUE; } } gtk_dialog_set_response_sensitive (dlg, RESPONSE_VIEW, btn_active); g_string_free (file_name, FALSE); } static void on_close_button_clicked (GtkDialog *dlg) { gtk_widget_destroy (GTK_WIDGET (dlg)); } static void build_selected_prj_list (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gint pk; GList **list = data; gtk_tree_model_get (model, iter, PROJECT_PK, &pk, -1); *list = g_list_append (*list, GINT_TO_POINTER (pk)); } static void on_gen_button_clicked (GtkDialog *dlg) { struct stat stat_buf; PGconn *conn; GtkToggleButton *show_all_cb; GtkTreeView *tree; GtkTreeSelection *sel; GtkEntry *dir_entry; GString *path_name; PrjRptType rpt_type; gint rtn = -1; gboolean active_only; GList *prj_list = NULL; gint status; GString *msg; GtkWidget *msg_dlg; rpt_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dlg), RPT_TYPE)); dir_entry = GTK_ENTRY (lookup_widget (GTK_WIDGET (dlg), PATH_ENTRY)); g_assert (dir_entry != NULL); show_all_cb = GTK_TOGGLE_BUTTON (lookup_widget (GTK_WIDGET (dlg), SHOW_ALL_CB)); g_assert (show_all_cb != NULL); conn = g_object_get_data (G_OBJECT (dlg), MY_DB_CONN); g_assert (conn != NULL); tree = GTK_TREE_VIEW (lookup_widget (GTK_WIDGET (dlg), PROJECT_LIST_VIEW)); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_selected_foreach (sel, build_selected_prj_list, &prj_list); prj_list = g_list_first (prj_list); if (!prj_list) { if (rpt_type == ChangeLog) { msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("You must select a project.")); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); return; } else { msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Generating the report without selecting any projects will\n" "result in the report being generated for all listed projects.\n" "Is this what you want?")); if (gtk_dialog_run (GTK_DIALOG (msg_dlg)) == GTK_RESPONSE_NO) { gtk_widget_destroy (msg_dlg); return; } gtk_widget_destroy (msg_dlg); } } path_name = g_string_new (gtk_entry_get_text (dir_entry)); active_only = !gtk_toggle_button_get_active (show_all_cb); if (path_name->len > 0) { status = stat (path_name->str, &stat_buf); if (status == 0 || rpt_type == ChangeLog) { switch (rpt_type) { case StatusRpt: if (S_ISDIR (stat_buf.st_mode)) { rtn = create_project_status_report (conn, path_name->str, prj_list, active_only); } else { rtn = INVALID_DIR; } break; case VersionRpt: if (S_ISDIR (stat_buf.st_mode)) { rtn = create_project_version_report (conn, path_name->str, prj_list, active_only, FALSE); } else { rtn = INVALID_DIR; } break; case ChangeLog: if (status == 0 && ((S_ISDIR (stat_buf.st_mode) || S_ISCHR (stat_buf.st_mode) || S_ISBLK (stat_buf.st_mode) || S_ISFIFO (stat_buf.st_mode)|| S_ISSOCK (stat_buf.st_mode)))) { rtn = INVALID_FILE; } else { rtn = create_change_log (conn, path_name->str, GPOINTER_TO_INT (prj_list->data)); } break; default: g_assert_not_reached (); } /* end switch (rpt_type) */ switch (rtn) { case 0: msg = g_string_new (""); g_string_printf (msg, _("The report was succuessfully generated in\n%s"), path_name->str); msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, msg->str); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); g_string_free (msg, TRUE); break; case -1: msg = g_string_new (""); g_string_printf (msg, _("An error occurred generating the report in\n%s\n"), path_name->str); msg = g_string_append (msg, g_strerror (errno)); msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, msg->str); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); g_string_free (msg, TRUE); break; case -2: msg = g_string_new (""); g_string_printf (msg, _("An error occurred generating the report in\n%s\n"), path_name->str); msg = g_string_append (msg, _("libPRepS internal SQL error - see syslog")); msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, msg->str); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); g_string_free (msg, TRUE); break; case INVALID_DIR: msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("The specified output path is not a valid, existing directory.")); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); break; case INVALID_FILE: msg = g_string_new (""); g_string_printf (msg, _("%s\nis either a directory or a spcial type of file.\n"), path_name->str); msg = g_string_append (msg, _("Please choose another name.")); msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, msg->str); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); g_string_free (msg, TRUE); break; default: g_assert_not_reached (); } /* end switch (rtn) */ } else /* stat() called failed */ { msg = g_string_new (_("There is a problem with the path:\n")); msg = g_string_append (msg, path_name->str); msg = g_string_append_c (msg, '\n'); msg = g_string_append (msg, g_strerror (errno)); msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, msg->str); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); g_string_free (msg, TRUE); syslog (LOG_ERR, _("Failed to stat %s: %m"), path_name->str); } } else { msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("You MUST supply an output path.")); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); } g_list_free (prj_list); g_string_free (path_name, TRUE); set_view_button_status (dlg, gtk_entry_get_text (GTK_ENTRY (dir_entry))); return; } static void on_path_entry_changed (GtkWidget *entry, gpointer user_data) { set_view_button_status (GTK_DIALOG (user_data), gtk_entry_get_text (GTK_ENTRY (entry))); } static void on_view_button_clicked (GtkDialog *dlg) { gchar *viewer; GString *file_name; GtkEntry *dir_entry; PrjRptType rpt_type; GtkWidget *main_win; GConfClient *client; main_win = g_object_get_data (G_OBJECT (dlg), MY_PARENT); g_assert (main_win != NULL); client = g_object_get_data (G_OBJECT (main_win), MY_GCONF_CLIENT); g_assert (client != NULL); rpt_type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (dlg), RPT_TYPE)); dir_entry = GTK_ENTRY (lookup_widget (GTK_WIDGET (dlg), PATH_ENTRY)); g_assert (dir_entry); file_name = g_string_new (gtk_entry_get_text (dir_entry)); if (rpt_type == ChangeLog) { viewer = text_viewer (client); } else { viewer = html_viewer (client); file_name = g_string_append (file_name, "/index.html"); } spawn_viewer (viewer, file_name->str); g_free (viewer); g_string_free (file_name, TRUE); return; } static void on_prj_rpt_dlg_clicked (GtkDialog *dlg, gint btn_cd, gpointer user_data) { switch (btn_cd) { case RESPONSE_GEN: on_gen_button_clicked (dlg); break; case RESPONSE_VIEW: on_view_button_clicked (dlg); break; case GTK_RESPONSE_CLOSE: on_close_button_clicked (dlg); break; case GTK_RESPONSE_DELETE_EVENT: break; default: g_assert_not_reached (); } } static GtkWidget * create_prj_rpt_dlg (GtkWidget *parent, PGconn *conn, PrjRptType rpt_type) { GtkWidget *prj_rpt_dlg; GtkWidget *dialog_vbox; GtkWidget *file_sel_btn; GtkWidget *hbox; GtkWidget *hsep; GtkWidget *label; GtkWidget *path_entry; GtkWidget *project_list_view; GtkListStore *project_list_store; GtkCellRenderer *rend; GtkTreeViewColumn *col; GtkTreeSelection *sel; GtkWidget *scrollwin; GtkWidget *sel_all_btn; GtkWidget *show_all_cb; GtkWidget *unsel_all_btn; GtkWidget *vbox; GtkTooltips *tooltips; GConfClient *client; /* * Just use the parent's tooltips... */ g_assert (parent != NULL); tooltips = g_object_get_data (G_OBJECT (parent), TOOLTIPS); g_assert (tooltips != NULL); client = g_object_get_data (G_OBJECT (parent), MY_GCONF_CLIENT); g_assert (client != NULL); prj_rpt_dlg = gtk_dialog_new_with_buttons ("", GTK_WINDOW (parent), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_EXECUTE, RESPONSE_GEN, GTK_STOCK_OPEN, RESPONSE_VIEW, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); GLADE_HOOKUP_OBJECT_NO_REF (prj_rpt_dlg, prj_rpt_dlg, "prj_rpt_dlg"); gtk_container_set_border_width (GTK_CONTAINER (prj_rpt_dlg), 5); g_signal_connect (prj_rpt_dlg, "show", G_CALLBACK (on_prj_rpt_dlg_show), NULL); g_signal_connect (prj_rpt_dlg, "destroy", G_CALLBACK (on_prj_rpt_dlg_destroy), NULL); g_signal_connect (prj_rpt_dlg, "response", G_CALLBACK (on_prj_rpt_dlg_clicked), NULL); switch (rpt_type) { case StatusRpt: gtk_window_set_title (GTK_WINDOW (prj_rpt_dlg), _("\"PRs by Status\" Report")); break; case VersionRpt: gtk_window_set_title (GTK_WINDOW (prj_rpt_dlg), _("\"PRs by Project Version\" Report")); break; case ChangeLog: gtk_window_set_title (GTK_WINDOW (prj_rpt_dlg), _("Project ChangeLog Report")); break; default: g_assert_not_reached (); } gtk_window_set_resizable (GTK_WINDOW (prj_rpt_dlg), FALSE); g_object_set_data (G_OBJECT (prj_rpt_dlg), TOP_DOG, prj_rpt_dlg); g_object_set_data (G_OBJECT (prj_rpt_dlg), MY_PARENT, parent); g_object_set_data (G_OBJECT (prj_rpt_dlg), MY_DB_CONN, conn); g_object_set_data (G_OBJECT (prj_rpt_dlg), MY_GCONF_CLIENT, client); g_object_set_data (G_OBJECT (prj_rpt_dlg), RPT_TYPE, GINT_TO_POINTER (rpt_type)); gtk_dialog_set_default_response (GTK_DIALOG (prj_rpt_dlg), RESPONSE_GEN); dialog_vbox = GTK_DIALOG (prj_rpt_dlg)->vbox; GLADE_HOOKUP_OBJECT (prj_rpt_dlg, dialog_vbox, "dialog_vbox"); gtk_box_set_spacing (GTK_BOX (dialog_vbox), 5); gtk_widget_show (dialog_vbox); vbox = gtk_vbox_new (FALSE, STD_BOX_SPACING); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, vbox, "vbox1"); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX (dialog_vbox), vbox, TRUE, TRUE, 0); scrollwin = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, scrollwin, "scrolledwindow1"); gtk_widget_show (scrollwin); gtk_box_pack_start (GTK_BOX (vbox), scrollwin, TRUE, TRUE, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN); gtk_widget_set_size_request (scrollwin, 325, 175); project_list_store = gtk_list_store_new (NUM_PROJECT_COLS, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT); project_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (project_list_store)); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, project_list_view, PROJECT_LIST_VIEW); gtk_container_add (GTK_CONTAINER (scrollwin), project_list_view); gtk_widget_show (project_list_view); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (project_list_view)); if (rpt_type == ChangeLog) { gtk_tree_selection_set_mode (sel, GTK_SELECTION_SINGLE); gtk_tooltips_set_tip (tooltips, project_list_view, _("Select a project to be included in the report."), NULL); } else { gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); gtk_tooltips_set_tip (tooltips, project_list_view, _("Select one or more projects to be included in the report. Selecting None is the same as selecting All"), NULL); } rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Project Name"), rend, "text", PROJECT_NAME, NULL); gtk_tree_view_column_set_min_width (col, 250); gtk_tree_view_column_set_sort_column_id (col, PROJECT_NAME); gtk_tree_view_append_column (GTK_TREE_VIEW (project_list_view), col); show_all_cb = gtk_check_button_new_with_label (_("Show Inactive Projects")); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, show_all_cb, SHOW_ALL_CB); gtk_widget_show (show_all_cb); gtk_box_pack_start (GTK_BOX (vbox), show_all_cb, TRUE, TRUE, 0); g_signal_connect (show_all_cb, "toggled", G_CALLBACK (on_show_all_cb_toggled), prj_rpt_dlg); gtk_tooltips_set_tip (tooltips, show_all_cb, _("Enable/Disable the display of inactive projects."), NULL); if (rpt_type != ChangeLog) { hbox = gtk_hbox_new (FALSE, 5); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, hbox, "hbox1"); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (dialog_vbox), hbox, TRUE, TRUE, 0); sel_all_btn = gtk_button_new_with_label (_("Select All")); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, sel_all_btn, SEL_ALL_BTN); gtk_widget_show (sel_all_btn); gtk_box_pack_start (GTK_BOX (hbox), sel_all_btn, TRUE, TRUE, 0); g_signal_connect (sel_all_btn, "clicked", G_CALLBACK (on_sel_all_button_clicked), prj_rpt_dlg); gtk_tooltips_set_tip (tooltips, sel_all_btn, _("Select all projects in the list."), NULL); unsel_all_btn = gtk_button_new_with_label (_("Select None")); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, unsel_all_btn, UNSEL_ALL_BTN); gtk_widget_show (unsel_all_btn); gtk_box_pack_start (GTK_BOX (hbox), unsel_all_btn, TRUE, TRUE, 0); g_signal_connect (unsel_all_btn, "clicked", G_CALLBACK (on_unsel_all_button_clicked), prj_rpt_dlg); gtk_tooltips_set_tip (tooltips, unsel_all_btn, _("Clear all current projects selections."), NULL); } hsep = gtk_hseparator_new (); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, hsep, "hsep1"); gtk_widget_show (hsep); gtk_box_pack_start (GTK_BOX (dialog_vbox), hsep, TRUE, TRUE, 0); vbox = gtk_vbox_new (FALSE, 0); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, vbox, "vbox2"); gtk_widget_show (vbox); gtk_box_pack_start (GTK_BOX (dialog_vbox), vbox, TRUE, TRUE, 0); if (rpt_type == ChangeLog) { label = gtk_label_new (_("ChangeLog Output File")); } else { label = gtk_label_new (_("Report Output Directory")); } GLADE_HOOKUP_OBJECT (prj_rpt_dlg, label, "label4"); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, TRUE); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); hbox = gtk_hbox_new (FALSE, 5); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, hbox, "hbox2"); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); path_entry = gtk_entry_new (); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, path_entry, PATH_ENTRY); gtk_widget_show (path_entry); gtk_box_pack_start (GTK_BOX (hbox), path_entry, TRUE, TRUE, 0); gtk_tooltips_set_tip (tooltips, path_entry, _("Enter the path where the report should be created."), NULL); g_signal_connect (path_entry, "changed", G_CALLBACK (on_path_entry_changed), prj_rpt_dlg); file_sel_btn = gtk_button_new_with_label (" ... "); GLADE_HOOKUP_OBJECT (prj_rpt_dlg, file_sel_btn, FILE_SEL_BTN); gtk_widget_show (file_sel_btn); gtk_box_pack_start (GTK_BOX (hbox), file_sel_btn, FALSE, FALSE, 0); gtk_tooltips_set_tip (tooltips, file_sel_btn, _("Press to select the report output directory."), NULL); g_signal_connect (file_sel_btn, "clicked", G_CALLBACK (on_file_sel_btn_clicked), prj_rpt_dlg); g_object_set_data (G_OBJECT (prj_rpt_dlg), TOOLTIPS, tooltips); return prj_rpt_dlg; } gint execute_prj_rpt_dlg (GtkWidget *parent, PGconn *conn, PrjRptType rpt_type) { GtkWidget *dlg; dlg = create_prj_rpt_dlg (parent, conn, rpt_type); gtk_widget_show (dlg); gtk_window_set_modal (GTK_WINDOW (dlg), TRUE); gtk_main (); return 0; }