29 #include <glib/gi18n.h>
36 #include <qofinstance-p.h>
39 #include "gnc-locale-utils.h"
89 const char * default_symbol;
92 #define GET_PRIVATE(o) \
93 (G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_COMMODITY, CommodityPrivate))
101 static void gnc_commodity_set_default_symbol(
gnc_commodity *,
const char *);
109 GHashTable * cm_table;
120 GHashTable * ns_table;
126 const char *old_code;
127 const char *new_code;
128 } gnc_new_iso_codes[] =
143 #define GNC_NEW_ISO_CODES \
144 (sizeof(gnc_new_iso_codes) / sizeof(struct gnc_new_iso_code))
146 static gboolean fq_is_installed = FALSE;
154 char *old_internal_name;
159 { TRUE, 0, 0,
"Currency",
"CURRENCY",
"currency" };
163 { FALSE, 0, 0,
"Amsterdam Euronext eXchange, NL",
"AEX",
"aex" },
164 { FALSE, 0, 0,
"AEX Futures (now in AEX)",
"AEX_FUTURES",
"aex_futures" },
165 { FALSE, 0, 0,
"AEX Options (now in AEX)",
"AEX_OPTIONS",
"aex_options" },
166 { FALSE, 0, 0,
"American International Assurance, HK",
"AIAHK",
"aiahk" },
167 { FALSE, 0, 0,
"Association of Mutual Funds in India",
"AMFIINDIA",
"amfiindia" },
168 { FALSE, 0, 0,
"Athens Stock Exchange, GR",
"ASEGR",
"asegr" },
169 { FALSE, 0, 0,
"Australian Stock Exchange, AU",
"ASX",
"asx" },
170 { FALSE, 0, 0,
"BMO NesbittBurns, CA",
"BMONESBITTBURNS",
"bmonesbittburns" },
171 { FALSE, 0, 0,
"BUX/Magyar Tökepiac, HU",
"BUX",
"bux" },
172 { FALSE, 0, 0,
"Cominvest, ex-Adig, DE",
"COMINVEST",
"cominvest" },
173 { FALSE, 0, 0,
"Deka Investments, DE",
"DEKA",
"deka" },
174 { FALSE, 0, 0,
"DWS, DE",
"DWS",
"dwsfunds" },
175 { FALSE, 0, 0,
"Fidelity Direct",
"FIDELITY_DIRECT",
"fidelity_direct" },
176 { FALSE, 0, 0,
"Finance Canada",
"FINANCECANADA",
"financecanada" },
177 { FALSE, 0, 0,
"Finanzpartner, DE",
"FINANZPARTNER",
"finanzpartner" },
178 { FALSE, 0, 0,
"First Trust Portfolios, US",
"FTPORTFOLIOS_DIRECT",
"ftportfolios_direct" },
179 { FALSE, 0, 0,
"Fund Library, CA",
"FUNDLIBRARY",
"fundlibrary" },
180 { FALSE, 0, 0,
"GoldMoney spot rates, JE",
"GOLDMONEY",
"goldmoney" },
181 { FALSE, 0, 0,
"HElsinki stock eXchange, FI",
"HEX",
"hex" },
182 { FALSE, 0, 0,
"Man Investments, AU",
"maninv",
"maninv" },
183 { FALSE, 0, 0,
"Morningstar, SE",
"MORNINGSTAR",
"morningstar" },
184 { FALSE, 0, 0,
"Motley Fool, US",
"FOOL",
"fool" },
185 { FALSE, 0, 0,
"New Zealand stock eXchange, NZ",
"NZX",
"nzx" },
186 { FALSE, 0, 0,
"Paris Stock Exchange/Boursorama, FR",
"BOURSO",
"bourso" },
187 { FALSE, 0, 0,
"Paris Stock Exchange/LeRevenu, FR",
"LEREVENU",
"lerevenu" },
188 { FALSE, 0, 0,
"Platinum Asset Management, AU",
"PLATINUM",
"platinum" },
189 { FALSE, 0, 0,
"Skandinaviska Enskilda Banken, SE",
"SEB_FUNDS",
"seb_funds" },
190 { FALSE, 0, 0,
"Sharenet, ZA",
"ZA",
"za" },
191 { FALSE, 0, 0,
"StockHouse Canada",
"STOCKHOUSE_FUND",
"stockhousecanada_fund" },
192 { FALSE, 0, 0,
"TD Waterhouse Canada",
"TDWATERHOUSE",
"tdwaterhouse" },
193 { FALSE, 0, 0,
"TD Efunds, CA",
"TDEFUNDS",
"tdefunds" },
194 { FALSE, 0, 0,
"TIAA-CREF, US",
"TIAACREF",
"tiaacref" },
195 { FALSE, 0, 0,
"Toronto Stock eXchange, CA",
"TSX",
"tsx" },
196 { FALSE, 0, 0,
"T. Rowe Price, US",
"TRPRICE_DIRECT",
"troweprice_direct" },
197 { FALSE, 0, 0,
"Trustnet, GB",
"TRUSTNET",
"trustnet" },
198 { FALSE, 0, 0,
"Union Investment, DE",
"UNIONFUNDS",
"unionfunds" },
199 { FALSE, 0, 0,
"US Treasury Bonds",
"usfedbonds",
"usfedbonds" },
200 { FALSE, 0, 0,
"US Govt. Thrift Savings Plan",
"TSP",
"tsp" },
201 { FALSE, 0, 0,
"Vanguard",
"VANGUARD",
"vanguard" },
202 { FALSE, 0, 0,
"VWD, DE (unmaintained)",
"VWD",
"vwd" },
203 { FALSE, 0, 0,
"Yahoo USA",
"YAHOO",
"yahoo" },
204 { FALSE, 0, 0,
"Yahoo Asia",
"YAHOO_ASIA",
"yahoo_asia" },
205 { FALSE, 0, 0,
"Yahoo Australia",
"YAHOO_AUSTRALIA",
"yahoo_australia" },
206 { FALSE, 0, 0,
"Yahoo Brasil",
"YAHOO_BRASIL",
"yahoo_brasil" },
207 { FALSE, 0, 0,
"Yahoo Europe",
"YAHOO_EUROPE",
"yahoo_europe" },
208 { FALSE, 0, 0,
"Yahoo New Zealand",
"YAHOO_NZ",
"yahoo_nz" },
209 { FALSE, 0, 0,
"Zuerich Investments (outdated)",
"ZIFUNDS",
"zifunds" },
213 { FALSE, 0, 0,
"Asia (Yahoo, ...)",
"ASIA",
"asia" },
214 { FALSE, 0, 0,
"Australia (ASX, Yahoo, ...)",
"AUSTRALIA",
"australia" },
215 { FALSE, 0, 0,
"Brasil (Yahoo, ...)",
"BRASIL",
"brasil" },
216 { FALSE, 0, 0,
"Canada (Yahoo, ...)",
"CANADA",
"canada" },
217 { FALSE, 0, 0,
"Canada Mutual (Fund Library, ...)",
"CANADAMUTUAL",
"canadamutual" },
218 { FALSE, 0, 0,
"Dutch (AEX, ...)",
"DUTCH",
"dutch" },
219 { FALSE, 0, 0,
"Europe (Yahoo, ...)",
"EUROPE",
"europe" },
220 { FALSE, 0, 0,
"Greece (ASE, ...)",
"GREECE",
"greece" },
221 { FALSE, 0, 0,
"India Mutual (AMFI, ...)",
"INDIAMUTUAL",
"indiamutual" },
222 { FALSE, 0, 0,
"Fidelity (Fidelity, ...)",
"FIDELITY",
"fidelity" },
223 { FALSE, 0, 0,
"Finland (HEX, ...)",
"FINLAND",
"finland" },
224 { FALSE, 0, 0,
"First Trust (First Trust, ...)",
"FTPORTFOLIOS",
"ftportfolios" },
225 { FALSE, 0, 0,
"France (Boursorama, ...)",
"FRANCE",
"france" },
226 { FALSE, 0, 0,
"Nasdaq (Yahoo, ...)",
"NASDAQ",
"nasdaq" },
227 { FALSE, 0, 0,
"New Zealand (Yahoo, ...)",
"NZ",
"nz" },
228 { FALSE, 0, 0,
"NYSE (Yahoo, ...)",
"NYSE",
"nyse" },
230 { FALSE, 0, 0,
"T. Rowe Price",
"TRPRICE",
"troweprice" },
231 { FALSE, 0, 0,
"U.K. Unit Trusts",
"UKUNITTRUSTS",
"uk_unit_trusts" },
232 { FALSE, 0, 0,
"USA (Yahoo, Fool ...)",
"USA",
"usa" },
235 static const int num_single_quote_sources =
237 static const int num_multiple_quote_sources =
239 static GList *new_quote_sources = NULL;
251 return fq_is_installed;
265 return num_single_quote_sources;
268 return num_multiple_quote_sources;
270 return g_list_length(new_quote_sources);
279 gnc_quote_source_init_tables (
void)
283 for (i = 0; i < num_single_quote_sources; i++)
286 single_quote_sources[i].index = i;
289 for (i = 0; i < num_multiple_quote_sources; i++)
292 multiple_quote_sources[i].index = i;
296 currency_quote_source.index = 0;
313 DEBUG(
"Creating new source %s", (source_name == NULL ?
"(null)" : source_name));
315 new_source->supported = supported;
317 new_source->index = g_list_length(new_quote_sources);
321 new_source->user_name = g_strdup(source_name);
326 new_source->old_internal_name = g_strdup(source_name);
327 new_source->internal_name = g_strdup(source_name);
328 new_quote_sources = g_list_append(new_quote_sources, new_source);
343 ENTER(
"type/index is %d/%d", type, index);
347 LEAVE(
"found %s", currency_quote_source.user_name);
348 return ¤cy_quote_source;
352 if (index < num_single_quote_sources)
354 LEAVE(
"found %s", single_quote_sources[index].user_name);
355 return &single_quote_sources[index];
360 if (index < num_multiple_quote_sources)
362 LEAVE(
"found %s", multiple_quote_sources[index].user_name);
363 return &multiple_quote_sources[index];
369 node = g_list_nth(new_quote_sources, index);
373 LEAVE(
"found %s", source->user_name);
390 if ((name == NULL) || (g_strcmp0(name,
"") == 0))
395 if (g_strcmp0(name, currency_quote_source.internal_name) == 0)
396 return ¤cy_quote_source;
397 if (g_strcmp0(name, currency_quote_source.old_internal_name) == 0)
398 return ¤cy_quote_source;
400 for (i = 0; i < num_single_quote_sources; i++)
402 if (g_strcmp0(name, single_quote_sources[i].internal_name) == 0)
403 return &single_quote_sources[i];
404 if (g_strcmp0(name, single_quote_sources[i].old_internal_name) == 0)
405 return &single_quote_sources[i];
408 for (i = 0; i < num_multiple_quote_sources; i++)
410 if (g_strcmp0(name, multiple_quote_sources[i].internal_name) == 0)
411 return &multiple_quote_sources[i];
412 if (g_strcmp0(name, multiple_quote_sources[i].old_internal_name) == 0)
413 return &multiple_quote_sources[i];
416 for (i = 0, node = new_quote_sources; node; node = node->next, i++)
419 if (g_strcmp0(name, source->internal_name) == 0)
421 if (g_strcmp0(name, source->old_internal_name) == 0)
425 DEBUG(
"gnc_quote_source_lookup_by_internal: Unknown source %s", name);
444 LEAVE(
"type is %d", source->type);
458 LEAVE(
"index is %d", source->index);
459 return source->index;
472 LEAVE(
"%ssupported", source && source->supported ?
"" :
"not ");
473 return source->supported;
485 LEAVE(
"user name %s", source->user_name);
486 return source->user_name;
498 LEAVE(
"internal name %s", source->internal_name);
499 return source->internal_name;
516 fq_is_installed = TRUE;
521 for (node = sources_list; node; node = node->next)
523 source_name = node->data;
528 DEBUG(
"Found source %s: %s", source_name, source->user_name);
529 source->supported = TRUE;
550 PERR (
"Failed to commit: %d", errcode);
551 gnc_engine_signal_commit_error( errcode );
559 commodity_free( GNC_COMMODITY(inst) );
576 qof_instance_set_dirty(&cm->inst);
583 g_free(priv->printname);
584 priv->printname = g_strdup_printf(
"%s (%s)",
585 priv->mnemonic ? priv->mnemonic :
"",
586 priv->fullname ? priv->fullname :
"");
594 g_free(priv->unique_name);
595 ns = priv->name_space;
596 priv->unique_name = g_strdup_printf(
"%s::%s",
598 priv->mnemonic ? priv->mnemonic :
"");
609 priv = GET_PRIVATE(com);
611 priv->name_space = NULL;
612 priv->fullname = CACHE_INSERT(
"");
613 priv->mnemonic = CACHE_INSERT(
"");
614 priv->cusip = CACHE_INSERT(
"");
615 priv->fraction = 10000;
616 priv->quote_flag = 0;
617 priv->quote_source = NULL;
618 priv->quote_tz = CACHE_INSERT(
"");
620 reset_printname(priv);
621 reset_unique_name(priv);
625 gnc_commodity_dispose(GObject *comp)
627 G_OBJECT_CLASS(gnc_commodity_parent_class)->dispose(comp);
631 gnc_commodity_finalize(GObject* comp)
633 G_OBJECT_CLASS(gnc_commodity_parent_class)->finalize(comp);
642 gnc_commodity_get_property (GObject *
object,
650 g_return_if_fail(GNC_IS_COMMODITY(
object));
652 commodity = GNC_COMMODITY(
object);
653 priv = GET_PRIVATE(commodity);
657 g_value_take_object(value, priv->name_space);
660 g_value_set_string(value, priv->fullname);
663 g_value_set_string(value, priv->mnemonic);
666 g_value_set_string(value, priv->printname);
669 g_value_set_string(value, priv->cusip);
672 g_value_set_int(value, priv->fraction);
674 case PROP_UNIQUE_NAME:
675 g_value_set_string(value, priv->unique_name);
677 case PROP_QUOTE_FLAG:
678 g_value_set_boolean(value, priv->quote_flag);
680 case PROP_QUOTE_SOURCE:
681 g_value_set_pointer(value, priv->quote_source);
684 g_value_set_string(value, priv->quote_tz);
687 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
693 gnc_commodity_set_property (GObject *
object,
700 g_return_if_fail(GNC_IS_COMMODITY(
object));
702 commodity = GNC_COMMODITY(
object);
703 g_assert (qof_instance_get_editlevel(commodity));
722 case PROP_QUOTE_FLAG:
725 case PROP_QUOTE_SOURCE:
732 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
739 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
741 gobject_class->dispose = gnc_commodity_dispose;
742 gobject_class->finalize = gnc_commodity_finalize;
743 gobject_class->set_property = gnc_commodity_set_property;
744 gobject_class->get_property = gnc_commodity_get_property;
748 g_object_class_install_property(gobject_class,
750 g_param_spec_object (
"namespace",
752 "The namespace field denotes the "
753 "namespace for this commodity, either "
754 "a currency or symbol from a quote source.",
755 GNC_TYPE_COMMODITY_NAMESPACE,
757 g_object_class_install_property(gobject_class,
759 g_param_spec_string (
"fullname",
760 "Full Commodity Name",
761 "The fullname is the official full name of"
765 g_object_class_install_property(gobject_class,
767 g_param_spec_string (
"mnemonic",
768 "Commodity Mnemonic",
769 "The mnemonic is the official abbreviated"
770 "designation for the currency.",
773 g_object_class_install_property(gobject_class,
775 g_param_spec_string (
"printname",
776 "Commodity Print Name",
777 "Printable form of the commodity name.",
780 g_object_class_install_property(gobject_class,
782 g_param_spec_string (
"cusip",
783 "Commodity CUSIP Code",
787 g_object_class_install_property(gobject_class,
789 g_param_spec_int (
"fraction",
791 "The fraction is the number of sub-units that "
792 "the basic commodity can be divided into.",
797 g_object_class_install_property(gobject_class,
799 g_param_spec_string (
"unique-name",
800 "Commodity Unique Name",
801 "Unique form of the commodity name which combines "
802 "the namespace name and the commodity name.",
805 g_object_class_install_property(gobject_class,
807 g_param_spec_boolean (
"quote_flag",
809 "TRUE if prices are to be downloaded for this "
810 "commodity from a quote source.",
813 g_object_class_install_property(gobject_class,
815 g_param_spec_pointer(
"quote-source",
817 "The quote source from which prices are downloaded.",
819 g_object_class_install_property(gobject_class,
821 g_param_spec_string (
"quote-tz",
822 "Commodity Quote Timezone",
830 const char * name_space,
const char * mnemonic,
831 const char * cusip,
int fraction)
833 gnc_commodity * retval = g_object_new(GNC_TYPE_COMMODITY, NULL);
836 gnc_commodity_begin_edit(retval);
838 if ( name_space != NULL )
841 if (g_strcmp0 (name_space,
"template") == 0 &&
842 g_strcmp0 (mnemonic,
"template") != 0)
844 PWARN(
"Converting commodity %s from namespace template to "
845 "namespace User", mnemonic);
859 mark_commodity_dirty (retval);
860 gnc_commodity_commit_edit(retval);
884 priv = GET_PRIVATE(cm);
889 CACHE_REMOVE (priv->fullname);
890 CACHE_REMOVE (priv->cusip);
891 CACHE_REMOVE (priv->mnemonic);
892 CACHE_REMOVE (priv->quote_tz);
893 priv->name_space = NULL;
896 priv->quote_source = NULL;
899 g_free(priv->printname);
900 priv->printname = NULL;
902 g_free(priv->unique_name);
903 priv->unique_name = NULL;
905 #ifdef ACCOUNTS_CLEANED_UP
910 if (priv->usage_count != 0)
912 PWARN(
"Destroying commodity (%p) with non-zero usage_count (%d).", cm,
924 gnc_commodity_begin_edit(cm);
925 qof_instance_set_destroying(cm, TRUE);
926 gnc_commodity_commit_edit(cm);
937 dest_priv->name_space = src_priv->name_space;
953 gnc_commodity * dest = g_object_new(GNC_TYPE_COMMODITY, NULL);
955 src_priv = GET_PRIVATE(src);
956 dest_priv = GET_PRIVATE(dest);
958 dest_priv->fullname = CACHE_INSERT(src_priv->fullname);
959 dest_priv->mnemonic = CACHE_INSERT(src_priv->mnemonic);
960 dest_priv->cusip = CACHE_INSERT(src_priv->cusip);
961 dest_priv->quote_tz = CACHE_INSERT(src_priv->quote_tz);
963 dest_priv->name_space = src_priv->name_space;
965 dest_priv->fraction = src_priv->fraction;
966 dest_priv->quote_flag = src_priv->quote_flag;
973 reset_printname(dest_priv);
974 reset_unique_name(dest_priv);
986 if (!cm)
return NULL;
987 return GET_PRIVATE(cm)->mnemonic;
997 if (!cm)
return NULL;
998 return GET_PRIVATE(cm)->printname;
1009 if (!cm)
return NULL;
1018 if (!cm)
return NULL;
1019 priv = GET_PRIVATE(cm);
1020 if (!priv->name_space)
return NULL;
1021 if (priv->name_space->iso4217)
1024 return GNC_COMMODITY_NS_ISO;
1032 if (!cm)
return NULL;
1033 return GET_PRIVATE(cm)->name_space;
1043 if (!cm)
return NULL;
1044 return GET_PRIVATE(cm)->fullname;
1055 if (!cm)
return NULL;
1056 return GET_PRIVATE(cm)->unique_name;
1067 if (!cm)
return NULL;
1068 return GET_PRIVATE(cm)->cusip;
1079 return GET_PRIVATE(cm)->fraction;
1087 gnc_commodity_get_auto_quote_control_flag(
const gnc_commodity *cm)
1091 if (!cm)
return FALSE;
1093 str = kvp_frame_get_string(cm->inst.kvp_data,
"auto_quote_control");
1094 return !str || (strcmp(str,
"false") != 0);
1104 if (!cm)
return FALSE;
1105 return (GET_PRIVATE(cm)->quote_flag);
1117 if (!cm)
return NULL;
1118 priv = GET_PRIVATE(cm);
1120 return ¤cy_quote_source;
1121 return priv->quote_source;
1125 gnc_commodity_get_default_quote_source(
const gnc_commodity *cm)
1128 return ¤cy_quote_source;
1140 if (!cm)
return NULL;
1141 return GET_PRIVATE(cm)->quote_tz;
1151 if (!cm)
return NULL;
1152 return kvp_frame_get_string(cm->inst.kvp_data,
"user_symbol");
1162 if (!cm)
return NULL;
1163 return GET_PRIVATE(cm)->default_symbol;
1172 const char *nice_symbol;
1174 if (!cm)
return NULL;
1177 if (nice_symbol && *nice_symbol)
1180 lc = gnc_localeconv();
1181 nice_symbol = lc->currency_symbol;
1186 if (nice_symbol && *nice_symbol)
1202 priv = GET_PRIVATE(cm);
1203 if (priv->mnemonic == mnemonic)
return;
1205 gnc_commodity_begin_edit(cm);
1206 CACHE_REMOVE (priv->mnemonic);
1207 priv->mnemonic = CACHE_INSERT(mnemonic);
1209 mark_commodity_dirty (cm);
1210 reset_printname(priv);
1211 reset_unique_name(priv);
1212 gnc_commodity_commit_edit(cm);
1228 priv = GET_PRIVATE(cm);
1232 if (priv->name_space == nsp)
1235 gnc_commodity_begin_edit(cm);
1236 priv->name_space = nsp;
1239 mark_commodity_dirty(cm);
1240 reset_printname(priv);
1241 reset_unique_name(priv);
1242 gnc_commodity_commit_edit(cm);
1255 priv = GET_PRIVATE(cm);
1256 if (priv->fullname == fullname)
return;
1258 CACHE_REMOVE (priv->fullname);
1259 priv->fullname = CACHE_INSERT (fullname);
1261 gnc_commodity_begin_edit(cm);
1262 mark_commodity_dirty(cm);
1263 reset_printname(priv);
1264 gnc_commodity_commit_edit(cm);
1279 priv = GET_PRIVATE(cm);
1280 if (priv->cusip == cusip)
return;
1282 gnc_commodity_begin_edit(cm);
1283 CACHE_REMOVE (priv->cusip);
1284 priv->cusip = CACHE_INSERT (cusip);
1285 mark_commodity_dirty(cm);
1286 gnc_commodity_commit_edit(cm);
1297 gnc_commodity_begin_edit(cm);
1298 GET_PRIVATE(cm)->fraction = fraction;
1299 mark_commodity_dirty(cm);
1300 gnc_commodity_commit_edit(cm);
1308 gnc_commodity_set_auto_quote_control_flag(
gnc_commodity *cm,
1309 const gboolean flag)
1311 ENTER (
"(cm=%p, flag=%d)", cm, flag);
1319 gnc_commodity_begin_edit(cm);
1321 "auto_quote_control", flag ? NULL :
"false");
1322 mark_commodity_dirty(cm);
1323 gnc_commodity_commit_edit(cm);
1336 ENTER (
"(cm=%p, flag=%d)", cm, flag);
1344 priv = GET_PRIVATE(cm);
1345 gnc_commodity_begin_edit(cm);
1356 gnc_commodity_set_auto_quote_control_flag(cm,
1357 (!flag && (priv->usage_count == 0)) || (flag && (priv->usage_count != 0)));
1359 gnc_commodity_commit_edit(cm);
1370 ENTER (
"(cm=%p, flag=%d)", cm, flag);
1373 gnc_commodity_begin_edit(cm);
1374 GET_PRIVATE(cm)->quote_flag = flag;
1375 mark_commodity_dirty(cm);
1376 gnc_commodity_commit_edit(cm);
1387 ENTER (
"(cm=%p, src=%p(%s))", cm, src, src ? src->internal_name :
"unknown");
1390 gnc_commodity_begin_edit(cm);
1391 GET_PRIVATE(cm)->quote_source = src;
1392 mark_commodity_dirty(cm);
1393 gnc_commodity_commit_edit(cm);
1408 ENTER (
"(cm=%p, tz=%s)", cm, tz ? tz :
"(null)");
1410 priv = GET_PRIVATE(cm);
1412 if (tz == priv->quote_tz)
1414 LEAVE(
"Already correct TZ");
1418 gnc_commodity_begin_edit(cm);
1419 CACHE_REMOVE (priv->quote_tz);
1420 priv->quote_tz = CACHE_INSERT (tz);
1421 mark_commodity_dirty(cm);
1422 gnc_commodity_commit_edit(cm);
1437 ENTER (
"(cm=%p, symbol=%s)", cm, user_symbol ? user_symbol :
"(null)");
1439 gnc_commodity_begin_edit(cm);
1441 lc = gnc_localeconv();
1442 if (!user_symbol || !*user_symbol)
1445 !g_strcmp0(lc->currency_symbol, user_symbol))
1453 mark_commodity_dirty(cm);
1454 gnc_commodity_commit_edit(cm);
1466 const char * default_symbol)
1468 GET_PRIVATE(cm)->default_symbol = default_symbol;
1480 ENTER(
"(cm=%p)", cm);
1488 priv = GET_PRIVATE(cm);
1490 if ((priv->usage_count == 0) && !priv->quote_flag
1491 && gnc_commodity_get_auto_quote_control_flag(cm)
1496 gnc_commodity_begin_edit(cm);
1499 gnc_commodity_get_default_quote_source(cm));
1500 gnc_commodity_commit_edit(cm);
1502 priv->usage_count++;
1503 LEAVE(
"(usage_count=%d)", priv->usage_count);
1515 ENTER(
"(cm=%p)", cm);
1523 priv = GET_PRIVATE(cm);
1525 if (priv->usage_count == 0)
1527 PWARN(
"usage_count already zero");
1532 priv->usage_count--;
1533 if ((priv->usage_count == 0) && priv->quote_flag
1534 && gnc_commodity_get_auto_quote_control_flag(cm)
1541 LEAVE(
"(usage_count=%d)", priv->usage_count);
1559 if (a == b)
return TRUE;
1560 if (!a || !b)
return FALSE;
1562 priv_a = GET_PRIVATE(a);
1563 priv_b = GET_PRIVATE(b);
1564 if (priv_a->name_space != priv_b->name_space)
return FALSE;
1565 if (g_strcmp0(priv_a->mnemonic, priv_b->mnemonic) != 0)
return FALSE;
1576 if (a == b)
return TRUE;
1580 DEBUG (
"one is NULL");
1584 priv_a = GET_PRIVATE(a);
1585 priv_b = GET_PRIVATE(b);
1588 if ((same_book && priv_a->name_space != priv_b->name_space)
1592 DEBUG (
"namespaces differ: %p(%s) vs %p(%s)",
1598 if (g_strcmp0(priv_a->mnemonic, priv_b->mnemonic) != 0)
1600 DEBUG (
"mnemonics differ: %s vs %s", priv_a->mnemonic, priv_b->mnemonic);
1604 if (g_strcmp0(priv_a->fullname, priv_b->fullname) != 0)
1606 DEBUG (
"fullnames differ: %s vs %s", priv_a->fullname, priv_b->fullname);
1610 if (g_strcmp0(priv_a->cusip, priv_b->cusip) != 0)
1612 DEBUG (
"cusips differ: %s vs %s", priv_a->cusip, priv_b->cusip);
1616 if (priv_a->fraction != priv_b->fraction)
1618 DEBUG (
"fractions differ: %d vs %d", priv_a->fraction, priv_b->fraction);
1659 return name_space->cm_list;
1665 return ((g_strcmp0(name_space, GNC_COMMODITY_NS_ISO) == 0) ||
1666 (g_strcmp0(name_space, GNC_COMMODITY_NS_CURRENCY) == 0));
1669 static const gchar *
1670 gnc_commodity_table_map_namespace(
const char * name_space)
1672 if (g_strcmp0(name_space, GNC_COMMODITY_NS_ISO) == 0)
1673 return GNC_COMMODITY_NS_CURRENCY;
1686 retval->ns_table = g_hash_table_new(&g_str_hash, &g_str_equal);
1687 retval->ns_list = NULL;
1698 if (!book)
return NULL;
1709 if (!from)
return NULL;
1711 if (!comtbl)
return NULL;
1714 twin = gnc_commodity_table_lookup_unique (comtbl, ucom);
1729 count_coms(gpointer key, gpointer value, gpointer user_data)
1732 guint *count = (guint*)user_data;
1734 if (g_strcmp0((
char*)key, GNC_COMMODITY_NS_CURRENCY) == 0)
1742 *count += g_hash_table_size(tbl);
1749 g_return_val_if_fail(tbl, 0);
1750 g_return_val_if_fail(tbl->ns_table, 0);
1752 g_hash_table_foreach(tbl->ns_table, count_coms, (gpointer)&count);
1764 const char * name_space,
const char * mnemonic)
1769 if (!table || !name_space || !mnemonic)
return NULL;
1781 for (i = 0; i < GNC_NEW_ISO_CODES; i++)
1783 if (strcmp(mnemonic, gnc_new_iso_codes[i].old_code) == 0)
1785 mnemonic = gnc_new_iso_codes[i].new_code;
1790 return g_hash_table_lookup(nsp->cm_table, (gpointer)mnemonic);
1805 const char * unique_name)
1811 if (!table || !unique_name)
return NULL;
1813 name_space = g_strdup (unique_name);
1814 mnemonic = strstr (name_space,
"::");
1817 g_free (name_space);
1824 commodity = gnc_commodity_table_lookup (table, name_space, mnemonic);
1826 g_free (name_space);
1838 const char * name_space,
1839 const char * fullname)
1845 if (!fullname || (fullname[0] ==
'\0'))
1850 for (iterator = all; iterator; iterator = iterator->next)
1852 if (!strcmp(fullname,
1855 retval = iterator->data;
1877 const char *ns_name;
1881 if (!table)
return NULL;
1882 if (!comm)
return NULL;
1884 priv = GET_PRIVATE(comm);
1886 ENTER (
"(table=%p, comm=%p) %s %s", table, comm,
1887 (priv->mnemonic == NULL ?
"(null)" : priv->mnemonic),
1888 (priv->fullname == NULL ?
"(null)" : priv->fullname));
1890 c = gnc_commodity_table_lookup (table, ns_name, priv->mnemonic);
1896 LEAVE(
"already in table");
1902 if (priv->name_space->iso4217)
1905 for (i = 0; i < GNC_NEW_ISO_CODES; i++)
1908 || !strcmp(priv->mnemonic, gnc_new_iso_codes[i].old_code))
1917 LEAVE(
"found at %p", c);
1922 if (g_strcmp0 (ns_name,
"template") == 0 &&
1923 g_strcmp0 (priv->mnemonic,
"template") != 0)
1925 PWARN(
"Converting commodity %s from namespace template to "
1926 "namespace User", priv->mnemonic);
1929 mark_commodity_dirty (comm);
1935 PINFO (
"insert %p %s into nsp=%p %s", priv->mnemonic, priv->mnemonic,
1936 nsp->cm_table, nsp->name);
1937 g_hash_table_insert(nsp->cm_table,
1938 CACHE_INSERT(priv->mnemonic),
1940 nsp->cm_list = g_list_append(nsp->cm_list, comm);
1943 LEAVE (
"(table=%p, comm=%p)", table, comm);
1959 const char *ns_name;
1964 priv = GET_PRIVATE(comm);
1966 c = gnc_commodity_table_lookup (table, ns_name, priv->mnemonic);
1967 if (c != comm)
return;
1974 nsp->cm_list = g_list_remove(nsp->cm_list, comm);
1975 g_hash_table_remove (nsp->cm_table, priv->mnemonic);
1986 const char * name_space)
1990 if (!table || !name_space)
2007 hash_keys_helper(gpointer key, gpointer value, gpointer data)
2010 *l = g_list_prepend(*l, key);
2014 g_hash_table_keys(GHashTable * table)
2017 g_hash_table_foreach(table, &hash_keys_helper, (gpointer) &l);
2022 hash_values_helper(gpointer key, gpointer value, gpointer data)
2025 *l = g_list_prepend(*l, value);
2029 g_hash_table_values(GHashTable * table)
2032 g_hash_table_foreach(table, &hash_values_helper, (gpointer) &l);
2047 return g_hash_table_keys(table->ns_table);
2056 return table->ns_list;
2070 if (!cm)
return FALSE;
2072 priv = GET_PRIVATE(cm);
2073 if ( !priv->name_space)
return FALSE;
2074 return priv->name_space->iso4217;
2080 const char *ns_name;
2081 if (!cm)
return FALSE;
2085 !g_strcmp0(ns_name, GNC_COMMODITY_NS_CURRENCY));
2095 const char * name_space)
2106 return g_hash_table_values(ns->cm_table);
2115 get_quotables_helper1(gpointer key, gpointer value, gpointer data)
2121 if (!priv->quote_flag ||
2122 !priv->quote_source || !priv->quote_source->supported)
2124 *l = g_list_prepend(*l, value);
2133 if (!priv->quote_flag ||
2134 !priv->quote_source || !priv->quote_source->supported)
2136 *l = g_list_prepend(*l, comm);
2144 const char *name_space;
2145 GList * nslist, * tmp;
2148 const char *expression = gnc_prefs_get_namespace_regexp();
2150 ENTER(
"table=%p, expression=%s", table, expression);
2154 if (expression && *expression)
2156 if (regcomp(&pattern, expression, REG_EXTENDED | REG_ICASE) != 0)
2158 LEAVE(
"Cannot compile regex");
2163 for (tmp = nslist; tmp; tmp = tmp->next)
2165 name_space = tmp->data;
2166 if (regexec(&pattern, name_space, 0, NULL, 0) == 0)
2168 DEBUG(
"Running list of %s commodities", name_space);
2172 g_hash_table_foreach(ns->cm_table, &get_quotables_helper1, (gpointer) &l);
2176 g_list_free(nslist);
2184 LEAVE(
"list head %p", l);
2202 gnc_commodity_namespace_dispose_real (GObject *nsp)
2207 gnc_commodity_namespace_finalize_real(GObject* nsp)
2213 const char * name_space,
2218 if (!table)
return NULL;
2220 name_space = gnc_commodity_table_map_namespace(name_space);
2224 ns = g_object_new(GNC_TYPE_COMMODITY_NAMESPACE, NULL);
2225 ns->cm_table = g_hash_table_new(g_str_hash, g_str_equal);
2226 ns->name = CACHE_INSERT((gpointer)name_space);
2231 g_hash_table_insert(table->ns_table,
2232 (gpointer) ns->name,
2234 table->ns_list = g_list_append(table->ns_list, ns);
2243 const char * name_space)
2245 if (!table || !name_space)
2248 name_space = gnc_commodity_table_map_namespace(name_space);
2249 return g_hash_table_lookup(table->ns_table, (gpointer)name_space);
2254 gnc_commodity_find_commodity_by_guid(
const GncGUID *guid,
QofBook *book)
2257 if (!guid || !book)
return NULL;
2268 ns_helper(gpointer key, gpointer value, gpointer user_data)
2278 const char * name_space)
2289 g_hash_table_remove(table->ns_table, name_space);
2290 table->ns_list = g_list_remove(table->ns_list, ns);
2292 g_list_free(ns->cm_list);
2295 g_hash_table_foreach_remove(ns->cm_table, ns_helper, NULL);
2296 g_hash_table_destroy(ns->cm_table);
2297 CACHE_REMOVE(ns->name);
2318 iter_commodity (gpointer key, gpointer value, gpointer user_data)
2325 iter_data->ok = (iter_data->func)(cm, iter_data->user_data);
2330 iter_namespace (gpointer key, gpointer value, gpointer user_data)
2333 g_hash_table_foreach (namespace_hash, iter_commodity, user_data);
2343 if (!tbl || !f)
return FALSE;
2345 iter_data.ok = TRUE;
2347 iter_data.user_data = user_data;
2349 g_hash_table_foreach(tbl->ns_table, iter_namespace, (gpointer)&iter_data);
2351 return iter_data.ok;
2366 ENTER (
"table=%p", t);
2368 for (item = t->ns_list; item; item = next)
2370 next = g_list_next(item);
2375 g_list_free(t->ns_list);
2377 g_hash_table_destroy(t->ns_table);
2380 LEAVE (
"table=%p", t);
2389 #define CUR_I18N(String) dgettext ("iso_4217", String)
2397 ENTER (
"table=%p", table);
2407 #include "iso-4217-currencies.c"
2417 LEAVE (
"table=%p", table);
2435 DI(.e_type = ) GNC_ID_COMMODITY,
2436 DI(.type_label = ) "Commodity",
2437 DI(.create = ) NULL,
2438 DI(.book_begin = ) NULL,
2439 DI(.book_end = ) NULL,
2449 DI(.e_type = ) GNC_ID_COMMODITY_NAMESPACE,
2450 DI(.type_label = ) "Namespace",
2451 DI(.create = ) NULL,
2452 DI(.book_begin = ) NULL,
2453 DI(.book_end = ) NULL,
2454 DI(.is_dirty = ) NULL,
2455 DI(.mark_clean = ) NULL,
2456 DI(.foreach = ) NULL,
2457 DI(.printable = ) NULL,
2461 commodity_table_book_begin (
QofBook *book)
2464 ENTER (
"book=%p", book);
2474 PWARN(
"unable to initialize book's commodity_table");
2477 LEAVE (
"book=%p", book);
2481 commodity_table_book_end (
QofBook *book)
2487 gnc_commodity_table_destroy (ct);
2490 static QofObject commodity_table_object_def =
2493 DI(.e_type = ) GNC_ID_COMMODITY_TABLE,
2494 DI(.type_label = ) "CommodityTable",
2495 DI(.create = ) NULL,
2496 DI(.book_begin = ) commodity_table_book_begin,
2497 DI(.book_end = ) commodity_table_book_end,
2498 DI(.is_dirty = ) qof_collection_is_dirty,
2499 DI(.mark_clean = ) qof_collection_mark_clean,
2500 DI(.foreach = ) NULL,
2501 DI(.printable = ) NULL,
2502 DI(.version_cmp = ) NULL,
2508 gnc_quote_source_init_tables();
2525 MonetaryList *l = list, *tmp;
2526 for (tmp = list; tmp; tmp = tmp->next)
2542 l = g_list_prepend(l, new_mon);
2553 MonetaryList *node, *next;
2554 for (node = list; node; node = next)
2561 list = g_list_delete_link(list, node);
2572 for (tmp = list; tmp; tmp = tmp->next)
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table *table, gnc_commodity *comm)
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
gboolean gnc_commodity_table_foreach_commodity(const gnc_commodity_table *table, gboolean(*f)(gnc_commodity *cm, gpointer user_data), gpointer user_data)
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
int gnc_commodity_get_fraction(const gnc_commodity *cm)
gboolean gnc_commodity_table_add_default_data(gnc_commodity_table *table, QofBook *book)
const char * gnc_quote_source_get_user_name(const gnc_quote_source *source)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
QofBook * qof_instance_get_book(gconstpointer)
gboolean qof_collection_is_dirty(const QofCollection *col)
gnc_quote_source * gnc_quote_source_add_new(const char *source_name, gboolean supported)
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
#define PINFO(format, args...)
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
const char * gnc_commodity_get_namespace_compat(const gnc_commodity *cm)
const char * gnc_commodity_get_user_symbol(const gnc_commodity *cm)
void gnc_commodity_set_quote_tz(gnc_commodity *cm, const char *tz)
void gnc_commodity_decrement_usage_count(gnc_commodity *cm)
void gnc_quote_source_set_fq_installed(const GList *sources_list)
const char * gnc_commodity_get_quote_tz(const gnc_commodity *cm)
#define DEBUG(format, args...)
void gnc_commodity_set_fraction(gnc_commodity *cm, int fraction)
KvpFrame * kvp_frame_copy(const KvpFrame *frame)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
gboolean gnc_quote_source_get_supported(const gnc_quote_source *source)
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
QuoteSourceType gnc_quote_source_get_type(const gnc_quote_source *source)
int gnc_commodity_compare_void(const void *a, const void *b)
gboolean gnc_numeric_zero_p(gnc_numeric a)
gnc_commodity * gnc_commodity_clone(const gnc_commodity *src, QofBook *dest_book)
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
void gnc_commodity_set_quote_flag(gnc_commodity *cm, const gboolean flag)
#define QOF_OBJECT_VERSION
gnc_quote_source * gnc_quote_source_lookup_by_ti(QuoteSourceType type, gint index)
gboolean qof_commit_edit(QofInstance *inst)
#define PERR(format, args...)
#define ENTER(format, args...)
void gnc_commodity_user_set_quote_flag(gnc_commodity *cm, const gboolean flag)
gnc_commodity_namespace * gnc_commodity_table_add_namespace(gnc_commodity_table *table, const char *name_space, QofBook *book)
void qof_collection_foreach(const QofCollection *, QofInstanceForeachCB, gpointer user_data)
GList * gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace *name_space)
void kvp_frame_delete(KvpFrame *frame)
void gnc_commodity_set_user_symbol(gnc_commodity *cm, const char *user_symbol)
const char * gnc_commodity_namespace_get_name(const gnc_commodity_namespace *ns)
#define PWARN(format, args...)
void qof_instance_init_data(QofInstance *, QofIdType, QofBook *)
MonetaryList * gnc_monetary_list_delete_zeros(MonetaryList *list)
gboolean qof_begin_edit(QofInstance *inst)
void gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
gint gnc_quote_source_num_entries(QuoteSourceType type)
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
gboolean gnc_commodity_table_register(void)
void gnc_commodity_increment_usage_count(gnc_commodity *cm)
void gnc_commodity_set_cusip(gnc_commodity *cm, const char *cusip)
void gnc_monetary_list_free(MonetaryList *list)
gnc_commodity * gnc_commodity_new(QofBook *book, const char *fullname, const char *name_space, const char *mnemonic, const char *cusip, int fraction)
int gnc_commodity_table_has_namespace(const gnc_commodity_table *table, const char *name_space)
void gnc_commodity_table_delete_namespace(gnc_commodity_table *table, const char *name_space)
gboolean gnc_commodity_namespace_is_iso(const char *name_space)
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
#define GNC_COMMODITY_NS_LEGACY
void qof_book_set_data(QofBook *book, const gchar *key, gpointer data)
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
const char * gnc_commodity_get_nice_symbol(const gnc_commodity *cm)
void qof_collection_mark_clean(QofCollection *)
Generic api to store and retrieve preferences.
CommodityList * gnc_commodity_table_get_commodities(const gnc_commodity_table *table, const char *name_space)
gnc_quote_source * gnc_quote_source_lookup_by_internal(const char *name)
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
int gnc_commodity_compare(const gnc_commodity *a, const gnc_commodity *b)
void gnc_commodity_set_fullname(gnc_commodity *cm, const char *fullname)
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
gnc_commodity_namespace * gnc_commodity_table_find_namespace(const gnc_commodity_table *table, const char *name_space)
void gnc_commodity_set_mnemonic(gnc_commodity *cm, const char *mnemonic)
const char * gnc_commodity_get_default_symbol(const gnc_commodity *cm)
CommodityList * gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table *table)
gnc_commodity_table * gnc_commodity_table_new(void)
gint gnc_quote_source_get_index(const gnc_quote_source *source)
gnc_commodity_namespace * gnc_commodity_get_namespace_ds(const gnc_commodity *cm)
#define LEAVE(format, args...)
const char * gnc_commodity_get_unique_name(const gnc_commodity *cm)
MonetaryList * gnc_monetary_list_add_monetary(MonetaryList *list, gnc_monetary add_mon)
void gnc_commodity_table_remove(gnc_commodity_table *table, gnc_commodity *comm)
void gnc_commodity_set_namespace(gnc_commodity *cm, const char *name_space)
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
guint gnc_commodity_table_get_size(const gnc_commodity_table *tbl)
const char * gnc_quote_source_get_internal_name(const gnc_quote_source *source)
gboolean qof_object_register(const QofObject *object)
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
void gnc_commodity_copy(gnc_commodity *dest, const gnc_commodity *src)
gpointer qof_book_get_data(const QofBook *book, const gchar *key)
GList * gnc_commodity_table_get_namespaces_list(const gnc_commodity_table *table)
void kvp_frame_set_string(KvpFrame *frame, const gchar *path, const gchar *str)
Store a copy of the string at the indicated path.
gnc_commodity * gnc_commodity_obtain_twin(const gnc_commodity *from, QofBook *book)
Commodity handling public routines.
void gnc_commodity_destroy(gnc_commodity *cm)
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
gboolean gnc_quote_source_fq_installed(void)
const gchar * QofLogModule