Implement a table widget with the list of the splits of one account, and open this if an account in the tree is double-clicked.

Date and values/amounts can follow next, once those types are suitably
wrapped into C++ as well.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18868 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Christian Stimming 2010-03-07 17:51:37 +00:00
parent 63fc328029
commit cad5dc6214
10 changed files with 440 additions and 43 deletions

View File

@ -50,6 +50,11 @@ public:
QString getCode() const { return QString::fromUtf8(xaccAccountGetCode(get())); }
QString getDescription() const { return QString::fromUtf8(xaccAccountGetDescription(get())); }
::SplitList* getSplitList() const { return xaccAccountGetSplitList(get()); }
/** @name Account tree traversal */
//@{
Account get_parent() const { return gnc_account_get_parent(get()); }
Account get_root() { return gnc_account_get_root(get()); }
bool is_root() const { return gnc_account_is_root(get()); }
@ -73,6 +78,7 @@ public:
gint get_current_depth () const { return gnc_account_get_current_depth(get()); }
gint get_tree_depth () const { return gnc_account_get_tree_depth(get()); }
//@}
typedef QList< ::Account*> AccountQList;

View File

@ -27,8 +27,8 @@ namespace gnc
{
AccountTreeModel::AccountTreeModel(Account rootaccount, QObject *parent)
: QAbstractItemModel(parent)
, m_root(rootaccount)
: QAbstractItemModel(parent)
, m_root(rootaccount)
{
}
@ -108,14 +108,14 @@ QVariant AccountTreeModel::data(const QModelIndex& index, int role) const
Account account(static_cast< ::Account*>(index.internalPointer()));
switch (index.column())
{
case 0:
return account.getName();
case 1:
return account.getCode();
case 2:
return account.getDescription();
default:
return QVariant();
case 0:
return account.getName();
case 1:
return account.getCode();
case 2:
return account.getDescription();
default:
return QVariant();
}
}
else
@ -141,14 +141,14 @@ QVariant AccountTreeModel::headerData(int section, Qt::Orientation orientation,
{
switch (section)
{
case 0:
return QString("Name");
case 1:
return QString("Code");
case 2:
return QString("Description");
default:
return QVariant();
case 0:
return QString("Name");
case 1:
return QString("Code");
case 2:
return QString("Description");
default:
return QVariant();
}
}
else
@ -162,11 +162,10 @@ QModelIndex AccountListModel::index(int row, int column,
const QModelIndex &parent) const
{
//qDebug() << "index(), " << row << column << parent;
if (!hasIndex(row, column, parent)
|| row >= m_acclist.size())
if (!hasIndex(row, column, parent) || row >= m_list.size())
return QModelIndex();
Account childItem = m_acclist.at(row);
Account childItem = m_list.at(row);
if (childItem.get())
{
//qDebug() << "returning" << childItem.getName();

View File

@ -72,12 +72,12 @@ class AccountListModel : public AccountTreeModel
Q_OBJECT
public:
AccountListModel(Account rootaccount, QObject *parent = 0)
: AccountTreeModel(rootaccount, parent)
, m_acclist(Account::fromGList(rootaccount.get_descendants()))
: AccountTreeModel(rootaccount, parent)
, m_list(Account::fromGList(rootaccount.get_descendants()))
{
}
int rowCount(const QModelIndex& parent = QModelIndex()) const { return m_acclist.size(); }
int rowCount(const QModelIndex& parent = QModelIndex()) const { return m_list.size(); }
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
@ -85,7 +85,7 @@ public:
QModelIndex parent(const QModelIndex &index) const { return QModelIndex(); }
private:
Account::AccountQList m_acclist;
Account::AccountQList m_list;
};

View File

@ -13,18 +13,22 @@ SET (gnc_SOURCES
AccountItemModel.cpp
Book.cpp
Session.cpp
SplitListModel.cpp
main.cpp
mainwindow.cpp
)
SET (gnc_QOBJECT_HEADERS
AccountItemModel.hpp
SplitListModel.hpp
mainwindow.hpp
)
SET (gnc_HEADERS ${gnc_QOBJECT_HEADERS}
Account.hpp
Book.hpp
Session.hpp
Split.hpp
Transaction.hpp
WeakPointer.hpp
)

103
src/gnc/Split.hpp Normal file
View File

@ -0,0 +1,103 @@
/*
* Split.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@gnu.org
*/
#ifndef GNC_SPLIT_HPP
#define GNC_SPLIT_HPP
// gnucash includes
#include "config.h"
extern "C"
{
#include "qof.h"
#include "engine/Split.h"
}
#include <QString>
#include <QList>
namespace gnc
{
class Split;
typedef QList< ::Split*> SplitQList;
}
#include "gnc/WeakPointer.hpp"
#include "gnc/Account.hpp"
#include "gnc/Book.hpp"
#include "gnc/Transaction.hpp"
namespace gnc
{
class Split : public WeakPointer< ::Split >
{
public:
typedef WeakPointer< ::Split > base_class;
Split(element_type* ptr = 0)
: base_class(ptr)
{ }
Book getBook() const { return xaccSplitGetBook(get()); }
Account getAccount() const { return xaccSplitGetAccount(get()); }
void setAccount(Account& acc) { xaccSplitSetAccount(get(), acc.get()); }
Transaction getParent() const { return xaccSplitGetParent(get()); }
void setParent(Transaction& trans) { xaccSplitSetParent(get(), trans.get()); }
QString getMemo() const { return QString::fromUtf8(xaccSplitGetMemo(get())); }
void setMemo(const QString& v) { xaccSplitSetMemo(get(), v.toUtf8()); }
QString getAction() const { return QString::fromUtf8(xaccSplitGetAction(get())); }
void setAction(const QString& v) { xaccSplitSetAction(get(), v.toUtf8()); }
char getReconcile() const { return xaccSplitGetReconcile(get()); }
void setReconcile(char v) { xaccSplitSetReconcile(get(), v); }
Split getOtherSplit() const { return xaccSplitGetOtherSplit(get()); }
QString getCorrAccountFullName() const
{
char * r = xaccSplitGetCorrAccountFullName(get());
QString result = QString::fromUtf8(r);
g_free (r);
return result;
}
QString getCorrAccountName() const { return QString::fromUtf8(xaccSplitGetCorrAccountName(get())); }
QString getCorrAccountCode() const { return QString::fromUtf8(xaccSplitGetCorrAccountCode(get())); }
static SplitQList fromGList(GList* glist)
{
SplitQList result;
GList* list = glist;
while (list)
{
result.append(reinterpret_cast< ::Split*>(list->data));
list = g_list_next(list);
}
return result;
}
};
} // END namespace gnc
#endif

124
src/gnc/SplitListModel.cpp Normal file
View File

@ -0,0 +1,124 @@
/*
* SplitListModel.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@gnu.org
*/
#include "SplitListModel.hpp"
#include <QDebug>
namespace gnc
{
SplitListModel::SplitListModel(const SplitQList splits, QObject *parent)
: QAbstractItemModel(parent)
, m_list(splits)
{
}
QModelIndex SplitListModel::index(int row, int column,
const QModelIndex &parent) const
{
//qDebug() << "index(), " << row << column << parent;
if (!hasIndex(row, column, parent) || row >= m_list.size())
return QModelIndex();
Split childItem = m_list.at(row);
if (childItem.get())
{
//qDebug() << "returning" << childItem.getName();
return createIndex(row, column, childItem.get());
}
else
return QModelIndex();
}
int SplitListModel::columnCount(const QModelIndex& parent) const
{
//qDebug() << "columnCount()" << parent;
// if (!parent.isValid())
// return 0;
// else
return 4; // Fixed number for now
}
QVariant SplitListModel::data(const QModelIndex& index, int role) const
{
//qDebug() << "data(), " << index;
if (!index.isValid())
return QVariant();
if (role == Qt::DisplayRole)
{
Split split(static_cast< ::Split*>(index.internalPointer()));
Transaction trans(split.getParent());
switch (index.column())
{
case 0:
return trans.getNum();
case 1:
return trans.getDescription();
case 2:
return split.getCorrAccountFullName();
case 3:
return QChar(split.getReconcile());
default:
return QVariant();
}
}
else
return QVariant();
}
Qt::ItemFlags SplitListModel::flags(const QModelIndex &index) const
{
//qDebug() << "flags()" << index;
if (!index.isValid())
return 0;
// Ensure read-only access only
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant SplitListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
//qDebug() << "headerData()" << section;
if (role != Qt::DisplayRole)
return QVariant();
if (orientation == Qt::Horizontal)
{
switch (section)
{
case 0:
return QString("Num");
case 1:
return QString("Description");
case 2:
return QString("Account");
case 3:
return QString("Reconciled?");
default:
return QVariant();
}
}
else
return QString("%1").arg(1 + section);
}
} // END namespace gnc

View File

@ -0,0 +1,57 @@
/*
* SplitListModel.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@gnu.org
*/
#ifndef GNC_SPLITLISTMODEL_HPP
#define GNC_SPLITLISTMODEL_HPP
#include "gnc/Split.hpp"
#include <QAbstractItemModel>
namespace gnc
{
/** This is the data model for a list of splits.
*/
class SplitListModel : public QAbstractItemModel
{
Q_OBJECT
public:
SplitListModel(const SplitQList splits, QObject *parent = 0);
QModelIndex parent(const QModelIndex &index) const { return QModelIndex(); }
int rowCount(const QModelIndex& parent = QModelIndex()) const { return m_list.size(); }
int columnCount(const QModelIndex& parent = QModelIndex()) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant data(const QModelIndex& index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
protected:
SplitQList m_list;
};
} // END namespace gnc
#endif

68
src/gnc/Transaction.hpp Normal file
View File

@ -0,0 +1,68 @@
/*
* Transaction.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@gnu.org
*/
#ifndef GNC_TRANSACTION_HPP
#define GNC_TRANSACTION_HPP
// gnucash includes
#include "config.h"
extern "C"
{
#include "qof.h"
#include "engine/Transaction.h"
}
#include "gnc/WeakPointer.hpp"
#include "gnc/Account.hpp"
#include "gnc/Book.hpp"
#include <QString>
#include <QList>
namespace gnc
{
class Transaction : public WeakPointer< ::Transaction >
{
public:
typedef WeakPointer< ::Transaction > base_class;
Transaction(element_type* ptr = 0)
: base_class(ptr)
{ }
QString getNum() const { return QString::fromUtf8(xaccTransGetNum(get())); }
void setNum(const QString& v) { xaccTransSetNum(get(), v.toUtf8()); }
QString getDescription() const { return QString::fromUtf8(xaccTransGetDescription(get())); }
void setDescription(const QString& v) { xaccTransSetDescription(get(), v.toUtf8()); }
QString getNotes() const { return QString::fromUtf8(xaccTransGetNotes(get())); }
void setNotes(const QString& v) { xaccTransSetNotes(get(), v.toUtf8()); }
int countSplits() const { return xaccTransCountSplits(get()); }
};
} // END namespace gnc
#endif

View File

@ -46,6 +46,8 @@ extern "C"
#include "gnc/Account.hpp"
#include "gnc/AccountItemModel.hpp"
#include "gnc/Book.hpp"
#include "gnc/Split.hpp"
#include "gnc/SplitListModel.hpp"
namespace gnc
{
@ -173,6 +175,9 @@ void MainWindow::createActions()
// ui->actionCut, SLOT(setEnabled(bool)));
// connect(ui->textEdit, SIGNAL(copyAvailable(bool)),
// ui->actionCopy, SLOT(setEnabled(bool)));
connect(ui->treeView, SIGNAL(activated(const QModelIndex &)),
this, SLOT(activatedAccount(const QModelIndex&)));
}
void MainWindow::createToolBars()
@ -246,6 +251,36 @@ QString MainWindow::strippedName(const QString &fullFileName)
return QFileInfo(fullFileName).fileName();
}
void MainWindow::activatedAccount(const QModelIndex & index)
{
if (index.model() != m_accountTreeModel)
{
qDebug() << "Wrong model";
return;
}
Account account(static_cast< ::Account*>(index.internalPointer()));
if (!account)
{
qDebug() << "Account is null; why?";
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.
QTableView *tableView = new QTableView(this); // FIXME: Parent object unclear
SplitListModel *smodel = new SplitListModel(Split::fromGList(slist), tableView);
tableView->setModel(smodel);
// Insert this as a new tab
ui->tabWidget->addTab(tableView, account.getName());
ui->tabWidget->setCurrentWidget(tableView);
// Right now it cannot be deleted - this will be implemented later.
}
// ////////////////////////////////////////////////////////////
void MainWindow::closeEvent(QCloseEvent *event)
@ -320,24 +355,24 @@ namespace
* are in use simultaneously */
class progress_functor
{
public:
progress_functor(QProgressBar *progressBar)
{
m_progressBar = progressBar;
}
~progress_functor()
{
m_progressBar = NULL;
}
static void static_func(const char *message, double percent)
{
assert(m_progressBar);
m_progressBar->setValue(int(percent));
// Give the Qt event loop some time
qApp->processEvents();
}
private:
static QProgressBar *m_progressBar;
public:
progress_functor(QProgressBar *progressBar)
{
m_progressBar = progressBar;
}
~progress_functor()
{
m_progressBar = NULL;
}
static void static_func(const char *message, double percent)
{
assert(m_progressBar);
m_progressBar->setValue(int(percent));
// Give the Qt event loop some time
qApp->processEvents();
}
private:
static QProgressBar *m_progressBar;
};
QProgressBar *progress_functor::m_progressBar = NULL;

View File

@ -51,6 +51,7 @@ public:
public slots:
void anchorClicked(const QUrl &);
void activatedAccount(const QModelIndex & index);
protected:
void closeEvent(QCloseEvent *event);