Git commit 1c7cf75c4dcd1699582ca67ee2baa72fe81a23c8 by Thomas Baumgart. Committed on 24/01/2021 at 09:03. Pushed by tbaumgart into branch 'master'.
Improve CSV importer - add credit/debit indicator column - add balance column - simplify code - add new column selections to UI GUI: M +210 -198 kmymoney/plugins/csv/import/bankingwizardpage.cpp M +10 -13 kmymoney/plugins/csv/import/bankingwizardpage.h M +676 -398 kmymoney/plugins/csv/import/bankingwizardpage.ui M +5 -4 kmymoney/plugins/csv/import/core/csvenums.h M +67 -5 kmymoney/plugins/csv/import/core/csvimportercore.cpp M +5 -1 kmymoney/plugins/csv/import/core/csvimportercore.h M +3 -5 kmymoney/plugins/csv/import/csvwizard.cpp https://invent.kde.org/office/kmymoney/commit/1c7cf75c4dcd1699582ca67ee2baa72fe81a23c8 diff --git a/kmymoney/plugins/csv/import/bankingwizardpage.cpp b/kmymoney/plugins/csv/import/bankingwizardpage.cpp index 3aaec851b..07541a937 100644 --- a/kmymoney/plugins/csv/import/bankingwizardpage.cpp +++ b/kmymoney/plugins/csv/import/bankingwizardpage.cpp @@ -1,6 +1,7 @@ /* * Copyright 2011-2017 Allan Anderson <[email protected]> * Copyright 2016-2018 Łukasz Wojniłowicz <[email protected]> + * Copyright 2020 Thomas Baumgart <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,6 +25,7 @@ #include <QFile> #include <QStandardItemModel> #include <QTextStream> +#include <QDebug> // ---------------------------------------------------------------------------- // KDE Includes @@ -35,11 +37,14 @@ #include "csvwizard.h" #include "core/csvimportercore.h" - +#include "icons.h" #include "ui_bankingwizardpage.h" // ---------------------------------------------------------------------------- +#define connectClearButton(col) \ + connect(ui->col ## Clear, &QToolButton::clicked, this, [&]() { clearComboBox(ui->col ); } ); + BankingPage::BankingPage(CSVWizard *dlg, CSVImporterCore *imp) : CSVWizardPage(dlg, imp) , m_profile(nullptr) @@ -47,32 +52,83 @@ BankingPage::BankingPage(CSVWizard *dlg, CSVImporterCore *imp) { ui->setupUi(this); + m_columnBoxes = QHash<Column, QComboBox*> { + {Column::Amount, ui->m_amountCol}, + {Column::Debit, ui->m_debitCol}, + {Column::Credit, ui->m_creditCol}, + {Column::Memo, ui->m_memoCol}, + {Column::Number, ui->m_numberCol}, + {Column::Date, ui->m_dateCol}, + {Column::Payee, ui->m_payeeCol}, + {Column::Category, ui->m_categoryCol}, + {Column::CreditDebitIndicator, ui->m_creditDebitIndicatorCol}, + {Column::Balance, ui->m_balanceCol} + }; + + auto clearComboBox = [&](QComboBox* combobox) { combobox->setCurrentIndex(-1); }; + connect(ui->m_clear, &QAbstractButton::clicked, this, &BankingPage::clearColumns); - connect(ui->m_radioAmount, &QAbstractButton::toggled, this, &BankingPage::amountToggled); - connect(ui->m_radioDebitCredit, &QAbstractButton::toggled, this, &BankingPage::debitCreditToggled); - connect(ui->m_oppositeSigns, &QAbstractButton::clicked, this, &BankingPage::oppositeSignsClicked); - - // initialize column names - m_dlg->m_colTypeName.insert(Column::Payee,i18n("Payee")); - m_dlg->m_colTypeName.insert(Column::Number,i18n("Number")); - m_dlg->m_colTypeName.insert(Column::Debit,i18n("Debit")); - m_dlg->m_colTypeName.insert(Column::Credit,i18n("Credit")); - m_dlg->m_colTypeName.insert(Column::Date,i18n("Date")); - m_dlg->m_colTypeName.insert(Column::Amount,i18n("Amount")); - m_dlg->m_colTypeName.insert(Column::Category,i18n("Category")); - m_dlg->m_colTypeName.insert(Column::Memo,i18n("Memo")); + connect(ui->m_oppositeSigns, &QAbstractButton::clicked, this, [&](bool checked) { m_profile->m_oppositeSigns = checked; }); + + connect(ui->m_amountTabWidget, &QTabWidget::currentChanged, this, [&](int index) { + if (ui->m_amountTabWidget->widget(index) == ui->amountTab) { // amountTab + clearComboBox(ui->m_debitCol); + clearComboBox(ui->m_creditCol); + } else { // creditDebitTab + clearComboBox(ui->m_amountCol); + } + }); void (QComboBox::* signal)(int) = &QComboBox::currentIndexChanged; - connect(ui->m_amountCol, signal, this, &BankingPage::amountColSelected); - connect(ui->m_debitCol, signal, this, &BankingPage::debitColSelected); - connect(ui->m_creditCol, signal, this, &BankingPage::creditColSelected); + connect(ui->m_amountCol, signal, this, [&](int col) { validateSelectedColumn(col, Column::Amount); }); + connect(ui->m_debitCol, signal, this, [&](int col) { validateSelectedColumn(col, Column::Debit); }); + connect(ui->m_creditCol, signal, this, [&](int col) { validateSelectedColumn(col, Column::Credit); }); + connect(ui->m_numberCol, signal, this, [&](int col) { validateSelectedColumn(col, Column::Number); }); + connect(ui->m_dateCol, signal, this, [&](int col) { validateSelectedColumn(col, Column::Date); }); + connect(ui->m_categoryCol, signal, this, [&](int col) { validateSelectedColumn(col, Column::Category); }); + + connect(ui->m_creditIndicator, &QLineEdit::textEdited, [&](const QString& indicator) { + m_profile->m_creditIndicator = indicator; + emit completeChanged(); + }); + connect(ui->m_debitIndicator, &QLineEdit::textEdited, [&](const QString& indicator) { + m_profile->m_debitIndicator = indicator; + emit completeChanged(); + }); + connect(ui->m_memoCol, signal, this, &BankingPage::memoColSelected); - connect(ui->m_numberCol, signal, this, &BankingPage::numberColSelected); - connect(ui->m_dateCol, signal, this, &BankingPage::dateColSelected); connect(ui->m_payeeCol, signal, this, &BankingPage::payeeColSelected); - connect(ui->m_categoryCol, signal, this, &BankingPage::categoryColSelected); + connect(ui->m_creditDebitIndicatorCol, signal, this, [&](int col) { + if (validateSelectedColumn(col, Column::CreditDebitIndicator)) { + ui->m_creditIndicator->setDisabled(col == -1); + ui->m_debitIndicator->setDisabled(col == -1); + ui->m_oppositeSigns->setEnabled(col == -1); + ui->labelBnk_opposite->setEnabled(col == -1); + } + }); + + connect(ui->m_memoColClear, &QToolButton::clicked, this, &BankingPage::clearMemoColumns); + + // connect the clear buttons with the comboboxes + connectClearButton(m_numberCol); + connectClearButton(m_dateCol); + connectClearButton(m_payeeCol); + connectClearButton(m_categoryCol); + connectClearButton(m_balanceCol); + connectClearButton(m_amountCol); + connectClearButton(m_creditDebitIndicatorCol); + connectClearButton(m_debitCol); + connectClearButton(m_creditCol); + + // setup clear icon on toolbuttons + const auto toolButtons = findChildren<QToolButton*>(); + for (const auto& button : toolButtons) { + button->setIcon(Icons::get(Icons::Icon::EditClear)); + } - connect(ui->m_clearMemoColumns, &QToolButton::clicked, this, &BankingPage::clearMemoColumns); + // assume debit/credit indicator is not filled + ui->m_creditIndicator->setDisabled(true); + ui->m_debitIndicator->setDisabled(true); } BankingPage::~BankingPage() @@ -82,40 +138,56 @@ BankingPage::~BankingPage() void BankingPage::initializePage() { - QHash<Column, QComboBox *> columns {{Column::Amount, ui->m_amountCol}, {Column::Debit, ui->m_debitCol}, - {Column::Credit, ui->m_creditCol}, {Column::Memo, ui->m_memoCol}, - {Column::Number, ui->m_numberCol}, {Column::Date, ui->m_dateCol}, - {Column::Payee, ui->m_payeeCol}, {Column::Category, ui->m_categoryCol}}; - m_profile = dynamic_cast<BankingProfile *>(m_imp->m_profile); updateCurrentMemoSelection(); + // fill in column numbers into all comboboxes if (ui->m_dateCol->count() != m_imp->m_file->m_columnCount) - m_dlg->initializeComboBoxes(columns); - - columns.remove(Column::Memo); - for (auto it = columns.cbegin(); it != columns.cend(); ++it) { - auto index = m_profile->m_colTypeNum.value(it.key()); - // reset values to undefined in case out of range - if (index >= it.value()->count()) { - m_profile->m_colTypeNum[it.key()] = -1;; + m_dlg->initializeComboBoxes(m_columnBoxes); + + m_dlg->m_colTypeName.clear(); + const auto labels = findChildren<QLabel*>(); + for (auto it = m_columnBoxes.cbegin(); it != m_columnBoxes.cend(); ++it) { + // m_dlg->m_colTypeName is constructed based on the QLabel::buddy() + // setup in the UI file pointing to the combobox + for (const auto& label : labels) { + if (label->buddy() == it.value()) { + m_dlg->m_colTypeName.insert(it.key(), label->text()); + break; + } + } + if (!m_dlg->m_colTypeName.contains(it.key())) { + qWarning() << "No colTypeName in BankingPage for" << it.value()->objectName(); + } + // skip memo column, we take of it later + if (it.key() == Column::Memo) + continue; + + auto index = -1; + if (m_profile->m_colTypeNum.contains(it.key())) { + index = m_profile->m_colTypeNum.value(it.key()); + } + // reset values to undefined in case out of range or unknown + if ((index == -1) || (index >= it.value()->count())) { + m_profile->m_colTypeNum[it.key()] = -1; } it.value()->setCurrentIndex(m_profile->m_colTypeNum.value(it.key())); } ui->m_oppositeSigns->setChecked(m_profile->m_oppositeSigns); - if (m_profile->m_memoColList.count() > 0) - { - for (int i = 0; i < m_profile->m_memoColList.count(); ++i) - ui->m_memoCol->setCurrentIndex(m_profile->m_memoColList.value(i)); - } else - ui->m_memoCol->setCurrentIndex(-1); + ui->m_memoCol->setCurrentIndex(-1); + for (int i = 0; i < m_profile->m_memoColList.count(); ++i) { + ui->m_memoCol->setCurrentIndex(m_profile->m_memoColList.value(i)); + } - if (this->m_profile->m_colTypeNum.value(Column::Debit) == -1) // If amount previously selected, set check radio_amount - ui->m_radioAmount->setChecked(true); - else // ...else set check radio_debCred to clear amount col - ui->m_radioDebitCredit->setChecked(true); + if (m_profile->m_colTypeNum.value(Column::Debit) == -1) // If amount previously selected, setup tab + ui->m_amountTabWidget->setCurrentWidget(ui->amountTab); + else // ...else set credit/debit tab + ui->m_amountTabWidget->setCurrentWidget(ui->debitCreditTab); + + ui->m_creditIndicator->setText(m_profile->m_creditIndicator); + ui->m_debitIndicator->setText(m_profile->m_debitIndicator); } int BankingPage::nextId() const @@ -125,94 +197,98 @@ int BankingPage::nextId() const bool BankingPage::isComplete() const { - return ui->m_dateCol->currentIndex() > -1 && - ui->m_payeeCol->currentIndex() > -1 && - (ui->m_amountCol->currentIndex() > -1 || - (ui->m_debitCol->currentIndex() > -1 && - ui->m_creditCol->currentIndex() > -1)); + bool rc = (ui->m_dateCol->currentIndex() > -1) && + (ui->m_payeeCol->currentIndex() > -1); + + if (ui->m_amountTabWidget->currentIndex() == 0) { // amountTab selected + rc &= (ui->m_amountCol->currentIndex() > -1); + if (ui->m_creditDebitIndicatorCol->currentIndex() > -1) { + // at least one of the indicators must be filled and they both must differ + rc &= !(ui->m_debitIndicator->text().isEmpty() && ui->m_creditIndicator->text().isEmpty()); + rc &= (ui->m_debitIndicator->text() != ui->m_creditIndicator->text()); + } + } else { + // debit and credit must be filled + rc &= (ui->m_debitCol->currentIndex() > -1) && + (ui->m_creditCol->currentIndex() > -1); + } + return rc; } bool BankingPage::validateMemoComboBox() { - if (m_profile->m_memoColList.isEmpty()) - return true; - - for (int i = 0; i < ui->m_memoCol->count(); ++i) - { - const QString txt = ui->m_memoCol->itemText(i); - if (txt.contains(QLatin1Char('*'))) // check if text containing '*' belongs to valid column types - if (m_profile->m_colNumType.value(i) != Column::Payee) { - ui->m_memoCol->setItemText(i, QString::number(i + 1)); - m_profile->m_memoColList.removeOne(i); - return false; - } + if (!m_profile->m_memoColList.isEmpty()) { + for (int i = 0; i < ui->m_memoCol->count(); ++i) + { + const QString txt = ui->m_memoCol->itemText(i); + if (txt.contains(QLatin1Char('*'))) // check if text containing '*' belongs to valid column types + if (m_profile->m_colNumType.value(i) != Column::Payee) { + ui->m_memoCol->setItemText(i, QString::number(i + 1)); + m_profile->m_memoColList.removeOne(i); + return false; + } + } } return true; } void BankingPage::memoColSelected(int col) { - if (m_profile->m_colNumType.value(col) == Column::Payee ) { - int rc = KMessageBox::Yes; - if (isVisible()) - rc = KMessageBox::questionYesNo(m_dlg, i18n("<center>The '<b>%1</b>' field already has this column selected.</center>" - "<center>If you wish to copy the Payee data to the memo field, click 'Yes'.</center>", - m_dlg->m_colTypeName.value(m_profile->m_colNumType.value(col)))); - if (rc == KMessageBox::Yes) { - ui->m_memoCol->setItemText(col, QString::number(col + 1) + QLatin1Char('*')); - if (!m_profile->m_memoColList.contains(col)) - m_profile->m_memoColList.append(col); - } else { - ui->m_memoCol->setItemText(col, QString::number(col + 1)); - m_profile->m_memoColList.removeOne(col); - } - //allow only separate memo field occupy combobox - ui->m_memoCol->blockSignals(true); - if (m_profile->m_colTypeNum.value(Column::Memo) != -1) - ui->m_memoCol->setCurrentIndex(m_profile->m_colTypeNum.value(Column::Memo)); - else - ui->m_memoCol->setCurrentIndex(-1); - ui->m_memoCol->blockSignals(false); + if (col != -1) { + if (m_profile->m_colNumType.value(col) == Column::Payee ) { + int rc = KMessageBox::Yes; + if (isVisible()) + rc = KMessageBox::questionYesNo(m_dlg, i18n("<center>The '<b>%1</b>' field already has this column selected.</center>" + "<center>If you wish to copy the Payee data to the memo field, click 'Yes'.</center>", + m_dlg->m_colTypeName.value(m_profile->m_colNumType.value(col)))); + if (rc == KMessageBox::Yes) { + ui->m_memoCol->setItemText(col, QString::number(col + 1) + QLatin1Char('*')); + if (!m_profile->m_memoColList.contains(col)) + m_profile->m_memoColList.append(col); + } else { + ui->m_memoCol->setItemText(col, QString::number(col + 1)); + m_profile->m_memoColList.removeOne(col); + } + //allow only separate memo field occupy combobox + QSignalBlocker blocker(ui->m_memoCol); + if (m_profile->m_colTypeNum.value(Column::Memo) != -1) + ui->m_memoCol->setCurrentIndex(m_profile->m_colTypeNum.value(Column::Memo)); + else + ui->m_memoCol->setCurrentIndex(-1); - } else { - if (m_profile->m_colTypeNum.value(Column::Memo) != -1) // check if this memo has any column 'number' assigned... - m_profile->m_memoColList.removeOne(col); // ...if true remove it from memo list + } else { + if (m_profile->m_colTypeNum.value(Column::Memo) != -1) // check if this memo has any column 'number' assigned... + m_profile->m_memoColList.removeOne(col); // ...if true remove it from memo list - if(validateSelectedColumn(col, Column::Memo)) { - if (col != - 1 && !m_profile->m_memoColList.contains(col)) { - m_profile->m_memoColList.append(col); - std::sort(m_profile->m_memoColList.begin(), m_profile->m_memoColList.end()); + if(validateSelectedColumn(col, Column::Memo)) { + if (!m_profile->m_memoColList.contains(col)) { + m_profile->m_memoColList.append(col); + std::sort(m_profile->m_memoColList.begin(), m_profile->m_memoColList.end()); + } } } + updateCurrentMemoSelection(); + // always clear the col in the combo box after it is added to the list + ui->m_memoCol->setCurrentIndex(-1); + } - updateCurrentMemoSelection(); } void BankingPage::updateCurrentMemoSelection() { const auto& list = m_profile->m_memoColList; const bool haveSelection = !list.isEmpty(); - QString txt; + QString txt = i18nc("@item:intext No field selection", "None"); if (haveSelection) { + txt.clear(); for (const auto& entry : list) { txt += QString("%1, ").arg(entry+1); } txt = txt.left(txt.length()-2); } - ui->m_currentMemoColums->setText(QString("%1").arg(txt, -30, QChar(' '))); + ui->m_currentMemoColumns->setText(i18nc("@label:listbox list of currently selected fields", "<i>Memo columns:</i> %1").arg(txt)); - ui->m_clearMemoColumns->setEnabled(haveSelection); -} - - -void BankingPage::categoryColSelected(int col) -{ - validateSelectedColumn(col, Column::Category); -} - -void BankingPage::numberColSelected(int col) -{ - validateSelectedColumn(col, Column::Number); + ui->m_memoColClear->setEnabled(haveSelection); } void BankingPage::payeeColSelected(int col) @@ -222,108 +298,39 @@ void BankingPage::payeeColSelected(int col) memoColSelected(col); // ...if true set memo field again } -void BankingPage::dateColSelected(int col) -{ - validateSelectedColumn(col, Column::Date); -} - -void BankingPage::debitColSelected(int col) -{ - validateSelectedColumn(col, Column::Debit); -} - -void BankingPage::creditColSelected(int col) -{ - validateSelectedColumn(col, Column::Credit); -} - -void BankingPage::amountColSelected(int col) -{ - validateSelectedColumn(col, Column::Amount); -} - -void BankingPage::amountToggled(bool checked) -{ - if (checked) { - ui->m_amountCol->setEnabled(true); // disable credit & debit ui choices - ui->labelBnk_amount->setEnabled(true); - ui->labelBnk_credits->setEnabled(false); - ui->labelBnk_debits->setEnabled(false); - - ui->m_debitCol->setEnabled(false); - ui->m_debitCol->setCurrentIndex(-1); - ui->m_creditCol->setEnabled(false); - ui->m_creditCol->setCurrentIndex(-1); - } -} - -void BankingPage::debitCreditToggled(bool checked) -{ - if (checked) { - ui->m_debitCol->setEnabled(true); // if 'debit/credit' selected - ui->labelBnk_debits->setEnabled(true); - ui->m_creditCol->setEnabled(true); - ui->labelBnk_credits->setEnabled(true); - - ui->m_amountCol->setEnabled(false); // disable 'amount' ui choices - ui->m_amountCol->setCurrentIndex(-1); // as credit/debit chosen - ui->labelBnk_amount->setEnabled(false); - } -} - -void BankingPage::oppositeSignsClicked(bool checked) -{ - m_profile->m_oppositeSigns = checked; -} - void BankingPage::clearColumns() { - ui->m_dateCol->setCurrentIndex(-1); - ui->m_payeeCol->setCurrentIndex(-1); - ui->m_numberCol->setCurrentIndex(-1); - ui->m_amountCol->setCurrentIndex(-1); - ui->m_debitCol->setCurrentIndex(-1); - ui->m_creditCol->setCurrentIndex(-1); - ui->m_categoryCol->setCurrentIndex(-1); + for (const auto& comboBox : m_columnBoxes) { + comboBox->setCurrentIndex(-1); + } + ui->m_creditIndicator->clear(); + ui->m_debitIndicator->clear(); clearMemoColumns(); } void BankingPage::clearMemoColumns() { + m_profile->m_colTypeNum[Column::Memo] = -1; + + for (auto it = m_profile->m_colNumType.begin(); it != m_profile->m_colNumType.end(); /* no inc here */) { + if (it.value() == Column::Memo) { + it = m_profile->m_colNumType.erase(it); + } else { + ++it; + } + } m_profile->m_memoColList.clear(); - ui->m_memoCol->setCurrentIndex(-1); + + updateCurrentMemoSelection(); } -void BankingPage::resetComboBox(const Column comboBox) +void BankingPage::resetComboBox(Column comboBox, int index) { - switch (comboBox) { - case Column::Amount: - ui->m_amountCol->setCurrentIndex(-1); - break; - case Column::Credit: - ui->m_creditCol->setCurrentIndex(-1); - break; - case Column::Date: - ui->m_dateCol->setCurrentIndex(-1); - break; - case Column::Debit: - ui->m_debitCol->setCurrentIndex(-1); - break; - case Column::Memo: - ui->m_memoCol->setCurrentIndex(-1); - break; - case Column::Number: - ui->m_numberCol->setCurrentIndex(-1); - break; - case Column::Payee: - ui->m_payeeCol->setCurrentIndex(-1); - break; - case Column::Category: - ui->m_categoryCol->setCurrentIndex(-1); - break; - default: + if (m_columnBoxes.contains(comboBox)) { + m_columnBoxes.value(comboBox)->setCurrentIndex(index); + } else { KMessageBox::sorry(m_dlg, i18n("<center>Field name not recognised.</center> <center>'<b>%1</b>'</center> Please re-enter your column selections." - , (int)comboBox), i18n("CSV import")); + , static_cast<int>(comboBox)), i18n("CSV import")); } } @@ -334,13 +341,18 @@ bool BankingPage::validateSelectedColumn(const int col, const Column type) bool ret = true; if (col == -1) { // user only wanted to reset his column so allow him + m_profile->m_colNumType.remove(m_profile->m_colTypeNum[type]); m_profile->m_colTypeNum[type] = col; // assign new column 'number' to this 'type' + + } else if (col == m_profile->m_colTypeNum[type]) { + // nothing to do since it is the same value + } else if (m_profile->m_colNumType.contains(col)) { // if this column 'number' has already 'type' assigned - KMessageBox::information(m_dlg, i18n("The '<b>%1</b>' field already has this column selected. <center>Please reselect both entries as necessary.</center>", - m_dlg->m_colTypeName.value(m_profile->m_colNumType.value(col)))); - resetComboBox(m_profile->m_colNumType.value(col)); - resetComboBox(type); + KMessageBox::information(m_dlg, i18n("Column <b>%1</b> cannot be selected because it is already used in '<b>%2</b>'.", + col+1, m_dlg->m_colTypeName.value(m_profile->m_colNumType.value(col)))); + resetComboBox(type, m_profile->m_colTypeNum[type]); ret = false; + } else { m_profile->m_colTypeNum[type] = col; // assign new column 'number' to this 'type' m_profile->m_colNumType[col] = type; // assign new 'type' to this column 'number' diff --git a/kmymoney/plugins/csv/import/bankingwizardpage.h b/kmymoney/plugins/csv/import/bankingwizardpage.h index 7297e0e96..4e206812b 100644 --- a/kmymoney/plugins/csv/import/bankingwizardpage.h +++ b/kmymoney/plugins/csv/import/bankingwizardpage.h @@ -1,6 +1,7 @@ /* * Copyright 2011-2017 Allan Anderson <[email protected]> * Copyright 2016-2018 Łukasz Wojniłowicz <[email protected]> + * Copyright 2020 Thomas Baumgart <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -22,6 +23,8 @@ // ---------------------------------------------------------------------------- // QT Includes +class QComboBox; + // ---------------------------------------------------------------------------- // KDE Includes @@ -60,27 +63,21 @@ private: int nextId() const final override; bool validateMemoComboBox(); - void resetComboBox(const Column comboBox); + void resetComboBox ( Column comboBox, int index = -1 ); bool validateSelectedColumn(const int col, const Column type); - BankingProfile *m_profile; - Ui::BankingPage *ui; - void memoColSelected(int col); - void categoryColSelected(int col); - void numberColSelected(int col); void payeeColSelected(int col); - void dateColSelected(int col); - void debitColSelected(int col); - void creditColSelected(int col); - void amountColSelected(int col); - void amountToggled(bool checked); - void debitCreditToggled(bool checked); - void oppositeSignsClicked(bool checked); + void clearColumns(); void updateCurrentMemoSelection(); void clearMemoColumns(); +private: + BankingProfile* m_profile; + Ui::BankingPage* ui; + + QHash<Column, QComboBox *> m_columnBoxes; }; #endif // BANKINGWIZARDPAGE_H diff --git a/kmymoney/plugins/csv/import/bankingwizardpage.ui b/kmymoney/plugins/csv/import/bankingwizardpage.ui index 9fae0e24c..71c215734 100644 --- a/kmymoney/plugins/csv/import/bankingwizardpage.ui +++ b/kmymoney/plugins/csv/import/bankingwizardpage.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>681</width> - <height>253</height> + <width>698</width> + <height>402</height> </rect> </property> <property name="sizePolicy"> @@ -19,247 +19,265 @@ <property name="windowTitle"> <string>Banking Wizard Page</string> </property> - <layout class="QHBoxLayout" name="hl1" stretch="5,1,5"> + <layout class="QVBoxLayout" name="verticalLayout_4"> <item> - <spacer name="leftSpacer"> + <widget class="QLabel" name="header"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Please select the appropriate columns to use, + corresponding to your data.</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="Line" name="line"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> + </widget> </item> <item> - <layout class="QVBoxLayout" name="verticalLayout"> + <layout class="QHBoxLayout" name="hl_selectors" stretch="0,0,0,0,0"> <item> - <widget class="QLabel" name="label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Please select the appropriate columns to use, - corresponding to your data.</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> + <spacer name="leftSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - <property name="wordWrap"> - <bool>true</bool> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> </property> - </widget> + </spacer> </item> <item> - <layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0,0,0,0"> - <item row="3" column="4"> - <widget class="QLabel" name="labelBnk_debits"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="accessibleName"> - <string comment="column containing debits field"/> - </property> - <property name="text"> - <string comment="location of debit column">Debit</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="labelBnk_category"> - <property name="maximumSize"> - <size> - <width>16777215</width> - <height>16777215</height> - </size> - </property> - <property name="accessibleName"> - <string comment="column containing number field"/> - </property> - <property name="text"> - <string comment="column containing number field">Category</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QComboBox" name="m_dateCol"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select column containing date field.</string> - </property> - <property name="maxVisibleItems"> - <number>12</number> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QComboBox" name="m_categoryCol"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select column containing category field.</string> - </property> - <property name="maxVisibleItems"> - <number>12</number> - </property> - </widget> - </item> - <item row="4" column="4"> - <widget class="QLabel" name="labelBnk_credits"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="accessibleName"> - <string comment="column containing credits field"/> - </property> - <property name="text"> - <string comment="location of credit column">Credit</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="4" column="5"> - <widget class="QComboBox" name="m_creditCol"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select column containing credit field.</string> - </property> - <property name="maxVisibleItems"> - <number>12</number> - </property> - </widget> - </item> - <item row="3" column="2"> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Minimum</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>6</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item row="3" column="3"> - <widget class="QRadioButton" name="m_radioDebitCredit"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="font"> - <font> - <underline>false</underline> - </font> - </property> - <property name="toolTip"> - <string>Select 'Debit/credit' if both columns exist, otherwise select 'Amount'.</string> - </property> - <property name="accessibleName"> - <string comment="presence of debit and credit column"/> - </property> - <property name="text"> - <string comment="presence of debit/credit columns">De&bit/credit</string> - </property> - <property name="checked"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="labelBnk_date"> - <property name="accessibleName"> - <string comment="column containing date field"/> - </property> - <property name="text"> - <string>Date</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="2" column="5"> - <widget class="QComboBox" name="m_amountCol"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select column containing amount field.</string> - </property> - <property name="maxVisibleItems"> - <number>12</number> - </property> - </widget> - </item> - <item row="3" column="5"> - <widget class="QComboBox" name="m_debitCol"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select column containing debit field.</string> - </property> - <property name="maxVisibleItems"> - <number>12</number> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="labelBnk_payee"> - <property name="accessibleName"> - <string comment="column containing payee or description field"/> - </property> - <property name="text"> - <string comment="column containing payee or description field">Payee/Description</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="6" column="1"> - <layout class="QHBoxLayout" name="hl2" stretch="1,10,0"> - <item> + <layout class="QVBoxLayout" name="vl_left"> + <item> + <layout class="QGridLayout" name="gl_fields"> + <item row="0" column="0"> + <widget class="QLabel" name="labelBnk_number"> + <property name="accessibleName"> + <string comment="column containing number field"/> + </property> + <property name="text"> + <string comment="column containing number field">Number</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_numberCol</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="m_numberCol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Select column containing number field.</string> + </property> + <property name="editable"> + <bool>false</bool> + </property> + <property name="maxVisibleItems"> + <number>12</number> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QToolButton" name="m_numberColClear"> + <property name="toolTip"> + <string>Clear number field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelBnk_date"> + <property name="accessibleName"> + <string comment="column containing date field"/> + </property> + <property name="text"> + <string>Date</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_dateCol</cstring> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="m_dateCol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="toolTip"> + <string>Select column containing date field.</string> + </property> + <property name="maxVisibleItems"> + <number>12</number> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QToolButton" name="m_dateColClear"> + <property name="toolTip"> + <string>Clear date field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelBnk_payee"> + <property name="accessibleName"> + <string comment="column containing payee or description field"/> + </property> + <property name="text"> + <string comment="column containing payee or description field">Payee/Description</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_payeeCol</cstring> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QComboBox" name="m_payeeCol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select column containing payee or description field.</string> + </property> + <property name="maxVisibleItems"> + <number>12</number> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QToolButton" name="m_payeeColClear"> + <property name="toolTip"> + <string>Clear payee field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="labelBnk_category"> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>16777215</height> + </size> + </property> + <property name="accessibleName"> + <string comment="column containing number field"/> + </property> + <property name="text"> + <string comment="column containing number field">Category</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_categoryCol</cstring> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QComboBox" name="m_categoryCol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select column containing category field.</string> + </property> + <property name="maxVisibleItems"> + <number>12</number> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QToolButton" name="m_categoryColClear"> + <property name="toolTip"> + <string>Clear category field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="labelBnk_memo"> + <property name="accessibleName"> + <string comment="column containing date field"/> + </property> + <property name="text"> + <string>Memo</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_memoCol</cstring> + </property> + </widget> + </item> + <item row="4" column="1"> <widget class="QComboBox" name="m_memoCol"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> @@ -275,205 +293,465 @@ </property> </widget> </item> - <item> - <widget class="QLabel" name="m_currentMemoColums"> + <item row="5" column="0" colspan="2"> + <widget class="QLabel" name="m_currentMemoColumns"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> <property name="text"> - <string notr="true">Selection</string> + <string>Selection</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property> </widget> </item> - <item> - <widget class="QToolButton" name="m_clearMemoColumns"> + <item row="5" column="2"> + <widget class="QToolButton" name="m_memoColClear"> <property name="toolTip"> - <string>Clear selected memo column entries</string> + <string>Clear memo field selection.</string> + </property> + <property name="text"> + <string>...</string> </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="labelBnk_balance"> <property name="text"> - <string comment="Clear memo column assignment">Clear</string> + <string>Balance</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_balanceCol</cstring> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QComboBox" name="m_balanceCol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select column containing balance field.</string> + </property> + </widget> + </item> + <item row="6" column="2"> + <widget class="QToolButton" name="m_balanceColClear"> + <property name="toolTip"> + <string>Clear balance field selection.</string> + </property> + <property name="text"> + <string>...</string> </property> </widget> </item> </layout> </item> - <item row="4" column="1"> - <widget class="QComboBox" name="m_payeeCol"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select column containing payee or description field.</string> - </property> - <property name="maxVisibleItems"> - <number>12</number> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="labelBnk_memo"> - <property name="accessibleName"> - <string comment="column containing date field"/> - </property> - <property name="text"> - <string>Memo</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QComboBox" name="m_numberCol"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select column containing number field.</string> - </property> - <property name="editable"> - <bool>false</bool> - </property> - <property name="maxVisibleItems"> - <number>12</number> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="labelBnk_number"> - <property name="accessibleName"> - <string comment="column containing number field"/> - </property> - <property name="text"> - <string comment="column containing number field">Number</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="2" column="4"> - <widget class="QLabel" name="labelBnk_amount"> - <property name="accessibleName"> - <string comment="presence of amount column"/> - </property> - <property name="text"> - <string comment="location of amount column">Amount</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - </widget> - </item> - <item row="2" column="3"> - <widget class="QRadioButton" name="m_radioAmount"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select 'Amount' if only one value column, otherwise select 'Debit/credit'.</string> - </property> - <property name="whatsThis"> - <string extracomment="Select 'Amount' if only one value column, otherwise select "/> - </property> - <property name="accessibleName"> - <string comment="presence of amount column"/> - </property> - <property name="text"> - <string comment="presence of amount column">A&mount</string> - </property> - <property name="checked"> - <bool>false</bool> - </property> - </widget> - </item> - <item row="0" column="0" colspan="7"> - <widget class="Line" name="line_4"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item> + <spacer name="verticalSpacer_2"> <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="5" column="5"> - <widget class="QCheckBox" name="m_oppositeSigns"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Select if your amount column has signs improperly set.</string> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> + <enum>Qt::Vertical</enum> </property> - <property name="text"> - <string>Opposite signs</string> - </property> - </widget> - </item> - <item row="7" column="5"> - <widget class="QPushButton" name="m_clear"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="toolTip"> - <string>Clear all selected column entries</string> - </property> - <property name="text"> - <string comment="Clear all column assignments">Clear all</string> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> </property> - </widget> + </spacer> </item> </layout> </item> + <item> + <spacer name="midSpace"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Minimum</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>13</width> + <height>29</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QTabWidget" name="m_amountTabWidget"> + <property name="currentIndex"> + <number>0</number> + </property> + <widget class="QWidget" name="amountTab"> + <attribute name="title"> + <string>Amount</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <layout class="QGridLayout" name="gl_amount"> + <item row="0" column="0"> + <widget class="QLabel" name="labelBnk_amount"> + <property name="accessibleName"> + <string comment="presence of amount column"/> + </property> + <property name="text"> + <string comment="location of amount column">Amount</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_amountCol</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="m_amountCol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select column containing amount field.</string> + </property> + <property name="maxVisibleItems"> + <number>12</number> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QToolButton" name="m_amountColClear"> + <property name="toolTip"> + <string>Clear amount field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelBnk_indicator"> + <property name="text"> + <string>Debit/Credit Indicator</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_creditDebitIndicatorCol</cstring> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="m_creditDebitIndicatorCol"> + <property name="toolTip"> + <string>Select column containing indicator field.</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QToolButton" name="m_creditDebitIndicatorColClear"> + <property name="toolTip"> + <string>Clear indicator field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelBnk_debit"> + <property name="text"> + <string>Indicator for Credit</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="2" column="1" colspan="2"> + <widget class="QLineEdit" name="m_creditIndicator"> + <property name="toolTip"> + <string>Enter text that is used to indicate that amount is a credit.</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="labelBnk_credit"> + <property name="text"> + <string>Indicator for Debit</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="3" column="1" colspan="2"> + <widget class="QLineEdit" name="m_debitIndicator"> + <property name="toolTip"> + <string>Enter text that is used to indicate that amount is a debit.</string> + </property> + <property name="clearButtonEnabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0"> + <widget class="QLabel" name="labelBnk_opposite"> + <property name="text"> + <string>Opposite signs</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="1" colspan="2"> + <widget class="QCheckBox" name="m_oppositeSigns"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select if your amount column has signs improperly set.</string> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>64</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + <widget class="QWidget" name="debitCreditTab"> + <attribute name="title"> + <string>Debit/credit</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QGridLayout" name="gl_debitcredit"> + <item row="0" column="0"> + <widget class="QLabel" name="labelBnk_debits"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="accessibleName"> + <string comment="column containing debits field"/> + </property> + <property name="text"> + <string comment="location of debit column">Debit</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_debitCol</cstring> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="m_debitCol"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select column containing debit field.</string> + </property> + <property name="maxVisibleItems"> + <number>12</number> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QToolButton" name="m_debitColClear"> + <property name="toolTip"> + <string>Clear debit field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelBnk_credits"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="accessibleName"> + <string comment="column containing credits field"/> + </property> + <property name="text"> + <string comment="location of credit column">Credit</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="buddy"> + <cstring>m_creditCol</cstring> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QComboBox" name="m_creditCol"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select column containing credit field.</string> + </property> + <property name="maxVisibleItems"> + <number>12</number> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QToolButton" name="m_creditColClear"> + <property name="toolTip"> + <string>Clear credit field selection.</string> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>38</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </widget> + </item> + <item> + <spacer name="rightSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> </layout> </item> <item> - <spacer name="rightSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> + <layout class="QHBoxLayout" name="hl_bottom"> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="m_clear"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Clear all selected column and indicator entries</string> + </property> + <property name="text"> + <string comment="Clear all column assignments">Clear all</string> + </property> + </widget> + </item> + </layout> </item> </layout> </widget> <tabstops> <tabstop>m_numberCol</tabstop> + <tabstop>m_numberColClear</tabstop> <tabstop>m_dateCol</tabstop> + <tabstop>m_dateColClear</tabstop> <tabstop>m_payeeCol</tabstop> + <tabstop>m_payeeColClear</tabstop> <tabstop>m_categoryCol</tabstop> + <tabstop>m_categoryColClear</tabstop> <tabstop>m_memoCol</tabstop> - <tabstop>m_clearMemoColumns</tabstop> - <tabstop>m_radioAmount</tabstop> - <tabstop>m_radioDebitCredit</tabstop> + <tabstop>m_memoColClear</tabstop> + <tabstop>m_balanceCol</tabstop> + <tabstop>m_balanceColClear</tabstop> + <tabstop>m_amountTabWidget</tabstop> <tabstop>m_amountCol</tabstop> + <tabstop>m_amountColClear</tabstop> + <tabstop>m_creditDebitIndicatorCol</tabstop> + <tabstop>m_creditDebitIndicatorColClear</tabstop> + <tabstop>m_creditIndicator</tabstop> + <tabstop>m_debitIndicator</tabstop> + <tabstop>m_oppositeSigns</tabstop> <tabstop>m_debitCol</tabstop> + <tabstop>m_debitColClear</tabstop> <tabstop>m_creditCol</tabstop> - <tabstop>m_oppositeSigns</tabstop> - <tabstop>m_clear</tabstop> + <tabstop>m_creditColClear</tabstop> </tabstops> <resources/> <connections/> diff --git a/kmymoney/plugins/csv/import/core/csvenums.h b/kmymoney/plugins/csv/import/core/csvenums.h index ce1f5a3a4..802c6d081 100644 --- a/kmymoney/plugins/csv/import/core/csvenums.h +++ b/kmymoney/plugins/csv/import/core/csvenums.h @@ -1,5 +1,6 @@ /* - * Copyright 2017 Łukasz Wojniłowicz <[email protected]> + * Copyright 2017 Łukasz Wojniłowicz <[email protected]> + * Copyright 2020 Thomas Baumgart <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,17 +16,17 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <QHash> - #ifndef CSVENUMS_H #define CSVENUMS_H +#include <QHash> + enum class FieldDelimiter { Comma = 0, Semicolon, Colon, Tab, Auto }; enum class TextDelimiter { DoubleQuote = 0, SingleQuote }; enum class DecimalSymbol { Dot = 0, Comma, Auto }; enum class ThousandSeparator { Comma = 0, Dot }; enum class DateFormat { YearMonthDay = 0, MonthDayYear, DayMonthYear }; -enum class Column { Date, Memo, Number, Payee, Amount, Credit, Debit, Category, Type, Price, Quantity, Fee, Symbol, Name, Empty = 0xFE, Invalid = 0xFF }; +enum class Column { Date, Memo, Number, Payee, Amount, Credit, Debit, Category, Type, Price, Quantity, Fee, Symbol, Name, CreditDebitIndicator, Balance, Empty = 0xFE, Invalid = 0xFF }; enum class Profile { Banking, Investment, CurrencyPrices, StockPrices }; enum class ProfileAction { Add, Remove, Rename, UpdateLastUsed }; diff --git a/kmymoney/plugins/csv/import/core/csvimportercore.cpp b/kmymoney/plugins/csv/import/core/csvimportercore.cpp index a59866f7d..a0a3019a1 100644 --- a/kmymoney/plugins/csv/import/core/csvimportercore.cpp +++ b/kmymoney/plugins/csv/import/core/csvimportercore.cpp @@ -1,6 +1,7 @@ /* * Copyright 2010 Allan Anderson <[email protected]> * Copyright 2017-2018 Łukasz Wojniłowicz <[email protected]> + * Copyright 2020 Thomas Baumgart <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -68,6 +69,8 @@ const QHash<Column, QString> CSVImporterCore::m_colTypeConfName { {Column::Fee, QStringLiteral("FeeCol")}, {Column::Symbol, QStringLiteral("SymbolCol")}, {Column::Name, QStringLiteral("NameCol")}, + {Column::CreditDebitIndicator, QStringLiteral("CreditDebitIndicatorCol")}, + {Column::Balance, QStringLiteral("BalanceCol")}, }; const QHash<miscSettingsE, QString> CSVImporterCore::m_miscSettingsConfName { @@ -89,7 +92,9 @@ const QHash<miscSettingsE, QString> CSVImporterCore::m_miscSettingsConfName { {ConfPriceFraction, QStringLiteral("PriceFraction")}, {ConfDontAsk, QStringLiteral("DontAsk")}, {ConfHeight, QStringLiteral("Height")}, - {ConfWidth, QStringLiteral("Width")} + {ConfWidth, QStringLiteral("Width")}, + {ConfCreditIndicator, QStringLiteral("CreditIndicator")}, + {ConfDebitIndicator, QStringLiteral("DebitIndicator")}, }; const QHash<eMyMoney::Transaction::Action, QString> CSVImporterCore::m_transactionConfName { @@ -901,10 +906,43 @@ bool CSVImporterCore::processBankRow(MyMoneyStatement &st, const BankingProfile // process amount field col = profile->m_colTypeNum.value(Column::Amount, -1); - tr.m_amount = processAmountField(profile, row, col); - if (col != -1 && profile->m_oppositeSigns) // change signs to opposite if requested by user - tr.m_amount *= MyMoneyMoney(-1); - + if (col != -1) { + tr.m_amount = processAmountField(profile, row, col); + col = profile->m_colTypeNum.value(Column::CreditDebitIndicator, -1); + if (col != -1) { + const auto indicator = m_file->m_model->item(row, col)->text(); + + QRegularExpression exp; + exp.setPatternOptions(QRegularExpression::CaseInsensitiveOption); + +#if QT_VERSION < QT_VERSION_CHECK(5, 12, 0) + auto pattern = profile->m_creditIndicator; + // simplified version of QRegularExpression::wildcardToRegularExpression() + // for older Qt versions where the method does not exist + pattern.replace(QLatin1String("\\"), QLatin1String("\\\\")); + pattern.replace(QLatin1String("."), QLatin1String("\\.")); + pattern.replace(QLatin1String("*"), QLatin1String(".*")); + pattern.replace(QLatin1String("?"), QLatin1String(".")); + pattern.prepend(QLatin1String("\\A")); + pattern.append(QLatin1String("\\z")); +#else + auto pattern = QRegularExpression::wildcardToRegularExpression(profile->m_creditIndicator); +#endif + exp.setPattern(pattern); + + if (exp.match(indicator).hasMatch()) { + tr.m_amount = tr.m_amount.abs(); + } else { + exp.setPattern(profile->m_debitIndicator); + if (exp.match(indicator).hasMatch()) { + tr.m_amount = -(tr.m_amount.abs()); + } + } + } else { + if (profile->m_oppositeSigns) // change signs to opposite if requested by user + tr.m_amount = -tr.m_amount; + } + } // process credit/debit field if (profile->m_colTypeNum.value(Column::Credit, -1) != -1 && profile->m_colTypeNum.value(Column::Debit, -1) != -1) { @@ -935,6 +973,20 @@ bool CSVImporterCore::processBankRow(MyMoneyStatement &st, const BankingProfile } } + // process balance field + col = profile->m_colTypeNum.value(Column::Balance, -1); + if (col != -1) { + // prior date than the one we have? Adjust it + if (!st.m_dateBegin.isValid() || st.m_dateBegin > tr.m_datePosted) { + st.m_dateBegin = tr.m_datePosted; + } + // later or equal date, adjust it and the closing balance + if (!st.m_dateEnd.isValid() || st.m_dateEnd <= tr.m_datePosted) { + st.m_dateEnd = tr.m_datePosted; + st.m_closingBalance = processAmountField(profile, row, col); + } + } + // calculate hash txt.clear(); for (int i = 0; i < m_file->m_columnCount; ++i) @@ -1477,8 +1529,12 @@ bool BankingProfile::readSettings(const KSharedConfigPtr &config) m_colTypeNum[Column::Credit] = profilesGroup.readEntry(CSVImporterCore::m_colTypeConfName.value(Column::Credit), -1); m_colTypeNum[Column::Date] = profilesGroup.readEntry(CSVImporterCore::m_colTypeConfName.value(Column::Date), -1); m_colTypeNum[Column::Category] = profilesGroup.readEntry(CSVImporterCore::m_colTypeConfName.value(Column::Category), -1); + m_colTypeNum[Column::CreditDebitIndicator] = profilesGroup.readEntry(CSVImporterCore::m_colTypeConfName.value(Column::CreditDebitIndicator), -1); + m_colTypeNum[Column::Balance] = profilesGroup.readEntry(CSVImporterCore::m_colTypeConfName.value(Column::Balance), -1); m_colTypeNum[Column::Memo] = -1; // initialize, otherwise random data may go here m_oppositeSigns = profilesGroup.readEntry(CSVImporterCore::m_miscSettingsConfName.value(ConfOppositeSigns), false); + m_creditIndicator = profilesGroup.readEntry(CSVImporterCore::m_miscSettingsConfName.value(ConfCreditIndicator), QString()); + m_debitIndicator = profilesGroup.readEntry(CSVImporterCore::m_miscSettingsConfName.value(ConfDebitIndicator), QString()); m_memoColList = profilesGroup.readEntry(CSVImporterCore::m_colTypeConfName.value(Column::Memo), QList<int>()); CSVProfile::readSettings(profilesGroup); @@ -1491,6 +1547,8 @@ void BankingProfile::writeSettings(const KSharedConfigPtr &config) CSVProfile::writeSettings(profilesGroup); profilesGroup.writeEntry(CSVImporterCore::m_miscSettingsConfName.value(ConfOppositeSigns), m_oppositeSigns); + profilesGroup.writeEntry(CSVImporterCore::m_miscSettingsConfName.value(ConfCreditIndicator), m_creditIndicator); + profilesGroup.writeEntry(CSVImporterCore::m_miscSettingsConfName.value(ConfDebitIndicator), m_debitIndicator); profilesGroup.writeEntry(CSVImporterCore::m_colTypeConfName.value(Column::Payee), m_colTypeNum.value(Column::Payee)); profilesGroup.writeEntry(CSVImporterCore::m_colTypeConfName.value(Column::Number), @@ -1505,6 +1563,10 @@ void BankingProfile::writeSettings(const KSharedConfigPtr &config) m_colTypeNum.value(Column::Date)); profilesGroup.writeEntry(CSVImporterCore::m_colTypeConfName.value(Column::Category), m_colTypeNum.value(Column::Category)); + profilesGroup.writeEntry(CSVImporterCore::m_colTypeConfName.value(Column::CreditDebitIndicator), + m_colTypeNum.value(Column::CreditDebitIndicator)); + profilesGroup.writeEntry(CSVImporterCore::m_colTypeConfName.value(Column::Balance), + m_colTypeNum.value(Column::Balance)); profilesGroup.writeEntry(CSVImporterCore::m_colTypeConfName.value(Column::Memo), m_memoColList); profilesGroup.config()->sync(); diff --git a/kmymoney/plugins/csv/import/core/csvimportercore.h b/kmymoney/plugins/csv/import/core/csvimportercore.h index fa3b1ae5e..e44594f13 100644 --- a/kmymoney/plugins/csv/import/core/csvimportercore.h +++ b/kmymoney/plugins/csv/import/core/csvimportercore.h @@ -1,6 +1,7 @@ /* * Copyright 2010 Allan Anderson <[email protected]> * Copyright 2017-2018 Łukasz Wojniłowicz <[email protected]> + * Copyright 2020 Thomas Baumgart <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -53,7 +54,8 @@ enum miscSettingsE { ConfDirectory, ConfEncoding, ConfDateFormat, ConfFeeIsPercentage, ConfFeeRate, ConfMinFee, ConfSecurityName, ConfSecuritySymbol, ConfCurrencySymbol, ConfPriceFraction, ConfDontAsk, - ConfHeight, ConfWidth + ConfHeight, ConfWidth, + ConfCreditIndicator, ConfDebitIndicator, }; enum validationResultE { ValidActionType, InvalidActionValues, NoActionType }; @@ -140,6 +142,8 @@ public: QList<int> m_memoColList; bool m_oppositeSigns; + QString m_creditIndicator; + QString m_debitIndicator; }; class KMM_CSVIMPORTERCORE_EXPORT InvestmentProfile : public CSVProfile diff --git a/kmymoney/plugins/csv/import/csvwizard.cpp b/kmymoney/plugins/csv/import/csvwizard.cpp index edb7c6e5d..7f06edc33 100644 --- a/kmymoney/plugins/csv/import/csvwizard.cpp +++ b/kmymoney/plugins/csv/import/csvwizard.cpp @@ -1,7 +1,7 @@ /* * Copyright 2015-2016 Allan Anderson <[email protected]> * Copyright 2016-2018 Łukasz Wojniłowicz <[email protected]> - * Copyright 2018 Thomas Baumgart <[email protected]> + * Copyright 2018-2020 Thomas Baumgart <[email protected]> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -439,16 +439,14 @@ void CSVWizard::initializeComboBoxes(const QHash<Column, QComboBox *> &columns) columnNumbers.append(QString::number(i + 1)); foreach (const auto column, columns) { - // disable widgets allowing their initialization - column->blockSignals(true); + // block signals from combobox during their initialization + QSignalBlocker blocker(column); // clear all existing items before adding new ones column->clear(); // populate comboboxes with col # values column->addItems(columnNumbers); // all comboboxes are set to 0 so set them to -1 column->setCurrentIndex(-1); - // enable widgets after their initialization - column->blockSignals(false); } }
