r18946 - gnucash/trunk/src/gnc - Cutecash: Code cleanup. Avoid crashes when undoing adding of new transactions by not deleting the tmp transaction object.

Christian Stimming cstim at code.gnucash.org
Sun Mar 21 17:37:50 EDT 2010


Author: cstim
Date: 2010-03-21 17:37:50 -0400 (Sun, 21 Mar 2010)
New Revision: 18946
Trac: http://svn.gnucash.org/trac/changeset/18946

Modified:
   gnucash/trunk/src/gnc/CMakeLists.txt
   gnucash/trunk/src/gnc/Split.cpp
   gnucash/trunk/src/gnc/Split.hpp
   gnucash/trunk/src/gnc/SplitListModel.cpp
   gnucash/trunk/src/gnc/Transaction.cpp
   gnucash/trunk/src/gnc/Transaction.hpp
   gnucash/trunk/src/gnc/mainwindow-file.cpp
Log:
Cutecash: Code cleanup. Avoid crashes when undoing adding of new transactions by not deleting the tmp transaction object.

Also, correctly set the document state to "clean" after saving.

Modified: gnucash/trunk/src/gnc/CMakeLists.txt
===================================================================
--- gnucash/trunk/src/gnc/CMakeLists.txt	2010-03-21 20:38:12 UTC (rev 18945)
+++ gnucash/trunk/src/gnc/CMakeLists.txt	2010-03-21 21:37:50 UTC (rev 18946)
@@ -40,6 +40,8 @@
   Book.hpp
   Cmd.hpp
   Commodity.hpp
+  GncInstance.hpp
+  Numeric.hpp
   QofEventWrapper.hpp
   Session.hpp
   Split.hpp

Modified: gnucash/trunk/src/gnc/Split.cpp
===================================================================
--- gnucash/trunk/src/gnc/Split.cpp	2010-03-21 20:38:12 UTC (rev 18945)
+++ gnucash/trunk/src/gnc/Split.cpp	2010-03-21 21:37:50 UTC (rev 18946)
@@ -39,55 +39,55 @@
 
 
 TmpSplit::TmpSplit(const Split& s, const TmpTransaction* parent_trans)
-        : account(s.getAccount().get())
-        , parent(parent_trans)
-        , memo(s.getMemo())
-        , action(s.getAction())
-        , reconcile(s.getReconcile())
-        , amount(s.getAmount())
-        , value(s.getValue())
+        : m_account(s.getAccount().get())
+        , m_parent(parent_trans)
+        , m_memo(s.getMemo())
+        , m_action(s.getAction())
+        , m_reconcile(s.getReconcile())
+        , m_amount(s.getAmount())
+        , m_value(s.getValue())
 {}
 
-TmpSplit::TmpSplit(::Account* _account)
+TmpSplit::TmpSplit(::Account* account)
 {
-    clear(_account);
+    clear(account);
 }
 
 TmpSplit* TmpSplit::getOtherSplit() const
 {
-    if (!parent)
+    if (!m_parent)
         return NULL;
-    const TmpTransaction& p = *parent;
+    const TmpTransaction& p = *m_parent;
     if (p.countSplits() != 2)
         return NULL;
     TmpTransaction::TmpSplitQList& splits = const_cast<TmpTransaction&>(p).getSplits();
-    if (splits.front().getAccount() != account)
+    if (splits.front().getAccount() != m_account)
         return &splits.front();
     else
         return &splits.back();
 }
 
-void TmpSplit::clear(::Account* _account)
+void TmpSplit::clear(::Account* account)
 {
-    account = _account;
-    parent = NULL;
-    memo.clear();
-    action.clear();
-    reconcile = '\0';
-    amount = Numeric::zero();
-    value = Numeric::zero();
+    m_account = account;
+    m_parent = NULL;
+    m_memo.clear();
+    m_action.clear();
+    m_reconcile = NREC;
+    m_amount = Numeric::zero();
+    m_value = Numeric::zero();
 }
 
-void TmpSplit::copyInto(Transaction& t)
+void TmpSplit::copyInto(Transaction& t) const
 {
     Split s(xaccMallocSplit(t.getBook().get()));
-    s.setAccount(account);
+    s.setAccount(m_account);
     s.setParent(t);
-    s.setMemo(memo);
-    s.setAction(action);
-    s.setReconcile(reconcile);
-    s.setAmount(amount);
-    s.setValue(value);
+    s.setMemo(m_memo);
+    s.setAction(m_action);
+    s.setReconcile(m_reconcile);
+    s.setAmount(m_amount);
+    s.setValue(m_value);
 }
 
 } // END namespace gnc

Modified: gnucash/trunk/src/gnc/Split.hpp
===================================================================
--- gnucash/trunk/src/gnc/Split.hpp	2010-03-21 20:38:12 UTC (rev 18945)
+++ gnucash/trunk/src/gnc/Split.hpp	2010-03-21 21:37:50 UTC (rev 18946)
@@ -112,46 +112,69 @@
     }
 };
 
+
+/** This is a temporary split which belongs to a temporary transaction
+ * (class gnc::TmpTransaction). Each of this tmp splits has all data
+ * fields just like a "real" split, but it is not (yet) added to the
+ * respective Account and Book. In other words, it is not stored in
+ * the book yet.
+ *
+ * For this reason this class supports a full copy-by-value, which
+ * will create new independent instances of all data fields. */
 class TmpSplit
 {
 public:
+    /** Creates a new tmp split whose content is copied from the given
+     * real transaction and it should belong to the given
+     * TmpTransaction (but it is not added to the TmpTransaction's
+     * split list here). */
     TmpSplit(const Split& s, const TmpTransaction* parent_trans);
+
+    /** Creates a new empty tmp split, with the Account pointer
+     * initialized with the given value. */
     TmpSplit(::Account* account = NULL);
 
+    /** Clears all data fields of this split. */
     void clear(::Account* account = NULL);
-    void copyInto(Transaction& t);
 
-    ::Account* getAccount() const { return account; }
-    void setAccount(::Account* v) { account = v;}
+    /** Copies the content of this tmp split into the given real
+     * transaction by allocating a new real gnc::Split and adding it
+     * to the given real gnc::Transaction. */
+    void copyInto(Transaction& t) const;
 
-    const TmpTransaction* getParent() const { return parent; }
-    void setParent(const TmpTransaction* v) { parent = v; }
+    ::Account* getAccount() const { return m_account; }
+    void setAccount(::Account* v) { m_account = v;}
 
+    const TmpTransaction* getParent() const { return m_parent; }
+    void setParent(const TmpTransaction* v) { m_parent = v; }
+
+    /** Returns a pointer to the "Other" split if it exists, or NULL
+     * if none or multiple of them exist. */
     TmpSplit* getOtherSplit() const;
 
-    QString getMemo() const { return memo; }
-    void setMemo(const QString& v) { memo = v; }
+    QString getMemo() const { return m_memo; }
+    void setMemo(const QString& v) { m_memo = v; }
 
-    QString getAction() const { return action; }
-    void setAction(const QString& v) { action = v; }
+    QString getAction() const { return m_action; }
+    void setAction(const QString& v) { m_action = v; }
 
-    char getReconcile() const { return reconcile; }
-    void setReconcile(char v) { reconcile = v; }
+    char getReconcile() const { return m_reconcile; }
+    void setReconcile(char v) { m_reconcile = v; }
 
-    Numeric getAmount() const { return amount; }
-    void setAmount(const Numeric& v) { amount = v; }
+    Numeric getAmount() const { return m_amount; }
+    void setAmount(const Numeric& v) { m_amount = v; }
 
-    Numeric getValue() const { return value; }
-    void setValue(const Numeric& v) { value = v; }
+    Numeric getValue() const { return m_value; }
+    void setValue(const Numeric& v) { m_value = v; }
 
 private:
-    ::Account* account;
-    const TmpTransaction* parent;
-    QString memo;
-    QString action;
-    char reconcile;
-    Numeric amount;
-    Numeric value;
+    ::Account* m_account;
+    const TmpTransaction* m_parent;
+    QString m_memo;
+    QString m_action;
+    char m_reconcile;
+    Numeric m_amount;
+    Numeric m_value;
 };
 
 } // END namespace gnc

Modified: gnucash/trunk/src/gnc/SplitListModel.cpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListModel.cpp	2010-03-21 20:38:12 UTC (rev 18945)
+++ gnucash/trunk/src/gnc/SplitListModel.cpp	2010-03-21 21:37:50 UTC (rev 18946)
@@ -48,6 +48,9 @@
         , m_enableNewTransaction(true)
 {
     recreateCache();
+
+    m_tmpTransaction.push_back(TmpSplit(NULL));
+    m_tmpTransaction.push_back(TmpSplit(NULL));
     recreateTmpTrans();
 }
 
@@ -71,15 +74,20 @@
 
 void SplitListModel::recreateTmpTrans()
 {
-    m_tmpTransaction.clear();
+    m_tmpTransaction.resetContent();
+    while (m_tmpTransaction.countSplits() > 2)
+        m_tmpTransaction.getSplits().pop_back();
+    Q_ASSERT(m_tmpTransaction.countSplits() == 2);
+
     m_tmpTransaction.setCommodity(m_account.getCommodity());
     m_tmpTransaction.setDatePosted(QDate::currentDate());
-    m_tmpTransaction.push_back(TmpSplit(m_account.get()));
-    m_tmpTransaction.push_back(TmpSplit(NULL));
+    TmpSplit& oursplit = m_tmpTransaction.getSplits().front();
+    TmpSplit& othersplit = m_tmpTransaction.getSplits().back();
+    oursplit.setAccount(m_account.get());
 
     Q_ASSERT(m_tmpTransaction.countSplits() == 2);
-    Q_ASSERT(m_tmpTransaction.getSplits().front().getAccount() == m_account.get());
-    Q_ASSERT(m_tmpTransaction.getSplits().back().getAccount() == NULL);
+    Q_ASSERT(oursplit.getAccount() == m_account.get());
+    Q_ASSERT(othersplit.getAccount() == NULL);
 }
 
 SplitListModel::~SplitListModel()

Modified: gnucash/trunk/src/gnc/Transaction.cpp
===================================================================
--- gnucash/trunk/src/gnc/Transaction.cpp	2010-03-21 20:38:12 UTC (rev 18945)
+++ gnucash/trunk/src/gnc/Transaction.cpp	2010-03-21 21:37:50 UTC (rev 18946)
@@ -54,47 +54,61 @@
     clear();
 }
 TmpTransaction::TmpTransaction(const Transaction& t)
-        : num(t.getNum())
-        , description(t.getDescription())
-        , notes(t.getNotes())
-        , commodity(t.getCurrency())
-        , datePosted(t.getDatePosted())
-        , dateTimeEntered(t.getDateEntered())
+        : m_num(t.getNum())
+        , m_description(t.getDescription())
+        , m_notes(t.getNotes())
+        , m_commodity(t.getCurrency())
+        , m_datePosted(t.getDatePosted())
+        , m_dateTimeEntered(t.getDateEntered())
 {
     SplitQList slist = Split::fromGList(t.getSplitList());
     Q_FOREACH(Split s, slist)
     {
-        splits.push_back(TmpSplit(s, this));
+        m_splits.push_back(TmpSplit(s, this));
     }
 }
+
 void TmpTransaction::clear()
 {
-    num.clear();
-    description.clear();
-    notes.clear();
-    commodity.reset();
-    datePosted = QDate();
-    dateTimeEntered = QDateTime();
-    splits.clear();
+    m_splits.clear();
+    resetContent();
 }
+
+void TmpTransaction::resetContent()
+{
+    m_num.clear();
+    m_description.clear();
+    m_notes.clear();
+    m_commodity.reset();
+    m_datePosted = QDate();
+    m_dateTimeEntered = QDateTime();
+    for (int i = 0; i < m_splits.size(); ++i)
+    {
+        TmpSplit& split = m_splits[i];
+        split.clear();
+        split.setParent(this);
+    }
+}
+
 void TmpTransaction::copyTo(Transaction& t) const
 {
-    t.setNum(num);
-    t.setDescription(description);
-    if (!notes.isEmpty())
-        t.setNotes(notes);
-    t.setCurrency(commodity);
-    t.setDatePosted(datePosted);
-    t.setDateEntered(dateTimeEntered);
-    Q_FOREACH(TmpSplit s, splits)
+    t.setNum(m_num);
+    t.setDescription(m_description);
+    if (!m_notes.isEmpty())
+        t.setNotes(m_notes);
+    t.setCurrency(m_commodity);
+    t.setDatePosted(m_datePosted);
+    t.setDateEntered(m_dateTimeEntered);
+    for (int i = 0; i < m_splits.size(); ++i)
     {
-        s.copyInto(t);
+        m_splits[i].copyInto(t);
     }
 }
+
 Transaction TmpTransaction::createAsReal() const
 {
-    Q_ASSERT (!splits.isEmpty());
-    Account acc(splits.front().getAccount());
+    Q_ASSERT (!m_splits.isEmpty());
+    Account acc(m_splits.front().getAccount());
     Q_ASSERT (acc);
     Book book(acc.getBook());
     Q_ASSERT (book);
@@ -104,10 +118,11 @@
     trans.commitEdit();
     return trans;
 }
+
 void TmpTransaction::push_back(const TmpSplit& s)
 {
-    splits.push_back(s);
-    splits.back().setParent(this);
+    m_splits.push_back(s);
+    m_splits.back().setParent(this);
 }
 
 } // END namespace gnc

Modified: gnucash/trunk/src/gnc/Transaction.hpp
===================================================================
--- gnucash/trunk/src/gnc/Transaction.hpp	2010-03-21 20:38:12 UTC (rev 18945)
+++ gnucash/trunk/src/gnc/Transaction.hpp	2010-03-21 21:37:50 UTC (rev 18946)
@@ -100,46 +100,71 @@
 };
 
 
+/** This is a temporary transaction. Each of this tmp transactions has
+ * all data fields just like a "real" transaction, but it is not (yet)
+ * added to the respective Account and Book. In other words, it is not
+ * stored in the book yet.
+ *
+ * For this reason this class supports a full copy-by-value, which
+ * will create new independent instances of all data fields. */
 class TmpTransaction
 {
 public:
     typedef QList<TmpSplit> TmpSplitQList;
 
+    /** Creates an empty tmp transaction */
     TmpTransaction();
+
+    /** Creates a tmp transaction whose content is copied from the
+     * given real transaction */
     TmpTransaction(const Transaction& t);
 
+    /** Clears all data fields of this transaction, including deletion
+     * of all splits stored here. */
     void clear();
+
+    /** Clears all data fields, but does not delete the splits and
+     * instead only resets the data fields of all splits */
+    void resetContent();
+
+    /** Copies the content of this tmp transaction into the given real
+     * transaction. */
     void copyTo(Transaction& t) const;
+
+    /** Allocates a new real transaction in the Book and Account as
+     * stored in the tmp transaction, copies the content of this tmp
+     * transaction into the newly allocated one, and returns the
+     * pointer to the newly created real transaction. */
     Transaction createAsReal() const;
 
-    QString getNum() const { return num; }
-    void setNum(const QString& v) { num = v; }
+    QString getNum() const { return m_num; }
+    void setNum(const QString& v) { m_num = v; }
 
-    QString getDescription() const { return description; }
-    void setDescription(const QString& v) { description = v; }
+    QString getDescription() const { return m_description; }
+    void setDescription(const QString& v) { m_description = v; }
 
     void push_back(const TmpSplit& s);
-    const TmpSplitQList& getSplits() const { return splits; }
-    TmpSplitQList& getSplits() { return splits; }
-    int countSplits() const { return splits.size(); }
+    const TmpSplitQList& getSplits() const { return m_splits; }
+    TmpSplitQList& getSplits() { return m_splits; }
+    int countSplits() const { return m_splits.size(); }
 
-    Commodity getCommodity() const { return commodity; }
-    void setCommodity(const Commodity& v) { commodity = v; }
+    Commodity getCommodity() const { return m_commodity; }
+    void setCommodity(const Commodity& v) { m_commodity = v; }
 
-    QDate getDatePosted() const { return datePosted; }
-    void setDatePosted(const QDate& v) { datePosted = v; }
+    QDate getDatePosted() const { return m_datePosted; }
+    void setDatePosted(const QDate& v) { m_datePosted = v; }
 
-    QDateTime getDateEntered() const { return dateTimeEntered; }
-    void setDateEntered(const QDateTime& v) { dateTimeEntered = v; }
+    QDateTime getDateEntered() const { return m_dateTimeEntered; }
+    void setDateEntered(const QDateTime& v) { m_dateTimeEntered = v; }
 
 private:
-    QString num;
-    QString description;
-    QString notes;
-    TmpSplitQList splits;
-    Commodity commodity;
-    QDate datePosted;
-    QDateTime dateTimeEntered;
+    QString m_num;
+    QString m_description;
+    QString m_notes;
+    TmpSplitQList m_splits;
+    Commodity m_commodity;
+    QDate m_datePosted;
+    QDateTime m_dateTimeEntered;
 };
 
 } // END namespace gnc

Modified: gnucash/trunk/src/gnc/mainwindow-file.cpp
===================================================================
--- gnucash/trunk/src/gnc/mainwindow-file.cpp	2010-03-21 20:38:12 UTC (rev 18945)
+++ gnucash/trunk/src/gnc/mainwindow-file.cpp	2010-03-21 21:37:50 UTC (rev 18946)
@@ -769,6 +769,7 @@
     xaccReopenLog();
     gnc_hook_run(HOOK_BOOK_SAVED, m_session.get());
 
+    documentCleanStateChanged(true);
     statusBar()->showMessage(tr("File saved"), 5000);
     return true;
 }



More information about the gnucash-changes mailing list