00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "config.h"
00027
00028 #include <gtk/gtk.h>
00029 #include <glib/gi18n.h>
00030
00031 #include "Account.h"
00032 #include "gnc-ui-util.h"
00033 #include "qof.h"
00034 #include "gnc-component-manager.h"
00035 #include "gnc-gtk-utils.h"
00036
00037 #include "gncCustomer.h"
00038 #include "gncJob.h"
00039 #include "gncVendor.h"
00040 #include "gncOwner.h"
00041 #include "gncInvoice.h"
00042
00043 #include "gnc-general-search.h"
00044 #include "qof.h"
00045 #include "business-gnome-utils.h"
00046 #include "dialog-customer.h"
00047 #include "dialog-job.h"
00048 #include "dialog-vendor.h"
00049 #include "dialog-employee.h"
00050 #include "dialog-invoice.h"
00051
00052 #include "gnc-commodity.h"
00053
00054 typedef enum
00055 {
00056 GNCSEARCH_TYPE_SELECT,
00057 GNCSEARCH_TYPE_EDIT
00058 } GNCSearchType;
00059
00060 static GtkWidget * gnc_owner_new (GtkWidget *label, GtkWidget *hbox,
00061 QofBook *book, GncOwner *owner,
00062 GNCSearchType type)
00063 {
00064 GtkWidget *edit;
00065 GNCSearchCB search_cb = NULL;
00066 const char *type_name = NULL;
00067 const char *text = NULL;
00068 gboolean text_editable = FALSE;
00069
00070 switch (type)
00071 {
00072 case GNCSEARCH_TYPE_SELECT:
00073 text = _("Select...");
00074 text_editable = TRUE;
00075 break;
00076 case GNCSEARCH_TYPE_EDIT:
00077 text = _("Edit...");
00078 text_editable = FALSE;
00079 };
00080
00081 switch (owner->type)
00082 {
00083 case GNC_OWNER_NONE:
00084 case GNC_OWNER_UNDEFINED:
00085 return NULL;
00086
00087 case GNC_OWNER_CUSTOMER:
00088 if (type == GNCSEARCH_TYPE_SELECT)
00089 search_cb = gnc_customer_search_select;
00090 else
00091 search_cb = gnc_customer_search_edit;
00092 type_name = GNC_CUSTOMER_MODULE_NAME;
00093 break;
00094
00095 case GNC_OWNER_JOB:
00096 if (type == GNCSEARCH_TYPE_SELECT)
00097 search_cb = gnc_job_search_select;
00098 else
00099 search_cb = gnc_job_search_edit;
00100 type_name = GNC_JOB_MODULE_NAME;
00101 break;
00102
00103 case GNC_OWNER_VENDOR:
00104 if (type == GNCSEARCH_TYPE_SELECT)
00105 search_cb = gnc_vendor_search_select;
00106 else
00107 search_cb = gnc_vendor_search_edit;
00108 type_name = GNC_VENDOR_MODULE_NAME;
00109 break;
00110
00111 case GNC_OWNER_EMPLOYEE:
00112 if (type == GNCSEARCH_TYPE_SELECT)
00113 search_cb = gnc_employee_search_select;
00114 else
00115 search_cb = gnc_employee_search_edit;
00116 type_name = GNC_EMPLOYEE_MODULE_NAME;
00117 break;
00118
00119 default:
00120 g_warning ("Unknown type");
00121 return NULL;
00122 }
00123
00124 edit = gnc_general_search_new (type_name, text, text_editable, search_cb, book, book);
00125 if (!edit)
00126 return NULL;
00127
00128 gnc_general_search_set_selected (GNC_GENERAL_SEARCH (edit),
00129 owner->owner.undefined);
00130 gtk_box_pack_start (GTK_BOX (hbox), edit, FALSE, FALSE, 0);
00131 if (label)
00132 gtk_label_set_text (GTK_LABEL (label), _(qof_object_get_type_label (type_name)));
00133
00134 return edit;
00135 }
00136
00137 GtkWidget * gnc_owner_select_create (GtkWidget *label, GtkWidget *hbox,
00138 QofBook *book, GncOwner *owner)
00139 {
00140 g_return_val_if_fail (hbox != NULL, NULL);
00141 g_return_val_if_fail (book != NULL, NULL);
00142 g_return_val_if_fail (owner != NULL, NULL);
00143
00144 return gnc_owner_new (label, hbox, book, owner, GNCSEARCH_TYPE_SELECT);
00145 }
00146
00147 GtkWidget * gnc_owner_edit_create (GtkWidget *label, GtkWidget *hbox,
00148 QofBook *book, GncOwner *owner)
00149 {
00150 g_return_val_if_fail (hbox != NULL, NULL);
00151 g_return_val_if_fail (book != NULL, NULL);
00152 g_return_val_if_fail (owner != NULL, NULL);
00153
00154 return gnc_owner_new (label, hbox, book, owner, GNCSEARCH_TYPE_EDIT);
00155 }
00156
00157 void gnc_owner_get_owner (GtkWidget *widget, GncOwner *owner)
00158 {
00159 g_return_if_fail (widget != NULL);
00160 g_return_if_fail (owner != NULL);
00161
00162
00163
00164
00165 owner->owner.undefined =
00166 gnc_general_search_get_selected (GNC_GENERAL_SEARCH (widget));
00167 }
00168
00169 void gnc_owner_set_owner (GtkWidget *widget, GncOwner *owner)
00170 {
00171 g_return_if_fail (widget != NULL);
00172 g_return_if_fail (owner != NULL);
00173
00174
00175
00176
00177
00178 gnc_general_search_set_selected (GNC_GENERAL_SEARCH (widget),
00179 owner->owner.undefined);
00180 }
00181
00182 typedef struct _invoice_select_info
00183 {
00184 GtkWidget *label;
00185 QofBook *book;
00186 GncOwner owner;
00187 gboolean have_owner;
00188 } GncISI;
00189
00190 static GNCSearchWindow *
00191 gnc_invoice_select_search_cb (gpointer start, gpointer isip)
00192 {
00193 GncISI *isi = isip;
00194
00195 if (!isi) return NULL;
00196 g_assert(isi->book);
00197
00198 return gnc_invoice_search (start,
00199 isi->have_owner ? &isi->owner : NULL,
00200 isi->book);
00201 }
00202
00203 static void
00204 gnc_invoice_select_search_set_label(GncISI* isi)
00205 {
00206 GncOwnerType owner_type;
00207 GncOwner *tmp;
00208 char *label;
00209
00210 g_assert(isi);
00211 if (!isi->label) return;
00212
00213 tmp = &isi->owner;
00214 owner_type = gncOwnerGetType(tmp);
00215 while (owner_type == GNC_OWNER_JOB)
00216 {
00217 tmp = gncOwnerGetEndOwner(tmp);
00218 owner_type = gncOwnerGetType(tmp);
00219 }
00220
00221
00222 switch (owner_type)
00223 {
00224 case GNC_OWNER_VENDOR:
00225 label = _("Bill");
00226 break;
00227 case GNC_OWNER_EMPLOYEE:
00228 label = _("Voucher");
00229 break;
00230 default:
00231 label = _("Invoice");
00232 }
00233
00234 gtk_label_set_text(GTK_LABEL(isi->label), label);
00235 }
00236
00237 GtkWidget * gnc_invoice_select_create (GtkWidget *hbox, QofBook *book,
00238 const GncOwner *owner,
00239 GncInvoice *invoice,
00240 GtkWidget *label)
00241 {
00242 GtkWidget *edit;
00243 GncISI *isi;
00244
00245 g_return_val_if_fail (hbox != NULL, NULL);
00246 g_return_val_if_fail (book != NULL, NULL);
00247
00248
00249 isi = g_new0(GncISI, 1);
00250 if (!isi)
00251 return NULL;
00252
00253 if (owner)
00254 {
00255 gncOwnerCopy(owner, &isi->owner);
00256 isi->have_owner = TRUE;
00257 }
00258 else
00259 {
00260 gncOwnerInitCustomer(&isi->owner, NULL);
00261 }
00262 isi->book = book;
00263 isi->label = label;
00264
00265 edit = gnc_general_search_new (GNC_INVOICE_MODULE_NAME, _("Select..."),
00266 TRUE, gnc_invoice_select_search_cb, isi, isi->book);
00267 if (!edit)
00268 {
00269 g_free(isi);
00270 return NULL;
00271 }
00272
00273 gnc_general_search_set_selected (GNC_GENERAL_SEARCH (edit), invoice);
00274 gtk_box_pack_start (GTK_BOX (hbox), edit, FALSE, FALSE, 0);
00275 g_object_set_data_full(G_OBJECT(edit), "isi-state", isi, g_free);
00276
00277
00278 gnc_invoice_select_search_set_label(isi);
00279
00280 return edit;
00281 }
00282
00283 GncInvoice * gnc_invoice_get_invoice (GtkWidget *widget)
00284 {
00285 g_return_val_if_fail (widget != NULL, NULL);
00286
00287 return gnc_general_search_get_selected (GNC_GENERAL_SEARCH (widget));
00288 }
00289
00290 void gnc_invoice_set_invoice (GtkWidget *widget, GncInvoice *invoice)
00291 {
00292 g_return_if_fail (widget != NULL);
00293 g_return_if_fail (invoice != NULL);
00294
00295 gnc_general_search_set_selected (GNC_GENERAL_SEARCH (widget), invoice);
00296 }
00297
00298 void gnc_invoice_set_owner (GtkWidget *widget, GncOwner *owner)
00299 {
00300 GncISI *isi;
00301
00302 g_return_if_fail (widget != NULL);
00303 g_return_if_fail (owner != NULL);
00304
00305 isi = g_object_get_data(G_OBJECT(widget), "isi-state");
00306 g_assert(isi);
00307
00308 if (isi->owner.owner.undefined == owner->owner.undefined)
00309 return;
00310
00311 gncOwnerCopy(owner, &isi->owner);
00312 isi->have_owner = TRUE;
00313 gnc_general_search_set_selected(GNC_GENERAL_SEARCH(widget), NULL);
00314
00315
00316 gnc_invoice_select_search_set_label(isi);
00317 }
00318
00319 void
00320 gnc_fill_account_select_combo (GtkWidget *combo, QofBook *book,
00321 GList *acct_types, GList *acct_commodities)
00322 {
00323 GtkListStore *store;
00324 GtkEntry *entry;
00325 GList *list, *node;
00326 char *text;
00327
00328 g_return_if_fail (combo && GTK_IS_COMBO_BOX_ENTRY(combo));
00329 g_return_if_fail (book);
00330 g_return_if_fail (acct_types);
00331
00332
00333 text = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
00334
00335 list = gnc_account_get_descendants (gnc_book_get_root_account (book));
00336
00337
00338 entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(combo)));
00339 gtk_entry_set_text(entry, "");
00340 store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo)));
00341 gtk_list_store_clear(store);
00342
00343
00344 for (node = list; node; node = node->next)
00345 {
00346 Account *account = node->data;
00347 char *name;
00348
00349
00350 if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account))
00351 == -1)
00352 continue;
00353
00354
00355
00356 if (acct_commodities)
00357 {
00358 if ( g_list_find_custom( acct_commodities,
00359 GINT_TO_POINTER(xaccAccountGetCommodity(account)),
00360 gnc_commodity_compare_void) == NULL )
00361 {
00362 continue;
00363 }
00364 }
00365
00366 name = gnc_account_get_full_name (account);
00367 gtk_combo_box_append_text(GTK_COMBO_BOX(combo), name);
00368 g_free(name);
00369 }
00370 gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
00371
00372 g_list_free (list);
00373
00374 gnc_cbe_set_by_string(GTK_COMBO_BOX_ENTRY(combo), text);
00375
00376 if (text)
00377 g_free (text);
00378 }
00379
00380 GList *
00381 gnc_business_account_types (GncOwner *owner)
00382 {
00383 g_return_val_if_fail (owner, NULL);
00384
00385 switch (gncOwnerGetType (owner))
00386 {
00387 case GNC_OWNER_CUSTOMER:
00388 return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_RECEIVABLE));
00389 case GNC_OWNER_VENDOR:
00390 case GNC_OWNER_EMPLOYEE:
00391 return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_PAYABLE));
00392 break;
00393 default:
00394 return (g_list_prepend (NULL, (gpointer)ACCT_TYPE_NONE));
00395 }
00396 }
00397
00398 GList *
00399 gnc_business_commodities (GncOwner *owner)
00400 {
00401 g_return_val_if_fail (owner, NULL);
00402 g_return_val_if_fail (gncOwnerGetCurrency(owner), NULL);
00403
00404 return (g_list_prepend (NULL, gncOwnerGetCurrency(owner)));
00405 }
00406
00407
00408
00409
00410 typedef const char * (*GenericLookup_t)(gpointer);
00411
00412 typedef struct
00413 {
00414 gint component_id;
00415 GtkWidget * omenu;
00416 QofBook * book;
00417 gboolean none_ok;
00418 const char * (*get_name)(gpointer);
00419 GList * (*get_list)(QofBook*);
00420
00421 gboolean building_menu;
00422 gpointer result;
00423 gpointer * result_p;
00424
00425 void (*changed_cb)(GtkWidget*, gpointer);
00426 gpointer cb_arg;
00427 } OpMenuData;
00428
00429 #define DO_ADD_ITEM(s,o) { \
00430 add_menu_item (menu, (s), omd, (o)); \
00431 if (omd->result == (o)) current = index; \
00432 index++; \
00433 }
00434
00435 static void
00436 business_option_changed (GtkWidget *widget, gpointer data)
00437 {
00438 OpMenuData *omd = data;
00439
00440 g_return_if_fail (omd);
00441 omd->result = g_object_get_data (G_OBJECT (widget), "this_item");
00442
00443 if (!omd->building_menu)
00444 {
00445 if (omd->result_p)
00446 *(omd->result_p) = omd->result;
00447
00448 if (omd->changed_cb)
00449 (omd->changed_cb)(omd->omenu, omd->cb_arg);
00450 }
00451 }
00452
00453 static void
00454 add_menu_item (GtkWidget *menu, const char *label, OpMenuData *omd,
00455 gpointer this_item)
00456 {
00457 GtkWidget *item = gtk_menu_item_new_with_label (label);
00458 g_object_set_data (G_OBJECT (item), "this_item", this_item);
00459 g_signal_connect (G_OBJECT (item), "activate",
00460 G_CALLBACK (business_option_changed), omd);
00461 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
00462 gtk_widget_show (item);
00463 }
00464
00465 static void
00466 generic_omenu_destroy_cb (GtkWidget *widget, gpointer data)
00467 {
00468 OpMenuData *omd = data;
00469
00470 gnc_unregister_gui_component (omd->component_id);
00471 g_free (omd);
00472 }
00473
00474 static void
00475 build_generic_optionmenu (OpMenuData *omd)
00476 {
00477 GList *items;
00478 GtkWidget *menu;
00479 int current = 0, index = 0;
00480
00481
00482 if (omd->get_list == NULL)
00483 return;
00484
00485
00486 items = (omd->get_list)(omd->book);
00487
00488
00489 menu = gtk_menu_new ();
00490
00491 omd->building_menu = TRUE;
00492
00493 if (omd->none_ok || items == NULL)
00494 DO_ADD_ITEM (_("None"), NULL);
00495
00496 for ( ; items; items = items->next)
00497 DO_ADD_ITEM ((omd->get_name)(items->data), items->data);
00498
00499 gtk_option_menu_set_menu (GTK_OPTION_MENU (omd->omenu), menu);
00500 gtk_option_menu_set_history (GTK_OPTION_MENU (omd->omenu), current);
00501 gtk_widget_show (menu);
00502
00503 omd->building_menu = FALSE;
00504 }
00505
00506 static void
00507 generic_omenu_refresh_handler (GHashTable *changes, gpointer user_data)
00508 {
00509 OpMenuData *omd = user_data;
00510 build_generic_optionmenu (omd);
00511 }
00512
00513 static OpMenuData *
00514 make_generic_optionmenu (GtkWidget *omenu, QofBook *book,
00515 gboolean none_ok, QofIdType type_name,
00516 GList * (*get_list)(QofBook*),
00517 GenericLookup_t get_name,
00518 gpointer *result)
00519 {
00520 OpMenuData *omd;
00521
00522 omd = g_object_get_data (G_OBJECT (omenu), "menu-data");
00523
00524
00525
00526
00527
00528
00529 if (!omd)
00530 {
00531 omd = g_new0 (OpMenuData, 1);
00532 omd->omenu = omenu;
00533 omd->book = book;
00534 omd->result_p = result;
00535 omd->none_ok = none_ok;
00536 omd->get_name = get_name;
00537 omd->get_list = get_list;
00538 g_object_set_data (G_OBJECT (omenu), "menu-data", omd);
00539
00540 if (result)
00541 omd->result = *result;
00542
00543 omd->component_id =
00544 gnc_register_gui_component ("generic-omenu-refresh-hook",
00545 generic_omenu_refresh_handler,
00546 NULL, omd);
00547
00548
00549 if (type_name)
00550 gnc_gui_component_watch_entity_type (omd->component_id,
00551 type_name,
00552 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
00553
00554 g_signal_connect (G_OBJECT (omenu), "destroy",
00555 G_CALLBACK (generic_omenu_destroy_cb), omd);
00556
00557 }
00558
00559 build_generic_optionmenu (omd);
00560
00561 return omd;
00562 }
00563
00564 void
00565 gnc_ui_optionmenu_set_changed_callback (GtkWidget *omenu,
00566 void (*changed_cb)(GtkWidget*, gpointer),
00567 gpointer cb_arg)
00568 {
00569 OpMenuData *omd;
00570
00571 if (!omenu) return;
00572
00573 omd = g_object_get_data (G_OBJECT (omenu), "menu-data");
00574 g_return_if_fail (omd);
00575
00576 omd->changed_cb = changed_cb;
00577 omd->cb_arg = cb_arg;
00578 }
00579
00580 gpointer
00581 gnc_ui_optionmenu_get_value (GtkWidget *omenu)
00582 {
00583 OpMenuData *omd;
00584
00585 if (!omenu) return NULL;
00586
00587 omd = g_object_get_data (G_OBJECT (omenu), "menu-data");
00588 g_return_val_if_fail (omd, NULL);
00589
00590 return omd->result;
00591 }
00592
00593 void
00594 gnc_ui_optionmenu_set_value (GtkWidget *omenu, gpointer data)
00595 {
00596 OpMenuData *omd;
00597 GtkWidget *menu;
00598 GList *node;
00599 gint counter;
00600
00601 if (!omenu) return;
00602
00603 omd = g_object_get_data (G_OBJECT (omenu), "menu-data");
00604 g_return_if_fail (omd);
00605
00606 menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (omenu));
00607 g_return_if_fail (menu);
00608
00609
00610 for (counter = 0, node = ((GTK_MENU_SHELL (menu))->children);
00611 node;
00612 node = node->next, counter++)
00613 {
00614 GObject *menuitem = node->data;
00615 gpointer this_object = g_object_get_data (menuitem, "this_item");
00616
00617 if (this_object == data)
00618 {
00619 gtk_option_menu_set_history (GTK_OPTION_MENU (omd->omenu), counter);
00620 return;
00621 }
00622 }
00623 }
00624
00625
00626
00627
00628
00629
00630
00631
00632 void
00633 gnc_ui_billterms_optionmenu (GtkWidget *omenu, QofBook *book,
00634 gboolean none_ok, GncBillTerm **choice)
00635 {
00636 if (!omenu || !book) return;
00637
00638 make_generic_optionmenu (omenu, book, none_ok, GNC_BILLTERM_MODULE_NAME,
00639 gncBillTermGetTerms,
00640 (GenericLookup_t)gncBillTermGetName,
00641 (gpointer *)choice);
00642 }
00643
00644 void
00645 gnc_ui_taxtables_optionmenu (GtkWidget *omenu, QofBook *book,
00646 gboolean none_ok, GncTaxTable **choice)
00647 {
00648 if (!omenu || !book) return;
00649
00650 make_generic_optionmenu (omenu, book, none_ok, GNC_TAXTABLE_MODULE_NAME,
00651 gncTaxTableGetTables,
00652 (GenericLookup_t)gncTaxTableGetName,
00653 (gpointer *)choice);
00654 }
00655
00656 void
00657 gnc_ui_taxincluded_optionmenu (GtkWidget *omenu, GncTaxIncluded *choice)
00658 {
00659 GtkWidget *menu;
00660 OpMenuData *omd;
00661 int current = 0, index = 0;
00662
00663 if (!omenu) return;
00664
00665 omd = make_generic_optionmenu (omenu, NULL, FALSE, NULL, NULL, NULL,
00666 (gpointer *)choice);
00667
00668 g_return_if_fail (omd);
00669
00670 menu = gtk_menu_new ();
00671
00672 add_menu_item (menu, _("Yes"), omd,
00673 GINT_TO_POINTER (GNC_TAXINCLUDED_YES));
00674 if (*choice == GNC_TAXINCLUDED_YES) current = index;
00675 index++;
00676
00677 add_menu_item (menu, _("No"), omd,
00678 GINT_TO_POINTER (GNC_TAXINCLUDED_NO));
00679 if (*choice == GNC_TAXINCLUDED_NO) current = index;
00680 index++;
00681
00682 add_menu_item (menu, _("Use Global"), omd,
00683 GINT_TO_POINTER (GNC_TAXINCLUDED_USEGLOBAL));
00684 if (*choice == GNC_TAXINCLUDED_USEGLOBAL) current = index;
00685 index++;
00686
00687 gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), menu);
00688 gtk_option_menu_set_history (GTK_OPTION_MENU (omenu), current);
00689 gtk_widget_show (menu);
00690 }