r18935 - gnucash/trunk/src/gnc - Cutecash: Implement entering new transactions in the register.

Christian Stimming cstim at code.gnucash.org
Fri Mar 19 18:01:56 EDT 2010


Author: cstim
Date: 2010-03-19 18:01:56 -0400 (Fri, 19 Mar 2010)
New Revision: 18935
Trac: http://svn.gnucash.org/trac/changeset/18935

Added:
   gnucash/trunk/src/gnc/SplitListView.cpp
   gnucash/trunk/src/gnc/SplitListView.hpp
Modified:
   gnucash/trunk/src/gnc/CMakeLists.txt
   gnucash/trunk/src/gnc/Cmd.cpp
   gnucash/trunk/src/gnc/Cmd.hpp
   gnucash/trunk/src/gnc/Split.cpp
   gnucash/trunk/src/gnc/SplitListModel.cpp
   gnucash/trunk/src/gnc/SplitListModel.hpp
   gnucash/trunk/src/gnc/Transaction.cpp
   gnucash/trunk/src/gnc/Transaction.hpp
   gnucash/trunk/src/gnc/mainwindow-file.cpp
   gnucash/trunk/src/gnc/mainwindow.cpp
   gnucash/trunk/src/gnc/mainwindow.ui
Log:
Cutecash: Implement entering new transactions in the register.

Only the account selection is still missing.

Modified: gnucash/trunk/src/gnc/CMakeLists.txt
===================================================================
--- gnucash/trunk/src/gnc/CMakeLists.txt	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/CMakeLists.txt	2010-03-19 22:01:56 UTC (rev 18935)
@@ -19,6 +19,7 @@
   Session.cpp
   Split.cpp
   SplitListModel.cpp
+  SplitListView.cpp
   Transaction.cpp
   main.cpp
   mainwindow.cpp
@@ -29,6 +30,7 @@
   AccountItemModel.hpp
   RecentFileMenu.hpp
   SplitListModel.hpp
+  SplitListView.hpp
   mainwindow.hpp
 )
 SET (gnc_HEADERS ${gnc_QOBJECT_HEADERS}

Modified: gnucash/trunk/src/gnc/Cmd.cpp
===================================================================
--- gnucash/trunk/src/gnc/Cmd.cpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/Cmd.cpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -41,14 +41,14 @@
 {
     return new Cmd<Split, QString>(QObject::tr("Edit Split Memo"),
                                    t, &Split::setMemo,
-                                   &Split::getMemo, newValue);
+                                   t.getMemo(), newValue);
 }
 
 QUndoCommand* setSplitAction(Split& t, const QString& newValue)
 {
     return new Cmd<Split, QString>(QObject::tr("Edit Split Action"),
                                    t, &Split::setAction,
-                                   &Split::getAction, newValue);
+                                   t.getAction(), newValue);
 }
 
 QUndoCommand* setSplitReconcile(Split& t, char newValue)
@@ -58,21 +58,21 @@
     // must be given explicitly.
     return new Cmd<Split, char, void (Split::*)(char)>(QObject::tr("Edit Split Reconcile"),
             t, &Split::setReconcile,
-            &Split::getReconcile, newValue);
+            t.getReconcile(), newValue);
 }
 
 QUndoCommand* setSplitAmount(Split& t, const Numeric& newValue)
 {
     return new Cmd<Split, Numeric>(QObject::tr("Edit Split Amount"),
                                    t, &Split::setAmount,
-                                   &Split::getAmount, newValue);
+                                   t.getAmount(), newValue);
 }
 
 QUndoCommand* setSplitValue(Split& t, const Numeric& newValue)
 {
     return new Cmd<Split, Numeric>(QObject::tr("Edit Split Value"),
                                    t, &Split::setValue,
-                                   &Split::getValue, newValue);
+                                   t.getValue(), newValue);
 }
 
 // ////////////////////////////////////////////////////////////
@@ -100,17 +100,8 @@
         Q_ASSERT(m_target);
     }
 
-    virtual void redo()
-    {
-        set(m_newValue);
-    }
-
-    virtual void undo()
-    {
-        set(m_previousValue);
-    }
-
-
+    virtual void redo() { set(m_newValue); }
+    virtual void undo() { set(m_previousValue); }
 private:
     void set(const value_type& value)
     {
@@ -226,29 +217,215 @@
                                      t);
 }
 
+// ////////////////////////////////////////////////////////////
 
+/** This is another templated implementation of a QUndoCommand
+ * class, this time with keeping a direct reference to the target object.
+ *
+ * This implements the Command pattern: Any instance of this
+ * class represents the change of one member variable (of type ValueT)
+ * in an instance of a TargetT object.
+ *
+ * As we need to keep a reference to the original object, it is
+ * relevant who owns the life cycle of that original object. For
+ * simplicity, we constrain this current implementation only to
+ * classes which are implementations of a WeakPointer<...> which by
+ * definition keeps a C pointer to the original object, and we hope
+ * that one lives longer than we do.
+ */
+template<class TargetT, class ValueT, typename SetterFunc = void (TargetT::*)(const ValueT&)>
+class CmdRef : public QUndoCommand
+{
+public:
+    /// The base class
+    typedef QUndoCommand base_class;
+
+    /// Type of the target object on which this command is applied
+    typedef TargetT target_type;
+
+    /// Type of the value that is set by this command
+    typedef ValueT value_type;
+
+    /// Type of the setter function to set the value in the target object
+    typedef SetterFunc setter_func;
+
+    /** Constructor with the previous value given directly.
+     *
+     * @param text The QUndoCommand's text which will be displayed in the Undo action.
+     * @param targetRef Reference to the target object on which this command is applied.
+     * @param setter Pointer to function which sets the value in the target object
+     * @param previousValue The previous value, in case this command needs to be undone
+     * @param newValue The new value to be set
+     * @param parent The parent QUndoCommand instance, or NULL.
+     */
+    CmdRef(const QString& text,
+           TargetT& targetRef,
+           setter_func setter,
+           const value_type& previousValue,
+           const value_type& newValue,
+           QUndoCommand *parent = 0)
+            : base_class(text, parent)
+            , m_target(targetRef)
+            , m_setter(setter)
+            , m_previousValue(previousValue)
+            , m_newValue(newValue)
+    {
+        Q_ASSERT(m_setter);
+    }
+
+    virtual void redo() { set(m_newValue); }
+    virtual void undo() { set(m_previousValue); }
+
+private:
+    void set(const value_type& value)
+    {
+        // Call the pointer-to-member which is stored in m_setter.
+        (m_target.*m_setter)(value);
+    }
+
+protected:
+    target_type& m_target;
+    setter_func m_setter;
+    value_type m_previousValue;
+    value_type m_newValue;
+};
+
+
 QUndoCommand* setSplitReconcile(TmpSplit& t, char newValue)
 {
-    return 0;
+    // Special third argument: The setter function takes a value
+    // directly, instead of a const-reference, so the template type
+    // must be given explicitly.
+    return new CmdRef<TmpSplit, char, void (TmpSplit::*)(char)>(QObject::tr("Edit Split Reconcile"),
+            t, &TmpSplit::setReconcile,
+            t.getReconcile(), newValue);
 }
 QUndoCommand* setTransactionNum(TmpTransaction& t, const QString& newValue)
 {
-    return 0;
+    return new CmdRef<TmpTransaction, QString>(QObject::tr("Edit Transaction Number"),
+            t, &TmpTransaction::setNum,
+            t.getNum(), newValue);
 }
 QUndoCommand* setTransactionDescription(TmpTransaction& t, const QString& newValue)
 {
-    return 0;
+    return new CmdRef<TmpTransaction, QString>(QObject::tr("Edit Transaction Description"),
+            t, &TmpTransaction::setDescription,
+            t.getDescription(), newValue);
 }
 QUndoCommand* setTransactionDate(TmpTransaction& t, const QDate& newValue)
 {
-    return 0;
+    return new CmdRef<TmpTransaction, QDate>(QObject::tr("Edit Transaction Date"),
+            t, &TmpTransaction::setDatePosted,
+            t.getDatePosted(), newValue);
 }
+
+// ////////////////////////////////////////////////////////////
+
+class TmpSplitValueAndAmountCmd : public QUndoCommand
+{
+public:
+    typedef QUndoCommand base_class;
+    typedef TmpSplit target_type;
+    typedef Numeric value_type;
+
+    /** Constructor without a getter-function but instead the previous
+     * value given directly.
+     */
+    TmpSplitValueAndAmountCmd(const QString& text,
+                              target_type& targetRef,
+                              const value_type& previousValue,
+                              const value_type& newValue,
+                              QUndoCommand *parent = 0)
+            : base_class(text, parent)
+            , m_target(targetRef)
+            , m_previousValue(previousValue)
+            , m_newValue(newValue)
+    {
+    }
+
+    virtual void redo() { set(m_newValue); }
+    virtual void undo() { set(m_previousValue); }
+private:
+    void set(const value_type& value)
+    {
+        const TmpTransaction* p_trans = m_target.getParent();
+//         if (trans.countSplits() != 2)
+//             return;
+//         Split other = m_target.getOtherSplit();
+//         Q_ASSERT(other);
+//         Commodity originCommodity = m_target.getAccount().getCommodity();
+//         Commodity transCommodity = trans.getCurrency();
+//         Commodity otherCommodity = other.getAccount().getCommodity();
+//         if (originCommodity != transCommodity
+//                 || transCommodity != otherCommodity)
+//             return;
+
+//         trans.beginEdit();
+        m_target.setValue(value);
+        m_target.setAmount(value);
+//         Numeric valueNeg = value.neg();
+//         other.setAmount(valueNeg);
+//         other.setValue(valueNeg);
+//         trans.commitEdit();
+    }
+
+protected:
+    target_type& m_target;
+    value_type m_previousValue;
+    value_type m_newValue;
+
+};
+
+
 QUndoCommand* setSplitValueAndAmount(TmpSplit& t, const Numeric& newValue)
 {
-    return 0;
+    return new TmpSplitValueAndAmountCmd(QObject::tr("Edit Transaction Value"),
+                                         t, t.getValue(), newValue);
 }
 
+// ////////////////////////////////////////////////////////////
 
+
+
+class TransactionCreateCmd : public QUndoCommand
+{
+public:
+    typedef QUndoCommand base_class;
+    typedef TmpTransaction target_type;
+
+    /** Constructor
+     */
+    TransactionCreateCmd(const QString& text,
+                         const target_type target,
+                         QUndoCommand *parent = 0)
+            : base_class(text, parent)
+            , m_template(target)
+            , m_created(NULL)
+    {}
+
+    virtual void redo()
+    {
+        m_created = m_template.createAsReal();
+    }
+
+    virtual void undo()
+    {
+        xaccTransDestroy(m_created.get());
+        m_created.reset();
+    }
+
+protected:
+    target_type m_template;
+    Transaction m_created;
+};
+
+QUndoCommand* commitNewTransaction(const TmpTransaction& t)
+{
+    return new TransactionCreateCmd(QObject::tr("Create Transaction"), t);
+}
+
+
+
 } // END namespace cmd
 
 

Modified: gnucash/trunk/src/gnc/Cmd.hpp
===================================================================
--- gnucash/trunk/src/gnc/Cmd.hpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/Cmd.hpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -174,6 +174,7 @@
 QUndoCommand* setSplitValueAndAmount(Split& t, const Numeric& newValue);
 QUndoCommand* setSplitValueAndAmount(TmpSplit& t, const Numeric& newValue);
 QUndoCommand* destroyTransaction(Transaction& t);
+QUndoCommand* commitNewTransaction(const TmpTransaction& t);
 
 } // END namespace cmd
 

Modified: gnucash/trunk/src/gnc/Split.cpp
===================================================================
--- gnucash/trunk/src/gnc/Split.cpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/Split.cpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -48,14 +48,14 @@
         , value(s.getValue())
 {}
 
-TmpSplit::TmpSplit(::Account* account)
+TmpSplit::TmpSplit(::Account* _account)
 {
-    clear(account);
+    clear(_account);
 }
 
-void TmpSplit::clear(::Account* account)
+void TmpSplit::clear(::Account* _account)
 {
-    account = account;
+    account = _account;
     parent = NULL;
     memo.clear();
     action.clear();

Modified: gnucash/trunk/src/gnc/SplitListModel.cpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListModel.cpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/SplitListModel.cpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -127,7 +127,7 @@
 //     if (!parent.isValid())
 //         return 0;
 //     else
-    return 8; // Fixed number for now
+    return COLUMN_LAST; // Fixed number for now
 }
 
 Qt::ItemFlags SplitListModel::flags(const QModelIndex &index) const
@@ -139,14 +139,16 @@
     Qt::ItemFlags result = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
     switch (index.column())
     {
-    case 0:
-    case 1:
-    case 2:
-    case 4:
-    case 5:
-    case 6:
+    case COLUMN_DATE:
+    case COLUMN_NUM:
+    case COLUMN_DESC:
+    case COLUMN_RECONCILE:
+    case COLUMN_INCREASE:
+    case COLUMN_DECREASE:
         // Allow write access as well
         return result | Qt::ItemIsEditable;
+    case COLUMN_ACCOUNT:
+    case COLUMN_BALANCE:
     default:
         // Ensure read-only access only
         return result;
@@ -170,7 +172,7 @@
         PrintAmountInfo printInfo(m_account, false);
         switch (index.column())
         {
-        case 0:
+        case COLUMN_DATE:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -179,7 +181,7 @@
             default:
                 return QVariant();
             }
-        case 1:
+        case COLUMN_NUM:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -188,7 +190,7 @@
             default:
                 return QVariant();
             }
-        case 2:
+        case COLUMN_DESC:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -197,7 +199,7 @@
             default:
                 return QVariant();
             }
-        case 3:
+        case COLUMN_ACCOUNT:
             switch (role)
             {
 //         case Qt::DisplayRole:
@@ -205,7 +207,7 @@
             default:
                 return QVariant();
             }
-        case 4:
+        case COLUMN_RECONCILE:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -214,31 +216,31 @@
             default:
                 return QVariant();
             }
-        case 5:
+        case COLUMN_INCREASE:
             switch (role)
             {
             case Qt::DisplayRole:
             case Qt::EditRole:
-                if (amount.positive_p())
+                if (!amount.zero_p() && amount.positive_p())
                     return amount.printAmount(printInfo);
                 else
                     return QString();
             default:
                 return QVariant();
             }
-        case 6:
+        case COLUMN_DECREASE:
             switch (role)
             {
             case Qt::DisplayRole:
             case Qt::EditRole:
-                if (amount.positive_p())
+                if (amount.zero_p() || amount.positive_p())
                     return QString();
                 else
                     return amount.neg().printAmount(printInfo);
             default:
                 return QVariant();
             }
-        case 7:
+        case COLUMN_BALANCE:
         default:
             return QVariant();
         }
@@ -257,7 +259,7 @@
 
         switch (index.column())
         {
-        case 0:
+        case COLUMN_DATE:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -266,7 +268,7 @@
             default:
                 return QVariant();
             }
-        case 1:
+        case COLUMN_NUM:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -275,7 +277,7 @@
             default:
                 return QVariant();
             }
-        case 2:
+        case COLUMN_DESC:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -284,7 +286,7 @@
             default:
                 return QVariant();
             }
-        case 3:
+        case COLUMN_ACCOUNT:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -292,7 +294,7 @@
             default:
                 return QVariant();
             }
-        case 4:
+        case COLUMN_RECONCILE:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -301,7 +303,7 @@
             default:
                 return QVariant();
             }
-        case 5:
+        case COLUMN_INCREASE:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -313,7 +315,7 @@
             default:
                 return QVariant();
             }
-        case 6:
+        case COLUMN_DECREASE:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -325,7 +327,7 @@
             default:
                 return QVariant();
             }
-        case 7:
+        case COLUMN_BALANCE:
             switch (role)
             {
             case Qt::DisplayRole:
@@ -352,21 +354,21 @@
     {
         switch (section)
         {
-        case 0:
+        case COLUMN_DATE:
             return tr("Date");
-        case 1:
+        case COLUMN_NUM:
             return tr("Num");
-        case 2:
+        case COLUMN_DESC:
             return tr("Description");
-        case 3:
+        case COLUMN_ACCOUNT:
             return tr("Transfer");
-        case 4:
+        case COLUMN_RECONCILE:
             return tr("R?");
-        case 5:
+        case COLUMN_INCREASE:
             return tr("Increase");
-        case 6:
+        case COLUMN_DECREASE:
             return tr("Decrease");
-        case 7:
+        case COLUMN_BALANCE:
             return tr("Balance");
         default:
             return QVariant();
@@ -396,7 +398,7 @@
         // spooky, doesn't it?
         switch (index.column())
         {
-        case 0:
+        case COLUMN_DATE:
         {
             QDate date = value.toDate();
             if (date.isValid())
@@ -405,13 +407,13 @@
             }
             break;
         }
-        case 1:
+        case COLUMN_NUM:
             cmd = cmd::setTransactionNum(trans, value.toString());
             break;
-        case 2:
+        case COLUMN_DESC:
             cmd = cmd::setTransactionDescription(trans, value.toString());
             break;
-        case 4:
+        case COLUMN_RECONCILE:
         {
             QString str(value.toString());
             if (str.size() > 0)
@@ -432,22 +434,22 @@
             }
             break;
         }
-        case 5:
-        case 6:
+        case COLUMN_INCREASE:
+        case COLUMN_DECREASE:
         {
             QString str(value.toString().simplified());
             Numeric n;
             QString errmsg = n.parse(str);
             if (errmsg.isEmpty())
             {
-                qDebug() << "Does setting numeric work? numeric=" << n.to_string();
-                if (index.column() == 6)
+                qDebug() << "Successfully parsed string to numeric=" << n.to_string();
+                if (index.column() == COLUMN_DECREASE)
                     n = n.neg();
                 // Check whether we have the simple case here
-                if (trans.getSplits().size() != 1)
+                if (trans.countSplits() != 1)
                 {
                     QMessageBox::warning(NULL, tr("Unimplemented"),
-                                         tr("Sorry, but editing a transaction with more than two splits (here: %1) is not yet implemented.").arg(trans.getSplits().size()));
+                                         tr("Sorry, but editing a transaction with more than two splits (here: %1) is not yet implemented.").arg(trans.countSplits()));
                 }
                 else
                 {
@@ -490,7 +492,7 @@
         // spooky, doesn't it?
         switch (index.column())
         {
-        case 0:
+        case COLUMN_DATE:
         {
             QDate date = value.toDate();
             if (date.isValid())
@@ -499,16 +501,16 @@
             }
             break;
         }
-        case 1:
+        case COLUMN_NUM:
             cmd = cmd::setTransactionNum(trans, value.toString());
             break;
-        case 2:
+        case COLUMN_DESC:
             cmd = cmd::setTransactionDescription(trans, value.toString());
             break;
-        case 4:
+        case COLUMN_RECONCILE:
         {
             QString str(value.toString());
-            if (str.size() > 0)
+            if (!str.isEmpty())
             {
                 char recn = str[0].toLatin1();
                 switch (recn)
@@ -526,16 +528,16 @@
             }
             break;
         }
-        case 5:
-        case 6:
+        case COLUMN_INCREASE:
+        case COLUMN_DECREASE:
         {
             QString str(value.toString().simplified());
             Numeric n;
             QString errmsg = n.parse(str);
             if (errmsg.isEmpty())
             {
-                qDebug() << "Does setting numeric work? numeric=" << n.to_string();
-                if (index.column() == 6)
+                qDebug() << "Successfully parsed string to numeric=" << n.to_string();
+                if (index.column() == COLUMN_DECREASE)
                     n = n.neg();
                 // Check whether we have the simple case here
                 if (split.getParent().countSplits() != 2)
@@ -620,4 +622,51 @@
     }
 }
 
+void SplitListModel::editorClosed(const QModelIndex& index,
+                                  QAbstractItemDelegate::EndEditHint hint)
+{
+    if (!index.isValid())
+        return;
+
+    if (m_enableNewTransaction && index.row() == m_list.size())
+    {
+        // Special case: The line with the new transaction
+
+        switch (hint)
+        {
+        case QAbstractItemDelegate::SubmitModelCache:
+            switch (index.column())
+            {
+            case COLUMN_DATE:
+            case COLUMN_NUM:
+            case COLUMN_DESC:
+            case COLUMN_ACCOUNT:
+            case COLUMN_RECONCILE:
+                break; // we want to do nothing
+            case COLUMN_INCREASE:
+            case COLUMN_DECREASE:
+            {
+                // Commit the new transaction
+                qDebug() << "Commit the new transaction as a real one";
+                QUndoCommand* cmd = cmd::commitNewTransaction(m_tmpTransaction);
+                recreateTmpTrans();
+                m_undoStack->push(cmd);
+                break;
+            }
+            default:
+                break; // nothing to do
+            }
+        case QAbstractItemDelegate::RevertModelCache:
+            recreateTmpTrans();
+            break;
+        }
+    }
+    else
+    {
+        // We are in the line of an existing transaction - no function
+        // implemented yet.
+    }
+
+}
+
 } // END namespace gnc

Modified: gnucash/trunk/src/gnc/SplitListModel.hpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListModel.hpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/SplitListModel.hpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -34,6 +34,7 @@
 }
 
 #include <QAbstractItemModel>
+#include <QAbstractItemDelegate>
 #include <QHash>
 class QUndoStack;
 
@@ -46,6 +47,20 @@
 {
     Q_OBJECT
 public:
+
+    enum ColumnNumbers
+    {
+        COLUMN_DATE = 0
+        , COLUMN_NUM
+        , COLUMN_DESC
+        , COLUMN_ACCOUNT
+        , COLUMN_RECONCILE
+        , COLUMN_INCREASE
+        , COLUMN_DECREASE
+        , COLUMN_BALANCE
+        , COLUMN_LAST
+    };
+
     SplitListModel(const Account& acc, QUndoStack* undoStack, QObject *parent = 0);
     ~SplitListModel();
 
@@ -65,6 +80,7 @@
 public slots:
     void transactionEvent( ::Transaction* trans, QofEventId event_type);
     void accountEvent( ::Account* trans, QofEventId event_type);
+    void editorClosed(const QModelIndex& index, QAbstractItemDelegate::EndEditHint hint);
 
 private:
     void recreateCache();

Added: gnucash/trunk/src/gnc/SplitListView.cpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListView.cpp	                        (rev 0)
+++ gnucash/trunk/src/gnc/SplitListView.cpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -0,0 +1,75 @@
+/*
+ * SplitListView.cpp
+ * Copyright (C) 2010 Christian Stimming
+ *
+ * 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 "SplitListView.hpp"
+
+#include "gnc/Account.hpp"
+#include "gnc/SplitListModel.hpp"
+
+#include <QtGui/QAbstractItemDelegate>
+#include <QUndoStack>
+#include <QDebug>
+
+namespace gnc
+{
+
+SplitListView::SplitListView(Account account, QUndoStack* undoStack, QWidget* parent)
+        : base_class(parent)
+{
+    SplitListModel *smodel = new SplitListModel(account, undoStack, this);
+    setModel(smodel);
+    connect(this, SIGNAL(editorClosed(const QModelIndex&,QAbstractItemDelegate::EndEditHint)),
+            smodel, SLOT(editorClosed(const QModelIndex&,QAbstractItemDelegate::EndEditHint)));
+
+    setAlternatingRowColors(true);
+
+    scrollToBottom();
+    if (model()->rowCount() > 0)
+        setCurrentIndex(model()->index(model()->rowCount() - 1, 0));
+}
+
+void SplitListView::closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint)
+{
+    base_class::closeEditor(editor, hint);
+    //qDebug() << "closeEditor, row=" << currentIndex().row() << "hint=" << hint;
+    QModelIndex index = currentIndex();
+    if (hint != QAbstractItemDelegate::NoHint)
+        emit editorClosed(index, hint);
+    if (index.isValid()
+            && hint == QAbstractItemDelegate::SubmitModelCache
+            && index.row() < model()->rowCount() - 1)
+    {
+        switch (index.column())
+        {
+        case SplitListModel::COLUMN_INCREASE:
+        case SplitListModel::COLUMN_DECREASE:
+            setCurrentIndex(model()->index(index.row() + 1,
+                                           SplitListModel::COLUMN_DATE,
+                                           index.parent()));
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+}

Added: gnucash/trunk/src/gnc/SplitListView.hpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListView.hpp	                        (rev 0)
+++ gnucash/trunk/src/gnc/SplitListView.hpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -0,0 +1,53 @@
+/*
+ * SplitListView.hpp
+ * Copyright (C) 2010 Christian Stimming
+ *
+ * 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
+ */
+
+#ifndef GNC_SPLITLISTVIEW_HPP
+#define GNC_SPLITLISTVIEW_HPP
+
+#include "gnc/Account.hpp"
+#include "gnc/SplitListModel.hpp"
+
+#include <QtGui/QTableView>
+#include <QtGui/QAbstractItemDelegate>
+#include <QUndoStack>
+#include <QDebug>
+
+namespace gnc
+{
+
+class SplitListView : public QTableView
+{
+    Q_OBJECT
+public:
+    typedef QTableView base_class;
+    SplitListView(Account account, QUndoStack* undoStack, QWidget* parent = 0);
+
+signals:
+    void editorClosed(const QModelIndex& index, QAbstractItemDelegate::EndEditHint hint);
+
+public slots:
+    void closeEditor(QWidget* editor, QAbstractItemDelegate::EndEditHint hint);
+};
+
+}
+
+#endif

Modified: gnucash/trunk/src/gnc/Transaction.cpp
===================================================================
--- gnucash/trunk/src/gnc/Transaction.cpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/Transaction.cpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -91,7 +91,7 @@
         s.copyInto(t);
     }
 }
-void TmpTransaction::createAsReal() const
+Transaction TmpTransaction::createAsReal() const
 {
     Q_ASSERT (!splits.isEmpty());
     Account acc(splits.front().getAccount());
@@ -102,6 +102,7 @@
     trans.beginEdit();
     copyTo(trans);
     trans.commitEdit();
+    return trans;
 }
 void TmpTransaction::push_back(const TmpSplit& s)
 {

Modified: gnucash/trunk/src/gnc/Transaction.hpp
===================================================================
--- gnucash/trunk/src/gnc/Transaction.hpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/Transaction.hpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -108,7 +108,7 @@
 
     void clear();
     void copyTo(Transaction& t) const;
-    void createAsReal() const;
+    Transaction createAsReal() const;
 
     QString getNum() const { return num; }
     void setNum(const QString& v) { num = v; }
@@ -119,6 +119,7 @@
     void push_back(const TmpSplit& s);
     const TmpSplitQList& getSplits() const { return splits; }
     TmpSplitQList& getSplits() { return splits; }
+    int countSplits() const { return splits.size(); }
 
     Commodity getCommodity() const { return commodity; }
     void setCommodity(const Commodity& v) { commodity = v; }

Modified: gnucash/trunk/src/gnc/mainwindow-file.cpp
===================================================================
--- gnucash/trunk/src/gnc/mainwindow-file.cpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/mainwindow-file.cpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -397,7 +397,9 @@
                   "or you may not have write permission for the directory. "
                   "If you proceed you may not be able to save any changes. "
                   "What would you like to do?"));
-        QMessageBox msgBox;
+        QMessageBox msgBox(this);
+        msgBox.setWindowTitle(fmt1);
+        msgBox.setText(fmt2);
         QPushButton *openAnyway = msgBox.addButton(tr("_Open Anyway"), QMessageBox::ActionRole);
         QPushButton *createNewFile = msgBox.addButton(tr("_Create New File"), QMessageBox::ActionRole);
         QPushButton *close = msgBox.addButton(QMessageBox::Close);

Modified: gnucash/trunk/src/gnc/mainwindow.cpp
===================================================================
--- gnucash/trunk/src/gnc/mainwindow.cpp	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/mainwindow.cpp	2010-03-19 22:01:56 UTC (rev 18935)
@@ -51,9 +51,8 @@
 #include "gnc/Split.hpp"
 #include "gnc/SplitListModel.hpp"
 #include "gnc/RecentFileMenu.hpp"
+#include "gnc/SplitListView.hpp"
 
-#include "gnc/Cmd.hpp"
-
 namespace gnc
 {
 
@@ -416,7 +415,7 @@
     if (index.model() != m_accountTreeModel
             && index.model() != m_accountListModel)
     {
-        qDebug() << "Wrong model";
+        qDebug() << "Wrong model; row=" << (index.isValid()? index.row() : -1);
         return;
     }
     Account account(static_cast< ::Account*>(index.internalPointer()));
@@ -428,14 +427,9 @@
 
     // We create a new model for this account which will query it for
     // its splits, and also a view widget for this list.
-    QTableView *tableView = new QTableView(ui->tabWidget); // FIXME: Is this parent correct?
-    SplitListModel *smodel = new SplitListModel(account, m_undoStack, tableView);
-    tableView->setModel(smodel);
-    tableView->setAlternatingRowColors(true);
-    tableView->scrollToBottom();
-    if (smodel->rowCount() > 0)
-        tableView->setCurrentIndex(smodel->index(smodel->rowCount() - 1, 0));
-    ui->actionCut->setEnabled(smodel->rowCount() > 0);
+    QTableView *tableView =
+        new SplitListView(account, m_undoStack, ui->tabWidget);
+    ui->actionCut->setEnabled(tableView->model()->rowCount() > 0);
 
     // Insert this as a new tab
     tableView->setProperty(PROPERTY_TAB_PREVIOUSPOS, ui->tabWidget->currentIndex());

Modified: gnucash/trunk/src/gnc/mainwindow.ui
===================================================================
--- gnucash/trunk/src/gnc/mainwindow.ui	2010-03-19 17:50:36 UTC (rev 18934)
+++ gnucash/trunk/src/gnc/mainwindow.ui	2010-03-19 22:01:56 UTC (rev 18935)
@@ -68,11 +68,17 @@
 &lt;p style=&quot; margin-top:18px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:12pt; font-weight:600;&quot;&gt;Free Finance Software. Easy to develop, easy to use.&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Currently this is more or less a proof-of-concept for developers:&lt;/span&gt;&lt;/p&gt;
 &lt;ol style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Load an existing gnucash XML file&lt;/li&gt;
-&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;It will show the account tree in a QTreeView&lt;/li&gt;
-&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Additionally the accounts will be shown in a flat list in a QTableView&lt;/li&gt;
-&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Double-click on  any account in either view; it will open the list of splits in that account.&lt;/li&gt;&lt;/ol&gt;
-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;The list of splits in the account is comparable to gnucash's single line view.  The amounts are already there. The dates are still missing, but that can't be hard, too.&lt;/span&gt;&lt;/p&gt;
-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;This is all read-only access so far, although &amp;quot;Save&amp;quot; probably works but hasn't been tested.&lt;/span&gt;&lt;/p&gt;
+&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;It will show the account tree in a tree view and also a list view &lt;/li&gt;
+&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Double-click on any account in either view; it will open the list of splits in that account.&lt;/li&gt;
+&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Save and Save-As works as normal.&lt;/li&gt;
+&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Edit any of the existing transaction/splits: Date, Description, or Amount. Click Undo. Click Redo. Click Undo. Etc. etc.&lt;/li&gt;
+&lt;li style=&quot; font-family:'Sans'; font-size:10pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Delete any of the existings transactions. Or entering a new one. Click Undo. Click Redo. Etc. etc.&lt;/li&gt;&lt;/ol&gt;
+&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;The list of splits in the account is comparable to gnucash's single line view.  Amounts, balance, date, all there.&lt;/span&gt;&lt;/p&gt;
+&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans'; font-size:10pt;&quot;&gt;The following parts are still missing:&lt;/span&gt;&lt;/p&gt;
+&lt;ul style=&quot;margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;&quot;&gt;&lt;li style=&quot; font-size:8pt;&quot; style=&quot; margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt; Currently the accout selection of a transaction cannot be edited. &lt;/li&gt;
+&lt;li style=&quot; font-size:8pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Editing or adding multi-split transactions are not yet supported (it shows only the string &amp;quot;--Split Transaction--&amp;quot;). &lt;/li&gt;
+&lt;li style=&quot; font-size:8pt;&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Editing or adding multi-currency transactions are not yet supported. &lt;/li&gt;
+&lt;li style=&quot; font-size:8pt;&quot; style=&quot; margin-top:0px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Any of the more specialized account views are not yet implemented.&lt;/li&gt;&lt;/ul&gt;
 &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;The fun part is how easy it was to add this. Let's see how far we will get...&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt; font-weight:600;&quot;&gt;Images&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;img src=&quot;:/pixmaps/gnucash_splash.png&quot; /&gt;&lt;/p&gt;
@@ -160,12 +166,12 @@
     <addaction name="actionAbout_Qt"/>
    </widget>
    <widget class="QMenu" name="menuAccount">
+    <property name="enabled">
+     <bool>false</bool>
+    </property>
     <property name="title">
      <string>&amp;Account</string>
     </property>
-    <property name="enabled">
-     <bool>false</bool>
-    </property>
     <addaction name="actionOpenAccount"/>
     <addaction name="actionNewAccount"/>
     <addaction name="actionDeleteAccount"/>
@@ -400,7 +406,7 @@
   </action>
   <action name="actionCloseTab">
    <property name="icon">
-    <iconset resource="gnucash.qrc">
+    <iconset resource="gtk-icons.qrc">
      <normaloff>:/gtk-icons/gtk-close.png</normaloff>:/gtk-icons/gtk-close.png</iconset>
    </property>
    <property name="text">



More information about the gnucash-changes mailing list