29#include <glib/gi18n.h>
31#include "dialog-utils.h"
32#include "gnc-component-manager.h"
35#include "gnc-gui-query.h"
36#include "gnc-query-view.h"
38#include "gnc-session.h"
40#include "engine-helpers.h"
41#include "qofbookslots.h"
45#include "dialog-search.h"
46#include "search-core-type.h"
47#include "search-param.h"
50static QofLogModule log_module = G_LOG_DOMAIN;
52#define DIALOG_SEARCH_CM_CLASS "dialog-search"
53#define GNC_PREFS_GROUP_SEARCH_GENERAL "dialogs.search"
54#define GNC_PREF_NEW_SEARCH_LIMIT "new-search-limit"
55#define GNC_PREF_ACTIVE_ONLY "search-for-active-only"
59 GNC_SEARCH_MATCH_ALL = 0,
60 GNC_SEARCH_MATCH_ANY = 1
73 GtkWidget *grouping_combo;
74 GtkWidget *match_all_label;
75 GtkWidget *criteria_table;
76 GtkWidget *criteria_scroll_window;
77 GtkWidget *result_hbox;
80 GtkWidget *result_view;
87 GtkWidget *active_only_check;
90 GtkWidget *select_button;
94 GtkWidget *close_button;
95 GtkWidget *cancel_button;
98 GNCSearchResultCB result_cb;
99 GNCSearchNewItemCB new_item_cb;
101 GNCSearchFree free_cb;
104 GNCSearchSelectedCB selected_cb;
106 gboolean allow_clear;
109 const gchar *type_label;
111 GNCSearchType grouping;
112 const QofParam *get_guid;
120 GNCSearchParam *last_param;
127 const gchar *prefs_group;
132 GNCSearchParam *param;
133 GNCSearchCoreType *element;
134 GtkWidget *elemwidget;
135 GtkWidget *container;
140static void search_clear_criteria (GNCSearchWindow *sw);
141static void gnc_search_dialog_display_results (GNCSearchWindow *sw);
147 GNCQueryView *qview = GNC_QUERY_VIEW(sw->result_view);
153 if (cb->cb_multiselect_fn && (!cb->cb_fcn ))
155 GList *entries = gnc_query_view_get_selected_entry_list (qview);
157 (cb->cb_multiselect_fn)(GTK_WINDOW (sw->dialog), entries, sw->user_data);
158 g_list_free (entries);
163 gpointer entry = gnc_query_view_get_selected_entry (qview);
165 (cb->cb_fcn)(GTK_WINDOW (sw->dialog), &entry, sw->user_data);
170gnc_search_dialog_result_clicked (GtkButton *button, GNCSearchWindow *sw)
174 cb = g_object_get_data (G_OBJECT (button),
"data");
175 gnc_search_callback_button_execute (cb, sw);
179gnc_search_dialog_select_buttons_enable (GNCSearchWindow *sw, gint selected)
181 gboolean enable, read_only;
186 for (blist = sw->button_list; blist; blist = blist->next)
192 gtk_widget_set_sensitive (GTK_WIDGET(blist->data), FALSE);
196 if(read_only == TRUE)
198 if((selected > 1) && (!(button_spec->cb_multiselect_fn == NULL)) && (button_spec->
sensitive_if_readonly == TRUE))
208 if((selected > 1) && (!(button_spec->cb_multiselect_fn == NULL)))
216 gtk_widget_set_sensitive (GTK_WIDGET(blist->data), enable);
221gnc_search_dialog_select_cb (GtkButton *button, GNCSearchWindow *sw)
224 g_return_if_fail (sw->selected_cb);
226 entry = gnc_query_view_get_selected_entry (GNC_QUERY_VIEW (sw->result_view));
227 if (!entry && !sw->allow_clear)
229 char *msg =
_(
"You must select an item from the list");
230 gnc_error_dialog (GTK_WINDOW (sw->dialog),
"%s", msg);
234 (sw->selected_cb)(GTK_WINDOW (sw->dialog), entry, sw->select_arg);
235 gnc_search_dialog_destroy (sw);
239gnc_search_dialog_select_row_cb (GNCQueryView *qview,
243 GNCSearchWindow *sw = user_data;
244 gint number_of_rows = GPOINTER_TO_INT(item);
245 gnc_search_dialog_select_buttons_enable(sw, number_of_rows);
249gnc_search_dialog_double_click_cb (GNCQueryView *qview,
253 GNCSearchWindow *sw = user_data;
257 gnc_search_dialog_select_cb (NULL, sw);
258 else if (sw->buttons)
260 gnc_search_callback_button_execute (sw->buttons, sw);
266gnc_search_dialog_init_result_view (GNCSearchWindow *sw)
268 GtkTreeSelection *selection;
270 sw->result_view = gnc_query_view_new(sw->display_list, sw->q);
273 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sw->result_view));
274 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
277 gnc_query_sort_order(GNC_QUERY_VIEW(sw->result_view), 1, GTK_SORT_ASCENDING);
280 g_signal_connect (GNC_QUERY_VIEW(sw->result_view),
"row_selected",
281 G_CALLBACK (gnc_search_dialog_select_row_cb), sw);
283 g_signal_connect (GNC_QUERY_VIEW(sw->result_view),
"double_click_entry",
284 G_CALLBACK(gnc_search_dialog_double_click_cb), sw);
288gnc_search_dialog_display_results (GNCSearchWindow *sw)
296 if (sw->result_view == NULL)
298 GtkWidget *scroller, *frame, *button_box, *button;
301 gnc_search_dialog_init_result_view (sw);
303 frame = gtk_frame_new(NULL);
306 scroller = gtk_scrolled_window_new (NULL, NULL);
307 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroller),
308 GTK_POLICY_AUTOMATIC,
309 GTK_POLICY_AUTOMATIC);
310 gtk_widget_set_size_request(GTK_WIDGET(scroller), 300, 100);
311 gtk_container_add (GTK_CONTAINER (scroller), sw->result_view);
312 gtk_container_add(GTK_CONTAINER(frame), scroller);
315 button_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
316 gtk_box_set_homogeneous (GTK_BOX (button_box), FALSE);
323 button = gtk_button_new_with_label (
_(
"Select"));
324 g_signal_connect (G_OBJECT (button),
"clicked",
325 G_CALLBACK (gnc_search_dialog_select_cb), sw);
326 gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 3);
327 sw->select_button = button;
329 for (i = 0; sw->buttons[i].label; i++)
332 button = gtk_button_new_with_label (
_(button_spec->label));
333 g_object_set_data (G_OBJECT (button),
"data", button_spec);
339 sw->button_list = g_list_append(sw->button_list, button);
341 g_signal_connect (G_OBJECT (button),
"clicked",
342 G_CALLBACK (gnc_search_dialog_result_clicked), sw);
343 gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 3);
348 gtk_box_pack_end (GTK_BOX (sw->result_hbox), button_box, FALSE, FALSE, 3);
349 gtk_box_pack_end (GTK_BOX (sw->result_hbox), frame, TRUE, TRUE, 3);
352 gtk_widget_show_all (sw->result_hbox);
355 if (!sw->selected_cb)
356 gtk_widget_hide (sw->select_button);
360 gnc_query_view_reset_query (GNC_QUERY_VIEW(sw->result_view), sw->q);
363 gnc_search_dialog_select_buttons_enable (sw, 0);
364 gnc_query_view_unselect_all (GNC_QUERY_VIEW(sw->result_view));
367 max_count =
gnc_prefs_get_float(GNC_PREFS_GROUP_SEARCH_GENERAL, GNC_PREF_NEW_SEARCH_LIMIT);
368 if (gnc_query_view_get_num_entries(GNC_QUERY_VIEW(sw->result_view)) < max_count)
369 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (sw->new_rb), TRUE);
372 if (gnc_query_view_get_num_entries (GNC_QUERY_VIEW(sw->result_view)) > 0)
374 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(sw->result_view));
375 GtkTreePath *path = gtk_tree_path_new_first ();
376 gtk_tree_selection_select_path (selection, path);
377 gtk_tree_path_free (path);
378 gtk_widget_grab_focus (sw->result_view);
383match_combo_changed (GtkComboBoxText *combo_box, GNCSearchWindow *sw)
385 sw->grouping = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_box));
389search_type_cb (GtkToggleButton *button, GNCSearchWindow *sw)
391 GSList * buttongroup = gtk_radio_button_get_group (GTK_RADIO_BUTTON(button));
393 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
396 g_slist_length (buttongroup) - g_slist_index (buttongroup, button) - 1;
401search_active_only_cb (GtkToggleButton *button, GNCSearchWindow *sw)
405 gtk_toggle_button_get_active (button));
409create_query_fragment (
QofIdTypeConst search_for, GNCSearchParam *param, QofQueryPredData *pdata)
411 GNCSearchParamKind kind = gnc_search_param_get_kind (param);
412 QofQuery *q = qof_query_create_for (search_for);
414 if (kind == SEARCH_PARAM_ELEM)
417 qof_query_add_term (q, gnc_search_param_get_param_path (GNC_SEARCH_PARAM_SIMPLE (param)),
418 pdata, QOF_QUERY_OR);
422 GList *plist = gnc_search_param_get_search (GNC_SEARCH_PARAM_COMPOUND (param));
424 for ( ; plist; plist = plist->next)
427 GNCSearchParam *param2 = plist->data;
428 QofQuery *q2 = create_query_fragment (search_for, param2,
431 QOF_QUERY_OR : QOF_QUERY_AND);
442search_update_query (GNCSearchWindow *sw)
444 static GSList *active_params = NULL;
449 if (sw->grouping == GNC_SEARCH_MATCH_ANY)
454 if (active_params == NULL)
455 active_params = g_slist_prepend (NULL, QOF_PARAM_ACTIVE);
458 if (sw->start_q == NULL)
460 sw->start_q = qof_query_create_for (sw->search_for);
470 q = qof_query_create_for (sw->search_for);
473 for (node = sw->crit_list; node; node = node->next)
476 QofQueryPredData* pdata;
478 pdata = gnc_search_core_type_get_predicate (data->element);
481 q2 = create_query_fragment(sw->search_for, GNC_SEARCH_PARAM (data->param), pdata);
494 switch (sw->search_type)
515 g_warning (
"bad search type: %d", sw->search_type);
520 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sw->active_only_check)))
523 active_params = NULL;
535gnc_search_dialog_show_close_cancel (GNCSearchWindow *sw)
539 gtk_widget_show (sw->cancel_button);
540 gtk_widget_hide (sw->close_button);
544 gtk_widget_hide (sw->cancel_button);
545 gtk_widget_show (sw->close_button);
550gnc_search_dialog_reset_widgets (GNCSearchWindow *sw)
552 gboolean sens = (sw->q != NULL);
553 gboolean crit_list_vis = FALSE;
555 gtk_widget_set_sensitive(GTK_WIDGET(sw->narrow_rb), sens);
556 gtk_widget_set_sensitive(GTK_WIDGET(sw->add_rb), sens);
557 gtk_widget_set_sensitive(GTK_WIDGET(sw->del_rb), sens);
561 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (sw->new_rb), FALSE);
562 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (sw->narrow_rb), TRUE);
566 crit_list_vis = TRUE;
568 gtk_widget_set_sensitive(sw->grouping_combo, crit_list_vis);
569 gtk_widget_set_visible (sw->criteria_scroll_window, crit_list_vis);
570 gtk_widget_set_visible (sw->match_all_label, !crit_list_vis);
574gnc_search_dialog_crit_ok (GNCSearchWindow *sw)
583 l = g_list_last (sw->crit_list);
585 ret = gnc_search_core_type_validate (data->element);
588 sw->last_param = data->param;
594search_find_cb (GtkButton *button, GNCSearchWindow *sw)
596 if (!gnc_search_dialog_crit_ok (sw))
599 search_update_query (sw);
600 search_clear_criteria (sw);
601 gnc_search_dialog_reset_widgets (sw);
605 gpointer entry = NULL;
608 GNCQueryView *qview = GNC_QUERY_VIEW (sw->result_view);
609 entry = gnc_query_view_get_selected_entry (qview);
611 (sw->result_cb)(sw->q, sw->user_data, &entry);
614 gnc_search_dialog_display_results (sw);
618search_new_item_cb (GtkButton *button, GNCSearchWindow *sw)
622 g_return_if_fail (sw->new_item_cb);
624 res = (sw->new_item_cb)(GTK_WINDOW (sw->dialog), sw->user_data);
628 const GncGUID *guid = (
const GncGUID *) ((sw->get_guid->param_getfcn)(res, sw->get_guid));
635 sw->start_q = qof_query_create_for (sw->search_for);
646 gnc_gui_component_watch_entity (sw->component_id, guid, QOF_EVENT_MODIFY);
651search_cancel_cb (GtkButton *button, GNCSearchWindow *sw)
654 gnc_search_dialog_destroy (sw);
658search_help_cb (GtkButton *button, GNCSearchWindow *sw)
660 gnc_gnome_help (GTK_WINDOW(sw->dialog), DF_MANUAL, DL_FIND_TRANSACTIONS);
664remove_element (GtkWidget *button, GNCSearchWindow *sw)
667 struct _elem_data *data;
672 element = g_object_get_data (G_OBJECT (button),
"element");
673 data = g_object_get_data (G_OBJECT (element),
"data");
676 sw->crit_list = g_list_remove (sw->crit_list, data);
679 gtk_container_remove (GTK_CONTAINER (sw->criteria_table), element);
680 gtk_container_remove (GTK_CONTAINER (sw->criteria_table), button);
685 gtk_widget_set_sensitive(sw->grouping_combo, FALSE);
686 gtk_widget_show(sw->match_all_label);
687 gtk_widget_hide(sw->criteria_scroll_window);
692attach_element (GtkWidget *element, GNCSearchWindow *sw,
int row)
697 data = g_object_get_data (G_OBJECT (element),
"data");
699 gnc_search_core_type_pass_parent (data->element, GTK_WINDOW(sw->dialog));
701 gtk_grid_attach (GTK_GRID (sw->criteria_table), element, 0, row, 1, 1);
702 gtk_widget_set_hexpand (element, TRUE);
703 gtk_widget_set_halign (element, GTK_ALIGN_FILL);
704 g_object_set (element,
"margin", 0, NULL);
706 remove = gtk_button_new_with_mnemonic (
_(
"_Remove"));
707 g_object_set_data (G_OBJECT (remove),
"element", element);
708 g_signal_connect (G_OBJECT (remove),
"clicked", G_CALLBACK (remove_element), sw);
710 gtk_grid_attach (GTK_GRID (sw->criteria_table), remove, 1, row, 1, 1);
711 gtk_widget_set_hexpand (remove, FALSE);
712 gtk_widget_set_halign (remove, GTK_ALIGN_CENTER);
713 g_object_set (remove,
"margin", 0, NULL);
715 gtk_widget_show (remove);
716 data->button = remove;
720combo_box_changed (GtkComboBox *combo_box,
struct _crit_data *data)
722 GNCSearchParam *param;
723 GNCSearchCoreType *newelem;
727 if (!gtk_combo_box_get_active_iter(combo_box, &iter))
729 model = gtk_combo_box_get_model(combo_box);
730 gtk_tree_model_get(model, &iter, SEARCH_COL_POINTER, ¶m, -1);
732 if (gnc_search_param_type_match (param, data->param))
744 if (data->elemwidget)
745 gtk_container_remove (GTK_CONTAINER (data->container), data->elemwidget);
746 g_object_unref (G_OBJECT (data->element));
748 newelem = gnc_search_core_type_new_type_name
749 (gnc_search_param_get_param_type (param));
750 data->element = newelem;
751 data->elemwidget = gnc_search_core_type_get_widget (newelem);
752 if (data->elemwidget)
754 gtk_box_pack_start (GTK_BOX (data->container), data->elemwidget,
758 gnc_search_core_type_pass_parent (data->element, GTK_WINDOW(data->dialog));
761 gtk_widget_show_all (data->container);
764 gtk_widget_queue_resize (GTK_WIDGET (data->dialog));
767 gnc_search_core_type_grab_focus (newelem);
768 gnc_search_core_type_editable_enters (newelem);
772search_clear_criteria (GNCSearchWindow *sw)
776 for (node = sw->crit_list; node; )
778 GList *tmp = node->next;
780 g_object_ref (data->button);
781 remove_element (data->button, sw);
787get_comb_box_widget (GNCSearchWindow *sw,
struct _crit_data *data)
789 GtkWidget *combo_box;
792 GtkCellRenderer *cell;
794 int index = 0, current = 0;
796 store = gtk_list_store_new(NUM_SEARCH_COLS, G_TYPE_STRING, G_TYPE_POINTER);
797 combo_box = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
798 g_object_unref(store);
800 cell = gtk_cell_renderer_text_new ();
801 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combo_box), cell, TRUE);
802 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
803 "text", SEARCH_COL_NAME,
806 for (l = sw->params_list; l; l = l->next)
808 GNCSearchParam *param = l->data;
810 gtk_list_store_append(store, &iter);
811 gtk_list_store_set(store, &iter,
812 SEARCH_COL_NAME,
_(gnc_search_param_get_title (param)),
813 SEARCH_COL_POINTER, param,
816 if (param == sw->last_param)
822 gtk_combo_box_set_active (GTK_COMBO_BOX(combo_box), current);
823 g_signal_connect (combo_box,
"changed", G_CALLBACK (combo_box_changed), data);
829get_element_widget (GNCSearchWindow *sw, GNCSearchCoreType *element)
831 GtkWidget *combo_box, *hbox, *p;
835 data->element = element;
836 data->dialog = GTK_DIALOG (sw->dialog);
838 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
839 gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
842 g_object_set_data_full (G_OBJECT (hbox),
"data", data, g_free);
844 p = gnc_search_core_type_get_widget (element);
845 data->elemwidget = p;
846 data->container = hbox;
847 data->param = sw->last_param;
849 combo_box = get_comb_box_widget (sw, data);
850 gtk_box_pack_start (GTK_BOX (hbox), combo_box, FALSE, FALSE, 0);
852 gtk_box_pack_start (GTK_BOX (hbox), p, FALSE, FALSE, 0);
853 gtk_widget_show_all (hbox);
859gnc_search_dialog_book_option_changed (gpointer new_val, gpointer user_data)
862 GNCSearchWindow *sw = user_data;
863 gboolean *new_data = (gboolean*)new_val;
865 GtkWidget *focused_widget = gtk_window_get_focus(GTK_WINDOW(sw->dialog));
867 g_return_if_fail (sw);
868 if (strcmp (sw->search_for, GNC_ID_SPLIT) != 0)
872 for (l = sw->params_list; l; l = l->next)
874 GNCSearchParam *param = l->data;
878 if (strcmp (gnc_search_param_get_title (param), N_(
"Action")) == 0)
879 gnc_search_param_set_title (param, N_(
"Number/Action"));
880 if (strcmp (gnc_search_param_get_title (param), N_(
"Number")) == 0)
881 gnc_search_param_set_title (param, N_(
"Transaction Number"));
885 if (strcmp (gnc_search_param_get_title (param), N_(
"Number/Action")) == 0)
886 gnc_search_param_set_title (param, N_(
"Action"));
887 if (strcmp (gnc_search_param_get_title (param), N_(
"Transaction Number")) == 0)
888 gnc_search_param_set_title (param, N_(
"Number"));
892 for (l = sw->crit_list; l; l = l->next)
895 GList *children = gtk_container_get_children (GTK_CONTAINER(data->container));
898 for (GList *child = children; child; child = g_list_next (child))
900 GtkWidget *combo_box = child->data;
903 if (GTK_IS_COMBO_BOX(combo_box))
905 GtkWidget *new_combo_box;
909 index = gtk_combo_box_get_active(GTK_COMBO_BOX(combo_box));
911 new_combo_box = get_comb_box_widget (sw, data);
913 if (focused_widget == combo_box)
914 focused_widget = new_combo_box;
915 gtk_widget_destroy(combo_box);
917 gtk_combo_box_set_active(GTK_COMBO_BOX(new_combo_box), index);
918 gtk_box_pack_start (GTK_BOX (data->container), new_combo_box,
920 gtk_box_reorder_child(GTK_BOX (data->container), new_combo_box, 0);
921 gtk_widget_show_all (data->container);
924 g_list_free (children);
926 gtk_widget_grab_focus(focused_widget);
938get_grid_size (GtkWidget *child, gpointer data)
941 gint top, left, height, width;
943 gtk_container_child_get(GTK_CONTAINER(gridsize->
grid), child,
944 "left-attach", &left,
950 if (left + width >= gridsize->
cols)
951 gridsize->
cols = left + width;
953 if (top + height >= gridsize->rows)
954 gridsize->rows = top + height;
958gnc_search_dialog_add_criterion (GNCSearchWindow *sw)
960 GNCSearchCoreType *new_sct;
969 if (!gnc_search_dialog_crit_ok (sw))
974 sw->last_param = sw->params_list->data;
977 gtk_widget_set_sensitive(sw->grouping_combo, TRUE);
978 gtk_widget_hide(sw->match_all_label);
979 gtk_widget_show(sw->criteria_scroll_window);
982 new_sct = gnc_search_core_type_new_type_name
983 (gnc_search_param_get_param_type (sw->last_param));
990 w = get_element_widget (sw, new_sct);
991 data = g_object_get_data (G_OBJECT (w),
"data");
992 sw->crit_list = g_list_append (sw->crit_list, data);
994 gridsize.grid = GTK_GRID (sw->criteria_table);
995 gtk_container_foreach(GTK_CONTAINER(sw->criteria_table), get_grid_size, &gridsize);
997 attach_element (w, sw, gridsize.rows);
999 gnc_search_core_type_grab_focus (new_sct);
1000 gnc_search_core_type_editable_enters (new_sct);
1005add_criterion (GtkWidget *button, GNCSearchWindow *sw)
1007 gint number_of_buttons = g_list_length (sw->crit_list) + 1;
1008 gint button_height = gtk_widget_get_allocated_height (button);
1009 gint min_height = MIN (number_of_buttons * button_height, 5 * button_height);
1013 gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW(
1014 sw->criteria_scroll_window),
1015 min_height + (button_height/2));
1017 gnc_search_dialog_add_criterion (sw);
1021gnc_search_dialog_close_cb (GtkDialog *dialog, GNCSearchWindow *sw)
1023 g_return_val_if_fail (sw, TRUE);
1027 if (strcmp (sw->search_for, GNC_ID_SPLIT) == 0)
1028 gnc_book_option_remove_cb(OPTION_NAME_NUM_FIELD_SOURCE,
1029 gnc_search_dialog_book_option_changed, sw);
1031 gnc_unregister_gui_component (sw->component_id);
1034 g_list_free (sw->crit_list);
1037 g_list_free (sw->button_list);
1045 (sw->free_cb)(sw->user_data);
1053refresh_handler (GHashTable *changes, gpointer data)
1055 GNCSearchWindow * sw = data;
1057 g_return_if_fail (sw);
1060 if (!sw->result_cb && (sw->result_view != NULL))
1061 gnc_search_dialog_display_results (sw);
1065close_handler (gpointer data)
1067 GNCSearchWindow * sw = data;
1069 g_return_if_fail (sw);
1070 gtk_widget_destroy (sw->dialog);
1075type_label_to_new_button(
const gchar* type_label)
1077 if (g_strcmp0(type_label,
_(
"Bill")) == 0)
1079 return _(
"New Bill");
1081 else if (g_strcmp0(type_label,
_(
"Customer")) == 0)
1083 return _(
"New Customer");
1085 else if (g_strcmp0(type_label,
_(
"Employee")) == 0)
1087 return _(
"New Employee");
1089 else if (g_strcmp0(type_label,
_(
"Expense Voucher")) == 0)
1091 return _(
"New Expense Voucher");
1093 else if (g_strcmp0(type_label,
_(
"Invoice")) == 0)
1095 return _(
"New Invoice");
1097 else if (g_strcmp0(type_label,
_(
"Job")) == 0)
1099 return _(
"New Job");
1101 else if (g_strcmp0(type_label,
_(
"Order")) == 0)
1103 return _(
"New Order");
1105 else if (g_strcmp0(type_label,
_(
"Transaction")) == 0)
1107 return _(
"New Transaction");
1109 else if (g_strcmp0(type_label,
_(
"Split")) == 0)
1111 return _(
"New Split");
1113 else if (g_strcmp0(type_label,
_(
"Vendor")) == 0)
1115 return _(
"New Vendor");
1119 PWARN(
"No translatable new-button label found for search type \"%s\", please add one into dialog-search.c!", type_label);
1120 return C_(
"Item represents an unknown object type (in the sense of bill, customer, invoice, transaction, split,…)!",
"New item");
1125gnc_search_dialog_init_widgets (GNCSearchWindow *sw,
const gchar *title)
1127 GtkBuilder *builder;
1128 GtkWidget *label, *add, *box;
1129 GtkComboBoxText *combo_box;
1131 GtkWidget *new_item_button;
1132 const char *type_label;
1135 builder = gtk_builder_new();
1136 gnc_builder_add_from_file (builder,
"dialog-search.glade",
"search_dialog");
1139 sw->dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"search_dialog"));
1140 gtk_window_set_title(GTK_WINDOW(sw->dialog), title);
1141 g_object_set_data (G_OBJECT (sw->dialog),
"dialog-info", sw);
1144 gtk_widget_set_name (GTK_WIDGET(sw->dialog),
"gnc-id-search");
1145 gnc_widget_style_context_add_class (GTK_WIDGET(sw->dialog),
"gnc-class-search");
1148 sw->result_hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"result_hbox"));
1151 sw->criteria_table = GTK_WIDGET(gtk_builder_get_object (builder,
"criteria_table"));
1152 sw->criteria_scroll_window = GTK_WIDGET(gtk_builder_get_object (builder,
"criteria_scroll_window"));
1155 label = GTK_WIDGET(gtk_builder_get_object (builder,
"type_label"));
1157 type_label = sw->type_label;
1160 gtk_label_set_text (GTK_LABEL (label), type_label);
1163 add = gtk_button_new_with_mnemonic (
_(
"_Add"));
1165 g_signal_connect (G_OBJECT (add),
"clicked", G_CALLBACK (add_criterion), sw);
1166 box = GTK_WIDGET(gtk_builder_get_object (builder,
"add_button_box"));
1167 gtk_box_pack_start (GTK_BOX (box), add, FALSE, FALSE, 3);
1168 gtk_widget_show (add);
1171 sw->grouping_combo = gtk_combo_box_text_new();
1172 combo_box = GTK_COMBO_BOX_TEXT(sw->grouping_combo);
1173 gtk_combo_box_text_append_text(combo_box,
_(
"all criteria are met"));
1174 gtk_combo_box_text_append_text(combo_box,
_(
"any criteria are met"));
1175 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), sw->grouping);
1176 g_signal_connect(combo_box,
"changed", G_CALLBACK (match_combo_changed), sw);
1178 box = GTK_WIDGET(gtk_builder_get_object (builder,
"type_menu_box"));
1179 gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET(combo_box), FALSE, FALSE, 3);
1180 gtk_widget_show(GTK_WIDGET(combo_box));
1183 sw->match_all_label = GTK_WIDGET(gtk_builder_get_object (builder,
"match_all_label"));
1186 sw->new_rb = GTK_WIDGET(gtk_builder_get_object (builder,
"new_search_radiobutton"));
1187 g_signal_connect (sw->new_rb,
"toggled",
1188 G_CALLBACK (search_type_cb), sw);
1189 sw->narrow_rb = GTK_WIDGET(gtk_builder_get_object (builder,
"narrow_search_radiobutton"));
1190 g_signal_connect (sw->narrow_rb,
"toggled",
1191 G_CALLBACK (search_type_cb), sw);
1192 sw->add_rb = GTK_WIDGET(gtk_builder_get_object (builder,
"add_search_radiobutton"));
1193 g_signal_connect (sw->add_rb,
"toggled",
1194 G_CALLBACK (search_type_cb), sw);
1195 sw->del_rb = GTK_WIDGET(gtk_builder_get_object (builder,
"delete_search_radiobutton"));
1196 g_signal_connect (sw->del_rb,
"toggled",
1197 G_CALLBACK (search_type_cb), sw);
1200 sw->active_only_check = GTK_WIDGET(gtk_builder_get_object (builder,
"active_only_check"));
1201 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sw->active_only_check), active);
1202 g_signal_connect (sw->active_only_check,
"toggled",
1203 G_CALLBACK (search_active_only_cb), sw);
1209 gtk_widget_set_sensitive (sw->active_only_check, FALSE);
1212 widget = GTK_WIDGET(gtk_builder_get_object (builder,
"find_button"));
1213 g_signal_connect (widget,
"clicked",
1214 G_CALLBACK (search_find_cb), sw);
1217 sw->cancel_button = GTK_WIDGET(gtk_builder_get_object (builder,
"cancel_button"));
1218 g_signal_connect (sw->cancel_button,
"clicked",
1219 G_CALLBACK (search_cancel_cb), sw);
1222 sw->close_button = GTK_WIDGET(gtk_builder_get_object (builder,
"close_button"));
1223 g_signal_connect (sw->close_button,
"clicked",
1224 G_CALLBACK (search_cancel_cb), sw);
1227 new_item_button = GTK_WIDGET(gtk_builder_get_object (builder,
"new_item_button"));
1228 gtk_button_set_label (GTK_BUTTON(new_item_button),
1229 type_label_to_new_button(type_label));
1230 g_signal_connect (new_item_button,
"clicked",
1231 G_CALLBACK (search_new_item_cb), sw);
1234 widget = GTK_WIDGET(gtk_builder_get_object (builder,
"help_button"));
1235 g_signal_connect (widget,
"clicked",
1236 G_CALLBACK (search_help_cb), sw);
1239 gnc_search_dialog_add_criterion (sw);
1243 if (strcmp (sw->search_for, GNC_ID_SPLIT) == 0)
1244 gnc_book_option_register_cb(OPTION_NAME_NUM_FIELD_SOURCE,
1245 gnc_search_dialog_book_option_changed, sw);
1248 if (!sw->new_item_cb)
1249 gtk_widget_hide (new_item_button);
1252 gtk_builder_connect_signals (builder, sw);
1255 sw->component_id = gnc_register_gui_component (DIALOG_SEARCH_CM_CLASS,
1258 gnc_gui_component_set_session (sw->component_id,
1259 gnc_get_current_session());
1262 g_signal_connect (G_OBJECT (sw->dialog),
"destroy",
1263 G_CALLBACK (gnc_search_dialog_close_cb), sw);
1265 gnc_search_dialog_reset_widgets (sw);
1266 gnc_search_dialog_show_close_cancel (sw);
1268 g_object_unref(G_OBJECT(builder));
1272gnc_search_dialog_destroy (GNCSearchWindow *sw)
1275 if (sw->prefs_group)
1276 gnc_save_window_size(sw->prefs_group, GTK_WINDOW(sw->dialog));
1277 gnc_close_gui_component (sw->component_id);
1281gnc_search_dialog_raise (GNCSearchWindow *sw)
1284 gtk_window_present (GTK_WINDOW(sw->dialog));
1288gnc_search_dialog_create (GtkWindow *parent,
1291 GList *display_list,
1294 GNCSearchResultCB result_callback,
1295 GNCSearchNewItemCB new_item_cb,
1296 gpointer user_data, GNCSearchFree free_cb,
1297 const gchar *prefs_group,
1298 const gchar *type_label,
1299 const gchar *style_class)
1301 GNCSearchWindow *sw = g_new0 (GNCSearchWindow, 1);
1303 g_return_val_if_fail (obj_type, NULL);
1304 g_return_val_if_fail (*obj_type !=
'\0', NULL);
1305 g_return_val_if_fail (param_list, NULL);
1308 g_return_val_if_fail ((callbacks && !result_callback) ||
1309 (!callbacks && result_callback), NULL);
1312 g_return_val_if_fail (display_list, NULL);
1314 sw->search_for = obj_type;
1315 sw->params_list = param_list;
1316 sw->display_list = display_list;
1317 sw->buttons = callbacks;
1318 sw->result_cb = result_callback;
1319 sw->new_item_cb = new_item_cb;
1320 sw->user_data = user_data;
1321 sw->free_cb = free_cb;
1322 sw->prefs_group = prefs_group;
1323 sw->type_label = type_label;
1329 sw->q = show_start_query;
1331 gnc_search_dialog_init_widgets (sw, title);
1332 if (sw->prefs_group)
1333 gnc_restore_window_size(sw->prefs_group, GTK_WINDOW(sw->dialog), parent);
1334 gtk_window_set_transient_for(GTK_WINDOW(sw->dialog), parent);
1335 gtk_widget_show(sw->dialog);
1340 gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW(
1341 sw->criteria_scroll_window),
1342 gtk_widget_get_allocated_height (
1343 GTK_WIDGET(sw->grouping_combo)) * 1.5);
1346 if (style_class != NULL)
1347 gnc_widget_style_context_add_class (GTK_WIDGET(sw->dialog), style_class);
1350 if (callbacks && show_start_query)
1352 gnc_search_dialog_reset_widgets (sw);
1353 gnc_search_dialog_display_results (sw);
1360guint gnc_search_dialog_connect_on_close (GNCSearchWindow *sw,
1364 g_return_val_if_fail (sw, 0);
1365 g_return_val_if_fail (func, 0);
1366 g_return_val_if_fail (user_data, 0);
1368 return g_signal_connect (G_OBJECT (sw->dialog),
"destroy",
1374void gnc_search_dialog_disconnect (GNCSearchWindow *sw, gpointer user_data)
1376 g_return_if_fail (sw);
1377 g_return_if_fail (user_data);
1379 g_signal_handlers_disconnect_matched (sw->dialog, G_SIGNAL_MATCH_DATA,
1380 0, 0, NULL, NULL, user_data);
1384void gnc_search_dialog_set_select_cb (GNCSearchWindow *sw,
1385 GNCSearchSelectedCB selected_cb,
1387 gboolean allow_clear)
1389 g_return_if_fail (sw);
1391 sw->selected_cb = selected_cb;
1392 sw->select_arg = user_data;
1393 sw->allow_clear = allow_clear;
1396 if (sw->select_button)
1399 gtk_widget_show (sw->select_button);
1401 gtk_widget_hide (sw->select_button);
1405 gnc_search_dialog_show_close_cancel (sw);
1416 list = gnc_search_param_prepend (list,
"Txn: All Accounts",
1418 type, SPLIT_TRANS, TRANS_SPLITLIST,
1420 list = gnc_search_param_prepend (list,
"Split Account", GNC_ID_ACCOUNT,
1421 type, SPLIT_ACCOUNT, QOF_PARAM_GUID,
1423 list = gnc_search_param_prepend (list,
"Split->Txn->Void?", NULL, type,
1424 SPLIT_TRANS, TRANS_VOID_STATUS, NULL);
1425 list = gnc_search_param_prepend (list,
"Split Int64", NULL, type,
1426 "d-share-int64", NULL);
1427 list = gnc_search_param_prepend (list,
"Split Amount (double)", NULL, type,
1428 "d-share-amount", NULL);
1429 list = gnc_search_param_prepend (list,
"Split Value (debcred)", NULL, type,
1431 list = gnc_search_param_prepend (list,
"Split Amount (numeric)", NULL, type,
1432 SPLIT_AMOUNT, NULL);
1433 list = gnc_search_param_prepend (list,
"Date Reconciled (date)", NULL, type,
1434 SPLIT_DATE_RECONCILED, NULL);
1435 list = gnc_search_param_prepend (list,
"Split Memo (string)", NULL, type,
1446 list = gnc_search_param_prepend (list,
"Amount", NULL, type, SPLIT_AMOUNT,
1448 list = gnc_search_param_prepend (list,
"Memo", NULL, type, SPLIT_MEMO, NULL);
1449 list = gnc_search_param_prepend (list,
"Date", NULL, type, SPLIT_TRANS,
1450 TRANS_DATE_POSTED, NULL);
1457do_nothing (GtkWindow *dialog, gpointer *a, gpointer b)
1463gnc_search_dialog_test (
void)
1465 static GList *params = NULL;
1466 static GList *display = NULL;
1470 { (
"View Split"), do_nothing, NULL, TRUE },
1471 { (
"New Split"), do_nothing, NULL, TRUE },
1472 { (
"Do Something"), do_nothing, NULL, TRUE },
1473 { (
"Do Nothing"), do_nothing, NULL, TRUE },
1474 { (
"Who Cares?"), do_nothing, NULL, FALSE },
1479 params = get_params_list (GNC_ID_SPLIT);
1481 if (display == NULL)
1482 display = get_display_list (GNC_ID_SPLIT);
1485 gnc_search_dialog_create (NULL, GNC_ID_SPLIT,
1486 _(
"Find Transaction"),
1488 NULL, NULL, buttons, NULL, NULL, NULL, NULL,
API for Transactions and Splits (journal entries)
Generic api to store and retrieve preferences.
utility functions for the GnuCash UI
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
const QofParam * qof_class_get_parameter(QofIdTypeConst obj_name, const char *parameter)
Return the registered Parameter Definition for the requested parameter.
#define ACCOUNT_MATCH_ALL_TYPE
This is the type-override when you want to match all accounts.
const gchar * QofIdTypeConst
QofIdTypeConst declaration.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
#define PWARN(format, args...)
Log a warning.
const char * qof_object_get_type_label(QofIdTypeConst type_name)
Get the printable label for a type.
gdouble gnc_prefs_get_float(const gchar *group, const gchar *pref_name)
Get an float value from the preferences backend.
gboolean gnc_prefs_set_bool(const gchar *group, const gchar *pref_name, gboolean value)
Store a boolean value into the preferences backend.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
void qof_query_add_term(QofQuery *q, QofQueryParamList *param_list, QofQueryPredData *pred_data, QofQueryOp op)
This is the general function that adds a new Query Term to a query.
void qof_query_add_guid_match(QofQuery *q, QofQueryParamList *param_list, const GncGUID *guid, QofQueryOp op)
DOCUMENT ME !!
QofQuery * qof_query_merge(QofQuery *q1, QofQuery *q2, QofQueryOp op)
Combine two queries together using the Boolean set (logical) operator 'op'.
QofQueryPredData * qof_query_core_predicate_copy(const QofQueryPredData *pdata)
Copy a predicate.
QofQuery * qof_query_copy(QofQuery *q)
Make a copy of the indicated query.
void qof_query_core_predicate_free(QofQueryPredData *pdata)
Destroy a predicate.
void qof_query_set_book(QofQuery *query, QofBook *book)
Set the book to be searched.
QofQuery * qof_query_invert(QofQuery *q)
Make a copy of the indicated query, inverting the sense of the search.
void qof_query_add_boolean_match(QofQuery *q, QofQueryParamList *param_list, gboolean value, QofQueryOp op)
Handy-dandy convenience routines, avoids having to create a separate predicate for boolean matches.
void qof_query_purge_terms(QofQuery *q, QofQueryParamList *param_list)
Remove query terms of a particular type from q.
QofQueryOp
Query Term Operators, for combining Query Terms.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
#define SPLIT_ACCOUNT_GUID
for guid_match_all
The type used to store guids in C.
gint cols
The number of columns and rows in the grid.
GtkGrid * grid
The grid being sized.