mymoneygncreader.h

Go to the documentation of this file.
00001 /***************************************************************************
00002                        mymoneygncreader  -  description
00003                           -------------------
00004  begin                : Wed Mar 3 2004
00005  copyright            : (C) 2000-2004 by Michael Edwardes
00006  email                : mte@users.sourceforge.net
00007                         Javier Campos Morales <javi_c@users.sourceforge.net>
00008                         Felix Rodriguez <frodriguez@users.sourceforge.net>
00009                         John C <thetacoturtle@users.sourceforge.net>
00010                         Thomas Baumgart <ipwizard@users.sourceforge.net>
00011                         Kevin Tambascio <ktambascio@users.sourceforge.net>
00012 ***************************************************************************/
00013 
00014 /***************************************************************************
00015  *                                                                         *
00016  *   This program is free software; you can redistribute it and/or modify  *
00017  *   it under the terms of the GNU General Public License as published by  *
00018  *   the Free Software Foundation; either version 2 of the License, or     *
00019  *   (at your option) any later version.                                   *
00020  *                                                                         *
00021  ***************************************************************************/
00022 /*
00023 The main class of this module, MyMoneyGncReader, contains only a readFile()
00024 function, which controls the import of data from an XML file created by the
00025 current GnuCash version (1.8.8).
00026 
00027 The XML is processed in class XmlReader, which is an implementation of the Qt
00028 SAX2 reader class.
00029 
00030 Data in the input file is processed as a set of objects which fortunately,
00031 though perhaps not surprisingly, have almost a one-for-one correspondence with
00032 KMyMoney objects. These objects are bounded by start and end XML elements, and
00033 may contain both nested objects (described as sub objects in the code), and data
00034 items, also delimited by start and end elements. For example:
00035 <gnc:account> * start of sub object within file
00036   <act:name>Account Name</act:name> * data string with start and end elements
00037   ...
00038 </gnc:account> * end of sub objects
00039 
00040 A GnuCash file may consist of more than one 'book', or set of data. It is not
00041 clear how we could currently implement this, so only the first book in a file is
00042 processed. This should satisfy most user situations.
00043 
00044 GnuCash is somewhat inconsistent in its division of the major sections of the
00045 file. For example, multiple price history entries are delimited by <gnc:pricedb>
00046 elements, while each account starts with  its own top-level element. In general,
00047 the 'container' elements are ignored.
00048 
00049 XmlReader
00050 
00051 This is an implementation of the Qt QXmlDefaultHandler class, which provides
00052 three main function calls in addition to start and end of document. The
00053 startElement() and endElement() calls are self-explanatory, the characters()
00054 function provides data strings. Thus in the above example, the sequence of calls
00055 would be
00056   startElement() for gnc:account
00057   startElement() for act:name
00058    characters() for 'Account Name'
00059   endElement() for act:name
00060   ...
00061   endElement() for gnc:account
00062 
00063 Objects
00064 
00065 Since the processing requirements of XML for most elements are very similar, the
00066 common code is implemented in a GncObject class, from which the others are
00067 derived, with virtual function calls to cater for any differences. The
00068 'grandfather' object, GncFile representing the file (or more correctly, 'book')
00069 as a whole, is created in the startDocument() function call.
00070 
00071 The constructor function of each object is responsible for providing two lists
00072 for the XmlReader to scan, a list of element names which represent sub objects
00073 (called sub elements in the code), and a similar list of names representing data
00074 elements. In addition, an array of variables (m_v) is provided and initialized,
00075 to contain the actual data strings.
00076 
00077 Implementation
00078 
00079 Since objects may be nested, a stack is used, with the top element pointing to
00080 the 'current object'. The startDocument() call creates the first, GncFile,
00081 object at the top of the stack.
00082 
00083 As each startElement() call occurs, the two element lists created by the current
00084 object are scanned.
00085 If this element represents the start of a sub object, the current object's subEl()
00086 function is called to create an instance of the appropriate type. This is then
00087 pushed to the top of the stack, and the new object's initiate() function is
00088 called. This is used to process any XML attributes attached to the element;
00089 GnuCash makes little use of these.
00090 If this represents the start of a data element, a pointer (m_dataPointer) is set
00091 to point to an entry in the array (m_v) in which a subsequent characters() call
00092 can store the actual data.
00093 
00094 When an endElement() call occurs, a check is made to see if it matches the
00095 element name which started the current object. If so, the object's terminate()
00096 function is called. If the object represents a similar KMM object, this will
00097 normally result in a call to a conversion routine in the main
00098 (MyMoneyGncReader) class to convert the data to native format and place it in
00099 storage. The stack is then popped, and the parent (now current) object notified
00100 by a call to its endSubEl() function. Again depending on the type of object,
00101 this will either delete the instance, or save it in its own storage for later
00102 processing.
00103 For example, a GncSplit object makes little sense outside the context of its
00104 transaction, so will be saved by the transaction. A GncTransaction object on the
00105 other hand will be converted, along with its attendant splits, and then deleted
00106 by its parent.
00107 
00108 Since at any one time an object will only be processing either a subobject or a
00109 data element, a single object variable, m_state, is used to determine the actual
00110 type. In effect, it acts as the current index into either the subElement or
00111 dataElement list. As an object variable, it will be saved on the stack across
00112 subobject processing.
00113 
00114 Exceptions and Problems
00115 
00116 Fatal exceptions are processed via the standard MyMoneyException method.
00117 Due to differences in implementation between GnuCash and KMM, it is not always
00118 possible to provide an absolutely correct conversion. When such a problem
00119 situation is recognized, a message, along with any relevant variable data, is
00120 passed to the main class, and used to produce a report when processing
00121 terminates. The GncMessages and GncMessageArg classes implement this.
00122 
00123 Anonymizer
00124 
00125 When debugging problems, it is often useful to have a trace of what is happening
00126 within the module. However, in view of the sensitive nature of personal finance
00127 data, most users will be reluctant to provide this. Accordingly, an anonymize
00128 (hide()) function is provided to handle data strings. These may either be passed
00129 through asis (non-personal data), blanked out (non-critical but possibly personal
00130 data), replaced with a generated version (required, but possibly personal), or
00131 randomized (monetary amounts). The action for each data item is determined in
00132 the object's constructor function along with the creation of the data element
00133 list.
00134 This module will later be used as the basis of a file anonymizer, which will
00135 enable users to safely provide us with a copy of their GnuCash files, and will
00136 allow us to test the structure, if not the data content, of the file.
00137 */
00138 
00139 #ifndef MYMONEYSTORAGEGNC_H
00140 #define MYMONEYSTORAGEGNC_H
00141 
00142 // Some STL headers in GCC4.3 contain operator new. Memory checker mangles these
00143 #ifdef _CHECK_MEMORY
00144   #undef new
00145 #endif
00146 // system includes
00147 #include <stdlib.h>
00148 
00149 // ----------------------------------------------------------------------------
00150 // QT Includes
00151 
00152 #include <qdatastream.h>
00153 class QIODevice;
00154 #include <qobject.h>
00155 #include <qvaluelist.h>
00156 #include <qptrlist.h>
00157 #include <qptrstack.h>
00158 #include <qxml.h>
00159 #include <qdatetime.h>
00160 #include <qtextcodec.h>
00161 
00162 // ----------------------------------------------------------------------------
00163 // Project Includes
00164 #ifdef _CHECK_MEMORY
00165   #include <kmymoney/mymoneyutils.h>
00166 #endif
00167 
00168 #ifndef _GNCFILEANON
00169 #include "../mymoney/storage/imymoneyserialize.h" // not used any more, but call interface requires it
00170 #include "../mymoney/storage/imymoneystorageformat.h"
00171 #endif // _GNCFILEANON
00172 
00173 // not sure what these are for, but leave them in
00174 #define VERSION_0_60_XML  0x10000010    // Version 0.5 file version info
00175 #define VERSION_0_61_XML  0x10000011    // use 8 bytes for MyMoneyMoney objects
00176 #define GNUCASH_ID_KEY "GNUCASH_ID"
00177 
00178 typedef QMap<QString, QString> map_accountIds;
00179 typedef map_accountIds::iterator map_accountIds_iter;
00180 typedef map_accountIds::const_iterator map_accountIds_citer;
00181 
00182 typedef QMap<QString, QStringList> map_elementVersions;
00183 
00184 class MyMoneyGncReader;
00185 
00192 class GncObject {
00193 public:
00194   GncObject();
00195   ; // to save delete loop when finished
00196   virtual ~GncObject() {}  // make sure to have impl  of all virtual rtns to avoid vtable errors?
00197 protected:
00198   friend class XmlReader;
00199   friend class MyMoneyGncReader;
00200 
00201   // check for sub object element; if it is, create the object
00202   GncObject *isSubElement (const QString &elName, const QXmlAttributes& elAttrs);
00203   // check for data element; if so, set data pointer
00204   bool isDataElement (const QString &elName, const QXmlAttributes& elAttrs);
00205   // process start element for 'this'; normally for attribute checking; other initialization done in constructor
00206   virtual void initiate (const QString&, const QXmlAttributes&) { return ;};
00207   // a sub object has completed; process the data it gathered
00208   virtual void endSubEl(GncObject *) {m_dataPtr = 0; return ;};
00209   // store data for data element
00210   void storeData (const QString& pData) // NB - data MAY come in chunks, and may need to be anonymized
00211   {if (m_dataPtr != 0)
00212     m_dataPtr->append (hide (pData, m_anonClass)); return ;}
00213   // following is provided only for a future file anonymizer
00214   QString getData () const { return ((m_dataPtr != 0) ? *m_dataPtr : "");};
00215   void resetDataPtr() {m_dataPtr = 0;};
00216   // process end element for 'this'; usually to convert to KMM format
00217   virtual void terminate() { return ;};
00218   void setVersion (const QString& v) {m_version = v; return; };
00219   QString version() const {return (m_version);};
00220 
00221   // some gnucash elements have version attribute; check it
00222   void checkVersion (const QString&, const QXmlAttributes&, const map_elementVersions&);
00223   // get name of element processed by 'this'
00224   QString getElName () const { return (m_elementName);};
00225   // pass 'main' pointer to object
00226   void setPm (MyMoneyGncReader *pM) {pMain = pM;};
00227   // debug only
00228   void debugDump();
00229 
00230   // called by isSubElement to create appropriate sub object
00231   virtual GncObject *startSubEl() { return (0);};
00232   // called by isDataElement to set variable pointer
00233   virtual void dataEl(const QXmlAttributes&) {m_dataPtr = m_v.at(m_state); m_anonClass = m_anonClassList[m_state];};
00234   // return gnucash data string variable pointer
00235   virtual QString var (int i) const;
00236   // anonymize data
00237   virtual QString hide (QString, unsigned int);
00238 
00239   MyMoneyGncReader *pMain;    // pointer to 'main' class
00240   // used at start of each transaction so same money hide factor is applied to all splits
00241   void adjustHideFactor();
00242 
00243   QString m_elementName; // save 'this' element's name
00244   QString m_version;     // and it's gnucash version
00245   const QString *m_subElementList; // list of sub object element names for 'this'
00246   unsigned int m_subElementListCount; // count of above
00247   const QString *m_dataElementList; // ditto for data elements
00248   unsigned int m_dataElementListCount;
00249   QString *m_dataPtr; // pointer to m_v variable for current data item
00250   mutable QPtrList<QString> m_v; // storage for variable pointers
00251 
00252   unsigned int m_state; // effectively, the index to subElementList or dataElementList, whichever is currently in use
00253 
00254   const unsigned int *m_anonClassList;
00255   enum anonActions {ASIS, SUPPRESS, NXTACC, NXTEQU, NXTPAY, NXTSCHD, MAYBEQ, MONEY1, MONEY2}; // anonymize actions - see hide()
00256   unsigned int m_anonClass; // class of current data item for anonymizer
00257   static double m_moneyHideFactor; // a per-transaction factor
00258 };
00259 
00260 // *****************************************************************************
00261 // This is the 'grandfather' object representing the gnucash file as a whole
00262 class GncFile : public GncObject {
00263 public:
00264   GncFile ();
00265   ~GncFile();
00266 private:
00267   enum iSubEls {BOOK, COUNT, CMDTY, PRICE, ACCT, TX, TEMPLATES, SCHEDULES, END_FILE_SELS };
00268   virtual GncObject *startSubEl();
00269   virtual void endSubEl(GncObject *);
00270 
00271   bool m_processingTemplates; // gnc uses same transaction element for ordinary and template tx's; this will distinguish
00272   bool m_bookFound;  // to  detect multi-book files
00273 };
00274 // The following are 'utility' objects, which occur within several other object types
00275 // ****************************************************************************
00276 // commodity specification. consists of
00277 //  cmdty:space - either ISO4217 if this cmdty is a currency, or, usually, the name of a stock exchange
00278 //  cmdty:id - ISO4217 currency symbol, or 'ticker symbol'
00279 class GncCmdtySpec : public GncObject {
00280 public:
00281   GncCmdtySpec ();
00282   ~GncCmdtySpec ();
00283 protected:
00284   friend class MyMoneyGncReader;
00285   friend class GncTransaction;
00286   bool isCurrency() const { return (*m_v.at(CMDTYSPC) == QString("ISO4217"));};
00287   QString id() const { return (*m_v.at(CMDTYID));};
00288   QString space() const { return (*m_v.at(CMDTYSPC));};
00289 private:
00290   // data elements
00291   enum CmdtySpecDataEls {CMDTYSPC, CMDTYID, END_CmdtySpec_DELS};
00292   virtual QString hide (QString, unsigned int);
00293 };
00294 // *********************************************************************
00295 // date; maybe one of two types, ts:date which is date/time, gdate which is date only
00296 // we do not preserve time data (at present)
00297 class GncDate : public GncObject {
00298 public:
00299   GncDate ();
00300   ~GncDate();
00301 protected:
00302   friend class MyMoneyGncReader;
00303   friend class GncPrice;
00304   friend class GncTransaction;
00305   friend class GncSplit;
00306   friend class GncSchedule;
00307   friend class GncRecurrence;
00308   const QDate date() const { return (QDate::fromString(m_v.at(TSDATE)->section(' ', 0, 0), Qt::ISODate));};
00309 private:
00310   // data elements
00311   enum DateDataEls {TSDATE, GDATE, END_Date_DELS};
00312   virtual void dataEl(const QXmlAttributes&) {m_dataPtr = m_v.at(TSDATE); m_anonClass = GncObject::ASIS;}
00313   ; // treat both date types the same
00314 };
00315 // ************* GncKvp********************************************
00316 // Key/value pairs, which are introduced by the 'slot' element
00317 // Consist of slot:key (the 'name' of the kvp), and slot:value (the data value)
00318 // the slot value also contains a slot type (string, integer, etc) implemented as an XML attribute
00319 // kvp's may be nested
00320 class GncKvp : public GncObject {
00321 public:
00322   GncKvp ();
00323   ~GncKvp();
00324 protected:
00325   friend class MyMoneyGncReader;
00326 
00327   QString key() const { return (var(KEY));};
00328   QString value() const { return (var(VALUE));};
00329   QString type() const { return (m_kvpType);};
00330   unsigned int kvpCount() const { return (m_kvpList.count());};
00331   const GncKvp *getKvp(unsigned int i) const { return (static_cast<GncKvp *>(m_kvpList.at(i)));};
00332 private:
00333   // subsidiary objects/elements
00334   enum KvpSubEls {KVP, END_Kvp_SELS };
00335   virtual GncObject *startSubEl();
00336   virtual void endSubEl(GncObject *);
00337   // data elements
00338   enum KvpDataEls {KEY, VALUE, END_Kvp_DELS };
00339   virtual void dataEl (const QXmlAttributes&);
00340   mutable QPtrList<GncObject> m_kvpList;
00341   QString m_kvpType;  // type is an XML attribute
00342 };
00343 // ************* GncLot********************************************
00344 // KMM doesn't have support for lots as yet
00345 class GncLot : public GncObject {
00346   public:
00347     GncLot ();
00348     ~GncLot();
00349   protected:
00350     friend class MyMoneyGncReader;
00351   private:
00352 };
00353 
00358 //********************************************************************
00359 class GncCountData : public GncObject {
00360 public:
00361   GncCountData ();
00362   ~GncCountData ();
00363 private:
00364   virtual void initiate (const QString&, const QXmlAttributes&);
00365   virtual void terminate();
00366   QString m_countType; // type of element being counted
00367 };
00368 //********************************************************************
00369 class GncCommodity : public GncObject {
00370 public:
00371   GncCommodity ();
00372   ~GncCommodity();
00373 protected:
00374   friend class MyMoneyGncReader;
00375   // access data values
00376   bool isCurrency() const { return (var(SPACE) == QString("ISO4217"));};
00377   QString space() const { return (var(SPACE));};
00378   QString id() const { return (var(ID));};
00379   QString name() const { return (var(NAME));};
00380   QString fraction() const { return (var(FRACTION));};
00381 private:
00382   virtual void terminate();
00383   // data elements
00384   enum {SPACE, ID, NAME, FRACTION, END_Commodity_DELS};
00385 };
00386 // ************* GncPrice********************************************
00387 class GncPrice : public GncObject {
00388 public:
00389   GncPrice ();
00390   ~GncPrice();
00391 protected:
00392   friend class MyMoneyGncReader;
00393   // access data values
00394   const GncCmdtySpec *commodity() const { return (m_vpCommodity);};
00395   const GncCmdtySpec *currency() const { return (m_vpCurrency);};
00396   QString value() const { return (var(VALUE));};
00397   QDate priceDate () const { return (m_vpPriceDate->date());};
00398 private:
00399   virtual void terminate();
00400   // sub object elements
00401   enum PriceSubEls {CMDTY, CURR, PRICEDATE, END_Price_SELS };
00402   virtual GncObject *startSubEl();
00403   virtual void endSubEl(GncObject *);
00404   // data elements
00405   enum PriceDataEls {VALUE, END_Price_DELS };
00406   GncCmdtySpec *m_vpCommodity, *m_vpCurrency;
00407   GncDate *m_vpPriceDate;
00408 };
00409 // ************* GncAccount********************************************
00410 class GncAccount : public GncObject {
00411 public:
00412   GncAccount ();
00413   ~GncAccount();
00414 protected:
00415   friend class MyMoneyGncReader;
00416   // access data values
00417   GncCmdtySpec *commodity() const { return (m_vpCommodity);};
00418   QString id () const { return (var(ID));};
00419   QString name () const { return (var(NAME));};
00420   QString desc () const { return (var(DESC));};
00421   QString type () const { return (var(TYPE));};
00422   QString parent () const { return (var(PARENT));};
00423 private:
00424   // subsidiary objects/elements
00425   enum AccountSubEls {CMDTY, KVP, LOTS, END_Account_SELS };
00426   virtual GncObject *startSubEl();
00427   virtual void endSubEl(GncObject *);
00428   virtual void terminate();
00429   // data elements
00430   enum AccountDataEls {ID, NAME, DESC, TYPE, PARENT, END_Account_DELS };
00431   GncCmdtySpec *m_vpCommodity;
00432   QPtrList<GncObject> m_kvpList;
00433 };
00434 // ************* GncSplit********************************************
00435 class GncSplit : public GncObject {
00436 public:
00437   GncSplit ();
00438   ~GncSplit();
00439 protected:
00440   friend class MyMoneyGncReader;
00441   // access data values
00442   QString id() const { return (var(ID));};
00443   QString memo() const { return (var(MEMO));};
00444   QString recon() const { return (var(RECON));};
00445   QString value() const { return (var(VALUE));};
00446   QString qty() const { return (var(QTY));};
00447   QString acct() const { return (var(ACCT));};
00448 const QDate reconDate() const {QDate x = QDate(); return (m_vpDateReconciled == NULL ? x : m_vpDateReconciled->date());};
00449 private:
00450   // subsidiary objects/elements
00451   enum TransactionSubEls {RECDATE, END_Split_SELS };
00452   virtual GncObject *startSubEl();
00453   virtual void endSubEl(GncObject *);
00454   // data elements
00455   enum SplitDataEls {ID, MEMO, RECON, VALUE, QTY, ACCT, END_Split_DELS };
00456   GncDate *m_vpDateReconciled;
00457 };
00458 // ************* GncTransaction********************************************
00459 class GncTransaction : public GncObject {
00460 public:
00461   GncTransaction (bool processingTemplates);
00462   ~GncTransaction();
00463 protected:
00464   friend class MyMoneyGncReader;
00465   // access data values
00466   QString id() const { return (var(ID));};
00467   QString no() const { return (var(NO));};
00468   QString desc() const { return (var(DESC));};
00469   QString currency() const { return (m_vpCurrency == NULL ? QString () : m_vpCurrency->id());};
00470   QDate dateEntered() const { return (m_vpDateEntered->date());};
00471   QDate datePosted() const { return (m_vpDatePosted->date());};
00472   bool isTemplate() const { return (m_template);};
00473   unsigned int splitCount() const { return (m_splitList.count());};
00474   unsigned int kvpCount() const { return (m_kvpList.count());};
00475   const GncObject *getSplit (unsigned int i) const { return (m_splitList.at(i));};
00476   const GncKvp *getKvp(unsigned int i) const { return (static_cast<GncKvp *>(m_kvpList.at(i)));};
00477 private:
00478   // subsidiary objects/elements
00479   enum TransactionSubEls {CURRCY, POSTED, ENTERED, SPLIT, KVP, END_Transaction_SELS };
00480   virtual GncObject *startSubEl();
00481   virtual void endSubEl(GncObject *);
00482   virtual void terminate();
00483   // data elements
00484   enum TransactionDataEls {ID, NO, DESC, END_Transaction_DELS };
00485   GncCmdtySpec *m_vpCurrency;
00486   GncDate *m_vpDateEntered, *m_vpDatePosted;
00487   mutable QPtrList<GncObject> m_splitList;
00488   bool m_template; // true if this is a template for scheduled transaction
00489   mutable QPtrList<GncObject> m_kvpList;
00490 };
00491 
00492 // ************* GncTemplateSplit********************************************
00493 class GncTemplateSplit : public GncObject {
00494 public:
00495   GncTemplateSplit ();
00496   ~GncTemplateSplit();
00497 protected:
00498   friend class MyMoneyGncReader;
00499   // access data values
00500   QString id() const { return (var(ID));};
00501   QString memo() const { return (var(MEMO));};
00502   QString recon() const { return (var(RECON));};
00503   QString value() const { return (var(VALUE));};
00504   QString qty() const { return (var(QTY));};
00505   QString acct() const { return (var(ACCT));};
00506   unsigned int kvpCount() const { return (m_kvpList.count());};
00507   const GncKvp *getKvp(unsigned int i) const { return (static_cast<GncKvp *>(m_kvpList.at(i)));};
00508 private:
00509   // subsidiary objects/elements
00510   enum TemplateSplitSubEls {KVP, END_TemplateSplit_SELS };
00511   virtual GncObject *startSubEl();
00512   virtual void endSubEl(GncObject *);
00513   // data elements
00514   enum TemplateSplitDataEls {ID, MEMO, RECON, VALUE, QTY, ACCT, END_TemplateSplit_DELS };
00515   mutable QPtrList<GncObject> m_kvpList;
00516 };
00517 // ************* GncSchedule********************************************
00518 class GncFreqSpec;
00519 class GncRecurrence;
00520 class GncSchedDef;
00521 class GncSchedule : public GncObject {
00522 public:
00523   GncSchedule ();
00524   ~GncSchedule();
00525 protected:
00526   friend class MyMoneyGncReader;
00527   // access data values
00528   QString name() const { return (var(NAME));};
00529   QString enabled() const {return var(ENABLED);};
00530   QString autoCreate() const { return (var(AUTOC));};
00531   QString autoCrNotify() const { return (var(AUTOCN));};
00532   QString autoCrDays() const { return (var(AUTOCD));};
00533   QString advCrDays() const { return (var(ADVCD));};
00534   QString advCrRemindDays() const { return (var(ADVRD));};
00535   QString instanceCount() const { return (var(INSTC));};
00536   QString numOccurs() const { return (var(NUMOCC));};
00537   QString remOccurs() const { return (var(REMOCC));};
00538   QString templId() const { return (var(TEMPLID));};
00539   QDate startDate () const
00540     {QDate x = QDate(); return (m_vpStartDate == NULL ? x : m_vpStartDate->date());};
00541   QDate lastDate () const
00542     {QDate x = QDate(); return (m_vpLastDate == NULL ? x : m_vpLastDate->date());};
00543   QDate endDate() const
00544     {QDate x = QDate(); return (m_vpEndDate == NULL ? x : m_vpEndDate->date());};
00545   const GncFreqSpec *getFreqSpec() const { return (m_vpFreqSpec);};
00546   const GncSchedDef *getSchedDef() const { return (m_vpSchedDef);};
00547 private:
00548   // subsidiary objects/elements
00549   enum ScheduleSubEls {STARTDATE, LASTDATE, ENDDATE, FREQ, RECURRENCE, DEFINST, END_Schedule_SELS };
00550   virtual GncObject *startSubEl();
00551   virtual void endSubEl(GncObject *);
00552   virtual void terminate();
00553   // data elements
00554   enum ScheduleDataEls {NAME, ENABLED, AUTOC, AUTOCN, AUTOCD, ADVCD, ADVRD, INSTC,
00555                         NUMOCC, REMOCC, TEMPLID, END_Schedule_DELS };
00556   GncDate *m_vpStartDate, *m_vpLastDate, *m_vpEndDate;
00557   GncFreqSpec *m_vpFreqSpec;
00558   mutable QPtrList<GncRecurrence> m_vpRecurrence; // gnc handles multiple occurrences
00559   GncSchedDef *m_vpSchedDef;
00560 };
00561 // ************* GncFreqSpec********************************************
00562 class GncFreqSpec : public GncObject {
00563 public:
00564   GncFreqSpec ();
00565   ~GncFreqSpec();
00566 protected:
00567   friend class MyMoneyGncReader;
00568   // access data values (only interval type used at present)
00569   QString intervalType() const { return (var(INTVT));};
00570 private:
00571   // subsidiary objects/elements
00572   enum FreqSpecSubEls {COMPO, END_FreqSpec_SELS };
00573   virtual GncObject *startSubEl();
00574   virtual void endSubEl(GncObject *);
00575   // data elements
00576   enum FreqSpecDataEls {INTVT, MONTHLY, DAILY, WEEKLY, INTVI, INTVO, INTVD, END_FreqSpec_DELS};
00577   virtual void terminate();
00578   mutable QPtrList<GncObject> m_fsList;
00579 };
00580 
00581 // ************* GncRecurrence********************************************
00582 // this object replaces GncFreqSpec from Gnucash 2.2 onwards
00583 class GncRecurrence : public GncObject {
00584 public:
00585   GncRecurrence ();
00586   ~GncRecurrence();
00587 protected:
00588   friend class MyMoneyGncReader;
00589   // access data values
00590   QDate startDate () const
00591     {QDate x = QDate(); return (m_vpStartDate == NULL ? x : m_vpStartDate->date());};
00592   QString mult() const {return (var(MULT));};
00593   QString periodType() const {return (var(PERIODTYPE));};
00594   QString getFrequency() const;
00595 private:
00596   // subsidiary objects/elements
00597   enum RecurrenceSubEls {STARTDATE, END_Recurrence_SELS };
00598   virtual GncObject *startSubEl();
00599   virtual void endSubEl(GncObject *);
00600   // data elements
00601   enum RecurrenceDataEls {MULT, PERIODTYPE, END_Recurrence_DELS};
00602   virtual void terminate();
00603   GncDate *m_vpStartDate;
00604 };
00605 
00606 // ************* GncSchedDef********************************************
00607 // This is a sub-object of GncSchedule, (sx:deferredInstance) function currently unknown
00608 class GncSchedDef : public GncObject {
00609   public:
00610     GncSchedDef ();
00611     ~GncSchedDef();
00612   protected:
00613     friend class MyMoneyGncReader;
00614   private:
00615   // subsidiary objects/elements
00616 };
00617 
00618 // ****************************************************************************************
00624 // *****************************************************************************************
00625 class XmlReader : public QXmlDefaultHandler {
00626 protected:
00627   friend class MyMoneyGncReader;
00628   XmlReader (MyMoneyGncReader *pM) : pMain(pM) {}  // keep pointer to 'main'
00629   void processFile (QIODevice*); // main entry point of reader
00630   //  define xml content handler functions
00631   bool startDocument ();
00632   bool startElement (const QString&, const QString&, const QString&, const QXmlAttributes&);
00633   bool endElement (const QString&, const QString&, const QString&);
00634   bool characters (const QString &);
00635   bool endDocument();
00636 private:
00637   QXmlInputSource *m_source;
00638   QXmlSimpleReader *m_reader;
00639   QPtrStack<GncObject> m_os; // stack of sub objects
00640   GncObject *m_co;           // current object, for ease of coding (=== m_os.top)
00641   MyMoneyGncReader *pMain;  // the 'main' pointer, to pass on to objects
00642   bool m_headerFound; // check for gnc-v2 header
00643 #ifdef _GNCFILEANON
00644   int lastType; // 0 = start element, 1 = data, 2 = end element
00645   int indentCount;
00646 #endif // _GNCFILEANON
00647 };
00648 
00652 class GncMessageArgs {
00653 protected:
00654   friend class MyMoneyGncReader;
00655   QString source; // 'type of message
00656   unsigned int code; // to identify actual message
00657   QValueList<QString> args; // variable arguments
00658 };
00659 
00660 class GncMessages {
00661 protected:
00662   friend class MyMoneyGncReader;
00663   static QString text (const QString, const unsigned int); // returns text of identified message
00664   static unsigned int argCount (const QString, const unsigned int); // returns no. of args required
00665 private:
00666   typedef struct {
00667     const QString source;
00668     const unsigned int code;
00669     QString text;
00670   }
00671   messText;
00672   static messText texts [];
00673 };
00674 
00680 #ifndef _GNCFILEANON
00681 class MyMoneyGncReader : public IMyMoneyStorageFormat {
00682 #else
00683 class MyMoneyGncReader {
00684 #endif // _GNCFILEANON
00685 public:
00686   MyMoneyGncReader();
00687   virtual ~MyMoneyGncReader();
00697 #ifndef _GNCFILEANON
00698   void readFile (QIODevice* pDevice, IMyMoneySerialize* storage); // main entry point, IODevice is gnucash file
00699   void writeFile (QIODevice*, IMyMoneySerialize*) { return ;}; // dummy entry needed by kmymoneywiew. we will not be writing
00700 #else
00701   void readFile (QString, QString);
00702 #endif // _GNCFILEANON
00703   QTextCodec *m_decoder;
00704 protected:
00705   friend class GncObject; // pity we can't just say GncObject. And compiler doesn't like multiple friends on one line...
00706   friend class GncFile; // there must be a better way...
00707   friend class GncDate;
00708   friend class GncCmdtySpec;
00709   friend class GncKvp;
00710   friend class GncLot;
00711   friend class GncCountData;
00712   friend class GncCommodity;
00713   friend class GncPrice;
00714   friend class GncAccount;
00715   friend class GncTransaction;
00716   friend class GncSplit;
00717   friend class GncTemplateTransaction;
00718   friend class GncTemplateSplit;
00719   friend class GncSchedule;
00720   friend class GncFreqSpec;
00721   friend class GncRecurrence;
00722   friend class XmlReader;
00723 #ifndef _GNCFILEANON
00724 
00725   void convertCommodity (const GncCommodity *);
00726   void convertPrice (const GncPrice *);
00727   void convertAccount (const GncAccount *);
00728   void convertTransaction (const GncTransaction *);
00729   void convertSplit (const GncSplit *);
00730   void saveTemplateTransaction (GncTransaction *t) {m_templateList.append (t);};
00731   void convertSchedule (const GncSchedule *);
00732   void convertFreqSpec (const GncFreqSpec *);
00733   void convertRecurrence (const GncRecurrence *);
00734 #else
00735 
00736   void convertCommodity (const GncCommodity *) {return;};
00737   void convertPrice (const GncPrice *) {return;};
00738   void convertAccount (const GncAccount *) {return;};
00739   void convertTransaction (const GncTransaction *) {return;};
00740   void convertSplit (const GncSplit *) {return;};
00741   void saveTemplateTransaction (GncTransaction *t)  {return;};
00742   void convertSchedule (const GncSchedule *) {return;};
00743   void convertFreqSpec (const GncFreqSpec *) {return;};
00744 #endif // _GNCFILEANON
00745 
00746   void postMessage (const QString&, const unsigned int, const char *);
00747   void postMessage (const QString&, const unsigned int, const char *, const char *);
00748   void postMessage (const QString&, const unsigned int, const char *, const char *, const char *);
00749   void postMessage (const QString&, const unsigned int, const QStringList&);
00750   void setProgressCallback (void(*callback)(int, int, const QString&));
00751   void signalProgress (int current, int total, const QString& = "");
00763   bool m_dropSuspectSchedules;
00776   unsigned int m_investmentOption;
00781   bool m_useFinanceQuote;
00788   bool m_useTxNotes;
00789     // set gnucash counts (not always accurate!)
00790   void setGncCommodityCount(int i) { m_gncCommodityCount = i;};
00791   void setGncAccountCount (int i) { m_gncAccountCount = i;};
00792   void setGncTransactionCount (int i) { m_gncTransactionCount = i;};
00793   void setGncScheduleCount (int i) { m_gncScheduleCount = i;};
00794   void setSmallBusinessFound (bool b) { m_smallBusinessFound = b;};
00795   void setBudgetsFound (bool b) { m_budgetsFound = b;};
00796   void setLotsFound (bool b) { m_lotsFound = b;};
00797   /*          Debug Options
00798     If you don't know what these are, best leave them alone.
00799        gncdebug - produce general debug messages
00800        xmldebug - produce a trace of the gnucash file XML
00801        bAnonymize - hide personal data (account names, payees, etc., randomize money amounts)
00802   */
00803   bool gncdebug; // general debug messages
00804   bool xmldebug; // xml trace
00805   bool bAnonymize; // anonymize input
00806   static double m_fileHideFactor; // an overall anonymization factor to be applied to all items
00807   bool developerDebug;
00808 private:
00809   void setOptions (); // to set user options from dialog
00810   void setFileHideFactor ();
00811   // the following handles the gnucash indicator for a bad value (-1/0) which causes us probs
00812   QString convBadValue (QString gncValue) const {return (gncValue == "-1/0" ? "0/1" : gncValue); };
00813 #ifndef _GNCFILEANON
00814   MyMoneyTransaction convertTemplateTransaction (const QString&, const GncTransaction *);
00815   void convertTemplateSplit (const QString&, const GncTemplateSplit *);
00816 #endif // _GNCFILEANON
00817   // wind up when all done
00818   void terminate();
00819   QString buildReportSection (const QString&);
00820   bool writeReportToFile (const QValueList<QString>&);
00821   // main storage
00822 #ifndef _GNCFILEANON
00823   IMyMoneyStorage *m_storage;
00824 #else
00825   QTextStream oStream;
00826 #endif // _GNCFILEANON
00827   XmlReader *m_xr;
00829   void (*m_progressCallback)(int, int, const QString&);
00830   // a map of which versions of the various elements (objects) we can import
00831   map_elementVersions m_versionList;
00832   // counters holding count data from the Gnc 'count-data' section
00833   int m_gncCommodityCount;
00834   int m_gncAccountCount;
00835   int m_gncTransactionCount;
00836   int m_gncScheduleCount;
00837 
00838   // flags indicating detection of features not (yet?) supported
00839   bool m_smallBusinessFound;
00840   bool m_budgetsFound;
00841   bool m_lotsFound;
00842 
00844   int m_commodityCount;
00845   int m_priceCount;
00846   int m_accountCount;
00847   int m_transactionCount;
00848   int m_templateCount;
00849   int m_scheduleCount;
00850 #ifndef _GNCFILEANON
00851   // counters for error reporting
00852   int m_ccCount, m_orCount, m_scCount;
00853   // currency counter
00854   QMap<QString, unsigned int> m_currencyCount;
00858   QMap<QString, QString> m_mapIds;
00859   QString m_rootId; // save the root id for terminate()
00860   QMap<QString, QString> m_mapEquities;
00861   QMap<QString, QString> m_mapSchedules;
00862   QMap<QString, QString> m_mapSources;
00867   QValueList<QString> m_stockList;
00871   QString m_txCommodity; // save commodity for current transaction
00872   QString m_txPayeeId;    // gnc has payee at tx level, we need it at split level
00873   QDate m_txDatePosted;   // ditto for post date
00874   QString m_txChequeNo;    // ditto for cheque number
00877   QValueList<MyMoneySplit> m_splitList, m_liabilitySplitList, m_otherSplitList;
00878   bool m_potentialTransfer;       // to determine whether this might be a transfer
00880   bool m_suspectSchedule;
00884   QPtrList<GncTransaction> m_templateList;
00886   QValueList<QString> m_suspectList;
00890   QPtrList<GncMessageArgs> m_messageList;
00891   GncMessages *m_messageTexts;
00895   QString createPayee (const QString&); // create a payee and return it's id
00896   QString createOrphanAccount (const QString&); // create unknown account and return the id
00897   QDate incrDate (QDate lastDate, unsigned char interval, unsigned int intervalCount); // for date calculations
00898   MyMoneyAccount checkConsistency (MyMoneyAccount& parent, MyMoneyAccount& child); // gnucash is sometimes TOO flexible
00899   void checkInvestmentOption (QString stockId); // implement user investment option
00900   void getPriceSource (MyMoneySecurity stock, QString gncSource);
00901 #endif // _GNCFILEANON
00902 };
00903 
00904 #endif // MYMONEYSTORAGEGNC_H

Generated on Wed Jan 26 13:03:18 2011 for KMyMoney by  doxygen 1.5.6