[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kmymoney] kmymoney/views: Improve the new ledger
From: Thomas Baumgart <null () kde ! org>
Date: 2017-12-31 14:15:42
Message-ID: E1eVeOs-0007Ih-Rh () code ! kde ! org
[Download RAW message or body]
Git commit b9e168955e73afa59925527b8ce8b32618bc4bfa by Thomas Baumgart.
Committed on 31/12/2017 at 14:15.
Pushed by tbaumgart into branch 'master'.
Improve the new ledger
The following changes have been made
- Display online balance if available
- Use standard colors from KColorScheme for separator background
- Paint separator text centered based on the view width
and not centered in detail column
M +186 -36 kmymoney/views/ledgerdelegate.cpp
M +6 -0 kmymoney/views/ledgerdelegate.h
M +28 -0 kmymoney/views/ledgerview.cpp
M +2 -0 kmymoney/views/ledgerview.h
https://commits.kde.org/kmymoney/b9e168955e73afa59925527b8ce8b32618bc4bfa
diff --git a/kmymoney/views/ledgerdelegate.cpp b/kmymoney/views/ledgerdelegate.cpp
index f3a74d1a..04dadfac 100644
--- a/kmymoney/views/ledgerdelegate.cpp
+++ b/kmymoney/views/ledgerdelegate.cpp
@@ -30,6 +30,7 @@
// KDE Includes
#include <KLocalizedString>
+#include <KColorScheme>
// ----------------------------------------------------------------------------
// Project Includes
@@ -124,6 +125,7 @@ QColor LedgerDelegate::m_erroneousColor = QColor(Qt::red);
QColor LedgerDelegate::m_importedColor = QColor(Qt::yellow);
QColor LedgerDelegate::m_separatorColor = QColor(0xff, 0xf2, 0x9b);
+
class LedgerSeperatorDate : public LedgerSeperator
{
public:
@@ -132,12 +134,30 @@ public:
virtual bool rowHasSeperator(const QModelIndex& index) const;
virtual QString separatorText(const QModelIndex& index) const;
+ virtual void adjustBackgroundScheme(QPalette& palette, const QModelIndex& index) \
const;
-private:
+protected:
QString getEntry(const QModelIndex& index, const QModelIndex& nextIndex) const;
QMap<QDate, QString> m_entries;
};
+class LedgerSeparatorOnlineBalance : public LedgerSeperatorDate
+{
+public:
+ LedgerSeparatorOnlineBalance(eLedgerModel::Role role);
+ virtual ~LedgerSeparatorOnlineBalance() {}
+
+ virtual bool rowHasSeperator(const QModelIndex& index) const;
+ virtual QString separatorText(const QModelIndex& index) const;
+ virtual void adjustBackgroundScheme(QPalette& palette, const QModelIndex& index) \
const; +
+ void setSeparatorData(const QDate& date, const MyMoneyMoney& amount, int \
fraction); +
+private:
+ QString m_balanceAmount;
+};
+
+
QDate LedgerSeperator::firstFiscalDate;
bool LedgerSeperator::showFiscalDate = true;
@@ -161,8 +181,6 @@ QModelIndex LedgerSeperator::nextIndex(const QModelIndex& index) \
const return QModelIndex();
}
-
-
LedgerSeperatorDate::LedgerSeperatorDate(eLedgerModel::Role role)
: LedgerSeperator(role)
{
@@ -206,13 +224,15 @@ QString LedgerSeperatorDate::getEntry(const QModelIndex& index, \
const QModelInde
const QAbstractItemModel* model = index.model();
QString rc;
- if (model->data(index, (int)m_role).toDate() != model->data(nextIndex, \
(int)m_role).toDate()) {
- const QDate key = model->data(index, (int)m_role).toDate();
- const QDate endKey = model->data(nextIndex, (int)m_role).toDate();
- QMap<QDate, QString>::const_iterator it = m_entries.upperBound(key);
- while((it != m_entries.cend()) && (it.key() <= endKey)) {
- rc = *it;
- ++it;
+ if(!m_entries.isEmpty()) {
+ if (model->data(index, (int)m_role).toDate() != model->data(nextIndex, \
(int)m_role).toDate()) { + const QDate key = model->data(index, \
(int)m_role).toDate(); + const QDate endKey = model->data(nextIndex, \
(int)m_role).toDate(); + QMap<QDate, QString>::const_iterator it = \
m_entries.upperBound(key); + while((it != m_entries.cend()) && (it.key() <= \
endKey)) { + rc = *it;
+ ++it;
+ }
}
}
return rc;
@@ -221,14 +241,16 @@ QString LedgerSeperatorDate::getEntry(const QModelIndex& index, \
const QModelInde bool LedgerSeperatorDate::rowHasSeperator(const QModelIndex& index) \
const {
bool rc = false;
- QModelIndex nextIdx = nextIndex(index);
- if(nextIdx.isValid() ) {
- const QString id = nextIdx.model()->data(nextIdx, \
(int)eLedgerModel::Role::TransactionSplitId).toString();
- // For a new transaction the id is completely empty, for a split view the \
transaction
- // part is filled but the split id is empty and the string ends with a dash
- // and we never draw a separator in front of that row
- if(!id.isEmpty() && !id.endsWith('-')) {
- rc = !getEntry(index, nextIdx).isEmpty();
+ if(!m_entries.isEmpty()) {
+ QModelIndex nextIdx = nextIndex(index);
+ if(nextIdx.isValid() ) {
+ const QString id = nextIdx.model()->data(nextIdx, \
(int)eLedgerModel::Role::TransactionSplitId).toString(); + // For a new \
transaction the id is completely empty, for a split view the transaction + // \
part is filled but the split id is empty and the string ends with a dash + // \
and we never draw a separator in front of that row + if(!id.isEmpty() && \
!id.endsWith('-')) { + rc = !getEntry(index, nextIdx).isEmpty();
+ }
}
}
return rc;
@@ -243,6 +265,74 @@ QString LedgerSeperatorDate::separatorText(const QModelIndex& \
index) const return QString();
}
+void LedgerSeperatorDate::adjustBackgroundScheme(QPalette& palette, const \
QModelIndex& index) const +{
+ Q_UNUSED(index);
+ KColorScheme::adjustBackground(palette, KColorScheme::ActiveBackground, \
QPalette::Base, KColorScheme::Button, KSharedConfigPtr()); +}
+
+
+
+LedgerSeparatorOnlineBalance::LedgerSeparatorOnlineBalance(eLedgerModel::Role role)
+ : LedgerSeperatorDate(role)
+{
+ // we don't need the standard values
+ m_entries.clear();
+}
+
+void LedgerSeparatorOnlineBalance::setSeparatorData(const QDate& date, const \
MyMoneyMoney& amount, int fraction) +{
+ m_entries.clear();
+ if (date.isValid()) {
+ m_balanceAmount = amount.formatMoney(fraction);
+ m_entries[date] = i18n("Online statement balance: %1").arg(m_balanceAmount);
+ }
+}
+
+bool LedgerSeparatorOnlineBalance::rowHasSeperator(const QModelIndex& index) const
+{
+ bool rc = false;
+ if(!m_entries.isEmpty()) {
+ QModelIndex nextIdx = nextIndex(index);
+ const QAbstractItemModel* model = index.model();
+ // if this is not the last entry?
+ if(nextIdx.isValid() ) {
+ // index points to the last entry of a date
+ rc = (model->data(index, (int)m_role).toDate() != model->data(nextIdx, \
(int)m_role).toDate()); + if (rc) {
+ // check if this the spot for the online balance data
+ rc &= ((model->data(index, (int)m_role).toDate() <= m_entries.firstKey())
+ && (model->data(nextIdx, (int)m_role).toDate() > m_entries.firstKey()));
+ }
+ } else {
+ rc = (model->data(index, (int)m_role).toDate() <= m_entries.firstKey());
+ }
+ }
+ return rc;
+}
+
+QString LedgerSeparatorOnlineBalance::separatorText(const QModelIndex& index) const
+{
+ if(rowHasSeperator(index)) {
+ return m_entries.first();
+ }
+ return QString();
+}
+
+void LedgerSeparatorOnlineBalance::adjustBackgroundScheme(QPalette& palette, const \
QModelIndex& index) const +{
+ const QAbstractItemModel* model = index.model();
+ QModelIndex amountIndex = model->index(index.row(), \
(int)eLedgerModel::Column::Balance); + QString amount = \
model->data(amountIndex).toString(); + KColorScheme::BackgroundRole role = \
KColorScheme::PositiveBackground; +
+ if (!m_entries.isEmpty()) {
+ if(amount != m_balanceAmount) {
+ role = KColorScheme::NegativeBackground;
+ }
+ }
+ KColorScheme::adjustBackground(palette, role, QPalette::Base, \
KColorScheme::Button, KSharedConfigPtr()); +}
@@ -253,8 +343,9 @@ public:
Private()
: m_editor(0)
, m_view(0)
- , m_separator(0)
, m_editorRow(-1)
+ , m_separator(0)
+ , m_onlineBalanceSeparator(0)
{}
~Private()
@@ -267,10 +358,16 @@ public:
return m_separator && m_separator->rowHasSeperator(index);
}
+ inline bool displayOnlineBalanceSeparator(const QModelIndex& index) const
+ {
+ return m_onlineBalanceSeparator && \
m_onlineBalanceSeparator->rowHasSeperator(index); + }
+
NewTransactionEditor* m_editor;
LedgerView* m_view;
- LedgerSeperator* m_separator;
int m_editorRow;
+ LedgerSeperator* m_separator;
+ LedgerSeparatorOnlineBalance* m_onlineBalanceSeparator;
};
@@ -289,10 +386,14 @@ LedgerDelegate::~LedgerDelegate()
void LedgerDelegate::setSortRole(eLedgerModel::Role role)
{
delete d->m_separator;
+ delete d->m_onlineBalanceSeparator;
d->m_separator = 0;
+ d->m_onlineBalanceSeparator = 0;
+
switch(role) {
case eLedgerModel::Role::PostDate:
d->m_separator = new LedgerSeperatorDate(role);
+ d->m_onlineBalanceSeparator = new LedgerSeparatorOnlineBalance(role);
break;
default:
qDebug() << "LedgerDelegate::setSortRole role" << (int)role << "not \
implemented"; @@ -300,12 +401,17 @@ void \
LedgerDelegate::setSortRole(eLedgerModel::Role role) }
}
-
void LedgerDelegate::setErroneousColor(const QColor& color)
{
m_erroneousColor = color;
}
+void LedgerDelegate::setOnlineBalance(const QDate& date, const MyMoneyMoney& amount, \
int fraction) +{
+ if(d->m_onlineBalanceSeparator) {
+ d->m_onlineBalanceSeparator->setSeparatorData(date, amount, fraction);
+ }
+}
QWidget* LedgerDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& \
option, const QModelIndex& index) const {
@@ -366,6 +472,7 @@ void LedgerDelegate::paint(QPainter* painter, const \
QStyleOptionViewItem& option QAbstractItemView* view = qobject_cast< \
QAbstractItemView* >(parent()); const bool editWidgetIsVisible = d->m_view && \
d->m_view->indexWidget(index); const bool rowHasSeperator = \
d->displaySeperator(index); + const bool rowHasOnlineBalance = \
d->displayOnlineBalanceSeparator(index);
// Background
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
@@ -376,9 +483,15 @@ void LedgerDelegate::paint(QPainter* painter, const \
QStyleOptionViewItem& option // don't draw over the separator space
opt.rect.setHeight(opt.rect.height() - lineHeight );
}
+ if (rowHasOnlineBalance) {
+ // don't draw over the online balance space
+ opt.rect.setHeight(opt.rect.height() - lineHeight );
+ }
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
+ QPalette::ColorGroup cg;
+
// Do not paint text if the edit widget is shown
if (!editWidgetIsVisible) {
if(view && (index.column() == (int)eLedgerModel::Column::Detail)) {
@@ -418,29 +531,27 @@ void LedgerDelegate::paint(QPainter* painter, const \
QStyleOptionViewItem& option opt.state &= ~QStyle::State_Enabled;
}
- QPalette::ColorGroup cg = (opt.state & QStyle::State_Enabled)
- ? QPalette::Normal : QPalette::Disabled;
+ cg = (opt.state & QStyle::State_Enabled) ? QPalette::Normal : \
QPalette::Disabled;
if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active)) {
cg = QPalette::Inactive;
}
- if (opt.state & QStyle::State_Selected) {
+ if (selected) {
// always use the normal palette since the background is also in normal
painter->setPen(opt.palette.color(QPalette::ColorGroup(QPalette::Normal), \
QPalette::HighlightedText)); +
+ } else if (erroneous) {
+ painter->setPen(m_erroneousColor);
+
} else {
painter->setPen(opt.palette.color(cg, QPalette::Text));
}
+
if (opt.state & QStyle::State_Editing) {
painter->setPen(opt.palette.color(cg, QPalette::Text));
painter->drawRect(textArea.adjusted(0, 0, -1, -1));
}
- // Don't play with the color if it's selected
- // otherwise switch the color if the transaction has errors
- if(erroneous && !selected) {
- painter->setPen(m_erroneousColor);
- }
-
// collect data for the various columns
if(index.column() == (int)eLedgerModel::Column::Detail) {
for(int i = 0; i < lines.count(); ++i) {
@@ -460,8 +571,7 @@ void LedgerDelegate::paint(QPainter* painter, const \
QStyleOptionViewItem& option o.state |= QStyle::State_KeyboardFocusChange;
o.state |= QStyle::State_Item;
- QPalette::ColorGroup cg = (opt.state & QStyle::State_Enabled)
- ? QPalette::Normal : QPalette::Disabled;
+ cg = (opt.state & QStyle::State_Enabled) ? QPalette::Normal : \
QPalette::Disabled;
o.backgroundColor = opt.palette.color(cg, (opt.state & QStyle::State_Selected)
? QPalette::Highlight : \
QPalette::Window);
style->proxy()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter, \
opt.widget); @@ -477,10 +587,40 @@ void LedgerDelegate::paint(QPainter* painter, \
const QStyleOptionViewItem& option }
// draw a separator if any
+ if (rowHasOnlineBalance) {
+ opt.rect.setY(opt.rect.y() + opt.rect.height());
+ opt.rect.setHeight(lineHeight);
+ d->m_onlineBalanceSeparator->adjustBackgroundScheme(opt.palette, index);
+ opt.backgroundBrush = opt.palette.base();
+
+ // never draw it as selected but always enabled
+ opt.state &= ~QStyle::State_Selected;
+ style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
+
+ // when the editor is shown, the row has only a single column
+ // so we need to paint the seperator if we get here in this casee
+ bool needPaint = editWidgetIsVisible;
+
+ if(!needPaint && (index.column() == (int)eLedgerModel::Column::Detail)) {
+ needPaint = true;
+ // adjust the rect to cover all columns
+ if(view && view->viewport()) {
+ opt.rect.setX(0);
+ opt.rect.setWidth(view->viewport()->width());
+ }
+ }
+
+ if(needPaint) {
+ painter->setPen(opt.palette.color(QPalette::Normal, QPalette::Text));
+ painter->drawText(opt.rect, Qt::AlignCenter, \
d->m_onlineBalanceSeparator->separatorText(index)); + }
+ }
+
if (rowHasSeperator) {
opt.rect.setY(opt.rect.y() + opt.rect.height());
- opt.rect.setHeight(lineHeight + margin);
- opt.backgroundBrush = m_separatorColor;
+ opt.rect.setHeight(lineHeight);
+ d->m_separator->adjustBackgroundScheme(opt.palette, index);
+ opt.backgroundBrush = opt.palette.base();
// never draw it as selected but always enabled
opt.state &= ~QStyle::State_Selected;
@@ -500,8 +640,7 @@ void LedgerDelegate::paint(QPainter* painter, const \
QStyleOptionViewItem& option }
if(needPaint) {
- QPalette::ColorGroup cg = QPalette::Normal;
- painter->setPen(opt.palette.color(cg, QPalette::Text));
+ painter->setPen(opt.palette.foreground().color());
painter->drawText(opt.rect, Qt::AlignCenter, \
d->m_separator->separatorText(index)); }
}
@@ -542,6 +681,10 @@ QSize LedgerDelegate::sizeHint(const QStyleOptionViewItem& \
option, const QModelI // don't draw over the separator space
size += QSize(0, lineHeight + margin);
}
+ if(d->displayOnlineBalanceSeparator(index)) {
+ // don't draw over the separator space
+ size += QSize(0, lineHeight + margin);
+ }
return size;
}
}
@@ -568,6 +711,9 @@ QSize LedgerDelegate::sizeHint(const QStyleOptionViewItem& \
option, const QModelI if (d->m_separator && d->m_separator->rowHasSeperator(index)) \
{ size.setHeight(size.height() + lineHeight + margin);
}
+ if (d->m_onlineBalanceSeparator && \
d->m_onlineBalanceSeparator->rowHasSeperator(index)) { + \
size.setHeight(size.height() + lineHeight + margin); + }
return size;
}
@@ -593,6 +739,10 @@ void LedgerDelegate::updateEditorGeometry(QWidget* editor, const \
QStyleOptionVie // consider the separator space
r.setHeight(r.height() - lineHeight - margin);
}
+ if(d->displayOnlineBalanceSeparator(index)) {
+ // consider the separator space
+ r.setHeight(r.height() - lineHeight - margin);
+ }
editor->setGeometry(r);
editor->update();
}
diff --git a/kmymoney/views/ledgerdelegate.h b/kmymoney/views/ledgerdelegate.h
index 66f93872..de088824 100644
--- a/kmymoney/views/ledgerdelegate.h
+++ b/kmymoney/views/ledgerdelegate.h
@@ -22,6 +22,7 @@
// QT Includes
#include <QStyledItemDelegate>
+class QColor;
// ----------------------------------------------------------------------------
// KDE Includes
@@ -33,6 +34,7 @@
#include "modelenums.h"
class LedgerView;
+class MyMoneyMoney;
class LedgerSeperator
{
@@ -43,6 +45,8 @@ public:
virtual bool rowHasSeperator(const QModelIndex& index) const = 0;
virtual QString separatorText(const QModelIndex& index) const = 0;
+ virtual void adjustBackgroundScheme(QPalette& palette, const QModelIndex& index) \
const = 0; +
static void setFirstFiscalDate(int firstMonth, int firstDay);
static void setShowFiscalDate(bool show) { showFiscalDate = show; }
static void setShowFancyDate(bool show) { showFancyDate = show; }
@@ -82,6 +86,8 @@ public:
*/
virtual int editorRow() const;
+ void setOnlineBalance(const QDate& date, const MyMoneyMoney& amount, int fraction \
= 0); +
static void setErroneousColor(const QColor& color);
static void setImportedColor(const QColor& color);
diff --git a/kmymoney/views/ledgerview.cpp b/kmymoney/views/ledgerview.cpp
index c724fee6..825e745c 100644
--- a/kmymoney/views/ledgerview.cpp
+++ b/kmymoney/views/ledgerview.cpp
@@ -23,6 +23,7 @@
#include <QHeaderView>
#include <QPainter>
#include <QResizeEvent>
+#include <QDate>
// ----------------------------------------------------------------------------
// KDE Includes
@@ -37,6 +38,7 @@
#include "mymoneymoney.h"
#include "mymoneyfile.h"
#include "mymoneyaccount.h"
+#include "accountsmodel.h"
class LedgerView::Private
{
@@ -175,6 +177,14 @@ void LedgerView::setAccount(const MyMoneyAccount& acc)
d->filterModel->setAccountType(acc.accountType());
d->setSortRole(eLedgerModel::Role::PostDate, (int)eLedgerModel::Column::Date);
+ if (acc.hasOnlineMapping()) {
+ connect(Models::instance()->accountsModel(), &AccountsModel::dataChanged, this, \
&LedgerView::accountChanged); + accountChanged();
+ } else {
+ disconnect(Models::instance()->accountsModel(), &AccountsModel::dataChanged, \
this, &LedgerView::accountChanged); + d->delegate->setOnlineBalance(QDate(), \
MyMoneyMoney()); + }
+
// if balance calculation has not been triggered, then run it immediately
if(!d->balanceCalculationPending) {
recalculateBalances();
@@ -205,6 +215,24 @@ QString LedgerView::accountId() const
return id;
}
+void LedgerView::accountChanged()
+{
+ QString id = accountId();
+ if(!id.isEmpty()) {
+ d->account = MyMoneyFile::instance()->account(id);
+ QDate onlineBalanceDate = \
QDate::fromString(d->account.value(QLatin1String("lastImportedTransactionDate")), \
Qt::ISODate); + MyMoneyMoney \
amount(d->account.value(QLatin1String("lastStatementBalance"))); + if \
(d->showValuesInverted) { + amount = -amount;
+ }
+ d->delegate->setOnlineBalance(onlineBalanceDate, amount, d->account.fraction());
+ } else {
+ d->delegate->setOnlineBalance(QDate(), MyMoneyMoney());
+ }
+ // force redraw
+ d->filterModel->invalidate();
+}
+
void LedgerView::recalculateBalances()
{
d->recalculateBalances();
diff --git a/kmymoney/views/ledgerview.h b/kmymoney/views/ledgerview.h
index 6cffcecd..3e1c9fba 100644
--- a/kmymoney/views/ledgerview.h
+++ b/kmymoney/views/ledgerview.h
@@ -87,6 +87,8 @@ protected Q_SLOTS:
virtual void recalculateBalances();
+ virtual void accountChanged();
+
Q_SIGNALS:
void transactionSelected(const QString& transactionSplitId);
void aboutToStartEdit();
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic