r21580 - gnucash/trunk/src - Add the possibility of multi-selection in the invoice/bill search window (but so far still disabled).

Christian Stimming cstim at code.gnucash.org
Fri Nov 18 16:53:13 EST 2011


Author: cstim
Date: 2011-11-18 16:53:13 -0500 (Fri, 18 Nov 2011)
New Revision: 21580
Trac: http://svn.gnucash.org/trac/changeset/21580

Modified:
   gnucash/trunk/src/business/business-gnome/dialog-customer.c
   gnucash/trunk/src/business/business-gnome/dialog-employee.c
   gnucash/trunk/src/business/business-gnome/dialog-invoice.c
   gnucash/trunk/src/business/business-gnome/dialog-invoice.h
   gnucash/trunk/src/business/business-gnome/dialog-job.c
   gnucash/trunk/src/business/business-gnome/dialog-order.c
   gnucash/trunk/src/business/business-gnome/dialog-vendor.c
   gnucash/trunk/src/gnome-search/dialog-search.c
   gnucash/trunk/src/gnome-search/dialog-search.h
Log:
Add the possibility of multi-selection in the invoice/bill search window (but so far still disabled).

Eventually, this should enable multi-duplication of a selection.
However, my gtk-2.20 seems to be broken w.r.t. multi-selections in
GtkCList, so I better have this available only in newer gtk and so far still deactivated.

Modified: gnucash/trunk/src/business/business-gnome/dialog-customer.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-customer.c	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/business/business-gnome/dialog-customer.c	2011-11-18 21:53:13 UTC (rev 21580)
@@ -903,11 +903,11 @@
     static GList *columns = NULL;
     static GNCSearchCallbackButton buttons[] =
     {
-        { N_("View/Edit Customer"), edit_customer_cb},
-        { N_("Customer's Jobs"), jobs_customer_cb},
-        //    { N_("Customer's Orders"), order_customer_cb},
-        { N_("Customer's Invoices"), invoice_customer_cb},
-        { N_("Process Payment"), payment_customer_cb},
+        { N_("View/Edit Customer"), edit_customer_cb, NULL},
+        { N_("Customer's Jobs"), jobs_customer_cb, NULL},
+        //    { N_("Customer's Orders"), order_customer_cb, NULL},
+        { N_("Customer's Invoices"), invoice_customer_cb, NULL},
+        { N_("Process Payment"), payment_customer_cb, NULL},
         { NULL },
     };
     (void)order_customer_cb;

Modified: gnucash/trunk/src/business/business-gnome/dialog-employee.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-employee.c	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/business/business-gnome/dialog-employee.c	2011-11-18 21:53:13 UTC (rev 21580)
@@ -706,9 +706,9 @@
     static GList *columns = NULL;
     static GNCSearchCallbackButton buttons[] =
     {
-        { N_("View/Edit Employee"), edit_employee_cb},
-        { N_("Expense Vouchers"), invoice_employee_cb},
-        { N_("Process Payment"), payment_employee_cb},
+        { N_("View/Edit Employee"), edit_employee_cb, NULL},
+        { N_("Expense Vouchers"), invoice_employee_cb, NULL},
+        { N_("Process Payment"), payment_employee_cb, NULL},
         { NULL },
     };
 

Modified: gnucash/trunk/src/business/business-gnome/dialog-invoice.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-invoice.c	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/business/business-gnome/dialog-invoice.c	2011-11-18 21:53:13 UTC (rev 21580)
@@ -476,7 +476,7 @@
     GncInvoice *invoice = iw_get_invoice (iw);
 
     if (invoice)
-        gnc_ui_invoice_duplicate (invoice);
+        gnc_ui_invoice_duplicate (invoice, TRUE);
 }
 
 void gnc_invoice_window_entryUpCB (GtkWidget *widget, gpointer data)
@@ -2461,7 +2461,7 @@
 }
 
 
-InvoiceWindow * gnc_ui_invoice_duplicate (GncInvoice *old_invoice)
+InvoiceWindow * gnc_ui_invoice_duplicate (GncInvoice *old_invoice, gboolean open_properties)
 {
     InvoiceWindow *iw;
     GncInvoice *new_invoice = NULL;
@@ -2507,10 +2507,13 @@
     // Now open that newly created invoice in the "edit" window
     iw = gnc_ui_invoice_edit (new_invoice);
 
-    // And also open the "properties" pop-up... however, changing the
-    // invoice ID won't be copied over to the tab title even though
-    // it's correctly copied into the invoice.
-    iw = gnc_ui_invoice_modify (new_invoice);
+    if (open_properties)
+    {
+        // And also open the "properties" pop-up... however, changing the
+        // invoice ID won't be copied over to the tab title even though
+        // it's correctly copied into the invoice.
+        iw = gnc_ui_invoice_modify (new_invoice);
+    }
 
     return iw;
 }
@@ -2577,7 +2580,7 @@
 duplicate_invoice_direct (gpointer invoice, gpointer user_data)
 {
     g_return_if_fail (invoice);
-    gnc_ui_invoice_duplicate (invoice);
+    gnc_ui_invoice_duplicate (invoice, TRUE);
 }
 
 static void
@@ -2589,6 +2592,20 @@
     duplicate_invoice_direct (*invoice_p, user_data);
 }
 
+static void multi_duplicate_invoice_one(gpointer data, gpointer user_data)
+{
+    GncInvoice *invoice = data;
+    if (invoice)
+        gnc_ui_invoice_duplicate(invoice, FALSE);
+}
+
+static void
+multi_duplicate_invoice_cb (GList *invoice_list, gpointer user_data)
+{
+    g_return_if_fail (invoice_list && user_data);
+    g_list_foreach(invoice_list, multi_duplicate_invoice_one, NULL);
+}
+
 static gpointer
 new_invoice_cb (gpointer user_data)
 {
@@ -2625,25 +2642,25 @@
     static GNCSearchCallbackButton *buttons;
     static GNCSearchCallbackButton inv_buttons[] =
     {
-        { N_("View/Edit Invoice"), edit_invoice_cb},
-        { N_("Process Payment"), pay_invoice_cb},
-        { N_("Duplicate"), duplicate_invoice_cb},
+        { N_("View/Edit Invoice"), edit_invoice_cb, NULL},
+        { N_("Process Payment"), pay_invoice_cb, NULL},
+        { N_("Duplicate"), duplicate_invoice_cb, multi_duplicate_invoice_cb},
         { NULL },
     };
     static GNCSearchCallbackButton bill_buttons[] =
     {
-        { N_("View/Edit Bill"), edit_invoice_cb},
-        { N_("Process Payment"), pay_invoice_cb},
-        { N_("Duplicate"), duplicate_invoice_cb},
+        { N_("View/Edit Bill"), edit_invoice_cb, NULL},
+        { N_("Process Payment"), pay_invoice_cb, NULL},
+        { N_("Duplicate"), duplicate_invoice_cb, multi_duplicate_invoice_cb},
         { NULL },
     };
     static GNCSearchCallbackButton emp_buttons[] =
     {
         /* Translators: The terms 'Voucher' and 'Expense Voucher' are used
            interchangeably in gnucash and mean the same thing. */
-        { N_("View/Edit Voucher"), edit_invoice_cb},
-        { N_("Process Payment"), pay_invoice_cb},
-        { N_("Duplicate"), duplicate_invoice_cb},
+        { N_("View/Edit Voucher"), edit_invoice_cb, NULL},
+        { N_("Process Payment"), pay_invoice_cb, NULL},
+        { N_("Duplicate"), duplicate_invoice_cb, multi_duplicate_invoice_cb},
         { NULL },
     };
 

Modified: gnucash/trunk/src/business/business-gnome/dialog-invoice.h
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-invoice.h	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/business/business-gnome/dialog-invoice.h	2011-11-18 21:53:13 UTC (rev 21580)
@@ -54,7 +54,7 @@
 /* Create and edit an invoice */
 InvoiceWindow * gnc_ui_invoice_edit (GncInvoice *invoice);
 InvoiceWindow * gnc_ui_invoice_new (GncOwner *owner, QofBook *book);
-InvoiceWindow * gnc_ui_invoice_duplicate (GncInvoice *invoice);
+InvoiceWindow * gnc_ui_invoice_duplicate (GncInvoice *invoice, gboolean open_properties);
 
 /* Search for invoices */
 GNCSearchWindow * gnc_invoice_search (GncInvoice *start, GncOwner *owner, QofBook *book);

Modified: gnucash/trunk/src/business/business-gnome/dialog-job.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-job.c	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/business/business-gnome/dialog-job.c	2011-11-18 21:53:13 UTC (rev 21580)
@@ -534,9 +534,9 @@
     static GList *columns = NULL;
     static GNCSearchCallbackButton buttons[] =
     {
-        { N_("View/Edit Job"), edit_job_cb},
-        { N_("View Invoices"), invoice_job_cb},
-        { N_("Process Payment"), payment_job_cb},
+        { N_("View/Edit Job"), edit_job_cb, NULL},
+        { N_("View Invoices"), invoice_job_cb, NULL},
+        { N_("Process Payment"), payment_job_cb, NULL},
         { NULL },
     };
 

Modified: gnucash/trunk/src/business/business-gnome/dialog-order.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-order.c	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/business/business-gnome/dialog-order.c	2011-11-18 21:53:13 UTC (rev 21580)
@@ -827,7 +827,7 @@
     static GList *columns = NULL;
     static GNCSearchCallbackButton buttons[] =
     {
-        { N_("View/Edit Order"), edit_order_cb},
+        { N_("View/Edit Order"), edit_order_cb, NULL},
         { NULL },
     };
 

Modified: gnucash/trunk/src/business/business-gnome/dialog-vendor.c
===================================================================
--- gnucash/trunk/src/business/business-gnome/dialog-vendor.c	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/business/business-gnome/dialog-vendor.c	2011-11-18 21:53:13 UTC (rev 21580)
@@ -708,11 +708,11 @@
     static GList *columns = NULL;
     static GNCSearchCallbackButton buttons[] =
     {
-        { N_("View/Edit Vendor"), edit_vendor_cb},
-        { N_("Vendor's Jobs"), jobs_vendor_cb},
-        //    { N_("Vendor Orders"), order_vendor_cb},
-        { N_("Vendor's Bills"), invoice_vendor_cb},
-        { N_("Pay Bill"), payment_vendor_cb},
+        { N_("View/Edit Vendor"), edit_vendor_cb, NULL},
+        { N_("Vendor's Jobs"), jobs_vendor_cb, NULL},
+        //    { N_("Vendor Orders"), order_vendor_cb, NULL},
+        { N_("Vendor's Bills"), invoice_vendor_cb, NULL},
+        { N_("Pay Bill"), payment_vendor_cb, NULL},
         { NULL },
     };
     (void)order_vendor_cb;

Modified: gnucash/trunk/src/gnome-search/dialog-search.c
===================================================================
--- gnucash/trunk/src/gnome-search/dialog-search.c	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/gnome-search/dialog-search.c	2011-11-18 21:53:13 UTC (rev 21580)
@@ -74,6 +74,8 @@
     /* The "results" sub-window widgets */
     GtkWidget *	result_list;
     gpointer	selected_item;
+    GList *selected_item_list;
+    GTree *selected_row_btree;
 
     /* The search_type radio-buttons */
     GtkWidget *	new_rb;
@@ -136,13 +138,38 @@
 static void search_clear_criteria (GNCSearchWindow *sw);
 static void gnc_search_dialog_display_results (GNCSearchWindow *sw);
 
+/** The callback for converting the row numbers from a GTree to actual item
+pointers in a GList */
+static gboolean cb_tree_to_itemlist (gpointer key,
+                                     gpointer value,
+                                     gpointer user_data)
+{
+    GNCSearchWindow *sw = user_data;
+    gpointer item = gtk_clist_get_row_data (GTK_CLIST(sw->result_list), GPOINTER_TO_INT(key));
+    sw->selected_item_list = g_list_prepend(sw->selected_item_list, item);
+    return FALSE;
+}
 
 static void
 gnc_search_callback_button_execute (GNCSearchCallbackButton *cb,
                                     GNCSearchWindow *sw)
 {
-    if (cb->cb_fcn)
-        (cb->cb_fcn)(&(sw->selected_item), sw->user_data);
+    // Do we have a callback for multi-selections, and also more than one selected item?
+    if (cb->cb_multiselect_fn && (g_tree_nnodes(sw->selected_row_btree) > 1))
+    {
+        // Yes, use the multi-selection callback
+        sw->selected_item_list = NULL;
+        g_tree_foreach(sw->selected_row_btree, cb_tree_to_itemlist, sw);
+        (cb->cb_multiselect_fn)(sw->selected_item_list, sw->user_data);
+        g_list_free(sw->selected_item_list);
+        sw->selected_item_list = NULL;
+    }
+    else
+    {
+        // No, stick to the single-item callback
+        if (cb->cb_fcn)
+            (cb->cb_fcn)(&(sw->selected_item), sw->user_data);
+    }
 }
 
 
@@ -212,7 +239,11 @@
 {
     GNCSearchWindow *sw = user_data;
     sw->selected_item = gtk_clist_get_row_data (clist, row);
+    //g_message("select-row, row=%d", row);
 
+    // Keep note of the selection of this row
+    g_tree_insert(sw->selected_row_btree, GINT_TO_POINTER(row), NULL);
+
     /* If we double-click an item, then either "select" it, or run it
      * through the first button (which should be view/edit
      */
@@ -236,7 +267,11 @@
 {
     GNCSearchWindow *sw = user_data;
     gpointer item = gtk_clist_get_row_data (clist, row);
+    //g_message("unselect-row, row=%d", row);
 
+    // Remove this row from the noted selection
+    g_tree_remove(sw->selected_row_btree, GINT_TO_POINTER(row));
+
     if (sw->selected_item == item)
         sw->selected_item = NULL;
 }
@@ -246,6 +281,10 @@
 gnc_search_dialog_init_result_list (GNCSearchWindow *sw)
 {
     sw->result_list = gnc_query_list_new(sw->display_list, sw->q);
+//#if GTK_CHECK_VERSION(2, 24, 0)
+//    // Apparently the multi-selection mode of GtkCList is broken in gtk-2.20
+//    gtk_clist_set_selection_mode(GTK_CLIST(sw->result_list), GTK_SELECTION_MULTIPLE);
+//#endif
 
     /* Setup the list callbacks */
     g_signal_connect (G_OBJECT (sw->result_list), "select-row",
@@ -1046,6 +1085,7 @@
     if (!sw) return;
     if (sw->gconf_section)
         gnc_save_window_size(sw->gconf_section, GTK_WINDOW(sw->dialog));
+    g_tree_destroy(sw->selected_row_btree);
     gnc_close_gui_component (sw->component_id);
 }
 
@@ -1057,6 +1097,11 @@
     gtk_window_present (GTK_WINDOW(sw->dialog));
 }
 
+static gint
+my_comparefunc_gint(gconstpointer a, gconstpointer b)
+{
+    return GPOINTER_TO_INT(a) < GPOINTER_TO_INT(b);
+}
 
 GNCSearchWindow *
 gnc_search_dialog_create (QofIdTypeConst obj_type, const gchar *title,
@@ -1094,6 +1139,8 @@
     sw->gconf_section = gconf_section;
     sw->type_label = type_label;
 
+    sw->selected_row_btree = g_tree_new(my_comparefunc_gint);
+
     /* Grab the get_guid function */
     sw->get_guid = qof_class_get_parameter (sw->search_for, QOF_PARAM_GUID);
     if (start_query)
@@ -1232,11 +1279,11 @@
     static GNCSearchCallbackButton buttons[] =
     {
         /* Don't mark these as translatable since these are only test strings! */
-        { ("View Split"), do_nothing },
-        { ("New Split"), do_nothing },
-        { ("Do Something"), do_nothing },
-        { ("Do Nothing"), do_nothing },
-        { ("Who Cares?"), do_nothing },
+        { ("View Split"), do_nothing, NULL },
+        { ("New Split"), do_nothing, NULL },
+        { ("Do Something"), do_nothing, NULL },
+        { ("Do Nothing"), do_nothing, NULL },
+        { ("Who Cares?"), do_nothing, NULL },
         { NULL }
     };
 

Modified: gnucash/trunk/src/gnome-search/dialog-search.h
===================================================================
--- gnucash/trunk/src/gnome-search/dialog-search.h	2011-11-18 21:04:01 UTC (rev 21579)
+++ gnucash/trunk/src/gnome-search/dialog-search.h	2011-11-18 21:53:13 UTC (rev 21580)
@@ -56,17 +56,25 @@
 /* Free the general user_data object */
 typedef void (*GNCSearchFree) (gpointer user_data);
 
-/* This callback is called when (if) the user clicks the 'select'
+/** This callback is called when (if) the user clicks the 'select'
  * button.  The search dialog will close when this callback function
  * returns.
  */
 typedef void (*GNCSearchSelectedCB) (gpointer selected_object,
                                      gpointer user_data);
 
+/** This callback is called when (if) the user clicks the 'select'
+ * button.  The search dialog will close when this callback function
+ * returns.
+ */
+typedef void (*GNCSearchMultiSelectedCB) (GList *list_of_selected_objects,
+                                          gpointer user_data);
+
 typedef struct
 {
     const char *		label;
     GNCSearchCallback	cb_fcn;
+    GNCSearchMultiSelectedCB cb_multiselect_fn;
 } GNCSearchCallbackButton;
 
 /* Caller MUST supply _EITHER_ a result_callback or a list of callback



More information about the gnucash-changes mailing list