gnucash unstable: Multiple changes pushed
Frank H.Ellenberger
fell at code.gnucash.org
Sat Mar 10 05:07:14 EST 2018
Updated via https://github.com/Gnucash/gnucash/commit/fdfa6f52 (commit)
via https://github.com/Gnucash/gnucash/commit/d61cd79a (commit)
via https://github.com/Gnucash/gnucash/commit/df26146d (commit)
from https://github.com/Gnucash/gnucash/commit/867fdce4 (commit)
commit fdfa6f528c70d317a20b7ba34f79111c67cd8ea0
Merge: 867fdce d61cd79
Author: fell <frank.h.ellenberger at gmail.com>
Date: Sat Mar 10 11:06:59 2018 +0100
Merge branch 'maint' into unstable
diff --cc doc/README-ca.win32-bin.txt
index e5e1fe3,e5e1fe3..93e5f86
--- a/doc/README-ca.win32-bin.txt
+++ b/doc/README-ca.win32-bin.txt
@@@ -1,52 -1,52 +1,52 @@@
--GnuCash és un programa de comptabilitat lliure, de codi obert publicat sota la
--Llicència Pública General GNU (GPL) i disponible per a GNU / Linux, *BSD,
--Solaris, Mac OSX i Microsoft Windows.
--
--Dissenyat per ser fà cil d'usar, però potent i flexible, GnuCash permet
--realitzar un seguiment dels comptes bancaris, les existències, els ingressos i les despeses. Tan rà pid i
--intuïtiu d'utilitzar com una llista de verificació, es basa en
--principis comptables professionals per assegurar balanços de comptes i informes precisos.
--
---------------------
--
--Opcions d'assistència disponibles:
--
--Preguntes freqüents en lÃnia: http://wiki.gnucash.org/wiki/FAQ
--Llistes de correu: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (Xat): canal #gnucash al servidor irc.gnome.org, vegeu també http://wiki.gnucash.org/wiki/IRC
--
--Si trobeu errors o problemes, no dubteu a informar-los
--a la nostra eina de seguiment d'errors "Bugzilla":
--http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--CaracterÃstiques principals:
--
-- * Comptabilitat de doble entrada
-- * Comptes d'accions / bons / fons d'inversió
-- * Importació de fitxers QIF / OFX
-- * OFX / HBCI Banca en lÃnia
-- * Informes, grà fics
-- * Comptabilitat de petites empreses
-- * Clients, venedors, treballs, factures, comptes de deutes i cobraments
-- * Transaccions programades
-- * CÃ lculs financers
--
--Podeu trobar més informació i un tutorial sobre com començar
--al menú "Ajuda" quan feu clic a "Guia de conceptes i tutorials".
--
---------------------
--
--Sobre el programa:
--
--GnuCash és un programa de comptabilitat lliure, de codi obert publicat sota la
--Llicència pública general GNU (GPL). Està desenvolupat de manera col·laborativa per
--12 persones de més de 6 països.
--
--La programació de GnuCash va començar el 1997, i la seva primera versió
--va ser l'any 1998.
--
---------------------
--
++GnuCash és un programa de comptabilitat lliure, de codi obert publicat sota la
++Llicència Pública General GNU (GPL) i disponible per a GNU / Linux, *BSD,
++Solaris, Mac OSX i Microsoft Windows.
++
++Dissenyat per ser fà cil d'usar, però potent i flexible, GnuCash permet
++realitzar un seguiment dels comptes bancaris, les existències, els ingressos i les despeses. Tan rà pid i
++intuïtiu d'utilitzar com una llista de verificació, es basa en
++principis comptables professionals per assegurar balanços de comptes i informes precisos.
++
++-------------------
++
++Opcions d'assistència disponibles:
++
++Preguntes freqüents en lÃnia: http://wiki.gnucash.org/wiki/FAQ
++Llistes de correu: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (Xat): canal #gnucash al servidor irc.gnome.org, vegeu també http://wiki.gnucash.org/wiki/IRC
++
++Si trobeu errors o problemes, no dubteu a informar-los
++a la nostra eina de seguiment d'errors "Bugzilla":
++http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++CaracterÃstiques principals:
++
++ * Comptabilitat de doble entrada
++ * Comptes d'accions / bons / fons d'inversió
++ * Importació de fitxers QIF / OFX
++ * OFX / HBCI Banca en lÃnia
++ * Informes, grà fics
++ * Comptabilitat de petites empreses
++ * Clients, venedors, treballs, factures, comptes de deutes i cobraments
++ * Transaccions programades
++ * CÃ lculs financers
++
++Podeu trobar més informació i un tutorial sobre com començar
++al menú "Ajuda" quan feu clic a "Guia de conceptes i tutorials".
++
++-------------------
++
++Sobre el programa:
++
++GnuCash és un programa de comptabilitat lliure, de codi obert publicat sota la
++Llicència pública general GNU (GPL). Està desenvolupat de manera col·laborativa per
++12 persones de més de 6 països.
++
++La programació de GnuCash va començar el 1997, i la seva primera versió
++va ser l'any 1998.
++
++-------------------
++
Aquesta és la traducció al català del fitxer README GnuCash 2.2.x per als paquets binaris de Windows.
diff --cc doc/README-de.win32-bin.txt
index 6bde138,6bde138..87a125e
--- a/doc/README-de.win32-bin.txt
+++ b/doc/README-de.win32-bin.txt
@@@ -1,56 -1,56 +1,56 @@@
--GnuCash ist eine freie OpenSource-Finanzverwaltung, kostenlos
--erhältlich unter der GNU GPL Lizenz für GNU/Linux, Unix, BSD,
--Solaris, Mac OSX und Microsoft Windows.
--
--Das Programm ist eine Komplettlösung zur Verwaltung der Finanzen von
--Privatanwendern und Kleinbetrieben. Das aus dem Rechnungswesen
--bekannte Prinzip der doppelten Buchführung wird in GnuCash konsequent
--umgesetzt, so dass GnuCash höchste Ansprüche an die Kontenführung
--erfüllen kann. Auch Onlinebanking über HBCI wird unterstützt.
--
---------------------
--
--Verfügbarer Support
--
--Englische FAQ-Seite: http://wiki.gnucash.org/wiki/FAQ
--Deutsche Mailingliste: http://lists.gnucash.org/mailman/listinfo/gnucash-de
--IRC (Online-Chat): Channel #gnucash auf Server irc.gnome.org, auch
--beschrieben auf http://wiki.gnucash.org/wiki/IRC
--
--Sollten Probleme auftreten, bitten die Entwickler darum, diese als
--englischsprachigen Fehlerbericht in »Bugzilla« einzutragen:
--http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--Feature-Ãbersicht:
--
-- * Doppelte Buchführung
-- * Aktienkonten, Währungskonten
-- * HBCI Online-Banking
-- * QIF/OFX/MT940 Importieren
-- * Berichte, Diagramme
-- * Buchführung für Kleinbetriebe
-- * Verwaltung von Kunden, Lieferanten, Aufträgen, Rechnungen
-- * Terminierte Buchungen
-- * Finanzrechner
--
--Weitere Informationen und eine (bisher nur englischsprachige)
--Einführung sind im Menü »Hilfe« zu finden unter dem Menüpunkt »GnuCash
--Kurs und Konzepte«.
--
---------------------
--
--Ãber GnuCash:
--
--GnuCash ist eine freie OpenSource-Finanzverwaltung, kostenlos
--erhältlich unter der GNU GPL Lizenz. Das Programm wird von 12
--Programmierern aus mehr als 6 Ländern gemeinsam weiterentwickelt.
--
--Die Anfänge von GnuCash reichen ins Jahr 1997 zurück. Die erste
--Veröffentlichung war im Jahr 1998.
--
---------------------
--
--This is the German GnuCash 2.2.x README file for Windows binary
--packages.
++GnuCash ist eine freie OpenSource-Finanzverwaltung, kostenlos
++erhältlich unter der GNU GPL Lizenz für GNU/Linux, Unix, BSD,
++Solaris, Mac OSX und Microsoft Windows.
++
++Das Programm ist eine Komplettlösung zur Verwaltung der Finanzen von
++Privatanwendern und Kleinbetrieben. Das aus dem Rechnungswesen
++bekannte Prinzip der doppelten Buchführung wird in GnuCash konsequent
++umgesetzt, so dass GnuCash höchste Ansprüche an die Kontenführung
++erfüllen kann. Auch Onlinebanking über HBCI wird unterstützt.
++
++-------------------
++
++Verfügbarer Support
++
++Englische FAQ-Seite: http://wiki.gnucash.org/wiki/FAQ
++Deutsche Mailingliste: http://lists.gnucash.org/mailman/listinfo/gnucash-de
++IRC (Online-Chat): Channel #gnucash auf Server irc.gnome.org, auch
++beschrieben auf http://wiki.gnucash.org/wiki/IRC
++
++Sollten Probleme auftreten, bitten die Entwickler darum, diese als
++englischsprachigen Fehlerbericht in »Bugzilla« einzutragen:
++http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++Feature-Ãbersicht:
++
++ * Doppelte Buchführung
++ * Aktienkonten, Währungskonten
++ * HBCI Online-Banking
++ * QIF/OFX/MT940 Importieren
++ * Berichte, Diagramme
++ * Buchführung für Kleinbetriebe
++ * Verwaltung von Kunden, Lieferanten, Aufträgen, Rechnungen
++ * Terminierte Buchungen
++ * Finanzrechner
++
++Weitere Informationen und eine (bisher nur englischsprachige)
++Einführung sind im Menü »Hilfe« zu finden unter dem Menüpunkt »GnuCash
++Kurs und Konzepte«.
++
++-------------------
++
++Ãber GnuCash:
++
++GnuCash ist eine freie OpenSource-Finanzverwaltung, kostenlos
++erhältlich unter der GNU GPL Lizenz. Das Programm wird von 12
++Programmierern aus mehr als 6 Ländern gemeinsam weiterentwickelt.
++
++Die Anfänge von GnuCash reichen ins Jahr 1997 zurück. Die erste
++Veröffentlichung war im Jahr 1998.
++
++-------------------
++
++This is the German GnuCash 2.2.x README file for Windows binary
++packages.
diff --cc doc/README-fr.win32-bin.txt
index 29e3b6f,29e3b6f..d34dae7
--- a/doc/README-fr.win32-bin.txt
+++ b/doc/README-fr.win32-bin.txt
@@@ -1,58 -1,58 +1,58 @@@
--GnuCash est un logiciel de comptabilité gratuit et de source
--libre, émis sous licence GNU Public Licence (GPL) et disponible
--sous GNU/Linux, *BSD, Solaris, Mac OSX et Microsoft Windows.
--
--Conçu pour une utilisation aisée, tout en étant puissant et flexible,
--GnuCash permet le suivi des comptes bancaires, des titres, des
--revenus et des dépenses. D'utilisation aussi rapide et intuitive
--qu'un registre de chèques, il est basé sur des principes comptables
--professionnels afin d'assurer des comptes en balance et des rapports
--précis.
--
---------------------
--
--Sources disponibles d'assistance :
--
--FAQ en ligne: http://wiki.gnucash.org/wiki/FAQ
--Listes de diffusions: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (Chat): Canal #gnucash sur le serveur irc.gnome.org,
--Aussi à consulter: http://wiki.gnucash.org/wiki/IRC
--
--N'hésitez pas à rapporter toute erreur ou tout problème rencontré
--sur notre outil de suivi des bogues "Bugzilla":
--http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--Survol des fonctionnalités::
--
-- * Comptabilité à partie double
-- * Comptes de titres en Actions/Obligations/Fonds d'investissement
-- * Importation de fichiers QIF/OFX
-- * Transactions bancaires en ligne OFX/HBCI
-- * Rapports et graphiques
-- * Comptabilité des petites entreprises
-- * Listes des clients, fournisseurs et prestations
-- * Facturation, Comptes clients et comptes fournisseurs
-- * Transactions récurrentes
-- * Calculs financiers
--
--Vous trouverez des informations additionnelles et un tutoriel sur la
--mise en route (en anglais, pour l'instant) en cliquant sur "Tutoriel
--et guide des concepts" dans le menu d'aide.
--
---------------------
--
--Ã propos du logiciel:
--
--GnuCash est un logiciel de comptabilité gratuit et de source
--libre, émis sous licence GNU Public Licence (GPL). Il est développé
--en collaboration par 12 personnes provenant d'au moins 6 pays.
--
--La programmation de GnuCash a commencé en 1997, sa première version
--a été lancée en 1998.
--
---------------------
--
--Ceci est le fichier README de GnuCash 2.2.x pour les paquetages en
--binaire pour Windows.
++GnuCash est un logiciel de comptabilité gratuit et de source
++libre, émis sous licence GNU Public Licence (GPL) et disponible
++sous GNU/Linux, *BSD, Solaris, Mac OSX et Microsoft Windows.
++
++Conçu pour une utilisation aisée, tout en étant puissant et flexible,
++GnuCash permet le suivi des comptes bancaires, des titres, des
++revenus et des dépenses. D'utilisation aussi rapide et intuitive
++qu'un registre de chèques, il est basé sur des principes comptables
++professionnels afin d'assurer des comptes en balance et des rapports
++précis.
++
++-------------------
++
++Sources disponibles d'assistance :
++
++FAQ en ligne: http://wiki.gnucash.org/wiki/FAQ
++Listes de diffusions: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (Chat): Canal #gnucash sur le serveur irc.gnome.org,
++Aussi à consulter: http://wiki.gnucash.org/wiki/IRC
++
++N'hésitez pas à rapporter toute erreur ou tout problème rencontré
++sur notre outil de suivi des bogues "Bugzilla":
++http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++Survol des fonctionnalités::
++
++ * Comptabilité à partie double
++ * Comptes de titres en Actions/Obligations/Fonds d'investissement
++ * Importation de fichiers QIF/OFX
++ * Transactions bancaires en ligne OFX/HBCI
++ * Rapports et graphiques
++ * Comptabilité des petites entreprises
++ * Listes des clients, fournisseurs et prestations
++ * Facturation, Comptes clients et comptes fournisseurs
++ * Transactions récurrentes
++ * Calculs financiers
++
++Vous trouverez des informations additionnelles et un tutoriel sur la
++mise en route (en anglais, pour l'instant) en cliquant sur "Tutoriel
++et guide des concepts" dans le menu d'aide.
++
++-------------------
++
++Ã propos du logiciel:
++
++GnuCash est un logiciel de comptabilité gratuit et de source
++libre, émis sous licence GNU Public Licence (GPL). Il est développé
++en collaboration par 12 personnes provenant d'au moins 6 pays.
++
++La programmation de GnuCash a commencé en 1997, sa première version
++a été lancée en 1998.
++
++-------------------
++
++Ceci est le fichier README de GnuCash 2.2.x pour les paquetages en
++binaire pour Windows.
diff --cc doc/README-it.win32-bin.txt
index 96a420c,96a420c..ae5fe55
--- a/doc/README-it.win32-bin.txt
+++ b/doc/README-it.win32-bin.txt
@@@ -1,51 -1,51 +1,51 @@@
--GnuCash è un programma di contabilità  libero e a codice aperto rilasciato con
--licenza GNU Public Licence (GPL) e disponibile per i sistemi GNU/Linux, *BSD,
--Solaris, Mac OSX e Microsoft Windows.
--
--Progettato per essere di facile utilizzo, ma allo stesso tempo potente e flessibile,
--GnuCash permette di tenere traccia dei propri conti bancari, delle azioni, dei costi e dei ricavi.
--Veloce e intuitivo come il registro degli assegni, GnuCash si basa su concetti fondamentali della
--contabilità  assicurando il bilancio dei conti e l'accurattezza dei resoconti.
--
---------------------
--
--Disponibilità  di supporto
--
--FAQ online (in inglese): http://wiki.gnucash.org/wiki/FAQ
--Mailing List: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (Chat): canale #gnucash sul server irc.gnome.org; vedere anche http://wiki.gnucash.org/wiki/IRC
--
--Se si riscontrassero dei problemi o dei bug utilizzando il programma, è possibile comunicarli nel sistema
--di tracciamento dei bug di GnuCash denominato "Bugzilla":
--http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--Caratteristiche principali:
--
-- * Contabilità a partita doppia
-- * Conti per azioni, obbligazioni(bond) e fondi comuni
-- * Importazione di file QIF/OFX
-- * OFX/HBCI Online Banking
-- * Resoconti e grafici
-- * Contabilità  di piccole imprese
-- * Clienti, venditori, lavori, fatture, conti per debiti e crediti correnti
-- * Transazioni pianificate
-- * Calcolatrice finanziaria
--
--Maggiori informazioni e una guida su come iniziare a utilizzare il programma, sono
--raggiungibili tramite il menu "Aiuto" selezionando la voce "Guida ai concetti e manuale".
--
---------------------
--
--Informazioni sul programma:
--
--GnuCash è un programma di contabilità  libero e a codice aperto rilasciato con
--licenza GNU Public Licence (GPL). E' sviluppato con la collaborazione di
--12 programmatori provenienti da oltre 6 paesi.
--
--La programmazione di GnuCash è iniziata nel 1997 e il primo rilascio risale al 1998.
--
---------------------
--
--Questo è il file LEGGIMI di GnuCash 2.2.x dei pacchetti binari per Windows.
++GnuCash è un programma di contabilità  libero e a codice aperto rilasciato con
++licenza GNU Public Licence (GPL) e disponibile per i sistemi GNU/Linux, *BSD,
++Solaris, Mac OSX e Microsoft Windows.
++
++Progettato per essere di facile utilizzo, ma allo stesso tempo potente e flessibile,
++GnuCash permette di tenere traccia dei propri conti bancari, delle azioni, dei costi e dei ricavi.
++Veloce e intuitivo come il registro degli assegni, GnuCash si basa su concetti fondamentali della
++contabilità  assicurando il bilancio dei conti e l'accurattezza dei resoconti.
++
++-------------------
++
++Disponibilità  di supporto
++
++FAQ online (in inglese): http://wiki.gnucash.org/wiki/FAQ
++Mailing List: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (Chat): canale #gnucash sul server irc.gnome.org; vedere anche http://wiki.gnucash.org/wiki/IRC
++
++Se si riscontrassero dei problemi o dei bug utilizzando il programma, è possibile comunicarli nel sistema
++di tracciamento dei bug di GnuCash denominato "Bugzilla":
++http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++Caratteristiche principali:
++
++ * Contabilità a partita doppia
++ * Conti per azioni, obbligazioni(bond) e fondi comuni
++ * Importazione di file QIF/OFX
++ * OFX/HBCI Online Banking
++ * Resoconti e grafici
++ * Contabilità  di piccole imprese
++ * Clienti, venditori, lavori, fatture, conti per debiti e crediti correnti
++ * Transazioni pianificate
++ * Calcolatrice finanziaria
++
++Maggiori informazioni e una guida su come iniziare a utilizzare il programma, sono
++raggiungibili tramite il menu "Aiuto" selezionando la voce "Guida ai concetti e manuale".
++
++-------------------
++
++Informazioni sul programma:
++
++GnuCash è un programma di contabilità  libero e a codice aperto rilasciato con
++licenza GNU Public Licence (GPL). E' sviluppato con la collaborazione di
++12 programmatori provenienti da oltre 6 paesi.
++
++La programmazione di GnuCash è iniziata nel 1997 e il primo rilascio risale al 1998.
++
++-------------------
++
++Questo è il file LEGGIMI di GnuCash 2.2.x dei pacchetti binari per Windows.
diff --cc doc/README-lv.win32-bin.txt
index 85a4578,85a4578..0d8cbc1
--- a/doc/README-lv.win32-bin.txt
+++ b/doc/README-lv.win32-bin.txt
@@@ -1,52 -1,52 +1,52 @@@
--GnuCash ir bezmaksas grÄmatvedÄ«bas programma, ko izplata saskaÅÄ ar
--GNU General Public License (GPL) licenci. To var izmantot uz GNU/Linux,
--*BSD, Solaris, Mac OSX un Microsoft Windows datoriem.
--
--GnuCash ir veidots tÄ, lai to bÅ«tu vienkÄrÅ¡i lietot, tajÄ pat laikÄ tas
--ir pietiekami jaudīgs un ļauj uzskaitīt skaidru naudu, banku kontus,
--akcijas, ieÅÄmumus un izdevumus.
--TajÄ var Ätri un Ärti reÄ£istrÄt darÄ«jumu, un tÄ ir balstÄ«ta uz
--profesionÄlÄs grÄmatvedÄ«bas principiem, nodroÅ¡inot bilanci un
--precÄ«zus pÄrskatus.
--
---------------------
--
--TehniskÄ palÄ«dzÄ«ba
--
--Tiešsaistes palīdzība: http://wiki.gnucash.org/wiki/FAQ
--VÄstkopas: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (sazÅa): #gnucash on server irc.gnome.org, skatÄ«t arÄ« http://wiki.gnucash.org/wiki/IRC
--
--Ja atklÄjat kļūdas vai problÄmas, nekautrÄjieties tÄs reÄ£istrÄt "Bugzilla" kļūdu apstrÄdes
--sistÄmÄ http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--GalvenÄs iespÄjas:
--
-- * DivkÄrÅ¡Ä ieraksta grÄmatvedÄ«ba
-- * Akciju/VÄrtspapÄ«ru/KapitÄla daļu konti
-- * QIF/OFX datu imports
-- * OFX/HBCI tiešsaistes banka
-- * PÄrskati, grafiki
-- * Mazo uzÅÄmumu biznesa atbalsts
-- * Klienti, PiegÄdÄtÄji, Darbi, SaÅemtie un izsniegtie rÄÄ·ini
-- * IeplÄnoti grÄmatojumi
-- * FinanÅ¡u aprÄÄ·ini
--
--VairÄk informÄcijas un sÄkotnÄjÄ apmÄcÄ«ba pieejama aktivizÄjot izvÄlni
--"PalÄ«dzÄ«ba" un "PamÄcÄ«ba un jÄdzienu ceļvedis".
--
---------------------
--
--Par šo programmu:
--
--GnuCash ir bezmaksas grÄmatvedÄ«bas programma, ko izplata saskaÅÄ ar
--GNU General Public License (GPL) licenci. TÄs galvenie izstrÄdÄtÄji ir
--12 cilvÄki, kas sadarbojas ar atbalstÄ«tÄjiem vairÄk kÄ 6 valstÄ«s.
--
--GnuCash izstrÄde sÄkÄs 1997. gadÄ un tÄs pirmais laidiens bija 1998. gadÄ.
--
---------------------
--
--Å is ir GnuCash 2.2.x README fails Windows binÄrajai pakotnei.
++GnuCash ir bezmaksas grÄmatvedÄ«bas programma, ko izplata saskaÅÄ ar
++GNU General Public License (GPL) licenci. To var izmantot uz GNU/Linux,
++*BSD, Solaris, Mac OSX un Microsoft Windows datoriem.
++
++GnuCash ir veidots tÄ, lai to bÅ«tu vienkÄrÅ¡i lietot, tajÄ pat laikÄ tas
++ir pietiekami jaudīgs un ļauj uzskaitīt skaidru naudu, banku kontus,
++akcijas, ieÅÄmumus un izdevumus.
++TajÄ var Ätri un Ärti reÄ£istrÄt darÄ«jumu, un tÄ ir balstÄ«ta uz
++profesionÄlÄs grÄmatvedÄ«bas principiem, nodroÅ¡inot bilanci un
++precÄ«zus pÄrskatus.
++
++-------------------
++
++TehniskÄ palÄ«dzÄ«ba
++
++Tiešsaistes palīdzība: http://wiki.gnucash.org/wiki/FAQ
++VÄstkopas: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (sazÅa): #gnucash on server irc.gnome.org, skatÄ«t arÄ« http://wiki.gnucash.org/wiki/IRC
++
++Ja atklÄjat kļūdas vai problÄmas, nekautrÄjieties tÄs reÄ£istrÄt "Bugzilla" kļūdu apstrÄdes
++sistÄmÄ http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++GalvenÄs iespÄjas:
++
++ * DivkÄrÅ¡Ä ieraksta grÄmatvedÄ«ba
++ * Akciju/VÄrtspapÄ«ru/KapitÄla daļu konti
++ * QIF/OFX datu imports
++ * OFX/HBCI tiešsaistes banka
++ * PÄrskati, grafiki
++ * Mazo uzÅÄmumu biznesa atbalsts
++ * Klienti, PiegÄdÄtÄji, Darbi, SaÅemtie un izsniegtie rÄÄ·ini
++ * IeplÄnoti grÄmatojumi
++ * FinanÅ¡u aprÄÄ·ini
++
++VairÄk informÄcijas un sÄkotnÄjÄ apmÄcÄ«ba pieejama aktivizÄjot izvÄlni
++"PalÄ«dzÄ«ba" un "PamÄcÄ«ba un jÄdzienu ceļvedis".
++
++-------------------
++
++Par šo programmu:
++
++GnuCash ir bezmaksas grÄmatvedÄ«bas programma, ko izplata saskaÅÄ ar
++GNU General Public License (GPL) licenci. TÄs galvenie izstrÄdÄtÄji ir
++12 cilvÄki, kas sadarbojas ar atbalstÄ«tÄjiem vairÄk kÄ 6 valstÄ«s.
++
++GnuCash izstrÄde sÄkÄs 1997. gadÄ un tÄs pirmais laidiens bija 1998. gadÄ.
++
++-------------------
++
++Å is ir GnuCash 2.2.x README fails Windows binÄrajai pakotnei.
diff --cc doc/README-nl.win32-bin.txt
index 6825257,6825257..d54bc23
--- a/doc/README-nl.win32-bin.txt
+++ b/doc/README-nl.win32-bin.txt
@@@ -1,51 -1,51 +1,51 @@@
--GnuCash is een vrij, open source boekhoudprogramma, uitgegeven
--onder de GNU General Public License (GPL) en is beschikbaar voor
--GNU/Linux, *BSD, Solaris, Mac OSX, en Microsoft Windows.
--
--Het is een eenvoudig te gebruiken, en tegelijkertijd krachtig en flexibel
--programma dat je helpt om je bankrekeningen, aandelen, inkomsten en uitgaven
--te beheren. Zo vlot en intuïtief te gebruiken als een dagboek enerzijds, en
--anderzijds gebaseerd op professionele boekhoudkundige principes om boeken in
--balans en nauwkeurige rapporten te verzekeren.
--
---------------------
--
--Beschikbare bronnen voor ondersteuning
--
--Online veel gestelde vragen (FAQ): http://wiki.gnucash.org/wiki/FAQ
--Mailing Lijsten: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (Chat): Channel #gnucash on server irc.gnome.org, see also http://wiki.gnucash.org/wiki/IRC
--
--Als je programmafouten (bugs) of problemen ervaart, aarzel niet om deze te melden in ons
--bug opvolgsysteem "Bugzilla":
--http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--Interessante functies:
--
-- * Dubbel boekhouden
-- * Aandelen-/belegginsrekeningen
-- * QIF/OFX/HBCI import met dubbele transactie herkenning
-- * Rapporten, grafieken
-- * Klein-ondernemingsboekhouding
-- * Klanten, verkopers, opdrachten, Facturen, Lopende rekening
-- * Periodieke Transacties
-- * Financiële berekeningen
--
--Meer informatie en een handleiding om je op weg te helpen vind je
--in het "Hulp" menu onder het "Tutorial en concepten gids".
--
---------------------
--
--Over het programma:
--
--GnuCash is a vrij, open source boekhoudprogramma uitgegeven onder de
--GNU General Public License (GPL). Het wordt door 12 personen uit meer dan
--6 landen gezamelijk ontwikkeld.
--
--De ontwikkeling van GnuCash begon in 1997, de de eerste uitgave was in 1998.
--
---------------------
--
--Dit is het Nederlandstalige GnuCash 2.2.x LEESMIJ bestand voor het Windows installatie programma.
++GnuCash is een vrij, open source boekhoudprogramma, uitgegeven
++onder de GNU General Public License (GPL) en is beschikbaar voor
++GNU/Linux, *BSD, Solaris, Mac OSX, en Microsoft Windows.
++
++Het is een eenvoudig te gebruiken, en tegelijkertijd krachtig en flexibel
++programma dat je helpt om je bankrekeningen, aandelen, inkomsten en uitgaven
++te beheren. Zo vlot en intuïtief te gebruiken als een dagboek enerzijds, en
++anderzijds gebaseerd op professionele boekhoudkundige principes om boeken in
++balans en nauwkeurige rapporten te verzekeren.
++
++-------------------
++
++Beschikbare bronnen voor ondersteuning
++
++Online veel gestelde vragen (FAQ): http://wiki.gnucash.org/wiki/FAQ
++Mailing Lijsten: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (Chat): Channel #gnucash on server irc.gnome.org, see also http://wiki.gnucash.org/wiki/IRC
++
++Als je programmafouten (bugs) of problemen ervaart, aarzel niet om deze te melden in ons
++bug opvolgsysteem "Bugzilla":
++http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++Interessante functies:
++
++ * Dubbel boekhouden
++ * Aandelen-/belegginsrekeningen
++ * QIF/OFX/HBCI import met dubbele transactie herkenning
++ * Rapporten, grafieken
++ * Klein-ondernemingsboekhouding
++ * Klanten, verkopers, opdrachten, Facturen, Lopende rekening
++ * Periodieke Transacties
++ * Financiële berekeningen
++
++Meer informatie en een handleiding om je op weg te helpen vind je
++in het "Hulp" menu onder het "Tutorial en concepten gids".
++
++-------------------
++
++Over het programma:
++
++GnuCash is a vrij, open source boekhoudprogramma uitgegeven onder de
++GNU General Public License (GPL). Het wordt door 12 personen uit meer dan
++6 landen gezamelijk ontwikkeld.
++
++De ontwikkeling van GnuCash begon in 1997, de de eerste uitgave was in 1998.
++
++-------------------
++
++Dit is het Nederlandstalige GnuCash 2.2.x LEESMIJ bestand voor het Windows installatie programma.
diff --cc doc/README-zh_CN.win32-bin.txt
index 01f9ea7,01f9ea7..c9f8915
--- a/doc/README-zh_CN.win32-bin.txt
+++ b/doc/README-zh_CN.win32-bin.txt
@@@ -1,41 -1,41 +1,41 @@@
--GnuCash æ¯ä¸ä¸ªå
è´¹çã弿¾æºä»£ç çç财软件ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è®¸å¯è¯(GPL)ï¼å¯è¿è¡äº GNU/Linuxã*BSDãSolarisãMac OSX以å微软 Windowsã
--
--è´åäºæäºä½¿ç¨ï¼ä½åè½å¼ºå¤§èä¸çµæ´»ãGnuCash å
许æ¨è·è¸ªé¶è¡è´¦æ·ãè¡ç¥¨ãæ¶å
¥åæ¯åºãå°±åè´¦ç°¿ä¸æ ·å¿«æ·èä¸ç´è§ï¼å®æ¯åºäºä¸ä¸çä¼è®¡ç念æ¥ç¡®ä¿å¹³è¡¡ç账簿ååç¡®çæ¥åã
--
---------------------
--
--æ¨å¯ä»¥è·å¾æ¯æçéå¾
--
--å¨çº¿å¸¸è§é®é¢è§£ç: http://wiki.gnucash.org/wiki/FAQ
--é®ä»¶å表: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (è天): irc.gnome.org æå¡å¨ç #gnucash é¢éï¼å¦è§ http://wiki.gnucash.org/wiki/IRC
--
--妿æ¨éå°äºä»»ä½ bug æè
é®é¢ï¼è¯·ä¸è¦ç¹è±«ï¼å°å®ä»¬æ¥å尿们ç bug è·è¸ªå·¥å
·âBugzillaâï¼http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--åè½äº®ç¹ï¼
--
-- * å¤å¼è®°è´¦ä¼è®¡
-- * è¡ç¥¨/åºå¸/åºéç§ç®
-- * QIF/OFX 导å
¥
-- * OFX/HBCI ç½ä¸é¶è¡
-- * æ¥åãå¾è¡¨
-- * å°åä¼ä¸è´¢ä¼
-- * 客æ·ãååãä»»å¡ãå票ãåºä»è´¦æ¬¾ååºæ¶è´¦æ¬¾
-- * 计åç交æ
-- * éè计ç®å·¥å
·
--
--å½ç¹å»âæç¨åç念æåâæ¶ï¼å¯ä»¥å¨â帮å©âèå䏿¾å°æ´å¤çä¿¡æ¯ä»¥åå¦ä½å¼å§çæç¨ã
--
---------------------
--
--å
³äºç¨åºï¼
--
--GnuCash æ¯ä¸ä¸ªå
è´¹çã弿¾æºä»£ç çç财软件ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è®¸å¯è¯(GPL)ã宿¯ç±æ¨ªè·¨6个å½å®¶å
±12个å¼å人åå
±ååä½å¼åèæã
--
--ç¨åºæ°åå¼å§äº1997å¹´ï¼å¹¶ä¸äº1998å¹´ç¬¬ä¸æ¬¡åå¸ã
--
---------------------
--
--è¿æ¯ GnuCash 2.2.x ç¨äº Windows äºè¿å¶åå¸å
çèªè¿°æä»¶ã
++GnuCash æ¯ä¸ä¸ªå
è´¹çã弿¾æºä»£ç çç财软件ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è®¸å¯è¯(GPL)ï¼å¯è¿è¡äº GNU/Linuxã*BSDãSolarisãMac OSX以å微软 Windowsã
++
++è´åäºæäºä½¿ç¨ï¼ä½åè½å¼ºå¤§èä¸çµæ´»ãGnuCash å
许æ¨è·è¸ªé¶è¡è´¦æ·ãè¡ç¥¨ãæ¶å
¥åæ¯åºãå°±åè´¦ç°¿ä¸æ ·å¿«æ·èä¸ç´è§ï¼å®æ¯åºäºä¸ä¸çä¼è®¡ç念æ¥ç¡®ä¿å¹³è¡¡ç账簿ååç¡®çæ¥åã
++
++-------------------
++
++æ¨å¯ä»¥è·å¾æ¯æçéå¾
++
++å¨çº¿å¸¸è§é®é¢è§£ç: http://wiki.gnucash.org/wiki/FAQ
++é®ä»¶å表: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (è天): irc.gnome.org æå¡å¨ç #gnucash é¢éï¼å¦è§ http://wiki.gnucash.org/wiki/IRC
++
++妿æ¨éå°äºä»»ä½ bug æè
é®é¢ï¼è¯·ä¸è¦ç¹è±«ï¼å°å®ä»¬æ¥å尿们ç bug è·è¸ªå·¥å
·âBugzillaâï¼http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++åè½äº®ç¹ï¼
++
++ * å¤å¼è®°è´¦ä¼è®¡
++ * è¡ç¥¨/åºå¸/åºéç§ç®
++ * QIF/OFX 导å
¥
++ * OFX/HBCI ç½ä¸é¶è¡
++ * æ¥åãå¾è¡¨
++ * å°åä¼ä¸è´¢ä¼
++ * 客æ·ãååãä»»å¡ãå票ãåºä»è´¦æ¬¾ååºæ¶è´¦æ¬¾
++ * 计åç交æ
++ * éè计ç®å·¥å
·
++
++å½ç¹å»âæç¨åç念æåâæ¶ï¼å¯ä»¥å¨â帮å©âèå䏿¾å°æ´å¤çä¿¡æ¯ä»¥åå¦ä½å¼å§çæç¨ã
++
++-------------------
++
++å
³äºç¨åºï¼
++
++GnuCash æ¯ä¸ä¸ªå
è´¹çã弿¾æºä»£ç çç财软件ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è®¸å¯è¯(GPL)ã宿¯ç±æ¨ªè·¨6个å½å®¶å
±12个å¼å人åå
±ååä½å¼åèæã
++
++ç¨åºæ°åå¼å§äº1997å¹´ï¼å¹¶ä¸äº1998å¹´ç¬¬ä¸æ¬¡åå¸ã
++
++-------------------
++
++è¿æ¯ GnuCash 2.2.x ç¨äº Windows äºè¿å¶åå¸å
çèªè¿°æä»¶ã
diff --cc doc/README-zh_TW.win32-bin.txt
index d0f0397,d0f0397..19f62d4
--- a/doc/README-zh_TW.win32-bin.txt
+++ b/doc/README-zh_TW.win32-bin.txt
@@@ -1,42 -1,42 +1,42 @@@
--GnuCash æ¯ä¸åèªç±ãéæ¾åå§ç¢¼ç帳åè»é«ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è¨±å¯è(GPL)ï¼æ¯æ´ GNU/Linux, *BSD, Solaris, Mac OSX åå¾®è» Windowsã
--
--GnuCash ä¸å
è¨è¨æææ¼ä½¿ç¨ï¼èä¸åè½å¼·å¤§åæå½æ§ãå®å¯ä»¥è¿½è¹¤éè¡å¸³æ¶ãè¡ç¥¨ãæ¶å
¥èæ¯åºï¼å°±åç¨å¸³ç°¿ä¸æ¨£å¿«æ·ãç´è¦ºãåºæ¼å°æ¥çæè¨åå確ä¿å¸³ç®å¹³è¡¡ä¸¦æä¾æºç¢ºçå ±è¡¨ã
--
---------------------
--
--å¯ç²å¾æ¯æ´ç管é
--
--常è¦åé¡è§£ç: http://wiki.gnucash.org/wiki/FAQ
--éä¿¡è«å£: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (è天): irc.gnome.org 伺æå¨ç #gnucash é »éï¼è¦ http://wiki.gnucash.org/wiki/IRC
--
--妿æ¨éå°äºä»»ä½ bug æåé¡ï¼è«ä¸è¦é²çï¼å°åé¡å ±åå°æåç bug 追蹤系統 "Bugzilla": (è«ç¨è±æ)
--http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--åè½ç¹é»:
--
-- * è¤å¼ç°¿è¨
-- * è¡ç¥¨/åµå¸/åºé帳è
-- * å¯å
¥ QIF/OFX
-- * OFX/HBCI 網路éè¡
-- * åå¼å ±åãå表
-- * å°ä¼æ¥è²¡å管ç
-- * 客æ¶ãå» åãå·¥ä½ãæ¶æãæä»å¸³æ¬¾ãææ¶å¸³æ¬¾
-- * 交ææç¨
-- * éèè¨ç®å·¥å
·
--
--æ´å¤è³è¨åå
¥éæå¸å¯ä»¥å¨åè½è¡¨ "說æ" 裡ç "æå¸èè§å¿µæå" æ¾å°ã
--
---------------------
--
--éæ¼ç¨å¼:
--
--GnuCash æ¯ä¸åèªç±ãéæ¾åå§ç¢¼ç帳åè»é«ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è¨±å¯è(GPL)ç¼å¸ã宿¯ç±æ©«è·¨ 6 åå
± 12 åéç¼äººå¡å
±ååä½éç¼èæã
--
--GnuCash çç¨å¼æ°å¯«å§æ¼ 1997 å¹´ï¼ç¬¬ä¸çç¼å¸æ¼ 1998 å¹´ã
--
---------------------
--
--鿝 GnuCash 2.2.x å¨ Windows äºé²ä½å¥ä»¶ç README æªæ¡ã
++GnuCash æ¯ä¸åèªç±ãéæ¾åå§ç¢¼ç帳åè»é«ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è¨±å¯è(GPL)ï¼æ¯æ´ GNU/Linux, *BSD, Solaris, Mac OSX åå¾®è» Windowsã
++
++GnuCash ä¸å
è¨è¨æææ¼ä½¿ç¨ï¼èä¸åè½å¼·å¤§åæå½æ§ãå®å¯ä»¥è¿½è¹¤éè¡å¸³æ¶ãè¡ç¥¨ãæ¶å
¥èæ¯åºï¼å°±åç¨å¸³ç°¿ä¸æ¨£å¿«æ·ãç´è¦ºãåºæ¼å°æ¥çæè¨åå確ä¿å¸³ç®å¹³è¡¡ä¸¦æä¾æºç¢ºçå ±è¡¨ã
++
++-------------------
++
++å¯ç²å¾æ¯æ´ç管é
++
++常è¦åé¡è§£ç: http://wiki.gnucash.org/wiki/FAQ
++éä¿¡è«å£: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (è天): irc.gnome.org 伺æå¨ç #gnucash é »éï¼è¦ http://wiki.gnucash.org/wiki/IRC
++
++妿æ¨éå°äºä»»ä½ bug æåé¡ï¼è«ä¸è¦é²çï¼å°åé¡å ±åå°æåç bug 追蹤系統 "Bugzilla": (è«ç¨è±æ)
++http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++åè½ç¹é»:
++
++ * è¤å¼ç°¿è¨
++ * è¡ç¥¨/åµå¸/åºé帳è
++ * å¯å
¥ QIF/OFX
++ * OFX/HBCI 網路éè¡
++ * åå¼å ±åãå表
++ * å°ä¼æ¥è²¡å管ç
++ * 客æ¶ãå» åãå·¥ä½ãæ¶æãæä»å¸³æ¬¾ãææ¶å¸³æ¬¾
++ * 交ææç¨
++ * éèè¨ç®å·¥å
·
++
++æ´å¤è³è¨åå
¥éæå¸å¯ä»¥å¨åè½è¡¨ "說æ" 裡ç "æå¸èè§å¿µæå" æ¾å°ã
++
++-------------------
++
++éæ¼ç¨å¼:
++
++GnuCash æ¯ä¸åèªç±ãéæ¾åå§ç¢¼ç帳åè»é«ï¼å®ä½¿ç¨ GNU éç¨å
Œ
±è¨±å¯è(GPL)ç¼å¸ã宿¯ç±æ©«è·¨ 6 åå
± 12 åéç¼äººå¡å
±ååä½éç¼èæã
++
++GnuCash çç¨å¼æ°å¯«å§æ¼ 1997 å¹´ï¼ç¬¬ä¸çç¼å¸æ¼ 1998 å¹´ã
++
++-------------------
++
++鿝 GnuCash 2.2.x å¨ Windows äºé²ä½å¥ä»¶ç README æªæ¡ã
diff --cc doc/README.win32-bin.txt
index 5bf8c2b,5bf8c2b..69a4b93
--- a/doc/README.win32-bin.txt
+++ b/doc/README.win32-bin.txt
@@@ -1,52 -1,52 +1,52 @@@
--GnuCash is a free, open source accounting program released under the
--GNU General Public License (GPL) and available for GNU/Linux, *BSD,
--Solaris, Mac OSX, and Microsoft Windows.
--
--Designed to be easy to use, yet powerful and flexible, GnuCash allows
--you to track bank accounts, stocks, income and expenses. As quick and
--intuitive to use as a checkbook register, it is based on professional
--accounting principles to ensure balanced books and accurate reports.
--
---------------------
--
--Available Support Options
--
--Online FAQ: http://wiki.gnucash.org/wiki/FAQ
--Mailing Lists: http://wiki.gnucash.org/wiki/Mailing_Lists
--IRC (Chat): Channel #gnucash on server irc.gnome.org, see also http://wiki.gnucash.org/wiki/IRC
--
--If you encounter any bugs or problems, do not hesitate to report them
--into our bug tracking tool "Bugzilla":
--http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
--
---------------------
--
--Feature Highlights:
--
-- * Double-Entry Accounting
-- * Stock/Bond/Mutual Fund Accounts
-- * QIF/OFX Import
-- * OFX/HBCI Online Banking
-- * Reports, Graphs
-- * Small-Business Accounting
-- * Customers, Vendors, Jobs, Invoices, Accounts/Payables and /Receivables
-- * Scheduled Transactions
-- * Financial Calculations
--
--More information and a Tutorial on how to get started can be found in
--the "Help" menu when clicking on "Tutorial and Concepts Guide".
--
---------------------
--
--About the Program:
--
--GnuCash is a free, open source accounting program released under the
--GNU General Public License (GPL). It is collaboratively developed by
--12 people from over 6 countries.
--
--Programming on GnuCash began in 1997, and its first release was in
--1998.
--
---------------------
--
--This is the GnuCash 2.2.x README file for Windows binary packages.
++GnuCash is a free, open source accounting program released under the
++GNU General Public License (GPL) and available for GNU/Linux, *BSD,
++Solaris, Mac OSX, and Microsoft Windows.
++
++Designed to be easy to use, yet powerful and flexible, GnuCash allows
++you to track bank accounts, stocks, income and expenses. As quick and
++intuitive to use as a checkbook register, it is based on professional
++accounting principles to ensure balanced books and accurate reports.
++
++-------------------
++
++Available Support Options
++
++Online FAQ: http://wiki.gnucash.org/wiki/FAQ
++Mailing Lists: http://wiki.gnucash.org/wiki/Mailing_Lists
++IRC (Chat): Channel #gnucash on server irc.gnome.org, see also http://wiki.gnucash.org/wiki/IRC
++
++If you encounter any bugs or problems, do not hesitate to report them
++into our bug tracking tool "Bugzilla":
++http://bugzilla.gnome.org/enter_bug.cgi?product=GnuCash
++
++-------------------
++
++Feature Highlights:
++
++ * Double-Entry Accounting
++ * Stock/Bond/Mutual Fund Accounts
++ * QIF/OFX Import
++ * OFX/HBCI Online Banking
++ * Reports, Graphs
++ * Small-Business Accounting
++ * Customers, Vendors, Jobs, Invoices, Accounts/Payables and /Receivables
++ * Scheduled Transactions
++ * Financial Calculations
++
++More information and a Tutorial on how to get started can be found in
++the "Help" menu when clicking on "Tutorial and Concepts Guide".
++
++-------------------
++
++About the Program:
++
++GnuCash is a free, open source accounting program released under the
++GNU General Public License (GPL). It is collaboratively developed by
++12 people from over 6 countries.
++
++Programming on GnuCash began in 1997, and its first release was in
++1998.
++
++-------------------
++
++This is the GnuCash 2.2.x README file for Windows binary packages.
diff --cc doc/examples/downloaded.mt940
index 64afa9a,64afa9a..3ddb2e1
--- a/doc/examples/downloaded.mt940
+++ b/doc/examples/downloaded.mt940
@@@ -1,9 -1,9 +1,9 @@@
--:20:STARTUMS
--:25:80007777/2602272001
--:28C:0
--:60F:C060228EUR0,00
--:61:0604280228D12,56N020NONREF//
--:86:020?00ÜBERWEISUNG?100?20TESTING GNUCASH FOR HBCI?21AND MT940
--?3080007777?312602272003?32GNUCASH?34000
--:62F:D060228EUR12,56
---
++:20:STARTUMS
++:25:80007777/2602272001
++:28C:0
++:60F:C060228EUR0,00
++:61:0604280228D12,56N020NONREF//
++:86:020?00ÜBERWEISUNG?100?20TESTING GNUCASH FOR HBCI?21AND MT940
++?3080007777?312602272003?32GNUCASH?34000
++:62F:D060228EUR12,56
++-
diff --cc gnucash/gnome-utils/gnc-tree-view-commodity.c
index 62d21d9,0000000..ebd2ea6
mode 100644,000000..100644
--- a/gnucash/gnome-utils/gnc-tree-view-commodity.c
+++ b/gnucash/gnome-utils/gnc-tree-view-commodity.c
@@@ -1,708 -1,0 +1,708 @@@
+/********************************************************************\
+ * gnc-tree-view-commodity.c -- GtkTreeView implementation to *
+ * display commodities in a GtkTreeView. *
+ * Copyright (C) 2003,2005 David Hampton <hampton at employees.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+ * *
+\********************************************************************/
+
+#include <config.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <string.h>
+
+#include "gnc-tree-view.h"
+#include "gnc-tree-model-commodity.h"
+#include "gnc-tree-view-commodity.h"
+
+#include "gnc-commodity.h"
+#include "gnc-component-manager.h"
+#include "gnc-engine.h"
+#include "gnc-glib-utils.h"
+#include "gnc-gnome-utils.h"
+#include "gnc-icons.h"
+#include "gnc-ui-util.h"
+
+
+/** Static Globals *******************************************************/
+
+/* This static indicates the debugging module that this .o belongs to. */
+static QofLogModule log_module = GNC_MOD_GUI;
+
+/** Declarations *********************************************************/
+static void gnc_tree_view_commodity_class_init (GncTreeViewCommodityClass *klass);
+static void gnc_tree_view_commodity_init (GncTreeViewCommodity *view);
+static void gnc_tree_view_commodity_finalize (GObject *object);
+static void gnc_tree_view_commodity_destroy (GtkWidget *widget);
+
+typedef struct GncTreeViewCommodityPrivate
+{
+ gpointer dummy;
+} GncTreeViewCommodityPrivate;
+
+#define GNC_TREE_VIEW_COMMODITY_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_VIEW_COMMODITY, GncTreeViewCommodityPrivate))
+
+
+/************************************************************/
+/* g_object required functions */
+/************************************************************/
+
+static GObjectClass *parent_class = NULL;
+
+GType
+gnc_tree_view_commodity_get_type (void)
+{
+ static GType gnc_tree_view_commodity_type = 0;
+
+ if (gnc_tree_view_commodity_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (GncTreeViewCommodityClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gnc_tree_view_commodity_class_init,
+ NULL,
+ NULL,
+ sizeof (GncTreeViewCommodity),
+ 0,
+ (GInstanceInitFunc) gnc_tree_view_commodity_init
+ };
+
+ gnc_tree_view_commodity_type = g_type_register_static (GNC_TYPE_TREE_VIEW,
+ "GncTreeViewCommodity",
+ &our_info, 0);
+ }
+
+ return gnc_tree_view_commodity_type;
+}
+
+static void
+gnc_tree_view_commodity_class_init (GncTreeViewCommodityClass *klass)
+{
+ GObjectClass *o_class;
+ GtkWidgetClass *widget_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ o_class = G_OBJECT_CLASS (klass);
+ widget_class = GTK_WIDGET_CLASS (klass);
+
+ /* GObject signals */
+ o_class->finalize = gnc_tree_view_commodity_finalize;
+
+ /* GtkWidget signals */
+ widget_class->destroy = gnc_tree_view_commodity_destroy;
+
+ g_type_class_add_private(klass, sizeof(GncTreeViewCommodityPrivate));
+}
+
+static void
+gnc_tree_view_commodity_init (GncTreeViewCommodity *view)
+{
+}
+
+static void
+gnc_tree_view_commodity_finalize (GObject *object)
+{
+ g_return_if_fail (object != NULL);
+ g_return_if_fail (GNC_IS_TREE_VIEW_COMMODITY (object));
+
+ ENTER("view %p", object);
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+ LEAVE(" ");
+}
+
+static void
+gnc_tree_view_commodity_destroy (GtkWidget *widget)
+{
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GNC_IS_TREE_VIEW_COMMODITY (widget));
+
+ ENTER("view %p", widget);
+
+ if (GTK_WIDGET_CLASS (parent_class)->destroy)
+ (* GTK_WIDGET_CLASS (parent_class)->destroy) (widget);
+ LEAVE(" ");
+}
+
+
+/************************************************************/
+/* sort functions */
+/************************************************************/
+
+static gboolean
+get_commodities_w_iters (GtkTreeModel *f_model,
+ GtkTreeIter *f_iter_a,
+ GtkTreeIter *f_iter_b,
+ GtkTreeModel **model_p,
+ GtkTreeIter *iter_a,
+ GtkTreeIter *iter_b,
+ gnc_commodity **comm_a,
+ gnc_commodity **comm_b)
+{
+ GncTreeModelCommodity *model;
+ GtkTreeModel *tree_model;
+
+ tree_model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
+ model = GNC_TREE_MODEL_COMMODITY(tree_model);
+
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
+ iter_a,
+ f_iter_a);
+
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
+ iter_b,
+ f_iter_b);
+
+ /* Both iters must point to commodities for this to be meaningful */
+ if (!gnc_tree_model_commodity_iter_is_commodity (model, iter_a))
+ return FALSE;
+ if (!gnc_tree_model_commodity_iter_is_commodity (model, iter_b))
+ return FALSE;
+
+ *comm_a = gnc_tree_model_commodity_get_commodity (model, iter_a);
+ *comm_b = gnc_tree_model_commodity_get_commodity (model, iter_b);
+ if (model_p)
+ *model_p = tree_model;
+ return TRUE;
+}
+
+static gboolean
+get_commodities (GtkTreeModel *f_model,
+ GtkTreeIter *f_iter_a,
+ GtkTreeIter *f_iter_b,
+ GtkTreeModel **model_p,
+ gnc_commodity **comm_a,
+ gnc_commodity **comm_b)
+{
+ GtkTreeIter iter_a, iter_b;
+
+ return get_commodities_w_iters(f_model, f_iter_a, f_iter_b, model_p,
+ &iter_a, &iter_b, comm_a, comm_b);
+}
+
+static gint
+sort_namespace (GtkTreeModel *f_model,
+ GtkTreeIter *f_iter_a,
+ GtkTreeIter *f_iter_b)
+{
+ GncTreeModelCommodity *model;
+ GtkTreeModel *tree_model;
+ GtkTreeIter iter_a, iter_b;
+ gnc_commodity_namespace *ns_a, *ns_b;
+
+ tree_model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
+ model = GNC_TREE_MODEL_COMMODITY(tree_model);
+
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
+ &iter_a,
+ f_iter_a);
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
+ &iter_b,
+ f_iter_b);
+
+ ns_a = gnc_tree_model_commodity_get_namespace (model, &iter_a);
+ ns_b = gnc_tree_model_commodity_get_namespace (model, &iter_b);
+ return safe_utf8_collate (gnc_commodity_namespace_get_gui_name (ns_a),
+ gnc_commodity_namespace_get_gui_name (ns_b));
+}
+
+static gint
+default_sort (gnc_commodity *comm_a, gnc_commodity *comm_b)
+{
+ gint fraction_a, fraction_b, result;
+
+ result = safe_utf8_collate (gnc_commodity_get_namespace (comm_a),
+ gnc_commodity_get_namespace (comm_b));
+ if (result != 0) return result;
+
+ result = safe_utf8_collate (gnc_commodity_get_mnemonic (comm_a),
+ gnc_commodity_get_mnemonic (comm_b));
+ if (result != 0) return result;
+
+ result = safe_utf8_collate (gnc_commodity_get_fullname (comm_a),
+ gnc_commodity_get_fullname (comm_b));
+ if (result != 0) return result;
+
+ result = safe_utf8_collate (gnc_commodity_get_cusip (comm_a),
+ gnc_commodity_get_cusip (comm_b));
+ if (result != 0) return result;
+
+ fraction_a = gnc_commodity_get_fraction (comm_a);
+ fraction_b = gnc_commodity_get_fraction (comm_b);
+
+ if (fraction_a < fraction_b)
+ return -1;
+
+ if (fraction_b < fraction_a)
+ return 1;
+
+ return 0;
+}
+
+static gint
+sort_by_commodity_string (GtkTreeModel *f_model,
+ GtkTreeIter *f_iter_a,
+ GtkTreeIter *f_iter_b,
+ gpointer user_data)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter_a, iter_b;
+ gnc_commodity *comm_a, *comm_b;
+ gchar *str1, *str2;
+ gint column = GPOINTER_TO_INT(user_data);
+ gint result;
+
+ if (!get_commodities_w_iters(f_model, f_iter_a, f_iter_b,
+ &model, &iter_a, &iter_b, &comm_a, &comm_b))
+ return sort_namespace (f_model, f_iter_a, f_iter_b);
+
+ /* Get the strings. */
+ gtk_tree_model_get(GTK_TREE_MODEL(model), &iter_a, column, &str1, -1);
+ gtk_tree_model_get(GTK_TREE_MODEL(model), &iter_b, column, &str2, -1);
+
+ result = safe_utf8_collate(str1, str2);
+ g_free(str1);
+ g_free(str2);
+ if (result != 0)
+ return result;
+ return default_sort(comm_a, comm_b);
+}
+
+
+static gint
+sort_by_fraction (GtkTreeModel *f_model,
+ GtkTreeIter *f_iter_a,
+ GtkTreeIter *f_iter_b,
+ gpointer user_data)
+{
+ gnc_commodity *comm_a, *comm_b;
+ gint fraction_a, fraction_b;
+
+ if (!get_commodities (f_model, f_iter_a, f_iter_b, NULL, &comm_a, &comm_b))
+ return sort_namespace (f_model, f_iter_a, f_iter_b);
+
+ fraction_a = gnc_commodity_get_fraction (comm_a);
+ fraction_b = gnc_commodity_get_fraction (comm_b);
+
+ if (fraction_a < fraction_b)
+ return -1;
+
+ if (fraction_b < fraction_a)
+ return 1;
+
+ return default_sort(comm_a, comm_b);
+}
+
+static gint
+sort_by_quote_flag (GtkTreeModel *f_model,
+ GtkTreeIter *f_iter_a,
+ GtkTreeIter *f_iter_b,
+ gpointer user_data)
+{
+ gnc_commodity *comm_a, *comm_b;
+ gboolean flag_a, flag_b;
+
+ if (!get_commodities (f_model, f_iter_a, f_iter_b, NULL, &comm_a, &comm_b))
+ return sort_namespace (f_model, f_iter_a, f_iter_b);
+
+ flag_a = gnc_commodity_get_quote_flag(comm_a);
+ flag_b = gnc_commodity_get_quote_flag(comm_b);
+
+ if (flag_a < flag_b)
+ return -1;
+ else if (flag_a > flag_b)
+ return 1;
+ return default_sort(comm_a, comm_b);
+}
+
+/************************************************************/
+/* New View Creation */
+/************************************************************/
+
+/*
+ * Create a new commodity tree view with (optional) top level root node.
+ * This view will be based on a model that is common to all view of
+ * the same set of books, but will have its own private filter on that
+ * model.
+ */
+GtkTreeView *
+gnc_tree_view_commodity_new (QofBook *book,
+ const gchar *first_property_name,
+ ...)
+{
+ GncTreeView *view;
+ GtkTreeModel *model, *f_model, *s_model;
+ GtkTreeViewColumn *col;
+ gnc_commodity_table *ct;
+ va_list var_args;
+
+ ENTER(" ");
+ /* Create/get a pointer to the existing model for this set of books. */
+ ct = gnc_commodity_table_get_table (book);
+ model = gnc_tree_model_commodity_new (book, ct);
+
+ /* Set up the view private filter on the common model. */
+ f_model = gtk_tree_model_filter_new (model, NULL);
+ g_object_unref(G_OBJECT(model));
+ s_model = gtk_tree_model_sort_new_with_model (f_model);
+ g_object_unref(G_OBJECT(f_model));
+
+ /* Create our view */
+ view = g_object_new (GNC_TYPE_TREE_VIEW_COMMODITY,
+ "name", "commodity_tree", NULL);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (view), s_model);
+ g_object_unref(G_OBJECT(s_model));
+
+ DEBUG("model ref count is %d", G_OBJECT(model)->ref_count);
+ DEBUG("f_model ref count is %d", G_OBJECT(f_model)->ref_count);
+ DEBUG("s_model ref count is %d", G_OBJECT(s_model)->ref_count);
+
+ /* Set default visibilities */
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view), FALSE);
+
+ col = gnc_tree_view_add_text_column (
+ view, _("Namespace"), "namespace", NULL, "NASDAQ",
+ GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE,
+ GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
+ sort_by_commodity_string);
+ col = gnc_tree_view_add_text_column (
+ view, _("Symbol"), "symbol", NULL, "ACMEACME",
+ GNC_TREE_MODEL_COMMODITY_COL_MNEMONIC,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
+ col = gnc_tree_view_add_text_column (
+ view, _("Name"), "name", NULL, "Acme Corporation, Inc.",
+ GNC_TREE_MODEL_COMMODITY_COL_FULLNAME,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
+ col = gnc_tree_view_add_text_column (
+ view, _("Print Name"), "printname", NULL,
+ "ACMEACME (Acme Corporation, Inc.)",
+ GNC_TREE_MODEL_COMMODITY_COL_PRINTNAME,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ col = gnc_tree_view_add_text_column (
+ view, _("Display symbol"), "user_symbol", NULL, "ACME",
+ GNC_TREE_MODEL_COMMODITY_COL_USER_SYMBOL,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
+ col = gnc_tree_view_add_text_column (
+ view, _("Unique Name"), "uniquename", NULL,
+ "NASDAQ::ACMEACME", GNC_TREE_MODEL_COMMODITY_COL_UNIQUE_NAME,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ col = gnc_tree_view_add_text_column (
+ /* Translators: Again replace CUSIP by the name of your
+ National Securities Identifying Number. */
- view, _("ISIN/CUSIP"), "cusip_code", NULL, "QWERTYUIOP",
++ view, _("ISIN/CUSIP"), "cusip_code", NULL, "US1234567890",
+ GNC_TREE_MODEL_COMMODITY_COL_CUSIP,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
+ col = gnc_tree_view_add_numeric_column (
+ view, _("Fraction"), "fraction", "10000",
+ GNC_TREE_MODEL_COMMODITY_COL_FRACTION,
+ GNC_TREE_VIEW_COLUMN_COLOR_NONE,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_fraction);
+ g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
+ col = gnc_tree_view_add_toggle_column(
+ view, _("Get Quotes"),
+ /* Translators: This string has a context prefix; the translation
+ must only contain the part after the | character. */
+ Q_("Column letter for 'Get Quotes'|Q"), "quote_flag",
+ GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_quote_flag,
+ NULL);
+ col = gnc_tree_view_add_text_column (
+ view, _("Source"), "quote_source", NULL, "alphavantage",
+ GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ col = gnc_tree_view_add_text_column (
+ view, _("Timezone"), "quote_timezone", NULL, "America/New_York",
+ GNC_TREE_MODEL_COMMODITY_COL_QUOTE_TZ,
+ GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
+ sort_by_commodity_string);
+ g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
+
+ gnc_tree_view_configure_columns(view);
+
+ /* Set properties */
+ va_start (var_args, first_property_name);
+ g_object_set_valist (G_OBJECT(view), first_property_name, var_args);
+ va_end (var_args);
+
+ /* Sort on the name column by default. This allows for a consistent
+ * sort if commodities are briefly removed and re-added. */
+ if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ NULL, NULL))
+ {
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
+ GNC_TREE_MODEL_COMMODITY_COL_FULLNAME,
+ GTK_SORT_ASCENDING);
+ }
+
+ gtk_widget_show(GTK_WIDGET(view));
+ LEAVE(" %p", view);
+ return GTK_TREE_VIEW(view);
+}
+
+/************************************************************/
+/* Auxiliary Functions */
+/************************************************************/
+
+#define debug_path(fn, path) { \
+ gchar *path_string = gtk_tree_path_to_string(path); \
+ fn("tree path %s", path_string); \
+ g_free(path_string); \
+ }
+
+#if 0 /* Not Used */
+static gboolean
+gnc_tree_view_commodity_get_iter_from_commodity (GncTreeViewCommodity *view,
+ gnc_commodity *commodity,
+ GtkTreeIter *s_iter)
+{
+ GtkTreeModel *model, *f_model, *s_model;
+ GtkTreeIter iter, f_iter;
+
+ g_return_val_if_fail(GNC_IS_TREE_VIEW_COMMODITY(view), FALSE);
+ g_return_val_if_fail(commodity != NULL, FALSE);
+ g_return_val_if_fail(s_iter != NULL, FALSE);
+
+ ENTER("view %p, commodity %p (%s)", view, commodity, gnc_commodity_get_mnemonic(commodity));
+
+ /* Reach down to the real model and get an iter for this commodity */
+ s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+ f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
+ model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
+ if (!gnc_tree_model_commodity_get_iter_from_commodity (GNC_TREE_MODEL_COMMODITY(model), commodity, &iter))
+ {
+ LEAVE("model_get_iter_from_commodity failed");
+ return FALSE;
+ }
+
+ /* convert back to a sort iter */
+ gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER(f_model),
+ &f_iter, &iter);
+ gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(s_model),
+ s_iter, &f_iter);
+ LEAVE(" ");
+ return TRUE;
+}
+#endif /* Not Used */
+
+/************************************************************/
+/* Commodity Tree View Visibility Filter */
+/************************************************************/
+
+typedef struct
+{
+ gnc_tree_view_commodity_ns_filter_func user_ns_fn;
+ gnc_tree_view_commodity_cm_filter_func user_cm_fn;
+ gpointer user_data;
+ GDestroyNotify user_destroy;
+} filter_user_data;
+
+static void
+gnc_tree_view_commodity_filter_destroy (gpointer data)
+{
+ filter_user_data *fd = data;
+
+ if (fd->user_destroy)
+ fd->user_destroy(fd->user_data);
+ g_free(fd);
+}
+
+static gboolean
+gnc_tree_view_commodity_filter_helper (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ gnc_commodity_namespace *name_space;
+ gnc_commodity *commodity;
+ filter_user_data *fd = data;
+
+ g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ if (gnc_tree_model_commodity_iter_is_namespace (GNC_TREE_MODEL_COMMODITY(model), iter))
+ {
+ if (fd->user_ns_fn)
+ {
+ name_space = gnc_tree_model_commodity_get_namespace (GNC_TREE_MODEL_COMMODITY(model), iter);
+ return fd->user_ns_fn(name_space, fd->user_data);
+ }
+ return TRUE;
+ }
+
+ if (gnc_tree_model_commodity_iter_is_commodity (GNC_TREE_MODEL_COMMODITY(model), iter))
+ {
+ if (fd->user_cm_fn)
+ {
+ commodity = gnc_tree_model_commodity_get_commodity (GNC_TREE_MODEL_COMMODITY(model), iter);
+ return fd->user_cm_fn(commodity, fd->user_data);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Set an GtkTreeModel visible filter on this commodity. This filter will be
+ * called for each commodity that the tree is about to show, and the
+ * commodity will be passed to the callback function.
+ */
+void
+gnc_tree_view_commodity_set_filter (GncTreeViewCommodity *view,
+ gnc_tree_view_commodity_ns_filter_func ns_func,
+ gnc_tree_view_commodity_cm_filter_func cm_func,
+ gpointer data,
+ GDestroyNotify destroy)
+{
+ GtkTreeModel *f_model, *s_model;
+ filter_user_data *fd = data;
+
+ g_return_if_fail(GNC_IS_TREE_VIEW_COMMODITY(view));
+ g_return_if_fail((ns_func != NULL) || (cm_func != NULL));
+
+ ENTER("view %p, ns func %p, cm func %p, data %p, destroy %p",
+ view, ns_func, cm_func, data, destroy);
+
+ fd = g_malloc(sizeof(filter_user_data));
+ fd->user_ns_fn = ns_func;
+ fd->user_cm_fn = cm_func;
+ fd->user_data = data;
+ fd->user_destroy = destroy;
+
+ s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
+ f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (f_model),
+ gnc_tree_view_commodity_filter_helper,
+ fd,
+ gnc_tree_view_commodity_filter_destroy);
+
+ /* Whack any existing levels. The top two levels have been created
+ * before this routine can be called. */
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
+ LEAVE(" ");
+}
+
+/*
+ * Forces the entire commodity tree to be re-evaluated for visibility.
+ */
+void
+gnc_tree_view_commodity_refilter (GncTreeViewCommodity *view)
+{
+ GtkTreeModel *f_model, *s_model;
+
+ g_return_if_fail(GNC_IS_TREE_VIEW_COMMODITY(view));
+
+ ENTER("view %p", view);
+ s_model = gtk_tree_view_get_model (GTK_TREE_VIEW(view));
+ f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
+ LEAVE(" ");
+}
+
+
+/************************************************************/
+/* Commodity Tree View Get/Set Functions */
+/************************************************************/
+
+/*
+ * Retrieve the selected commodity from an commodity tree view. The
+ * commodity tree must be in single selection mode.
+ */
+gnc_commodity *
+gnc_tree_view_commodity_get_selected_commodity (GncTreeViewCommodity *view)
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model, *f_model, *s_model;
+ GtkTreeIter iter, f_iter, s_iter;
+ gnc_commodity *commodity;
+
+ g_return_val_if_fail (GNC_IS_TREE_VIEW_COMMODITY (view), NULL);
+
+ ENTER("view %p", view);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
+ if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter))
+ {
+ LEAVE("no commodity, get_selected failed");
+ return FALSE;
+ }
+
+ gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
+ &f_iter, &s_iter);
+
+ f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
+ &iter, &f_iter);
+
+ model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
+ commodity = gnc_tree_model_commodity_get_commodity (GNC_TREE_MODEL_COMMODITY(model),
+ &iter);
+ LEAVE("commodity %p (%s)", commodity,
+ commodity ? gnc_commodity_get_mnemonic(commodity) : "");
+ return commodity;
+}
+
+
+#if 0 /* Not Used */
+/*
+ * This helper function is called once for each row in the tree view
+ * that is currently selected. Its task is to an the corresponding
+ * commodity to the end of a glist.
+ */
+static void
+get_selected_commodities_helper (GtkTreeModel *s_model,
+ GtkTreePath *s_path,
+ GtkTreeIter *s_iter,
+ gpointer data)
+{
+ GList **return_list = data;
+ GtkTreeModel *model, *f_model;
+ GtkTreeIter iter, f_iter;
+ gnc_commodity *commodity;
+
+ gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
+ &f_iter, s_iter);
+
+ f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
+ gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
+ &iter, &f_iter);
+
+ model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
+ commodity = gnc_tree_model_commodity_get_commodity (GNC_TREE_MODEL_COMMODITY(model),
+ &iter);
+ *return_list = g_list_append(*return_list, commodity);
+}
+#endif /* Not Used */
diff --cc gnucash/gnucash.rc.in
index b2e2776,0000000..bff61e1
mode 100644,000000..100644
--- a/gnucash/gnucash.rc.in
+++ b/gnucash/gnucash.rc.in
@@@ -1,33 -1,0 +1,33 @@@
- #include <windows.h>
-
- APPLICATION_ICON ICON DISCARDABLE "../data/pixmaps/gnucash-icon.ico"
-
- VS_VERSION VERSIONINFO
- FILEVERSION @GNUCASH_MAJOR_VERSION@, at GNUCASH_MINOR_VERSION@, at GNUCASH_MICRO_VERSION@,0
- PRODUCTVERSION @GNUCASH_MAJOR_VERSION@, at GNUCASH_MINOR_VERSION@, at GNUCASH_MICRO_VERSION@,0
- FILEFLAGSMASK 0x3fL
- FILEFLAGS 0x0L
- FILEOS VOS__WINDOWS32
- FILETYPE VFT_APP
- FILESUBTYPE 0x0L
- BEGIN
- BLOCK "StringFileInfo"
- BEGIN
- BLOCK "040904E4"
- BEGIN
- VALUE "CompanyName", "GnuCash Development Team"
- VALUE "FileDescription", "GnuCash Program File"
- VALUE "FileVersion", "@VERSION@"
- VALUE "InternalName", "gnucash"
- VALUE "LegalCopyright", "©2017 GnuCash Development Team, Licence: GPL v2.0 or later"
- VALUE "OriginalFilename", "gnucash.exe"
- VALUE "ProductName", "GnuCash Free Finance Manager"
- VALUE "ProductVersion", "@VERSION@"
- END
- END
-
- BLOCK "VarFileInfo"
- BEGIN
- VALUE "Translation", 0x409, 1252
- END
- END
++#include <windows.h>
++
++APPLICATION_ICON ICON DISCARDABLE "../data/pixmaps/gnucash-icon.ico"
++
++VS_VERSION VERSIONINFO
++ FILEVERSION @GNUCASH_MAJOR_VERSION@, at GNUCASH_MINOR_VERSION@, at GNUCASH_MICRO_VERSION@,0
++ PRODUCTVERSION @GNUCASH_MAJOR_VERSION@, at GNUCASH_MINOR_VERSION@, at GNUCASH_MICRO_VERSION@,0
++ FILEFLAGSMASK 0x3fL
++ FILEFLAGS 0x0L
++ FILEOS VOS__WINDOWS32
++ FILETYPE VFT_APP
++ FILESUBTYPE 0x0L
++BEGIN
++ BLOCK "StringFileInfo"
++ BEGIN
++ BLOCK "040904E4"
++ BEGIN
++ VALUE "CompanyName", "GnuCash Development Team"
++ VALUE "FileDescription", "GnuCash Program File"
++ VALUE "FileVersion", "@VERSION@"
++ VALUE "InternalName", "gnucash"
++ VALUE "LegalCopyright", "©2017 GnuCash Development Team, Licence: GPL v2.0 or later"
++ VALUE "OriginalFilename", "gnucash.exe"
++ VALUE "ProductName", "GnuCash Free Finance Manager"
++ VALUE "ProductVersion", "@VERSION@"
++ END
++ END
++
++ BLOCK "VarFileInfo"
++ BEGIN
++ VALUE "Translation", 0x409, 1252
++ END
++END
diff --cc libgnucash/engine/gnc-commodity.c
index ae37acb,0000000..0978fb8
mode 100644,000000..100644
--- a/libgnucash/engine/gnc-commodity.c
+++ b/libgnucash/engine/gnc-commodity.c
@@@ -1,2629 -1,0 +1,2651 @@@
+/********************************************************************
+ * gnc-commodity.c -- api for tradable commodities (incl. currency) *
+ * Copyright (C) 2000 Bill Gribble *
+ * Copyright (C) 2001,2003 Linas Vepstas <linas at linas.org> *
+ * Copyright (c) 2006 David Hampton <hampton at employees.org> *
+ * *
+ * This program is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of *
+ * the License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact: *
+ * *
+ * Free Software Foundation Voice: +1-617-542-5942 *
+ * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
+ * Boston, MA 02110-1301, USA gnu at gnu.org *
+ * *
+ *******************************************************************/
+
+#include <config.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <ctype.h>
+#include <limits.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <regex.h>
+#include <qofinstance-p.h>
+
+#include "gnc-commodity.h"
+#include "gnc-locale-utils.h"
+#include "gnc-prefs.h"
+
+static QofLogModule log_module = GNC_MOD_COMMODITY;
+
+/* Parts per unit is nominal, i.e. number of 'partname' units in
+ * a 'unitname' unit. fraction is transactional, i.e. how many
+ * of the smallest-transactional-units of the currency are there
+ * in a 'unitname' unit. */
+
+enum
+{
+ PROP_0,
+ PROP_NAMESPACE, /* Table */
+ PROP_FULL_NAME, /* Table */
+ PROP_MNEMONIC, /* Table */
+ PROP_PRINTNAME, /* Constructed */
+ PROP_CUSIP, /* Table */
+ PROP_FRACTION, /* Table */
+ PROP_UNIQUE_NAME, /* Constructed */
+ PROP_QUOTE_FLAG, /* Table */
+ PROP_QUOTE_SOURCE, /* Table */
+ PROP_QUOTE_TZ, /* Table */
+};
+
+struct gnc_commodity_s
+{
+ QofInstance inst;
+};
+
+typedef struct CommodityPrivate
+{
+ gnc_commodity_namespace *name_space;
+
+ char * fullname;
+ char * mnemonic;
+ char * printname;
+ char * cusip; /* CUSIP or other identifying code */
+ int fraction;
+ char * unique_name;
+
+ gboolean quote_flag; /* user wants price quotes */
+ gnc_quote_source * quote_source; /* current/old source of quotes */
+ char * quote_tz;
+
+ /* the number of accounts using this commodity - this field is not
+ * persisted */
+ int usage_count;
+
+ /* the default display_symbol, set in iso-4217-currencies at start-up */
+ const char * default_symbol;
+} CommodityPrivate;
+
+#define GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((o), GNC_TYPE_COMMODITY, CommodityPrivate))
+
+struct _GncCommodityClass
+{
+ QofInstanceClass parent_class;
+};
+
+static void commodity_free(gnc_commodity * cm);
+static void gnc_commodity_set_default_symbol(gnc_commodity *, const char *);
+
+struct gnc_commodity_namespace_s
+{
+ QofInstance inst;
+
+ gchar * name;
+ gboolean iso4217;
+ GHashTable * cm_table;
+ GList * cm_list;
+};
+
+struct _GncCommodityNamespaceClass
+{
+ QofInstanceClass parent_class;
+};
+
+struct gnc_commodity_table_s
+{
+ GHashTable * ns_table;
+ GList * ns_list;
+};
+
+struct gnc_new_iso_code
+{
+ const char *old_code;
+ const char *new_code;
+} gnc_new_iso_codes[] =
+{
+ {"RUR", "RUB"}, /* Russian Ruble: RUR through 1997-12, RUB from 1998-01 onwards; see bug #393185 */
+ {"PLZ", "PLN"}, /* Polish Zloty */
+ {"UAG", "UAH"}, /* Ukraine Hryvnia */
+ {"NIS", "ILS"}, /* New Israeli Shekel: The informal abbreviation may be "NIS", but
+ its iso-4217 is clearly ILS and only this! Incorrectly changed
+ due to bug#152755 (Nov 2004) and changed back again by bug#492417
+ (Oct 2008). */
+ {"MXP", "MXN"}, /* Mexican (Nuevo) Peso */
+ {"TRL", "TRY"}, /* New Turkish Lira: changed 2005 */
+
+ /* Only add currencies to this table when the old currency no longer
+ * exists in the file iso-4217-currencies.scm */
+};
+#define GNC_NEW_ISO_CODES \
+ (sizeof(gnc_new_iso_codes) / sizeof(struct gnc_new_iso_code))
+
+static char *fq_version = NULL;
+
+struct gnc_quote_source_s
+{
+ gboolean supported;
+ QuoteSourceType type;
+ gint index;
- char *user_name; /* User friendly name */
++ char *user_name; /* User friendly name incl. region code*/
+ char *old_internal_name; /* Name used internally (deprecated) */
- char *internal_name; /* Name used internally and by finance::quote. */
++ char *internal_name; /* Name used internally and by finance::quote. */
+};
+
++/* To update the following lists search the FQ modules for their 'method's
++ * because most of them have more than one.
++ */
+static gnc_quote_source currency_quote_source =
+{ TRUE, 0, 0, "Currency", "CURRENCY", "currency" };
+
+static gnc_quote_source single_quote_sources[] =
+{
- { FALSE, 0, 0, "Alphavantage USA", "ALPHAVANTAGE", "alphavantage" },
++ { FALSE, 0, 0, "Alphavantage, US", "ALPHAVANTAGE", "alphavantage" },
+ { FALSE, 0, 0, "Amsterdam Euronext eXchange, NL", "AEX", "aex" },
+ { FALSE, 0, 0, "American International Assurance, HK", "AIAHK", "aiahk" },
- { FALSE, 0, 0, "Association of Mutual Funds in India", "AMFIINDIA", "amfiindia" },
++ { FALSE, 0, 0, "Association of Mutual Funds in India", "AMFIINDIA", "amfiindia" },
+ { FALSE, 0, 0, "Athens Stock Exchange, GR", "ASEGR", "asegr" },
+ { FALSE, 0, 0, "Australian Stock Exchange, AU", "ASX", "asx" },
+ { FALSE, 0, 0, "BAMOSZ funds, HU", "BAMOSZ", "bamosz" },
+ { FALSE, 0, 0, "BMO NesbittBurns, CA", "BMONESBITTBURNS", "bmonesbittburns" },
+ { FALSE, 0, 0, "Bucharest Stock Exchange, RO", "BSERO", "bsero" },
+ { FALSE, 0, 0, "Budapest Stock Exchange (BET), ex-BUX, HU", "BSE", "bse" },
+ { FALSE, 0, 0, "Canada Mutual", "CANADAMUTUAL", "canadamutual" },
+ { FALSE, 0, 0, "Citywire Funds, GB", "citywire", "citywire" },
+ { FALSE, 0, 0, "Colombo Stock Exchange, LK", "CSE", "cse" },
+ { FALSE, 0, 0, "Cominvest, ex-Adig, DE", "COMINVEST", "cominvest" },
+ { FALSE, 0, 0, "Deka Investments, DE", "DEKA", "deka" },
+ { FALSE, 0, 0, "Dutch", "DUTCH", "dutch" },
+ { FALSE, 0, 0, "DWS, DE", "DWS", "dwsfunds" },
+ { FALSE, 0, 0, "Equinox Unit Trusts, ZA", "ZA_unittrusts", "za_unittrusts" },
- { FALSE, 0, 0, "Fidelity", "FIDELITY", "fidelity" },
+ { FALSE, 0, 0, "Fidelity Direct", "FIDELITY_DIRECT", "fidelity_direct" },
++ { FALSE, 0, 0, "Fidelity Fixed", "FIDELITY_DIRECT", "fidelityfixed" },
+ { FALSE, 0, 0, "Finance Canada", "FINANCECANADA", "financecanada" },
+ { FALSE, 0, 0, "Financial Times Funds service, GB", "FTFUNDS", "ftfunds" },
+ { FALSE, 0, 0, "Finanzpartner, DE", "FINANZPARTNER", "finanzpartner" },
+ { FALSE, 0, 0, "First Trust Portfolios, US", "FTPORTFOLIOS", "ftportfolios" },
+ { FALSE, 0, 0, "Fund Library, CA", "FUNDLIBRARY", "fundlibrary" },
+ { FALSE, 0, 0, "GoldMoney spot rates, JE", "GOLDMONEY", "goldmoney" },
+ { FALSE, 0, 0, "Greece", "GREECE", "greece" },
+ { FALSE, 0, 0, "Helsinki stock eXchange, FI", "HEX", "hex" },
+ { FALSE, 0, 0, "Hungary", "HU", "hu" },
+ { FALSE, 0, 0, "India Mutual", "INDIAMUTUAL", "indiamutual" },
+ { FALSE, 0, 0, "Man Investments, AU", "maninv", "maninv" },
+ { FALSE, 0, 0, "Morningstar, GB", "MSTARUK", "mstaruk" },
+ { FALSE, 0, 0, "Morningstar, JP", "MORNINGSTARJP", "morningstarjp" },
+ { FALSE, 0, 0, "Morningstar, SE", "MORNINGSTAR", "morningstar" },
+ { FALSE, 0, 0, "Motley Fool, US", "FOOL", "fool" },
+ { FALSE, 0, 0, "New Zealand stock eXchange, NZ", "NZX", "nzx" },
+ { FALSE, 0, 0, "Paris Stock Exchange/Boursorama, FR", "BOURSO", "bourso" },
+ { FALSE, 0, 0, "Paris Stock Exchange/LeRevenu, FR", "LEREVENU", "lerevenu" },
+ { FALSE, 0, 0, "Platinum Asset Management, AU", "PLATINUM", "platinum" },
+ { FALSE, 0, 0, "Romania", "romania", "romania" },
+ { FALSE, 0, 0, "SIX Swiss Exchange funds, CH", "SIXFUNDS", "sixfunds" },
+ { FALSE, 0, 0, "SIX Swiss Exchange shares, CH", "SIXSHARES", "sixshares" },
+ { FALSE, 0, 0, "Skandinaviska Enskilda Banken, SE", "SEB_FUNDS", "seb_funds" },
+ { FALSE, 0, 0, "Sharenet, ZA", "ZA", "za" },
+ { FALSE, 0, 0, "StockHouse Canada", "STOCKHOUSE_FUND", "stockhousecanada_fund" },
- { FALSE, 0, 0, "TD Waterhouse Canada", "TDWATERHOUSE", "tdwaterhouse" },
++ { FALSE, 0, 0, "TD Waterhouse Funds, CA", "TDWATERHOUSE", "tdwaterhouse" },
+ { FALSE, 0, 0, "TD Efunds, CA", "TDEFUNDS", "tdefunds" },
+ { FALSE, 0, 0, "TIAA-CREF, US", "TIAACREF", "tiaacref" },
+ { FALSE, 0, 0, "Toronto Stock eXchange, CA", "TSX", "tsx" },
+ { FALSE, 0, 0, "T. Rowe Price", "TRPRICE", "troweprice" },
+ { FALSE, 0, 0, "T. Rowe Price, US", "TRPRICE_DIRECT", "troweprice_direct" },
+ { FALSE, 0, 0, "Trustnet via tnetuk.pm, GB", "TNETUK", "tnetuk" },
+ { FALSE, 0, 0, "Trustnet via trustnet.pm, GB", "TRUSTNET", "trustnet" },
+ { FALSE, 0, 0, "U.K. Unit Trusts", "UKUNITTRUSTS", "uk_unit_trusts" },
+ { FALSE, 0, 0, "Union Investment, DE", "UNIONFUNDS", "unionfunds" },
+ { FALSE, 0, 0, "US Treasury Bonds", "usfedbonds", "usfedbonds" },
+ { FALSE, 0, 0, "US Govt. Thrift Savings Plan", "TSP", "tsp" },
- { FALSE, 0, 0, "Vanguard", "VANGUARD", "vanguard" }, /* No module seen in F::Q 1.17. */
++ { FALSE, 0, 0, "Vanguard", "VANGUARD", "vanguard" }, /* Method of Alphavantage */
+ { FALSE, 0, 0, "VWD, DE (unmaintained)", "VWD", "vwd" },
+ { FALSE, 0, 0, "Yahoo as JSON", "YAHOO_JSON", "yahoo_json" },
++ { FALSE, 0, 0, "Yahoo as YQL", "YAHOO_YQL", "yahoo_yql" },
+};
+static gnc_quote_source multiple_quote_sources[] =
+{
- { FALSE, 0, 0, "Europe (Athens, Boursorama, Bucharest)", "EUROPE", "europe" },
- { FALSE, 0, 0, "France (Boursorama, LeRevenue)", "FRANCE", "france" },
++ { FALSE, 0, 0, "Australia (ASX, ...)", "AUSTRALIA", "australia" },
++ { FALSE, 0, 0, "Canada (Alphavantage, TSX, ...)", "CANADA", "canada" },
++ { FALSE, 0, 0, "Canada Mutual (Fund Library, StockHouse, ...)", "CANADAMUTUAL", "canadamutual" },
++ { FALSE, 0, 0, "Dutch (AEX, ...)", "DUTCH", "dutch" },
++ { FALSE, 0, 0, "Europe (asegr,.bsero, hex ...)", "EUROPE", "europe" },
++ { FALSE, 0, 0, "Greece (ASE, ...)", "GREECE", "greece" },
++ { FALSE, 0, 0, "Hungary (Bamosz, BET, ...)", "HU", "hu" },
++ { FALSE, 0, 0, "India Mutual (AMFI, ...)", "INDIAMUTUAL", "indiamutual" },
++ { FALSE, 0, 0, "Fidelity (Fidelity, ...)", "FIDELITY", "fidelity" },
++ { FALSE, 0, 0, "Finland (HEX, ...)", "FINLAND", "finland" },
++ { FALSE, 0, 0, "First Trust (First Trust, ...)", "FTPORTFOLIOS", "ftportfolios" },
++ { FALSE, 0, 0, "France (bourso, ĺerevenu, ...)", "FRANCE", "france" },
++ { FALSE, 0, 0, "Nasdaq (alphavantage, fool, ...)", "NASDAQ", "nasdaq" },
++ { FALSE, 0, 0, "New Zealand (NZX, ...)", "NZ", "nz" },
++ { FALSE, 0, 0, "NYSE (alphavantage, fool, ...)", "NYSE", "nyse" },
++ { FALSE, 0, 0, "South Africa (Sharenet, ...)", "ZA", "za" },
++ { FALSE, 0, 0, "Romania (BSE-RO, ...)", "romania", "romania" },
++ { FALSE, 0, 0, "T. Rowe Price", "TRPRICE", "troweprice" },
+ { FALSE, 0, 0, "U.K. Funds (citywire, FTfunds, MStar, tnetuk, ...)", "ukfunds", "ukfunds" },
++ { FALSE, 0, 0, "U.K. Unit Trusts (trustnet, ...)", "UKUNITTRUSTS", "uk_unit_trusts" },
++ { FALSE, 0, 0, "USA (Alphavantage, Fool, ...)", "USA", "usa" },
+};
+
+static const int num_single_quote_sources =
+ sizeof(single_quote_sources) / sizeof(gnc_quote_source);
+static const int num_multiple_quote_sources =
+ sizeof(multiple_quote_sources) / sizeof(gnc_quote_source);
+static GList *new_quote_sources = NULL;
+
+
+/********************************************************************
+ * gnc_quote_source_fq_installed
+ *
+ * This function indicates whether or not the Finance::Quote module
+ * is installed on a users computer.
+ ********************************************************************/
+gboolean
+gnc_quote_source_fq_installed (void)
+{
+ return (fq_version != NULL);
+}
+
+
+/********************************************************************
+ * gnc_quote_source_fq_version
+ *
+ * This function the version of the Finance::Quote module installed
+ * on a user's computer or NULL if no installation is found.
+ ********************************************************************/
+const char*
+gnc_quote_source_fq_version (void)
+{
+ return fq_version;
+}
+
+/********************************************************************
+ * gnc_quote_source_num_entries
+ *
+ * Return the number of entries for a given type of price source.
+ ********************************************************************/
+gint gnc_quote_source_num_entries(QuoteSourceType type)
+{
+ if (type == SOURCE_CURRENCY)
+ return 1;
+
+ if (type == SOURCE_SINGLE)
+ return num_single_quote_sources;
+
+ if (type == SOURCE_MULTI)
+ return num_multiple_quote_sources;
+
+ return g_list_length(new_quote_sources);
+}
+
+/********************************************************************
+ * gnc_quote_source_init_tables
+ *
+ * Update the type/index values for prices sources.
+ ********************************************************************/
+static void
+gnc_quote_source_init_tables (void)
+{
+ gint i;
+
+ for (i = 0; i < num_single_quote_sources; i++)
+ {
+ single_quote_sources[i].type = SOURCE_SINGLE;
+ single_quote_sources[i].index = i;
+ }
+
+ for (i = 0; i < num_multiple_quote_sources; i++)
+ {
+ multiple_quote_sources[i].type = SOURCE_MULTI;
+ multiple_quote_sources[i].index = i;
+ }
+
+ currency_quote_source.type = SOURCE_CURRENCY;
+ currency_quote_source.index = 0;
+}
+
+
+/********************************************************************
+ * gnc_quote_source_add_new
+ *
+ * Add a new price source. Called when unknown source names are found
+ * either in the F::Q installation (a newly available source) or in
+ * the user's data file (a source that has vanished but needs to be
+ * tracked.)
+ ********************************************************************/
+gnc_quote_source *
+gnc_quote_source_add_new (const char *source_name, gboolean supported)
+{
+ gnc_quote_source *new_source;
+
+ DEBUG("Creating new source %s", (source_name == NULL ? "(null)" : source_name));
+ new_source = malloc(sizeof(gnc_quote_source));
+ new_source->supported = supported;
+ new_source->type = SOURCE_UNKNOWN;
+ new_source->index = g_list_length(new_quote_sources);
+
+ /* This name can be changed if/when support for this price source is
+ * integrated into gnucash. */
+ new_source->user_name = g_strdup(source_name);
+
+ /* This name is permanent and must be kept the same if/when support
+ * for this price source is integrated into gnucash (i.e. for a
+ * nice user name). */
+ new_source->old_internal_name = g_strdup(source_name);
+ new_source->internal_name = g_strdup(source_name);
+ new_quote_sources = g_list_append(new_quote_sources, new_source);
+ return new_source;
+}
+
+/********************************************************************
+ * gnc_quote_source_lookup_by_xxx
+ *
+ * Lookup a price source data structure based upon various criteria.
+ ********************************************************************/
+gnc_quote_source *
+gnc_quote_source_lookup_by_ti (QuoteSourceType type, gint index)
+{
+ gnc_quote_source *source;
+ GList *node;
+
+ ENTER("type/index is %d/%d", type, index);
+ switch (type)
+ {
+ case SOURCE_CURRENCY:
+ LEAVE("found %s", currency_quote_source.user_name);
+ return ¤cy_quote_source;
+ break;
+
+ case SOURCE_SINGLE:
+ if (index < num_single_quote_sources)
+ {
+ LEAVE("found %s", single_quote_sources[index].user_name);
+ return &single_quote_sources[index];
+ }
+ break;
+
+ case SOURCE_MULTI:
+ if (index < num_multiple_quote_sources)
+ {
+ LEAVE("found %s", multiple_quote_sources[index].user_name);
+ return &multiple_quote_sources[index];
+ }
+ break;
+
+ case SOURCE_UNKNOWN:
+ default:
+ node = g_list_nth(new_quote_sources, index);
+ if (node)
+ {
+ source = node->data;
+ LEAVE("found %s", source->user_name);
+ return source;
+ }
+ break;
+ }
+
+ LEAVE("not found");
+ return NULL;
+}
+
+gnc_quote_source *
+gnc_quote_source_lookup_by_internal(const char * name)
+{
+ gnc_quote_source *source;
+ GList *node;
+ gint i;
+
+ if ((name == NULL) || (g_strcmp0(name, "") == 0))
+ {
+ return NULL;
+ }
+
+ if (g_strcmp0(name, currency_quote_source.internal_name) == 0)
+ return ¤cy_quote_source;
+ if (g_strcmp0(name, currency_quote_source.old_internal_name) == 0)
+ return ¤cy_quote_source;
+
+ for (i = 0; i < num_single_quote_sources; i++)
+ {
+ if (g_strcmp0(name, single_quote_sources[i].internal_name) == 0)
+ return &single_quote_sources[i];
+ if (g_strcmp0(name, single_quote_sources[i].old_internal_name) == 0)
+ return &single_quote_sources[i];
+ }
+
+ for (i = 0; i < num_multiple_quote_sources; i++)
+ {
+ if (g_strcmp0(name, multiple_quote_sources[i].internal_name) == 0)
+ return &multiple_quote_sources[i];
+ if (g_strcmp0(name, multiple_quote_sources[i].old_internal_name) == 0)
+ return &multiple_quote_sources[i];
+ }
+
+ for (i = 0, node = new_quote_sources; node; node = node->next, i++)
+ {
+ source = node->data;
+ if (g_strcmp0(name, source->internal_name) == 0)
+ return source;
+ if (g_strcmp0(name, source->old_internal_name) == 0)
+ return source;
+ }
+
+ DEBUG("gnc_quote_source_lookup_by_internal: Unknown source %s", name);
+ return NULL;
+}
+
+/********************************************************************
+ * gnc_quote_source_get_xxx
+ *
+ * Accessor functions - get functions only. There are no set functions.
+ ********************************************************************/
+QuoteSourceType
+gnc_quote_source_get_type (const gnc_quote_source *source)
+{
+ ENTER("%p", source);
+ if (!source)
+ {
+ LEAVE("bad source");
+ return SOURCE_SINGLE;
+ }
+
+ LEAVE("type is %d", source->type);
+ return source->type;
+}
+
+gint
+gnc_quote_source_get_index (const gnc_quote_source *source)
+{
+ ENTER("%p", source);
+ if (!source)
+ {
+ LEAVE("bad source");
+ return 0;
+ }
+
+ LEAVE("index is %d", source->index);
+ return source->index;
+}
+
+gboolean
+gnc_quote_source_get_supported (const gnc_quote_source *source)
+{
+ ENTER("%p", source);
+ if (!source)
+ {
+ LEAVE("bad source");
+ return FALSE;
+ }
+
+ LEAVE("%ssupported", source && source->supported ? "" : "not ");
+ return source->supported;
+}
+
+const char *
+gnc_quote_source_get_user_name (const gnc_quote_source *source)
+{
+ ENTER("%p", source);
+ if (!source)
+ {
+ LEAVE("bad source");
+ return NULL;
+ }
+ LEAVE("user name %s", source->user_name);
+ return source->user_name;
+}
+
+const char *
+gnc_quote_source_get_internal_name (const gnc_quote_source *source)
+{
+ ENTER("%p", source);
+ if (!source)
+ {
+ LEAVE("bad source");
+ return NULL;
+ }
+ LEAVE("internal name %s", source->internal_name);
+ return source->internal_name;
+}
+
+
+/********************************************************************
+ * gnc_quote_source_set_fq_installed
+ *
+ * Update gnucash internal tables on what Finance::Quote sources are
+ * installed.
+ ********************************************************************/
+void
+gnc_quote_source_set_fq_installed (const char* version_string,
+ const GList *sources_list)
+{
+ gnc_quote_source *source;
+ char *source_name;
+ const GList *node;
+
+ ENTER(" ");
+
+ if (!sources_list)
+ return;
+
+ if (fq_version)
+ {
+ g_free (fq_version);
+ fq_version = NULL;
+ }
+
+ if (version_string)
+ fq_version = g_strdup (version_string);
+
+ for (node = sources_list; node; node = node->next)
+ {
+ source_name = node->data;
+
+ source = gnc_quote_source_lookup_by_internal(source_name);
+ if (source != NULL)
+ {
+ DEBUG("Found source %s: %s", source_name, source->user_name);
+ source->supported = TRUE;
+ continue;
+ }
+
+ gnc_quote_source_add_new(source_name, TRUE);
+ }
+ LEAVE(" ");
+}
+
+/********************************************************************
+ * QoF Helpers
+ ********************************************************************/
+
+void
+gnc_commodity_begin_edit (gnc_commodity *cm)
+{
+ qof_begin_edit(&cm->inst);
+}
+
+static void commit_err (QofInstance *inst, QofBackendError errcode)
+{
+ PERR ("Failed to commit: %d", errcode);
+ gnc_engine_signal_commit_error( errcode );
+}
+
+static void noop (QofInstance *inst) {}
+
+static void
+comm_free(QofInstance* inst)
+{
+ commodity_free( GNC_COMMODITY(inst) );
+}
+
+void
+gnc_commodity_commit_edit (gnc_commodity *cm)
+{
+ if (!qof_commit_edit (QOF_INSTANCE(cm))) return;
+ qof_commit_edit_part2 (&cm->inst, commit_err, noop, comm_free);
+}
+
+/********************************************************************
+ * gnc_commodity_new
+ ********************************************************************/
+
+static void
+mark_commodity_dirty (gnc_commodity *cm)
+{
+ qof_instance_set_dirty(&cm->inst);
+ qof_event_gen (&cm->inst, QOF_EVENT_MODIFY, NULL);
+}
+
+static void
+reset_printname(CommodityPrivate *priv)
+{
+ g_free(priv->printname);
+ priv->printname = g_strdup_printf("%s (%s)",
+ priv->mnemonic ? priv->mnemonic : "",
+ priv->fullname ? priv->fullname : "");
+}
+
+static void
+reset_unique_name(CommodityPrivate *priv)
+{
+ gnc_commodity_namespace *ns;
+
+ g_free(priv->unique_name);
+ ns = priv->name_space;
+ priv->unique_name = g_strdup_printf("%s::%s",
+ ns ? ns->name : "",
+ priv->mnemonic ? priv->mnemonic : "");
+}
+
+/* GObject Initialization */
+G_DEFINE_TYPE(gnc_commodity, gnc_commodity, QOF_TYPE_INSTANCE);
+
+static void
+gnc_commodity_init(gnc_commodity* com)
+{
+ CommodityPrivate* priv;
+
+ priv = GET_PRIVATE(com);
+
+ priv->name_space = NULL;
+ priv->fullname = CACHE_INSERT("");
+ priv->mnemonic = CACHE_INSERT("");
+ priv->cusip = CACHE_INSERT("");
+ priv->fraction = 10000;
+ priv->quote_flag = 0;
+ priv->quote_source = NULL;
+ priv->quote_tz = CACHE_INSERT("");
+
+ reset_printname(priv);
+ reset_unique_name(priv);
+}
+
+static void
+gnc_commodity_dispose(GObject *comp)
+{
+ G_OBJECT_CLASS(gnc_commodity_parent_class)->dispose(comp);
+}
+
+static void
+gnc_commodity_finalize(GObject* comp)
+{
+ G_OBJECT_CLASS(gnc_commodity_parent_class)->finalize(comp);
+}
+/* Note that g_value_set_object() refs the object, as does
+ * g_object_get(). But g_object_get() only unrefs once when it disgorges
+ * the object, leaving an unbalanced ref, which leaks. So instead of
+ * using g_value_set_object(), use g_value_take_object() which doesn't
+ * ref the object when used in get_property().
+ */
+static void
+gnc_commodity_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ gnc_commodity *commodity;
+ CommodityPrivate* priv;
+
+ g_return_if_fail(GNC_IS_COMMODITY(object));
+
+ commodity = GNC_COMMODITY(object);
+ priv = GET_PRIVATE(commodity);
+ switch (prop_id)
+ {
+ case PROP_NAMESPACE:
+ g_value_take_object(value, priv->name_space);
+ break;
+ case PROP_FULL_NAME:
+ g_value_set_string(value, priv->fullname);
+ break;
+ case PROP_MNEMONIC:
+ g_value_set_string(value, priv->mnemonic);
+ break;
+ case PROP_PRINTNAME:
+ g_value_set_string(value, priv->printname);
+ break;
+ case PROP_CUSIP:
+ g_value_set_string(value, priv->cusip);
+ break;
+ case PROP_FRACTION:
+ g_value_set_int(value, priv->fraction);
+ break;
+ case PROP_UNIQUE_NAME:
+ g_value_set_string(value, priv->unique_name);
+ break;
+ case PROP_QUOTE_FLAG:
+ g_value_set_boolean(value, priv->quote_flag);
+ break;
+ case PROP_QUOTE_SOURCE:
+ g_value_set_pointer(value, priv->quote_source);
+ break;
+ case PROP_QUOTE_TZ:
+ g_value_set_string(value, priv->quote_tz);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gnc_commodity_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ gnc_commodity *commodity;
+
+ g_return_if_fail(GNC_IS_COMMODITY(object));
+
+ commodity = GNC_COMMODITY(object);
+ g_assert (qof_instance_get_editlevel(commodity));
+
+ switch (prop_id)
+ {
+ case PROP_NAMESPACE:
+ gnc_commodity_set_namespace(commodity, g_value_get_object(value));
+ break;
+ case PROP_FULL_NAME:
+ gnc_commodity_set_fullname(commodity, g_value_get_string(value));
+ break;
+ case PROP_MNEMONIC:
+ gnc_commodity_set_mnemonic(commodity, g_value_get_string(value));
+ break;
+ case PROP_CUSIP:
+ gnc_commodity_set_cusip(commodity, g_value_get_string(value));
+ break;
+ case PROP_FRACTION:
+ gnc_commodity_set_fraction(commodity, g_value_get_int(value));
+ break;
+ case PROP_QUOTE_FLAG:
+ gnc_commodity_set_quote_flag(commodity, g_value_get_boolean(value));
+ break;
+ case PROP_QUOTE_SOURCE:
+ gnc_commodity_set_quote_source(commodity, g_value_get_pointer(value));
+ break;
+ case PROP_QUOTE_TZ:
+ gnc_commodity_set_quote_tz(commodity, g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+static void
+gnc_commodity_class_init(struct _GncCommodityClass* klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
+
+ gobject_class->dispose = gnc_commodity_dispose;
+ gobject_class->finalize = gnc_commodity_finalize;
+ gobject_class->set_property = gnc_commodity_set_property;
+ gobject_class->get_property = gnc_commodity_get_property;
+
+ g_type_class_add_private(klass, sizeof(CommodityPrivate));
+
+ g_object_class_install_property(gobject_class,
+ PROP_NAMESPACE,
+ g_param_spec_object ("namespace",
+ "Namespace",
+ "The namespace field denotes the "
+ "namespace for this commodity, either "
+ "a currency or symbol from a quote source.",
+ GNC_TYPE_COMMODITY_NAMESPACE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_class,
+ PROP_FULL_NAME,
+ g_param_spec_string ("fullname",
+ "Full Commodity Name",
+ "The fullname is the official full name of"
+ "the currency.",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_class,
+ PROP_MNEMONIC,
+ g_param_spec_string ("mnemonic",
+ "Commodity Mnemonic",
+ "The mnemonic is the official abbreviated"
+ "designation for the currency.",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_class,
+ PROP_PRINTNAME,
+ g_param_spec_string ("printname",
+ "Commodity Print Name",
+ "Printable form of the commodity name.",
+ NULL,
+ G_PARAM_READABLE));
+ g_object_class_install_property(gobject_class,
+ PROP_CUSIP,
+ g_param_spec_string ("cusip",
+ "Commodity CUSIP Code",
+ "?????",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_class,
+ PROP_FRACTION,
+ g_param_spec_int ("fraction",
+ "Fraction",
+ "The fraction is the number of sub-units that "
+ "the basic commodity can be divided into.",
+ 1,
+ 1000000,
+ 1,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_class,
+ PROP_UNIQUE_NAME,
+ g_param_spec_string ("unique-name",
+ "Commodity Unique Name",
+ "Unique form of the commodity name which combines "
+ "the namespace name and the commodity name.",
+ NULL,
+ G_PARAM_READABLE));
+ g_object_class_install_property(gobject_class,
+ PROP_QUOTE_FLAG,
+ g_param_spec_boolean ("quote_flag",
+ "Quote Flag",
+ "TRUE if prices are to be downloaded for this "
+ "commodity from a quote source.",
+ FALSE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_class,
+ PROP_QUOTE_SOURCE,
+ g_param_spec_pointer("quote-source",
+ "Quote Source",
+ "The quote source from which prices are downloaded.",
+ G_PARAM_READWRITE));
+ g_object_class_install_property(gobject_class,
+ PROP_QUOTE_TZ,
+ g_param_spec_string ("quote-tz",
+ "Commodity Quote Timezone",
+ "?????",
+ NULL,
+ G_PARAM_READWRITE));
+}
+
+gnc_commodity *
+gnc_commodity_new(QofBook *book, const char * fullname,
+ const char * name_space, const char * mnemonic,
+ const char * cusip, int fraction)
+{
+ gnc_commodity * retval = g_object_new(GNC_TYPE_COMMODITY, NULL);
+
+ qof_instance_init_data (&retval->inst, GNC_ID_COMMODITY, book);
+ gnc_commodity_begin_edit(retval);
+
+ if ( name_space != NULL )
+ {
+ /* Prevent setting anything except template in namespace template. */
+ if (g_strcmp0 (name_space, GNC_COMMODITY_NS_TEMPLATE) == 0 &&
+ g_strcmp0 (mnemonic, "template") != 0)
+ {
+ PWARN("Converting commodity %s from namespace template to "
+ "namespace User", mnemonic);
+ name_space = "User";
+ }
+ gnc_commodity_set_namespace(retval, name_space);
+ if (gnc_commodity_namespace_is_iso(name_space))
+ {
+ gnc_commodity_set_quote_source(retval,
+ gnc_quote_source_lookup_by_internal("currency") );
+ }
+ }
+ gnc_commodity_set_fullname(retval, fullname);
+ gnc_commodity_set_mnemonic(retval, mnemonic);
+ gnc_commodity_set_cusip(retval, cusip);
+ gnc_commodity_set_fraction(retval, fraction);
+ mark_commodity_dirty (retval);
+ gnc_commodity_commit_edit(retval);
+
+ qof_event_gen (&retval->inst, QOF_EVENT_CREATE, NULL);
+
+ return retval;
+}
+
+
+/********************************************************************
+ * gnc_commodity_destroy
+ ********************************************************************/
+
+static void
+commodity_free(gnc_commodity * cm)
+{
+ QofBook *book;
+ gnc_commodity_table *table;
+ CommodityPrivate* priv;
+
+ if (!cm) return;
+
+ book = qof_instance_get_book(&cm->inst);
+ table = gnc_commodity_table_get_table(book);
+ gnc_commodity_table_remove(table, cm);
+ priv = GET_PRIVATE(cm);
+
+ qof_event_gen (&cm->inst, QOF_EVENT_DESTROY, NULL);
+
+ /* Set at creation */
+ CACHE_REMOVE (priv->fullname);
+ CACHE_REMOVE (priv->cusip);
+ CACHE_REMOVE (priv->mnemonic);
+ CACHE_REMOVE (priv->quote_tz);
+ priv->name_space = NULL;
+
+ /* Set through accessor functions */
+ priv->quote_source = NULL;
+
+ /* Automatically generated */
+ g_free(priv->printname);
+ priv->printname = NULL;
+
+ g_free(priv->unique_name);
+ priv->unique_name = NULL;
+
+#ifdef ACCOUNTS_CLEANED_UP
+ /* Account objects are not actually cleaned up when a book is closed (in fact
+ * a memory leak), but commodities are, so in currently this warning gets hit
+ * quite frequently. Disable the check until cleaning up of accounts objects
+ * on close is implemented. */
+ if (priv->usage_count != 0)
+ {
+ PWARN("Destroying commodity (%p) with non-zero usage_count (%d).", cm,
+ priv->usage_count);
+ }
+#endif
+
+ /* qof_instance_release (&cm->inst); */
+ g_object_unref(cm);
+}
+
+void
+gnc_commodity_destroy(gnc_commodity * cm)
+{
+ gnc_commodity_begin_edit(cm);
+ qof_instance_set_destroying(cm, TRUE);
+ gnc_commodity_commit_edit(cm);
+}
+
+void
+gnc_commodity_copy(gnc_commodity * dest, const gnc_commodity *src)
+{
+ CommodityPrivate* src_priv = GET_PRIVATE(src);
+ CommodityPrivate* dest_priv = GET_PRIVATE(dest);
+
+ gnc_commodity_set_fullname (dest, src_priv->fullname);
+ gnc_commodity_set_mnemonic (dest, src_priv->mnemonic);
+ dest_priv->name_space = src_priv->name_space;
+ gnc_commodity_set_fraction (dest, src_priv->fraction);
+ gnc_commodity_set_cusip (dest, src_priv->cusip);
+ gnc_commodity_set_quote_flag (dest, src_priv->quote_flag);
+ gnc_commodity_set_quote_source (dest, gnc_commodity_get_quote_source (src));
+ gnc_commodity_set_quote_tz (dest, src_priv->quote_tz);
+ qof_instance_copy_kvp (QOF_INSTANCE (dest), QOF_INSTANCE (src));
+}
+
+gnc_commodity *
+gnc_commodity_clone(const gnc_commodity *src, QofBook *dest_book)
+{
+ CommodityPrivate* src_priv;
+ CommodityPrivate* dest_priv;
+
+ gnc_commodity * dest = g_object_new(GNC_TYPE_COMMODITY, NULL);
+ qof_instance_init_data (&dest->inst, GNC_ID_COMMODITY, dest_book);
+ src_priv = GET_PRIVATE(src);
+ dest_priv = GET_PRIVATE(dest);
+
+ dest_priv->fullname = CACHE_INSERT(src_priv->fullname);
+ dest_priv->mnemonic = CACHE_INSERT(src_priv->mnemonic);
+ dest_priv->cusip = CACHE_INSERT(src_priv->cusip);
+ dest_priv->quote_tz = CACHE_INSERT(src_priv->quote_tz);
+
+ dest_priv->name_space = src_priv->name_space;
+
+ dest_priv->fraction = src_priv->fraction;
+ dest_priv->quote_flag = src_priv->quote_flag;
+
+ gnc_commodity_set_quote_source (dest, gnc_commodity_get_quote_source (src));
+
+ qof_instance_copy_kvp (QOF_INSTANCE (dest), QOF_INSTANCE (src));
+
+ reset_printname(dest_priv);
+ reset_unique_name(dest_priv);
+
+ return dest;
+}
+
+/********************************************************************
+ * gnc_commodity_get_mnemonic
+ ********************************************************************/
+
+const char *
+gnc_commodity_get_mnemonic(const gnc_commodity * cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->mnemonic;
+}
+
+/********************************************************************
+ * gnc_commodity_get_printname
+ ********************************************************************/
+
+const char *
+gnc_commodity_get_printname(const gnc_commodity * cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->printname;
+}
+
+
+/********************************************************************
+ * gnc_commodity_get_namespace
+ ********************************************************************/
+
+const char *
+gnc_commodity_get_namespace(const gnc_commodity * cm)
+{
+ if (!cm) return NULL;
+ return gnc_commodity_namespace_get_name(GET_PRIVATE(cm)->name_space);
+}
+
+gnc_commodity_namespace *
+gnc_commodity_get_namespace_ds(const gnc_commodity * cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->name_space;
+}
+
+/********************************************************************
+ * gnc_commodity_get_fullname
+ ********************************************************************/
+
+const char *
+gnc_commodity_get_fullname(const gnc_commodity * cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->fullname;
+}
+
+
+/********************************************************************
+ * gnc_commodity_get_unique_name
+ ********************************************************************/
+
+const char *
+gnc_commodity_get_unique_name(const gnc_commodity * cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->unique_name;
+}
+
+
+/********************************************************************
+ * gnc_commodity_get_cusip
+ ********************************************************************/
+
+const char *
+gnc_commodity_get_cusip(const gnc_commodity * cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->cusip;
+}
+
+/********************************************************************
+ * gnc_commodity_get_fraction
+ ********************************************************************/
+
+int
+gnc_commodity_get_fraction(const gnc_commodity * cm)
+{
+ if (!cm) return 0;
+ return GET_PRIVATE(cm)->fraction;
+}
+
+/********************************************************************
+ * gnc_commodity_get_auto_quote_control_flag
+ ********************************************************************/
+
+static gboolean
+gnc_commodity_get_auto_quote_control_flag(const gnc_commodity *cm)
+{
+ GValue v = G_VALUE_INIT;
+
+ if (!cm) return FALSE;
+ qof_instance_get_kvp (QOF_INSTANCE (cm), &v, 1, "auto_quote_control");
+ if (G_VALUE_HOLDS_STRING (&v) &&
+ strcmp(g_value_get_string (&v), "false") == 0)
+ return FALSE;
+ return TRUE;
+}
+
+/********************************************************************
+ * gnc_commodity_get_quote_flag
+ ********************************************************************/
+
+gboolean
+gnc_commodity_get_quote_flag(const gnc_commodity *cm)
+{
+ if (!cm) return FALSE;
+ return (GET_PRIVATE(cm)->quote_flag);
+}
+
+/********************************************************************
+ * gnc_commodity_get_quote_source
+ ********************************************************************/
+
+gnc_quote_source*
+gnc_commodity_get_quote_source(const gnc_commodity *cm)
+{
+ CommodityPrivate* priv;
+
+ if (!cm) return NULL;
+ priv = GET_PRIVATE(cm);
+ if (!priv->quote_source && gnc_commodity_is_iso(cm))
+ return ¤cy_quote_source;
+ return priv->quote_source;
+}
+
+gnc_quote_source*
+gnc_commodity_get_default_quote_source(const gnc_commodity *cm)
+{
+ if (cm && gnc_commodity_is_iso(cm))
+ return ¤cy_quote_source;
+ /* Should make this a user option at some point. */
+ return gnc_quote_source_lookup_by_internal("alphavantage");
+}
+
+/********************************************************************
+ * gnc_commodity_get_quote_tz
+ ********************************************************************/
+
+const char*
+gnc_commodity_get_quote_tz(const gnc_commodity *cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->quote_tz;
+}
+
+/********************************************************************
+ * gnc_commodity_get_user_symbol
+ ********************************************************************/
+const char*
+gnc_commodity_get_user_symbol(const gnc_commodity *cm)
+{
+ GValue v = G_VALUE_INIT;
+ if (!cm) return NULL;
+ qof_instance_get_kvp (QOF_INSTANCE(cm), &v, 1, "user_symbol");
+ if (G_VALUE_HOLDS_STRING (&v))
+ return g_value_get_string (&v);
+ return NULL;
+}
+
+/********************************************************************
+ * gnc_commodity_get_default_symbol
+ *******************************************************************/
+const char*
+gnc_commodity_get_default_symbol(const gnc_commodity *cm)
+{
+ if (!cm) return NULL;
+ return GET_PRIVATE(cm)->default_symbol;
+}
+
+/********************************************************************
+ * gnc_commodity_get_nice_symbol
+ *******************************************************************/
+const char*
+gnc_commodity_get_nice_symbol (const gnc_commodity *cm)
+{
+ const char *nice_symbol;
+ struct lconv *lc;
+ if (!cm) return NULL;
+
+ nice_symbol = gnc_commodity_get_user_symbol(cm);
+ if (nice_symbol && *nice_symbol)
+ return nice_symbol;
+
+ lc = gnc_localeconv();
+ nice_symbol = lc->currency_symbol;
+ if (!g_strcmp0(gnc_commodity_get_mnemonic(cm), lc->int_curr_symbol))
+ return nice_symbol;
+
+ nice_symbol = gnc_commodity_get_default_symbol(cm);
+ if (nice_symbol && *nice_symbol)
+ return nice_symbol;
+
+ return gnc_commodity_get_mnemonic(cm);
+}
+
+/********************************************************************
+ * gnc_commodity_set_mnemonic
+ ********************************************************************/
+
+void
+gnc_commodity_set_mnemonic(gnc_commodity * cm, const char * mnemonic)
+{
+ CommodityPrivate* priv;
+
+ if (!cm) return;
+ priv = GET_PRIVATE(cm);
+ if (priv->mnemonic == mnemonic) return;
+
+ gnc_commodity_begin_edit(cm);
+ CACHE_REMOVE (priv->mnemonic);
+ priv->mnemonic = CACHE_INSERT(mnemonic);
+
+ mark_commodity_dirty (cm);
+ reset_printname(priv);
+ reset_unique_name(priv);
+ gnc_commodity_commit_edit(cm);
+}
+
+/********************************************************************
+ * gnc_commodity_set_namespace
+ ********************************************************************/
+
+void
+gnc_commodity_set_namespace(gnc_commodity * cm, const char * name_space)
+{
+ QofBook *book;
+ gnc_commodity_table *table;
+ gnc_commodity_namespace *nsp;
+ CommodityPrivate* priv;
+
+ if (!cm) return;
+ priv = GET_PRIVATE(cm);
+ book = qof_instance_get_book (&cm->inst);
+ table = gnc_commodity_table_get_table(book);
+ nsp = gnc_commodity_table_add_namespace(table, name_space, book);
+ if (priv->name_space == nsp)
+ return;
+
+ gnc_commodity_begin_edit(cm);
+ priv->name_space = nsp;
+ if (nsp->iso4217)
+ priv->quote_source = gnc_quote_source_lookup_by_internal("currency");
+ mark_commodity_dirty(cm);
+ reset_printname(priv);
+ reset_unique_name(priv);
+ gnc_commodity_commit_edit(cm);
+}
+
+/********************************************************************
+ * gnc_commodity_set_fullname
+ ********************************************************************/
+
+void
+gnc_commodity_set_fullname(gnc_commodity * cm, const char * fullname)
+{
+ CommodityPrivate* priv;
+
+ if (!cm) return;
+ priv = GET_PRIVATE(cm);
+ if (priv->fullname == fullname) return;
+
+ CACHE_REMOVE (priv->fullname);
+ priv->fullname = CACHE_INSERT (fullname);
+
+ gnc_commodity_begin_edit(cm);
+ mark_commodity_dirty(cm);
+ reset_printname(priv);
+ gnc_commodity_commit_edit(cm);
+}
+
+/********************************************************************
+ * gnc_commodity_set_cusip
+ ********************************************************************/
+
+void
+gnc_commodity_set_cusip(gnc_commodity * cm,
+ const char * cusip)
+{
+ CommodityPrivate* priv;
+
+ if (!cm) return;
+
+ priv = GET_PRIVATE(cm);
+ if (priv->cusip == cusip) return;
+
+ gnc_commodity_begin_edit(cm);
+ CACHE_REMOVE (priv->cusip);
+ priv->cusip = CACHE_INSERT (cusip);
+ mark_commodity_dirty(cm);
+ gnc_commodity_commit_edit(cm);
+}
+
+/********************************************************************
+ * gnc_commodity_set_fraction
+ ********************************************************************/
+
+void
+gnc_commodity_set_fraction(gnc_commodity * cm, int fraction)
+{
+ if (!cm) return;
+ gnc_commodity_begin_edit(cm);
+ GET_PRIVATE(cm)->fraction = fraction;
+ mark_commodity_dirty(cm);
+ gnc_commodity_commit_edit(cm);
+}
+
+/********************************************************************
+ * gnc_commodity_set_auto_quote_control_flag
+ ********************************************************************/
+
+static void
+gnc_commodity_set_auto_quote_control_flag(gnc_commodity *cm,
+ const gboolean flag)
+{
+ GValue v = G_VALUE_INIT;
+ ENTER ("(cm=%p, flag=%d)", cm, flag);
+
+ if (!cm)
+ {
+ LEAVE("");
+ return;
+ }
+ gnc_commodity_begin_edit(cm);
+ if (flag)
+ qof_instance_set_kvp (QOF_INSTANCE (cm), NULL, 1, "auto_quote_control");
+ else
+ {
+ g_value_init (&v, G_TYPE_STRING);
+ g_value_set_string (&v, "false");
+ qof_instance_set_kvp (QOF_INSTANCE (cm), &v, 1, "auto_quote_control");
+ }
+ mark_commodity_dirty(cm);
+ gnc_commodity_commit_edit(cm);
+ LEAVE("");
+}
+
+/********************************************************************
+ * gnc_commodity_user_set_quote_flag
+ ********************************************************************/
+
+void
+gnc_commodity_user_set_quote_flag(gnc_commodity *cm, const gboolean flag)
+{
+ CommodityPrivate* priv;
+
+ ENTER ("(cm=%p, flag=%d)", cm, flag);
+
+ if (!cm)
+ {
+ LEAVE("");
+ return;
+ }
+
+ priv = GET_PRIVATE(cm);
+ gnc_commodity_begin_edit(cm);
+ gnc_commodity_set_quote_flag(cm, flag);
+ if (gnc_commodity_is_iso(cm))
+ {
+ /* For currencies, disable auto quote control if the quote flag is being
+ * changed from its default value and enable it if the quote flag is being
+ * reset to its default value. The defaults for the quote flag are
+ * disabled if no accounts are using the currency, and true otherwise.
+ * Thus enable auto quote control if flag is FALSE and there are not any
+ * accounts using this currency OR flag is TRUE and there are accounts
+ * using this currency; otherwise disable auto quote control */
+ gnc_commodity_set_auto_quote_control_flag(cm,
+ (!flag && (priv->usage_count == 0)) || (flag && (priv->usage_count != 0)));
+ }
+ gnc_commodity_commit_edit(cm);
+ LEAVE("");
+}
+
+/********************************************************************
+ * gnc_commodity_set_quote_flag
+ ********************************************************************/
+
+void
+gnc_commodity_set_quote_flag(gnc_commodity *cm, const gboolean flag)
+{
+ ENTER ("(cm=%p, flag=%d)", cm, flag);
+
+ if (!cm) return;
+ gnc_commodity_begin_edit(cm);
+ GET_PRIVATE(cm)->quote_flag = flag;
+ mark_commodity_dirty(cm);
+ gnc_commodity_commit_edit(cm);
+ LEAVE(" ");
+}
+
+/********************************************************************
+ * gnc_commodity_set_quote_source
+ ********************************************************************/
+
+void
+gnc_commodity_set_quote_source(gnc_commodity *cm, gnc_quote_source *src)
+{
+ ENTER ("(cm=%p, src=%p(%s))", cm, src, src ? src->internal_name : "unknown");
+
+ if (!cm) return;
+ gnc_commodity_begin_edit(cm);
+ GET_PRIVATE(cm)->quote_source = src;
+ mark_commodity_dirty(cm);
+ gnc_commodity_commit_edit(cm);
+ LEAVE(" ");
+}
+
+/********************************************************************
+ * gnc_commodity_set_quote_tz
+ ********************************************************************/
+
+void
+gnc_commodity_set_quote_tz(gnc_commodity *cm, const char *tz)
+{
+ CommodityPrivate* priv;
+
+ if (!cm) return;
+
+ ENTER ("(cm=%p, tz=%s)", cm, tz ? tz : "(null)");
+
+ priv = GET_PRIVATE(cm);
+
+ if (tz == priv->quote_tz)
+ {
+ LEAVE("Already correct TZ");
+ return;
+ }
+
+ gnc_commodity_begin_edit(cm);
+ CACHE_REMOVE (priv->quote_tz);
+ priv->quote_tz = CACHE_INSERT (tz);
+ mark_commodity_dirty(cm);
+ gnc_commodity_commit_edit(cm);
+ LEAVE(" ");
+}
+
+/********************************************************************
+ * gnc_commodity_set_user_symbol
+ ********************************************************************/
+
+void
+gnc_commodity_set_user_symbol(gnc_commodity * cm, const char * user_symbol)
+{
+ struct lconv *lc;
+ GValue v = G_VALUE_INIT;
+ if (!cm) return;
+
+ ENTER ("(cm=%p, symbol=%s)", cm, user_symbol ? user_symbol : "(null)");
+
+ gnc_commodity_begin_edit(cm);
+
+ lc = gnc_localeconv();
+ if (!user_symbol || !*user_symbol)
+ user_symbol = NULL;
+ else if (!g_strcmp0(lc->int_curr_symbol, gnc_commodity_get_mnemonic(cm)) &&
+ !g_strcmp0(lc->currency_symbol, user_symbol))
+ /* if the user gives the ISO symbol for the locale currency or the
+ * default symbol, actually remove the user symbol */
+ user_symbol = NULL;
+ else if (!g_strcmp0(user_symbol, gnc_commodity_get_default_symbol(cm)))
+ user_symbol = NULL;
+ if (user_symbol)
+ {
+ g_value_init (&v, G_TYPE_STRING);
+ g_value_set_string (&v, user_symbol);
+ qof_instance_set_kvp (QOF_INSTANCE(cm), &v, 1, "user_symbol");
+ }
+ else
+ qof_instance_set_kvp (QOF_INSTANCE(cm), NULL, 1, "user_symbol");
+
+ mark_commodity_dirty(cm);
+ gnc_commodity_commit_edit(cm);
+
+ LEAVE(" ");
+}
+
+/********************************************************************
+ * gnc_commodity_set_default_symbol
+ * Not made visible in gnc-commodity.h, it is only called from
+ * iso-4217-currencies.c at startup.
+ ********************************************************************/
+void
+gnc_commodity_set_default_symbol(gnc_commodity * cm,
+ const char * default_symbol)
+{
+ GET_PRIVATE(cm)->default_symbol = default_symbol;
+}
+
+/********************************************************************
+ * gnc_commodity_increment_usage_count
+ ********************************************************************/
+
+void
+gnc_commodity_increment_usage_count(gnc_commodity *cm)
+{
+ CommodityPrivate* priv;
+
+ ENTER("(cm=%p)", cm);
+
+ if (!cm)
+ {
+ LEAVE("");
+ return;
+ }
+
+ priv = GET_PRIVATE(cm);
+
+ if ((priv->usage_count == 0) && !priv->quote_flag
+ && gnc_commodity_get_auto_quote_control_flag(cm)
+ && gnc_commodity_is_iso(cm))
+ {
+ /* compatibility hack - Gnucash 1.8 gets currency quotes when a
+ non-default currency is assigned to an account. */
+ gnc_commodity_begin_edit(cm);
+ gnc_commodity_set_quote_flag(cm, TRUE);
+ gnc_commodity_set_quote_source(cm,
+ gnc_commodity_get_default_quote_source(cm));
+ gnc_commodity_commit_edit(cm);
+ }
+ priv->usage_count++;
+ LEAVE("(usage_count=%d)", priv->usage_count);
+}
+
+/********************************************************************
+ * gnc_commodity_decrement_usage_count
+ ********************************************************************/
+
+void
+gnc_commodity_decrement_usage_count(gnc_commodity *cm)
+{
+ CommodityPrivate* priv;
+
+ ENTER("(cm=%p)", cm);
+
+ if (!cm)
+ {
+ LEAVE("");
+ return;
+ }
+
+ priv = GET_PRIVATE(cm);
+
+ if (priv->usage_count == 0)
+ {
+ PWARN("usage_count already zero");
+ LEAVE("");
+ return;
+ }
+
+ priv->usage_count--;
+ if ((priv->usage_count == 0) && priv->quote_flag
+ && gnc_commodity_get_auto_quote_control_flag(cm)
+ && gnc_commodity_is_iso(cm))
+ {
+ /* if this is a currency with auto quote control enabled and no more
+ * accounts reference this currency, disable quote retrieval */
+ gnc_commodity_set_quote_flag(cm, FALSE);
+ }
+ LEAVE("(usage_count=%d)", priv->usage_count);
+}
+
+/********************************************************************\
+\********************************************************************/
+
+
+/********************************************************************
+ * gnc_commodity_equiv
+ * are two commodities the same?
+ ********************************************************************/
+
+gboolean
+gnc_commodity_equiv(const gnc_commodity * a, const gnc_commodity * b)
+{
+ CommodityPrivate* priv_a;
+ CommodityPrivate* priv_b;
+
+ if (a == b) return TRUE;
+ if (!a || !b) return FALSE;
+
+ priv_a = GET_PRIVATE(a);
+ priv_b = GET_PRIVATE(b);
+ if (priv_a->name_space != priv_b->name_space) return FALSE;
+ if (g_strcmp0(priv_a->mnemonic, priv_b->mnemonic) != 0) return FALSE;
+ return TRUE;
+}
+
+gboolean
+gnc_commodity_equal(const gnc_commodity * a, const gnc_commodity * b)
+{
+ CommodityPrivate* priv_a;
+ CommodityPrivate* priv_b;
+ gboolean same_book;
+
+ if (a == b) return TRUE;
+
+ if (!a || !b)
+ {
+ DEBUG ("one is NULL");
+ return FALSE;
+ }
+
+ priv_a = GET_PRIVATE(a);
+ priv_b = GET_PRIVATE(b);
+ same_book = qof_instance_get_book(QOF_INSTANCE(a)) == qof_instance_get_book(QOF_INSTANCE(b));
+
+ if ((same_book && priv_a->name_space != priv_b->name_space)
+ || (!same_book && g_strcmp0( gnc_commodity_namespace_get_name(priv_a->name_space),
+ gnc_commodity_namespace_get_name(priv_b->name_space)) != 0))
+ {
+ DEBUG ("namespaces differ: %p(%s) vs %p(%s)",
+ priv_a->name_space, gnc_commodity_namespace_get_name(priv_a->name_space),
+ priv_b->name_space, gnc_commodity_namespace_get_name(priv_b->name_space));
+ return FALSE;
+ }
+
+ if (g_strcmp0(priv_a->mnemonic, priv_b->mnemonic) != 0)
+ {
+ DEBUG ("mnemonics differ: %s vs %s", priv_a->mnemonic, priv_b->mnemonic);
+ return FALSE;
+ }
+
+ if (g_strcmp0(priv_a->fullname, priv_b->fullname) != 0)
+ {
+ DEBUG ("fullnames differ: %s vs %s", priv_a->fullname, priv_b->fullname);
+ return FALSE;
+ }
+
+ if (g_strcmp0(priv_a->cusip, priv_b->cusip) != 0)
+ {
+ DEBUG ("cusips differ: %s vs %s", priv_a->cusip, priv_b->cusip);
+ return FALSE;
+ }
+
+ if (priv_a->fraction != priv_b->fraction)
+ {
+ DEBUG ("fractions differ: %d vs %d", priv_a->fraction, priv_b->fraction);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int gnc_commodity_compare(const gnc_commodity * a, const gnc_commodity * b)
+{
+ if (gnc_commodity_equal(a, b))
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+int gnc_commodity_compare_void(const void * a, const void * b)
+{
+ return gnc_commodity_compare(a, b);
+}
+
+/************************************************************
+ * Namespace functions *
+ ************************************************************/
+const char *
+gnc_commodity_namespace_get_name (const gnc_commodity_namespace *ns)
+{
+ if (ns == NULL)
+ return NULL;
+ return ns->name;
+}
+
+const char *
+gnc_commodity_namespace_get_gui_name (const gnc_commodity_namespace *ns)
+{
+ if (ns == NULL)
+ return NULL;
+ if (g_strcmp0 (ns->name, GNC_COMMODITY_NS_CURRENCY) == 0)
+ return GNC_COMMODITY_NS_ISO_GUI;
+ return ns->name;
+}
+
+GList *
+gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace *name_space)
+{
+ if (!name_space)
+ return NULL;
+
+ return name_space->cm_list;
+}
+
+gboolean
+gnc_commodity_namespace_is_iso(const char *name_space)
+{
+ return ((g_strcmp0(name_space, GNC_COMMODITY_NS_ISO) == 0) ||
+ (g_strcmp0(name_space, GNC_COMMODITY_NS_CURRENCY) == 0));
+}
+
+static const gchar *
+gnc_commodity_table_map_namespace(const char * name_space)
+{
+ if (g_strcmp0(name_space, GNC_COMMODITY_NS_ISO) == 0)
+ return GNC_COMMODITY_NS_CURRENCY;
+ return name_space;
+}
+
+/********************************************************************
+ * gnc_commodity_table_new
+ * make a new commodity table
+ ********************************************************************/
+
+gnc_commodity_table *
+gnc_commodity_table_new(void)
+{
+ gnc_commodity_table * retval = g_new0(gnc_commodity_table, 1);
+ retval->ns_table = g_hash_table_new(&g_str_hash, &g_str_equal);
+ retval->ns_list = NULL;
+ return retval;
+}
+
+/********************************************************************
+ * book anchor functons
+ ********************************************************************/
+
+gnc_commodity_table *
+gnc_commodity_table_get_table(QofBook *book)
+{
+ if (!book) return NULL;
+ return qof_book_get_data (book, GNC_COMMODITY_TABLE);
+}
+
+gnc_commodity *
+gnc_commodity_obtain_twin (const gnc_commodity *from, QofBook *book)
+{
+ gnc_commodity *twin;
+ const char * ucom;
+ gnc_commodity_table * comtbl;
+
+ if (!from) return NULL;
+ comtbl = gnc_commodity_table_get_table (book);
+ if (!comtbl) return NULL;
+
+ ucom = gnc_commodity_get_unique_name (from);
+ twin = gnc_commodity_table_lookup_unique (comtbl, ucom);
+ if (!twin)
+ {
+ twin = gnc_commodity_clone (from, book);
+ twin = gnc_commodity_table_insert (comtbl, twin);
+ }
+ return twin;
+}
+
+/********************************************************************
+ * gnc_commodity_table_get_size
+ * get the size of the commodity table
+ ********************************************************************/
+
+static void
+count_coms(gpointer key, gpointer value, gpointer user_data)
+{
+ GHashTable *tbl = ((gnc_commodity_namespace*)value)->cm_table;
+ guint *count = (guint*)user_data;
+
+ if (g_strcmp0((char*)key, GNC_COMMODITY_NS_CURRENCY) == 0)
+ {
+ /* don't count default commodities */
+ return;
+ }
+
+ if (!value) return;
+
+ *count += g_hash_table_size(tbl);
+}
+
+guint
+gnc_commodity_table_get_size(const gnc_commodity_table* tbl)
+{
+ guint count = 0;
+ g_return_val_if_fail(tbl, 0);
+ g_return_val_if_fail(tbl->ns_table, 0);
+
+ g_hash_table_foreach(tbl->ns_table, count_coms, (gpointer)&count);
+
+ return count;
+}
+
+/********************************************************************
+ * gnc_commodity_table_lookup
+ * locate a commodity by namespace and mnemonic.
+ ********************************************************************/
+
+gnc_commodity *
+gnc_commodity_table_lookup(const gnc_commodity_table * table,
+ const char * name_space, const char * mnemonic)
+{
+ gnc_commodity_namespace * nsp = NULL;
+ unsigned int i;
+
+ if (!table || !name_space || !mnemonic) return NULL;
+
+ nsp = gnc_commodity_table_find_namespace(table, name_space);
+
+ if (nsp)
+ {
+ /*
+ * Backward compatibility support for currencies that have
+ * recently changed.
+ */
+ if (nsp->iso4217)
+ {
+ for (i = 0; i < GNC_NEW_ISO_CODES; i++)
+ {
+ if (strcmp(mnemonic, gnc_new_iso_codes[i].old_code) == 0)
+ {
+ mnemonic = gnc_new_iso_codes[i].new_code;
+ break;
+ }
+ }
+ }
+ return g_hash_table_lookup(nsp->cm_table, (gpointer)mnemonic);
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/********************************************************************
+ * gnc_commodity_table_lookup
+ * locate a commodity by unique name.
+ ********************************************************************/
+
+gnc_commodity *
+gnc_commodity_table_lookup_unique(const gnc_commodity_table *table,
+ const char * unique_name)
+{
+ char *name_space;
+ char *mnemonic;
+ gnc_commodity *commodity;
+
+ if (!table || !unique_name) return NULL;
+
+ name_space = g_strdup (unique_name);
+ mnemonic = strstr (name_space, "::");
+ if (!mnemonic)
+ {
+ g_free (name_space);
+ return NULL;
+ }
+
+ *mnemonic = '\0';
+ mnemonic += 2;
+
+ commodity = gnc_commodity_table_lookup (table, name_space, mnemonic);
+
+ g_free (name_space);
+
+ return commodity;
+}
+
+/********************************************************************
+ * gnc_commodity_table_find_full
+ * locate a commodity by namespace and printable name
+ ********************************************************************/
+
+gnc_commodity *
+gnc_commodity_table_find_full(const gnc_commodity_table * table,
+ const char * name_space,
+ const char * fullname)
+{
+ gnc_commodity * retval = NULL;
+ GList * all;
+ GList * iterator;
+
+ if (!fullname || (fullname[0] == '\0'))
+ return NULL;
+
+ all = gnc_commodity_table_get_commodities(table, name_space);
+
+ for (iterator = all; iterator; iterator = iterator->next)
+ {
+ if (!strcmp(fullname,
+ gnc_commodity_get_printname(iterator->data)))
+ {
+ retval = iterator->data;
+ break;
+ }
+ }
+
+ g_list_free (all);
+
+ return retval;
+}
+
+
+/********************************************************************
+ * gnc_commodity_table_insert
+ * add a commodity to the table.
+ ********************************************************************/
+
+gnc_commodity *
+gnc_commodity_table_insert(gnc_commodity_table * table,
+ gnc_commodity * comm)
+{
+ gnc_commodity_namespace * nsp = NULL;
+ gnc_commodity *c;
+ const char *ns_name;
+ CommodityPrivate* priv;
+ QofBook *book;
+
+ if (!table) return NULL;
+ if (!comm) return NULL;
+
+ priv = GET_PRIVATE(comm);
+
+ ENTER ("(table=%p, comm=%p) %s %s", table, comm,
+ (priv->mnemonic == NULL ? "(null)" : priv->mnemonic),
+ (priv->fullname == NULL ? "(null)" : priv->fullname));
+ ns_name = gnc_commodity_namespace_get_name(priv->name_space);
+ c = gnc_commodity_table_lookup (table, ns_name, priv->mnemonic);
+
+ if (c)
+ {
+ if (c == comm)
+ {
+ LEAVE("already in table");
+ return c;
+ }
+
+ /* Backward compatibility support for currencies that have
+ * recently changed. */
+ if (priv->name_space->iso4217)
+ {
+ guint i;
+ for (i = 0; i < GNC_NEW_ISO_CODES; i++)
+ {
+ if (!priv->mnemonic
+ || !strcmp(priv->mnemonic, gnc_new_iso_codes[i].old_code))
+ {
+ gnc_commodity_set_mnemonic(comm, gnc_new_iso_codes[i].new_code);
+ break;
+ }
+ }
+ }
+ gnc_commodity_copy (c, comm);
+ gnc_commodity_destroy (comm);
+ LEAVE("found at %p", c);
+ return c;
+ }
+
+ /* Prevent setting anything except template in namespace template. */
+ if (g_strcmp0 (ns_name, GNC_COMMODITY_NS_TEMPLATE) == 0 &&
+ g_strcmp0 (priv->mnemonic, "template") != 0)
+ {
+ PWARN("Converting commodity %s from namespace template to "
+ "namespace User", priv->mnemonic);
+ gnc_commodity_set_namespace (comm, "User");
+ ns_name = "User";
+ mark_commodity_dirty (comm);
+ }
+
+ book = qof_instance_get_book (&comm->inst);
+ nsp = gnc_commodity_table_add_namespace(table, ns_name, book);
+
+ PINFO ("insert %p %s into nsp=%p %s", priv->mnemonic, priv->mnemonic,
+ nsp->cm_table, nsp->name);
+ g_hash_table_insert(nsp->cm_table,
+ CACHE_INSERT(priv->mnemonic),
+ (gpointer)comm);
+ nsp->cm_list = g_list_append(nsp->cm_list, comm);
+
+ qof_event_gen (&comm->inst, QOF_EVENT_ADD, NULL);
+ LEAVE ("(table=%p, comm=%p)", table, comm);
+ return comm;
+}
+
+/********************************************************************
+ * gnc_commodity_table_remove
+ * remove a commodity from the table.
+ ********************************************************************/
+
+void
+gnc_commodity_table_remove(gnc_commodity_table * table,
+ gnc_commodity * comm)
+{
+ gnc_commodity_namespace * nsp;
+ gnc_commodity *c;
+ CommodityPrivate* priv;
+ const char *ns_name;
+
+ if (!table) return;
+ if (!comm) return;
+
+ priv = GET_PRIVATE(comm);
+ ns_name = gnc_commodity_namespace_get_name(priv->name_space);
+ c = gnc_commodity_table_lookup (table, ns_name, priv->mnemonic);
+ if (c != comm) return;
+
+ qof_event_gen (&comm->inst, QOF_EVENT_REMOVE, NULL);
+
+ nsp = gnc_commodity_table_find_namespace(table, ns_name);
+ if (!nsp) return;
+
+ nsp->cm_list = g_list_remove(nsp->cm_list, comm);
+ g_hash_table_remove (nsp->cm_table, priv->mnemonic);
+ /* XXX minor mem leak, should remove the key as well */
+}
+
+/********************************************************************
+ * gnc_commodity_table_has_namespace
+ * see if the commodities namespace exists. May have zero commodities.
+ ********************************************************************/
+
+int
+gnc_commodity_table_has_namespace(const gnc_commodity_table * table,
+ const char * name_space)
+{
+ gnc_commodity_namespace * nsp = NULL;
+
+ if (!table || !name_space)
+ {
+ return 0;
+ }
+
+ nsp = gnc_commodity_table_find_namespace(table, name_space);
+ if (nsp)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static void
+hash_keys_helper(gpointer key, gpointer value, gpointer data)
+{
+ GList ** l = data;
+ *l = g_list_prepend(*l, key);
+}
+
+static GList *
+g_hash_table_keys(GHashTable * table)
+{
+ GList * l = NULL;
+ g_hash_table_foreach(table, &hash_keys_helper, (gpointer) &l);
+ return l;
+}
+
+static void
+hash_values_helper(gpointer key, gpointer value, gpointer data)
+{
+ GList ** l = data;
+ *l = g_list_prepend(*l, value);
+}
+
+static GList *
+g_hash_table_values(GHashTable * table)
+{
+ GList * l = NULL;
+ g_hash_table_foreach(table, &hash_values_helper, (gpointer) &l);
+ return l;
+}
+
+/********************************************************************
+ * gnc_commodity_table_get_namespaces
+ * see if any commodities in the namespace exist
+ ********************************************************************/
+
+GList *
+gnc_commodity_table_get_namespaces(const gnc_commodity_table * table)
+{
+ if (!table)
+ return NULL;
+
+ return g_hash_table_keys(table->ns_table);
+}
+
+GList *
+gnc_commodity_table_get_namespaces_list(const gnc_commodity_table * table)
+{
+ if (!table)
+ return NULL;
+
+ return table->ns_list;
+}
+
+/* Because gnc_commodity_table_add_namespace maps GNC_COMMODITY_NS_ISO to
+ GNC_COMMODITY_NS_CURRENCY and then sets iso4217 if the namespace is
+ either of these, the net result is that the iso4217 bit is set only
+ for GNC_COMMODITY_NS_CURRENCY. This means that gnc_commodity_is_iso is
+ a subset of gnc_commodity_is_currency. Most callers seem to use
+ gnc_commodity_is_iso. */
+gboolean
+gnc_commodity_is_iso(const gnc_commodity * cm)
+{
+ CommodityPrivate* priv;
+
+ if (!cm) return FALSE;
+
+ priv = GET_PRIVATE(cm);
+ if ( !priv->name_space) return FALSE;
+ return priv->name_space->iso4217;
+}
+
+gboolean
+gnc_commodity_is_currency(const gnc_commodity *cm)
+{
+ const char *ns_name;
+ if (!cm) return FALSE;
+
+ ns_name = gnc_commodity_namespace_get_name(GET_PRIVATE(cm)->name_space);
+ return (!g_strcmp0(ns_name, GNC_COMMODITY_NS_LEGACY) ||
+ !g_strcmp0(ns_name, GNC_COMMODITY_NS_CURRENCY));
+}
+
+/********************************************************************
+ * gnc_commodity_table_get_commodities
+ * list commodities in a given namespace
+ ********************************************************************/
+
+static CommodityList*
+commodity_table_get_all_noncurrency_commodities(const gnc_commodity_table* table)
+{
+ GList *node = NULL, *nslist = gnc_commodity_table_get_namespaces(table);
+ CommodityList *retval = NULL;
+ for (node = nslist; node; node=g_list_next(node))
+ {
+ gnc_commodity_namespace *ns = NULL;
+ if (g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_CURRENCY) == 0
+ || g_strcmp0((char*)(node->data), GNC_COMMODITY_NS_TEMPLATE) == 0)
+ continue;
+ ns = gnc_commodity_table_find_namespace(table, (char*)(node->data));
+ if (!ns)
+ continue;
+ retval = g_list_concat(g_hash_table_values(ns->cm_table), retval);
+ }
+ g_list_free(nslist);
+ return retval;
+}
+
+CommodityList *
+gnc_commodity_table_get_commodities(const gnc_commodity_table * table,
+ const char * name_space)
+{
+ gnc_commodity_namespace * ns = NULL;
+
+ if (!table)
+ return NULL;
+ if (g_strcmp0(name_space, GNC_COMMODITY_NS_NONCURRENCY) == 0)
+ return commodity_table_get_all_noncurrency_commodities(table);
+ ns = gnc_commodity_table_find_namespace(table, name_space);
+ if (!ns)
+ return NULL;
+
+ return g_hash_table_values(ns->cm_table);
+}
+
+/********************************************************************
+ * gnc_commodity_table_get_quotable_commodities
+ * list commodities in a given namespace that get price quotes
+ ********************************************************************/
+
+static void
+get_quotables_helper1(gpointer key, gpointer value, gpointer data)
+{
+ gnc_commodity *comm = value;
+ CommodityPrivate* priv = GET_PRIVATE(comm);
+ GList ** l = data;
+
+ if (!priv->quote_flag ||
+ !priv->quote_source || !priv->quote_source->supported)
+ return;
+ *l = g_list_prepend(*l, value);
+}
+
+static gboolean
+get_quotables_helper2 (gnc_commodity *comm, gpointer data)
+{
+ GList ** l = data;
+ CommodityPrivate* priv = GET_PRIVATE(comm);
+
+ if (!priv->quote_flag ||
+ !priv->quote_source || !priv->quote_source->supported)
+ return TRUE;
+ *l = g_list_prepend(*l, comm);
+ return TRUE;
+}
+
+CommodityList *
+gnc_commodity_table_get_quotable_commodities(const gnc_commodity_table * table)
+{
+ gnc_commodity_namespace * ns = NULL;
+ const char *name_space;
+ GList * nslist, * tmp;
+ GList * l = NULL;
+ regex_t pattern;
+ const char *expression = gnc_prefs_get_namespace_regexp();
+
+ ENTER("table=%p, expression=%s", table, expression);
+ if (!table)
+ return NULL;
+
+ if (expression && *expression)
+ {
+ if (regcomp(&pattern, expression, REG_EXTENDED | REG_ICASE) != 0)
+ {
+ LEAVE("Cannot compile regex");
+ return NULL;
+ }
+
+ nslist = gnc_commodity_table_get_namespaces(table);
+ for (tmp = nslist; tmp; tmp = tmp->next)
+ {
+ name_space = tmp->data;
+ if (regexec(&pattern, name_space, 0, NULL, 0) == 0)
+ {
+ DEBUG("Running list of %s commodities", name_space);
+ ns = gnc_commodity_table_find_namespace(table, name_space);
+ if (ns)
+ {
+ g_hash_table_foreach(ns->cm_table, &get_quotables_helper1, (gpointer) &l);
+ }
+ }
+ }
+ g_list_free(nslist);
+ regfree(&pattern);
+ }
+ else
+ {
+ gnc_commodity_table_foreach_commodity(table, get_quotables_helper2,
+ (gpointer) &l);
+ }
+ LEAVE("list head %p", l);
+ return l;
+}
+
+/********************************************************************
+ * gnc_commodity_table_add_namespace
+ * add an empty namespace if it does not exist
+ ********************************************************************/
+
+/* GObject Initialization */
+QOF_GOBJECT_IMPL(gnc_commodity_namespace, gnc_commodity_namespace, QOF_TYPE_INSTANCE);
+
+static void
+gnc_commodity_namespace_init(gnc_commodity_namespace* ns)
+{
+}
+
+static void
+gnc_commodity_namespace_dispose_real (GObject *nsp)
+{
+}
+
+static void
+gnc_commodity_namespace_finalize_real(GObject* nsp)
+{
+}
+
+gnc_commodity_namespace *
+gnc_commodity_table_add_namespace(gnc_commodity_table * table,
+ const char * name_space,
+ QofBook *book)
+{
+ gnc_commodity_namespace * ns = NULL;
+
+ if (!table) return NULL;
+
+ name_space = gnc_commodity_table_map_namespace(name_space);
+ ns = gnc_commodity_table_find_namespace(table, name_space);
+ if (!ns)
+ {
+ ns = g_object_new(GNC_TYPE_COMMODITY_NAMESPACE, NULL);
+ ns->cm_table = g_hash_table_new(g_str_hash, g_str_equal);
+ ns->name = CACHE_INSERT((gpointer)name_space);
+ ns->iso4217 = gnc_commodity_namespace_is_iso(name_space);
+ qof_instance_init_data (&ns->inst, GNC_ID_COMMODITY_NAMESPACE, book);
+ qof_event_gen (&ns->inst, QOF_EVENT_CREATE, NULL);
+
+ g_hash_table_insert(table->ns_table,
+ (gpointer) ns->name,
+ (gpointer) ns);
+ table->ns_list = g_list_append(table->ns_list, ns);
+ qof_event_gen (&ns->inst, QOF_EVENT_ADD, NULL);
+ }
+ return ns;
+}
+
+
+gnc_commodity_namespace *
+gnc_commodity_table_find_namespace(const gnc_commodity_table * table,
+ const char * name_space)
+{
+ if (!table || !name_space)
+ return NULL;
+
+ name_space = gnc_commodity_table_map_namespace(name_space);
+ return g_hash_table_lookup(table->ns_table, (gpointer)name_space);
+}
+
+
+gnc_commodity *
+gnc_commodity_find_commodity_by_guid(const GncGUID *guid, QofBook *book)
+{
+ QofCollection *col;
+ if (!guid || !book) return NULL;
+ col = qof_book_get_collection (book, GNC_ID_COMMODITY);
+ return (gnc_commodity *) qof_collection_lookup_entity (col, guid);
+}
+
+/********************************************************************
+ * gnc_commodity_table_delete_namespace
+ * delete a namespace
+ ********************************************************************/
+
+static int
+ns_helper(gpointer key, gpointer value, gpointer user_data)
+{
+ gnc_commodity * c = value;
+ gnc_commodity_destroy(c);
+ CACHE_REMOVE(key); /* key is commodity mnemonic */
+ return TRUE;
+}
+
+void
+gnc_commodity_table_delete_namespace(gnc_commodity_table * table,
+ const char * name_space)
+{
+ gnc_commodity_namespace * ns;
+
+ if (!table) return;
+
+ ns = gnc_commodity_table_find_namespace(table, name_space);
+ if (!ns)
+ return;
+
+ qof_event_gen (&ns->inst, QOF_EVENT_REMOVE, NULL);
+ g_hash_table_remove(table->ns_table, name_space);
+ table->ns_list = g_list_remove(table->ns_list, ns);
+
+ g_list_free(ns->cm_list);
+ ns->cm_list = NULL;
+
+ g_hash_table_foreach_remove(ns->cm_table, ns_helper, NULL);
+ g_hash_table_destroy(ns->cm_table);
+ CACHE_REMOVE(ns->name);
+
+ qof_event_gen (&ns->inst, QOF_EVENT_DESTROY, NULL);
+ /* qof_instance_release(&ns->inst); */
+ g_object_unref(ns);
+}
+
+/********************************************************************
+ * gnc_commodity_table_foreach_commodity
+ * call user-defined function once for every commodity in every
+ * namespace
+ ********************************************************************/
+
+typedef struct
+{
+ gboolean ok;
+ gboolean (*func)(gnc_commodity *, gpointer);
+ gpointer user_data;
+} IterData;
+
+static void
+iter_commodity (gpointer key, gpointer value, gpointer user_data)
+{
+ IterData *iter_data = (IterData *) user_data;
+ gnc_commodity *cm = (gnc_commodity *) value;
+
+ if (iter_data->ok)
+ {
+ iter_data->ok = (iter_data->func)(cm, iter_data->user_data);
+ }
+}
+
+static void
+iter_namespace (gpointer key, gpointer value, gpointer user_data)
+{
+ GHashTable *namespace_hash = ((gnc_commodity_namespace *) value)->cm_table;
+ g_hash_table_foreach (namespace_hash, iter_commodity, user_data);
+}
+
+gboolean
+gnc_commodity_table_foreach_commodity (const gnc_commodity_table * tbl,
+ gboolean (*f)(gnc_commodity *, gpointer),
+ gpointer user_data)
+{
+ IterData iter_data;
+
+ if (!tbl || !f) return FALSE;
+
+ iter_data.ok = TRUE;
+ iter_data.func = f;
+ iter_data.user_data = user_data;
+
+ g_hash_table_foreach(tbl->ns_table, iter_namespace, (gpointer)&iter_data);
+
+ return iter_data.ok;
+}
+
+/********************************************************************
+ * gnc_commodity_table_destroy
+ * cleanup and free.
+ ********************************************************************/
+
+void
+gnc_commodity_table_destroy(gnc_commodity_table * t)
+{
+ gnc_commodity_namespace * ns;
+ GList *item, *next;
+
+ if (!t) return;
+ ENTER ("table=%p", t);
+
+ for (item = t->ns_list; item; item = next)
+ {
+ next = g_list_next(item);
+ ns = item->data;
+ gnc_commodity_table_delete_namespace(t, ns->name);
+ }
+
+ g_list_free(t->ns_list);
+ t->ns_list = NULL;
+ g_hash_table_destroy(t->ns_table);
+ t->ns_table = NULL;
+ g_free(t);
+ LEAVE ("table=%p", t);
+}
+
+/* =========================================================== */
+
+/********************************************************************
+ * gnc_commodity_table_add_default_data
+ ********************************************************************/
+
+#define CUR_I18N(String) dgettext ("iso_4217", String)
+
+gboolean
+gnc_commodity_table_add_default_data(gnc_commodity_table *table, QofBook *book)
+{
+ QofCollection *col;
+ gnc_commodity* c;
+
+ ENTER ("table=%p", table);
+ gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_AMEX, book);
+ gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_NYSE, book);
+ gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_NASDAQ, book);
+ gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_EUREX, book);
+ gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_MUTUAL, book);
+ gnc_commodity_table_add_namespace(table, GNC_COMMODITY_NS_TEMPLATE, book);
+ c = gnc_commodity_new(book, "template", GNC_COMMODITY_NS_TEMPLATE, "template", "template", 1);
+ gnc_commodity_table_insert(table, c);
+
+#include "iso-4217-currencies.c"
+
+ /* We've just created the default namespaces and currencies. Mark
+ * these collections as clean because there is no USER entered data
+ * in these collections as of yet. */
+ col = qof_book_get_collection(book, GNC_ID_COMMODITY);
+ qof_collection_mark_clean(col);
+ col = qof_book_get_collection(book, GNC_ID_COMMODITY_NAMESPACE);
+ qof_collection_mark_clean(col);
+
+ LEAVE ("table=%p", table);
+ return TRUE;
+}
+
+/********************************************************************
+ ********************************************************************/
+/* QofObject function implementation and registration */
+
+#ifdef _MSC_VER
+/* MSVC compiler doesn't have C99 "designated initializers"
+ * so we wrap them in a macro that is empty on MSVC. */
+# define DI(x) /* */
+#else
+# define DI(x) x
+#endif
+static QofObject commodity_object_def =
+{
+ DI(.interface_version = ) QOF_OBJECT_VERSION,
+ DI(.e_type = ) GNC_ID_COMMODITY,
+ DI(.type_label = ) "Commodity",
+ DI(.create = ) NULL,
+ DI(.book_begin = ) NULL,
+ DI(.book_end = ) NULL,
+ DI(.is_dirty = ) qof_collection_is_dirty,
+ DI(.mark_clean = ) qof_collection_mark_clean,
+ DI(.foreach = ) qof_collection_foreach,
+ DI(.printable = ) (const char * (*)(gpointer)) gnc_commodity_get_fullname,
+};
+
+static QofObject namespace_object_def =
+{
+ DI(.interface_version = ) QOF_OBJECT_VERSION,
+ DI(.e_type = ) GNC_ID_COMMODITY_NAMESPACE,
+ DI(.type_label = ) "Namespace",
+ DI(.create = ) NULL,
+ DI(.book_begin = ) NULL,
+ DI(.book_end = ) NULL,
+ DI(.is_dirty = ) NULL,
+ DI(.mark_clean = ) NULL,
+ DI(.foreach = ) NULL,
+ DI(.printable = ) NULL,
+};
+
+static void
+commodity_table_book_begin (QofBook *book)
+{
+ gnc_commodity_table *ct;
+ ENTER ("book=%p", book);
+
+ if (gnc_commodity_table_get_table(book))
+ return;
+
+ ct = gnc_commodity_table_new ();
+ qof_book_set_data (book, GNC_COMMODITY_TABLE, ct);
+
+ if (!gnc_commodity_table_add_default_data(ct, book))
+ {
+ PWARN("unable to initialize book's commodity_table");
+ }
+
+ LEAVE ("book=%p", book);
+}
+
+static void
+commodity_table_book_end (QofBook *book)
+{
+ gnc_commodity_table *ct;
+
+ ct = gnc_commodity_table_get_table (book);
+ qof_book_set_data (book, GNC_COMMODITY_TABLE, NULL);
+ gnc_commodity_table_destroy (ct);
+}
+
+static QofObject commodity_table_object_def =
+{
+ DI(.interface_version = ) QOF_OBJECT_VERSION,
+ DI(.e_type = ) GNC_ID_COMMODITY_TABLE,
+ DI(.type_label = ) "CommodityTable",
+ DI(.create = ) NULL,
+ DI(.book_begin = ) commodity_table_book_begin,
+ DI(.book_end = ) commodity_table_book_end,
+ DI(.is_dirty = ) qof_collection_is_dirty,
+ DI(.mark_clean = ) qof_collection_mark_clean,
+ DI(.foreach = ) NULL,
+ DI(.printable = ) NULL,
+ DI(.version_cmp = ) NULL,
+};
+
+gboolean
+gnc_commodity_table_register (void)
+{
+ gnc_quote_source_init_tables();
+
+ if (!qof_object_register (&commodity_object_def))
+ return FALSE;
+ if (!qof_object_register (&namespace_object_def))
+ return FALSE;
+ return qof_object_register (&commodity_table_object_def);
+}
+
+/* *******************************************************************
+* gnc_monetary methods
+********************************************************************/
+
+/** Add a gnc_monetary to the list */
+MonetaryList *
+gnc_monetary_list_add_monetary(MonetaryList *list, gnc_monetary add_mon)
+{
+ MonetaryList *l = list, *tmp;
+ for (tmp = list; tmp; tmp = tmp->next)
+ {
+ gnc_monetary *list_mon = tmp->data;
+ if (gnc_commodity_equiv(list_mon->commodity, add_mon.commodity))
+ {
+ list_mon->value = gnc_numeric_add(list_mon->value, add_mon.value,
+ GNC_DENOM_AUTO, GNC_HOW_DENOM_EXACT);
+ break;
+ }
+ }
+
+ /* See if we found an entry, and add one if not */
+ if (tmp == NULL)
+ {
+ gnc_monetary *new_mon = g_new0(gnc_monetary, 1);
+ *new_mon = add_mon;
+ l = g_list_prepend(l, new_mon);
+ }
+
+ return l;
+}
+
+/** Delete all entries in the list that have zero value. Return list
+ pointer will be a null pointer if there are no non-zero entries **/
+MonetaryList *
+gnc_monetary_list_delete_zeros(MonetaryList *list)
+{
+ MonetaryList *node, *next;
+ for (node = list; node; node = next)
+ {
+ gnc_monetary *mon = node->data;
+ next = node->next;
+ if (gnc_numeric_zero_p(mon->value))
+ {
+ g_free(mon);
+ list = g_list_delete_link(list, node);
+ }
+ }
+ return list;
+}
+
+/** Free a MonetaryList and all the monetaries it points to */
+void
+gnc_monetary_list_free(MonetaryList *list)
+{
+ MonetaryList *tmp;
+ for (tmp = list; tmp; tmp = tmp->next)
+ {
+ g_free(tmp->data);
+ }
+
+ g_list_free(list);
+}
+
+/* ========================= END OF FILE ============================== */
commit d61cd79ae3c8adfc521c3781fb25eb81ec2a1627
Author: fell <frank.h.ellenberger at gmail.com>
Date: Sat Mar 10 10:23:56 2018 +0100
Minor fix in de.po
diff --git a/po/de.po b/po/de.po
index 86b4e16..5e0c77f 100644
--- a/po/de.po
+++ b/po/de.po
@@ -5809,11 +5809,14 @@ msgstr "_Buchabschluss"
msgid "Archive old data using accounting periods"
msgstr "Alte Daten abschlieÃen und in vorigen Buchführungsperioden speichern."
+# Fell: Wie oft muà ich hier noch Editor durch Datenbank ersetzen? S. u.
+# Der Kurs-Editor ist das Fenster, welches danach aufgerufen wird.
+#
#. Translators: This entry opens the Price Database window
#. * and will be renamed to "_Price Database" in v.2.8
#: ../src/gnome/gnc-plugin-basic-commands.c:190
msgid "_Price Editor"
-msgstr "_Kurs-Editor"
+msgstr "_Kurs-Datenbank"
#: ../src/gnome/gnc-plugin-basic-commands.c:191
msgid "View and edit the prices for stocks and mutual funds"
commit df26146d2af3bc40bfc5e3b10f30c3faceb6b501
Author: fell <frank.h.ellenberger at gmail.com>
Date: Sat Mar 10 10:20:26 2018 +0100
Backport and review of commit c0fd3b3:
Remove all references to the now-defunct Yahoo! quote retrieval
diff --git a/doc/gnc-fq-dump.1 b/doc/gnc-fq-dump.1
index 1fd1eab..dc593a5 100644
--- a/doc/gnc-fq-dump.1
+++ b/doc/gnc-fq-dump.1
@@ -134,8 +134,8 @@ gnc\-fq\-dump \- Print out data from the F::Q module
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 5
-\& gnc\-fq\-dump yahoo CSCO JNPR
-\& gnc\-fq\-dump yahoo BAESY.PK
+\& gnc\-fq\-dump alphavantage CSCO JNPR
+\& gnc\-fq\-dump alphavantage BAESY.PK
\& gnc\-fq\-dump europe 48406.PA 13000.PA
\& gnc\-fq\-dump vwd 632034
\& gnc\-fq\-dump ftportfolios FKYGTX
diff --git a/src/backend/dbi/test/test-dbi.xml b/src/backend/dbi/test/test-dbi.xml
index 863ae36..5ea03f5 100644
--- a/src/backend/dbi/test/test-dbi.xml
+++ b/src/backend/dbi/test/test-dbi.xml
@@ -51,7 +51,7 @@
<cmdty:xcode>12345</cmdty:xcode>
<cmdty:fraction>10000</cmdty:fraction>
<cmdty:get_quotes/>
- <cmdty:quote_source>yahoo</cmdty:quote_source>
+ <cmdty:quote_source>alphavantage</cmdty:quote_source>
</gnc:commodity>
<gnc:account version="2.0.0">
<act:name>Root Account</act:name>
diff --git a/src/doc/design/top-level.texi b/src/doc/design/top-level.texi
index 2900092..31406a0 100644
--- a/src/doc/design/top-level.texi
+++ b/src/doc/design/top-level.texi
@@ -116,9 +116,9 @@ Jon Trowbridge (@url{http://www.gnome.org/guppi}).
The @dfn{Price Quotes} module (@file{src/quotes}) is a Perl system to
fetch stock price data off the Internet and insert it into the GnuCash
Engine. This module requires the functionality of the Finance::Quote
-module available at SourceForge. The Finance::Quote module can fetch
-price quotes from many different sources including Yahoo, Yahoo Europe,
-and some international exchanges.
+module available from CPAN. The Finance::Quote module can fetch
+price quotes from many different sources including Alphavantage
+and several international exchanges and fund companies.
The Finance::Quote module also supports fetching currency exchange
rates. GnuCash will be extended to allow the fetching and use of
diff --git a/src/engine/gnc-commodity.c b/src/engine/gnc-commodity.c
index 7993d14..fd66afa 100644
--- a/src/engine/gnc-commodity.c
+++ b/src/engine/gnc-commodity.c
@@ -149,19 +149,23 @@ struct gnc_quote_source_s
gboolean supported;
QuoteSourceType type;
gint index;
- char *user_name; /* User friendly name */
+ char *user_name; /* User friendly name incl. region code*/
char *old_internal_name; /* Name used internally (deprecated) */
- char *internal_name; /* Name used internally and by finance::quote. */
+ char *internal_name; /* Name used internally and by finance::quote. */
};
+/* To update the following lists search the FQ modules for their 'method's
+ * because most of them have more than one.
+ */
static gnc_quote_source currency_quote_source =
{ TRUE, 0, 0, "Currency", "CURRENCY", "currency" };
static gnc_quote_source single_quote_sources[] =
{
+ { FALSE, 0, 0, "Alphavantage, US", "ALPHAVANTAGE", "alphavantage" },
{ FALSE, 0, 0, "Amsterdam Euronext eXchange, NL", "AEX", "aex" },
{ FALSE, 0, 0, "American International Assurance, HK", "AIAHK", "aiahk" },
- { FALSE, 0, 0, "Association of Mutual Funds in India", "AMFIINDIA", "amfiindia" },
+ { FALSE, 0, 0, "Association of Mutual Funds in India", "AMFIINDIA", "amfiindia" },
{ FALSE, 0, 0, "Athens Stock Exchange, GR", "ASEGR", "asegr" },
{ FALSE, 0, 0, "Australian Stock Exchange, AU", "ASX", "asx" },
{ FALSE, 0, 0, "BAMOSZ funds, HU", "BAMOSZ", "bamosz" },
@@ -173,8 +177,9 @@ static gnc_quote_source single_quote_sources[] =
{ FALSE, 0, 0, "Cominvest, ex-Adig, DE", "COMINVEST", "cominvest" },
{ FALSE, 0, 0, "Deka Investments, DE", "DEKA", "deka" },
{ FALSE, 0, 0, "DWS, DE", "DWS", "dwsfunds" },
- { FALSE, 0, 0, "Equinox Unit Trusts, ZA", "ZA_unittrusts", "za_unittrusts" },
+ { FALSE, 0, 0, "Equinox Unit Trusts, ZA", "ZA_unittrusts", "za_unittrusts" },
{ FALSE, 0, 0, "Fidelity Direct", "FIDELITY_DIRECT", "fidelity_direct" },
+ { FALSE, 0, 0, "Fidelity Fixed", "FIDELITY_DIRECT", "fidelityfixed" },
{ FALSE, 0, 0, "Finance Canada", "FINANCECANADA", "financecanada" },
{ FALSE, 0, 0, "Financial Times Funds service, GB", "FTFUNDS", "ftfunds" },
{ FALSE, 0, 0, "Finanzpartner, DE", "FINANZPARTNER", "finanzpartner" },
@@ -196,7 +201,7 @@ static gnc_quote_source single_quote_sources[] =
{ FALSE, 0, 0, "Skandinaviska Enskilda Banken, SE", "SEB_FUNDS", "seb_funds" },
{ FALSE, 0, 0, "Sharenet, ZA", "ZA", "za" },
{ FALSE, 0, 0, "StockHouse Canada", "STOCKHOUSE_FUND", "stockhousecanada_fund" },
- { FALSE, 0, 0, "TD Waterhouse Canada", "TDWATERHOUSE", "tdwaterhouse" },
+ { FALSE, 0, 0, "TD Waterhouse Funds, CA", "TDWATERHOUSE", "tdwaterhouse" },
{ FALSE, 0, 0, "TD Efunds, CA", "TDEFUNDS", "tdefunds" },
{ FALSE, 0, 0, "TIAA-CREF, US", "TIAACREF", "tiaacref" },
{ FALSE, 0, 0, "Toronto Stock eXchange, CA", "TSX", "tsx" },
@@ -206,41 +211,34 @@ static gnc_quote_source single_quote_sources[] =
{ FALSE, 0, 0, "Union Investment, DE", "UNIONFUNDS", "unionfunds" },
{ FALSE, 0, 0, "US Treasury Bonds", "usfedbonds", "usfedbonds" },
{ FALSE, 0, 0, "US Govt. Thrift Savings Plan", "TSP", "tsp" },
- { FALSE, 0, 0, "Vanguard", "VANGUARD", "vanguard" }, /* No module seen in F::Q 1.17. */
+ { FALSE, 0, 0, "Vanguard", "VANGUARD", "vanguard" }, /* Method of Alphavantage */
{ FALSE, 0, 0, "VWD, DE (unmaintained)", "VWD", "vwd" },
- { FALSE, 0, 0, "Yahoo USA", "YAHOO", "yahoo" },
- { FALSE, 0, 0, "Yahoo Asia", "YAHOO_ASIA", "yahoo_asia" },
- { FALSE, 0, 0, "Yahoo Australia", "YAHOO_AUSTRALIA", "yahoo_australia" },
- { FALSE, 0, 0, "Yahoo Brasil", "YAHOO_BRASIL", "yahoo_brasil" },
- { FALSE, 0, 0, "Yahoo Europe", "YAHOO_EUROPE", "yahoo_europe" },
- { FALSE, 0, 0, "Yahoo New Zealand", "YAHOO_NZ", "yahoo_nz" },
{ FALSE, 0, 0, "Yahoo as JSON", "YAHOO_JSON", "yahoo_json" },
+ { FALSE, 0, 0, "Yahoo as YQL", "YAHOO_YQL", "yahoo_yql" },
};
static gnc_quote_source multiple_quote_sources[] =
{
- { FALSE, 0, 0, "Asia (Yahoo, ...)", "ASIA", "asia" },
- { FALSE, 0, 0, "Australia (ASX, Yahoo, ...)", "AUSTRALIA", "australia" },
- { FALSE, 0, 0, "Brasil (Yahoo, ...)", "BRASIL", "brasil" },
- { FALSE, 0, 0, "Canada (Yahoo, ...)", "CANADA", "canada" },
- { FALSE, 0, 0, "Canada Mutual (Fund Library, ...)", "CANADAMUTUAL", "canadamutual" },
+ { FALSE, 0, 0, "Australia (ASX, ...)", "AUSTRALIA", "australia" },
+ { FALSE, 0, 0, "Canada (Alphavantage, TSX, ...)", "CANADA", "canada" },
+ { FALSE, 0, 0, "Canada Mutual (Fund Library, StockHouse, ...)", "CANADAMUTUAL", "canadamutual" },
{ FALSE, 0, 0, "Dutch (AEX, ...)", "DUTCH", "dutch" },
- { FALSE, 0, 0, "Europe (Yahoo, ...)", "EUROPE", "europe" },
+ { FALSE, 0, 0, "Europe (asegr,.bsero, hex ...)", "EUROPE", "europe" },
{ FALSE, 0, 0, "Greece (ASE, ...)", "GREECE", "greece" },
- { FALSE, 0, 0, "Hungary (Bamosz, BET)", "HU", "hu" },
+ { FALSE, 0, 0, "Hungary (Bamosz, BET, ...)", "HU", "hu" },
{ FALSE, 0, 0, "India Mutual (AMFI, ...)", "INDIAMUTUAL", "indiamutual" },
{ FALSE, 0, 0, "Fidelity (Fidelity, ...)", "FIDELITY", "fidelity" },
{ FALSE, 0, 0, "Finland (HEX, ...)", "FINLAND", "finland" },
{ FALSE, 0, 0, "First Trust (First Trust, ...)", "FTPORTFOLIOS", "ftportfolios" },
- { FALSE, 0, 0, "France (Boursorama, ...)", "FRANCE", "france" },
- { FALSE, 0, 0, "Nasdaq (Yahoo, ...)", "NASDAQ", "nasdaq" },
- { FALSE, 0, 0, "New Zealand (Yahoo, ...)", "NZ", "nz" },
- { FALSE, 0, 0, "NYSE (Yahoo, ...)", "NYSE", "nyse" },
- /* { FALSE, 0, 0, "South Africa (Sharenet, ...)", "ZA", "za" }, */
+ { FALSE, 0, 0, "France (bourso, ĺerevenu, ...)", "FRANCE", "france" },
+ { FALSE, 0, 0, "Nasdaq (alphavantage, fool, ...)", "NASDAQ", "nasdaq" },
+ { FALSE, 0, 0, "New Zealand (NZX, ...)", "NZ", "nz" },
+ { FALSE, 0, 0, "NYSE (alphavantage, fool, ...)", "NYSE", "nyse" },
+ { FALSE, 0, 0, "South Africa (Sharenet, ...)", "ZA", "za" },
{ FALSE, 0, 0, "Romania (BSE-RO, ...)", "romania", "romania" },
{ FALSE, 0, 0, "T. Rowe Price", "TRPRICE", "troweprice" },
{ FALSE, 0, 0, "U.K. Funds (citywire, FTfunds, MStar, tnetuk, ...)", "ukfunds", "ukfunds" },
{ FALSE, 0, 0, "U.K. Unit Trusts (trustnet, ...)", "UKUNITTRUSTS", "uk_unit_trusts" },
- { FALSE, 0, 0, "USA (Yahoo, Fool, ...)", "USA", "usa" },
+ { FALSE, 0, 0, "USA (Alphavantage, Fool, ...)", "USA", "usa" },
};
static const int num_single_quote_sources =
@@ -1160,7 +1158,7 @@ gnc_commodity_get_default_quote_source(const gnc_commodity *cm)
if (cm && gnc_commodity_is_iso(cm))
return ¤cy_quote_source;
/* Should make this a user option at some point. */
- return gnc_quote_source_lookup_by_internal("yahoo");
+ return gnc_quote_source_lookup_by_internal("alphavantage");
}
/********************************************************************
diff --git a/src/gnome-utils/gnc-tree-view-commodity.c b/src/gnome-utils/gnc-tree-view-commodity.c
index a6d6f6c..0db663e 100644
--- a/src/gnome-utils/gnc-tree-view-commodity.c
+++ b/src/gnome-utils/gnc-tree-view-commodity.c
@@ -418,7 +418,7 @@ gnc_tree_view_commodity_new (QofBook *book,
col = gnc_tree_view_add_text_column (
/* Translators: Again replace CUSIP by the name of your
National Securities Identifying Number. */
- view, _("ISIN/CUSIP"), "cusip_code", NULL, "QWERTYUIOP",
+ view, _("ISIN/CUSIP"), "cusip_code", NULL, "US1234567890",
GNC_TREE_MODEL_COMMODITY_COL_CUSIP,
GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
sort_by_commodity_string);
@@ -440,7 +440,7 @@ gnc_tree_view_commodity_new (QofBook *book,
sort_by_quote_flag,
NULL);
col = gnc_tree_view_add_text_column (
- view, _("Source"), "quote_source", NULL, "yahoo",
+ view, _("Source"), "quote_source", NULL, "alphavantage",
GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE,
GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
sort_by_commodity_string);
diff --git a/src/quotes/Quote_example.pl b/src/quotes/Quote_example.pl
index 82192e0..220ee27 100755
--- a/src/quotes/Quote_example.pl
+++ b/src/quotes/Quote_example.pl
@@ -22,12 +22,12 @@ my $quoter = Finance::Quote->new();
# -----------------------------------
# get quotes for two stocks ...
-%quotes = $quoter->fetch("yahoo","IBM", "SGI");
+%quotes = $quoter->fetch("alphavantage","IBM", "SGI");
# print some selected values
-print "NYSE by Yahoo: ", $quotes {"IBM", "name"},
+print "NYSE by Alphavantage: ", $quotes {"IBM", "name"},
" last price: ", $quotes {"IBM", "last"}, "\n";
-print "NYSE by Yahoo: ", $quotes {"SGI", "name"},
+print "NYSE by Alphavantage: ", $quotes {"SGI", "name"},
" last price: ", $quotes {"SGI", "last"}, "\n";
# loop over and print all values.
diff --git a/src/quotes/gnc-fq-dump b/src/quotes/gnc-fq-dump
index 4203436..935647c 100755
--- a/src/quotes/gnc-fq-dump
+++ b/src/quotes/gnc-fq-dump
@@ -191,8 +191,8 @@ gnc-fq-dump - Print out data from the F::Q module
=head1 SYNOPSIS
- gnc-fq-dump yahoo CSCO JNPR
- gnc-fq-dump yahoo BAESY.PK
+ gnc-fq-dump alphavantage CSCO JNPR
+ gnc-fq-dump alphavantage BAESY.PK
gnc-fq-dump europe 48406.PA 13000.PA
gnc-fq-dump vwd 632034
gnc-fq-dump ftportfolios FKYGTX
diff --git a/src/quotes/gnc-fq-helper.in b/src/quotes/gnc-fq-helper.in
index 86ba14d..6111ab6 100755
--- a/src/quotes/gnc-fq-helper.in
+++ b/src/quotes/gnc-fq-helper.in
@@ -48,16 +48,14 @@ side :>).
(<method-name> symbol symbol symbol ...)
where <method-name> indicates the desired Finance::Quote method.
-The currently recognized subset is yahoo, yahoo_europe,
-fidelity_direct, troweprice_direct, vanguard, asx, tiaacref,
-and currency.
+One can list the many methods by running gnc-fq-check.
For currency quotes, the symbols alternate between the 'from'
and 'to' currencies.
For example:
-(yahoo "IBM" "LNUX")
+(alphavantage "IBM" "LNUX")
(fidelity_direct "FBIOX" "FSELX")
(currency "USD" "AUD")
@@ -78,7 +76,7 @@ need to convert it to that.
For example:
- $ echo '(yahoo "CSCO" "JDSU" "^IXIC")' | ./gnc-fq-helper
+ $ echo '(alphavantage "CSCO" "JDSU" "^IXIC")' | ./gnc-fq-helper
(("CSCO" (symbol . "CSCO")
(gnc:time-no-zone . "2001-03-13 19:27:00")
(last . 20.375)
@@ -95,7 +93,7 @@ For example:
On error, the overall result may be #f, or on individual errors, the
list sub-item for a given symbol may be #f, like this:
- $ echo '(yahoo "CSCO" "JDSU")' | ./gnc-fq-helper
+ $ echo '(alphavantage "CSCO" "JDSU")' | ./gnc-fq-helper
(#f
("JDSU" (symbol . "JDSU")
(gnc:time-no-zone . "2001-03-13 19:27:00")
diff --git a/src/quotes/gnc-value-portfolio b/src/quotes/gnc-value-portfolio
deleted file mode 100755
index 7c27f08..0000000
--- a/src/quotes/gnc-value-portfolio
+++ /dev/null
@@ -1,672 +0,0 @@
-#!/usr/bin/perl -w
-#######################################################################
-# $Id$
-# Looks up investment prices on the web, and builds a report
-# to summarize the results
-#######################################################################
-$HISTORYFILE="histprices";
-$newprices = "NO"; # Haven't found *any* new prices so far...
-
-#######################################################################
-# Start by initializing the security list
-#######################################################################
-# My TSE stocks...
-
-#######################################################################
-&add_stock("T", 100, 1670.5, "TSE");
-#&add_stock("NVA", 100, 1345.5, "TSE");
-&add_stock("NVA", 100, -10.16, "TSE");
-&add_stock("TRP", 52, 1345.50, "TSE");
-&add_stock("PCA", 100, 1733, "TSE");
-&add_stock("TOC", 50, 21.035*50, "TSE");
-&add_stock("RY", 50, 32.785*50, "TSE");
-
-#######################################################################
-# My Canada Trust Everest funds...
-#######################################################################
-# Original numbers of units...
-#&add_stock("CTMM", 83.951, 839.51, "CTE"); # Not strictly correct..
-#&add_stock("CTBOND", 121.747, 1315.17, "CTE");
-#&add_stock("CTSTK", 57.177, 832.73, "CTE");
-#&add_stock("CTSPEC", 28.263, 504.07, "CTE");
-#&add_stock("CTAMER", 177.723, 1983.05, "CTE");
-#&add_stock("CTUSEQ", 19.644, 294.91, "CTE");
-#&add_stock("CTASIA", 28.224, 251.99, "CTE");
-#&add_stock("CTEURO", 60.136, 530.50, "CTE");
-#&add_stock("CTEMER", 27.463, 266.67, "CTE");
-#&add_stock("CTIBND", 84.879, 907.37, "CTE");
-
-# Units as at Oct 31/98
-&add_stock("CTMM", 89.572, 839.51, "CTE");
-
-&add_stock("CTBOND", 137.398, 1315.17, "CTE");
-&add_stock("CTSTK", 62.896, 832.73, "CTE");
-&add_stock("CTSPEC", 28.263, 504.07, "CTE");
-&add_stock("CTAMER", 251.604, 1983.05, "CTE");
-&add_stock("CTUSEQ", 20.467, 294.91, "CTE");
-&add_stock("CTASIA", 28.238, 251.99, "CTE");
-&add_stock("CTEURO", 91.298, 530.50, "CTE");
-&add_stock("CTEMER", 27.463, 266.67, "CTE");
-&add_stock("CTIBND", 94.264, 907.37, "CTE");
-
-# Stuff on NYSE
-&add_stock("MOT", 15, (62+5/8)*15, "NYSE");
-#&add_stock("IFMXE", 0.1, 0.1, "NYSE");
-&add_stock("TSG", 13.0289, 43.02*5+43.75+44.48, "NYSE");
-&add_stock("TSG", 27.619-13.0289, 44.48*8, "NYSE");
-
-# SuperSaver 401(k)... Approximate...
-&add_stock("AADBX", 0.3*2115.93/14, 0.3*1604.85, "NYSE");
-&add_stock("AADEX", 0.5*2115.93/19, 0.5*1604.85, "NYSE");
-&add_stock("AAIEX", 0.2*2115.93/15, 0.2*1604.85, "NYSE");
-
-# SGRP Balances: Approximate...
-&add_stock("AADBX", 712.33/14.9, 700, "NYSE"); # Balanced
-&add_stock("AADEX", 4556.64/22.5 + (533.94+200.24+183.55)/22.5, 3500+(533.94+200.24+183.55), "NYSE"); # Equity
-&add_stock("AAIEX", 1829.63/18.8 + (213.57+80.1+73.41)/18.8, 1700+(213.57+80.1+73.41), "NYSE"); # Int'l Equity
-&add_stock("AASPX", 2104.81/15 + (320.37+120.12+110.13)/15, 1900 + (320.37+120.12+110.13), "NYSE"); # Stock Index
-
-
-#######################################################################
-# Working Ventures fund...
-#######################################################################
-&add_stock("WORKVE", 219.701, 3000, "OTHER");
-$PRICE{"WORKVE"} = 3000/219.701; # Hack in a price for Working Ventures
-$OLD{"WORKVE"} = "yes"; # Indicate that this is *not* a "new" price...
-
-
-#######################################################################
-# Map CT Everest fund names to the "short" IDs
-#######################################################################
-# I don't want to get long names; this builds an array that
-# shortens the names used in the CT Everest Funds web page to
-# the ones used above
-#######################################################################
-&ct_fund_ids; # Get mapping of CT "long" fund names to "short" names
-
-&load_prices; # Load old prices, so that failure to get a price
- # means we fall back to the previously-found
- # price
-
-$CURRNAME{"CDN"} = "Canadian";
-$CURRNAME{"USD"} = "United States";
-$CURRATE{"CDN"} = 1;
-$CURRATE{"USD"} = 1.37;
-&get_currency("USD");
-#######################################################################
-# Now, get the current prices by sundry queries of web sites
-#######################################################################
-&search_web_for_prices(); # Find new closing prices
-&calc_variances(); # Calculate variances
-
-#######################################################################
-# Run report that details portfolio value based on the prices, costs
-# and quantities of shares...
-#######################################################################
-if ($newprices eq "YES") {
- &show_report(); # Display a report summarizing the results...
-# &show_variances();
-# &hilo_portfolios();
- &save_prices(); # Save prices...
-}
-exit 0; # Done
-
-#######################################################################
-#######################################################################
-#######################################################################
-#######################################################################
-#######################################################################
-######################## End of the main body #########################
-#######################################################################
-#######################################################################
-#######################################################################
-#######################################################################
-#######################################################################
-
-#######################################################################
-#######################################################################
-############################# Subroutines #############################
-#######################################################################
-#######################################################################
-
-
-#######################################################################
-############### &add_stock("NVA", 100, 1345.5, "TSE"); ################
-#######################################################################
-# Add a security to the "active list," including the "ticker symbol,"
-# quantity of shares, original total cost, and the exchange to look it
-# up on.
-#######################################################################
-sub add_stock {
- local($ticker, $num, $cost, $exchange) = @_;
- $NUM{$ticker} += $num;
- $COST{$ticker} += $cost;
- $EXCHANGE{$ticker} = $exchange;
- local ($currency) = "CDN";
- if ($exchange eq "TSE") {
- $currency = "CDN";
- }
- if ($exchange eq "NYSE") {
- $currency = "USD";
- }
- if ($exchange eq "NY") {
- $currency = "USD";
- }
- $CURRENCY{$ticker} = $currency;
-}
-
-#######################################################################
-######## &get_url_command("http://www.conline.com/~cbbrowne");#########
-#######################################################################
-# Build the appropriate command that accesses (in raw form) the
-# requested URL. Probably ought to change this to use the w3c
-# "line mode" utility, as it's minscule
-#######################################################################
-sub get_url_command {
- local ($url) = @_;
- return "lynx -source '$url'";
-}
-
-#######################################################################
-###################### &search_web_for_prices(); ######################
-#######################################################################
-# This program searches the %EXCHANGE array, determining how
-# the security price should be searched out, and invokes the
-# appropriate method.
-#######################################################################
-sub search_web_for_prices {
- local ($ticker);
-
- # Do some per-ticker searching
- foreach $ticker (keys EXCHANGE) {
- local($exchange) = $EXCHANGE{$ticker};
- if ($exchange eq "TSE") {
- &get_TSE($ticker);
- &get_yahoo($ticker, "TSE");
- }
-
- if ($exchange eq "CTE") {
- # Do nothing; data is coming
- # in en masse via &get_all_everest_rates;
- }
- if ($exchange eq "NYSE") {
- &get_yahoo($ticker, $EXCHANGE{$ticker});
- }
- }
-
- # search for CT Everest fund data
- &get_CT_Everest; # Get Everest mutual fund data
-
- # Search for Working Ventures fund data
- &get_WV;
-
- # get all of the TSE stock prices
- # foreach $ticker (ord("a")..ord("z")) {
- # &get_TSE( chr($ticker) );
- # }
-}
-
-#######################################################################
-########################## &get_TSE ("RY"); ###########################
-#######################################################################
-# Look up a stock's price on the TSE using the Telenium service
-#######################################################################
-sub get_TSE {
- local ($stock) = @_;
- local ($page) = "http://www.telenium.ca/TSE/" .
-
- lc(
- substr($stock, 0, 1)
- )
- . ".html";
- if ($OLD{$stock} eq "NO!") { # We've already priced this stock
- return;
- }
- local ($command) = &get_url_command($page) . " | grep ' $stock'";
- local ($line);
- open(GETPAGE, "$command |");
-# open(GETPAGE, "<a:/t~1.htm");
- while ($line = <GETPAGE>) {
- chop $line;
-# print $line, "\n";
- if ($line =~ /(\d*\.\d*)\D+\d+\S*\s+\d+\s+\S+\s+\d+\/\d+\s+(\S*)\s*$/) {
- local($lp, $ls) = (sprintf("%.4f", $1), $2);
-
-# print "Found $ls @ $lp\n";
- #... 21.3 21.35 21.2 21.2 -0.15 142300 193 02/14 T
- #... 19.4 19.5 19.2 19.35-0.1 687239 181 02/04 T
- #... 51.5 52 50.6 51.4 0 1527378 583 02/05 RY
-
- #... 1.18 1.2 1.1 1.2 0.02 44700 29 02/03 NBX
- # ^^^
- # Want this "close" value...
- if ($lp < 0.001) {
- # Do nothing
- } elsif ($ls eq $stock) {
- if ((($lp * 1.0) != $PRICE{$stock}) && ($price > 0)) {
- $newprices = "YES";
- $PRICE{$stock} = sprintf("%.4f", $price);
- print "NEW PRICE: $stock, $lp\n";
- } else {
- $price = $PRICE{$stock};
- }
- $PRICE{$stock} = sprintf("%.4f", $lp);
- $OLD{$stock} = "NO!"; # Indicate that this is an update...
- }
- }
- }
- close GETPAGE;
-}
-
-#######################################################################
-############################ &get_yahoo(); ############################
-#######################################################################
-# Look up a stock via "yahoo"
-#######################################################################
-sub get_yahoo {
- local ($stock, $exchange) = @_;
- local ($price);
- if (($exchange eq "NY") || ($exchange eq "NYSE")) {
- $exchange = "";
- }
- if ($exchange eq "TSE") {
- $exchange = ".TO";
- }
- local ($page) = "http://quote.yahoo.com/download/quotes.csv?symbols=" .
-
- $stock . $exchange .
- "&format=sl1d1t1c1ohgv&ext=.csv";
- if ($OLD{$stock} eq "NO!") { # We've already priced this stock
- return;
- }
- local ($command) = &get_url_command($page);
- local ($line);
-# print $command, "\n";
- open(GETPAGE, "$command |");
- while ($line = <GETPAGE>) {
-# print "$line";
- local ($trash, $price)=split(/,/, $line);
-# print "$trash, $price\n";
-# print "Old price: ", $PRICE{$stock}, "\n";
- if ((($price * 1.0) != $PRICE{$stock}) && ($price > 0) ) {
- $newprices = "YES";
- print "NEW PRICE: $stock, $price\n";
- } else {
- $price = $PRICE{$stock};
-# print "Keep old price: $price\n";
- }
- $PRICE{$stock} = sprintf("%.4f", $price);
- $OLD{$stock} = "NO!"; # Indicate that this is an update...
-# print "Done - ", $stock, $PRICE{$stock}, $OLD{$stock}, "\n";
- }
-}
-
-#######################################################################
-########################## &get_CT_Everest(); #########################
-#######################################################################
-# Look up all of the CT Everest mutual fund prices
-#######################################################################
-sub get_CT_Everest {
- local ($line, $fund, $value);
- local ($url) = "http://www.canadatrust.com/test/ctrates/EV.html";
- local ($command) = &get_url_command($url);
- open(FUNDS, "$command |");
- while ($line = <FUNDS>) {
- if ($line =~ /.*\s+\d+.\d+\s+\d+.\d+\s+.\d+.\d+/) {
-# print "CT: $line";
- $fund = substr($line, 0, 15);
-# print "fund: [", $fund, "] ID:[", $ID{$fund}, "]\n";
- if ($ID{$fund} ne "") {
- $value = substr($line, 30, 11);
- if (($value*1.0) != $PRICE{$ID{$fund}}) {
- $newprices = "YES";
- print "NEW PRICE: $fund, $value\n";
-
- }
-
- $PRICE{$ID{$fund}} = $value;
- $OLD{$ID{$fund}} = "NO!"; # Indicate that this is an update...
-# print "CT Price: $value ", $ID{$fund}, "\n";
- }
- }
- }
- close FUNDS;
-}
-
-#######################################################################
-############################## &get_WV(); #############################
-#######################################################################
-# Look up Working Ventures fund price
-#######################################################################
-sub get_WV {
- local ($url) = "http://www.workingventures.ca/main_cell.html";
- local ($command) = &get_url_command($url) . " | grep 'share price' ";
- open(FUNDS, "$command |");
- while (<FUNDS>) {
- if (/\D+\$(\d+\.\d+)\D+/) {
- # matches .... $13.66 ...
- if (($1 * 1.0) != $PRICE{"WORKVE"}) {
- $newprices = "YES";
- print "NEW PRICE: WV, $1\n";
- }
-
- $PRICE{"WORKVE"} = sprintf("%.4f", $1);
- $OLD{"WORKVE"} = "NO!"; # Indicate that this is an update...
- }
- }
- close FUNDS;
-}
-
-#######################################################################
-########################### &ct_fund_ids (); ##########################
-#######################################################################
-# Build an associative array that lets one take the names used in the
-# CT mutual fund web page, and associate them with the short forms
-# used as "ticker" codes
-#######################################################################
-sub ct_fund_ids {
- %ID = ("MONEY MARKET ", "CTMM",
- "PREMIUM MMF ", "CTPMM",
- "SHORT TERM BND ", "CTSTB",
- "MORTGAGE ", "CTMTG",
- "BALANCED ", "CTBAL",
- "BOND ", "CTBOND",
- "DIV INCOME ", "CTDIV",
- "STOCK ", "CTSTK",
- "SPECIAL EQUITY ", "CTSPEC",
- "INT'L BOND ", "CTIBND",
- "NORTH AMERICAN ", "CTNA",
- "AMERIGROWTH ", "CTAMER",
- "U.S. EQUITY ", "CTUSEQ",
- "ASIAGROWTH ", "CTASIA",
- "EUROGROWTH ", "CTEURO",
- "GLOBALGROWTH ", "CTGLOB",
- "INT'L EQUITY ", "CTINTL",
- "EMERGING MKTS. ", "CTEMER"
- );
-}
-
-
-#######################################################################
-############################ &save_prices()############################
-#######################################################################
-# Dump data out to a file
-#######################################################################
-sub save_prices {
- local ($date) = `date '+%Y/%m/%d-%H:%M:%S'`;
- chop $date;
- local ($ticker, $price);
- open(HISTPRICES, ">>$HISTORYFILE");
- while ($ticker = each %PRICE) {
- if ($OLD{$ticker} eq "yes") {
- # Don't dump it; we didn't get a new price...
- } else {
- $key = $date . "" . $ticker;
- $price = $PRICE{$ticker};
- print HISTPRICES $date, "|", $ticker, "|", $price, "\n";;
- }
- }
- close HISTPRICES;
-}
-
-#######################################################################
-########################### &load_prices();############################
-#######################################################################
-# Preload prices, thus always keeping around the latest successfully
-# located price.
-# This means that if the web search process fails, we still do have
-# pricing, even if it's somewhat out of date...
-#######################################################################
-sub load_prices {
- local ($date) = `date '+%Y/%m/%d-%H:%M:%S'`;
- chop $date;
- local ($ticker, $price, $line);
- open(HISTPRICES, "<$HISTORYFILE");
- while ($line = <HISTPRICES>) {
- ($date, $ticker, $price) = split(/\|/, $line);
- $PRICE{$ticker} = $price;
- $OLD{$ticker} = "yes"; # Indicate that this is an old price
- # and thus not to be redumped
- }
- close HISTPRICES;
-}
-
-
-
-#######################################################################
-############################ &show_report();###########################
-#######################################################################
-# Look up all of the securities, and build a report listing the cost,
-# value, and net profit/loss on each security, along with totals.
-########################################################################
-sub show_report {
- local($date) = `date`;
- chop $date;
- local($ticker, $shares, $price, $value, $cost, $profitloss);
- local ($tp, $tv, $tc);
-format STDOUT_TOP =
- Portfolio Valuation
- as at @<<<<<<<<<<<<<<<<<<<<<<<<<<<
-$date
-Ticker Shares Recent Price Value Cost Profit/Loss
-------------------------------------------------------------------------
-.
-
-
-format STDOUT =
-@<<<<<<< @>>>>>>> @>>>>>>>> @>>>>>>>>>>> @>>>>>>>>>>> @>>>>>>>>>>>>
-$ticker, $shares, $price, $value, $cost, $profitloss
-.
-
-
- foreach $stock (sort keys EXCHANGE) {
- if ($stock ne "zPortfolio") {
- $ticker = $stock;
- $shares = sprintf("%.4f", $NUM{$stock});
- $price = sprintf("%.4f", $PRICE{$stock});
- $value = sprintf("%.2f", $shares * $price * $CURRATE{$CURRENCY{$stock}});
- $cost = sprintf("%.2f", $COST{$stock} * $CURRATE{$CURRENCY{$stock} });
- $profitloss = sprintf("%.2f", $value - $cost);
- $tv += $value;
- $tc += $cost;
- $tp += $profitloss;
- write;
- }
- }
-
-($ticker, $shares, $price, $value, $cost, $profitloss) =
- ("", "", "", "---------------", "---------------", "---------------");
-write;
-
-($ticker, $shares, $price, $value, $cost, $profitloss) =
- ("Total", "", "", sprintf("%.2f", $tv), sprintf("%.2f" ,$tc),
- sprintf("%.2f" ,$tp));
-
-write;
-($ticker, $shares, $price, $value, $cost, $profitloss) =
- ("", "", "", "===============", "===============", "===============");
-write;
-}
-
-
-
-#########################################################################=
-#####
-############################## Find Variances #########################=
-#####
-#########################################################################=
-#####
-sub calc_variances {
- local ($x);
- open(PRICEF, "<$HISTORYFILE");
- while (<PRICEF>) {
- ($date, $id, $price) = split(/\|/, $_);
- $XCOUNT{$id} ++;
- $quantity = $NUM{$id};
- $x = $quantity * $price * $CURRATE{$CURRENCY{$id}};
- $XSUM{$id} += $x;
- $XSQUARESUM{$id} += ($x * $x);
-
- $DATES{$date} ++;
- $PRICES{"$date|$id"} = $price;
-# printf "XC: %9.2f XSUM: %9.2f XSQ: %9.2f\n", $XCOUNT{$id}, $XSUM{$id}, $XSQUARESUM{$id};
- }
-
- &complete_price_list(); # Get prices for *every* day
- &value_portfolios(); # Value the portfolio for every day
-}
-
-# Need to make sure that we have prices for each stock for each date
-# This is done by (for each stock) going thru all the dates, and
-# inserting prices for dates where prices are missing. We use the
-# last price present for the stock.
-sub complete_price_list {
- foreach $stock (keys XCOUNT) {
- $current_price = $XSUM{$stock} / $XCOUNT{$stock};
-
- # Move forwards until a price gets found. That price
- # is then used for all "empty" price slots up to the first
- # actual measurement
- FIRSTPRICE:
- foreach $date (sort keys DATES) {
- if ($PRICES{"$date|$stock"}) {
- $current_price = $PRICES{"$date|$stock"};
- last FIRSTPRICE;
- }
- }
-
- # Now, proceed onwards...
- foreach $date (sort keys DATES) {
- if ($PRICES{"$date|$stock"}) {
- # There's a price
- $current_price = $PRICES{"$date|$stock"};
- } else {
- $PRICES{"$date|$stock"} = $current_price;
- }
- }
- }
-}
-
-sub value_portfolios {
-# &setup_portfolio_quantities();
- $NUM{"zPortfolio"}=1;
- foreach $date (sort keys DATES) {
- $price = 0;
- foreach $stock (keys XCOUNT) {
- $price += $NUM{$stock} * $PRICES{"$date|$stock"}* $CURRATE{$CURRENCY{$stock}};
- }
- $XCOUNT{"zPortfolio"} ++;
- $XSUM{"zPortfolio"} += $price;
- $XSQUARESUM{"zPortfolio"} += ($price * $price);
-# printf "Portfolio on %15s valued at %14.2f\n", $date, $price;
-
- }
-}
-
-sub hilo_portfolios {
- local($date, $hi, $lo, $hival, $loval);
- local ($stock, $price, $latest_date);
- foreach $stock (keys XCOUNT) {
- $LO{$stock} = 99999999;
- $HI{$stock} = -99999999;
- }
- $HI{"zPortfolio"} = -99999999;
- $LO{"zPortfolio"} = 99999999;
- foreach $date (keys DATES) {
- local ($pprice);
- local($dt) = split(/-/, $date);
- foreach $stock (keys XCOUNT) {
- $price = $PRICES{"$date|$stock"};
- if ($date >= $latest_date) {
- $latest_date = $date;
- $CURRENT{$stock} = $price;
- }
- if ($price > $HI{$stock}) {
- ($HI{$stock}, $HIDATE{$stock}) = ($price, $dt);
- }
- if ($price < $LO{$stock}) {
- ($LO{$stock}, $LODATE{$stock}) = ($price, $dt);
- }
- $pprice += $NUM{$stock} * $price;
- }
- if ($date >= $latest_date) {
- $latest_date = $date;
- $CURRENT{"zPortfolio"} = $pprice;
- }
- if ($pprice > $HI{"zPortfolio"}) {
- ($HI{"zPortfolio"}, $HIDATE{"zPortfolio"}) = ($pprice, $dt);
- }
- if ($pprice > $LO{"zPortfolio"}) {
- ($LO{"zPortfolio"}, $LODATE{"zPortfolio"}) = ($pprice, $dt);
- }
- }
- # Report results...
- print
-"-----------------------------------------------------------------------
- Highs/Lows
------------------------------------------------------------------------
-";
- printf "%10s %10s %10s %10s %10s %10s\n", "Stock", "High Date", "High",
- "Low Date", "Low Price", "Current";
- print "-----------------------------------------------------------------------";
- foreach $stock (sort keys XCOUNT) {
- printf "%10s %10s %10.2f %10s %10.2f %10.2f\n", $stock, $HIDATE{$stock},
- $HI{$stock}, $LODATE{$stock}, $LO{$stock}, $CURRENT{$stock};
- }
- print "-----------------------------------------------------------------------";
-
-}
-
-sub show_variances {
- print
- "-----------------------------------------------------------------------
- Variance/Standard Deviations for Portfolio *VALUE*
-------------------------------------------------------------------------
- Security Mean Variance Std. Dev. % Std.Dev
-------------------------------------------------------------------------
-";
-
- foreach $i (sort keys XCOUNT) {
- if ($XCOUNT{$i} > 2) {
- $variance = (($XCOUNT{$i} * $XSQUARESUM{$i})
- - ($XSUM{$i} * $XSUM{$i})) /
- ($XCOUNT{$i} * ($XCOUNT{$i}-1));
-
- }
- $variance = -$variance if ($variance < 0);
- $deviation = sqrt($variance);
-
-# printf "XC: %5d XSUM: %9.2f XSQ: %9.2f\n", $XCOUNT{$i}, $XSUM{$i}, $XSQUARESUM{$i};
- # Divide by mean price to determine volatility of price
- if ($XCOUNT{$i} != 0 && $XSUM{$i} != 0) {
- $volatility = $deviation / ($XSUM{$i} / $XCOUNT{$i});
- printf "%10s %10.2f %14.3f %9.3f %9.3f\n", $i, $XSUM{$i}/$XCOUNT{$i},
- $variance, $deviation,
- $volatility *100;
-
- ($VARIANCE{$i}, $STD{$i}, $VOLATILITY{$i}) = ($variance, $deviation,
- $volatility);
- }
- }
- print "------------------------------------------------------------------------";
-
-}
-
-sub get_currency {
- local ($to) = @_;
- local($url) =
- "http://www.dna.lth.se/cgi-bin/kurt/rates/rates?CAD+$to";
- local($line, $rate);
- local ($command) = &get_url_command($url);
-
- local($fromname, $toname) = ($CURRNAME{"CDN"}, $CURRNAME{$to});
- open(CURRS, "$command |");
- while ($line = <CURRS>) {
- if ($line =~ /Rate: $fromname.*$toname.*:\s*(\d*.\d+)/) {
- $rate = $1;
- $CURRATE{$toname} = sprintf("%f", $rate);
- return;
- }
- }
-}
-
diff --git a/src/scm/price-quotes.scm b/src/scm/price-quotes.scm
index 2f01ca1..5dcbaa2 100644
--- a/src/scm/price-quotes.scm
+++ b/src/scm/price-quotes.scm
@@ -118,7 +118,7 @@
;;
;; (<fq-method> sym sym ...)
;;
- ;; i.e. (yahoo "RHAT" "LNUX" "IBM")
+ ;; i.e. (alphavantage "RHAT" "LNUX" "IBM")
;;
;; for currencies, we have
;;
@@ -210,7 +210,7 @@
;; gnc-fq-helper. Each item will of the list will be of the
;; form:
;;
- ;; (("yahoo" (commodity-1 currency-1 tz-1)
+ ;; (("alphavantage" (commodity-1 currency-1 tz-1)
;; (commodity-2 currency-2 tz-2) ...)
;; ("fidelity_direct" (commodity-3 currency-3 tz-3)
;; (commodity-4 currency-4 tz-4) ...)
@@ -259,10 +259,10 @@
;; their fq-suitable symbol strings. i.e. turn the former into
;; the latter:
;;
- ;; ("yahoo" (commodity-1 currency-1 tz-1)
+ ;; ("alphavantage" (commodity-1 currency-1 tz-1)
;; (commodity-2 currency-2 tz-2) ...)
;;
- ;; ("yahoo" "IBM" "AMD" ...)
+ ;; ("alphavantage" "IBM" "AMD" ...)
;;
(if (equal? (car fq-call-data) "currency")
Summary of changes:
doc/README-ca.win32-bin.txt | 102 +++++++++++-----------
doc/README-de.win32-bin.txt | 112 ++++++++++++-------------
doc/README-fr.win32-bin.txt | 116 +++++++++++++-------------
doc/README-it.win32-bin.txt | 102 +++++++++++-----------
doc/README-lv.win32-bin.txt | 104 +++++++++++------------
doc/README-nl.win32-bin.txt | 102 +++++++++++-----------
doc/README-zh_CN.win32-bin.txt | 82 +++++++++---------
doc/README-zh_TW.win32-bin.txt | 84 +++++++++----------
doc/README.win32-bin.txt | 104 +++++++++++------------
doc/examples/downloaded.mt940 | 18 ++--
doc/gnc-fq-dump.1 | 4 +-
gnucash/gnome-utils/gnc-tree-view-commodity.c | 2 +-
gnucash/gnucash.rc.in | 66 +++++++--------
libgnucash/doc/design/top-level.texi | 2 +-
libgnucash/engine/gnc-commodity.c | 40 +++++++--
15 files changed, 531 insertions(+), 509 deletions(-)
More information about the gnucash-changes
mailing list