File indexing completed on 2024-05-12 05:07:54
0001 /* 0002 SPDX-FileCopyrightText: 2008-2018 Thomas Baumgart <tbaumgart@kde.org> 0003 SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kaccounttemplateselector.h" 0008 0009 // ---------------------------------------------------------------------------- 0010 // QT Includes 0011 0012 #include <QDomElement> 0013 #include <QTreeView> 0014 0015 // ---------------------------------------------------------------------------- 0016 // KDE Includes 0017 0018 #include <KTextEdit> 0019 0020 // ---------------------------------------------------------------------------- 0021 // Project Includes 0022 0023 #include "ui_kaccounttemplateselector.h" 0024 0025 #include <mymoneytemplate.h> 0026 #include <templatesmodel.h> 0027 #include <mymoneyaccount.h> 0028 0029 class KAccountTemplateSelectorPrivate : public QObject 0030 { 0031 Q_DISABLE_COPY(KAccountTemplateSelectorPrivate) 0032 0033 public: 0034 Ui::KAccountTemplateSelector* ui; 0035 TemplatesModel* model; 0036 QMap<QString, QTreeWidgetItem*> templateHierarchy; 0037 0038 public: 0039 KAccountTemplateSelectorPrivate(QObject* parent) 0040 : QObject(parent) 0041 , ui(new Ui::KAccountTemplateSelector) 0042 , model(nullptr) 0043 { 0044 } 0045 0046 ~KAccountTemplateSelectorPrivate() 0047 { 0048 delete ui; 0049 } 0050 0051 0052 QTreeWidgetItem* hierarchyItem(const QString& parent, const QString& name) 0053 { 0054 if (!templateHierarchy.contains(parent) 0055 || templateHierarchy[parent] == 0) { 0056 static const QRegularExpression hierarchyExp(QLatin1String("(.*):(.*)")); 0057 const auto hierarchyParts(hierarchyExp.match(parent)); 0058 if (hierarchyParts.hasMatch()) 0059 templateHierarchy[parent] = hierarchyItem(hierarchyParts.captured(1), hierarchyParts.captured(2)); 0060 } 0061 QTreeWidgetItem *item = new QTreeWidgetItem(templateHierarchy[parent]); 0062 item->setText(0, name); 0063 return item; 0064 } 0065 0066 bool hierarchy(QMap<QString, QTreeWidgetItem*>& list, const QString& parent, QDomNode account) 0067 { 0068 bool rc = true; 0069 while (rc == true && !account.isNull()) { 0070 if (account.isElement()) { 0071 QDomElement accountElement = account.toElement(); 0072 if (accountElement.tagName() == QLatin1String("account")) { 0073 QString name = QString("%1:%2").arg(parent, accountElement.attribute("name")); 0074 list[name] = 0; 0075 hierarchy(list, name, account.firstChild()); 0076 } 0077 } 0078 account = account.nextSibling(); 0079 } 0080 return rc; 0081 } 0082 0083 void hierarchy(QDomNode accounts, QMap<QString, QTreeWidgetItem*>& list) 0084 { 0085 bool rc = !accounts.isNull(); 0086 while (rc == true && !accounts.isNull() && accounts.isElement()) { 0087 QDomElement rootNode = accounts.toElement(); 0088 QString name = rootNode.attribute(QLatin1String("name")); 0089 if (rootNode.tagName() == QLatin1String("account")) { 0090 rootNode = rootNode.firstChild().toElement(); 0091 eMyMoney::Account::Type type = static_cast<eMyMoney::Account::Type>(accounts.toElement().attribute(QLatin1String("type")).toUInt()); 0092 switch (type) { 0093 case eMyMoney::Account::Type::Asset: 0094 case eMyMoney::Account::Type::Liability: 0095 case eMyMoney::Account::Type::Income: 0096 case eMyMoney::Account::Type::Expense: 0097 case eMyMoney::Account::Type::Equity: 0098 if (name.isEmpty()) 0099 name = MyMoneyAccount::accountTypeToString(type); 0100 list[name] = 0; 0101 rc = hierarchy(list, name, rootNode); 0102 break; 0103 0104 default: 0105 rc = false; 0106 break; 0107 } 0108 } else { 0109 rc = false; 0110 } 0111 accounts = accounts.nextSibling(); 0112 } 0113 } 0114 0115 void loadHierarchy() 0116 { 0117 if (model == nullptr) { 0118 return; 0119 } 0120 templateHierarchy.clear(); 0121 const auto selection = ui->m_groupList->selectionModel()->selectedIndexes(); 0122 for (const auto& idx : qAsConst(selection)) { 0123 const auto tmpl = model->itemByIndex(idx); 0124 hierarchy(tmpl.accountTree(), templateHierarchy); 0125 } 0126 0127 // I need to think about this some more. The code works and shows 0128 // the current account hierarchy. It might be useful, to show 0129 // existing accounts dimmed and the new ones in bold or so. 0130 #if 0 0131 // add the hierarchy from the MyMoneyFile object 0132 QList<MyMoneyAccount> aList; 0133 QList<MyMoneyAccount>::const_iterator it_a; 0134 auto file = MyMoneyFile::instance(); 0135 file->accountList(aList); 0136 if (aList.count() > 0) { 0137 templateHierarchy[file->accountToCategory(file->asset().id(), true)] = 0; 0138 templateHierarchy[file->accountToCategory(file->liability().id(), true)] = 0; 0139 templateHierarchy[file->accountToCategory(file->income().id(), true)] = 0; 0140 templateHierarchy[file->accountToCategory(file->expense().id(), true)] = 0; 0141 templateHierarchy[file->accountToCategory(file->equity().id(), true)] = 0; 0142 } 0143 0144 for (it_a = aList.begin(); it_a != aList.end(); ++it_a) { 0145 templateHierarchy[file->accountToCategory((*it_a).id(), true)] = 0; 0146 } 0147 #endif 0148 0149 ui->m_accountList->clear(); 0150 0151 static const QRegularExpression hierarchyExp(QLatin1String("(.*):(.*)")); 0152 for (QMap<QString, QTreeWidgetItem*>::iterator it_h = templateHierarchy.begin(); it_h != templateHierarchy.end(); ++it_h) { 0153 const auto hierarchyParts(hierarchyExp.match(it_h.key())); 0154 if (!hierarchyParts.hasMatch()) { 0155 (*it_h) = new QTreeWidgetItem(ui->m_accountList); 0156 (*it_h)->setText(0, it_h.key()); 0157 } else { 0158 (*it_h) = hierarchyItem(hierarchyParts.captured(1), hierarchyParts.captured(2)); 0159 } 0160 (*it_h)->setExpanded(true); 0161 } 0162 0163 ui->m_description->clear(); 0164 const auto idx = ui->m_groupList->currentIndex(); 0165 if (idx.isValid()) { 0166 const auto desc = idx.data(eMyMoney::Model::TemplatesLongDescriptionRole).toString(); 0167 ui->m_description->setText(desc); 0168 } 0169 } 0170 }; 0171 0172 KAccountTemplateSelector::KAccountTemplateSelector(QWidget* parent) 0173 : QWidget(parent) 0174 , d_ptr(new KAccountTemplateSelectorPrivate(this)) 0175 { 0176 Q_D(KAccountTemplateSelector); 0177 d->ui->setupUi(this); 0178 d->ui->m_accountList->header()->hide(); 0179 d->ui->m_groupList->setSelectionMode(QAbstractItemView::ExtendedSelection); 0180 d->ui->m_groupList->setFocus(); 0181 } 0182 0183 KAccountTemplateSelector::~KAccountTemplateSelector() 0184 { 0185 Q_D(KAccountTemplateSelector); 0186 delete d; 0187 } 0188 0189 void KAccountTemplateSelector::setModel(TemplatesModel* model) 0190 { 0191 Q_D(KAccountTemplateSelector); 0192 d->model = model; 0193 d->ui->m_groupList->setModel(model); 0194 connect(d->ui->m_groupList->selectionModel(), 0195 &QItemSelectionModel::selectionChanged, 0196 d, 0197 &KAccountTemplateSelectorPrivate::loadHierarchy, 0198 Qt::UniqueConnection); 0199 } 0200 0201 QList<MyMoneyTemplate> KAccountTemplateSelector::selectedTemplates() const 0202 { 0203 Q_D(const KAccountTemplateSelector); 0204 QList<MyMoneyTemplate> list; 0205 if (d->model != nullptr) { 0206 const auto selection = d->ui->m_groupList->selectionModel()->selectedIndexes(); 0207 for (const auto& idx : qAsConst(selection)) { 0208 list << d->model->itemByIndex(idx); 0209 } 0210 } 0211 return list; 0212 } 0213 0214 void KAccountTemplateSelector::setupInitialSelection() 0215 { 0216 Q_D(KAccountTemplateSelector); 0217 const auto defaultCountry = QLocale().country(); 0218 0219 const auto rows = d->model->rowCount(); 0220 for (int row = 0; row < rows; ++row) { 0221 auto idx = d->model->index(row, 0); 0222 const auto locale = idx.data(eMyMoney::Model::TemplatesLocaleRole).toString(); 0223 0224 if (QLocale(locale).country() == defaultCountry) { 0225 d->ui->m_groupList->collapseAll(); 0226 d->ui->m_groupList->setExpanded(idx, true); 0227 d->ui->m_groupList->scrollTo(idx, QAbstractItemView::PositionAtTop); 0228 d->ui->m_groupList->setCurrentIndex(idx); 0229 d->ui->m_groupList->resizeColumnToContents(0); 0230 break; 0231 } 0232 } 0233 }