GnuCash c935c2f+
Loading...
Searching...
No Matches
dialog-customer.c
1/*
2 * dialog-customer.c -- Dialog for Customer entry
3 * Copyright (C) 2001 Derek Atkins
4 * Author: Derek Atkins <warlord@MIT.EDU>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, contact:
18 *
19 * Free Software Foundation Voice: +1-617-542-5942
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21 * Boston, MA 02110-1301, USA gnu@gnu.org
22 */
23
24#include <config.h>
25
26#include <gtk/gtk.h>
27#include <glib/gi18n.h>
28#include <gdk/gdkkeysyms.h>
29
30#include "dialog-utils.h"
31#include "gnc-amount-edit.h"
32#include "gnc-currency-edit.h"
33#include "gnc-component-manager.h"
34#include "gnc-ui.h"
35#include "gnc-gui-query.h"
36#include "gnc-ui-util.h"
37#include "qof.h"
38
39#include "dialog-search.h"
40#include "search-param.h"
41#include "QuickFill.h"
42#include "gnc-addr-quickfill.h"
43
44#include "gncAddress.h"
45#include "gncCustomer.h"
46#include "gncCustomerP.h"
47
48#include "business-gnome-utils.h"
49#include "dialog-customer.h"
50#include "dialog-job.h"
51#include "dialog-order.h"
52#include "dialog-invoice.h"
53#include "dialog-payment.h"
54
55#define DIALOG_NEW_CUSTOMER_CM_CLASS "dialog-new-customer"
56#define DIALOG_EDIT_CUSTOMER_CM_CLASS "dialog-edit-customer"
57
58#define GNC_PREFS_GROUP_SEARCH "dialogs.business.customer-search"
59
60void gnc_customer_taxtable_check_cb (GtkToggleButton *togglebutton,
61 gpointer user_data);
62
63void gnc_customer_window_ok_cb (GtkWidget *widget, gpointer data);
64void gnc_customer_window_cancel_cb (GtkWidget *widget, gpointer data);
65void gnc_customer_window_help_cb (GtkWidget *widget, gpointer data);
66void gnc_customer_window_destroy_cb (GtkWidget *widget, gpointer data);
67void gnc_customer_name_changed_cb (GtkWidget *widget, gpointer data);
68void gnc_customer_terms_changed_cb (GtkWidget *widget, gpointer data);
69void gnc_customer_taxincluded_changed_cb (GtkWidget *widget, gpointer data);
70void gnc_customer_taxtable_changed_cb (GtkWidget *widget, gpointer data);
71void gnc_customer_addr2_insert_cb(GtkEditable *editable,
72 gchar *new_text, gint new_text_length,
73 gint *position, gpointer user_data);
74void gnc_customer_addr3_insert_cb(GtkEditable *editable,
75 gchar *new_text, gint new_text_length,
76 gint *position, gpointer user_data);
77void gnc_customer_addr4_insert_cb(GtkEditable *editable,
78 gchar *new_text, gint new_text_length,
79 gint *position, gpointer user_data);
80void gnc_customer_shipaddr2_insert_cb(GtkEditable *editable,
81 gchar *new_text, gint new_text_length,
82 gint *position, gpointer user_data);
83void gnc_customer_shipaddr3_insert_cb(GtkEditable *editable,
84 gchar *new_text, gint new_text_length,
85 gint *position, gpointer user_data);
86void gnc_customer_shipaddr4_insert_cb(GtkEditable *editable,
87 gchar *new_text, gint new_text_length,
88 gint *position, gpointer user_data);
89gboolean
90gnc_customer_addr2_key_press_cb( GtkEntry *entry, GdkEventKey *event,
91 gpointer user_data );
92gboolean
93gnc_customer_addr3_key_press_cb( GtkEntry *entry, GdkEventKey *event,
94 gpointer user_data );
95gboolean
96gnc_customer_addr4_key_press_cb( GtkEntry *entry, GdkEventKey *event,
97 gpointer user_data );
98gboolean
99gnc_customer_shipaddr2_key_press_cb( GtkEntry *entry, GdkEventKey *event,
100 gpointer user_data );
101gboolean
102gnc_customer_shipaddr3_key_press_cb( GtkEntry *entry, GdkEventKey *event,
103 gpointer user_data );
104gboolean
105gnc_customer_shipaddr4_key_press_cb( GtkEntry *entry, GdkEventKey *event,
106 gpointer user_data );
107
108#define ADDR_QUICKFILL "GncAddress-Quickfill"
109
110typedef enum
111{
112 NEW_CUSTOMER,
113 EDIT_CUSTOMER
114} CustomerDialogType;
115
117{
118 QofBook *book;
119 QofQuery *q;
120};
121
123{
124 GtkWidget * dialog;
125
126 GtkWidget * id_entry;
127 GtkWidget * company_entry;
128
129 GtkWidget * name_entry;
130 GtkWidget * addr1_entry;
131 GtkWidget * addr2_entry;
132 GtkWidget * addr3_entry;
133 GtkWidget * addr4_entry;
134 GtkWidget * phone_entry;
135 GtkWidget * fax_entry;
136 GtkWidget * email_entry;
137
138 GtkWidget * shipname_entry;
139 GtkWidget * shipaddr1_entry;
140 GtkWidget * shipaddr2_entry;
141 GtkWidget * shipaddr3_entry;
142 GtkWidget * shipaddr4_entry;
143 GtkWidget * shipphone_entry;
144 GtkWidget * shipfax_entry;
145 GtkWidget * shipemail_entry;
146
147 GtkWidget * currency_edit;
148 GtkWidget * terms_menu;
149 GtkWidget * discount_amount;
150 GtkWidget * credit_amount;
151
152 GtkWidget * active_check;
153 GtkWidget * taxincluded_menu;
154 GtkWidget * notes_text;
155
156 GtkWidget * taxtable_check;
157 GtkWidget * taxtable_menu;
158
159 GncTaxIncluded taxincluded;
160 GncBillTerm * terms;
161 CustomerDialogType dialog_type;
162 GncGUID customer_guid;
163 gint component_id;
164 QofBook * book;
165 GncCustomer * created_customer;
166
167 GncTaxTable * taxtable;
168
169 /* stored data for the description quickfill selection function */
170 QuickFill *addr2_quickfill;
171 QuickFill *addr3_quickfill;
172 QuickFill *addr4_quickfill;
173 gint addrX_start_selection;
174 gint addrX_end_selection;
175 guint addrX_selection_source_id;
176};
177
178void
179gnc_customer_taxtable_check_cb (GtkToggleButton *togglebutton,
180 gpointer user_data)
181{
182 CustomerWindow *cw = user_data;
183
184 if (gtk_toggle_button_get_active (togglebutton))
185 gtk_widget_set_sensitive (cw->taxtable_menu, TRUE);
186 else
187 gtk_widget_set_sensitive (cw->taxtable_menu, FALSE);
188}
189
190static GncCustomer *
191cw_get_customer (CustomerWindow *cw)
192{
193 if (!cw)
194 return NULL;
195
196 return gncCustomerLookup (cw->book, &cw->customer_guid);
197}
198
199static void gnc_ui_to_customer (CustomerWindow *cw, GncCustomer *cust)
200{
201 GtkTextBuffer* text_buffer;
202 GtkTextIter start, end;
203 gchar *text;
204 GncAddress *addr, *shipaddr;
205
206 addr = gncCustomerGetAddr (cust);
207 shipaddr = gncCustomerGetShipAddr (cust);
208
209 gnc_suspend_gui_refresh ();
210
211 gncCustomerBeginEdit (cust);
212
213 if (cw->dialog_type == NEW_CUSTOMER)
214 qof_event_gen(QOF_INSTANCE(cust), QOF_EVENT_ADD, NULL);
215
216 gncCustomerSetID (cust, gtk_entry_get_text (GTK_ENTRY (cw->id_entry)));
217 gncCustomerSetName (cust, gtk_entry_get_text (GTK_ENTRY (cw->company_entry)));
218
219 gncAddressSetName (addr, gtk_entry_get_text (GTK_ENTRY (cw->name_entry)));
220 gncAddressSetAddr1 (addr, gtk_entry_get_text (GTK_ENTRY (cw->addr1_entry)));
221 gncAddressSetAddr2 (addr, gtk_entry_get_text (GTK_ENTRY (cw->addr2_entry)));
222 gncAddressSetAddr3 (addr, gtk_entry_get_text (GTK_ENTRY (cw->addr3_entry)));
223 gncAddressSetAddr4 (addr, gtk_entry_get_text (GTK_ENTRY (cw->addr4_entry)));
224 gncAddressSetPhone (addr, gtk_entry_get_text (GTK_ENTRY (cw->phone_entry)));
225 gncAddressSetFax (addr, gtk_entry_get_text (GTK_ENTRY (cw->fax_entry)));
226 gncAddressSetEmail (addr, gtk_entry_get_text (GTK_ENTRY (cw->email_entry)));
227 gncAddressSetName (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipname_entry)));
228 gncAddressSetAddr1 (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipaddr1_entry)));
229 gncAddressSetAddr2 (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipaddr2_entry)));
230 gncAddressSetAddr3 (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipaddr3_entry)));
231 gncAddressSetAddr4 (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipaddr4_entry)));
232 gncAddressSetPhone (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipphone_entry)));
233 gncAddressSetFax (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipfax_entry)));
234 gncAddressSetEmail (shipaddr, gtk_entry_get_text (GTK_ENTRY (cw->shipemail_entry)));
235
236 gncCustomerSetActive (cust, gtk_toggle_button_get_active
237 (GTK_TOGGLE_BUTTON (cw->active_check)));
238 gncCustomerSetTaxIncluded (cust, cw->taxincluded);
239
240 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(cw->notes_text));
241 gtk_text_buffer_get_bounds (text_buffer, &start, &end);
242 text = gtk_text_buffer_get_text (text_buffer, &start, &end, FALSE);
243 gncCustomerSetNotes (cust, text);
244
245 /* Parse and set the currency, terms, discount, and credit amounts */
246 gncCustomerSetCurrency (cust,
247 gnc_currency_edit_get_currency (GNC_CURRENCY_EDIT
248 (cw->currency_edit)));
249 gncCustomerSetTerms (cust, cw->terms);
250 gncCustomerSetDiscount (cust, gnc_amount_edit_get_amount
251 (GNC_AMOUNT_EDIT (cw->discount_amount)));
252 gncCustomerSetCredit (cust, gnc_amount_edit_get_amount
253 (GNC_AMOUNT_EDIT (cw->credit_amount)));
254
255 gncCustomerSetTaxTableOverride
256 (cust, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (cw->taxtable_check)));
257 gncCustomerSetTaxTable (cust, cw->taxtable);
258
259 gncCustomerCommitEdit (cust);
260 gnc_resume_gui_refresh ();
261 g_free (text);
262}
263
264static gboolean check_edit_amount (GtkWidget *amount,
265 gnc_numeric *min, gnc_numeric *max,
266 const char * error_message)
267{
268 GError *error = NULL;
269 if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (amount), &error))
270 {
271 gnc_error_dialog (gnc_ui_get_gtk_window (amount), "%s", error->message);
272 g_error_free (error);
273 return TRUE;
274 }
275 /* We've got a valid-looking number; check mix/max */
276 if (min || max)
277 {
278 gnc_numeric val = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (amount));
279 if ((min && gnc_numeric_compare (*min, val) > 0) ||
280 (max && gnc_numeric_compare (val, *max) > 0))
281 {
282 if (error_message)
283 gnc_error_dialog (gnc_ui_get_gtk_window (amount), "%s", error_message);
284 return TRUE;
285 }
286 }
287 return FALSE;
288}
289
290static gboolean check_entry_nonempty (GtkWidget *entry,
291 const char * error_message)
292{
293 const char *res = gtk_entry_get_text (GTK_ENTRY (entry));
294 if (g_strcmp0 (res, "") == 0)
295 {
296 if (error_message)
297 gnc_error_dialog (gnc_ui_get_gtk_window (entry), "%s", error_message);
298 return TRUE;
299 }
300 return FALSE;
301}
302
303void
304gnc_customer_window_ok_cb (GtkWidget *widget, gpointer data)
305{
306 CustomerWindow *cw = data;
307 gnc_numeric min, max;
308 gchar *string;
309 gnc_commodity *currency;
310 GNCPrintAmountInfo print_info;
311
312 /* Check for valid company name */
313 if (check_entry_nonempty (cw->company_entry,
314 _("The Company Name field cannot be left blank, please "
315 "enter a company name or a person's name.")))
316 return;
317
318 /* Verify terms, discount, and credit are valid (or empty) */
319 min = gnc_numeric_zero ();
320 max = gnc_numeric_create (100, 1);
321
322 if (check_edit_amount (cw->discount_amount, &min, &max,
323 _("Discount percentage must be between 0-100 "
324 "or you must leave it blank.")))
325 return;
326
327 currency = gnc_currency_edit_get_currency (GNC_CURRENCY_EDIT(cw->currency_edit));
328 print_info = gnc_commodity_print_info (currency, FALSE);
329 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (cw->credit_amount), print_info);
330 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (cw->credit_amount),
331 gnc_commodity_get_fraction (currency));
332
333 if (check_edit_amount (cw->credit_amount, &min, NULL,
334 _("Credit must be a positive amount or "
335 "you must leave it blank.")))
336 return;
337
338 /* Set the customer id if one has not been chosen */
339 if (g_strcmp0 (gtk_entry_get_text (GTK_ENTRY (cw->id_entry)), "") == 0)
340 {
341 string = gncCustomerNextID (cw->book);
342 gtk_entry_set_text (GTK_ENTRY (cw->id_entry), string);
343 g_free(string);
344 }
345
346 /* Now save it off */
347 {
348 GncCustomer *customer = cw_get_customer (cw);
349 if (customer)
350 {
351 gnc_ui_to_customer (cw, customer);
352 }
353 cw->created_customer = customer;
354 cw->customer_guid = *guid_null ();
355 }
356
357 gnc_close_gui_component (cw->component_id);
358}
359
360void
361gnc_customer_window_cancel_cb (GtkWidget *widget, gpointer data)
362{
363 CustomerWindow *cw = data;
364
365 gnc_close_gui_component (cw->component_id);
366}
367
368void
369gnc_customer_window_help_cb (GtkWidget *widget, gpointer data)
370{
371 CustomerWindow *cw = data;
372 gnc_gnome_help (GTK_WINDOW(cw->dialog), DF_MANUAL, DL_USAGE_CUSTOMER);
373}
374
375void
376gnc_customer_window_destroy_cb (GtkWidget *widget, gpointer data)
377{
378 CustomerWindow *cw = data;
379 GncCustomer *customer = cw_get_customer (cw);
380
381 gnc_suspend_gui_refresh ();
382
383 if (cw->dialog_type == NEW_CUSTOMER && customer != NULL)
384 {
385 gncCustomerBeginEdit (customer);
386 gncCustomerDestroy (customer);
387 cw->customer_guid = *guid_null ();
388 }
389
390 if (cw->addrX_selection_source_id)
391 g_source_remove (cw->addrX_selection_source_id);
392
393 gnc_unregister_gui_component (cw->component_id);
394 gnc_resume_gui_refresh ();
395
396 g_free (cw);
397}
398
399void
400gnc_customer_name_changed_cb (GtkWidget *widget, gpointer data)
401{
402 CustomerWindow *cw = data;
403 if (!cw)
404 return;
405
406 gnc_owner_window_set_title (GTK_WINDOW (cw->dialog),
407 (cw->dialog_type == EDIT_CUSTOMER) ?
408 _("Edit Customer") : _("New Customer"),
409 cw->company_entry, cw->id_entry);
410}
411
412void
413gnc_customer_terms_changed_cb (GtkWidget *widget, gpointer data)
414{
415 GtkComboBox *cbox = GTK_COMBO_BOX (widget);
416 CustomerWindow *cw = data;
417
418 if (!cw) return;
419 if (!cbox) return;
420
421 cw->terms = gnc_simple_combo_get_value (cbox);
422}
423
424void
425gnc_customer_taxincluded_changed_cb (GtkWidget *widget, gpointer data)
426{
427 GtkComboBox *cbox = GTK_COMBO_BOX (widget);
428 CustomerWindow *cw = data;
429
430 if (!cw) return;
431 if (!cbox) return;
432
433 cw->taxincluded = GPOINTER_TO_INT (gnc_simple_combo_get_value (cbox));
434}
435
436void
437gnc_customer_taxtable_changed_cb (GtkWidget *widget, gpointer data)
438{
439 GtkComboBox *cbox = GTK_COMBO_BOX (widget);
440 CustomerWindow *cw = data;
441
442 if (!cw) return;
443 if (!cbox) return;
444
445 cw->taxtable = gnc_simple_combo_get_value (cbox);
446}
447
448static void
449gnc_customer_window_close_handler (gpointer user_data)
450{
451 CustomerWindow *cw = user_data;
452
453 gtk_widget_destroy (cw->dialog);
454 // cw has already been freed by this point.
455 // cw->dialog = NULL;
456}
457
458static void
459gnc_customer_window_refresh_handler (GHashTable *changes, gpointer user_data)
460{
461 CustomerWindow *cw = user_data;
462 const EventInfo *info;
463 GncCustomer *customer = cw_get_customer (cw);
464
465 /* If there isn't a customer behind us, close down */
466 if (!customer)
467 {
468 gnc_close_gui_component (cw->component_id);
469 return;
470 }
471
472 /* Next, close if this is a destroy event */
473 if (changes)
474 {
475 info = gnc_gui_get_entity_events (changes, &cw->customer_guid);
476 if (info && (info->event_mask & QOF_EVENT_DESTROY))
477 {
478 gnc_close_gui_component (cw->component_id);
479 return;
480 }
481 }
482}
483
484static gboolean
485find_handler (gpointer find_data, gpointer user_data)
486{
487 const GncGUID *customer_guid = find_data;
488 CustomerWindow *cw = user_data;
489
490 return(cw && guid_equal(&cw->customer_guid, customer_guid));
491}
492
493static CustomerWindow *
494gnc_customer_new_window (GtkWindow *parent, QofBook *bookp, GncCustomer *cust)
495{
496 CustomerWindow *cw;
497 GtkBuilder *builder;
498 GtkWidget *hbox, *edit;
499 gnc_commodity *currency;
500 GNCPrintAmountInfo print_info;
501
502 /*
503 * Find an existing window for this customer. If found, bring it to
504 * the front.
505 */
506 if (cust)
507 {
508 GncGUID customer_guid;
509
510 customer_guid = *gncCustomerGetGUID(cust);
511 cw = gnc_find_first_gui_component (DIALOG_EDIT_CUSTOMER_CM_CLASS,
512 find_handler, &customer_guid);
513 if (cw)
514 {
515 gtk_window_set_transient_for (GTK_WINDOW(cw->dialog), parent);
516 gtk_window_present (GTK_WINDOW(cw->dialog));
517 return(cw);
518 }
519 }
520
521 /* Find the default currency */
522 if (cust)
523 currency = gncCustomerGetCurrency (cust);
524 else
525 currency = gnc_default_currency ();
526
527 /*
528 * No existing customer window found. Build a new one.
529 */
530 cw = g_new0 (CustomerWindow, 1);
531
532 cw->book = bookp;
533
534 /* Find the dialog */
535 builder = gtk_builder_new();
536 gnc_builder_add_from_file (builder, "dialog-customer.glade", "terms_store");
537 gnc_builder_add_from_file (builder, "dialog-customer.glade", "tax_included_store");
538 gnc_builder_add_from_file (builder, "dialog-customer.glade", "taxtable_store");
539 gnc_builder_add_from_file (builder, "dialog-customer.glade", "customer_dialog");
540 cw->dialog = GTK_WIDGET (gtk_builder_get_object (builder, "customer_dialog"));
541 gtk_window_set_transient_for (GTK_WINDOW(cw->dialog), parent);
542
543 // Set the name for this dialog so it can be easily manipulated with css
544 gtk_widget_set_name (GTK_WIDGET(cw->dialog), "gnc-id-customer");
545 gnc_widget_style_context_add_class (GTK_WIDGET(cw->dialog), "gnc-class-customers");
546
547 g_object_set_data (G_OBJECT (cw->dialog), "dialog_info", cw);
548
549 /* Get entry points */
550 cw->id_entry = GTK_WIDGET (gtk_builder_get_object (builder, "id_entry"));
551 cw->company_entry = GTK_WIDGET (gtk_builder_get_object (builder, "company_entry"));
552
553 cw->name_entry = GTK_WIDGET (gtk_builder_get_object (builder, "name_entry"));
554 cw->addr1_entry = GTK_WIDGET (gtk_builder_get_object (builder, "addr1_entry"));
555 cw->addr2_entry = GTK_WIDGET (gtk_builder_get_object (builder, "addr2_entry"));
556 cw->addr3_entry = GTK_WIDGET (gtk_builder_get_object (builder, "addr3_entry"));
557 cw->addr4_entry = GTK_WIDGET (gtk_builder_get_object (builder, "addr4_entry"));
558 cw->phone_entry = GTK_WIDGET (gtk_builder_get_object (builder, "phone_entry"));
559 cw->fax_entry = GTK_WIDGET (gtk_builder_get_object (builder, "fax_entry"));
560 cw->email_entry = GTK_WIDGET (gtk_builder_get_object (builder, "email_entry"));
561
562 cw->shipname_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipname_entry"));
563 cw->shipaddr1_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipaddr1_entry"));
564 cw->shipaddr2_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipaddr2_entry"));
565 cw->shipaddr3_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipaddr3_entry"));
566 cw->shipaddr4_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipaddr4_entry"));
567 cw->shipphone_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipphone_entry"));
568 cw->shipfax_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipfax_entry"));
569 cw->shipemail_entry = GTK_WIDGET (gtk_builder_get_object (builder, "shipemail_entry"));
570
571 cw->active_check = GTK_WIDGET (gtk_builder_get_object (builder, "active_check"));
572 cw->taxincluded_menu = GTK_WIDGET (gtk_builder_get_object (builder, "tax_included_menu"));
573 cw->notes_text = GTK_WIDGET (gtk_builder_get_object (builder, "notes_text"));
574
575 cw->terms_menu = GTK_WIDGET (gtk_builder_get_object (builder, "terms_menu"));
576
577 cw->taxtable_check = GTK_WIDGET (gtk_builder_get_object (builder, "taxtable_button"));
578 cw->taxtable_menu = GTK_WIDGET (gtk_builder_get_object (builder, "taxtable_menu"));
579
580 /* Currency */
581 edit = gnc_currency_edit_new();
582 gnc_currency_edit_set_currency (GNC_CURRENCY_EDIT(edit), currency);
583 cw->currency_edit = edit;
584
585 hbox = GTK_WIDGET (gtk_builder_get_object (builder, "currency_box"));
586 gtk_box_pack_start (GTK_BOX (hbox), edit, TRUE, TRUE, 0);
587
588 /* DISCOUNT: Percentage Value */
589 edit = gnc_amount_edit_new();
590 gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (edit), TRUE);
591 print_info = gnc_integral_print_info ();
592 print_info.max_decimal_places = 5;
593 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (edit), print_info);
594 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (edit), 100000);
595 cw->discount_amount = edit;
596 gtk_widget_show (edit);
597
598 hbox = GTK_WIDGET (gtk_builder_get_object (builder, "discount_box"));
599 gtk_box_pack_start (GTK_BOX (hbox), edit, TRUE, TRUE, 0);
600
601 /* CREDIT: Monetary Value */
602 edit = gnc_amount_edit_new();
603 print_info = gnc_commodity_print_info (currency, FALSE);
604 gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (edit), TRUE);
605 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (edit), print_info);
606 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (edit),
607 gnc_commodity_get_fraction (currency));
608 cw->credit_amount = edit;
609 gtk_widget_show (edit);
610
611 hbox = GTK_WIDGET (gtk_builder_get_object (builder, "credit_box"));
612 gtk_box_pack_start (GTK_BOX (hbox), edit, TRUE, TRUE, 0);
613
614 /* Setup signals */
615 gtk_builder_connect_signals_full( builder,
616 gnc_builder_connect_full_func,
617 cw);
618
619 /* Setup initial values */
620 if (cust != NULL)
621 {
622 GtkTextBuffer* text_buffer;
623 GncAddress *addr, *shipaddr;
624 const char *string;
625
626 cw->dialog_type = EDIT_CUSTOMER;
627 cw->customer_guid = *gncCustomerGetGUID (cust);
628
629 addr = gncCustomerGetAddr (cust);
630 shipaddr = gncCustomerGetShipAddr (cust);
631
632 gtk_entry_set_text (GTK_ENTRY (cw->id_entry), gncCustomerGetID (cust));
633 gtk_entry_set_text (GTK_ENTRY (cw->company_entry), gncCustomerGetName (cust));
634
635 /* Setup Address */
636 gtk_entry_set_text (GTK_ENTRY (cw->name_entry), gncAddressGetName (addr));
637 gtk_entry_set_text (GTK_ENTRY (cw->addr1_entry), gncAddressGetAddr1 (addr));
638 gtk_entry_set_text (GTK_ENTRY (cw->addr2_entry), gncAddressGetAddr2 (addr));
639 gtk_entry_set_text (GTK_ENTRY (cw->addr3_entry), gncAddressGetAddr3 (addr));
640 gtk_entry_set_text (GTK_ENTRY (cw->addr4_entry), gncAddressGetAddr4 (addr));
641 gtk_entry_set_text (GTK_ENTRY (cw->phone_entry), gncAddressGetPhone (addr));
642 gtk_entry_set_text (GTK_ENTRY (cw->fax_entry), gncAddressGetFax (addr));
643 gtk_entry_set_text (GTK_ENTRY (cw->email_entry), gncAddressGetEmail (addr));
644
645 /* Setup Ship-to Address */
646 gtk_entry_set_text (GTK_ENTRY (cw->shipname_entry), gncAddressGetName (shipaddr));
647 gtk_entry_set_text (GTK_ENTRY (cw->shipaddr1_entry), gncAddressGetAddr1 (shipaddr));
648 gtk_entry_set_text (GTK_ENTRY (cw->shipaddr2_entry), gncAddressGetAddr2 (shipaddr));
649 gtk_entry_set_text (GTK_ENTRY (cw->shipaddr3_entry), gncAddressGetAddr3 (shipaddr));
650 gtk_entry_set_text (GTK_ENTRY (cw->shipaddr4_entry), gncAddressGetAddr4 (shipaddr));
651 gtk_entry_set_text (GTK_ENTRY (cw->shipphone_entry), gncAddressGetPhone (shipaddr));
652 gtk_entry_set_text (GTK_ENTRY (cw->shipfax_entry), gncAddressGetFax (shipaddr));
653 gtk_entry_set_text (GTK_ENTRY (cw->shipemail_entry), gncAddressGetEmail (shipaddr));
654
655 /* Set toggle buttons */
656 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw->active_check),
657 gncCustomerGetActive (cust));
658
659 string = gncCustomerGetNotes (cust);
660 text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(cw->notes_text));
661 gtk_text_buffer_set_text (text_buffer, string, -1);
662
663 cw->component_id =
664 gnc_register_gui_component (DIALOG_EDIT_CUSTOMER_CM_CLASS,
665 gnc_customer_window_refresh_handler,
666 gnc_customer_window_close_handler,
667 cw);
668 cw->terms = gncCustomerGetTerms (cust);
669
670 }
671 else
672 {
673 cust = gncCustomerCreate (bookp);
674 cw->customer_guid = *gncCustomerGetGUID (cust);
675
676 cw->dialog_type = NEW_CUSTOMER;
677 cw->component_id =
678 gnc_register_gui_component (DIALOG_NEW_CUSTOMER_CM_CLASS,
679 gnc_customer_window_refresh_handler,
680 gnc_customer_window_close_handler,
681 cw);
682
683 /* XXX: get the global-default terms */
684 cw->terms = NULL;
685 }
686
687 /* I know that cust exists here -- either passed in or just created */
688
689 cw->taxincluded = gncCustomerGetTaxIncluded (cust);
690 gnc_taxincluded_combo (GTK_COMBO_BOX(cw->taxincluded_menu), cw->taxincluded);
691 gnc_billterms_combo (GTK_COMBO_BOX(cw->terms_menu), bookp, TRUE, cw->terms);
692
693 cw->taxtable = gncCustomerGetTaxTable (cust);
694 gnc_taxtables_combo (GTK_COMBO_BOX(cw->taxtable_menu), bookp, TRUE, cw->taxtable);
695 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cw->taxtable_check),
696 gncCustomerGetTaxTableOverride (cust));
697 gnc_customer_taxtable_check_cb (GTK_TOGGLE_BUTTON (cw->taxtable_check), cw);
698
699 /* Set up the addr line quickfill */
700 cw->addr2_quickfill = gnc_get_shared_address_addr2_quickfill(cw->book, ADDR_QUICKFILL);
701 cw->addr3_quickfill = gnc_get_shared_address_addr3_quickfill(cw->book, ADDR_QUICKFILL);
702 cw->addr4_quickfill = gnc_get_shared_address_addr4_quickfill(cw->book, ADDR_QUICKFILL);
703
704 /* Set the Discount, and Credit amounts */
705 gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (cw->discount_amount),
706 gncCustomerGetDiscount (cust));
707 gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (cw->credit_amount),
708 gncCustomerGetCredit (cust));
709
710 gnc_gui_component_watch_entity_type (cw->component_id,
711 GNC_CUSTOMER_MODULE_NAME,
712 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
713
714 gtk_widget_show_all (cw->dialog);
715 g_object_unref(G_OBJECT(builder));
716
717 return cw;
718}
719
720CustomerWindow *
721gnc_ui_customer_edit (GtkWindow *parent, GncCustomer *cust)
722{
723 CustomerWindow *cw;
724
725 if (!cust) return NULL;
726
727 cw = gnc_customer_new_window (parent, gncCustomerGetBook(cust), cust);
728
729 return cw;
730}
731
732CustomerWindow *
733gnc_ui_customer_new (GtkWindow *parent, QofBook *bookp)
734{
735 CustomerWindow *cw;
736
737 /* Make sure required options exist */
738 if (!bookp) return NULL;
739
740 cw = gnc_customer_new_window (parent, bookp, NULL);
741
742 return cw;
743}
744
745/* Functions for customer selection widgets */
746
747static void
748invoice_customer_cb (GtkWindow *dialog, gpointer *cust_p, gpointer user_data)
749{
750 struct _customer_select_window *sw = user_data;
751 GncOwner owner;
752 GncCustomer *cust;
753
754 g_return_if_fail (cust_p && user_data);
755
756 cust = *cust_p;
757
758 if (!cust)
759 return;
760
761 gncOwnerInitCustomer (&owner, cust);
762 gnc_invoice_search (dialog, NULL, &owner, sw->book);
763 return;
764}
765
766static void
767order_customer_cb (GtkWindow *dialog, gpointer *cust_p, gpointer user_data)
768{
769 struct _customer_select_window *sw = user_data;
770 GncOwner owner;
771 GncCustomer *cust;
772
773 g_return_if_fail (cust_p && user_data);
774
775 cust = *cust_p;
776
777 if (!cust)
778 return;
779
780 gncOwnerInitCustomer (&owner, cust);
781 gnc_order_search (dialog, NULL, &owner, sw->book);
782 return;
783}
784
785static void
786jobs_customer_cb (GtkWindow *dialog, gpointer *cust_p, gpointer user_data)
787{
788 struct _customer_select_window *sw = user_data;
789 GncOwner owner;
790 GncCustomer *cust;
791
792 g_return_if_fail (cust_p && user_data);
793
794 cust = *cust_p;
795
796 if (!cust)
797 return;
798
799 gncOwnerInitCustomer (&owner, cust);
800 gnc_job_search (dialog, NULL, &owner, sw->book);
801 return;
802}
803
804static void
805payment_customer_cb (GtkWindow *dialog, gpointer *cust_p, gpointer user_data)
806{
807 struct _customer_select_window *sw = user_data;
808 GncOwner owner;
809 GncCustomer *cust;
810
811 g_return_if_fail (cust_p && user_data);
812
813 cust = *cust_p;
814
815 if (!cust)
816 return;
817
818 gncOwnerInitCustomer (&owner, cust);
819 gnc_ui_payment_new (dialog, &owner, sw->book);
820 return;
821}
822
823static void
824edit_customer_cb (GtkWindow *dialog, gpointer *cust_p, gpointer user_data)
825{
826 GncCustomer *cust;
827
828 g_return_if_fail (cust_p);
829 cust = *cust_p;
830
831 if (!cust)
832 return;
833
834 gnc_ui_customer_edit (dialog, cust);
835
836 return;
837}
838
839static gpointer
840new_customer_cb (GtkWindow *dialog, gpointer user_data)
841{
842 struct _customer_select_window *sw = user_data;
843 CustomerWindow *cw;
844
845 g_return_val_if_fail (sw, NULL);
846
847 cw = gnc_ui_customer_new (dialog, sw->book);
848 return cw_get_customer (cw);
849}
850
851static void
852free_userdata_cb (gpointer user_data)
853{
854 struct _customer_select_window *sw = user_data;
855
856 g_return_if_fail (sw);
857
858 qof_query_destroy (sw->q);
859 g_free (sw);
860}
861
862GNCSearchWindow *
863gnc_customer_search (GtkWindow *parent, GncCustomer *start, QofBook *book)
864{
865 QofQuery *q, *q2 = NULL;
866 QofIdType type = GNC_CUSTOMER_MODULE_NAME;
867 struct _customer_select_window *sw;
868 static GList *params = NULL;
869 static GList *columns = NULL;
870 static GNCSearchCallbackButton buttons[] =
871 {
872 { N_("View/Edit Customer"), edit_customer_cb, NULL, TRUE},
873 { N_("Customer's Jobs"), jobs_customer_cb, NULL, TRUE},
874 // { N_("Customer's Orders"), order_customer_cb, NULL, TRUE},
875 { N_("Customer's Invoices"), invoice_customer_cb, NULL, TRUE},
876 { N_("Process Payment"), payment_customer_cb, NULL, FALSE},
877 { NULL },
878 };
879 (void)order_customer_cb;
880
881 g_return_val_if_fail (book, NULL);
882
883 /* Build parameter list in reverse order */
884 if (params == NULL)
885 {
886 params = gnc_search_param_prepend (params, _("Shipping Contact"), NULL, type,
887 CUSTOMER_SHIPADDR, ADDRESS_NAME, NULL);
888 params = gnc_search_param_prepend (params, _("Billing Contact"), NULL, type,
889 CUSTOMER_ADDR, ADDRESS_NAME, NULL);
890 params = gnc_search_param_prepend (params, _("Customer ID"), NULL, type,
891 CUSTOMER_ID, NULL);
892 params = gnc_search_param_prepend (params, _("Company Name"), NULL, type,
893 CUSTOMER_NAME, NULL);
894 }
895
896 /* Build the column list in reverse order */
897 if (columns == NULL)
898 {
899 columns = gnc_search_param_prepend (columns, _("Shipping Contact"), NULL, type,
900 CUSTOMER_SHIPADDR, ADDRESS_NAME, NULL);
901 columns = gnc_search_param_prepend (columns, _("Contact"), NULL, type,
902 CUSTOMER_ADDR, ADDRESS_NAME, NULL);
903 columns = gnc_search_param_prepend (columns, _("Company"), NULL, type,
904 CUSTOMER_NAME, NULL);
905 columns = gnc_search_param_prepend (columns, _("ID #"), NULL, type,
906 CUSTOMER_ID, NULL);
907 }
908
909 /* Build the queries */
910 q = qof_query_create_for (type);
911 qof_query_set_book (q, book);
912
913#if 0
914 if (start)
915 {
916 q2 = qof_query_copy (q);
917 qof_query_add_guid_match (q2, g_slist_prepend (NULL, QOF_PARAM_GUID),
918 gncCustomerGetGUID (start), QOF_QUERY_AND);
919 }
920#endif
921
922 /* launch select dialog and return the result */
923 sw = g_new0 (struct _customer_select_window, 1);
924
925 sw->book = book;
926 sw->q = q;
927
928 return gnc_search_dialog_create (parent, type, _("Find Customer"),
929 params, columns, q, q2, buttons, NULL,
930 new_customer_cb, sw, free_userdata_cb,
931 GNC_PREFS_GROUP_SEARCH, NULL,
932 "gnc-class-customers");
933}
934
935GNCSearchWindow *
936gnc_customer_search_select (GtkWindow *parent, gpointer start, gpointer book)
937{
938 if (!book) return NULL;
939
940 return gnc_customer_search (parent, start, book);
941}
942
943GNCSearchWindow *
944gnc_customer_search_edit (GtkWindow *parent, gpointer start, gpointer book)
945{
946 if (start)
947 gnc_ui_customer_edit (parent, start);
948
949 return NULL;
950}
951
952static gboolean
953idle_select_region_addr2(gpointer user_data)
954{
955 CustomerWindow *wdata = user_data;
956 g_return_val_if_fail(user_data, FALSE);
957
958 /* g_warning("Selection start=%d end=%d",wdata->addrX_start_selection, wdata->addrX_end_selection); */
959
960 gtk_editable_select_region(GTK_EDITABLE(wdata->addr2_entry),
961 wdata->addrX_start_selection,
962 wdata->addrX_end_selection);
963
964 wdata->addrX_selection_source_id = 0;
965 return FALSE;
966}
967
968static gboolean
969idle_select_region_addr3(gpointer user_data)
970{
971 CustomerWindow *wdata = user_data;
972 g_return_val_if_fail(user_data, FALSE);
973
974 gtk_editable_select_region(GTK_EDITABLE(wdata->addr3_entry),
975 wdata->addrX_start_selection,
976 wdata->addrX_end_selection);
977
978 wdata->addrX_selection_source_id = 0;
979 return FALSE;
980}
981static gboolean
982idle_select_region_addr4(gpointer user_data)
983{
984 CustomerWindow *wdata = user_data;
985 g_return_val_if_fail(user_data, FALSE);
986
987 gtk_editable_select_region(GTK_EDITABLE(wdata->addr4_entry),
988 wdata->addrX_start_selection,
989 wdata->addrX_end_selection);
990 wdata->addrX_selection_source_id = 0;
991 return FALSE;
992}
993
994static gboolean
995idle_select_region_shipaddr2(gpointer user_data)
996{
997 CustomerWindow *wdata = user_data;
998 g_return_val_if_fail(user_data, FALSE);
999
1000 gtk_editable_select_region(GTK_EDITABLE(wdata->shipaddr2_entry),
1001 wdata->addrX_start_selection,
1002 wdata->addrX_end_selection);
1003
1004 wdata->addrX_selection_source_id = 0;
1005 return FALSE;
1006}
1007
1008static gboolean
1009idle_select_region_shipaddr3(gpointer user_data)
1010{
1011 CustomerWindow *wdata = user_data;
1012 g_return_val_if_fail(user_data, FALSE);
1013
1014 gtk_editable_select_region(GTK_EDITABLE(wdata->shipaddr3_entry),
1015 wdata->addrX_start_selection,
1016 wdata->addrX_end_selection);
1017
1018 wdata->addrX_selection_source_id = 0;
1019 return FALSE;
1020}
1021static gboolean
1022idle_select_region_shipaddr4(gpointer user_data)
1023{
1024 CustomerWindow *wdata = user_data;
1025 g_return_val_if_fail(user_data, FALSE);
1026
1027 gtk_editable_select_region(GTK_EDITABLE(wdata->shipaddr4_entry),
1028 wdata->addrX_start_selection,
1029 wdata->addrX_end_selection);
1030 wdata->addrX_selection_source_id = 0;
1031 return FALSE;
1032}
1033
1034/* Implementation of the steps common to all address lines. Returns
1035 * TRUE if anything was inserted by quickfill, otherwise FALSE. */
1036static gboolean
1037gnc_customer_addr_common_insert_cb(GtkEditable *editable,
1038 gchar *new_text, gint new_text_length,
1039 gint *position, gpointer user_data, QuickFill *qf)
1040{
1041 CustomerWindow *wdata = user_data;
1042 gchar *concatenated_text;
1043 QuickFill *match;
1044 gint prefix_len, concatenated_text_len;
1045
1046 if (new_text_length <= 0)
1047 return FALSE;
1048
1049 /*g_warning("In gnc_customer_addr_common_insert_cb");*/
1050
1051 {
1052 gchar *suffix = gtk_editable_get_chars(editable, *position, -1);
1053 /* If we are inserting in the middle, do nothing */
1054 if (*suffix)
1055 {
1056 g_free(suffix);
1057 return FALSE;
1058 }
1059 g_free(suffix);
1060 }
1061
1062 {
1063 gchar *prefix = gtk_editable_get_chars(editable, 0, *position);
1064 prefix_len = strlen(prefix);
1065 concatenated_text = g_strconcat(prefix, new_text, (gchar*) NULL);
1066 concatenated_text_len = prefix_len + new_text_length;
1067 g_free(prefix);
1068 }
1069
1070 match = gnc_quickfill_get_string_match(qf, concatenated_text);
1071 g_free(concatenated_text);
1072 if (match)
1073 {
1074 const char* match_str = gnc_quickfill_string(match);
1075 if (match_str)
1076 {
1077 gint match_str_len = strlen(match_str);
1078 if (match_str_len > concatenated_text_len)
1079 {
1080 /* g_warning("Got match \"%s\" match_str_len=%d new_text=%s position=%d prefix_len=%d", match_str, match_str_len, new_text, *position, prefix_len); */
1081
1082 g_signal_handlers_block_matched (G_OBJECT (editable),
1083 G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, user_data);
1084
1085 gtk_editable_insert_text(editable,
1086 match_str + prefix_len,
1087 match_str_len - prefix_len,
1088 position);
1089
1090 g_signal_handlers_unblock_matched (G_OBJECT (editable),
1091 G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, user_data);
1092
1093 /* stop the current insert */
1094 g_signal_stop_emission_by_name (G_OBJECT (editable), "insert_text");
1095
1096 /* set the position */
1097 *position = concatenated_text_len;
1098
1099 /* select region on idle, because it would be reset once this function
1100 finishes */
1101 wdata->addrX_start_selection = *position;
1102 wdata->addrX_end_selection = -1;
1103
1104 return TRUE;
1105 }
1106 }
1107 }
1108 return FALSE;
1109}
1110
1111void gnc_customer_addr2_insert_cb(GtkEditable *editable,
1112 gchar *new_text, gint new_text_length,
1113 gint *position, gpointer user_data)
1114{
1115 CustomerWindow *wdata = user_data;
1116 gboolean r;
1117
1118 /* The handling common to all address lines is done in this other
1119 * function. */
1120 r = gnc_customer_addr_common_insert_cb(editable, new_text, new_text_length,
1121 position, user_data, wdata->addr2_quickfill);
1122
1123 /* Did we insert something? Then set up the correct idle handler */
1124 if (r)
1125 {
1126 /* select region on idle, because it would be reset once this function
1127 finishes */
1128 wdata->addrX_selection_source_id = g_idle_add(idle_select_region_addr2,
1129 user_data);
1130 }
1131}
1132
1133void gnc_customer_addr3_insert_cb(GtkEditable *editable,
1134 gchar *new_text, gint new_text_length,
1135 gint *position, gpointer user_data)
1136{
1137 CustomerWindow *wdata = user_data;
1138 gboolean r;
1139
1140 /* The handling common to all address lines is done in this other
1141 * function. */
1142 r = gnc_customer_addr_common_insert_cb(editable, new_text, new_text_length,
1143 position, user_data, wdata->addr3_quickfill);
1144
1145 /* Did we insert something? Then set up the correct idle handler */
1146 if (r)
1147 {
1148 wdata->addrX_selection_source_id = g_idle_add(idle_select_region_addr3,
1149 user_data);
1150 }
1151}
1152
1153void gnc_customer_addr4_insert_cb(GtkEditable *editable,
1154 gchar *new_text, gint new_text_length,
1155 gint *position, gpointer user_data)
1156{
1157 CustomerWindow *wdata = user_data;
1158 gboolean r;
1159
1160 /* The handling common to all address lines is done in this other
1161 * function. */
1162 r = gnc_customer_addr_common_insert_cb(editable, new_text, new_text_length,
1163 position, user_data, wdata->addr4_quickfill);
1164
1165 /* Did we insert something? Then set up the correct idle handler */
1166 if (r)
1167 {
1168 wdata->addrX_selection_source_id = g_idle_add(idle_select_region_addr4,
1169 user_data);
1170 }
1171}
1172
1173void gnc_customer_shipaddr2_insert_cb(GtkEditable *editable,
1174 gchar *new_text, gint new_text_length,
1175 gint *position, gpointer user_data)
1176{
1177 CustomerWindow *wdata = user_data;
1178 gboolean r;
1179
1180 /* The handling common to all address lines is done in this other
1181 * function. */
1182 r = gnc_customer_addr_common_insert_cb(editable, new_text, new_text_length,
1183 position, user_data, wdata->addr2_quickfill);
1184
1185 /* Did we insert something? Then set up the correct idle handler */
1186 if (r)
1187 {
1188 wdata->addrX_selection_source_id = g_idle_add(idle_select_region_shipaddr2,
1189 user_data);
1190 }
1191}
1192
1193void gnc_customer_shipaddr3_insert_cb(GtkEditable *editable,
1194 gchar *new_text, gint new_text_length,
1195 gint *position, gpointer user_data)
1196{
1197 CustomerWindow *wdata = user_data;
1198 gboolean r;
1199
1200 /* The handling common to all address lines is done in this other
1201 * function. */
1202 r = gnc_customer_addr_common_insert_cb(editable, new_text, new_text_length,
1203 position, user_data, wdata->addr3_quickfill);
1204
1205 /* Did we insert something? Then set up the correct idle handler */
1206 if (r)
1207 {
1208 wdata->addrX_selection_source_id = g_idle_add(idle_select_region_shipaddr3,
1209 user_data);
1210 }
1211}
1212
1213void gnc_customer_shipaddr4_insert_cb(GtkEditable *editable,
1214 gchar *new_text, gint new_text_length,
1215 gint *position, gpointer user_data)
1216{
1217 CustomerWindow *wdata = user_data;
1218 gboolean r;
1219
1220 /* The handling common to all address lines is done in this other
1221 * function. */
1222 r = gnc_customer_addr_common_insert_cb(editable, new_text, new_text_length,
1223 position, user_data, wdata->addr4_quickfill);
1224
1225 /* Did we insert something? Then set up the correct idle handler */
1226 if (r)
1227 {
1228 wdata->addrX_selection_source_id = g_idle_add(idle_select_region_shipaddr4,
1229 user_data);
1230 }
1231}
1232
1233static gboolean
1234gnc_customer_common_key_press_cb( GtkEntry *entry,
1235 GdkEventKey *event,
1236 gpointer user_data, GtkWidget* editable )
1237{
1238 gboolean done_with_input = FALSE;
1239
1240 /* Most "special" keys are allowed to be handled directly by
1241 * the entry's key press handler, but in some cases that doesn't
1242 * seem to work right, so handle them here.
1243 */
1244 switch ( event->keyval )
1245 {
1246 case GDK_KEY_Tab:
1247 case GDK_KEY_ISO_Left_Tab:
1248 if ( !( event->state & GDK_SHIFT_MASK) ) /* Complete on Tab,
1249 * but not Shift-Tab */
1250 {
1251 /* NOT done with input, though, since we need to focus to the next
1252 * field. Unselect the current field, though.
1253 */
1254 gtk_editable_select_region( GTK_EDITABLE(editable),
1255 0, 0 );
1256 }
1257 break;
1258 }
1259
1260 return( done_with_input );
1261}
1262gboolean
1263gnc_customer_addr2_key_press_cb( GtkEntry *entry,
1264 GdkEventKey *event,
1265 gpointer user_data )
1266{
1267 CustomerWindow *wdata = user_data;
1268 return gnc_customer_common_key_press_cb(entry, event, user_data,
1269 wdata->addr2_entry);
1270}
1271gboolean
1272gnc_customer_addr3_key_press_cb( GtkEntry *entry,
1273 GdkEventKey *event,
1274 gpointer user_data )
1275{
1276 CustomerWindow *wdata = user_data;
1277 return gnc_customer_common_key_press_cb(entry, event, user_data,
1278 wdata->addr3_entry);
1279}
1280gboolean
1281gnc_customer_addr4_key_press_cb( GtkEntry *entry,
1282 GdkEventKey *event,
1283 gpointer user_data )
1284{
1285 CustomerWindow *wdata = user_data;
1286 return gnc_customer_common_key_press_cb(entry, event, user_data,
1287 wdata->addr4_entry);
1288}
1289gboolean
1290gnc_customer_shipaddr2_key_press_cb( GtkEntry *entry,
1291 GdkEventKey *event,
1292 gpointer user_data )
1293{
1294 CustomerWindow *wdata = user_data;
1295 return gnc_customer_common_key_press_cb(entry, event, user_data,
1296 wdata->shipaddr2_entry);
1297}
1298gboolean
1299gnc_customer_shipaddr3_key_press_cb( GtkEntry *entry,
1300 GdkEventKey *event,
1301 gpointer user_data )
1302{
1303 CustomerWindow *wdata = user_data;
1304 return gnc_customer_common_key_press_cb(entry, event, user_data,
1305 wdata->shipaddr3_entry);
1306}
1307gboolean
1308gnc_customer_shipaddr4_key_press_cb( GtkEntry *entry,
1309 GdkEventKey *event,
1310 gpointer user_data )
1311{
1312 CustomerWindow *wdata = user_data;
1313 return gnc_customer_common_key_press_cb(entry, event, user_data,
1314 wdata->shipaddr4_entry);
1315}
QuickFill is used to auto-complete typed user entries.
Currency selection widget.
utility functions for the GnuCash UI
an Address object
Core Customer Interface.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
#define gncCustomerGetGUID(x)
const gchar * QofIdType
QofIdType declaration.
Definition qofid.h:80
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
Definition qofevent.cpp:231
void gnc_currency_edit_set_currency(GNCCurrencyEdit *gce, const gnc_commodity *currency)
Set the widget to display a certain currency name.
GtkWidget * gnc_currency_edit_new(void)
Create a new GNCCurrencyEdit widget which can be used to provide an easy way to enter ISO currency co...
gnc_commodity * gnc_currency_edit_get_currency(GNCCurrencyEdit *gce)
Retrieve the displayed currency of the widget.
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
Definition guid.cpp:165
gboolean guid_equal(const GncGUID *guid_1, const GncGUID *guid_2)
Given two GUIDs, return TRUE if they are non-NULL and equal.
Definition guid.cpp:237
GtkWindow * gnc_ui_get_gtk_window(GtkWidget *widget)
Get a pointer to the widget's immediate top level GtkWindow.
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...
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b
void qof_query_add_guid_match(QofQuery *q, QofQueryParamList *param_list, const GncGUID *guid, QofQueryOp op)
DOCUMENT ME !!
QofQuery * qof_query_copy(QofQuery *q)
Make a copy of the indicated query.
void qof_query_set_book(QofQuery *query, QofBook *book)
Set the book to be searched.
void qof_query_destroy(QofQuery *query)
Frees the resources associate with a Query object.
QuickFill * gnc_quickfill_get_string_match(QuickFill *qf, const char *str)
Return a subnode in the tree whose strings all match the string 'str' as the next substring.
Definition QuickFill.c:179
QuickFill * gnc_get_shared_address_addr3_quickfill(QofBook *book, const char *key)
Create/fetch a quickfill GncAddress description strings on the Addr3 part.
const char * gnc_quickfill_string(QuickFill *qf)
For the given node 'qf', return the best-guess matching string.
Definition QuickFill.c:123
QuickFill * gnc_get_shared_address_addr2_quickfill(QofBook *book, const char *key)
Similar to the Account Names account name quickfill, we create a cached quickfill with the address li...
QuickFill * gnc_get_shared_address_addr4_quickfill(QofBook *book, const char *key)
Create/fetch a quickfill GncAddress description strings on the Addr4 part.
GncTaxIncluded
How to interpret the TaxIncluded.
Definition gncTaxTable.h:86
credit, discount and shipaddr are unique to GncCustomer id, name, notes, terms, addr,...
The type used to store guids in C.
Definition guid.h:75
modtime is the internal date of the last modtime See libgnucash/engine/TaxTableBillTermImmutability....
QofBook reference.
Definition qofbook-p.hpp:47
A Query.
Definition qofquery.cpp:75