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