mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Fix enhancement bug 101456 - 'Find' dialog cumbersome for Business functions
When opening an invoice search dialog from a specific company, list is populated by all invoices. Patch by Geert Janssens git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18349 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
5ee9dcade2
commit
d5a4c757ff
@ -64,13 +64,16 @@ static GtkWidget * gnc_owner_new (GtkWidget *label, GtkWidget *hbox,
|
||||
GNCSearchCB search_cb = NULL;
|
||||
const char *type_name = NULL;
|
||||
const char *text = NULL;
|
||||
gboolean text_editable = FALSE;
|
||||
|
||||
switch (type) {
|
||||
case GNCSEARCH_TYPE_SELECT:
|
||||
text = _("Select...");
|
||||
text_editable = TRUE;
|
||||
break;
|
||||
case GNCSEARCH_TYPE_EDIT:
|
||||
text = _("Edit...");
|
||||
text_editable = FALSE;
|
||||
};
|
||||
|
||||
switch (owner->type) {
|
||||
@ -115,7 +118,7 @@ static GtkWidget * gnc_owner_new (GtkWidget *label, GtkWidget *hbox,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
edit = gnc_general_search_new (type_name, text, search_cb, book);
|
||||
edit = gnc_general_search_new (type_name, text, text_editable, search_cb, book, book);
|
||||
if (!edit)
|
||||
return NULL;
|
||||
|
||||
@ -251,7 +254,7 @@ GtkWidget * gnc_invoice_select_create (GtkWidget *hbox, QofBook *book,
|
||||
isi->label = label;
|
||||
|
||||
edit = gnc_general_search_new (GNC_INVOICE_MODULE_NAME, _("Select..."),
|
||||
gnc_invoice_select_search_cb, isi);
|
||||
TRUE, gnc_invoice_select_search_cb, isi, isi->book);
|
||||
if (!edit) {
|
||||
g_free(isi);
|
||||
return NULL;
|
||||
|
@ -1110,8 +1110,8 @@ gnc_invoice_update_job_choice (InvoiceWindow *iw)
|
||||
case NEW_INVOICE:
|
||||
case MOD_INVOICE:
|
||||
iw->job_choice =
|
||||
gnc_general_search_new (GNC_JOB_MODULE_NAME, _("Select..."),
|
||||
gnc_invoice_select_job_cb, iw);
|
||||
gnc_general_search_new (GNC_JOB_MODULE_NAME, _("Select..."), TRUE,
|
||||
gnc_invoice_select_job_cb, iw, iw->book);
|
||||
|
||||
gnc_general_search_set_selected (GNC_GENERAL_SEARCH (iw->job_choice),
|
||||
gncOwnerGetJob (&iw->job));
|
||||
@ -1181,8 +1181,8 @@ gnc_invoice_update_proj_job (InvoiceWindow *iw)
|
||||
iw->proj_job_choice = NULL;
|
||||
} else {
|
||||
iw->proj_job_choice =
|
||||
gnc_general_search_new (GNC_JOB_MODULE_NAME, _("Select..."),
|
||||
gnc_invoice_select_proj_job_cb, iw);
|
||||
gnc_general_search_new (GNC_JOB_MODULE_NAME, _("Select..."), TRUE,
|
||||
gnc_invoice_select_proj_job_cb, iw, iw->book);
|
||||
|
||||
gnc_general_search_set_selected (GNC_GENERAL_SEARCH(iw->proj_job_choice),
|
||||
gncOwnerGetJob (&iw->proj_job));
|
||||
|
@ -51,6 +51,12 @@ enum
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
/* Columns used in GtkEntryCompletion's model */
|
||||
enum {
|
||||
GSL_COLUMN_TEXT,
|
||||
GSL_COLUMN_QOFOBJECT,
|
||||
GSL_N_COLUMNS
|
||||
};
|
||||
|
||||
static void gnc_general_search_init (GNCGeneralSearch *gsl);
|
||||
static void gnc_general_search_class_init (GNCGeneralSearchClass *class);
|
||||
@ -256,14 +262,179 @@ search_cb(GtkButton * button, gpointer user_data)
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
create_children (GNCGeneralSearch *gsl, const char *label)
|
||||
/** The completion attached to search edit widget has selected a
|
||||
* match. This function extracts the completed string from the
|
||||
* completion code's temporary model, and uses that to set the iterator
|
||||
* and object data of the selection for use when the user leaves the widget.
|
||||
* This should always point to a valid iterator since the user
|
||||
* made the selection from a list of available object names.
|
||||
*
|
||||
* @param completion Unused.
|
||||
*
|
||||
* @param comp_model A temporary model used by completion code that
|
||||
* contains only the current matches.
|
||||
*
|
||||
* @param comp_iter The iter in the completion's temporary model
|
||||
* that represents the user selected match.
|
||||
*
|
||||
* @param cbe A pointer to a currency entry widget. */
|
||||
static gboolean
|
||||
gnc_gsl_match_selected_cb (GtkEntryCompletion *completion,
|
||||
GtkTreeModel *comp_model,
|
||||
GtkTreeIter *comp_iter,
|
||||
GNCGeneralSearch *gsl)
|
||||
{
|
||||
QofObject * qofobject;
|
||||
|
||||
gtk_tree_model_get(comp_model, comp_iter, GSL_COLUMN_QOFOBJECT, &qofobject, -1);
|
||||
gnc_general_search_set_selected (gsl, qofobject);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** The focus left the general search edit widget, so reset the widget to
|
||||
* its last known good value. If the widget value contained a valid
|
||||
* value then this is a noop. Otherwise the widget will be reset
|
||||
* to the last user selected value. This latter state will occur
|
||||
* if the user has typed characters directly into the widget but not
|
||||
* selected a completion.
|
||||
*
|
||||
* @param entry The entry widget in which the user is typing.
|
||||
*
|
||||
* @param event Unused.
|
||||
*
|
||||
* @param gsl A pointer to a general search widget. */
|
||||
static gboolean
|
||||
gnc_gsl_focus_out_cb (GtkEntry *entry,
|
||||
GdkEventFocus *event,
|
||||
GNCGeneralSearch *gsl)
|
||||
{
|
||||
const gchar *text;
|
||||
GtkEntryCompletion *completion;
|
||||
GtkTreeModel *model;
|
||||
GtkTreeIter iter;
|
||||
gchar *lc_text, *tree_string, *lc_tree_string;
|
||||
gboolean match, valid_iter;
|
||||
QofObject *qofobject;
|
||||
gpointer selected_item=NULL;
|
||||
|
||||
/* Attempt to match the current text to a qofobject. */
|
||||
completion = gtk_entry_get_completion(entry);
|
||||
model = gtk_entry_completion_get_model(completion);
|
||||
|
||||
/* Return if completion tree is empty */
|
||||
valid_iter = gtk_tree_model_get_iter_first(model, &iter);
|
||||
if (!valid_iter)
|
||||
return FALSE;
|
||||
|
||||
text = gtk_entry_get_text(entry);
|
||||
lc_text = g_utf8_strdown(text, -1);
|
||||
|
||||
/* The last, valid selected entry can match the entered text
|
||||
* No need to search further in that case */
|
||||
if (gsl->selected_item)
|
||||
{
|
||||
GNCGeneralSearchPrivate * priv;
|
||||
|
||||
priv=_PRIVATE(gsl);
|
||||
tree_string = g_strdup(qof_object_printable(priv->type, gsl->selected_item));
|
||||
lc_tree_string = g_utf8_strdown(tree_string, -1);
|
||||
match = g_utf8_collate(lc_text, lc_tree_string) == 0;
|
||||
g_free(tree_string);
|
||||
g_free(lc_tree_string);
|
||||
if (match)
|
||||
selected_item = gsl->selected_item;
|
||||
}
|
||||
|
||||
/* Otherwise, find a match in the completion list */
|
||||
while (valid_iter && !selected_item)
|
||||
{
|
||||
gtk_tree_model_get(model, &iter, GSL_COLUMN_TEXT, &tree_string, -1);
|
||||
lc_tree_string = g_utf8_strdown(tree_string, -1);
|
||||
match = g_utf8_collate(lc_text, lc_tree_string) == 0;
|
||||
g_free(tree_string);
|
||||
g_free(lc_tree_string);
|
||||
if (match)
|
||||
{
|
||||
gtk_tree_model_get(model, &iter, GSL_COLUMN_QOFOBJECT, &qofobject, -1);
|
||||
selected_item = qofobject;
|
||||
} else
|
||||
valid_iter = gtk_tree_model_iter_next(model, &iter);
|
||||
}
|
||||
|
||||
g_free(lc_text);
|
||||
gnc_general_search_set_selected (gsl, selected_item);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
create_children (GNCGeneralSearch *gsl,
|
||||
const char *label,
|
||||
gboolean text_editable,
|
||||
GNCIdTypeConst type,
|
||||
QofBook *book)
|
||||
{
|
||||
GtkListStore * list_store;
|
||||
QueryNew * q;
|
||||
GtkTreeIter iter;
|
||||
GList * list, * it;
|
||||
GtkEntryCompletion *completion;
|
||||
|
||||
/* Add a text entry box */
|
||||
gsl->entry = gtk_entry_new ();
|
||||
gtk_editable_set_editable (GTK_EDITABLE (gsl->entry), FALSE);
|
||||
if (!text_editable)
|
||||
gtk_editable_set_editable (GTK_EDITABLE (gsl->entry), FALSE);
|
||||
gtk_box_pack_start (GTK_BOX (gsl), gsl->entry, TRUE, TRUE, 0);
|
||||
|
||||
|
||||
/* Setup a GtkEntryCompletion auxiliary widget for our Entry box
|
||||
* This requires an internal table ("model") with the possible
|
||||
* auto-completion text entries */
|
||||
|
||||
/* Query for the requested object type */
|
||||
q = qof_query_create_for (type);
|
||||
qof_query_add_boolean_match(q, g_slist_prepend
|
||||
(NULL, QOF_PARAM_ACTIVE), TRUE, QOF_QUERY_AND);
|
||||
qof_query_set_book (q, book);
|
||||
list = qof_query_run(q);
|
||||
|
||||
/* Setup the internal model */
|
||||
list_store = gtk_list_store_new (GSL_N_COLUMNS, G_TYPE_STRING, G_TYPE_OBJECT);
|
||||
for (it = list; it != NULL ; it = it->next)
|
||||
{
|
||||
char * name;
|
||||
|
||||
name = g_strdup(qof_object_printable(type, it->data));
|
||||
/* Add a new row to the model */
|
||||
if (name)
|
||||
{
|
||||
gtk_list_store_append (list_store, &iter);
|
||||
gtk_list_store_set (list_store, &iter,
|
||||
GSL_COLUMN_TEXT, name,
|
||||
GSL_COLUMN_QOFOBJECT, G_OBJECT(it->data),
|
||||
-1);
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gncQueryDestroy(q);
|
||||
|
||||
/* Add the GtkEntryCompletion widget */
|
||||
completion = gtk_entry_completion_new();
|
||||
gtk_entry_completion_set_model(completion, GTK_TREE_MODEL(list_store));
|
||||
gtk_entry_completion_set_text_column(completion, 0);
|
||||
gtk_entry_completion_set_inline_completion(completion, TRUE);
|
||||
gtk_entry_set_completion(GTK_ENTRY(gsl->entry), completion);
|
||||
|
||||
g_signal_connect (G_OBJECT (completion), "match_selected",
|
||||
G_CALLBACK (gnc_gsl_match_selected_cb), gsl);
|
||||
g_signal_connect (G_OBJECT (gsl->entry), "focus-out-event",
|
||||
G_CALLBACK (gnc_gsl_focus_out_cb), gsl);
|
||||
|
||||
g_object_unref(completion);
|
||||
gtk_widget_show (gsl->entry);
|
||||
|
||||
/* Add the search button */
|
||||
gsl->button = gtk_button_new_with_label (label);
|
||||
gtk_box_pack_start (GTK_BOX (gsl), gsl->button, FALSE, FALSE, 0);
|
||||
g_signal_connect (G_OBJECT (gsl->button), "clicked",
|
||||
@ -275,13 +446,30 @@ create_children (GNCGeneralSearch *gsl, const char *label)
|
||||
* gnc_general_search_new:
|
||||
*
|
||||
* Creates a new GNCGeneralSearch widget which can be used to provide
|
||||
* an easy way to choose selections
|
||||
* an easy way to choose selections.
|
||||
*
|
||||
* Returns a GNCGeneralSearch widget.
|
||||
* @param type The type of object that this widget will be used for.
|
||||
* This parameter is a GNCIdTypeConst.
|
||||
* @param label The label for the GtkButton child widget.
|
||||
* @param text_editable switch to enable or disable direct text entry
|
||||
* @param search_cb The callback function to use when an object has been
|
||||
* selected in the search dialog. This dialog is created when clicking on
|
||||
* the GtkButton child widget.
|
||||
* @param user_data Generic pointer to context relevant data that can be
|
||||
* used by callback functions later on. At present, depending on the context
|
||||
* this can be a QofBook, a GncISI structure or a InvoiceWindow structure.
|
||||
* @param book Pointer to the QofBook for this search widget. This is used for
|
||||
* the autocompletion in the text entry widget.
|
||||
*
|
||||
* @return a GNCGeneralSearch widget.
|
||||
*/
|
||||
GtkWidget *
|
||||
gnc_general_search_new (GNCIdTypeConst type, const char *label,
|
||||
GNCSearchCB search_cb, gpointer user_data)
|
||||
gnc_general_search_new (GNCIdTypeConst type,
|
||||
const char *label,
|
||||
gboolean text_editable,
|
||||
GNCSearchCB search_cb,
|
||||
gpointer user_data,
|
||||
QofBook *book)
|
||||
{
|
||||
GNCGeneralSearch *gsl;
|
||||
GNCGeneralSearchPrivate *priv;
|
||||
@ -294,7 +482,7 @@ gnc_general_search_new (GNCIdTypeConst type, const char *label,
|
||||
|
||||
gsl = g_object_new (GNC_TYPE_GENERAL_SEARCH, NULL);
|
||||
|
||||
create_children (gsl, label);
|
||||
create_children (gsl, label, text_editable, type, book);
|
||||
|
||||
priv = _PRIVATE(gsl);
|
||||
priv->type = type;
|
||||
@ -328,10 +516,10 @@ gnc_general_search_set_selected (GNCGeneralSearch *gsl, gpointer selection)
|
||||
priv = _PRIVATE(gsl);
|
||||
if (selection != gsl->selected_item) {
|
||||
gsl->selected_item = selection;
|
||||
reset_selection_text (gsl);
|
||||
g_signal_emit(gsl,
|
||||
general_search_signals[SELECTION_CHANGED], 0);
|
||||
}
|
||||
reset_selection_text (gsl);
|
||||
|
||||
gnc_gui_component_clear_watches (priv->component_id);
|
||||
|
||||
|
@ -74,8 +74,10 @@ typedef struct {
|
||||
|
||||
GtkWidget *gnc_general_search_new (GNCIdTypeConst type,
|
||||
const char *label,
|
||||
gboolean text_editable,
|
||||
GNCSearchCB search_cb,
|
||||
gpointer user_data);
|
||||
gpointer user_data,
|
||||
QofBook *book);
|
||||
|
||||
void gnc_general_search_allow_clear (GNCGeneralSearch *gsl,
|
||||
gboolean allow_clear);
|
||||
|
Loading…
Reference in New Issue
Block a user