From kde-commits Mon Jan 31 23:37:23 2011 From: =?utf-8?q?Stefan_B=C3=B6hmann?= Date: Mon, 31 Jan 2011 23:37:23 +0000 To: kde-commits Subject: =?utf-8?q?=5Bknipptasch=5D_/=3A_move_AccountModel_from_gui/_to_c?= Message-Id: <20110131233723.232C9A60CD () git ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=129651717506249 Git commit b94e3c7d4a0f0747ffc931afd547f0011977a047 by Stefan Böhmann. Pushed by sboehmann into branch 'master'. move AccountModel from gui/ to core/ M +4 -0 core/CMakeLists.txt A +771 -0 core/accountmodel.cpp [License: GPL (v2+)] A +141 -0 core/accountmodel.h [License: GPL (v2+)] A +1 -0 core/include/Knipptasch/AccountModel [License: Trivial file] M +0 -2 gui/CMakeLists.txt D +0 -632 gui/accountmodel.cpp D +0 -114 gui/accountmodel.h M +1 -0 gui/accountsortfilterproxymodel.cpp M +56 -6 gui/accountwidget.cpp M +3 -1 gui/delegate/categorydelegate.cpp M +3 -1 gui/delegate/postingtextdelegate.cpp M +4 -2 gui/quickreportwidget.cpp http://commits.kde.org/knipptasch/b94e3c7d4a0f0747ffc931afd547f0011977a047 diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 891b642..5df4818 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -17,6 +17,8 @@ set( knipptasch_core_SOURCES exportplugin.cpp importplugin.cpp + accountmodel.cpp + widgets/dateedit.cpp widgets/datevalidator.cpp widgets/datepickerpopup.cpp @@ -38,6 +40,8 @@ set( knipptasch_core_HEADERS exportplugin.h importplugin.h + accountmodel.h + widgets/dateedit.h widgets/datevalidator.h widgets/datepickerpopup.h diff --git a/core/accountmodel.cpp b/core/accountmodel.cpp new file mode 100644 index 0000000..724a7ee --- /dev/null +++ b/core/accountmodel.cpp @@ -0,0 +1,771 @@ +/* + * Copyright 2007-2010 by Stefan Böhmann + * + * 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, see . + */ +#include "accountmodel.h" + +#include "backend/account.h" +#include "backend/posting.h" +#include "backend/category.h" +#include "backend/money.h" + +#include "compat/utils.h" + +#include +#include +#include +#include +#include +#include +#include + + + +struct AccountModel::Private +{ + Private() + : account( 0 ), + posting( new Posting ) + { + } + + + ~Private() + { + delete posting; + delete account; + } + + + Account *account; + Posting *posting; + + QString dateFormat; + QColor positiveAmountForegroundColor; + QColor negativeAmountForegroundColor; + QColor availableWarrantyForegroundColor; + QColor expiredWarrantyForegroundColor; + QColor currentPostingBackgroundColor; + QColor futurePostingBackgroundColor; + QColor incompletePostingBackgroundColor; + QColor defaultPostingBackgroundColor; +}; + + + +AccountModel::AccountModel(QObject *parent) + : QAbstractTableModel( parent ), + d( new AccountModel::Private ) +{ +} + + +AccountModel::~AccountModel() +{ + delete d; +} + + +Account* AccountModel::account() +{ + return d->account; +} + + +const Account* AccountModel::account() const +{ + return d->account; +} + + +void AccountModel::setAccount(Account *account) +{ +#if QT_VERSION >= 0x040600 + beginResetModel(); +#endif + + d->account = account; + delete d->posting; + d->posting = new Posting; + +#if QT_VERSION >= 0x040600 + endResetModel(); +#else + reset(); +#endif +} + + +const Posting* AccountModel::posting(const QModelIndex &index) const +{ + if( index.isValid() ) { + return posting( index.row() ); + } + + return 0; +} + + +const Posting* AccountModel::posting(int row) const +{ + Q_ASSERT( row >= 0 ); + + if( row < account()->countPostings() ) { + return account()->posting( row ); + } + + return 0; +} + + +Posting* AccountModel::posting(const QModelIndex &index) +{ + if( index.isValid() ) { + return posting( index.row() ); + } + + return 0; +} + + +Posting* AccountModel::posting(int row) +{ + Q_ASSERT( row >= 0 ); + + if( row < account()->countPostings() ) { + return account()->posting( row ); + } + + return 0; +} + + +AccountModel::PostingTypeFlags AccountModel::postingType(int row) const +{ + if( row < d->account->countPostings() ) { + return postingType( d->account->posting( row ) ); + } + + return postingType( d->posting ); +} + + +int AccountModel::rowCount(const QModelIndex &parent) const +{ + if( !d->account ) { + return 0; + } + + if( parent.isValid() ) { + return 0; + } + + return d->account->countPostings() + 1; +} + + +int AccountModel::columnCount(const QModelIndex &parent) const +{ + if( parent.isValid() ) { + return 0; + } + + return AccountModel::ENTRYCOUNT; +} + + +QVariant AccountModel::data(const QModelIndex &index, int role) const +{ + if( !index.isValid() ) { + return QVariant(); + } + + if( !d->account ) { + return QVariant(); + } + + Q_ASSERT( index.row() >= 0 ); + Q_ASSERT( index.row() <= d->account->countPostings() ); + + switch( role ) { + case Qt::TextAlignmentRole: + return textAlignmentRoleData( index ); + + case Qt::BackgroundRole: + return backgroundRoleData( index ); + + case Qt::ForegroundRole: + return foregroundRoleData( index ); + + case Qt::DecorationRole: + return decorationRoleData( index ); + + case Qt::EditRole: + case Qt::DisplayRole: + break; + + default: // Can't handle this role... + return QVariant(); + } + + Posting *entry = 0; + if( index.row() < d->account->countPostings() ) { + entry = d->account->posting( index.row() ); + } + else { + entry = d->posting; + } + + Q_ASSERT( entry ); + + switch( index.column() ) + { + case MATURITY: + { + QDate dt = entry->maturity(); + if( role == Qt::EditRole ) { + return dt; + } + if( !dateFormat().isEmpty() ) { + return dt.toString( dateFormat() ); + } + return formatShortDate( dt ); + } + case POSTINGTEXT: + return entry->postingText(); + + case AMOUNT: + if( role == Qt::EditRole ) { + return QVariant::fromValue( entry->amount() ); + } + else if( entry->amount().cents() != 0 ) { + return entry->amount().toString(); + } + return QVariant(); + + case BALANCE: + break; + + case VALUEDATE: + { + QDate dt = entry->valueDate(); + if( role == Qt::EditRole ) { + return dt; + } + if( !dateFormat().isEmpty() ) { + return dt.toString( dateFormat() ); + } + return formatShortDate( dt ); + } + case CATEGORY: + if( role == Qt::EditRole ) { + return account()->identifierByObject( entry->category() ); + } + else if( entry->category() ) { + return entry->category()->name(); + } + + return QVariant(); + + case PAYEE: + return entry->payee(); + + case STATEMENT: + if( role == Qt::EditRole || entry->page() > 0 ) { + return entry->page(); + } + break; + + case VOUCHER: + entry->voucher(); + + case WARRANTY: + { + QDate dt = entry->warranty(); + if( role == Qt::EditRole ) { + return dt; + } + if( !dateFormat().isEmpty() ) { + return dt.toString( dateFormat() ); + } + return formatShortDate( dt ); + } + case PAYMENT: + return entry->methodOfPayment(); + + case DESCRIPTION: + return entry->description(); + } + + return QVariant(); +} + + +QVariant AccountModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section < AccountModel::ENTRYCOUNT ) { + switch( section ) { + case MATURITY: + return tr( "Maturity" ); + + case POSTINGTEXT: + return tr( "Posting Text" ); + + case AMOUNT: + return tr( "Amount" ); + + case BALANCE: + return tr( "Balance" ); + + case CATEGORY: + return tr( "Category" ); + + case PAYEE: + return tr( "Payee" ); + + case STATEMENT: + return tr( "Statement" ); + + case VOUCHER: + return tr( "Voucher" ); + + case WARRANTY: + return tr( "Warranty" ); + + case PAYMENT: + return tr( "Method of payment" ); + + case VALUEDATE: + return tr( "Value Date" ); + + case DESCRIPTION: + return tr( "Description" ); + + default: + break; + } + } + + return QAbstractTableModel::headerData( section, orientation, role ); +} + + +bool AccountModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if( !index.isValid() ) { + return false; + } + + if( !d->account ) { + return false; + } + + if( !(role == Qt::EditRole || role == Qt::DisplayRole) ) { + return false; + } + + if( index.column() == BALANCE ) { + return false; + } + + Posting *entry = 0; + if( index.row() < d->account->countPostings() ) { + entry = d->account->posting( index.row() ); + } + else { + Q_ASSERT( index.row() == d->account->countPostings() ); + entry = d->posting; + } + + Q_ASSERT( entry ); + + switch( index.column() ) { + case MATURITY: + entry->setMaturity( value.toDate() ); + break; + + case POSTINGTEXT: + entry->setPostingText( value.toString().trimmed() ); + break; + + case AMOUNT: + { + bool ok; + double amount = value.toDouble( &ok ); + if( !ok ) { + qDebug() << "invalid amount value"; + } + else { + entry->setAmount( amount ); + } + } + break; + + case BALANCE: + return false; + + case VALUEDATE: + entry->setValueDate( value.toDate() ); + break; + + case CATEGORY: + if( role == Qt::EditRole ) { + bool ok; + int v = value.toInt( &ok ); + Q_ASSERT( ok ); + + Object *object = account()->objectByIdentifier( v ); + Category *category = 0; + + if( object ) { + category = qobject_cast( object ); + Q_ASSERT( category ); + } + + entry->setCategory( category ); + } + break; + + case PAYEE: + entry->setPayee( value.toString() ); + break; + + case STATEMENT: + entry->setPage( value.toInt() ); + break; + + case VOUCHER: + entry->setVoucher( value.toString() ); + break; + + case DESCRIPTION: + entry->setDescription( value.toString() ); + break; + } + + if( index.row() >= d->account->countPostings() ) { + if( postingIsValid( d->posting ) ) { + beginInsertRows( QModelIndex(), rowCount(), rowCount() ); + d->account->addPosting( entry ); + endInsertRows(); + + d->posting = new Posting; + emit dataChanged( createIndex( rowCount()-1, 0 ), + createIndex( rowCount(), columnCount() ) ); + } + } + else { + emit dataChanged( createIndex( index.row(), index.column() ), + createIndex( index.row(), index.column() ) ); + } + + return true; +} + + +Qt::ItemFlags AccountModel::flags(const QModelIndex &index) const +{ + if( !index.isValid() ) { + return 0; + } + + if( !d->account ) { + return 0; + } + + if( index.column() == BALANCE ) { + return QAbstractItemModel::flags( index ); + } + + return QAbstractTableModel::flags( index ) | Qt::ItemIsEditable; +} + + +bool AccountModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if( !d->account ) { + return false; + } + + bool re = false; + + if( ( row + count - 1 ) == d->account->countPostings() ) { + count -= 1; + d->posting = new Posting; + re = true; + } + + if( ( row + count - 1 ) < d->account->countPostings() ) { + beginRemoveRows( parent, row, row + count - 1 ); + + for(int i = 0; i < count; ++i) { + d->account->removePosting( row ); + } + + endRemoveRows(); + re = true; + } + + return re; +} + + +QString AccountModel::dateFormat() const +{ + return d->dateFormat; +} + + +void AccountModel::setDateFormat(const QString &str) +{ + d->dateFormat = str; +} + + +QColor AccountModel::positiveAmountForegroundColor() const +{ + return d->positiveAmountForegroundColor; +} + + +void AccountModel::setPositiveAmountForegroundColor(const QColor &color) +{ + d->positiveAmountForegroundColor = color; +} + + +QColor AccountModel::negativeAmountForegroundColor() const +{ + return d->negativeAmountForegroundColor; +} + + +void AccountModel::setNegativeAmountForegroundColor(const QColor &color) +{ + d->negativeAmountForegroundColor = color; +} + +QColor AccountModel::availableWarrantyForegroundColor() const +{ + return d->availableWarrantyForegroundColor; +} + + +void AccountModel::setAvailableWarrantyForegroundColor(const QColor &color) +{ + d->availableWarrantyForegroundColor = color; +} + + +QColor AccountModel::expiredWarrantyForegroundColor() const +{ + return d->expiredWarrantyForegroundColor; +} + + +void AccountModel::setExpiredWarrantyForegroundColor(const QColor &color) +{ + d->expiredWarrantyForegroundColor = color; +} + + +QColor AccountModel::currentPostingBackgroundColor() const +{ + return d->currentPostingBackgroundColor; +} + + +void AccountModel::setCurrentPostingBackgroundColor(const QColor &color) +{ + d->currentPostingBackgroundColor = color; +} + + +QColor AccountModel::futurePostingBackgroundColor() const +{ + return d->futurePostingBackgroundColor; +} + + +void AccountModel::setFuturePostingBackgroundColor(const QColor &color) +{ + d->futurePostingBackgroundColor = color; +} + + +QColor AccountModel::incompletePostingBackgroundColor() const +{ + return d->incompletePostingBackgroundColor; +} + + +void AccountModel::setIncompletePostingBackgroundColor(const QColor &color) +{ + d->incompletePostingBackgroundColor = color; +} + + +QColor AccountModel::defaultPostingBackgroundColor() const +{ + return d->defaultPostingBackgroundColor; +} + + +void AccountModel::setDefaultPostingBackgroundColor(const QColor &color) +{ + d->defaultPostingBackgroundColor = color; +} + + +AccountModel::PostingTypeFlags AccountModel::postingType(const Posting *ptr) const +{ + Q_ASSERT( d->posting ); + Q_ASSERT( ptr ); + + PostingTypeFlags type = 0; + + if( ptr == d->posting ) { + type |= Current; + } + + if( !ptr->valueDate().isValid() ) { + type |= Incomplete; + } + + if( !postingIsValid( ptr ) ) { + type |= Invalid; + } + + if( ptr->maturity().isValid() && ptr->maturity() > QDate::currentDate() ) { + type |= Future; + } + + return type; +} + + +bool AccountModel::postingIsValid(const Posting *ptr) +{ + Q_ASSERT( ptr ); + + if( !ptr->maturity().isValid() ) { + return false; + } + + if( ptr->amount() == 0.0 ) { + return false; + } + + if( ptr->postingText().isEmpty() ) { + return false; + } + + return true; +} + + +QVariant AccountModel::backgroundRoleData(const QModelIndex &index) const +{ + AccountModel::PostingTypeFlags type = postingType( index.row() ); + + if( type & AccountModel::Current && currentPostingBackgroundColor().isValid() ) { + return currentPostingBackgroundColor(); + } + else if( type & AccountModel::Future && futurePostingBackgroundColor().isValid() ) { + return futurePostingBackgroundColor(); + } + else if( type & AccountModel::Incomplete && incompletePostingBackgroundColor().isValid() ) { + return incompletePostingBackgroundColor(); + } + else if( defaultPostingBackgroundColor().isValid() ) { + return defaultPostingBackgroundColor(); + } + + return QVariant(); +} + + +QVariant AccountModel::foregroundRoleData(const QModelIndex &index) const +{ + QColor c; + + switch( index.column() ) { + case AccountModel::AMOUNT: + c = data( index, Qt::EditRole ).value() >= 0.0 + ? positiveAmountForegroundColor() + : negativeAmountForegroundColor(); + break; + + case AccountModel::WARRANTY: + c = data( index, Qt::EditRole ).value() < QDate::currentDate() + ? availableWarrantyForegroundColor() + : expiredWarrantyForegroundColor(); + break; + + default: + break; + } + + return c.isValid() ? c : QVariant(); +} + + +QVariant AccountModel::textAlignmentRoleData(const QModelIndex &index) const +{ + switch( index.column() ) { + case AccountModel::VALUEDATE: + case AccountModel::MATURITY: + case AccountModel::WARRANTY: + case AccountModel::AMOUNT: + return static_cast( Qt::AlignRight | Qt::AlignVCenter ); + default: + break; + } + + return QVariant(); +} + + +QVariant AccountModel::decorationRoleData(const QModelIndex &index) const +{ + switch( index.column() ) { + case AccountModel::CATEGORY: + { + Posting *entry = 0; + if( index.row() < d->account->countPostings() ) { + entry = d->account->posting( index.row() ); + } + else { + entry = d->posting; + } + + Q_ASSERT( entry ); + + if( entry->category() && entry->category()->color().isValid() ) { + return entry->category()->color(); + } + } + + default: + break; + } + + return QVariant(); +} + + + +// kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; +// vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/core/accountmodel.h b/core/accountmodel.h new file mode 100644 index 0000000..197734b --- /dev/null +++ b/core/accountmodel.h @@ -0,0 +1,141 @@ +/* + * Copyright 2007-2010 by Stefan Böhmann + * + * 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, see . + */ +#ifndef KNIPPTASCH_CORE_ACCOUNTMODEL_H +#define KNIPPTASCH_CORE_ACCOUNTMODEL_H + +#include "knipptasch_core_export.h" + +#include + +class Account; +class Posting; +class Money; + +class QColor; + + +/** + * @class AccountModel + * @brief + * + * @author Stefan Böhmann + */ +class KNIPPTASCH_CORE_EXPORT AccountModel : public QAbstractTableModel +{ + Q_OBJECT + + public: + enum Column + { + MATURITY = 0, + POSTINGTEXT, + AMOUNT, + VALUEDATE, + CATEGORY, + BALANCE, + PAYEE, + STATEMENT, + VOUCHER, + WARRANTY, + PAYMENT, + DESCRIPTION, + ENTRYCOUNT + }; + + enum PostingTypeFlag + { + Scheduled = 1, + SplitPosting = 2, + WithAttachments = 4, + Incomplete = 8, + Invalid = 16, + Current = 32, + Future = 64 + }; + + Q_DECLARE_FLAGS(PostingTypeFlags, PostingTypeFlag) + + explicit AccountModel(QObject *parent = 0); + ~AccountModel(); + + Account* account(); + const Account* account() const; + void setAccount(Account *account); + + const Posting* posting(const QModelIndex &index) const; + const Posting* posting(int row) const; + Posting* posting(const QModelIndex &index); + Posting* posting(int row); + + PostingTypeFlags postingType(int row) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole); + Qt::ItemFlags flags(const QModelIndex &index) const; + + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + + QString dateFormat() const; + void setDateFormat(const QString &str); + + QColor positiveAmountForegroundColor() const; + void setPositiveAmountForegroundColor(const QColor &color); + QColor negativeAmountForegroundColor() const; + void setNegativeAmountForegroundColor(const QColor &color); + QColor availableWarrantyForegroundColor() const; + void setAvailableWarrantyForegroundColor(const QColor &color); + QColor expiredWarrantyForegroundColor() const; + void setExpiredWarrantyForegroundColor(const QColor &color); + QColor currentPostingBackgroundColor() const; + void setCurrentPostingBackgroundColor(const QColor &color); + QColor futurePostingBackgroundColor() const; + void setFuturePostingBackgroundColor(const QColor &color); + QColor incompletePostingBackgroundColor() const; + void setIncompletePostingBackgroundColor(const QColor &color); + QColor defaultPostingBackgroundColor() const; + void setDefaultPostingBackgroundColor(const QColor &color); + + private: + QVariant backgroundRoleData(const QModelIndex &index) const; + QVariant foregroundRoleData(const QModelIndex &index) const; + QVariant textAlignmentRoleData(const QModelIndex &index) const; + QVariant decorationRoleData(const QModelIndex &index) const; + + void initDemoAccountAddPosting(const QDate &date, const QString &postingText, const Money &amount, bool valueDate = true); + + PostingTypeFlags postingType(const Posting *p) const; + static bool postingIsValid(const Posting *p); + + private: + class Private; + Private* const d; +}; + + +Q_DECLARE_OPERATORS_FOR_FLAGS( AccountModel::PostingTypeFlags ) +Q_DECLARE_METATYPE( AccountModel::PostingTypeFlags ) + + +#endif + +// kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; +// vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/core/include/Knipptasch/AccountModel b/core/include/Knipptasch/AccountModel new file mode 100644 index 0000000..ff21237 --- /dev/null +++ b/core/include/Knipptasch/AccountModel @@ -0,0 +1 @@ +#include diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 2f33598..3556c7f 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -1,7 +1,6 @@ project( knipptasch ) set(knipptasch_SOURCES - accountmodel.cpp accountsortfilterproxymodel.cpp accountwidget.cpp welcomewidget.cpp @@ -45,7 +44,6 @@ set(knipptasch_SOURCES set( knipptasch_HEADERS mainwindow.h accountwidget.h - accountmodel.h accountsortfilterproxymodel.h welcomewidget.h aboutdialog.h diff --git a/gui/accountmodel.cpp b/gui/accountmodel.cpp deleted file mode 100644 index f442f51..0000000 --- a/gui/accountmodel.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Copyright 2007-2010 by Stefan Böhmann - * - * 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, see . - */ -#include "accountmodel.h" - -#include "preferences.h" - -#include "backend/account.h" -#include "backend/posting.h" -#include "backend/category.h" -#include "backend/money.h" - -#include "compat/utils.h" - -#include -#include -#include -#include -#include -#include -#include - - -AccountModel::AccountModel(QObject *parent) - : QAbstractTableModel( parent ), - m_account( 0 ), - m_posting( new Posting ) -{ -} - - -AccountModel::~AccountModel() -{ - delete m_posting; - delete m_account; -} - - -void AccountModel::setAccount(Account *account) -{ -#if QT_VERSION >= 0x040600 - beginResetModel(); -#endif - - m_account = account; - delete m_posting; - m_posting = new Posting; - -#if QT_VERSION >= 0x040600 - endResetModel(); -#else - reset(); -#endif -} - - -const Posting* AccountModel::posting(const QModelIndex &index) const -{ - if( index.isValid() ) { - return posting( index.row() ); - } - - return 0; -} - - -const Posting* AccountModel::posting(int row) const -{ - Q_ASSERT( row >= 0 ); - - if( row < account()->countPostings() ) { - return account()->posting( row ); - } - - return 0; -} - - -Posting* AccountModel::posting(const QModelIndex &index) -{ - if( index.isValid() ) { - return posting( index.row() ); - } - - return 0; -} - - -Posting* AccountModel::posting(int row) -{ - Q_ASSERT( row >= 0 ); - - if( row < account()->countPostings() ) { - return account()->posting( row ); - } - - return 0; -} - - -AccountModel::PostingTypeFlags AccountModel::postingType(int row) const -{ - if( row < m_account->countPostings() ) { - return postingType( m_account->posting( row ) ); - } - - return postingType( m_posting ); -} - - -int AccountModel::rowCount(const QModelIndex &parent) const -{ - if( !m_account ) { - return 0; - } - - if( parent.isValid() ) { - return 0; - } - - return m_account->countPostings() + 1; -} - - -int AccountModel::columnCount(const QModelIndex &parent) const -{ - if( parent.isValid() ) { - return 0; - } - - return AccountModel::ENTRYCOUNT; -} - - -QVariant AccountModel::data(const QModelIndex &index, int role) const -{ - if( !index.isValid() ) { - return QVariant(); - } - - if( !m_account ) { - return QVariant(); - } - - Q_ASSERT( index.row() >= 0 ); - Q_ASSERT( index.row() <= m_account->countPostings() ); - - switch( role ) { - case Qt::TextAlignmentRole: - return textAlignmentRoleData( index ); - - case Qt::BackgroundRole: - return backgroundRoleData( index ); - - case Qt::ForegroundRole: - return foregroundRoleData( index ); - - case Qt::DecorationRole: - return decorationRoleData( index ); - - case Qt::EditRole: - case Qt::DisplayRole: - break; - - default: // Can't handle this role... - return QVariant(); - } - - Posting *entry = 0; - if( index.row() < m_account->countPostings() ) { - entry = m_account->posting( index.row() ); - } - else { - entry = m_posting; - } - - Q_ASSERT( entry ); - - switch( index.column() ) - { - case MATURITY: - { - QDate dt = entry->maturity(); - if( role == Qt::EditRole ) { - return dt; - } - if( !Preferences::self()->userDefinedDateFormat().isEmpty() ) { - return dt.toString( Preferences::self()->userDefinedDateFormat() ); - } - return formatShortDate( dt ); - } - case POSTINGTEXT: - return entry->postingText(); - - case AMOUNT: - if( role == Qt::EditRole ) { - return QVariant::fromValue( entry->amount() ); - } - else if( entry->amount().cents() != 0 ) { - return entry->amount().toString(); - } - return QVariant(); - - case BALANCE: - break; - - case VALUEDATE: - { - QDate dt = entry->valueDate(); - if( role == Qt::EditRole ) { - return dt; - } - if( !Preferences::self()->userDefinedDateFormat().isEmpty() ) { - return dt.toString( Preferences::self()->userDefinedDateFormat() ); - } - return formatShortDate( dt ); - } - case CATEGORY: - if( role == Qt::EditRole ) { - return account()->identifierByObject( entry->category() ); - } - else if( entry->category() ) { - return entry->category()->name(); - } - - return QVariant(); - - case PAYEE: - return entry->payee(); - - case STATEMENT: - if( role == Qt::EditRole || entry->page() > 0 ) { - return entry->page(); - } - break; - - case VOUCHER: - entry->voucher(); - - case WARRANTY: - { - QDate dt = entry->warranty(); - if( role == Qt::EditRole ) { - return dt; - } - if( !Preferences::self()->userDefinedDateFormat().isEmpty() ) { - return dt.toString( Preferences::self()->userDefinedDateFormat() ); - } - return formatShortDate( dt ); - } - case PAYMENT: - return entry->methodOfPayment(); - - case DESCRIPTION: - return entry->description(); - } - - return QVariant(); -} - - -QVariant AccountModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if( orientation == Qt::Horizontal && role == Qt::DisplayRole && section < AccountModel::ENTRYCOUNT ) { - switch( section ) { - case MATURITY: - return tr( "Maturity" ); - - case POSTINGTEXT: - return tr( "Posting Text" ); - - case AMOUNT: - return tr( "Amount" ); - - case BALANCE: - return tr( "Balance" ); - - case CATEGORY: - return tr( "Category" ); - - case PAYEE: - return tr( "Payee" ); - - case STATEMENT: - return tr( "Statement" ); - - case VOUCHER: - return tr( "Voucher" ); - - case WARRANTY: - return tr( "Warranty" ); - - case PAYMENT: - return tr( "Method of payment" ); - - case VALUEDATE: - return tr( "Value Date" ); - - case DESCRIPTION: - return tr( "Description" ); - - default: - break; - } - } - - return QAbstractTableModel::headerData( section, orientation, role ); -} - - -bool AccountModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if( !index.isValid() ) { - return false; - } - - if( !m_account ) { - return false; - } - - if( !(role == Qt::EditRole || role == Qt::DisplayRole) ) { - return false; - } - - if( index.column() == BALANCE ) { - return false; - } - - Posting *entry = 0; - if( index.row() < m_account->countPostings() ) { - entry = m_account->posting( index.row() ); - } - else { - Q_ASSERT( index.row() == m_account->countPostings() ); - entry = m_posting; - } - - Q_ASSERT( entry ); - - switch( index.column() ) { - case MATURITY: - entry->setMaturity( value.toDate() ); - break; - - case POSTINGTEXT: - entry->setPostingText( value.toString().trimmed() ); - break; - - case AMOUNT: - { - bool ok; - double amount = value.toDouble( &ok ); - if( !ok ) { - qDebug() << "invalid amount value"; - } - else { - entry->setAmount( amount ); - } - } - break; - - case BALANCE: - return false; - - case VALUEDATE: - entry->setValueDate( value.toDate() ); - break; - - case CATEGORY: - if( role == Qt::EditRole ) { - bool ok; - int v = value.toInt( &ok ); - Q_ASSERT( ok ); - - Object *object = account()->objectByIdentifier( v ); - Category *category = 0; - - if( object ) { - category = qobject_cast( object ); - Q_ASSERT( category ); - } - - entry->setCategory( category ); - } - break; - - case PAYEE: - entry->setPayee( value.toString() ); - break; - - case STATEMENT: - entry->setPage( value.toInt() ); - break; - - case VOUCHER: - entry->setVoucher( value.toString() ); - break; - - case DESCRIPTION: - entry->setDescription( value.toString() ); - break; - } - - if( index.row() >= m_account->countPostings() ) { - if( postingIsValid( m_posting ) ) { - beginInsertRows( QModelIndex(), rowCount(), rowCount() ); - m_account->addPosting( entry ); - endInsertRows(); - - m_posting = new Posting; - emit dataChanged( createIndex( rowCount()-1, 0 ), createIndex( rowCount(), columnCount() ) ); - } - } - else { - emit dataChanged( createIndex( index.row(), index.column() ), createIndex( index.row(), index.column() ) ); - } - - return true; -} - - -Qt::ItemFlags AccountModel::flags(const QModelIndex &index) const -{ - if( !index.isValid() ) { - return 0; - } - - if( !m_account ) { - return 0; - } - - if( index.column() == BALANCE ) { - return QAbstractItemModel::flags( index ); - } - - return QAbstractTableModel::flags( index ) | Qt::ItemIsEditable; -} - - -bool AccountModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if( !m_account ) { - return false; - } - - bool re = false; - - if( ( row + count - 1 ) == m_account->countPostings() ) { - count -= 1; - m_posting = new Posting; - re = true; - } - - if( ( row + count - 1 ) < m_account->countPostings() ) { - beginRemoveRows( parent, row, row + count - 1 ); - - for(int i = 0; i < count; ++i) { - m_account->removePosting( row ); - } - - endRemoveRows(); - re = true; - } - - return re; -} - - -AccountModel::PostingTypeFlags AccountModel::postingType(const Posting *ptr) const -{ - Q_ASSERT( m_posting ); - Q_ASSERT( ptr ); - - PostingTypeFlags type = 0; - - if( ptr == m_posting ) { - type |= Current; - } - - if( !ptr->valueDate().isValid() ) { - type |= Incomplete; - } - - if( !postingIsValid( ptr ) ) { - type |= Invalid; - } - - if( ptr->maturity().isValid() && ptr->maturity() > QDate::currentDate() ) { - type |= Future; - } - - return type; -} - - -bool AccountModel::postingIsValid(const Posting *ptr) -{ - Q_ASSERT( ptr ); - - if( !ptr->maturity().isValid() ) { - return false; - } - - if( ptr->amount() == 0.0 ) { - return false; - } - - if( ptr->postingText().isEmpty() ) { - return false; - } - - return true; -} - - -QVariant AccountModel::backgroundRoleData(const QModelIndex &index) const -{ - AccountModel::PostingTypeFlags type = postingType( index.row() ); - - if( type & AccountModel::Current && Preferences::self()->currentPostingBackgroundEnabled() ) { - return Preferences::self()->currentPostingBackgroundColor(); - } - else if( type & AccountModel::Future && Preferences::self()->futurePostingBackgroundEnabled() ) { - return Preferences::self()->futurePostingBackgroundColor(); - } - else if( type & AccountModel::Incomplete && Preferences::self()->incompletePostingBackgroundEnabled() ) { - return Preferences::self()->incompletePostingBackgroundColor(); - } - - if( Preferences::self()->defaultPostingBackgroundEnabled() ) { - return Preferences::self()->defaultPostingBackgroundColor(); - } - - return QVariant(); -} - - -QVariant AccountModel::foregroundRoleData(const QModelIndex &index) const -{ - switch( index.column() ) { - case AccountModel::AMOUNT: - { - Money m = data( index, Qt::EditRole ).value(); - if( m >= 0.0 && Preferences::self()->positiveAmountForegroundEnabled() ) { - return Preferences::self()->positiveAmountForegroundColor(); - } - else if( m < 0.0 && Preferences::self()->negativeAmountForegroundEnabled() ) { - return Preferences::self()->negativeAmountForegroundColor(); - } - } - break; - - case AccountModel::WARRANTY: - { - QDate d = data( index, Qt::EditRole ).value(); - if( d < QDate::currentDate() && Preferences::self()->availableWarrantyForegroundEnabled() ) { - return Preferences::self()->availableWarrantyForegroundColor(); - } - else if( Preferences::self()->expiredWarrantyForegroundEnabled() ) { - return Preferences::self()->expiredWarrantyForegroundColor(); - } - } - break; - - default: - break; - } - - return QVariant(); -} - - -QVariant AccountModel::textAlignmentRoleData(const QModelIndex &index) const -{ - switch( index.column() ) { - case AccountModel::VALUEDATE: - case AccountModel::MATURITY: - case AccountModel::WARRANTY: - case AccountModel::AMOUNT: - return static_cast( Qt::AlignRight | Qt::AlignVCenter ); - default: - break; - } - - return QVariant(); -} - - -QVariant AccountModel::decorationRoleData(const QModelIndex &index) const -{ - switch( index.column() ) { - case AccountModel::CATEGORY: - { - Posting *entry = 0; - if( index.row() < m_account->countPostings() ) { - entry = m_account->posting( index.row() ); - } - else { - entry = m_posting; - } - - Q_ASSERT( entry ); - - if( entry->category() && entry->category()->color().isValid() ) { - return entry->category()->color(); - } - } - - default: - break; - } - - return QVariant(); -} - - - -// kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; -// vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/gui/accountmodel.h b/gui/accountmodel.h deleted file mode 100644 index dfdfb1d..0000000 --- a/gui/accountmodel.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2007-2010 by Stefan Böhmann - * - * 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, see . - */ -#ifndef ACCOUNTMODEL_H -#define ACCOUNTMODEL_H - -#include - -#include - - -/** - * @class AccountModel - * @brief - * - * @author Stefan Böhmann - */ -class AccountModel : public QAbstractTableModel -{ - Q_OBJECT - - public: - enum Column - { - MATURITY = 0, - POSTINGTEXT, - AMOUNT, - VALUEDATE, - CATEGORY, - BALANCE, - PAYEE, - STATEMENT, - VOUCHER, - WARRANTY, - PAYMENT, - DESCRIPTION, - ENTRYCOUNT - }; - - enum PostingTypeFlag - { - Scheduled = 1, - SplitPosting = 2, - WithAttachments = 4, - Incomplete = 8, - Invalid = 16, - Current = 32, - Future = 64 - }; - - Q_DECLARE_FLAGS(PostingTypeFlags, PostingTypeFlag) - - explicit AccountModel(QObject *parent = 0); - ~AccountModel(); - - Account* account() { return m_account; } - const Account* account() const { return m_account; } - void setAccount(Account *account); - - const Posting* posting(const QModelIndex &index) const; - const Posting* posting(int row) const; - Posting* posting(const QModelIndex &index); - Posting* posting(int row); - - PostingTypeFlags postingType(int row) const; - - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole); - Qt::ItemFlags flags(const QModelIndex &index) const; - - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - - private: - QVariant backgroundRoleData(const QModelIndex &index) const; - QVariant foregroundRoleData(const QModelIndex &index) const; - QVariant textAlignmentRoleData(const QModelIndex &index) const; - QVariant decorationRoleData(const QModelIndex &index) const; - - void initDemoAccountAddPosting(const QDate &date, const QString &postingText, const Money &amount, bool valueDate = true); - - PostingTypeFlags postingType(const Posting *p) const; - static bool postingIsValid(const Posting *p); - - private: - Account *m_account; - Posting *m_posting; -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS( AccountModel::PostingTypeFlags ) -Q_DECLARE_METATYPE( AccountModel::PostingTypeFlags ) - - -#endif - -// kate: word-wrap off; encoding utf-8; indent-width 4; tab-width 4; line-numbers on; mixed-indent off; remove-trailing-space-save on; replace-tabs-save on; replace-tabs on; space-indent on; -// vim:set spell et sw=4 ts=4 nowrap cino=l1,cs,U1: diff --git a/gui/accountsortfilterproxymodel.cpp b/gui/accountsortfilterproxymodel.cpp index b077268..9ad74f8 100644 --- a/gui/accountsortfilterproxymodel.cpp +++ b/gui/accountsortfilterproxymodel.cpp @@ -18,6 +18,7 @@ #include "preferences.h" #include "backend/money.h" +#include "backend/account.h" #include "backend/posting.h" #include diff --git a/gui/accountwidget.cpp b/gui/accountwidget.cpp index 01eda64..d4e0730 100644 --- a/gui/accountwidget.cpp +++ b/gui/accountwidget.cpp @@ -41,6 +41,7 @@ #include "compat/standardaction.h" #include "compat/utils.h" +#include #include #include #include @@ -288,6 +289,8 @@ QList AccountWidget::selectedPostings() const void AccountWidget::loadConfig() { + Preferences *p = Preferences::self(); + QByteArray arr = QByteArray::fromBase64( Preferences::self()->horizontalHeaderState().toAscii() ); if( arr.isEmpty() ) { @@ -305,13 +308,58 @@ void AccountWidget::loadConfig() ui->view->horizontalHeader()->restoreState( arr ); } - // TODO: Make configurable - //ui->view->setEditTriggers( QAbstractItemView::AllEditTriggers ); - ui->view->horizontalHeader()->setMovable( Preferences::self()->movableColumns() ); + m_model->setPositiveAmountForegroundColor( + p->positiveAmountForegroundEnabled() + ? p->positiveAmountForegroundColor() + : QColor() + ); - ui->view->horizontalHeader()->setCascadingSectionResizes( - Preferences::self()->cascadingSectionResize() ); + m_model->setNegativeAmountForegroundColor( + p->negativeAmountForegroundEnabled() + ? p->negativeAmountForegroundColor() + : QColor() + ); + + m_model->setAvailableWarrantyForegroundColor( + p->availableWarrantyForegroundEnabled() + ? p->availableWarrantyForegroundColor() + : QColor() + ); + + m_model->setExpiredWarrantyForegroundColor( + p->expiredWarrantyForegroundEnabled() + ? p->expiredWarrantyForegroundColor() + : QColor() + ); + + m_model->setCurrentPostingBackgroundColor( + p->currentPostingBackgroundEnabled() + ? p->currentPostingBackgroundColor() + : QColor() + ); + + m_model->setFuturePostingBackgroundColor( + p->futurePostingBackgroundEnabled() + ? p->futurePostingBackgroundColor() + : QColor() + ); + + m_model->setIncompletePostingBackgroundColor( + p->incompletePostingBackgroundEnabled() + ? p->incompletePostingBackgroundColor() + : QColor() + ); + + m_model->setDefaultPostingBackgroundColor( + p->defaultPostingBackgroundEnabled() + ? p->defaultPostingBackgroundColor() + : QColor() + ); + + QHeaderView *h = ui->view->horizontalHeader(); + h->setMovable( p->movableColumns() ); + h->setCascadingSectionResizes( p->cascadingSectionResize() ); ui->view->reset(); } @@ -319,7 +367,9 @@ void AccountWidget::loadConfig() void AccountWidget::saveConfig() { - Preferences::self()->setHorizontalHeaderState( ui->view->horizontalHeader()->saveState().toBase64() ); + Preferences::self()->setHorizontalHeaderState( + ui->view->horizontalHeader()->saveState().toBase64() + ); } diff --git a/gui/delegate/categorydelegate.cpp b/gui/delegate/categorydelegate.cpp index f03e4cd..b76b1c1 100644 --- a/gui/delegate/categorydelegate.cpp +++ b/gui/delegate/categorydelegate.cpp @@ -17,10 +17,12 @@ #include "categorydelegate.h" #include "categorycombobox.h" -#include "accountsortfilterproxymodel.h" +#include "backend/account.h" #include "backend/posting.h" #include "backend/category.h" +#include "accountsortfilterproxymodel.h" + #include #include #include diff --git a/gui/delegate/postingtextdelegate.cpp b/gui/delegate/postingtextdelegate.cpp index 736a0be..23fa614 100644 --- a/gui/delegate/postingtextdelegate.cpp +++ b/gui/delegate/postingtextdelegate.cpp @@ -16,9 +16,11 @@ */ #include "postingtextdelegate.h" -#include "accountsortfilterproxymodel.h" +#include "backend/account.h" #include "backend/posting.h" +#include "accountsortfilterproxymodel.h" + #include "preferences.h" #include diff --git a/gui/quickreportwidget.cpp b/gui/quickreportwidget.cpp index 65eb82d..4de5e92 100644 --- a/gui/quickreportwidget.cpp +++ b/gui/quickreportwidget.cpp @@ -17,6 +17,10 @@ #include "quickreportwidget.h" #include "ui_quickreportwidget.h" +#include "backend/account.h" +#include "backend/money.h" +#include "backend/posting.h" + #include "accountsortfilterproxymodel.h" #include "preferences.h" @@ -31,8 +35,6 @@ #include #include -#include "backend/money.h" -#include "backend/posting.h" bool doSortPostings(const Posting *p1, const Posting *p2)