diff --git a/ChangeLog b/ChangeLog index a124182002..0b5cb67da9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2002-10-18 Benoit Grégoire + + * Implement a working commodity matcher for the generic import + module. + * src/gnome-utils/dialog-commodity.c,.h: Extend the API to allow + the user to be told what he is trying to match, and to fill in + default values for new commodities + * Use the new matcher in the ofx module. The latest libofx CVS + is needed. + 2002-10-17 Derek Atkins * fix bug #96030 -- change "Customer/Vendor Name" to "Company Name" diff --git a/src/app-file/Makefile.am b/src/app-file/Makefile.am index 398b4fdb78..9fb326f3d9 100644 --- a/src/app-file/Makefile.am +++ b/src/app-file/Makefile.am @@ -32,6 +32,7 @@ libgncmod_app_file_la_LIBADD = \ ../engine/libgncmod-engine.la \ ../gnome-utils/libgncmod-gnome-utils.la \ ./gnome/libgnc-app-file-gnome.la \ + ../app-utils/libgncmod-app-utils.la \ ${GUILE_LIBS} \ ${GLIB_LIBS} diff --git a/src/gnome-utils/commodity.glade b/src/gnome-utils/commodity.glade index 5d974708bb..0ac5eee690 100644 --- a/src/gnome-utils/commodity.glade +++ b/src/gnome-utils/commodity.glade @@ -101,6 +101,23 @@ + + GtkLabel + select_user_prompt + + GTK_JUSTIFY_CENTER + False + 0.5 + 0.5 + 0 + 0 + + 0 + False + False + + + GtkHBox hbox62 diff --git a/src/gnome-utils/dialog-commodity.c b/src/gnome-utils/dialog-commodity.c index 1448a0311b..af981940a7 100644 --- a/src/gnome-utils/dialog-commodity.c +++ b/src/gnome-utils/dialog-commodity.c @@ -41,9 +41,14 @@ struct select_commodity_window { GtkWidget * namespace_combo; GtkWidget * commodity_combo; GtkWidget * commodity_entry; - + GtkWidget * select_user_prompt; gnc_commodity_callback callback; void * callback_data; + + char * default_exchange_code; + char * default_fullname; + char * default_mnemonic; + int default_fraction; }; struct commodity_window { @@ -92,28 +97,83 @@ gnc_ui_commodity_set_help_callback (gnc_commodity_help_callback cb) help_callback = cb; } + /******************************************************************** - * gnc_ui_select_commodity_modal() + * gnc_ui_select_commodity_modal_full() ********************************************************************/ - -gnc_commodity * -gnc_ui_select_commodity_modal(gnc_commodity * orig_sel, - GtkWidget * parent) { +gnc_commodity * +gnc_ui_select_commodity_modal_full(gnc_commodity * orig_sel, + GtkWidget * parent, + char * user_message, + char * exchange_code, + char * fullname, + char * mnemonic, + int fraction) +{ gnc_commodity * retval = NULL; - +#define PROMPT_SIZE 2048 + gchar user_prompt_text[PROMPT_SIZE] = ""; + SelectCommodityWindow * win = gnc_ui_select_commodity_create(orig_sel, &select_modal_callback, &retval); + win->default_exchange_code=exchange_code; + win->default_fullname=fullname; + win->default_mnemonic=mnemonic; + + if(user_message!=NULL) + { + strncat(user_prompt_text,user_message,PROMPT_SIZE-strlen(user_prompt_text)); + } + else if( exchange_code!=NULL || fullname!=NULL || mnemonic!=NULL) + { + strncat(user_prompt_text,_("\nPlease select a commodity to match:"),PROMPT_SIZE-strlen(user_prompt_text)); + } + if(fullname!=NULL) + { + strncat(user_prompt_text,_("\nCommodity: "),PROMPT_SIZE-strlen(user_prompt_text)); + strncat(user_prompt_text,fullname,PROMPT_SIZE-strlen(user_prompt_text)); + } + if(exchange_code!=NULL) + { + strncat(user_prompt_text,_("\nExchange code (CUSIP or similar): "),PROMPT_SIZE-strlen(user_prompt_text)); + strncat(user_prompt_text,exchange_code,PROMPT_SIZE-strlen(user_prompt_text)); + } + if(mnemonic!=NULL) + { + strncat(user_prompt_text,_("\nMnemonic(Ticker symbol or similar): "),PROMPT_SIZE-strlen(user_prompt_text)); + strncat(user_prompt_text,mnemonic,PROMPT_SIZE-strlen(user_prompt_text)); + } + + gtk_label_set_text ((GtkLabel *)(win->select_user_prompt), + user_prompt_text); + if(parent) { gnome_dialog_set_parent(GNOME_DIALOG(win->dialog), GTK_WINDOW(parent)); } gtk_window_set_modal(GTK_WINDOW(win->dialog), TRUE); gtk_widget_show (win->dialog); gtk_main(); - + return retval; } +/******************************************************************** + * gnc_ui_select_commodity_modal() + ********************************************************************/ + +gnc_commodity * +gnc_ui_select_commodity_modal(gnc_commodity * orig_sel, + GtkWidget * parent) { + return gnc_ui_select_commodity_modal_full(orig_sel, + parent, + NULL, + NULL, + NULL, + NULL, + 0); +} + static gint select_commodity_close (GnomeDialog *dialog, gpointer data) @@ -161,6 +221,7 @@ gnc_ui_select_commodity_create(const gnc_commodity * orig_sel, retval->namespace_combo = glade_xml_get_widget (xml, "namespace_combo"); retval->commodity_combo = glade_xml_get_widget (xml, "commodity_combo"); retval->commodity_entry = glade_xml_get_widget (xml, "commodity_entry"); + retval->select_user_prompt = glade_xml_get_widget (xml, "select_user_prompt"); retval->callback = callback; retval->callback_data = callback_data; @@ -168,6 +229,9 @@ gnc_ui_select_commodity_create(const gnc_commodity * orig_sel, gtk_signal_connect (GTK_OBJECT(retval->dialog), "close", GTK_SIGNAL_FUNC(select_commodity_close), retval); + gtk_label_set_text ((GtkLabel *)retval->select_user_prompt, + ""); + /* build the menus of namespaces and commodities */ namespace = gnc_ui_update_namespace_picker(retval->namespace_combo, @@ -286,11 +350,15 @@ gnc_ui_select_commodity_new_cb(GtkButton * button, const char * namespace = gnc_ui_namespace_picker_ns (w->namespace_combo); const gnc_commodity * new_commodity = - gnc_ui_new_commodity_modal(namespace, w->dialog); - + gnc_ui_new_commodity_modal_full(namespace, + w->dialog, + w->default_exchange_code, + w->default_fullname, + w->default_mnemonic, + w->default_fraction); if(new_commodity) { char *namespace; - + namespace = gnc_ui_update_namespace_picker(w->namespace_combo, gnc_commodity_get_namespace @@ -553,27 +621,69 @@ new_modal_callback(const gnc_commodity * arg, void * data) { } /******************************************************************** - * gnc_ui_new_commodity_modal() + * gnc_ui_new_commodity_modal_full() ********************************************************************/ -gnc_commodity * -gnc_ui_new_commodity_modal(const char * selected_namespace, - GtkWidget * parent) { +gnc_commodity * +gnc_ui_new_commodity_modal_full(const char * default_namespace, + GtkWidget * parent, + char * exchange_code, + char * fullname, + char * mnemonic, + int fraction) { gnc_commodity * retval = NULL; - + CommodityWindow * win = - gnc_ui_new_commodity_create(selected_namespace, &new_modal_callback, + gnc_ui_new_commodity_create(default_namespace, &new_modal_callback, &retval); + if(fullname!=NULL) + { + gtk_entry_set_text((GtkEntry *)(win->fullname_entry), + fullname); + } + if(mnemonic!=NULL) + { + gtk_entry_set_text((GtkEntry *)(win->mnemonic_entry), + mnemonic); + } + if(exchange_code!=NULL) + { + gtk_entry_set_text((GtkEntry *)(win->code_entry), + exchange_code); + } + if(fraction>0) + { + gtk_spin_button_set_value (GTK_SPIN_BUTTON(win->fraction_spinbutton), + fraction); + } + /*(GtkWidget *)(win->namespace_combo);*/ + + if(parent) { gnome_dialog_set_parent(GNOME_DIALOG(win->dialog), GTK_WINDOW(parent)); } gtk_window_set_modal(GTK_WINDOW(win->dialog), TRUE); gtk_widget_show (win->dialog); gtk_main(); - + return retval; } +/******************************************************************** + * gnc_ui_new_commodity_modal() + ********************************************************************/ + +gnc_commodity * +gnc_ui_new_commodity_modal(const char * default_namespace, + GtkWidget * parent) { + return gnc_ui_new_commodity_modal_full(default_namespace, + parent, + NULL, + NULL, + NULL, + 0); +} + /******************************************************************** * gnc_ui_edit_commodity_modal() ********************************************************************/ diff --git a/src/gnome-utils/dialog-commodity.h b/src/gnome-utils/dialog-commodity.h index fe3533d743..f840680431 100644 --- a/src/gnome-utils/dialog-commodity.h +++ b/src/gnome-utils/dialog-commodity.h @@ -41,13 +41,37 @@ void gnc_ui_select_commodity_destroy(SelectCommodityWindow * w); void gnc_ui_commodity_destroy(CommodityWindow * w); +/*Offer the user to select a commodity matching exchange_code, + fullname and mnemonic. If the user decides to create a new one, those + values are used as default. If fullname is NULL, the user won't be + told he has to match anything in perticular.*/ + +gnc_commodity * +gnc_ui_select_commodity_modal_full(gnc_commodity * orig_sel, + GtkWidget * parent, + char * user_message, + char * exchange_code, + char * fullname, + char * mnemonic, + int fraction); + gnc_commodity * gnc_ui_select_commodity_modal(gnc_commodity * orig_sel, GtkWidget * parent); + +gnc_commodity * +gnc_ui_new_commodity_modal_full(const char * default_namespace, + GtkWidget * parent, + char * exchange_code, + char * fullname, + char * mnemonic, + int fraction); + gnc_commodity * gnc_ui_new_commodity_modal(const char * default_namespace, - GtkWidget * parent); + GtkWidget * parent + ); gboolean gnc_ui_edit_commodity_modal(gnc_commodity *commodity, diff --git a/src/import-export/Account-matcher.c b/src/import-export/Account-matcher.c index a5eddd6e19..82460a3ca6 100644 --- a/src/import-export/Account-matcher.c +++ b/src/import-export/Account-matcher.c @@ -36,7 +36,6 @@ #include #include "gnc-generic-import.h" #include "Account.h" -#include "dialog-commodity.h" #include "dialog-utils.h" #include "AccWindow.h" diff --git a/src/import-export/Makefile.am b/src/import-export/Makefile.am index dcbe254486..31b134534e 100644 --- a/src/import-export/Makefile.am +++ b/src/import-export/Makefile.am @@ -4,6 +4,7 @@ pkglib_LTLIBRARIES=libgncmod-generic-import.la libgncmod_generic_import_la_SOURCES = \ Account-matcher.c \ + Commodity-matcher.c \ Transaction-matcher.c \ Utilities.c \ gncmod-generic-import.c diff --git a/src/import-export/Transaction-matcher.c b/src/import-export/Transaction-matcher.c index 1d803f843c..ea21b37765 100644 --- a/src/import-export/Transaction-matcher.c +++ b/src/import-export/Transaction-matcher.c @@ -38,7 +38,6 @@ #include "gnc-generic-import.h" #include "Account.h" #include "Transaction.h" -#include "dialog-commodity.h" #include "dialog-utils.h" #include "gnc-engine-util.h" diff --git a/src/import-export/gnc-generic-import.h b/src/import-export/gnc-generic-import.h index fc140626f1..e7f2a809f4 100644 --- a/src/import-export/gnc-generic-import.h +++ b/src/import-export/gnc-generic-import.h @@ -74,6 +74,46 @@ Account * gnc_import_select_account(char * account_online_id_value, gnc_commodity * new_account_default_commodity, GNCAccountType new_account_default_type); +/* The gnc_import_select_commodity(): + + Must be called with a string containing a unique identifier for the + commodity. If an commodity with a matching exchange_code is + found, the function immediately returns with a pointer to that + commodity. Otherwise, the user may be prompted to select a GnuCash + account or create a new one (in both cases, the exchange_code is written + written to the commodity's exchange_code field, overwriting anything that + was there before. + + Params: + + char * exchange_code: The string containing the code for which you + want a matching commodity. A CUISP code or similar UNIQUE code. + The stock ticker is NOT appropriate, unless you have no other option. + + char auto_create: If 0, if the exchange_code value in unknown, + the function returns NULL, otherwise, the user will be asked to + create a new account. + + char * default_fullname: A human-readable description of the commodity, such + as the stock name. Can be NULL. If it is not NULL, it will be shown + to the user when selecting a commodity. It will also be used as + the default if a new commodity is created. + + char * default_mnemonic: Usually the stock ticker or similar. Can be NULL. + If it is not NULL, it will be shown + to the user when selecting a commodity. It will also be used as + the default if a new commodity is created. + + + Return: A pointer to the found or created commodity, or NULL if no + account was found or created. + +*/ +gnc_commodity * gnc_import_select_commodity(char * exchange_code, + char auto_create, + char * default_fullname, + char * default_mnemonic); + /* Your import module should create a new transaction in the current book, add as many splits as it knows about, and associate each split with an account. It should then call gnc_import_add_trans() with that transaction diff --git a/src/import-export/ofx/gnc-ofx-import.c b/src/import-export/ofx/gnc-ofx-import.c index a71a34ae6a..060010a234 100644 --- a/src/import-export/ofx/gnc-ofx-import.c +++ b/src/import-export/ofx/gnc-ofx-import.c @@ -33,7 +33,7 @@ #include #include -#include "libofx.h" +#include "libofx/libofx.h" #include "gnc-generic-import.h" #include "Account.h" #include "Transaction.h" @@ -94,17 +94,38 @@ selected_filename = gnc_file_dialog("Select an OFX/QFX file to process", } -int ofx_proc_status(struct OfxStatusData data) +int ofx_proc_status_cb(struct OfxStatusData data) { return 0; } -int ofx_proc_security(const struct OfxSecurityData data) +int ofx_proc_security_cb(const struct OfxSecurityData data) { -return 0; + char * tmp_exchange_code=NULL; + char * tmp_default_fullname=NULL; + char * tmp_default_mnemonic=NULL; + + if(data.unique_id_valid==true) + { + tmp_exchange_code=(char *)data.unique_id; + } + if(data.secname_valid==true) + { + tmp_default_fullname=(char *)data.secname; + } + if(data.ticker_valid==true) + { + tmp_default_mnemonic=(char *)data.ticker; + } + + gnc_import_select_commodity(tmp_exchange_code, + true, + tmp_default_fullname, + tmp_default_mnemonic); + return 0; } -int ofx_proc_transaction(struct OfxTransactionData data) +int ofx_proc_transaction_cb(struct OfxTransactionData data) { char dest_string[255]; time_t current_time; @@ -277,12 +298,12 @@ int ofx_proc_transaction(struct OfxTransactionData data) return 0; }//end ofx_proc_transaction() -int ofx_proc_statement(struct OfxStatementData data) +int ofx_proc_statement_cb(struct OfxStatementData data) { return 0; }//end ofx_proc_statement() -int ofx_proc_account(struct OfxAccountData data) +int ofx_proc_account_cb(struct OfxAccountData data) { Account *selected_account; gnc_commodity_table * commodity_table;