/*------------------------------------------------------------------------- * Copyright (c) 1999-2005 Kenneth W. Sodemann (stuffle@mac.com) *------------------------------------------------------------------------- * find_dlg * * Synopsis: * Find problem reports based on user specified criteria. * * $Id: find_dlg.c,v 1.52 2005/05/11 00:39:55 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 #include #include #include #include #include #include "defs.h" #include "error_chks.h" #include "gstr_utils.h" #include "gtkutils.h" #include "pr_query.h" #include "probupdate_dlg.h" #include "sqlstr.h" #include "util.h" /* * Define the main widgets in the dialog box. */ #define CHANGE_LOG_CB "change_log_cb" #define DESCR_CB "descr_cb" #define FIX_CB "fix_cb" #define IGNORE_CASE_CB "ignore_case_cb" #define INACTIVE_CHECK_BOX "inactive_cb" #define PROBLEM_TYPE_LIST_VIEW "problem_type_list_view" #define PROJECT_LIST_VIEW "project_list_view" #define RESPONSIBLE_LIST_VIEW "responsible_list_view" #define RESULTS_LIST_VIEW "results_list_view" #define SEVERITY_LIST_VIEW "severity_list_view" #define STATUS_LIST_VIEW "status_list_view" #define SUBMITTER_LIST_VIEW "submitter_list_view" #define TEXT_ENTRY "text_entry" #define TITLE_CB "title_cb" #define DISPLAY_ARCH_CB "display_arch_cb" #define DISP_ARCH_NOTIFY "disp_arch_notify" /* * Response buttons */ #define RESPONSE_FIND 1 #define RESPONSE_OPEN 2 #define NO_INACTIVE " AND active = TRUE " #define SUB_RESP_ORDER_BY " ORDER BY 2, 1 " /* * To weed out the potentially large number of submitters, only show * those who are in the submitter table for projects that are somehow * related to the current user. */ #define SELECT_SUBMITTER "\ SELECT login_id, \ last_name || ', ' || first_name || ' (' || login_id || ')' \ FROM person p \ WHERE login_id in \ (SELECT login_id \ FROM submitter \ WHERE project_num in (SELECT project_num \ FROM project \ WHERE login_id = getpgusername ()) \ OR project_num in (SELECT project_num \ FROM submitter \ WHERE login_id = getpgusername ()) \ OR project_num in (SELECT project_num \ FROM responsible \ WHERE login_id = getpgusername ())) " /* * See comment on SELECT_SUBMITTER. Same applies here. */ #define SELECT_RESPONSIBLE "\ SELECT login_id, \ last_name || ', ' || first_name || ' (' || login_id || ')' \ FROM person p \ WHERE login_id in \ (SELECT login_id \ FROM responsible \ WHERE project_num in (SELECT project_num \ FROM project \ WHERE login_id = getpgusername ()) \ OR project_num in (SELECT project_num \ FROM submitter \ WHERE login_id = getpgusername ()) \ OR project_num in (SELECT project_num \ FROM responsible \ WHERE login_id = getpgusername ())) " enum { ATTRIB_NAME = 0, ATTRIB_PK, NUM_ATTRIB_COLS }; enum { RESULT_PR_NUM = 0, RESULT_PROJECT, RESULT_STATUS, RESULT_PROBLEM_TYPE, RESULT_SEVERITY, RESULT_TITLE, RESULT_PK, NUM_RESULT_COLS }; /* * This application can only have one find dialog visable at a time, this * is the one... */ static GtkWidget *find_dlg = NULL; static void show_arch_change_notify (GConfClient *client, guint cnxn_id, GConfEntry *entry, gpointer user_data) { gboolean display_arch; GConfValue *value; GtkToggleButton *arch_cb; g_assert (client != NULL); g_assert (user_data != NULL); arch_cb = GTK_TOGGLE_BUTTON (lookup_widget (user_data, DISPLAY_ARCH_CB)); g_assert (arch_cb != NULL); value = gconf_entry_get_value (entry); if (value != NULL && value->type == GCONF_VALUE_BOOL) { display_arch = gconf_value_get_bool (value); } else { display_arch = FALSE; } if (gtk_toggle_button_get_active (arch_cb) != display_arch) { gtk_toggle_button_set_active (arch_cb, display_arch); } } static void setup_gconf_notify_handlers (GConfClient *client, GtkWidget *main_win) { GString *key; guint notify_id; g_assert (client != NULL); g_assert (main_win != NULL); key = g_string_new (""); g_string_printf (key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, FIND_DLG_SEC, SHOW_ARCH); notify_id = gconf_client_notify_add (client, key->str, show_arch_change_notify, main_win, NULL, NULL); g_object_set_data (G_OBJECT (main_win), DISP_ARCH_NOTIFY, GUINT_TO_POINTER (notify_id)); g_string_free (key, TRUE); } static void remove_gconf_notify_handlers (GConfClient *client, GtkWidget *main_win) { guint notify_id; g_assert (client != NULL); g_assert (main_win != NULL); notify_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (main_win), DISP_ARCH_NOTIFY)); if (notify_id != 0) { gconf_client_notify_remove (client, notify_id); } } static void raise_or_create_pr_update_dlg (GtkWidget *find_dialog, PGconn *conn, gint pk_num) { GtkWidget *main_win; /* the application main window */ GtkWidget *upd_dlg; GList *child_list; GList *list_iter; g_assert (find_dialog != NULL); g_assert (conn != NULL); main_win = g_object_get_data (G_OBJECT (find_dialog), MY_PARENT); g_assert (main_win != NULL); /* * Go through the existing list of children first. If we have a child * that is already displaying this PR, just bring that one to the * front. * * NOTE: All of the PR update dialogs are created as "children" of * the main window, NONE are created as "children" of the find * dialog. */ child_list = g_object_get_data (G_OBJECT (main_win), pr_dlg_list); for (list_iter = g_list_first (child_list); list_iter != NULL; list_iter = list_iter->next) { if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (list_iter->data), PK_NUM)) == pk_num) { gdk_window_show (GTK_WIDGET (list_iter->data)->window); gdk_window_raise (GTK_WIDGET (list_iter->data)->window); return; } } /* * Didn't find a child already displaying the PR, so create one. */ upd_dlg = create_problem_update_dlg (main_win, conn, pk_num); gtk_widget_show (upd_dlg); child_list = g_list_append (child_list, upd_dlg); g_object_set_data (G_OBJECT (main_win), pr_dlg_list, child_list); g_signal_connect (upd_dlg, "destroy", G_CALLBACK (child_dead), (gpointer)pr_dlg_list); return; } static void draw_results_tree_list (GtkTreeView *tree, PGresult *res) { GtkSortType order; gint col; GtkListStore *old_store; GtkListStore *new_store; GtkTreeIter iter; gint i, n; g_assert (tree != NULL); g_assert (res != NULL); old_store = GTK_LIST_STORE (gtk_tree_view_get_model (tree)); gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (old_store), &col, &order); new_store = gtk_list_store_new (NUM_RESULT_COLS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT); gtk_list_store_clear (new_store); n = PQntuples (res); for (i = 0; i < n; i++) { gtk_list_store_append (new_store, &iter); gtk_list_store_set (new_store, &iter, RESULT_PR_NUM, atoi (PQgetvalue (res, i, PR_NUMBER_POS)), RESULT_PROJECT, PQgetvalue (res, i, PROJECT_NAME_POS), RESULT_STATUS, PQgetvalue (res, i, STATUS_NAME_POS), RESULT_PROBLEM_TYPE, PQgetvalue (res, i, PROBLEM_TYPE_NAME_POS), RESULT_SEVERITY, PQgetvalue (res, i, SEVERITY_NAME_POS), RESULT_TITLE, PQgetvalue (res, i, PR_TITLE_POS), RESULT_PK, atoi (PQgetvalue (res, i, PR_NUMBER_POS)), -1); } gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (new_store), col, order); gtk_tree_view_set_model (tree, GTK_TREE_MODEL (new_store)); g_object_unref (old_store); } static void fill_single_col_tree (GtkTreeView *tree, PGresult *res, gboolean pk_is_numeric) { gint i, n; GtkListStore *store; GtkTreeIter iter; g_assert (tree != NULL); g_assert (res != NULL); store = GTK_LIST_STORE (gtk_tree_view_get_model (tree)); gtk_list_store_clear (store); n = PQntuples (res); for (i = 0; i < n; i++) { gtk_list_store_append (store, &iter); if (pk_is_numeric) { gtk_list_store_set (store, &iter, ATTRIB_NAME, PQgetvalue (res, i, SQLSTR_NAME_POS), ATTRIB_PK, atoi (PQgetvalue(res, i, SQLSTR_PK_POS)), -1); } else { gtk_list_store_set (store, &iter, ATTRIB_NAME, PQgetvalue (res, i, SQLSTR_NAME_POS), ATTRIB_PK, PQgetvalue (res, i, SQLSTR_PK_POS), -1); } } } /* * draw_tree_lists * * Fill the data in all of the selection tree/lists (all tree/lists except * for the results list). * * Return TRUE if success, FALSE otherwise. */ static gboolean draw_tree_lists (PGconn *conn, GtkWidget *main_widget, gboolean include_inactive) { GtkTreeView *tree; PGresult *res; gboolean in_error = FALSE; GString *sql_buffer; GConfClient *client; g_assert (conn != NULL); g_assert (main_widget != NULL); client = g_object_get_data (G_OBJECT (main_widget), MY_GCONF_CLIENT); g_assert (client != NULL); /* * project list */ sql_buffer = g_string_new (""); prj_sql_str (sql_buffer, (include_inactive ? ALL_ITEMS : ACTIVE_ITEMS_ONLY), TRUE, TRUE, TRUE, FALSE, client, 0); res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("Getting project data"))) { tree = GTK_TREE_VIEW (lookup_widget (main_widget, PROJECT_LIST_VIEW)); g_assert (tree != NULL); fill_single_col_tree (tree, res, TRUE); } else { in_error = TRUE; } PQclear (res); /* * status list */ if (!in_error) { stat_sql_str (sql_buffer, (include_inactive ? ALL_ITEMS : ACTIVE_ITEMS_ONLY), client, 0); res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("Getting status data"))) { tree = GTK_TREE_VIEW (lookup_widget (main_widget, STATUS_LIST_VIEW)); g_assert (tree != NULL); fill_single_col_tree (tree, res, TRUE); } else { in_error = TRUE; } PQclear (res); } /* * problem type list */ if (!in_error) { pr_type_sql_str (sql_buffer, (include_inactive ? ALL_ITEMS : ACTIVE_ITEMS_ONLY), client, 0); res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("Getting problem type data"))) { tree = GTK_TREE_VIEW (lookup_widget (main_widget, PROBLEM_TYPE_LIST_VIEW)); g_assert (tree != NULL); fill_single_col_tree (tree, res, TRUE); } else { in_error = TRUE; } PQclear (res); } /* * severity list */ if (!in_error) { sevr_sql_str (sql_buffer, (include_inactive ? ALL_ITEMS : ACTIVE_ITEMS_ONLY), client, 0); res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("Getting severity data"))) { tree = GTK_TREE_VIEW (lookup_widget (main_widget, SEVERITY_LIST_VIEW)); g_assert (tree != NULL); fill_single_col_tree (tree, res, TRUE); } else { in_error = TRUE; } PQclear (res); } /* * submitter list */ if (!in_error) { sql_buffer = g_string_assign (sql_buffer, SELECT_SUBMITTER); if (!include_inactive) { sql_buffer = g_string_append (sql_buffer, NO_INACTIVE); } sql_buffer = g_string_append (sql_buffer, SUB_RESP_ORDER_BY); res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("Getting submitter data"))) { tree = GTK_TREE_VIEW (lookup_widget (main_widget, SUBMITTER_LIST_VIEW)); g_assert (tree != NULL); fill_single_col_tree (tree, res, FALSE); } else { in_error = TRUE; } PQclear (res); } /* * responsible list */ if (!in_error) { sql_buffer = g_string_assign (sql_buffer, SELECT_RESPONSIBLE); if (!include_inactive) { sql_buffer = g_string_append (sql_buffer, NO_INACTIVE); } sql_buffer = g_string_append (sql_buffer, SUB_RESP_ORDER_BY); res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("Getting responsible data"))) { tree = GTK_TREE_VIEW (lookup_widget (main_widget, RESPONSIBLE_LIST_VIEW)); g_assert (tree != NULL); fill_single_col_tree (tree, res, FALSE); } else { in_error = TRUE; } PQclear (res); } return !in_error; } static void on_display_arch_toggled (GtkWidget *widget, gpointer user_data) { GConfClient *client; gboolean value; GString *key; PGconn *conn; g_assert (widget != NULL); g_assert (user_data != NULL); conn = g_object_get_data (G_OBJECT (user_data), MY_DB_CONN); g_assert (conn != NULL); client = g_object_get_data (G_OBJECT (user_data), MY_GCONF_CLIENT); g_assert (client != NULL); key = g_string_new (""); g_string_printf (key, "%s/%s/%s/%s", BASE_KEY, WINSTATES, FIND_DLG_SEC, SHOW_ARCH); value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); gconf_client_set_bool (client, key->str, value, NULL); g_string_free (key, TRUE); } static void on_find_dlg_show (GtkWidget *window, gpointer user_data) { PGconn *conn; GtkToggleButton *inactive_cb; GtkToggleButton *arch_cb; GString *config_str; gboolean flag; GConfClient *client; GError *error = NULL; g_assert (window != NULL); conn = g_object_get_data (G_OBJECT (window), MY_DB_CONN); g_assert (conn != NULL); client = g_object_get_data (G_OBJECT (window), MY_GCONF_CLIENT); g_assert (client != NULL); inactive_cb = GTK_TOGGLE_BUTTON (lookup_widget (window, INACTIVE_CHECK_BOX)); g_assert (inactive_cb != NULL); arch_cb = GTK_TOGGLE_BUTTON (lookup_widget (window, DISPLAY_ARCH_CB)); g_assert (arch_cb != NULL); config_str = g_string_new (""); g_string_printf (config_str, "%s/%s/%s/%s", BASE_KEY, WINSTATES, FIND_DLG_SEC, SHOW_INACT); flag = gconf_client_get_bool (client, config_str->str, &error); if (error != NULL) { g_warning (error->message); g_error_free (error); error = NULL; flag = FALSE; } gtk_toggle_button_set_active (inactive_cb, flag); g_string_printf (config_str, "%s/%s/%s/%s", BASE_KEY, WINSTATES, FIND_DLG_SEC, SHOW_ARCH); flag = gconf_client_get_bool (client, config_str->str, &error); if (error != NULL) { g_warning (error->message); g_error_free (error); error = NULL; flag = FALSE; } gtk_toggle_button_set_active (arch_cb, flag); g_string_free (config_str, TRUE); if (!draw_tree_lists (conn, window, flag)) { gtk_widget_destroy (window); } g_signal_connect (arch_cb, "toggled", G_CALLBACK (on_display_arch_toggled), window); setup_gconf_notify_handlers (client, window); return; } static void on_find_dlg_destroy (GtkWidget *window, gpointer user_data) { GString *config_str; GtkToggleButton *cb; GConfClient *client; g_assert (window != NULL); config_str = g_string_new (""); client = g_object_get_data (G_OBJECT (window), MY_GCONF_CLIENT); g_assert (client != NULL); cb = GTK_TOGGLE_BUTTON (lookup_widget (window, INACTIVE_CHECK_BOX)); g_assert (cb != NULL); g_string_printf (config_str, "%s/%s/%s/%s", BASE_KEY, WINSTATES, FIND_DLG_SEC, SHOW_INACT); gconf_client_set_bool (client, config_str->str, gtk_toggle_button_get_active (cb), NULL); g_string_free (config_str, TRUE); remove_gconf_notify_handlers (client, window); return; } static gint find_order_by_pos (const gchar *sql) { gchar *curr; gint diff; g_assert (sql != NULL); /* * If this is a properly formed query from libPRepS (and it should * be), there will be ONE and ONLY ONE "ORDER BY"... */ curr = strstr (sql, "ORDER BY"); g_assert (curr != NULL); diff = (gint)(curr - sql); return diff; } /* * These "append" functions are all called by * gtk_tree_selection_selected_foreach(). They are all _very_ similar, and * I should probably look at merging them at some point. For now, however, * this works, and I doubt there will be much maint required.... */ static void append_problem_type (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gint pk; g_assert (model != NULL); g_assert (path != NULL); g_assert (iter != NULL); g_assert (data != NULL); gtk_tree_model_get (model, iter, ATTRIB_PK, &pk, -1); add_problem_type_restriction (data, pk); } static void append_project (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gint pk; g_assert (model != NULL); g_assert (path != NULL); g_assert (iter != NULL); g_assert (data != NULL); gtk_tree_model_get (model, iter, ATTRIB_PK, &pk, -1); add_project_restriction (data, pk); } static void append_responsible (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gchar *id; g_assert (model != NULL); g_assert (path != NULL); g_assert (iter != NULL); g_assert (data != NULL); gtk_tree_model_get (model, iter, ATTRIB_PK, &id, -1); add_responsible_restriction (data, id); g_free (id); } static void append_severity (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gint pk; g_assert (model != NULL); g_assert (path != NULL); g_assert (iter != NULL); g_assert (data != NULL); gtk_tree_model_get (model, iter, ATTRIB_PK, &pk, -1); add_severity_restriction (data, pk); } static void append_status (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gint pk; g_assert (model != NULL); g_assert (path != NULL); g_assert (iter != NULL); g_assert (data != NULL); gtk_tree_model_get (model, iter, ATTRIB_PK, &pk, -1); add_status_restriction (data, pk); } static void append_submitter (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { gchar *id; g_assert (model != NULL); g_assert (path != NULL); g_assert (iter != NULL); g_assert (data != NULL); gtk_tree_model_get (model, iter, ATTRIB_PK, &id, -1); add_submitter_restriction (data, id); g_free (id); } static void find_prs (GtkDialog *dlg) { pr_query_struct *query; PGconn *conn; GtkWidget *main_widget; PGresult *res; GString *sql_buffer; GString *text_str; GtkEntry *text_entry; gchar *text_buf; GtkToggleButton *cb; GString *text_search_str = NULL; gchar oper[5]; gboolean search_title; gboolean search_descr; gboolean search_fix; gboolean search_change_log; gboolean search_all; gboolean add_or; GtkTreeSelection *sel; GtkTreeView *tree; GdkCursor *cursor; gboolean show_arch; g_assert (dlg != NULL); /* * Depending upon what is being searched for, this may take a bit * of time. Set the cursor for this window to a wait cursor. */ cursor = gdk_cursor_new (GDK_WATCH); gdk_window_set_cursor (GTK_WIDGET (dlg)->window, cursor); gdk_cursor_unref (cursor); while (gtk_events_pending()) { gtk_main_iteration(); } /* * Setup any preliminary data that is needed. */ main_widget = GTK_WIDGET (dlg); conn = g_object_get_data (G_OBJECT (dlg), MY_DB_CONN); g_assert (conn != NULL); query = create_pr_query (PQuser (conn)); /* * Get any project restrictions. */ tree = GTK_TREE_VIEW (lookup_widget (main_widget, PROJECT_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_selected_foreach (sel, append_project, query); /* * Get any status restrictions. */ tree = GTK_TREE_VIEW (lookup_widget (main_widget, STATUS_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_selected_foreach (sel, append_status, query); /* * Get any problem type restrictions. */ tree = GTK_TREE_VIEW (lookup_widget (main_widget, PROBLEM_TYPE_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_selected_foreach (sel, append_problem_type, query); /* * Get any severity restrictions. */ tree = GTK_TREE_VIEW (lookup_widget (main_widget, SEVERITY_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_selected_foreach (sel, append_severity, query); /* * Get any submitter restrictions. */ tree = GTK_TREE_VIEW (lookup_widget (main_widget, SUBMITTER_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_selected_foreach (sel, append_submitter, query); /* * Get any responsible restrictions. */ tree = GTK_TREE_VIEW (lookup_widget (main_widget, RESPONSIBLE_LIST_VIEW)); g_assert (tree != NULL); sel = gtk_tree_view_get_selection (tree); gtk_tree_selection_selected_foreach (sel, append_responsible, query); /* * Get any text seach restrictions */ text_entry = GTK_ENTRY (lookup_widget (main_widget, TEXT_ENTRY)); text_buf = (gchar *)gtk_entry_get_text (text_entry); if (strlen (text_buf) != 0) { text_str = g_string_new (text_buf); g_string_prepare_db_instr (text_str); cb = GTK_TOGGLE_BUTTON (lookup_widget (main_widget, TITLE_CB)); search_title = gtk_toggle_button_get_active (cb); cb = GTK_TOGGLE_BUTTON (lookup_widget (main_widget, DESCR_CB)); search_descr = gtk_toggle_button_get_active (cb); cb = GTK_TOGGLE_BUTTON (lookup_widget (main_widget, FIX_CB)); search_fix = gtk_toggle_button_get_active (cb); cb = GTK_TOGGLE_BUTTON (lookup_widget (main_widget, CHANGE_LOG_CB)); search_change_log = gtk_toggle_button_get_active (cb); /* * If they have none of them checked, just search them all... */ search_all = !(search_title || search_descr || search_fix || search_change_log); cb = GTK_TOGGLE_BUTTON (lookup_widget (main_widget, IGNORE_CASE_CB)); g_assert (cb != NULL); if (gtk_toggle_button_get_active (cb)) { strcpy (oper, " ~* "); } else { strcpy (oper, " ~ " ); } text_search_str = g_string_new (" AND ("); add_or = FALSE; if (search_title || search_all) { text_search_str = g_string_append (text_search_str, "pr.title"); text_search_str = g_string_append (text_search_str, oper); text_search_str = g_string_append (text_search_str, text_str->str); add_or = TRUE; } if (search_descr || search_all) { if (add_or) { text_search_str = g_string_append (text_search_str, " OR "); } text_search_str = g_string_append (text_search_str, "pr.descr"); text_search_str = g_string_append (text_search_str, oper); text_search_str = g_string_append (text_search_str, text_str->str); add_or = TRUE; } if (search_fix || search_all) { if (add_or) { text_search_str = g_string_append (text_search_str, " OR "); } text_search_str = g_string_append (text_search_str, "pr.fix"); text_search_str = g_string_append (text_search_str, oper); text_search_str = g_string_append (text_search_str, text_str->str); add_or = TRUE; } if (search_change_log || search_all) { if (add_or) { text_search_str = g_string_append (text_search_str, " OR "); } text_search_str = g_string_append (text_search_str, "pr.change_log_text"); text_search_str = g_string_append (text_search_str, oper); text_search_str = g_string_append (text_search_str, text_str->str); add_or = TRUE; } text_search_str = g_string_append (text_search_str, ") "); } cb = GTK_TOGGLE_BUTTON (lookup_widget (main_widget, DISPLAY_ARCH_CB)); g_assert (cb != NULL); show_arch = gtk_toggle_button_get_active (cb); /* * Execute the query and display the results. */ tree = GTK_TREE_VIEW (lookup_widget (main_widget, RESULTS_LIST_VIEW)); g_assert (tree != NULL); sql_buffer = create_query_string (query, show_arch); if (text_search_str != NULL) { sql_buffer = g_string_insert (sql_buffer, find_order_by_pos (sql_buffer->str), text_search_str->str); g_string_free (text_search_str, TRUE); } res = PQexec (conn, sql_buffer->str); if (chk_sql_error (res, _("Executing find query"))) { draw_results_tree_list (tree, res); } destroy_pr_query (query); g_string_free (sql_buffer, TRUE); PQclear (res); gdk_window_set_cursor (GTK_WIDGET (dlg)->window, NULL); } static void modify_selected_pr (GtkDialog *dlg) { PGconn *conn; GtkTreeIter iter; GtkTreeView *tree; GtkListStore *store; GtkTreeSelection *sel; gint pk_num; GtkWidget *msg_dlg; g_assert (dlg != 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), RESULTS_LIST_VIEW)); g_assert (tree != NULL); store = GTK_LIST_STORE (gtk_tree_view_get_model (tree)); sel = gtk_tree_view_get_selection (tree); /* * The user must have selected a PR to modify. */ if (!gtk_tree_selection_get_selected (sel, NULL, &iter)) { msg_dlg = gtk_message_dialog_new (GTK_WINDOW (dlg), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, _("You must select a problem to modify.")); gtk_dialog_run (GTK_DIALOG (msg_dlg)); gtk_widget_destroy (msg_dlg); return; } gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, RESULT_PK, &pk_num, -1); raise_or_create_pr_update_dlg (GTK_WIDGET (dlg), conn, pk_num); return; } static void dismiss_dlg (GtkDialog *dlg) { GConfClient *client; g_assert (dlg != NULL); client = g_object_get_data (G_OBJECT (dlg), MY_GCONF_CLIENT); g_assert (client != NULL); save_dlg_size (client, GTK_WIDGET (dlg), FIND_DLG_SEC); gtk_widget_destroy (GTK_WIDGET (dlg)); } static void on_mod_menu_item (GtkWidget *widget, gpointer user_data) { g_assert (widget != NULL); g_assert (user_data != NULL); modify_selected_pr (GTK_DIALOG (user_data)); } static void on_find_dlg_clicked (GtkDialog *dlg, gint btn_cd, gpointer user_data) { g_assert (dlg != NULL); switch (btn_cd) { case RESPONSE_FIND: find_prs (dlg); break; case RESPONSE_OPEN: modify_selected_pr (dlg); break; case GTK_RESPONSE_CLOSE: dismiss_dlg (dlg); break; case GTK_RESPONSE_DELETE_EVENT: break; default: g_assert_not_reached(); } } static void on_inactive_cb_toggled (GtkToggleButton *togglebutton, gpointer user_data) { GtkToggleButton *inactive_cb; PGconn *conn; g_assert (togglebutton != NULL); g_assert (user_data != NULL); inactive_cb = GTK_TOGGLE_BUTTON (lookup_widget (GTK_WIDGET (user_data), INACTIVE_CHECK_BOX)); conn = g_object_get_data (G_OBJECT (user_data), MY_DB_CONN); g_assert (conn != NULL); draw_tree_lists (conn, GTK_WIDGET (user_data), gtk_toggle_button_get_active (inactive_cb)); } static gboolean on_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data) { static GtkMenu *popup = NULL; GtkWidget *main_win = GTK_WIDGET (user_data); GtkWidget *item; GtkTreeModel *model; GtkTreeSelection *sel; GtkTreeIter iter; GtkTreePath *path; PGconn *conn; gint pk_num; gboolean handled = FALSE; g_assert (widget != NULL); g_assert (user_data != NULL); if (popup == NULL) { popup = GTK_MENU (gtk_menu_new ()); gtk_widget_show (GTK_WIDGET (popup)); item = gtk_menu_item_new_with_label (_("Edit...")); g_signal_connect (item, "activate", G_CALLBACK (on_mod_menu_item), user_data); gtk_menu_shell_append (GTK_MENU_SHELL (popup), item); gtk_widget_show (item); } if (event != NULL) { switch (event->button) { case 1: switch (event->type) { case GDK_2BUTTON_PRESS: handled = TRUE; model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); if (gtk_tree_selection_get_selected (sel, NULL, &iter)) { gtk_tree_model_get (model, &iter, RESULT_PK, &pk_num, -1); conn = g_object_get_data (G_OBJECT (main_win), MY_DB_CONN); g_assert (conn != NULL); raise_or_create_pr_update_dlg (main_win, conn, pk_num); } break; default: break; } break; case 2: break; case 3: switch (event->type) { case GDK_BUTTON_PRESS: handled = TRUE; if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), event->x, event->y, &path, NULL, NULL, NULL)) { sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); gtk_tree_selection_select_path (sel, path); gtk_menu_popup (popup, NULL, NULL, NULL, NULL, event->button, event->time); gtk_tree_path_free (path); } break; default: break; } break; default: break; } } return handled; } static GtkWidget * create_find_dlg (GtkWidget *parent, PGconn *conn) { GtkWidget *find_dlg; GtkWidget *dialog_vbox1; GtkWidget *vbox1; GtkWidget *table1; GtkWidget *label; GtkCellRenderer *rend; GtkTreeViewColumn *col; GtkTreeSelection *sel; GtkWidget *sub_scrolledwindow; GtkWidget *submitter_list_view; GtkListStore *submitter_list_store; GtkWidget *resp_scrolledwindow; GtkWidget *responsible_list_view; GtkListStore *responsible_list_store; GtkWidget *prj_scrolledwindow; GtkWidget *project_list_view; GtkListStore *project_list_store; GtkWidget *stat_scrolledwindow; GtkWidget *status_list_view; GtkListStore *status_list_store; GtkWidget *pt_scrolledwindow; GtkWidget *problem_type_list_view; GtkListStore *problem_type_list_store; GtkWidget *sevr_scrolledwindow; GtkWidget *severity_list_view; GtkListStore *severity_list_store; GtkWidget *res_scrolledwindow; GtkWidget *results_list_view; GtkListStore *results_list_store; GtkWidget *inactive_cb; GtkWidget *hbox; GtkWidget *inner_hbox; GtkWidget *text_lbl; GtkWidget *text_entry; GtkWidget *sep; GtkWidget *cb; GtkTooltips *tooltips; GConfClient *client; g_assert (parent != NULL); g_assert (conn != 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); /* * I don't want this dialog to act like it has a parent (this gets * annoying with this type of dialog. Thus, I don't give a parent, * the logically is has one... */ find_dlg = gtk_dialog_new_with_buttons (_("Find Problem Reports"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_FIND, RESPONSE_FIND, GTK_STOCK_OPEN, RESPONSE_OPEN, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL); GLADE_HOOKUP_OBJECT_NO_REF (find_dlg, find_dlg, "find_dlg"); gtk_container_set_border_width (GTK_CONTAINER (find_dlg), 5); gtk_window_set_resizable (GTK_WINDOW (find_dlg), TRUE); g_signal_connect (find_dlg, "show", G_CALLBACK (on_find_dlg_show), NULL); g_signal_connect (find_dlg, "destroy", G_CALLBACK (on_find_dlg_destroy), NULL); g_signal_connect (find_dlg, "response", G_CALLBACK (on_find_dlg_clicked), NULL); g_object_set_data (G_OBJECT (find_dlg), TOP_DOG, find_dlg); g_object_set_data (G_OBJECT (find_dlg), MY_PARENT, parent); g_object_set_data (G_OBJECT (find_dlg), MY_DB_CONN, conn); g_object_set_data (G_OBJECT (find_dlg), MY_GCONF_CLIENT, client); set_dlg_size (client, find_dlg, FIND_DLG_SEC, 630, 400); dialog_vbox1 = GTK_DIALOG (find_dlg)->vbox; gtk_widget_show (dialog_vbox1); vbox1 = gtk_vbox_new (FALSE, 0); GLADE_HOOKUP_OBJECT (find_dlg, vbox1, "vbox1"); gtk_widget_show (vbox1); gtk_box_pack_start (GTK_BOX (dialog_vbox1), vbox1, TRUE, TRUE, 0); table1 = gtk_table_new (4, 4, FALSE); GLADE_HOOKUP_OBJECT (find_dlg, table1, "table1"); gtk_widget_show (table1); gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0); gtk_table_set_row_spacings (GTK_TABLE (table1), 2); gtk_table_set_col_spacings (GTK_TABLE (table1), 7); label = gtk_label_new (_("Status")); GLADE_HOOKUP_OBJECT (find_dlg, label, "label1"); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table1), label, 1, 2, 2, 3, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (_("Problem Type")); GLADE_HOOKUP_OBJECT (find_dlg, label, "label2"); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table1), label, 0, 1, 2, 3, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (_("Severity")); GLADE_HOOKUP_OBJECT (find_dlg, label, "label3"); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table1), label, 1, 2, 0, 1, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (_("Submitter")); GLADE_HOOKUP_OBJECT (find_dlg, label, "label4"); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table1), label, 2, 3, 0, 1, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (_("Responsible")); GLADE_HOOKUP_OBJECT (find_dlg, label, "label5"); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table1), label, 3, 4, 0, 1, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); label = gtk_label_new (_("Project")); GLADE_HOOKUP_OBJECT (find_dlg, label, "label6"); gtk_widget_show (label); gtk_table_attach (GTK_TABLE (table1), label, 0, 1, 0, 1, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); sub_scrolledwindow = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (find_dlg, sub_scrolledwindow, "sub_scrolledwindow"); gtk_widget_show (sub_scrolledwindow); gtk_table_attach (GTK_TABLE (table1), sub_scrolledwindow, 2, 3, 1, 4, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sub_scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sub_scrolledwindow), GTK_SHADOW_ETCHED_IN); submitter_list_store = gtk_list_store_new (NUM_ATTRIB_COLS, G_TYPE_STRING, G_TYPE_STRING); submitter_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (submitter_list_store)); GLADE_HOOKUP_OBJECT (find_dlg, submitter_list_view, SUBMITTER_LIST_VIEW); gtk_widget_show (submitter_list_view); gtk_container_add (GTK_CONTAINER (sub_scrolledwindow), submitter_list_view); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (col, rend, TRUE); gtk_tree_view_column_set_attributes (col, rend, "text", ATTRIB_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (submitter_list_view), col); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (submitter_list_view), FALSE); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (submitter_list_view)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); resp_scrolledwindow = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (find_dlg, resp_scrolledwindow, "resp_scrolledwindow"); gtk_widget_show (resp_scrolledwindow); gtk_table_attach (GTK_TABLE (table1), resp_scrolledwindow, 3, 4, 1, 4, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (resp_scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (resp_scrolledwindow), GTK_SHADOW_ETCHED_IN); responsible_list_store = gtk_list_store_new (NUM_ATTRIB_COLS, G_TYPE_STRING, G_TYPE_STRING); responsible_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (responsible_list_store)); GLADE_HOOKUP_OBJECT (find_dlg, responsible_list_view, RESPONSIBLE_LIST_VIEW); gtk_widget_show (responsible_list_view); gtk_container_add (GTK_CONTAINER (resp_scrolledwindow), responsible_list_view); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (col, rend, TRUE); gtk_tree_view_column_set_attributes (col, rend, "text", ATTRIB_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (responsible_list_view), col); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (responsible_list_view), FALSE); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (responsible_list_view)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); prj_scrolledwindow = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (find_dlg, prj_scrolledwindow, "prj_scrolledwindow"); gtk_widget_show (prj_scrolledwindow); gtk_table_attach (GTK_TABLE (table1), prj_scrolledwindow, 0, 1, 1, 2, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (prj_scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (prj_scrolledwindow), GTK_SHADOW_ETCHED_IN); project_list_store = gtk_list_store_new (NUM_ATTRIB_COLS, G_TYPE_STRING, G_TYPE_INT); project_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (project_list_store)); GLADE_HOOKUP_OBJECT (find_dlg, project_list_view, PROJECT_LIST_VIEW); gtk_widget_show (project_list_view); gtk_container_add (GTK_CONTAINER (prj_scrolledwindow), project_list_view); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (col, rend, TRUE); gtk_tree_view_column_set_attributes (col, rend, "text", ATTRIB_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (project_list_view), col); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (project_list_view), FALSE); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (project_list_view)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); stat_scrolledwindow = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (find_dlg, stat_scrolledwindow, "stat_scrolledwindow"); gtk_widget_show (stat_scrolledwindow); gtk_table_attach (GTK_TABLE (table1), stat_scrolledwindow, 1, 2, 3, 4, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (stat_scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (stat_scrolledwindow), GTK_SHADOW_ETCHED_IN); status_list_store = gtk_list_store_new (NUM_ATTRIB_COLS, G_TYPE_STRING, G_TYPE_INT); status_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (status_list_store)); GLADE_HOOKUP_OBJECT (find_dlg, status_list_view, STATUS_LIST_VIEW); gtk_widget_show (status_list_view); gtk_container_add (GTK_CONTAINER (stat_scrolledwindow), status_list_view); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (col, rend, TRUE); gtk_tree_view_column_set_attributes (col, rend, "text", ATTRIB_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (status_list_view), col); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (status_list_view), FALSE); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (status_list_view)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); pt_scrolledwindow = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (find_dlg, pt_scrolledwindow, "pt_scrolledwindow"); gtk_widget_show (pt_scrolledwindow); gtk_table_attach (GTK_TABLE (table1), pt_scrolledwindow, 0, 1, 3, 4, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (pt_scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (pt_scrolledwindow), GTK_SHADOW_ETCHED_IN); problem_type_list_store = gtk_list_store_new (NUM_ATTRIB_COLS, G_TYPE_STRING, G_TYPE_INT); problem_type_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (problem_type_list_store)); GLADE_HOOKUP_OBJECT (find_dlg, problem_type_list_view, PROBLEM_TYPE_LIST_VIEW); gtk_widget_show (problem_type_list_view); gtk_container_add (GTK_CONTAINER (pt_scrolledwindow), problem_type_list_view); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (col, rend, TRUE); gtk_tree_view_column_set_attributes (col, rend, "text", ATTRIB_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (problem_type_list_view), col); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (problem_type_list_view), FALSE); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (problem_type_list_view)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); sevr_scrolledwindow = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (find_dlg, sevr_scrolledwindow, "sevr_scrolledwindow"); gtk_widget_show (sevr_scrolledwindow); gtk_table_attach (GTK_TABLE (table1), sevr_scrolledwindow, 1, 2, 1, 2, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sevr_scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sevr_scrolledwindow), GTK_SHADOW_ETCHED_IN); severity_list_store = gtk_list_store_new (NUM_ATTRIB_COLS, G_TYPE_STRING, G_TYPE_INT); severity_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (severity_list_store)); GLADE_HOOKUP_OBJECT (find_dlg, severity_list_view, SEVERITY_LIST_VIEW); gtk_widget_show (severity_list_view); gtk_container_add (GTK_CONTAINER (sevr_scrolledwindow), severity_list_view); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (col, rend, TRUE); gtk_tree_view_column_set_attributes (col, rend, "text", ATTRIB_NAME, NULL); gtk_tree_view_append_column (GTK_TREE_VIEW (severity_list_view), col); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (severity_list_view), FALSE); sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (severity_list_view)); gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); inactive_cb = gtk_check_button_new_with_label (_("Display inactive items")); GLADE_HOOKUP_OBJECT (find_dlg, inactive_cb, INACTIVE_CHECK_BOX); gtk_widget_show (inactive_cb); g_signal_connect (inactive_cb, "toggled", G_CALLBACK (on_inactive_cb_toggled), find_dlg); gtk_box_pack_start (GTK_BOX (vbox1), inactive_cb, FALSE, FALSE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (inactive_cb), FALSE); gtk_tooltips_set_tip (tooltips, inactive_cb, _("Check this box to display all statuses, problem types, severities, and projects, even if those items are inactive. Otherwise only active items are shown."), NULL); sep = gtk_hseparator_new (); GLADE_HOOKUP_OBJECT (find_dlg, sep, "hsep1"); gtk_widget_show (sep); gtk_box_pack_start (GTK_BOX (vbox1), sep, FALSE, FALSE, 2); hbox = gtk_hbox_new (FALSE, 5); GLADE_HOOKUP_OBJECT (find_dlg, hbox, "hbox1"); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (vbox1), hbox, FALSE, FALSE, 0); inner_hbox = gtk_hbox_new (FALSE, 2); GLADE_HOOKUP_OBJECT (find_dlg, inner_hbox, "hbox2"); gtk_widget_show (inner_hbox); gtk_box_pack_start (GTK_BOX (hbox), inner_hbox, TRUE, TRUE, 0); text_lbl = gtk_label_new (_("Text:")); GLADE_HOOKUP_OBJECT (find_dlg, text_lbl, "label7"); gtk_box_pack_start (GTK_BOX (inner_hbox), text_lbl, FALSE, FALSE, 0); gtk_widget_show (text_lbl); text_entry = gtk_entry_new(); GLADE_HOOKUP_OBJECT (find_dlg, text_entry, TEXT_ENTRY); gtk_box_pack_start (GTK_BOX (inner_hbox), text_entry, TRUE, TRUE, 0); gtk_widget_show (text_entry); cb = gtk_check_button_new_with_label (_("Ignore Case")); GLADE_HOOKUP_OBJECT (find_dlg, cb, IGNORE_CASE_CB); gtk_box_pack_start (GTK_BOX (hbox), cb, FALSE, FALSE, 0); gtk_widget_show (cb); hbox = gtk_hbox_new (FALSE, 5); GLADE_HOOKUP_OBJECT (find_dlg, hbox, "hbox3"); gtk_box_pack_start (GTK_BOX (vbox1), hbox, FALSE, FALSE, 3); gtk_widget_show (hbox); text_lbl = gtk_label_new (_("Limit Text Search To:")); GLADE_HOOKUP_OBJECT (find_dlg, text_lbl, "label8"); gtk_box_pack_start (GTK_BOX (hbox), text_lbl, FALSE, FALSE, 0); gtk_widget_show (text_lbl); cb = gtk_check_button_new_with_label (_("Title")); GLADE_HOOKUP_OBJECT (find_dlg, cb, TITLE_CB); gtk_box_pack_start (GTK_BOX (hbox), cb, FALSE, FALSE, 0); gtk_widget_show (cb); cb = gtk_check_button_new_with_label (_("Description")); GLADE_HOOKUP_OBJECT (find_dlg, cb, DESCR_CB); gtk_box_pack_start (GTK_BOX (hbox), cb, FALSE, FALSE, 0); gtk_widget_show (cb); cb = gtk_check_button_new_with_label (_("Fix Description")); GLADE_HOOKUP_OBJECT (find_dlg, cb, FIX_CB); gtk_box_pack_start (GTK_BOX (hbox), cb, FALSE, FALSE, 0); gtk_widget_show (cb); cb = gtk_check_button_new_with_label (_("ChangeLog Description")); GLADE_HOOKUP_OBJECT (find_dlg, cb, CHANGE_LOG_CB); gtk_box_pack_start (GTK_BOX (hbox), cb, FALSE, FALSE, 0); gtk_widget_show (cb); cb = gtk_check_button_new_with_label (_("Include Archived Problem Reports")); GLADE_HOOKUP_OBJECT (find_dlg, cb, DISPLAY_ARCH_CB); gtk_box_pack_start (GTK_BOX (vbox1), cb, FALSE, FALSE, 0); gtk_widget_show (cb); sep = gtk_hseparator_new (); GLADE_HOOKUP_OBJECT (find_dlg, sep, "hsep2"); gtk_widget_show (sep); gtk_box_pack_start (GTK_BOX (vbox1), sep, FALSE, FALSE, 0); res_scrolledwindow = gtk_scrolled_window_new (NULL, NULL); GLADE_HOOKUP_OBJECT (find_dlg, res_scrolledwindow, "res_scrolledwindow"); gtk_widget_show (res_scrolledwindow); gtk_box_pack_start (GTK_BOX (vbox1), res_scrolledwindow, TRUE, TRUE, 0); gtk_container_set_border_width (GTK_CONTAINER (res_scrolledwindow), 5); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (res_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (res_scrolledwindow), GTK_SHADOW_ETCHED_IN); results_list_store = gtk_list_store_new (NUM_RESULT_COLS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT); results_list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (results_list_store)); GLADE_HOOKUP_OBJECT (find_dlg, results_list_view, RESULTS_LIST_VIEW); g_signal_connect (G_OBJECT (results_list_view), "button-press-event", G_CALLBACK (on_button_press_event), find_dlg); gtk_widget_show (results_list_view); gtk_container_add (GTK_CONTAINER (res_scrolledwindow), results_list_view); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("PR#"), rend, "text", RESULT_PR_NUM, NULL); gtk_tree_view_column_set_sort_column_id (col, RESULT_PR_NUM); gtk_tree_view_append_column (GTK_TREE_VIEW (results_list_view), col); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Project"), rend, "text", RESULT_PROJECT, NULL); gtk_tree_view_column_set_sort_column_id (col, RESULT_PROJECT); gtk_tree_view_append_column (GTK_TREE_VIEW (results_list_view), col); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Status"), rend, "text", RESULT_STATUS, NULL); gtk_tree_view_column_set_sort_column_id (col, RESULT_STATUS); gtk_tree_view_append_column (GTK_TREE_VIEW (results_list_view), col); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Problem Type"), rend, "text", RESULT_PROBLEM_TYPE, NULL); gtk_tree_view_column_set_sort_column_id (col, RESULT_PROBLEM_TYPE); gtk_tree_view_append_column (GTK_TREE_VIEW (results_list_view), col); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Severity"), rend, "text", RESULT_SEVERITY, NULL); gtk_tree_view_column_set_sort_column_id (col, RESULT_SEVERITY); gtk_tree_view_append_column (GTK_TREE_VIEW (results_list_view), col); rend = gtk_cell_renderer_text_new (); col = gtk_tree_view_column_new_with_attributes (_("Title"), rend, "text", RESULT_TITLE, NULL); gtk_tree_view_column_set_sort_column_id (col, RESULT_TITLE); gtk_tree_view_append_column (GTK_TREE_VIEW (results_list_view), col); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (results_list_view), TRUE); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (results_list_store), RESULT_PR_NUM, GTK_SORT_ASCENDING); g_object_set_data (G_OBJECT (find_dlg), TOOLTIPS, tooltips); return find_dlg; } void destroy_find_dlg (void) { if (find_dlg != NULL) { gtk_widget_destroy (find_dlg); find_dlg = NULL; } } void show_find_dlg (GtkWidget *parent, PGconn *conn) { g_assert (parent != NULL); g_assert (conn != NULL); /* * If the dialog box exists, just make sure it is visable, otherwise * create it. */ if (find_dlg) { gdk_window_show (find_dlg->window); gdk_window_raise (find_dlg->window); } else { find_dlg = create_find_dlg (parent, conn); /* * When the dialog is destroyed, call gtk_widget_destroyed(), * which will set the "user_data" (&find_dlg in this case) to * NULL. */ g_signal_connect (find_dlg, "destroy", G_CALLBACK (gtk_widget_destroyed), &find_dlg); gtk_widget_show (find_dlg); } }