r18913 - gnucash/trunk/src/gnc - Cutecash: Add Commodity wrapper. Use gnc-exp-parser for numbers.

Christian Stimming cstim at code.gnucash.org
Mon Mar 15 14:39:21 EDT 2010


Author: cstim
Date: 2010-03-15 14:39:21 -0400 (Mon, 15 Mar 2010)
New Revision: 18913
Trac: http://svn.gnucash.org/trac/changeset/18913

Added:
   gnucash/trunk/src/gnc/Commodity.hpp
Modified:
   gnucash/trunk/src/gnc/Account.hpp
   gnucash/trunk/src/gnc/CMakeLists.txt
   gnucash/trunk/src/gnc/Cmd.cpp
   gnucash/trunk/src/gnc/Cmd.hpp
   gnucash/trunk/src/gnc/Numeric.cpp
   gnucash/trunk/src/gnc/Numeric.hpp
   gnucash/trunk/src/gnc/SplitListModel.cpp
   gnucash/trunk/src/gnc/SplitListModel.hpp
   gnucash/trunk/src/gnc/Transaction.hpp
   gnucash/trunk/src/gnc/main.cpp
   gnucash/trunk/src/gnc/mainwindow.cpp
Log:
Cutecash: Add Commodity wrapper. Use gnc-exp-parser for numbers.

 - Allow amounts to be edited.
 - Let the date column be handled by the QDate delegate with a QDateEdit widget

Modified: gnucash/trunk/src/gnc/Account.hpp
===================================================================
--- gnucash/trunk/src/gnc/Account.hpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/Account.hpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -32,6 +32,7 @@
 }
 
 #include "gnc/WeakPointer.hpp"
+#include "gnc/Commodity.hpp"
 
 #include <QString>
 #include <QList>
@@ -59,6 +60,8 @@
     QString getName() const { return QString::fromUtf8(xaccAccountGetName(get())); }
     QString getCode() const { return QString::fromUtf8(xaccAccountGetCode(get())); }
     QString getDescription() const { return QString::fromUtf8(xaccAccountGetDescription(get())); }
+    Commodity getCommodity() const { return xaccAccountGetCommodity(get()); }
+    int getCommoditySCU() const { return xaccAccountGetCommoditySCU(get()); }
 
     ::SplitList* getSplitList() const { return xaccAccountGetSplitList(get()); }
 

Modified: gnucash/trunk/src/gnc/CMakeLists.txt
===================================================================
--- gnucash/trunk/src/gnc/CMakeLists.txt	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/CMakeLists.txt	2010-03-15 18:39:21 UTC (rev 18913)
@@ -33,6 +33,7 @@
   Account.hpp
   Book.hpp
   Cmd.hpp
+  Commodity.hpp
   QofEventWrapper.hpp
   Session.hpp
   Split.hpp

Modified: gnucash/trunk/src/gnc/Cmd.cpp
===================================================================
--- gnucash/trunk/src/gnc/Cmd.cpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/Cmd.cpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -81,28 +81,28 @@
 {
     return new Cmd<Transaction, QString>(QObject::tr("Edit Transaction Number"),
                                          t, &Transaction::setNum,
-                                         &Transaction::getNum, newValue);
+                                         t.getNum(), newValue);
 }
 
 QUndoCommand* setTransactionDescription(Transaction& t, const QString& newValue)
 {
     return new Cmd<Transaction, QString>(QObject::tr("Edit Transaction Description"),
                                          t, &Transaction::setDescription,
-                                         &Transaction::getDescription, newValue);
+                                         t.getDescription(), newValue);
 }
 
 QUndoCommand* setTransactionNotes(Transaction& t, const QString& newValue)
 {
     return new Cmd<Transaction, QString>(QObject::tr("Edit Transaction Notes"),
                                          t, &Transaction::setNotes,
-                                         &Transaction::getNotes, newValue);
+                                         t.getNotes(), newValue);
 }
 
-QUndoCommand* setTransactionDate(Transaction& t, const QDateTime& newValue)
+QUndoCommand* setTransactionDate(Transaction& t, const QDate& newValue)
 {
-    return new Cmd<Transaction, QDateTime>(QObject::tr("Edit Transaction Date"),
-                                           t, &Transaction::setDatePosted,
-                                           &Transaction::getDatePosted, newValue);
+    return new Cmd<Transaction, QDate>(QObject::tr("Edit Transaction Date"),
+                                       t, &Transaction::setDatePosted,
+                                       t.getDatePosted().date(), newValue);
 }
 
 

Modified: gnucash/trunk/src/gnc/Cmd.hpp
===================================================================
--- gnucash/trunk/src/gnc/Cmd.hpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/Cmd.hpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -160,7 +160,7 @@
 QUndoCommand* setTransactionNum(Transaction& t, const QString& newValue);
 QUndoCommand* setTransactionDescription(Transaction& t, const QString& newValue);
 QUndoCommand* setTransactionNotes(Transaction& t, const QString& newValue);
-QUndoCommand* setTransactionDate(Transaction& t, const QDateTime& newValue);
+QUndoCommand* setTransactionDate(Transaction& t, const QDate& newValue);
 
 } // END namespace cmd
 

Added: gnucash/trunk/src/gnc/Commodity.hpp
===================================================================
--- gnucash/trunk/src/gnc/Commodity.hpp	                        (rev 0)
+++ gnucash/trunk/src/gnc/Commodity.hpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -0,0 +1,61 @@
+/*
+ * Commodity.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_COMMODITY_HPP
+#define GNC_COMMODITY_HPP
+
+// gnucash includes
+#include "config.h"
+extern "C"
+{
+#include "qof.h"
+#include "engine/gnc-commodity.h"
+}
+
+#include "gnc/WeakPointer.hpp"
+#include <QString>
+
+/** Wrapper around a gnucash gnc_commodity pointer */
+namespace gnc
+{
+
+class Commodity : public WeakPointer<gnc_commodity>
+{
+public:
+    typedef WeakPointer<gnc_commodity> base_class;
+    Commodity(element_type *ptr = 0)
+            : base_class(ptr)
+    {}
+    QString get_mnemonic() const { return gnc_commodity_get_mnemonic(get()); }
+    QString get_namespace() const { return gnc_commodity_get_namespace(get()); }
+    QString get_fullname() const { return gnc_commodity_get_fullname(get()); }
+    QString get_printname() const { return gnc_commodity_get_printname(get()); }
+
+    int get_fraction() const { return gnc_commodity_get_fraction(get()); }
+    bool get_quote_flag() const { return gnc_commodity_get_quote_flag(get()); }
+
+    bool is_currency() const { return gnc_commodity_is_currency(get()); }
+};
+
+} // END namespace gnc
+
+#endif

Modified: gnucash/trunk/src/gnc/Numeric.cpp
===================================================================
--- gnucash/trunk/src/gnc/Numeric.cpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/Numeric.cpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -24,6 +24,11 @@
 #include "gnc/Account.hpp"
 #include "gnc/Split.hpp"
 
+extern "C"
+{
+#include "app-utils/gnc-exp-parser.h"
+}
+
 namespace gnc
 {
 
@@ -37,7 +42,7 @@
         : base_class(gnc_split_amount_print_info(split.get(), use_symbol))
 {}
 
-QString Numeric::printAmount(const PrintAmountInfo& info)
+QString Numeric::printAmount(const PrintAmountInfo& info) const
 {
     char buf[256];
     if (!xaccSPrintAmount (buf, *this, info))
@@ -45,5 +50,25 @@
     return QString::fromUtf8(buf);
 }
 
+QString Numeric::parse(const QString& str)
+{
+    QString errorString;
 
+    const char* input = str.toUtf8();
+    char *error_loc;
+    Numeric result;
+    gboolean p = gnc_exp_parser_parse(input, &result, &error_loc);
+    if (p)
+    {
+        *this = result;
+    }
+    else
+    {
+        errorString = QString::fromUtf8(gnc_exp_parser_error_string());
+    }
+
+    return errorString;
+}
+
+
 } // END namespace gnc

Modified: gnucash/trunk/src/gnc/Numeric.hpp
===================================================================
--- gnucash/trunk/src/gnc/Numeric.hpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/Numeric.hpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -167,7 +167,13 @@
 
     Numeric reduce() const { return gnc_numeric_reduce(*this); }
 
-    QString printAmount(const PrintAmountInfo& info);
+    QString printAmount(const PrintAmountInfo& info) const;
+
+    /** Parses the given string by the expression parser. On success,
+     * the value is written into this object and an empty string is
+     * returned. On error, this object is unchanged and a string with
+     * the error message is returned. */
+    QString parse(const QString& str);
 };
 
 inline bool operator==(const Numeric& a, const Numeric& b)

Modified: gnucash/trunk/src/gnc/SplitListModel.cpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListModel.cpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/SplitListModel.cpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -26,15 +26,17 @@
 #include "gnc/Session.hpp"
 #include <QDebug>
 #include <QUndoStack>
+#include <QBrush>
 
 namespace gnc
 {
 
 
 
-SplitListModel::SplitListModel(const SplitQList splits, QUndoStack* undoStack, QObject *parent)
+SplitListModel::SplitListModel(const Account& acc, QUndoStack* undoStack, QObject *parent)
         : QAbstractItemModel(parent)
-        , m_list(splits)
+        , m_account(acc)
+        , m_list(Split::fromGList(acc.getSplitList()))
         , m_undoStack(undoStack)
         , m_eventWrapper(*this, &SplitListModel::transactionModified,
                          GNC_ID_TRANS, QOF_EVENT_MODIFY)
@@ -89,8 +91,8 @@
     case 1:
     case 2:
     case 4:
-        //case 5:
-        //case 6:
+    case 5:
+    case 6:
         // Allow write access as well
         return result | Qt::ItemIsEditable;
     default:
@@ -107,40 +109,93 @@
 
     Split split(static_cast< ::Split*>(index.internalPointer()));
     Transaction trans(split.getParent());
-    if (role == Qt::DisplayRole)
+    Numeric amount = split.getValue(); // Alternatively: xaccSplitConvertAmount(split.get(), split.getAccount().get());
+    PrintAmountInfo printInfo(split.get(), false);
+
+    switch (index.column())
     {
-        Numeric amount = split.getAmount(); // Alternatively: xaccSplitConvertAmount(split.get(), split.getAccount().get());
-        PrintAmountInfo printInfo(split.get(), false);
-        switch (index.column())
+    case 0:
+        switch (role)
         {
-        case 0:
-            return trans.getDatePosted().date().toString(Qt::ISODate);
-        case 1:
+        case Qt::DisplayRole:
+        case Qt::EditRole:
+            return trans.getDatePosted().date();
+        default:
+            return QVariant();
+        }
+    case 1:
+        switch (role)
+        {
+        case Qt::DisplayRole:
+        case Qt::EditRole:
             return trans.getNum();
-        case 2:
+        default:
+            return QVariant();
+        }
+    case 2:
+        switch (role)
+        {
+        case Qt::DisplayRole:
+        case Qt::EditRole:
             return trans.getDescription();
-        case 3:
+        default:
+            return QVariant();
+        }
+    case 3:
+        switch (role)
+        {
+        case Qt::DisplayRole:
             return split.getCorrAccountFullName();
-        case 4:
+        default:
+            return QVariant();
+        }
+    case 4:
+        switch (role)
+        {
+        case Qt::DisplayRole:
             return QChar(split.getReconcile());
-        case 5:
+        default:
+            return QVariant();
+        }
+    case 5:
+        switch (role)
+        {
+        case Qt::DisplayRole:
+        case Qt::EditRole:
             if (amount.positive_p())
                 return amount.printAmount(printInfo);
             else
                 return QString();
-        case 6:
+        default:
+            return QVariant();
+        }
+    case 6:
+        switch (role)
+        {
+        case Qt::DisplayRole:
+        case Qt::EditRole:
             if (amount.positive_p())
                 return QString();
             else
                 return amount.neg().printAmount(printInfo);
-        case 7:
+        default:
+            return QVariant();
+        }
+    case 7:
+        switch (role)
+        {
+        case Qt::DisplayRole:
             return split.getBalance().printAmount(printInfo);
+        case Qt::ForegroundRole:
+            return split.getBalance().negative_p()
+                   ? QBrush(Qt::red)
+                   : QBrush();
         default:
             return QVariant();
         }
+    default:
+        return QVariant();
     }
-    else
-        return QVariant();
 }
 
 QVariant SplitListModel::headerData(int section, Qt::Orientation orientation, int role) const
@@ -192,7 +247,7 @@
         {
         case 0:
         {
-            QDateTime date = value.toDateTime();
+            QDate date = value.toDate();
             if (date.isValid())
             {
                 cmd = cmd::setTransactionDate(trans, date);
@@ -209,26 +264,29 @@
             cmd = cmd::setSplitReconcile(split, value.toChar().toLatin1());
             break;
         case 5:
+        case 6:
         {
-            bool x;
-            double v = value.toDouble(&x);
-            if (!x)
+            QString str(value.toString());
+            Numeric n;
+//             bool x;
+//             double v = value.toDouble(&x);
+            QString errmsg = n.parse(str);
+            if (errmsg.isEmpty())
             {
-                qDebug() << "Cannot convert string to gnc_numeric:" << value.toString();
+                qDebug() << "Does setting numeric work? numeric=" << n.to_string();
+                if (index.column() == 6)
+                    n = n.neg();
+//                 cmd = cmd::setSplitAmount(split, n);
+//                 m_undoStack->push(cmd);
+                cmd = cmd::setSplitValue(split, n);
             }
             else
             {
-                Numeric n(v, 100, GNC_HOW_RND_ROUND);
-                qDebug() << "Does setting numeric work? numeric=" << n.to_string();
-                cmd = cmd::setSplitAmount(split, n);
+                qDebug() << "Cannot convert string to gnc_numeric:" << str;
             }
             // Sigh. This doesn't seem to work so far.
             break;
         }
-//         case 6:
-//             cmd = cmd::setSplitAmount(split, Numeric(value.toString()).neg());
-//             break;
-
         default:
             break;
         }

Modified: gnucash/trunk/src/gnc/SplitListModel.hpp
===================================================================
--- gnucash/trunk/src/gnc/SplitListModel.hpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/SplitListModel.hpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -23,6 +23,7 @@
 #ifndef GNC_SPLITLISTMODEL_HPP
 #define GNC_SPLITLISTMODEL_HPP
 
+#include "gnc/Account.hpp"
 #include "gnc/Split.hpp"
 #include "gnc/QofEventWrapper.hpp"
 
@@ -44,7 +45,7 @@
 {
     Q_OBJECT
 public:
-    SplitListModel(const SplitQList splits, QUndoStack* undoStack, QObject *parent = 0);
+    SplitListModel(const Account& acc, QUndoStack* undoStack, QObject *parent = 0);
     ~SplitListModel();
 
     QModelIndex parent(const QModelIndex &index) const { return QModelIndex(); }
@@ -62,6 +63,7 @@
     void transactionModified( ::Transaction* trans);
 
 protected:
+    Account m_account;
     SplitQList m_list;
     QUndoStack* m_undoStack;
     typedef QHash< ::Transaction*, int> TransactionRowHash;

Modified: gnucash/trunk/src/gnc/Transaction.hpp
===================================================================
--- gnucash/trunk/src/gnc/Transaction.hpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/Transaction.hpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -31,10 +31,11 @@
 #include "engine/Transaction.h"
 }
 
-#include "gnc/WeakPointer.hpp"
 #include "gnc/Account.hpp"
 #include "gnc/Book.hpp"
+#include "gnc/Commodity.hpp"
 #include "gnc/Numeric.hpp"
+#include "gnc/WeakPointer.hpp"
 
 #include <QString>
 #include <QList>
@@ -68,6 +69,14 @@
 
     int countSplits() const { return xaccTransCountSplits(get()); }
 
+    Commodity getCurrency() const { return xaccTransGetCurrency(get()); }
+    void setCurrency(const Commodity& c) { xaccTransSetCurrency(get(), c.get()); }
+
+    Numeric getImbalanceValue() const { return xaccTransGetImbalanceValue(get()); }
+    bool isBalanced() const { return xaccTransIsBalanced(get()); }
+    Numeric getAccountConvRate(const Account& acc) const { return xaccTransGetAccountConvRate(get(), acc.get()); }
+
+    void setDatePosted(const QDate& t) { xaccTransSetDatePostedSecs(get(), QDateTime(t, QTime(12,0,0)).toTime_t()); }
     void setDatePosted(const QDateTime& t) { xaccTransSetDatePostedSecs(get(), t.toTime_t()); }
     void setDateEntered(const QDateTime& t) { xaccTransSetDateEnteredSecs(get(), t.toTime_t()); }
     QDateTime getDatePosted() const { return toQDateTime(xaccTransRetDatePostedTS(get())); }

Modified: gnucash/trunk/src/gnc/main.cpp
===================================================================
--- gnucash/trunk/src/gnc/main.cpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/main.cpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -44,6 +44,7 @@
 #include "engine/engine-helpers.h"
 #include "engine/gnc-engine.h"
 #include "app-utils/gnc-ui-util.h" // for gnc_ui_util_init()
+#include "app-utils/gnc-exp-parser.h" // for gnc_exp_parser_init()
 #include "swig-runtime.h"
 
 #include "backend/xml/gnc-backend-xml.h"
@@ -185,6 +186,7 @@
     gnc_module_init_business_core_init();
     gnc_module_init_business_core_xml_init();
     gnc_ui_util_init();
+    gnc_exp_parser_init();
 
     int r;
     {
@@ -201,6 +203,7 @@
     }
 
     // Shutdown of the C side after all C++ was destructed already.
+    gnc_exp_parser_shutdown();
     //gnc_module_finalize_backend_dbi();
     qof_close();
     return r;

Modified: gnucash/trunk/src/gnc/mainwindow.cpp
===================================================================
--- gnucash/trunk/src/gnc/mainwindow.cpp	2010-03-15 18:38:26 UTC (rev 18912)
+++ gnucash/trunk/src/gnc/mainwindow.cpp	2010-03-15 18:39:21 UTC (rev 18913)
@@ -88,8 +88,6 @@
 
     readSettings();
 
-//     connect(ui->labelMain, SIGNAL(linkActivated(const QString&)),
-//             this, SLOT(documentWasModified()));
     connect(m_undoStack, SIGNAL(cleanChanged(bool)),
             this, SLOT(documentCleanStateChanged(bool)));
 
@@ -163,14 +161,14 @@
 
 void MainWindow::documentWasModified()
 {
-    setWindowModified(true);
+    documentCleanStateChanged(false);
 }
 
-void MainWindow::documentCleanStateChanged(bool clean)
+void MainWindow::documentCleanStateChanged(bool documentIsClean)
 {
-    bool unchanged = (clean == isWindowModified());
+    bool unchanged = (documentIsClean == isWindowModified());
 
-    setWindowModified(!clean);
+    setWindowModified(!documentIsClean);
     if (!unchanged)
         updateWindowTitle();
 }
@@ -208,20 +206,17 @@
 
     connect(ui->actionNew, SIGNAL(triggered()), this, SLOT(newFile()));
     connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close()));
-
-//     connect(ui->actionCut, SIGNAL(triggered()), ui->textEdit, SLOT(cut()));
-//     connect(ui->actionCopy, SIGNAL(triggered()), ui->textEdit, SLOT(copy()));
-//     connect(ui->actionPaste, SIGNAL(triggered()), ui->textEdit, SLOT(paste()));
-
     connect(ui->actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
 
     ui->actionCut->setEnabled(false);
     ui->actionCopy->setEnabled(false);
 
-//     connect(ui->textEdit, SIGNAL(copyAvailable(bool)),
+//     connect(ui->textBrowser, SIGNAL(copyAvailable(bool)),
 //             ui->actionCut, SLOT(setEnabled(bool)));
-//     connect(ui->textEdit, SIGNAL(copyAvailable(bool)),
-//             ui->actionCopy, SLOT(setEnabled(bool)));
+    connect(ui->textBrowser, SIGNAL(copyAvailable(bool)),
+            ui->actionCopy, SLOT(setEnabled(bool)));
+    connect(ui->actionCopy, SIGNAL(triggered()),
+            ui->textBrowser, SLOT(copy()));
 
     connect(ui->treeView, SIGNAL(activated(const QModelIndex &)),
             this, SLOT(accountItemActivated(const QModelIndex&)));
@@ -257,7 +252,7 @@
 
 void MainWindow::readSettings()
 {
-    QSettings settings("Trolltech", "Application Example");
+    QSettings settings("gnucash.org", "Cutecash");
     QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
     QSize size = settings.value("size", QSize(400, 400)).toSize();
     resize(size);
@@ -267,7 +262,7 @@
 
 void MainWindow::writeSettings()
 {
-    QSettings settings("Trolltech", "Application Example");
+    QSettings settings("gnucash.org", "Cutecash");
     settings.setValue("pos", pos());
     settings.setValue("size", size());
     menuRecentFiles->writeSettings(&settings, "RecentFiles");
@@ -275,7 +270,7 @@
 
 bool MainWindow::maybeSave()
 {
-    if (false)//ui->textEdit->document()->isModified())
+    if (isWindowModified())
     {
         QMessageBox::StandardButton ret;
         ret = QMessageBox::warning(this, tr("Application"),
@@ -294,8 +289,7 @@
 {
     menuRecentFiles->usingFile(fileName);
     m_currentFilename = fileName;
-//     ui->textEdit->document()->setModified(false);
-    setWindowModified(false);
+    documentCleanStateChanged(true);
 
     updateWindowTitle();
 }
@@ -432,15 +426,15 @@
         return;
     }
 
-    // We have an account, so obtains its list of splits now.
-    ::SplitList* slist = account.getSplitList();
-
-    // We create a new model for this list of splits and also a view
-    // widget for this list.
+    // 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(Split::fromGList(slist), m_undoStack, tableView);
+    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));
 
     // Insert this as a new tab
     tableView->setProperty(PROPERTY_TAB_PREVIOUSPOS, ui->tabWidget->currentIndex());



More information about the gnucash-changes mailing list