File indexing completed on 2024-05-12 05:07:49

0001 /*
0002     SPDX-FileCopyrightText: 2015-2019 Thomas Baumgart <tbaumgart@kde.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "onlinebalancedelegate.h"
0007 
0008 // ----------------------------------------------------------------------------
0009 // QT Includes
0010 
0011 #include <QApplication>
0012 #include <QScrollBar>
0013 #include <QPainter>
0014 #include <QDebug>
0015 #include <QDate>
0016 #include <QSortFilterProxyModel>
0017 
0018 // ----------------------------------------------------------------------------
0019 // KDE Includes
0020 
0021 #include <KLocalizedString>
0022 #include <KColorScheme>
0023 
0024 // ----------------------------------------------------------------------------
0025 // Project Includes
0026 
0027 #include "mymoneyfile.h"
0028 #include "mymoneyutils.h"
0029 #include "ledgerview.h"
0030 #include "journalmodel.h"
0031 #include "payeesmodel.h"
0032 #include "newtransactioneditor.h"
0033 
0034 QColor OnlineBalanceDelegate::m_erroneousColor = QColor(Qt::red);
0035 QColor OnlineBalanceDelegate::m_importedColor = QColor(Qt::yellow);
0036 QColor OnlineBalanceDelegate::m_separatorColor = QColor(0xff, 0xf2, 0x9b);
0037 
0038 
0039 
0040 
0041 class OnlineBalanceDelegate::Private
0042 {
0043 public:
0044     Private()
0045         : m_editor(nullptr)
0046         , m_view(nullptr)
0047         , m_editorRow(-1)
0048         , m_singleLineRole(eMyMoney::Model::SplitPayeeRole)
0049         , m_lineHeight(12)
0050         , m_margin(2)
0051 
0052     {}
0053 
0054     ~Private()
0055     {
0056     }
0057 
0058     QStringList displayString(const QModelIndex& index, const QStyleOptionViewItem& opt)
0059     {
0060         QStringList lines;
0061         if(index.column() == JournalModel::Column::Detail) {
0062             lines << index.data(m_singleLineRole).toString();
0063             if(opt.state & QStyle::State_Selected) {
0064                 lines.clear();
0065                 lines << index.data(eMyMoney::Model::Roles::SplitPayeeRole).toString();
0066                 lines << index.data(eMyMoney::Model::Roles::TransactionCounterAccountRole).toString();
0067                 lines << index.data(eMyMoney::Model::Roles::SplitSingleLineMemoRole).toString();
0068 
0069             } else {
0070                 if(lines.at(0).isEmpty()) {
0071                     lines.clear();
0072                     lines << index.data(eMyMoney::Model::Roles::SplitSingleLineMemoRole).toString();
0073                 }
0074                 if(lines.at(0).isEmpty()) {
0075                     lines << index.data(eMyMoney::Model::Roles::TransactionCounterAccountRole).toString();
0076                 }
0077             }
0078             lines.removeAll(QString());
0079 
0080         } else {
0081             lines << opt.text;
0082         }
0083         return lines;
0084     }
0085 
0086     NewTransactionEditor*         m_editor;
0087     LedgerView*                   m_view;
0088     int                           m_editorRow;
0089     eMyMoney::Model::Roles        m_singleLineRole;
0090     int                           m_lineHeight;
0091     int                           m_margin;
0092     QBrush                        m_backGround;
0093 };
0094 
0095 
0096 OnlineBalanceDelegate::OnlineBalanceDelegate(LedgerView* parent)
0097     : KMMStyledItemDelegate(parent)
0098     , d(new Private)
0099 {
0100     d->m_view = parent;
0101 }
0102 
0103 OnlineBalanceDelegate::~OnlineBalanceDelegate()
0104 {
0105     delete d;
0106 }
0107 
0108 void OnlineBalanceDelegate::setErroneousColor(const QColor& color)
0109 {
0110     m_erroneousColor = color;
0111 }
0112 
0113 void OnlineBalanceDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
0114 {
0115     QStyleOptionViewItem opt = option;
0116     initStyleOption(&opt, index);
0117 
0118     // never change the background of the cell the mouse is hovering over
0119     opt.state &= ~QStyle::State_MouseOver;
0120 
0121     // never show the focus
0122     opt.state &= ~QStyle::State_HasFocus;
0123 
0124     // if selected, always show as active, so that the
0125     // background does not change when the editor is shown
0126     if (opt.state & QStyle::State_Selected) {
0127         opt.state |= QStyle::State_Active;
0128     }
0129     // never draw it as selected but always enabled
0130     opt.state &= ~QStyle::State_Selected;
0131     opt.state |= QStyle::State_Enabled;
0132 
0133     painter->save();
0134 
0135     QAbstractItemView* view = qobject_cast< QAbstractItemView* >(parent());
0136 
0137     // Background
0138     QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
0139     const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin);
0140 
0141     const QRect textArea = QRect(opt.rect.x() + margin, opt.rect.y() + margin, opt.rect.width() - 2 * margin, opt.rect.height() - 2 * margin);
0142 
0143     QString onlineBalanceValueTxt(i18nc("text for online balance value if not available", "n/a"));
0144     QString onlineBalanceDateTxt(i18nc("text for online balance date if not available", "n/a"));
0145     const auto onlineBalanceDate = index.data(eMyMoney::Model::AccountOnlineBalanceDateRole).toDate();
0146     if (onlineBalanceDate.isValid()) {
0147         onlineBalanceDateTxt = MyMoneyUtils::formatDate(onlineBalanceDate);
0148     }
0149     const auto onlineBalanceValue = index.data(eMyMoney::Model::AccountOnlineBalanceValueRole).value<MyMoneyMoney>();
0150     const auto accountId(index.data(eMyMoney::Model::IdRole).toString());
0151     auto accountBalance(onlineBalanceValue);
0152     if (!accountId.isEmpty()) {
0153         accountBalance = MyMoneyFile::instance()->balance(accountId, onlineBalanceDate);
0154         onlineBalanceValueTxt = onlineBalanceValue.formatMoney(index.data(eMyMoney::Model::AccountFractionRole).toInt());
0155     }
0156 
0157     KColorScheme::BackgroundRole role = (accountBalance == onlineBalanceValue) ? KColorScheme::PositiveBackground : KColorScheme::NegativeBackground;
0158 
0159     KColorScheme::adjustBackground(opt.palette, role, QPalette::Base, KColorScheme::View, KSharedConfigPtr());
0160     // opt.rect.setHeight(lineHeight);
0161     opt.backgroundBrush = opt.palette.base();
0162     d->m_backGround = opt.backgroundBrush;
0163 
0164     opt.rect.setX(opt.rect.x()-2);
0165     opt.rect.setWidth(opt.rect.width()+5);
0166     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
0167 
0168     switch (index.column()) {
0169     case JournalModel::Column::Detail:
0170         // adjust the rect to cover all columns
0171         if(view && view->viewport()) {
0172             opt.rect.setX(0);
0173             opt.rect.setWidth(view->viewport()->width());
0174         }
0175         painter->setPen(opt.palette.color(QPalette::Normal, QPalette::Text));
0176         painter->drawText(opt.rect, Qt::AlignCenter, i18nc("Label in ledger for online balance row", "Online Balance"));
0177         break;
0178     case JournalModel::Column::Date:
0179         painter->setPen(opt.palette.color(QPalette::Normal, QPalette::Text));
0180         painter->drawText(textArea, opt.displayAlignment, onlineBalanceDateTxt);
0181         break;
0182     case JournalModel::Column::Balance:
0183         painter->setPen(opt.palette.color(QPalette::Normal, QPalette::Text));
0184         painter->drawText(textArea, opt.displayAlignment, onlineBalanceValueTxt);
0185         break;
0186     }
0187 
0188     painter->restore();
0189 }
0190 
0191 QSize OnlineBalanceDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
0192 {
0193     QStyleOptionViewItem opt = option;
0194     initStyleOption(&opt, index);
0195     QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
0196     d->m_margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin);
0197     d->m_lineHeight = opt.fontMetrics.lineSpacing();
0198 
0199     QSize size(10, d->m_lineHeight + 2 * d->m_margin);
0200 
0201     return size;
0202 }
0203 
0204 /**
0205  * This eventfilter seems to do nothing but it prevents that selecting a
0206  * different row with the mouse closes the editor
0207  */
0208 bool OnlineBalanceDelegate::eventFilter(QObject* o, QEvent* event)
0209 {
0210     return QAbstractItemDelegate::eventFilter(o, event);
0211 }