diff --git a/kmymoney/dialogs/konlinetransferform.cpp b/kmymoney/dialogs/konlinetransferform.cpp index 9a66b2ab4..9494601bd 100644 --- a/kmymoney/dialogs/konlinetransferform.cpp +++ b/kmymoney/dialogs/konlinetransferform.cpp @@ -1,330 +1,330 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "konlinetransferform.h" #include "ui_konlinetransferformdecl.h" #include #include #include #include #include #include #include #include #include "kguiutils.h" #include "kmymoneylineedit.h" #include "onlinetasks/interfaces/ui/ionlinejobedit.h" #include "mymoney/mymoneyfile.h" #include "mymoney/mymoneyaccount.h" #include "mymoney/onlinejobadministration.h" #include "models/models.h" #include using namespace Icons; kOnlineTransferForm::kOnlineTransferForm(QWidget *parent) : QDialog(parent), ui(new Ui::kOnlineTransferFormDecl), m_onlineJobEditWidgets(QList()), m_requiredFields(new kMandatoryFieldGroup(this)) { ui->setupUi(this); ui->unsupportedIcon->setPixmap(QIcon::fromTheme(g_Icons[Icon::DialogInformation]).pixmap(style()->pixelMetric(QStyle::PM_MessageBoxIconSize))); // The ui designer fills the QScrollArea with a QWidget. Remove it so we can simply check for .widget() == nullptr // if it contains a valid widget delete ui->creditTransferEdit->takeWidget(); OnlineBankingAccountNamesFilterProxyModel* accountsModel = new OnlineBankingAccountNamesFilterProxyModel(this); auto const model = Models::instance()->accountsModel(); accountsModel->setSourceModel(model); ui->originAccount->setModel(accountsModel); ui->convertMessage->hide(); ui->convertMessage->setWordWrap(true); auto edits = onlineJobAdministration::instance()->onlineJobEdits(); std::for_each(edits.constBegin(), edits.constEnd(), [this](onlineJobAdministration::onlineJobEditOffer in) {this->loadOnlineJobEditPlugin(in);}); // Message Widget for read only jobs m_duplicateJob = KStandardAction::copy(this); connect(m_duplicateJob, SIGNAL(triggered(bool)), SLOT(duplicateCurrentJob())); ui->headMessage->hide(); ui->headMessage->setWordWrap(true); ui->headMessage->setCloseButtonVisible(false); ui->headMessage->addAction(m_duplicateJob); connect(ui->transferTypeSelection, SIGNAL(currentIndexChanged(int)), this, SLOT(convertCurrentJob(int))); connect(ui->buttonAbort, SIGNAL(clicked(bool)), this, SLOT(reject())); connect(ui->buttonSend, SIGNAL(clicked(bool)), this, SLOT(sendJob())); connect(ui->buttonEnque, SIGNAL(clicked(bool)), this, SLOT(accept())); connect(m_requiredFields, SIGNAL(stateChanged(bool)), ui->buttonEnque, SLOT(setEnabled(bool))); connect(ui->originAccount, SIGNAL(accountSelected(QString)), this, SLOT(accountChanged())); accountChanged(); setJobReadOnly(false); m_requiredFields->add(ui->originAccount); m_requiredFields->setOkButton(ui->buttonSend); } void kOnlineTransferForm::loadOnlineJobEditPlugin(const onlineJobAdministration::onlineJobEditOffer& pluginDesc) { try { std::unique_ptr loader{new QPluginLoader(pluginDesc.fileName, this)}; QObject* plugin = loader->instance(); if (!plugin) { qWarning() << "Could not load plugin for online job editor from file \"" << pluginDesc.fileName << "\"."; return; } // Cast to KPluginFactory KPluginFactory* pluginFactory = qobject_cast< KPluginFactory* >(plugin); if (!pluginFactory) { qWarning() << "Could not create plugin factory for online job editor in file \"" << pluginDesc.fileName << "\"."; return; } IonlineJobEdit* widget = pluginFactory->create(pluginDesc.pluginKeyword, this); if (!widget) { qWarning() << "Could not create online job editor in file \"" << pluginDesc.fileName << "\"."; return; } // directly load the first widget into QScrollArea bool showWidget = true; if (!m_onlineJobEditWidgets.isEmpty()) { widget->setEnabled(false); showWidget = false; } m_onlineJobEditWidgets.append(widget); ui->transferTypeSelection->addItem(pluginDesc.name); m_requiredFields->add(widget); if (showWidget) showEditWidget(widget); } catch (MyMoneyException& e) { qWarning("Error while loading a plugin (IonlineJobEdit)."); } } void kOnlineTransferForm::convertCurrentJob(const int& index) { Q_ASSERT(index < m_onlineJobEditWidgets.count()); IonlineJobEdit* widget = m_onlineJobEditWidgets.at(index); // Vars set by onlineJobAdministration::convertBest onlineTaskConverter::convertType convertType; QString userMessage; widget->setOnlineJob(onlineJobAdministration::instance()->convertBest(activeOnlineJob(), widget->supportedOnlineTasks(), convertType, userMessage)); if (convertType == onlineTaskConverter::convertImpossible && userMessage.isEmpty()) userMessage = i18n("During the change of the order your previous entries could not be converted."); if (!userMessage.isEmpty()) { switch (convertType) { case onlineTaskConverter::convertionLossyMajor: ui->convertMessage->setMessageType(KMessageWidget::Warning); break; case onlineTaskConverter::convertImpossible: case onlineTaskConverter::convertionLossyMinor: ui->convertMessage->setMessageType(KMessageWidget::Information); break; case onlineTaskConverter::convertionLoseless: break; } ui->convertMessage->setText(userMessage); ui->convertMessage->animatedShow(); } showEditWidget(widget); } void kOnlineTransferForm::duplicateCurrentJob() { IonlineJobEdit* widget = qobject_cast< IonlineJobEdit* >(ui->creditTransferEdit->widget()); if (widget == 0) return; onlineJob duplicate(QString(), activeOnlineJob()); widget->setOnlineJob(duplicate); } void kOnlineTransferForm::accept() { emit acceptedForSave(activeOnlineJob()); QDialog::accept(); } void kOnlineTransferForm::sendJob() { emit acceptedForSend(activeOnlineJob()); QDialog::accept(); } void kOnlineTransferForm::reject() { QDialog::reject(); } bool kOnlineTransferForm::setOnlineJob(const onlineJob job) { QString name; try { name = job.task()->taskName(); } catch (const onlineJob::emptyTask&) { return false; } setCurrentAccount(job.responsibleAccount()); if (showEditWidget(name)) { IonlineJobEdit* widget = qobject_cast(ui->creditTransferEdit->widget()); if (widget != 0) { // This can happen if there are no widgets const bool ret = widget->setOnlineJob(job); setJobReadOnly(!job.isEditable()); return ret; } } return false; } void kOnlineTransferForm::accountChanged() { const QString accountId = ui->originAccount->getSelected(); try { ui->orderAccountBalance->setValue(MyMoneyFile::instance()->balance(accountId)); } catch (const MyMoneyException&) { // @todo this can happen until the selection allows to select correct accounts only ui->orderAccountBalance->setText(""); } foreach (IonlineJobEdit* widget, m_onlineJobEditWidgets) widget->setOriginAccount(accountId); checkNotSupportedWidget(); } bool kOnlineTransferForm::checkEditWidget() { return checkEditWidget(qobject_cast(ui->creditTransferEdit->widget())); } bool kOnlineTransferForm::checkEditWidget(IonlineJobEdit* widget) { if (widget != 0 && onlineJobAdministration::instance()->isJobSupported(ui->originAccount->getSelected(), widget->supportedOnlineTasks())) { return true; } return false; } /** @todo auto set another widget if a loseless convert is possible */ void kOnlineTransferForm::checkNotSupportedWidget() { if (!checkEditWidget()) { ui->displayStack->setCurrentIndex(0); } else { ui->displayStack->setCurrentIndex(1); } } void kOnlineTransferForm::setCurrentAccount(const QString& accountId) { ui->originAccount->setSelected(accountId); } onlineJob kOnlineTransferForm::activeOnlineJob() const { IonlineJobEdit* widget = qobject_cast(ui->creditTransferEdit->widget()); if (widget == 0) return onlineJob(); return widget->getOnlineJob(); } void kOnlineTransferForm::setJobReadOnly(const bool& readOnly) { ui->originAccount->setDisabled(readOnly); ui->transferTypeSelection->setDisabled(readOnly); if (readOnly) { ui->headMessage->setMessageType(KMessageWidget::Information); if (activeOnlineJob().sendDate().isValid()) ui->headMessage->setText(i18n("This credit-transfer was sent to your bank at %1 therefore cannot be edited anymore. You may create a copy for editing.").arg(activeOnlineJob().sendDate().toString(Qt::DefaultLocaleShortDate))); else ui->headMessage->setText(i18n("This credit-transfer is not editable. You may create a copy for editing.")); if (this->isHidden()) ui->headMessage->show(); else ui->headMessage->animatedShow(); } else { ui->headMessage->animatedHide(); } } bool kOnlineTransferForm::showEditWidget(const QString& onlineTaskName) { int index = 0; foreach (IonlineJobEdit* widget, m_onlineJobEditWidgets) { if (widget->supportedOnlineTasks().contains(onlineTaskName)) { ui->transferTypeSelection->setCurrentIndex(index); showEditWidget(widget); return true; } ++index; } return false; } void kOnlineTransferForm::showEditWidget(IonlineJobEdit* widget) { Q_CHECK_PTR(widget); QWidget* oldWidget = ui->creditTransferEdit->takeWidget(); if (oldWidget != 0) { // This is true at the first call of showEditWidget() and if there are no widgets. oldWidget->setEnabled(false); disconnect(oldWidget, SIGNAL(readOnlyChanged(bool)), this, SLOT(setJobReadOnly(bool))); } widget->setEnabled(true); ui->creditTransferEdit->setWidget(widget); setJobReadOnly(widget->isReadOnly()); widget->show(); connect(widget, SIGNAL(readOnlyChanged(bool)), SLOT(setJobReadOnly(bool))); checkNotSupportedWidget(); m_requiredFields->changed(); } kOnlineTransferForm::~kOnlineTransferForm() { ui->creditTransferEdit->takeWidget(); qDeleteAll(m_onlineJobEditWidgets); delete ui; delete m_duplicateJob; } diff --git a/kmymoney/dialogs/konlinetransferform.h b/kmymoney/dialogs/konlinetransferform.h index 71dd5d331..a968ff864 100644 --- a/kmymoney/dialogs/konlinetransferform.h +++ b/kmymoney/dialogs/konlinetransferform.h @@ -1,139 +1,139 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KONLINETRANSFERFORM_H #define KONLINETRANSFERFORM_H // ---------------------------------------------------------------------------- // QT Includes #include // ---------------------------------------------------------------------------- // Project Includes #include "mymoney/onlinejob.h" #include "mymoney/onlinejobadministration.h" class IonlineJobEdit; class kMandatoryFieldGroup; namespace Ui { class kOnlineTransferFormDecl; } /** * @brief The kOnlineTransferForm class * * @todo Disable Send/Enque button if no task is shown. * @todo If this dialog is shown a second time without setting a onlineJob it, it shows the previous content. * Fix this by creating the IonlineJobEdit widgets on demand and destroying them afterwards. */ class kOnlineTransferForm : public QDialog { Q_OBJECT public: kOnlineTransferForm(QWidget *parent = 0); virtual ~kOnlineTransferForm(); signals: /** @brief The user wants this job to be saved */ void acceptedForSave(onlineJob); /** @brief User wants to send the onlineJob directly */ void acceptedForSend(onlineJob); public slots: virtual void accept(); virtual void reject(); /** @brief sets the current origin account */ virtual void setCurrentAccount(const QString& accountId); /** * @brief Sets an onlineTransfer to edit * * @return true if there is widget which supports editing this onlineJob */ virtual bool setOnlineJob(const onlineJob); void duplicateCurrentJob(); private slots: /** @brief Slot for account selection box */ void accountChanged(); /** * @brief Slot to change job type * @param index of KComboBox (== index of selected widget in m_onlineJobEditWidgets) */ void convertCurrentJob(const int& index); /** @brief Slot for send button */ void sendJob(); /** * @brief Load a plugin */ void loadOnlineJobEditPlugin(const onlineJobAdministration::onlineJobEditOffer& plugin); /** @{ */ /** * @brief Activates the onlineJobEdit widget */ bool showEditWidget(const QString& onlineTaskName); void showEditWidget(IonlineJobEdit* widget); /** @} */ /** * @brief Shows warning if checkEditWidget() == false */ void checkNotSupportedWidget(); void setJobReadOnly(const bool&); private: /** * @brief returns the currently edited onlineJob * Can be a null job */ onlineJob activeOnlineJob() const; Ui::kOnlineTransferFormDecl* ui; QList m_onlineJobEditWidgets; kMandatoryFieldGroup* m_requiredFields; QAction* m_duplicateJob; /** * @brief Checks if widget can edit any task the selected account supports */ bool checkEditWidget(IonlineJobEdit* widget); /** * @brief Checks current widget * @see checkEditWidget( IonlineJobEdit* widget ) */ bool checkEditWidget(); void editWidgetChanged(); }; #endif // KONLINETRANSFERFORM_H diff --git a/kmymoney/dialogs/settings/ksettingskmymoney.cpp b/kmymoney/dialogs/settings/ksettingskmymoney.cpp index 52e99bb72..20b615ea8 100644 --- a/kmymoney/dialogs/settings/ksettingskmymoney.cpp +++ b/kmymoney/dialogs/settings/ksettingskmymoney.cpp @@ -1,79 +1,79 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2016 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ksettingskmymoney.h" #include #include "ksettingsgeneral.h" #include "ksettingsregister.h" #include "ksettingsgpg.h" #include "ksettingscolors.h" #include "ksettingsfonts.h" #include "ksettingsicons.h" #include "ksettingsschedules.h" #include "ksettingsonlinequotes.h" #include "ksettingshome.h" #include "ksettingsforecast.h" #include "ksettingsreports.h" #include "pluginloader.h" #include "icons/icons.h" using namespace Icons; KSettingsKMyMoney::KSettingsKMyMoney(QWidget *parent, const QString &name, KCoreConfigSkeleton *config) : KConfigDialog(parent, name, config) { // create the pages ... KSettingsGeneral* generalPage = new KSettingsGeneral(); KSettingsRegister* registerPage = new KSettingsRegister(); KSettingsHome* homePage = new KSettingsHome(); KSettingsSchedules* schedulesPage = new KSettingsSchedules(); KSettingsGpg* encryptionPage = new KSettingsGpg(); KSettingsColors* colorsPage = new KSettingsColors(); KSettingsFonts* fontsPage = new KSettingsFonts(); KSettingsIcons* iconsPage = new KSettingsIcons(); KSettingsOnlineQuotes* onlineQuotesPage = new KSettingsOnlineQuotes(); KSettingsForecast* forecastPage = new KSettingsForecast(); KPluginSelector* pluginsPage = KMyMoneyPlugin::PluginLoader::instance()->pluginSelectorWidget(); KSettingsReports* reportsPage = new KSettingsReports(); addPage(generalPage, i18nc("General settings", "General"), g_Icons[Icon::SystemRun]); addPage(homePage, i18n("Home"), g_Icons[Icon::ViewHome]); addPage(registerPage, i18nc("Ledger view settings", "Ledger"), g_Icons[Icon::ViewFinancialList]); addPage(schedulesPage, i18n("Scheduled transactions"), g_Icons[Icon::ViewSchedules]); addPage(onlineQuotesPage, i18n("Online Quotes"), g_Icons[Icon::PreferencesNetwork]); addPage(reportsPage, i18nc("Report settings", "Reports"), g_Icons[Icon::ViewReports]); addPage(forecastPage, i18nc("Forecast settings", "Forecast"), g_Icons[Icon::ViewForecast]); addPage(encryptionPage, i18n("Encryption"), g_Icons[Icon::Kgpg]); addPage(colorsPage, i18n("Colors"), g_Icons[Icon::PreferencesColor]); addPage(fontsPage, i18n("Fonts"), g_Icons[Icon::PreferencesFont]); addPage(iconsPage, i18n("Icons"), g_Icons[Icon::PreferencesIcon]); addPage(pluginsPage, i18n("Plugins"), g_Icons[Icon::NetworkDisconect]); setHelp("details.settings", "kmymoney"); QAbstractButton* defaultButton = button(QDialogButtonBox::RestoreDefaults); connect(this, &KConfigDialog::rejected, schedulesPage, &KSettingsSchedules::slotResetRegion); connect(this, &KConfigDialog::rejected, iconsPage, &KSettingsIcons::slotResetTheme); connect(this, &KConfigDialog::settingsChanged, generalPage, &KSettingsGeneral::slotUpdateEquitiesVisibility); connect(this, &KConfigDialog::accepted, pluginsPage, &KPluginSelector::save); connect(defaultButton, &QAbstractButton::clicked, pluginsPage, &KPluginSelector::defaults); } diff --git a/kmymoney/dialogs/settings/ksettingskmymoney.h b/kmymoney/dialogs/settings/ksettingskmymoney.h index 33a2280fa..ae5806484 100644 --- a/kmymoney/dialogs/settings/ksettingskmymoney.h +++ b/kmymoney/dialogs/settings/ksettingskmymoney.h @@ -1,34 +1,34 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2016 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KSETTINGSKMYMONEY_H #define KSETTINGSKMYMONEY_H #include /** * @brief The general settings dialog */ class KSettingsKMyMoney : public KConfigDialog { public: KSettingsKMyMoney(QWidget *parent, const QString &name, KCoreConfigSkeleton *config); }; #endif /* KSETTINGSKMYMONEY_H */ diff --git a/kmymoney/misc/charvalidator.cpp b/kmymoney/misc/charvalidator.cpp index b2ec7043a..91afa8ec5 100644 --- a/kmymoney/misc/charvalidator.cpp +++ b/kmymoney/misc/charvalidator.cpp @@ -1,41 +1,41 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "misc/charvalidator.h" charValidator::charValidator(QObject* parent, const QString& characters) : QValidator(parent), m_allowedCharacters(characters) { } QValidator::State charValidator::validate(QString& string, int& pos) const { Q_UNUSED(pos); const int length = string.length(); for (int i = 0; i < length; ++i) { if (!m_allowedCharacters.contains(string.at(i))) return QValidator::Invalid; } return QValidator::Acceptable; } void charValidator::setAllowedCharacters(const QString& chars) { m_allowedCharacters = chars; } diff --git a/kmymoney/misc/charvalidator.h b/kmymoney/misc/charvalidator.h index 4942c9210..48a18a6f9 100644 --- a/kmymoney/misc/charvalidator.h +++ b/kmymoney/misc/charvalidator.h @@ -1,38 +1,38 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CHARVALIDATOR_H #define CHARVALIDATOR_H #include class charValidator : public QValidator { Q_OBJECT public: charValidator(QObject* parent = 0, const QString& characters = QString()); virtual QValidator::State validate(QString& , int&) const; void setAllowedCharacters(const QString&); private: QString m_allowedCharacters; }; #endif // CHARVALIDATOR_H diff --git a/kmymoney/misc/validators.cpp b/kmymoney/misc/validators.cpp index 82f772a07..8523e6282 100644 --- a/kmymoney/misc/validators.cpp +++ b/kmymoney/misc/validators.cpp @@ -1,41 +1,41 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "validators.h" #include bool validators::checkLineLength(const QString& text, const int& length) { const QStringList lines = text.split('\n'); foreach (QString line, lines) { if (line.length() > length) return false; } return true; } bool validators::checkCharset(const QString& text, const QString& allowedChars) { const int length = text.length(); for (int i = 0; i < length; ++i) { if (!allowedChars.contains(text.at(i))) return false; } return true; } diff --git a/kmymoney/misc/validators.h b/kmymoney/misc/validators.h index 43ae4d3e6..c802998d6 100644 --- a/kmymoney/misc/validators.h +++ b/kmymoney/misc/validators.h @@ -1,40 +1,40 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef VALIDATORS_H #define VALIDATORS_H #include namespace validators { enum lengthStatus { ok = 0, tooShort = -1, tooLong = 1 }; /** @brief checks if all lines in text are shorter than length */ bool checkLineLength(const QString& text, const int& length); /** @brief checks if text uses only charactes in allowedChars */ bool checkCharset(const QString& text, const QString& allowedChars); }; #endif // VALIDATORS_H diff --git a/kmymoney/models/onlinebankingaccountsfilterproxymodel.cpp b/kmymoney/models/onlinebankingaccountsfilterproxymodel.cpp index adfea3526..66070bbd6 100644 --- a/kmymoney/models/onlinebankingaccountsfilterproxymodel.cpp +++ b/kmymoney/models/onlinebankingaccountsfilterproxymodel.cpp @@ -1,62 +1,62 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinebankingaccountsfilterproxymodel.h" #include "accountsmodel.h" #include "mymoney/onlinejobadministration.h" OnlineBankingAccountsFilterProxyModel::OnlineBankingAccountsFilterProxyModel(QObject* parent) : QSortFilterProxyModel(parent) { } bool OnlineBankingAccountsFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { const QModelIndex sourceIndex = sourceModel()->index(source_row, 0, source_parent); const QString accountId = sourceModel()->data(sourceIndex, AccountsModel::AccountIdRole).toString(); if (accountId.isEmpty()) return false; else if (onlineJobAdministration::instance()->isAnyJobSupported(accountId)) return true; return filterAcceptsParent(sourceIndex); } Qt::ItemFlags OnlineBankingAccountsFilterProxyModel::flags(const QModelIndex& index) const { const QString accountId = sourceModel()->data(mapToSource(index), AccountsModel::AccountIdRole).toString(); if (onlineJobAdministration::instance()->isAnyJobSupported(accountId)) return QSortFilterProxyModel::flags(index); return QSortFilterProxyModel::flags(index) & ~Qt::ItemIsSelectable; } bool OnlineBankingAccountsFilterProxyModel::filterAcceptsParent(const QModelIndex& index) const { auto const model = sourceModel(); const auto rowCount = model->rowCount(index); for (auto i = 0; i < rowCount; ++i) { const auto childIndex = model->index(i, AccountsModel::Account, index); // CAUTION! Assumption is being made that Account column number is always 0 if (onlineJobAdministration::instance()->isAnyJobSupported(model->data(childIndex, AccountsModel::AccountIdRole).toString())) return true; if (filterAcceptsParent(childIndex)) return true; } return false; } diff --git a/kmymoney/models/onlinebankingaccountsfilterproxymodel.h b/kmymoney/models/onlinebankingaccountsfilterproxymodel.h index 4bdb33efd..1c606feab 100644 --- a/kmymoney/models/onlinebankingaccountsfilterproxymodel.h +++ b/kmymoney/models/onlinebankingaccountsfilterproxymodel.h @@ -1,46 +1,46 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEBANKINGACCOUNTSFILTERPROXYMODEL_H #define ONLINEBANKINGACCOUNTSFILTERPROXYMODEL_H #include class OnlineBankingAccountsFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT public: OnlineBankingAccountsFilterProxyModel(QObject* parent = 0); /** * @brief Makes accounts which do not support any onlineJob non-selectable */ virtual Qt::ItemFlags flags(const QModelIndex& index) const; protected: virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; private: /** * @brief Has parent at least one visible child? */ bool filterAcceptsParent(const QModelIndex& index) const; }; #endif // ONLINEBANKINGACCOUNTSFILTERPROXYMODEL_H diff --git a/kmymoney/models/onlinejobmessagesmodel.cpp b/kmymoney/models/onlinejobmessagesmodel.cpp index be37a2de6..7e641ceaf 100644 --- a/kmymoney/models/onlinejobmessagesmodel.cpp +++ b/kmymoney/models/onlinejobmessagesmodel.cpp @@ -1,122 +1,122 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobmessagesmodel.h" #include #include #include using namespace Icons; onlineJobMessagesModel::onlineJobMessagesModel(QObject* parent) : QAbstractTableModel(parent), m_job() { } QVariant onlineJobMessagesModel::data(const QModelIndex& index, int role) const { const QList messages = m_job.jobMessageList(); if (index.row() >= messages.count()) return QVariant(); switch (index.column()) { case 0: switch (role) { // Status/Date column case Qt::DisplayRole: return messages[index.row()].timestamp(); case Qt::DecorationRole: switch (messages[index.row()].type()) { case onlineJobMessage::debug: case onlineJobMessage::log: case onlineJobMessage::information: return QIcon::fromTheme(g_Icons[Icon::DialogInformation]); case onlineJobMessage::warning: return QIcon::fromTheme(g_Icons[Icon::DialogWarning]); case onlineJobMessage::error: return QIcon::fromTheme(g_Icons[Icon::DialogError]); } case Qt::ToolTipRole: switch (messages[index.row()].type()) { case onlineJobMessage::debug: return i18n("Information to find issues."); case onlineJobMessage::log: return i18n("Information stored for provability."); case onlineJobMessage::information: return i18n("Informative message without certain significance."); case onlineJobMessage::warning: return i18n("Warning message."); case onlineJobMessage::error: return i18n("Error"); } default: return QVariant(); } case 1: switch (role) { // Origin column case Qt::DisplayRole: return messages[index.row()].sender(); default: return QVariant(); } case 2: switch (role) { // Message column case Qt::DisplayRole: return messages[index.row()].message(); default: return QVariant(); } } // Actually we should never get here. But let's make this model bullet proof. return QVariant(); } int onlineJobMessagesModel::columnCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return 3; } int onlineJobMessagesModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) return 0; return m_job.jobMessageList().count(); } QModelIndex onlineJobMessagesModel::parent(const QModelIndex&) const { return QModelIndex(); } QVariant onlineJobMessagesModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal) { switch (section) { case 0: switch (role) { case Qt::DisplayRole: return i18n("Date"); default: return QVariant(); } case 1: switch (role) { case Qt::DisplayRole: return i18n("Origin"); default: return QVariant(); } case 2: switch (role) { case Qt::DisplayRole: return i18n("Description"); default: return QVariant(); } } } return QVariant(); } void onlineJobMessagesModel::setOnlineJob(const onlineJob& job) { beginResetModel(); m_job = job; endResetModel(); } diff --git a/kmymoney/models/onlinejobmessagesmodel.h b/kmymoney/models/onlinejobmessagesmodel.h index e1f6280b7..4ef2d7fc6 100644 --- a/kmymoney/models/onlinejobmessagesmodel.h +++ b/kmymoney/models/onlinejobmessagesmodel.h @@ -1,45 +1,45 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBMESSAGESMODEL_H #define ONLINEJOBMESSAGESMODEL_H #include #include "mymoney/onlinejob.h" class onlineJobMessagesModel : public QAbstractTableModel { Q_OBJECT public: explicit onlineJobMessagesModel(QObject* parent = 0); virtual QVariant data(const QModelIndex& index, int role) const; virtual int columnCount(const QModelIndex& parent) const; virtual int rowCount(const QModelIndex& parent) const; virtual QModelIndex parent(const QModelIndex& child) const; virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; public slots: void setOnlineJob(const onlineJob& job); protected: onlineJob m_job; }; #endif // ONLINEJOBMESSAGESMODEL_H diff --git a/kmymoney/models/onlinejobmodel.cpp b/kmymoney/models/onlinejobmodel.cpp index c88b22f9a..89e361342 100644 --- a/kmymoney/models/onlinejobmodel.cpp +++ b/kmymoney/models/onlinejobmodel.cpp @@ -1,271 +1,271 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobmodel.h" #include #include #include #include #include "mymoneyutils.h" #include "onlinetasks/interfaces/tasks/onlinetask.h" #include "onlinetasks/interfaces/tasks/credittransfer.h" #include "mymoney/onlinejobtyped.h" #include using namespace Icons; onlineJobModel::onlineJobModel(QObject *parent) : QAbstractTableModel(parent), m_jobIdList(QStringList()) { MyMoneyFile *const file = MyMoneyFile::instance(); connect(file, &MyMoneyFile::objectAdded, this, &onlineJobModel::slotObjectAdded); connect(file, &MyMoneyFile::objectModified, this, &onlineJobModel::slotObjectModified); connect(file, &MyMoneyFile::objectRemoved, this, &onlineJobModel::slotObjectRemoved); } void onlineJobModel::load() { unload(); beginInsertRows(QModelIndex(), 0, 0); foreach (const onlineJob job, MyMoneyFile::instance()->onlineJobList()) { m_jobIdList.append(job.id()); } endInsertRows(); } void onlineJobModel::unload() { if (!m_jobIdList.isEmpty()) { beginResetModel(); m_jobIdList.clear(); endResetModel(); } } int onlineJobModel::rowCount(const QModelIndex & parent) const { if (parent.isValid()) return 0; return m_jobIdList.count(); } int onlineJobModel::columnCount(const QModelIndex & parent) const { if (parent.isValid()) return 0; return 4; } QVariant onlineJobModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { switch (section) { case columns::ColAccount: return i18n("Account"); case columns::ColAction: return i18n("Action"); case columns::ColDestination: return i18n("Destination"); case columns::ColValue: return i18n("Value"); } } return QVariant(); } /** * @todo LOW improve speed * @todo use now onlineJob system */ QVariant onlineJobModel::data(const QModelIndex & index, int role) const { if (index.parent().isValid()) return QVariant(); Q_ASSERT(m_jobIdList.length() > index.row()); onlineJob job; try { job = MyMoneyFile::instance()->getOnlineJob(m_jobIdList[index.row()]); } catch (const MyMoneyException&) { return QVariant(); } // id of MyMoneyObject if (role == roles::OnlineJobId) return QVariant::fromValue(job.id()); else if (role == roles::OnlineJobRole) return QVariant::fromValue(job); // If job is null, display an error message and exit if (job.isNull()) { if (index.column() == columns::ColAction) { switch (role) { case Qt::DisplayRole: return i18n("Not able to display this job."); case Qt::ToolTipRole: return i18n("Could not find a plugin to display this job or it does not contain any data."); } } return QVariant(); } // Show general information if (index.column() == columns::ColAccount) { // Account column if (role == Qt::DisplayRole) { return QVariant::fromValue(job.responsibleMyMoneyAccount().name()); } else if (role == Qt::DecorationRole) { if (job.isLocked()) return QIcon::fromTheme(g_Icons[Icon::TaskOngoing]); switch (job.bankAnswerState()) { case onlineJob::acceptedByBank: return QIcon::fromTheme(g_Icons[Icon::TaskComplete]); case onlineJob::sendingError: case onlineJob::abortedByUser: case onlineJob::rejectedByBank: return QIcon::fromTheme(g_Icons[Icon::TaskReject]); case onlineJob::noBankAnswer: break; } if (job.sendDate().isValid()) { return QIcon::fromTheme(g_Icons[Icon::TaskAccepted]); } else if (!job.isValid()) { return QIcon::fromTheme(g_Icons[Icon::TaskAttention]); } } else if (role == Qt::ToolTipRole) { if (job.isLocked()) return i18n("Job is being processed at the moment."); switch (job.bankAnswerState()) { case onlineJob::acceptedByBank: return i18nc("Arg 1 is a date/time", "This job was accepted by the bank on %1.").arg(job.bankAnswerDate().toString(Qt::DefaultLocaleShortDate)); case onlineJob::sendingError: return i18nc("Arg 1 is a date/time", "Sending this job failed (tried on %1).").arg(job.sendDate().toString(Qt::DefaultLocaleShortDate)); case onlineJob::abortedByUser: return i18n("Sending this job was manually aborted."); case onlineJob::rejectedByBank: return i18nc("Arg 1 is a date/time", "The bank rejected this job on %1.").arg(job.bankAnswerDate().toString(Qt::DefaultLocaleShortDate)); case onlineJob::noBankAnswer: if (job.sendDate().isValid()) return i18nc("Arg 1 is a date/time", "The bank accepted this job on %1.").arg(job.sendDate().toString(Qt::DefaultLocaleShortDate)); else if (!job.isValid()) return i18n("This job needs further editing and cannot be sent therefore."); else return i18n("This job is ready for sending."); } } return QVariant(); } else if (index.column() == columns::ColAction) { if (role == Qt::DisplayRole) return QVariant::fromValue(job.task()->jobTypeName()); return QVariant(); } // Show credit transfer data try { onlineJobTyped transfer(job); if (index.column() == columns::ColValue) { if (role == Qt::DisplayRole) return QVariant::fromValue(MyMoneyUtils::formatMoney(transfer.task()->value(), transfer.task()->currency())); } else if (index.column() == columns::ColDestination) { if (role == Qt::DisplayRole) { const payeeIdentifierTyped ibanBic(transfer.constTask()->beneficiary()); return QVariant(ibanBic->ownerName()); } } } catch (MyMoneyException&) { } catch (payeeIdentifier::exception&) { } return QVariant(); } void onlineJobModel::reloadAll() { emit dataChanged(index(rowCount() - 1, 0), index(rowCount() - 1, columnCount() - 1)); } /** * This method removes the rows from MyMoneyFile. */ bool onlineJobModel::removeRow(int row, const QModelIndex& parent) { if (parent.isValid()) return false; Q_ASSERT(m_jobIdList.count() < row); MyMoneyFile* file = MyMoneyFile::instance(); MyMoneyFileTransaction transaction; const onlineJob job = file->getOnlineJob(m_jobIdList[row]); file->removeOnlineJob(job); transaction.commit(); return true; } /** * This method removes the rows from MyMoneyFile. */ bool onlineJobModel::removeRows(int row, int count, const QModelIndex & parent) { if (parent.isValid()) return false; Q_ASSERT(m_jobIdList.count() > row); Q_ASSERT(m_jobIdList.count() >= (row + count)); MyMoneyFile* file = MyMoneyFile::instance(); MyMoneyFileTransaction transaction; for (int i = 0; i < count; ++i) { const onlineJob job = file->getOnlineJob(m_jobIdList[row+i]); file->removeOnlineJob(job); } transaction.commit(); return true; } void onlineJobModel::slotObjectAdded(MyMoneyFile::notificationObjectT objType, const MyMoneyObject * const obj) { if (Q_LIKELY(objType != MyMoneyFile::notifyOnlineJob)) return; beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_jobIdList.append(obj->id()); endInsertRows(); } void onlineJobModel::slotObjectModified(MyMoneyFile::notificationObjectT objType, const MyMoneyObject * const obj) { if (Q_LIKELY(objType != MyMoneyFile::notifyOnlineJob)) return; int row = m_jobIdList.indexOf(obj->id()); if (row != -1) emit dataChanged(index(row, 0), index(row, columnCount() - 1)); } void onlineJobModel::slotObjectRemoved(MyMoneyFile::notificationObjectT objType, const QString& id) { if (Q_LIKELY(objType != MyMoneyFile::notifyOnlineJob)) return; int row = m_jobIdList.indexOf(id); if (row != -1) { m_jobIdList.removeAll(id); beginRemoveRows(QModelIndex(), row, row); endRemoveRows(); } } diff --git a/kmymoney/models/onlinejobmodel.h b/kmymoney/models/onlinejobmodel.h index 873597faa..2387ee330 100644 --- a/kmymoney/models/onlinejobmodel.h +++ b/kmymoney/models/onlinejobmodel.h @@ -1,80 +1,80 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBMODEL_H #define ONLINEJOBMODEL_H #include #include #include "mymoney/mymoneyfile.h" class Models; class onlineJobModel : public QAbstractTableModel { Q_OBJECT public: /** * @brief Item Data roles for onlineJobs * In addition to Qt::ItemDataRole */ enum roles { OnlineJobId = Qt::UserRole, /**< QString of onlineJob.id() */ OnlineJobRole /**< the real onlineJob */ }; enum columns { ColAccount, ColAction, ColDestination, ColValue }; int rowCount(const QModelIndex & parent = QModelIndex()) const; int columnCount(const QModelIndex & parent = QModelIndex()) const; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; QVariant headerData(int section, Qt::Orientation orientation , int role = Qt::DisplayRole) const; /** @brief Remove onlineJob identified by row */ bool removeRow(int row, const QModelIndex & parent = QModelIndex()); /** @brief Remove onlineJobs identified by row and count */ bool removeRows(int row, int count, const QModelIndex & parent = QModelIndex()); signals: public slots: void reloadAll(); void slotObjectAdded(MyMoneyFile::notificationObjectT objType, const MyMoneyObject * const obj); void slotObjectModified(MyMoneyFile::notificationObjectT objType, const MyMoneyObject * const obj); void slotObjectRemoved(MyMoneyFile::notificationObjectT objType, const QString& id); /** @brief Load data from MyMoneyFile */ void load(); void unload(); protected: /** Only @ref Models should be able to construct this class */ explicit onlineJobModel(QObject *parent = 0); friend class Models; private: QStringList m_jobIdList; }; #endif // ONLINEJOBMODEL_H diff --git a/kmymoney/models/payeeidentifiercontainermodel.cpp b/kmymoney/models/payeeidentifiercontainermodel.cpp index e38443d7f..7c732ffb1 100644 --- a/kmymoney/models/payeeidentifiercontainermodel.cpp +++ b/kmymoney/models/payeeidentifiercontainermodel.cpp @@ -1,136 +1,136 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "payeeidentifiercontainermodel.h" #include "mymoney/mymoneyfile.h" #include "payeeidentifier/payeeidentifierloader.h" #include "payeeidentifier/payeeidentifier.h" #include #include payeeIdentifierContainerModel::payeeIdentifierContainerModel(QObject* parent) : QAbstractListModel(parent), m_data(QSharedPointer()) { } QVariant payeeIdentifierContainerModel::data(const QModelIndex& index, int role) const { // Needed for the selection box and it prevents a crash if index is out of range if (m_data.isNull() || index.row() >= rowCount(index.parent()) - 1) return QVariant(); const ::payeeIdentifier ident = m_data->payeeIdentifiers().at(index.row()); if (role == payeeIdentifier) { return QVariant::fromValue< ::payeeIdentifier >(ident); } else if (ident.isNull()) { return QVariant(); } else if (role == payeeIdentifierType) { return ident.iid(); } else if (role == Qt::DisplayRole) { // The custom delegates won't ask for this role return QVariant::fromValue(i18n("The plugin to show this information could not be found.")); } return QVariant(); } bool payeeIdentifierContainerModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!m_data.isNull() && role == payeeIdentifier) { ::payeeIdentifier ident = value.value< ::payeeIdentifier >(); if (index.row() == rowCount(index.parent()) - 1) { // The new row will be the last but one beginInsertRows(index.parent(), index.row() - 1, index.row() - 1); m_data->addPayeeIdentifier(ident); endInsertRows(); } else { m_data->modifyPayeeIdentifier(index.row(), ident); emit dataChanged(createIndex(index.row(), 0), createIndex(index.row(), 0)); } return true; } return QAbstractItemModel::setData(index, value, role); } Qt::ItemFlags payeeIdentifierContainerModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled; const QString type = data(index, payeeIdentifierType).toString(); // type.isEmpty() means the type selection can be shown if (!type.isEmpty() && payeeIdentifierLoader::instance()->hasItemEditDelegate(type)) flags |= Qt::ItemIsEditable; return flags; } int payeeIdentifierContainerModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent); if (m_data.isNull()) return 0; // Always a row more which creates new entries return m_data->payeeIdentifiers().count() + 1; } /** @brief unused at the moment */ bool payeeIdentifierContainerModel::insertRows(int row, int count, const QModelIndex& parent) { Q_UNUSED(row); Q_UNUSED(count); Q_UNUSED(parent); return false; } bool payeeIdentifierContainerModel::removeRows(int row, int count, const QModelIndex& parent) { if (m_data.isNull()) return false; if (count < 1 || row + count >= rowCount(parent)) return false; beginRemoveRows(parent, row, row + count - 1); for (int i = row; i < row + count; ++i) { m_data->removePayeeIdentifier(i); } endRemoveRows(); return true; } void payeeIdentifierContainerModel::setSource(const MyMoneyPayeeIdentifierContainer data) { beginResetModel(); m_data = QSharedPointer(new MyMoneyPayeeIdentifierContainer(data)); endResetModel(); } void payeeIdentifierContainerModel::closeSource() { beginResetModel(); m_data = QSharedPointer(); endResetModel(); } QList< ::payeeIdentifier > payeeIdentifierContainerModel::identifiers() const { if (m_data.isNull()) return QList< ::payeeIdentifier >(); return m_data->payeeIdentifiers(); } diff --git a/kmymoney/models/payeeidentifiercontainermodel.h b/kmymoney/models/payeeidentifiercontainermodel.h index f5035586b..a10d6d989 100644 --- a/kmymoney/models/payeeidentifiercontainermodel.h +++ b/kmymoney/models/payeeidentifiercontainermodel.h @@ -1,92 +1,92 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERCONTAINERMODEL_H #define PAYEEIDENTIFIERCONTAINERMODEL_H #include #include "mymoney/payeeidentifiermodel.h" #include "mymoney/mymoneypayeeidentifiercontainer.h" #include "payeeidentifier/payeeidentifier.h" /** * @brief Model for MyMoneyPayeeIdentifierContainer * * Changes the user does have initernal effect only. * * @see payeeIdentifierModel */ class payeeIdentifierContainerModel : public QAbstractListModel { Q_OBJECT public: /** * @brief Roles for this model * * They are equal to payeeIdentifierModel::roles */ enum roles { payeeIdentifierType = payeeIdentifierModel::payeeIdentifierType, /**< type of payeeIdentifier */ payeeIdentifier = payeeIdentifierModel::payeeIdentifier /**< actual payeeIdentifier */ }; payeeIdentifierContainerModel(QObject* parent = 0); virtual QVariant data(const QModelIndex& index, int role) const; /** * This model only supports to edit payeeIdentifier role with a QVariant of type * payeeIdentifier. */ virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual int rowCount(const QModelIndex& parent) const; virtual bool insertRows(int row, int count, const QModelIndex& parent); virtual bool removeRows(int row, int count, const QModelIndex& parent); /** * @brief Set source of data * * This makes the model editable. */ void setSource(MyMoneyPayeeIdentifierContainer data); /** @brief Get stored data */ QList< ::payeeIdentifier > identifiers() const; public slots: /** * @brief Removes all data from the model * * The model is not editable afterwards. */ void closeSource(); private: /** @internal * The use of a shared pointer makes this future prof. Because using identifier() causes * some unnecessary work. */ QSharedPointer m_data; }; #endif // PAYEEIDENTIFIERCONTAINERMODEL_H diff --git a/kmymoney/mymoney/mymoneypayeeidentifiercontainer.cpp b/kmymoney/mymoney/mymoneypayeeidentifiercontainer.cpp index abeea9e98..806dd5115 100644 --- a/kmymoney/mymoney/mymoneypayeeidentifiercontainer.cpp +++ b/kmymoney/mymoney/mymoneypayeeidentifiercontainer.cpp @@ -1,112 +1,112 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "mymoneypayeeidentifiercontainer.h" #include #include "payeeidentifier/payeeidentifierloader.h" MyMoneyPayeeIdentifierContainer::MyMoneyPayeeIdentifierContainer() : m_payeeIdentifiers(QList< ::payeeIdentifier >()) { } unsigned int MyMoneyPayeeIdentifierContainer::payeeIdentifierCount() const { return m_payeeIdentifiers.count(); } payeeIdentifier MyMoneyPayeeIdentifierContainer::payeeIdentifier(unsigned int index) const { return m_payeeIdentifiers.at(index); } QList MyMoneyPayeeIdentifierContainer::payeeIdentifiers() const { return m_payeeIdentifiers; } void MyMoneyPayeeIdentifierContainer::addPayeeIdentifier(const ::payeeIdentifier& ident) { m_payeeIdentifiers.append(ident); } void MyMoneyPayeeIdentifierContainer::addPayeeIdentifier(const unsigned int position, const ::payeeIdentifier& ident) { m_payeeIdentifiers.insert(position, ident); } void MyMoneyPayeeIdentifierContainer::removePayeeIdentifier(const ::payeeIdentifier& ident) { m_payeeIdentifiers.removeOne(ident); } void MyMoneyPayeeIdentifierContainer::removePayeeIdentifier(const int index) { Q_ASSERT(m_payeeIdentifiers.count() > index && index >= 0); m_payeeIdentifiers.removeAt(index); } void MyMoneyPayeeIdentifierContainer::modifyPayeeIdentifier(const ::payeeIdentifier& ident) { QList< ::payeeIdentifier >::Iterator end = m_payeeIdentifiers.end(); for (QList< ::payeeIdentifier >::Iterator iter = m_payeeIdentifiers.begin(); iter != end; ++iter) { if (iter->id() == ident.id()) { *iter = ident; return; } } } void MyMoneyPayeeIdentifierContainer::modifyPayeeIdentifier(const int index, const ::payeeIdentifier& ident) { Q_ASSERT(m_payeeIdentifiers.count() > index && index >= 0); m_payeeIdentifiers[index] = ident; } void MyMoneyPayeeIdentifierContainer::resetPayeeIdentifiers(const QList< ::payeeIdentifier >& list) { m_payeeIdentifiers = list; } void MyMoneyPayeeIdentifierContainer::loadXML(QDomElement node) { // Load identifiers QDomNodeList identifierNodes = node.elementsByTagName("payeeIdentifier"); const uint identifierNodesLength = identifierNodes.length(); for (uint i = 0; i < identifierNodesLength; ++i) { const QDomElement element = identifierNodes.item(i).toElement(); ::payeeIdentifier ident = payeeIdentifierLoader::instance()->createPayeeIdentifierFromXML(element); if (ident.isNull()) { qWarning() << "Could not load payee identifier" << element.attribute("type", "*no pidid set*"); continue; } addPayeeIdentifier(ident); } } void MyMoneyPayeeIdentifierContainer::writeXML(QDomDocument document, QDomElement parent) const { // Add payee identifiers foreach (const ::payeeIdentifier& ident, m_payeeIdentifiers) { if (!ident.isNull()) { ident.writeXML(document, parent); } } } diff --git a/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h b/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h index ccf023173..0c9538450 100644 --- a/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h +++ b/kmymoney/mymoney/mymoneypayeeidentifiercontainer.h @@ -1,77 +1,77 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MYMONEYPAYEEIDENTIFIERCONTAINER_H #define MYMONEYPAYEEIDENTIFIERCONTAINER_H #include "kmm_mymoney_export.h" #include #include #include #include "payeeidentifier/payeeidentifier.h" #include "payeeidentifier/payeeidentifiertyped.h" /** * * * @internal payeeIdentifiers should get their own id. So they can be created as all other MyMoneyObjects. * But adding a MyMoneyObject to MyMoneyFile and its storage backends is so time-consuming, * I won't do that - sorry. So all payeeIdentifiers have to be created when a MyMoneyPayeeIdentifierContainer * is loaded. Optimal would be if they are only created if needed (which won't be often). */ class KMM_MYMONEY_EXPORT MyMoneyPayeeIdentifierContainer { public: MyMoneyPayeeIdentifierContainer(); unsigned int payeeIdentifierCount() const; ::payeeIdentifier payeeIdentifier(unsigned int) const; QList< ::payeeIdentifier > payeeIdentifiers() const; template< class type > QList< ::payeeIdentifierTyped > payeeIdentifiersByType() const; void addPayeeIdentifier(const ::payeeIdentifier& ident); void addPayeeIdentifier(const unsigned int position, const ::payeeIdentifier& ident); void removePayeeIdentifier(const ::payeeIdentifier& ident); void removePayeeIdentifier(const int index); void modifyPayeeIdentifier(const ::payeeIdentifier& ident); void modifyPayeeIdentifier(const int index, const ::payeeIdentifier& ident); void resetPayeeIdentifiers(const QList< ::payeeIdentifier >& list = QList< ::payeeIdentifier >()); protected: void loadXML(QDomElement node); void writeXML(QDomDocument document, QDomElement parent) const; private: QList< ::payeeIdentifier > m_payeeIdentifiers; }; template< class type > QList< payeeIdentifierTyped > MyMoneyPayeeIdentifierContainer::payeeIdentifiersByType() const { QList< payeeIdentifierTyped > typedList; return typedList; } #endif // MYMONEYPAYEEIDENTIFIERCONTAINER_H diff --git a/kmymoney/mymoney/onlinejob.cpp b/kmymoney/mymoney/onlinejob.cpp index e2b450019..0f7ab2ea6 100644 --- a/kmymoney/mymoney/onlinejob.cpp +++ b/kmymoney/mymoney/onlinejob.cpp @@ -1,280 +1,280 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "onlinejob.h" #include "mymoneyfile.h" #include "mymoneyexception.h" #include "onlinetasks/interfaces/tasks/credittransfer.h" #include "onlinejobadministration.h" #include "mymoneystoragenames.h" using namespace MyMoneyStorageNodes; onlineJob::onlineJob() : MyMoneyObject(), m_task(0), m_jobSend(QDateTime()), m_jobBankAnswerDate(QDateTime()), m_jobBankAnswerState(noBankAnswer), m_messageList(QList()), m_locked(false) { } onlineJob::onlineJob(onlineTask* task, const QString &id) : MyMoneyObject(id), m_task(task), m_jobSend(QDateTime()), m_jobBankAnswerDate(QDateTime()), m_jobBankAnswerState(noBankAnswer), m_messageList(QList()), m_locked(false) { } onlineJob::onlineJob(onlineJob const& other) : MyMoneyObject(other.id()), m_task(0), m_jobSend(other.m_jobSend), m_jobBankAnswerDate(other.m_jobBankAnswerDate), m_jobBankAnswerState(other.m_jobBankAnswerState), m_messageList(other.m_messageList), m_locked(other.m_locked) { copyPointerFromOtherJob(other); } onlineJob::onlineJob(const QString &id, const onlineJob& other) : MyMoneyObject(id), m_task(), m_jobSend(QDateTime()), m_jobBankAnswerDate(QDateTime()), m_jobBankAnswerState(noBankAnswer), m_messageList(QList()), m_locked(false) { copyPointerFromOtherJob(other); } onlineJob::onlineJob(const QDomElement& element) : MyMoneyObject(element, true), m_messageList(QList()), m_locked(false) { m_jobSend = QDateTime::fromString(element.attribute(getAttrName(anSend)), Qt::ISODate); m_jobBankAnswerDate = QDateTime::fromString(element.attribute(getAttrName(anBankAnswerDate)), Qt::ISODate); QString state = element.attribute(getAttrName(anBankAnswerState)); if (state == getAttrName(anAbortedByUser)) m_jobBankAnswerState = abortedByUser; else if (state == getAttrName(anAcceptedByBank)) m_jobBankAnswerState = acceptedByBank; else if (state == getAttrName(anRejectedByBank)) m_jobBankAnswerState = rejectedByBank; else if (state == getAttrName(anSendingError)) m_jobBankAnswerState = sendingError; else m_jobBankAnswerState = noBankAnswer; QDomElement taskElem = element.firstChildElement(getElName(enOnlineTask)); m_task = onlineJobAdministration::instance()->createOnlineTaskByXml(taskElem.attribute(getAttrName(anIID)), taskElem); } void onlineJob::copyPointerFromOtherJob(const onlineJob &other) { if (!other.isNull()) m_task = other.constTask()->clone(); } onlineJob onlineJob::operator = (const onlineJob & other) { if (this == &other) return *this; delete m_task; m_id = other.m_id; m_jobSend = other.m_jobSend; m_jobBankAnswerDate = other.m_jobBankAnswerDate; m_jobBankAnswerState = other.m_jobBankAnswerState; m_messageList = other.m_messageList; m_locked = other.m_locked; copyPointerFromOtherJob(other); return *this; } void onlineJob::reset() { clearId(); m_jobSend = QDateTime(); m_jobBankAnswerDate = QDateTime(); m_jobBankAnswerState = noBankAnswer; m_locked = false; } onlineJob::~onlineJob() { delete m_task; } onlineTask* onlineJob::task() { if (m_task == 0) throw emptyTask(__FILE__, __LINE__); return m_task; } const onlineTask* onlineJob::task() const { if (m_task == 0) throw emptyTask(__FILE__, __LINE__); return m_task; } QString onlineJob::taskIid() const { try { return task()->taskName(); } catch (const emptyTask&) { } return QString(); } QString onlineJob::responsibleAccount() const { try { return task()->responsibleAccount(); } catch (const emptyTask&) { } return QString(); } MyMoneyAccount onlineJob::responsibleMyMoneyAccount() const { QString accountId = responsibleAccount(); if (!accountId.isEmpty()) return MyMoneyFile::instance()->account(accountId); return MyMoneyAccount(); } bool onlineJob::setLock(bool enable) { m_locked = enable; return true; } bool onlineJob::isEditable() const { return (!isLocked() && sendDate().isNull() && (m_jobBankAnswerState == noBankAnswer || m_jobBankAnswerState == sendingError)); } void onlineJob::setJobSend(const QDateTime &dateTime) { m_jobSend = dateTime; } void onlineJob::setBankAnswer(const sendingState sendingState, const QDateTime &dateTime) { m_jobBankAnswerState = sendingState; m_jobBankAnswerDate = dateTime; } void onlineJob::addJobMessage(const onlineJobMessage& message) { m_messageList.append(message); } void onlineJob::addJobMessage(const onlineJobMessage::messageType& type, const QString& sender, const QString& message, const QString& errorCode, const QDateTime& timestamp) { onlineJobMessage logMessage(type, sender, message, timestamp); logMessage.setSenderErrorCode(errorCode); m_messageList.append(logMessage); } QList onlineJob::jobMessageList() const { return m_messageList; } /** @todo give life */ void onlineJob::writeXML(QDomDocument &document, QDomElement &parent) const { QDomElement el = document.createElement(nodeNames[nnOnlineJob]); writeBaseXML(document, el); if (!m_jobSend.isNull()) el.setAttribute(getAttrName(anSend), m_jobSend.toString(Qt::ISODate)); if (!m_jobBankAnswerDate.isNull()) el.setAttribute(getAttrName(anBankAnswerDate), m_jobBankAnswerDate.toString(Qt::ISODate)); switch (m_jobBankAnswerState) { case abortedByUser: el.setAttribute(getAttrName(anBankAnswerState), getAttrName(anAbortedByUser)); break; case acceptedByBank: el.setAttribute(getAttrName(anBankAnswerState), getAttrName(anAcceptedByBank)); break; case rejectedByBank: el.setAttribute(getAttrName(anBankAnswerState), getAttrName(anRejectedByBank)); break; case sendingError: el.setAttribute(getAttrName(anBankAnswerState), getAttrName(anSendingError)); break; case noBankAnswer: default: void(); } QDomElement taskEl = document.createElement(getElName(enOnlineTask)); taskEl.setAttribute(getAttrName(anIID), taskIid()); try { task()->writeXML(document, taskEl); // throws execption if there is no task el.appendChild(taskEl); // only append child if there is something to append } catch (const emptyTask&) { } parent.appendChild(el); } bool onlineJob::isValid() const { if (m_task != 0) return m_task->isValid(); return false; } bool onlineJob::hasReferenceTo(const QString& id) const { if (m_task != 0) return m_task->hasReferenceTo(id); return false; } const QString onlineJob::getElName(const elNameE _el) { static const QMap elNames = { {enOnlineTask, QStringLiteral("onlineTask")} }; return elNames[_el]; } const QString onlineJob::getAttrName(const attrNameE _attr) { static const QHash attrNames = { {anSend, QStringLiteral("send")}, {anBankAnswerDate, QStringLiteral("bankAnswerDate")}, {anBankAnswerState, QStringLiteral("bankAnswerState")}, {anIID, QStringLiteral("iid")}, {anAbortedByUser, QStringLiteral("abortedByUser")}, {anAcceptedByBank, QStringLiteral("acceptedByBank")}, {anRejectedByBank, QStringLiteral("rejectedByBank")}, {anSendingError, QStringLiteral("sendingError")}, }; return attrNames[_attr]; } diff --git a/kmymoney/mymoney/onlinejob.h b/kmymoney/mymoney/onlinejob.h index 1a7cd4d42..ecf9eaf1f 100644 --- a/kmymoney/mymoney/onlinejob.h +++ b/kmymoney/mymoney/onlinejob.h @@ -1,380 +1,380 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ONLINEJOB_H #define ONLINEJOB_H #include "mymoneyobject.h" #include "mymoneyaccount.h" #include "mymoneyexception.h" #include "onlinejobmessage.h" class onlineTask; /** * @brief Class to share jobs which can be procceded by an online banking plugin * * This class stores only the status information and a pointer to an @r onlineTask which stores * the real data. So onlineJob is similar to an shared pointer. * * If you know the type of the onlineTask, @r onlineJobTyped is the first choice to use. * * It is save to use because accesses to pointers (e.g. task() ) throw an execption if onlineJob is null. * * Online jobs are usually not created directly but over @r onlineJobAdministration::createOnlineJob. This is * required to allow loading of onlineTasks at runtime and only if needed. * * This class was created to help writing stable and reliable code. Before an unsafe structure (= pointer) * is accessed it is checked. Exceptions are thrown if the content is unsafe. * * @see onlineTask * @see onlineJobTyped * @todo LOW make data implicitly shared */ class KMM_MYMONEY_EXPORT onlineJob : public MyMoneyObject { Q_GADGET KMM_MYMONEY_UNIT_TESTABLE public: enum elNameE { enOnlineTask }; Q_ENUM(elNameE) enum attrNameE { anSend, anBankAnswerDate, anBankAnswerState, anIID, anAbortedByUser, anAcceptedByBank, anRejectedByBank, anSendingError }; Q_ENUM(attrNameE) /** * @brief Contructor for null onlineJobs * * A onlineJob which is null cannot become valid again. * @see isNull() */ onlineJob(); /** * @brief Default construtor * * The onlineJob takes ownership of the task. The task is deleted in the destructor. */ onlineJob(onlineTask* task, const QString& id = MyMoneyObject::m_emptyId); /** @brief Copy constructor */ onlineJob(onlineJob const& other); /** * @brief Create new onlineJob as copy of other * * This constructor does not copy the status information but the task only. */ onlineJob(const QString &id, const onlineJob& other); /** @brief Contruct from xml */ onlineJob(const QDomElement&); virtual ~onlineJob(); /** * @brief Returns task attached to this onlineJob * * You should not store this pointer but use onlineJob::task() (or @r onlineJobTyped::task()) * every time you access it. * * @note The return type may change in future (e.g. to an atomic pointer). But you can always expect * the operator @c -> to work like it does for onlineTask*. * * @throws emptyTask if isNull() */ onlineTask* task(); /** @copydoc task(); */ const onlineTask* task() const; /** * @brief Returns task attached to this onlineJob as const * @throws emptyTask if isNull() */ const onlineTask* constTask() const { return task(); } /** * @brief Returns task of type T attached to this onlineJob * * Internaly a dynamic_cast is done and the result is checked. * * @throws emptyTask if isNull() * @throws badTaskCast if attached task cannot be casted to T */ template T* task(); /** @copydoc task() */ template const T* task() const; template const T* constTask() const { return task(); } template bool canTaskCast() const; QString taskIid() const; /** @todo implement */ virtual bool hasReferenceTo(const QString &id) const; virtual void writeXML(QDomDocument &document, QDomElement &parent) const; /** * @brief The state of a job given by the onlinePlugin */ enum sendingState { noBankAnswer, /**< Used during or before sending or if sendDate().isValid() the job was successfully sent */ acceptedByBank, /**< bank definetly confirmed the job */ rejectedByBank, /**< bank definetly rejected this job */ abortedByUser, /**< aborted by user during sending */ sendingError /**< an error occurred, the job is certainly not executed by the bank */ }; /** * @brief Account this job is related to * * Each job must have an account on which the job operates. This is used to determine * the correct onlinePlugin which can execute this job. If the job is related to more * than one account (e.g. a password change) select a random one. * * @return accountId or QString() if none is set or job isNull. */ virtual QString responsibleAccount() const; /** * @brief Returns the MyMoneyAccount this job is related to * @see responsibleAccount() */ MyMoneyAccount responsibleMyMoneyAccount() const; /** * @brief Check if this onlineJob is editable by the user * * A job is no longer editable by the user if it is used for documentary purposes * e.g. the job was sent to the bank. In that case create a new job based on the * old one. * * @todo make it possible to use onlineJobs as templates */ virtual bool isEditable() const; /** * @brief Checks if this onlineJob has an attached task * * @return true if no task is attached to this job */ virtual bool isNull() const { return (m_task == 0); } /** * @brief Checks if an valid onlineTask is attached * * @return true if task().isValid(), false if isNull() or !task.isValid() */ virtual bool isValid() const; /** * @brief DateTime the job was sent to the bank * * A valid return does not mean that this job was accepted by the bank. * * @return A valid QDateTime if send to bank, an QDateTime() if not send. */ virtual QDateTime sendDate() const { return m_jobSend; } /** * @brief Mark this job as send * * To be used by online plugin only! * * Set dateTime to QDateTime to mark unsend. */ virtual void setJobSend(const QDateTime &dateTime = QDateTime::currentDateTime()); /** * @brief The bank's answer to this job * * To be used by online plugin only! * * Set dateTime to QDateTime() and bankAnswer to noState to mark unsend. If bankAnswer == noState dateTime.isNull() must be true! */ void setBankAnswer(const sendingState sendingState, const QDateTime &dateTime = QDateTime::currentDateTime()); /** * @brief DateTime of the last status update by the bank * */ QDateTime bankAnswerDate() const { return m_jobBankAnswerDate; } /** * @brief Returns last status sand by bank * @return */ sendingState bankAnswerState() const { return m_jobBankAnswerState; } /** * @brief locks the onlineJob for sending it * * Used when the job is in sending process by the online plugin. * * A locked onlineJob cannot be removed from the storage. * * @note The onlineJob can still be edited and stored. But it should be done by * the one how owns the lock only. * * @todo Enforce the lock somehow? Note: the onlinePlugin must still be able to * write to the job. * * @param enable true locks the job, false unlocks the job */ virtual bool setLock(bool enable = true); /** * @brief Get lock status */ virtual bool isLocked() const { return m_locked; } /** * @brief Make this onlineJob a "new" onlineJob * * Removes all status information, log, and the id. Only * the task is keept. */ virtual void reset(); /** * @brief addJobMessage * * To be used by online plugin only. * @param message */ virtual void addJobMessage(const onlineJobMessage &message); /** * @brief Convenient method to set add a log message */ virtual void addJobMessage(const onlineJobMessage::messageType& type, const QString& sender, const QString& message, const QString& errorCode = QString(), const QDateTime& timestamp = QDateTime::currentDateTime()); /** * @brief jobMessageList * @return */ virtual QList jobMessageList() const; onlineJob operator =(const onlineJob&); /** * @brief Thrown if a cast of a task fails * * This is inspired by std::bad_cast */ class badTaskCast : public MyMoneyException { public: badTaskCast(const QString& file = "", const long unsigned int& line = 0) : MyMoneyException("Casted onlineTask with wrong type", file, line) {} }; /** * @brief Thrown if a task of an invalid onlineJob is requested */ class emptyTask : public MyMoneyException { public: emptyTask(const QString& file = "", const long unsigned int& line = 0) : MyMoneyException("Requested onlineTask of onlineJob without any task", file, line) {} }; /** @brief onlineTask attatched to this job */ onlineTask* m_task; private: /** * @brief Date-time the job was sent to the bank * * This does not mean an answer was given by the bank */ QDateTime m_jobSend; /** * @brief Date-time of confirmation/rejection of the bank * * which state this timestamp belongs to is stored in m_jobBankAnswerState */ QDateTime m_jobBankAnswerDate; /** * @brief Answer of the bank * * combined with m_jobBankAnswerDate */ sendingState m_jobBankAnswerState; /** * @brief Validation result status */ QList m_messageList; /** * @brief Locking state */ bool m_locked; /** @brief Copies stored pointers (used by copy constructors) */ inline void copyPointerFromOtherJob(const onlineJob& other); static const QString getElName(const elNameE _el); static const QString getAttrName(const attrNameE _attr); }; template T* onlineJob::task() { T* ret = dynamic_cast(m_task); if (ret == 0) throw badTaskCast(__FILE__, __LINE__); return ret; } template const T* onlineJob::task() const { const T* ret = dynamic_cast(m_task); if (ret == 0) throw badTaskCast(__FILE__, __LINE__); return ret; } Q_DECLARE_METATYPE(onlineJob) #endif // ONLINEJOB_H diff --git a/kmymoney/mymoney/onlinejobadministration.cpp b/kmymoney/mymoney/onlinejobadministration.cpp index 93ce4eb6d..b959af1a9 100644 --- a/kmymoney/mymoney/onlinejobadministration.cpp +++ b/kmymoney/mymoney/onlinejobadministration.cpp @@ -1,410 +1,410 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobadministration.h" // ---------------------------------------------------------------------------- // Std Includes #include // ---------------------------------------------------------------------------- // QT Includes #include #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include #include // ---------------------------------------------------------------------------- // Project Includes #include "mymoney/mymoneyfile.h" #include "mymoney/mymoneyaccount.h" #include "mymoney/mymoneykeyvaluecontainer.h" #include "plugins/onlinepluginextended.h" #include "onlinetasks/unavailabletask/tasks/unavailabletask.h" #include "onlinetasks/interfaces/tasks/credittransfer.h" onlineJobAdministration::onlineJobAdministration(QObject *parent) : QObject(parent) { } onlineJobAdministration::~onlineJobAdministration() { clearCaches(); } void onlineJobAdministration::clearCaches() { qDeleteAll(m_onlineTasks); m_onlineTasks.clear(); qDeleteAll(m_onlineTaskConverter); m_onlineTaskConverter.clear(); } KMyMoneyPlugin::OnlinePluginExtended* onlineJobAdministration::getOnlinePlugin(const QString& accountId) const { MyMoneyAccount acc = MyMoneyFile::instance()->account(accountId); QMap::const_iterator it_p; it_p = m_onlinePlugins.constFind(acc.onlineBankingSettings().value("provider")); if (it_p != m_onlinePlugins.constEnd()) { // plugin found, use it return *it_p; } return 0; } void onlineJobAdministration::addPlugin(const QString& pluginName, KMyMoneyPlugin::OnlinePluginExtended *plugin) { const bool sendAnyTask = canSendAnyTask(); const bool sendCreditTransfer = canSendCreditTransfer(); m_onlinePlugins.insert(pluginName, plugin); if (!sendAnyTask && canSendAnyTask()) emit canSendAnyTaskChanged(true); if (!sendCreditTransfer && canSendCreditTransfer()) emit canSendCreditTransferChanged(true); } QStringList onlineJobAdministration::availableOnlineTasks() { auto plugins = KPluginLoader::findPlugins("kmymoney", [](const KPluginMetaData& data) { return !(data.rawData()["KMyMoney"].toObject()["OnlineTask"].isNull()); }); QStringList list; for(const KPluginMetaData& plugin: plugins) { QJsonValue array = plugin.rawData()["KMyMoney"].toObject()["OnlineTask"].toObject()["Iid"]; if (array.isArray()) list.append(array.toVariant().toStringList()); } return list; } /** * @internal The real work is done here. */ bool onlineJobAdministration::isJobSupported(const QString& accountId, const QString& name) const { foreach (KMyMoneyPlugin::OnlinePluginExtended* plugin, m_onlinePlugins) { if (plugin->availableJobs(accountId).contains(name)) return true; } return false; } bool onlineJobAdministration::isJobSupported(const QString& accountId, const QStringList& names) const { foreach (QString name, names) { if (isJobSupported(accountId, name)) return true; } return false; } bool onlineJobAdministration::isAnyJobSupported(const QString& accountId) const { if (accountId.isEmpty()) return false; foreach (KMyMoneyPlugin::OnlinePluginExtended* plugin, m_onlinePlugins) { if (!(plugin->availableJobs(accountId).isEmpty())) return true; } return false; } onlineJob onlineJobAdministration::createOnlineJob(const QString& name, const QString& id) const { return (onlineJob(createOnlineTask(name), id)); } onlineTask* onlineJobAdministration::createOnlineTask(const QString& name) const { const onlineTask* task = rootOnlineTask(name); if (task != 0) return task->clone(); return 0; } onlineTask* onlineJobAdministration::createOnlineTaskByXml(const QString& iid, const QDomElement& element) const { onlineTask* task = rootOnlineTask(iid); if (task != 0) { return task->createFromXml(element); } qWarning("In the file is a onlineTask for which I could not find the plugin ('%s')", qPrintable(iid)); return new unavailableTask(element); } onlineTask* onlineJobAdministration::createOnlineTaskFromSqlDatabase(const QString& iid, const QString& onlineTaskId, QSqlDatabase connection) const { onlineTask* task = rootOnlineTask(iid); if (task != 0) return task->createFromSqlDatabase(connection, onlineTaskId); qWarning("In the file is a onlineTask for which I could not find the plugin ('%s')", qPrintable(iid)); return 0; } /** * @interanl Using KPluginFactory to create the plugins seemed to be good idea. The drawback is that it does not support to create non QObjects directly. * This made this function way longer than needed and adds many checks. * * @fixme Delete created tasks */ onlineTask* onlineJobAdministration::rootOnlineTask(const QString& name) const { auto plugins = KPluginLoader::findPlugins("kmymoney", [&name](const KPluginMetaData& data) { QJsonValue array = data.rawData()["KMyMoney"].toObject()["OnlineTask"].toObject()["Iids"]; if (array.isArray()) return (array.toVariant().toStringList().contains(name)); return false; }); if (plugins.isEmpty()) return nullptr; if (plugins.length() != 1) qWarning() << "Multiple plugins which offer the online task \"" << name << "\" were found. Loading a random one."; // Load plugin std::unique_ptr loader = std::unique_ptr(new QPluginLoader{plugins.first().fileName()}); QObject* plugin = loader->instance(); if (!plugin) { qWarning() << "Could not load plugin for online task \"" << name << "\", file name \"" << plugins.first().fileName() << "\"."; return nullptr; } // Cast to KPluginFactory KPluginFactory* pluginFactory = qobject_cast< KPluginFactory* >(plugin); if (!pluginFactory) { qWarning() << "Could not create plugin factory for online task \"" << name << "\", file name \"" << plugins.first().fileName() << "\"."; return nullptr; } // Create onlineTaskFactory const QString pluginKeyword = plugins.first().rawData()["KMyMoney"].toObject()["OnlineTask"].toObject()["PluginKeyword"].toString(); // Can create only objects which inherit from QObject directly QObject* taskFactoryObject = pluginFactory->create(pluginKeyword, onlineJobAdministration::instance()); KMyMoneyPlugin::onlineTaskFactory* taskFactory = qobject_cast< KMyMoneyPlugin::onlineTaskFactory* >(taskFactoryObject); if (!taskFactory) { qWarning() << "Could not create online task factory for online task \"" << name << "\", file name \"" << plugins.first().fileName() << "\"."; return nullptr; } // Finally create task onlineTask* task = taskFactory->createOnlineTask(name); if (task) // Add to our cache as this is still used in several places onlineJobAdministration::instance()->registerOnlineTask(taskFactory->createOnlineTask(name)); return task; } onlineTaskConverter::convertType onlineJobAdministration::canConvert(const QString& originalTaskIid, const QString& convertTaskIid) const { return canConvert(originalTaskIid, QStringList(convertTaskIid)); } onlineTaskConverter::convertType onlineJobAdministration::canConvert(const QString& originalTaskIid, const QStringList& convertTaskIids) const { Q_ASSERT(false); //! @todo Make alive onlineTaskConverter::convertType bestConvertType = onlineTaskConverter::convertImpossible; #if 0 foreach (QString destinationName, destinationNames) { onlineTask::convertType type = canConvert(original, destinationName); if (type == onlineTask::convertionLossy) bestConvertType = onlineTask::convertionLossy; else if (type == onlineTask::convertionLoseless) return onlineTask::convertionLoseless; } #else Q_UNUSED(originalTaskIid); Q_UNUSED(convertTaskIids); #endif return bestConvertType; } /** * @todo if more than one converter offers the convert, use best */ onlineJob onlineJobAdministration::convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const { onlineJob newJob; QList converterList = m_onlineTaskConverter.values(convertTaskIid); foreach (onlineTaskConverter* converter, converterList) { if (converter->convertibleTasks().contains(original.taskIid())) { onlineTask* task = converter->convert(*original.task(), convertType, userInformation); Q_ASSERT_X(convertType != onlineTaskConverter::convertImpossible || task != 0, qPrintable("converter for " + converter->convertedTask()), "Converter returned convertType 'impossible' but return was not null_ptr."); if (task != 0) { newJob = onlineJob(task, onlineJobId); break; } } } return newJob; } onlineJob onlineJobAdministration::convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& convertType, QString& userInformation) const { return convertBest(original, convertTaskIids, convertType, userInformation, original.id()); } onlineJob onlineJobAdministration::convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& bestConvertType, QString& bestUserInformation, const QString& onlineJobId) const { onlineJob bestConvert; bestConvertType = onlineTaskConverter::convertImpossible; bestUserInformation = QString(); foreach (QString taskIid, convertTaskIids) { // Try convert onlineTaskConverter::convertType convertType = onlineTaskConverter::convertImpossible; QString userInformation; onlineJob convertJob = convert(original, taskIid, convertType, userInformation, onlineJobId); // Check if it was successful if (bestConvertType < convertType) { bestConvert = convertJob; bestUserInformation = userInformation; bestConvertType = convertType; if (convertType == onlineTaskConverter::convertionLoseless) break; } } return bestConvert; } void onlineJobAdministration::registerOnlineTask(onlineTask *const task) { if (Q_UNLIKELY(task == 0)) return; const bool sendAnyTask = canSendAnyTask(); const bool sendCreditTransfer = canSendCreditTransfer(); m_onlineTasks.insert(task->taskName(), task); qDebug() << "onlineTask available" << task->taskName(); if (sendAnyTask != canSendAnyTask()) emit canSendAnyTaskChanged(!sendAnyTask); if (sendCreditTransfer != canSendCreditTransfer()) emit canSendCreditTransferChanged(!sendCreditTransfer); } void onlineJobAdministration::registerOnlineTaskConverter(onlineTaskConverter* const converter) { if (Q_UNLIKELY(converter == 0)) return; m_onlineTaskConverter.insertMulti(converter->convertedTask(), converter); qDebug() << "onlineTaskConverter available" << converter->convertedTask() << converter->convertibleTasks(); } onlineJobAdministration::onlineJobEditOffers onlineJobAdministration::onlineJobEdits() { auto plugins = KPluginLoader::findPlugins("kmymoney", [](const KPluginMetaData& data) { return !(data.rawData()["KMyMoney"].toObject()["OnlineTask"].toObject()["Editors"].isNull()); }); onlineJobAdministration::onlineJobEditOffers list; list.reserve(plugins.size()); for(const KPluginMetaData& data: plugins) { QJsonArray editorsArray = data.rawData()["KMyMoney"].toObject()["OnlineTask"].toObject()["Editors"].toArray(); for(QJsonValue entry: editorsArray) { if (!entry.toObject()["OnlineTaskIds"].isNull()) { list.append(onlineJobAdministration::onlineJobEditOffer{ data.fileName(), entry.toObject()["PluginKeyword"].toString(), KPluginMetaData::readTranslatedString(entry.toObject(), "Name") }); } } } return list; } IonlineTaskSettings::ptr onlineJobAdministration::taskSettings(const QString& taskName, const QString& accountId) const { KMyMoneyPlugin::OnlinePluginExtended* plugin = getOnlinePlugin(accountId); if (plugin != 0) return (plugin->settings(accountId, taskName)); return IonlineTaskSettings::ptr(); } bool onlineJobAdministration::canSendAnyTask() { // Check if any plugin supports a loaded online task foreach (KMyMoneyPlugin::OnlinePluginExtended* plugin, m_onlinePlugins) { QList accounts; MyMoneyFile::instance()->accountList(accounts, QStringList(), true); foreach (MyMoneyAccount account, accounts) { foreach (QString onlineTaskIid, plugin->availableJobs(account.id())) { if (m_onlineTasks.contains(onlineTaskIid)) return true; } } } return false; } bool onlineJobAdministration::canSendCreditTransfer() { foreach (onlineTask* task, m_onlineTasks) { // Check if a online task has the correct type if (dynamic_cast(task) != 0) { foreach (KMyMoneyPlugin::OnlinePluginExtended* plugin, m_onlinePlugins) { QList accounts; MyMoneyFile::instance()->accountList(accounts, QStringList(), true); foreach (MyMoneyAccount account, accounts) { if (plugin->availableJobs(account.id()).contains(task->taskName())) return true; } } } } return false; } //! @fixme plugin query bool onlineJobAdministration::canEditOnlineJob(const onlineJob& job) { return (!job.taskIid().isEmpty() && !KServiceTypeTrader::self()->query(QLatin1String("KMyMoney/OnlineTaskUi"), QString("'%1' ~in [X-KMyMoney-onlineTaskIds]").arg(job.taskIid())).isEmpty()); } void onlineJobAdministration::updateOnlineTaskProperties() { emit canSendAnyTaskChanged(canSendAnyTask()); emit canSendCreditTransferChanged(canSendCreditTransfer()); } diff --git a/kmymoney/mymoney/onlinejobadministration.h b/kmymoney/mymoney/onlinejobadministration.h index 577909ae2..812cd98cb 100644 --- a/kmymoney/mymoney/onlinejobadministration.h +++ b/kmymoney/mymoney/onlinejobadministration.h @@ -1,343 +1,343 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBADMINISTRATION_H #define ONLINEJOBADMINISTRATION_H // ---------------------------------------------------------------------------- // QT Includes #include #include #include // ---------------------------------------------------------------------------- // KDE Includes #include // ---------------------------------------------------------------------------- // Project Includes #include "onlinejob.h" #include "onlinetasks/interfaces/tasks/onlinetask.h" #include "onlinetasks/interfaces/tasks/ionlinetasksettings.h" #include "onlinetasks/interfaces/converter/onlinetaskconverter.h" class IonlineJobEdit; namespace KMyMoneyPlugin { class OnlinePluginExtended; } /** * @brief Connection between KMyMoney and the plugins * * It's main task is the communication with plugins * and caching their information during run-time. During * sending this class selects the correct plugin for each * onlineJob. * * This class keeps an overview which account can handle which job and * offers methods to access these information. * * onlineJobAdministration is created with singleton pattern. Get the * instance with @ref onlineJobAdministration::instance() . */ class KMM_MYMONEY_EXPORT onlineJobAdministration : public QObject { Q_OBJECT KMM_MYMONEY_UNIT_TESTABLE Q_PROPERTY(bool canSendAnyTask READ canSendAnyTask NOTIFY canSendAnyTaskChanged STORED false); Q_PROPERTY(bool canSendCreditTransfer READ canSendCreditTransfer NOTIFY canSendCreditTransferChanged STORED false); public: explicit onlineJobAdministration(QObject *parent = 0); ~onlineJobAdministration(); struct onlineJobEditOffer { QString fileName; QString pluginKeyword; QString name; }; using onlineJobEditOffers = QVector; /** * @brief List all available onlineTasks */ QStringList availableOnlineTasks(); static onlineJobAdministration* instance() { static onlineJobAdministration m_instance; return &m_instance; } /** @brief clear the internal caches for shutdown */ void clearCaches(); /** @brief Use onlineTask::name() to create a corresponding onlineJob */ onlineJob createOnlineJob(const QString& name, const QString& id = MyMoneyObject::emptyId()) const; /** * @brief Return list of IonlineJobEdits * * Method is temporary! * * @return I stay owner of all pointers. */ onlineJobEditOffers onlineJobEdits(); QString onlineJobEditName(onlineJobEditOffer); bool isJobSupported(const QString& accountId, const QString& name) const; bool isJobSupported(const QString& accountId, const QStringList& names) const; bool isAnyJobSupported(const QString& accountId) const; onlineTaskConverter::convertType canConvert(const QString& originalTaskIid, const QString& convertTaskIid) const; onlineTaskConverter::convertType canConvert(const QString& originalTaskIid, const QStringList& convertTaskIids) const; #if 0 template onlineJobTyped convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const; template onlineJobTyped convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const; #endif /** * @brief Convert an onlineTask to another type * * @param original onlineJob to convert * @param convertTaskIid onlineTask iid you want to convert into * @param convertType OUT result of conversion. Note: this depends on original * @param userInformation OUT A translated html-string with information about the changes which were done * @param onlineJobId The id of the new onlineJob, if none is given original.id() is used */ onlineJob convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const; /** * @copydoc convert() */ onlineJob convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const; /** * @brief Converts a onlineTask to best fitting type of a set of onlineTasks * * Will look for best conversion possible from original to any of convertTaskIids. * * @param original onlineJob to convert * @param convertTaskIids onlineTask-iids you want to convert into. * @param convertType OUT result of conversion. Note: this depends on original * @param userInformation OUT A translated html-string with information about the changes which were done * @param onlineJobId The id of the new onlineJob, if none is given original.id() is used */ onlineJob convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const; /** * @brief Convinient for convertBest() which crates an onlineJob with the same id as original. */ onlineJob convertBest(const onlineJob& original, const QStringList& convertTaskIids, onlineTaskConverter::convertType& convertType, QString& userInformation) const; /** * @brief Request onlineTask::settings from plugin * * @return QSharedPointer to settings from plugin, can be a nullptr */ template QSharedPointer taskSettings(const QString& taskId, const QString& accountId) const; /** * @brief Request onlineTask::settings from plugin * * @see onlineTask::settings * * @param taskId onlineTask::name() * @param accountId MyMoneyAccount.id() * @return QSharedPointer to settings. QSharedPointer::isNull() is true if an error occurs * (e.g. plugin does not support the task). */ QSharedPointer taskSettings(const QString& taskId, const QString& accountId) const; /** * @brief Check if the onlineTask system can do anything * * This is true if at least one plugin can process one of the available onlineTasks for at least one available account. */ bool canSendAnyTask(); /** * @brief Are there plugins and accounts to send a credit transfers? * * Like @r canSendAnyTask() but restricts the onlineTasks to credit transfers. This is useful * to disable the create credit transfer buttons. */ bool canSendCreditTransfer(); /** * @brief Are all preconditions set to edit the given job? */ bool canEditOnlineJob(const onlineJob& job); /** * @brief See if a online task has a specified base * * This is usable if you want to see if e.g. taskIid is * of type creditTransfer */ template bool isInherited(const QString& taskIid) const; signals: /** * @brief Emitted if canSendAnyTask() changed * * At the moment it this signal can be sent even if the status did not change. */ void canSendAnyTaskChanged(bool); /** * @brief Emitted if canSendCreditTransfer changed * * At the moment it this signal can be sent even if the status did not change. */ void canSendCreditTransferChanged(bool); public slots: void addPlugin(const QString& pluginName, KMyMoneyPlugin::OnlinePluginExtended*); /** * @brief Slot for plugins to make an onlineTask available. * @param task the task to register, I take ownership */ void registerOnlineTask(onlineTask *const task); /** * @brief Slot for plugins to make an onlineTaskConverter available. * @param converter the converter to register, I take ownership */ void registerOnlineTaskConverter(onlineTaskConverter *const converter); /** * @brief Check if the properties about available and sendable online tasks are still valid */ void updateOnlineTaskProperties(); private: /** * @brief Find onlinePlugin which is responsible for accountId * @param accountId * @return Pointer to onlinePluginExtended, do not delete. */ KMyMoneyPlugin::OnlinePluginExtended* getOnlinePlugin(const QString& accountId) const; /** * @brief Creates an onlineTask by iid * @return pointer to task, caller gains ownership. Can be 0. */ onlineTask* createOnlineTask(const QString& iid) const; /** * @brief Creates an onlineTask by its iid and xml data * @return pointer to task, caller gains ownership. Can be 0. */ onlineTask* createOnlineTaskByXml(const QString& iid, const QDomElement& element) const; /** * @brief Creates an onlineTask by its iid and xml data * @return pointer to task, caller gains ownership. Can be 0. */ onlineTask* createOnlineTaskFromSqlDatabase(const QString& iid, const QString& onlineJobId, QSqlDatabase connection) const; // Must be able to call createOnlineTaskByXml friend class onlineJob; // Must be able to call createOnlineTask template friend class onlineJobTyped; // Must be able to call createOnlineTaskFromSqlDatabase() friend class MyMoneyStorageSql; /** * @brief Get root instance of an onlineTask * * Returns a pointer from m_onlineTasks or tries to load/create * a approiate root element. * * Only createOnlineTask and createOnlineTaskByXml use it. * * @return A pointer, you do *not* gain ownership! Can be 0 if something went wrong. * * @internal Made to be forward compatible when onlineTask are loaded as plugins. */ inline onlineTask* rootOnlineTask(const QString& name) const; /** * The key is the onlinePlugin's name */ QMap m_onlinePlugins; /** * The key is the name of the task */ QMap m_onlineTasks; /** * Key is the task the converter converts to */ QMultiMap m_onlineTaskConverter; /** * Intances of editors */ QList m_onlineTaskEditors; }; template QSharedPointer onlineJobAdministration::taskSettings(const QString& taskName, const QString& accountId) const { IonlineTaskSettings::ptr settings = taskSettings(taskName, accountId); if (!settings.isNull()) { QSharedPointer settingsFinal = settings.dynamicCast(); if (Q_LIKELY(!settingsFinal.isNull())) // This can only happen if the onlinePlugin has a bug. return settingsFinal; } return QSharedPointer(); } template< class baseTask > bool onlineJobAdministration::isInherited(const QString& taskIid) const { return (dynamic_cast(rootOnlineTask(taskIid)) != 0); } #if 0 template onlineJobTyped onlineJobAdministration::convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation, const QString& onlineJobId) const { onlineJob job = convert(original, convertTaskIid, convertType, userInformation, onlineJobId); return onlineJobTyped(job); } template onlineJobTyped< T > onlineJobAdministration::convert(const onlineJob& original, const QString& convertTaskIid, onlineTaskConverter::convertType& convertType, QString& userInformation) const { return convert(original, convertTaskIid, convertType, userInformation, original.id()); } #endif #endif // ONLINEJOBADMINISTRATION_H diff --git a/kmymoney/mymoney/onlinejobfolder.cpp b/kmymoney/mymoney/onlinejobfolder.cpp index db050281a..5cb02274a 100644 --- a/kmymoney/mymoney/onlinejobfolder.cpp +++ b/kmymoney/mymoney/onlinejobfolder.cpp @@ -1,30 +1,30 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobfolder.h" onlineJobFolder::onlineJobFolder() : m_folder(folderOutbox) { } onlineJobFolder::onlineJobFolder(const onlineJobFolders& folder) : m_folder(folder) { } diff --git a/kmymoney/mymoney/onlinejobfolder.h b/kmymoney/mymoney/onlinejobfolder.h index ee54c998d..710b20e44 100644 --- a/kmymoney/mymoney/onlinejobfolder.h +++ b/kmymoney/mymoney/onlinejobfolder.h @@ -1,65 +1,65 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBFOLDER_H #define ONLINEJOBFOLDER_H /** * @brief Folder to organize @ref onlineJob "onlineJobs" * * This class is mainly for forward compatibility. At the monent there are only four default * folders outbox(), drafts(), templates(), historic(). These static methods are also the only * way to create a folder. * * If job organizing becomes more complicated this class can be extended. * */ class onlineJobFolder { public: inline onlineJobFolder(const onlineJobFolder &other) : m_folder(other.m_folder) {} static onlineJobFolder outbox() { return onlineJobFolder(folderOutbox); } static onlineJobFolder drafts() { return onlineJobFolder(folderDrafts); } static onlineJobFolder templates() { return onlineJobFolder(folderTemplates); } static onlineJobFolder historic() { return onlineJobFolder(folderHistoric); } private: enum onlineJobFolders { folderOutbox, folderDrafts, folderTemplates, folderHistoric }; onlineJobFolder(); onlineJobFolder(const onlineJobFolders& folder); onlineJobFolders m_folder; }; #endif // ONLINEJOBFOLDER_H diff --git a/kmymoney/mymoney/onlinejobmessage.cpp b/kmymoney/mymoney/onlinejobmessage.cpp index 3c48fac8c..c5a0d8ec0 100644 --- a/kmymoney/mymoney/onlinejobmessage.cpp +++ b/kmymoney/mymoney/onlinejobmessage.cpp @@ -1,27 +1,27 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobmessage.h" onlineJobMessage::onlineJobMessage() : m_type(error), m_sender(QString()), m_message(QString()), m_timestamp(QDateTime()) { } diff --git a/kmymoney/mymoney/onlinejobmessage.h b/kmymoney/mymoney/onlinejobmessage.h index d12ebcd27..3ff3385e1 100644 --- a/kmymoney/mymoney/onlinejobmessage.h +++ b/kmymoney/mymoney/onlinejobmessage.h @@ -1,121 +1,121 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBMESSAGE_H #define ONLINEJOBMESSAGE_H #include #include /** * @brief Represets a log message for onlineJobs */ class onlineJobMessage { public: /** * @brief Type of message * * An usually it is not easy to categorise log messages. This description is only a hint. */ enum messageType { debug, /**< Just for debug purposes. In normal scenarios the user should not see this. No need to store this message. Plugins should not create them at all if debug mode is not enabled. */ log, /**< A piece of information the user should not see during normal operation. It is not shown in any UI by default. It is stored persistantly. */ information, /**< Information that should be kept but without the need to burden the user. The user can see this during normal operation. */ warning, /**< A piece of information the user should see but not be enforced to do so (= no modal dialog). E.g. a task is expected to have direct effect but insted you have to wait a day (and that is commen behavior). */ error /**< Important for the user - he must be warned. E.g. a task could unexpectedly not be executed */ }; onlineJobMessage(messageType type, QString sender, QString message, QDateTime timestamp = QDateTime::currentDateTime()) : m_type(type), m_sender(sender), m_message(message), m_timestamp(timestamp) {} ~onlineJobMessage() {} bool isDebug() const { return (m_type == debug); } bool isLog() const { return (m_type == log); } bool isInformation() const { return (m_type == information); } bool isWarning() const { return (m_type == warning); } bool isError() const { return (m_type == error); } bool isPersistant() const { return (m_type != debug); } /** @see messageType */ messageType type() const { return m_type; } /** * @brief Who "wrote" this message? * * Could be "OnlinePlugin" or "Bank" */ QString sender() const { return m_sender; } /** * @brief What happend? */ QString message() const { return m_message; } /** @brief DateTime of message */ QDateTime timestamp() const { return m_timestamp; } /** * @brief Set an error code of the plugin */ void setSenderErrorCode(const QString& errorCode) { m_senderErrorCode = errorCode; } QString senderErrorCode() { return m_senderErrorCode; } private: messageType m_type; QString m_sender; QString m_message; QDateTime m_timestamp; QString m_senderErrorCode; onlineJobMessage(); }; #endif // ONLINEJOBMESSAGE_H diff --git a/kmymoney/mymoney/onlinejobtyped.h b/kmymoney/mymoney/onlinejobtyped.h index 7bf72413b..eebdab274 100644 --- a/kmymoney/mymoney/onlinejobtyped.h +++ b/kmymoney/mymoney/onlinejobtyped.h @@ -1,148 +1,148 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBTYPED_H #define ONLINEJOBTYPED_H #include "onlinejob.h" #include "onlinejobadministration.h" /** * @brief Convenient template if you know the task type of an onlineJob * * To prevent using onlineJob.task() repeatingly you can use this class * where task() has a defined return type. * * Any type check is done in the constructors. So an invalid onlineJobTyped * cannot exist. This class is very fast as well because task() does not need * any checks. * * onlineJobTyped::isNull() is always false. All constructors will throw * onlineJobTyped::badCast or onlineJobTyped::emptyTask if they fail. */ template class onlineJobTyped : public onlineJob { KMM_MYMONEY_UNIT_TESTABLE public: /** * @brief create new task * * @throws emptyTask if plugin could not be found/loaded (determined at runtime). */ explicit onlineJobTyped(); /** * @brief Create typed onlineJob * * @throws emptyTask if task == 0 */ explicit onlineJobTyped(T* task, const QString& id = MyMoneyObject::m_emptyId); /** @brief Copy constructor */ onlineJobTyped(onlineJobTyped const& other); /** * @brief Copy from onlineJob * * @throws badTaskCast if task in other does not fit T * @throws emptyTask if other has no task */ explicit onlineJobTyped(const onlineJob &other); /** @brief Copy constructor with new id */ explicit onlineJobTyped(const QString &id, const onlineJobTyped& other); /** Does not throw */ inline T* task(); /** Does not throw */ inline const T* task() const; /** Does not throw */ inline const T* constTask() const { return task(); } /** Does not throw */ onlineJobTyped operator =(onlineJobTyped const& other); private: T* m_taskTyped; }; template onlineJobTyped::onlineJobTyped() : onlineJob(onlineJobAdministration::instance()->createOnlineTask(T::name())) { m_taskTyped = static_cast(onlineJob::task()); // this can throw emptyTask // Just be safe: an onlineTask developer could have done something wrong Q_CHECK_PTR(dynamic_cast(onlineJob::task())); } template onlineJobTyped::onlineJobTyped(T* task, const QString& id) : onlineJob(task, id), m_taskTyped(task) { if (task == 0) throw emptyTask(__FILE__, __LINE__); } template onlineJobTyped::onlineJobTyped(onlineJobTyped const& other) : onlineJob(other) { m_taskTyped = dynamic_cast(onlineJob::task()); Q_CHECK_PTR(m_taskTyped); } template onlineJobTyped onlineJobTyped::operator =(onlineJobTyped const & other) { onlineJob::operator =(other); m_taskTyped = dynamic_cast(onlineJob::task()); Q_CHECK_PTR(m_taskTyped); return (*this); } template onlineJobTyped::onlineJobTyped(const onlineJob &other) : onlineJob(other) { m_taskTyped = dynamic_cast(onlineJob::task()); // can throw emptyTask if (m_taskTyped == 0) throw badTaskCast(__FILE__, __LINE__); } template T* onlineJobTyped::task() { Q_CHECK_PTR(m_taskTyped); return m_taskTyped; } template const T* onlineJobTyped::task() const { Q_CHECK_PTR(m_taskTyped); return m_taskTyped; } #endif // ONLINEJOBTYPED_H diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifier.cpp b/kmymoney/mymoney/payeeidentifier/payeeidentifier.cpp index 9985c3876..b6537c421 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifier.cpp +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifier.cpp @@ -1,154 +1,154 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "payeeidentifier.h" payeeIdentifier::payeeIdentifier() : m_id(0), m_payeeIdentifier(0) { } payeeIdentifier::payeeIdentifier(const payeeIdentifier& other) : m_id(other.m_id), m_payeeIdentifier(0) { if (other.m_payeeIdentifier != 0) m_payeeIdentifier = other.m_payeeIdentifier->clone(); } payeeIdentifier::payeeIdentifier(payeeIdentifierData*const data) : m_id(0), m_payeeIdentifier(data) { } payeeIdentifier::payeeIdentifier(const payeeIdentifier::id_t& id, payeeIdentifierData*const data) : m_id(id), m_payeeIdentifier(data) { } payeeIdentifier::payeeIdentifier(const QString& id, payeeIdentifierData*const data) : m_id(id.mid(5).toUInt()), m_payeeIdentifier(data) { bool ok = false; // hopefully the compiler optimizes this away if compiled in non-debug mode Q_ASSERT(id.mid(5).toUInt(&ok) && ok); } payeeIdentifier::payeeIdentifier(const payeeIdentifier::id_t& id, const payeeIdentifier& other) : m_id(id), m_payeeIdentifier(0) { if (other.m_payeeIdentifier != 0) m_payeeIdentifier = other.m_payeeIdentifier->clone(); } QString payeeIdentifier::idString() const { if (m_id == 0) return QString(); return QLatin1String("IDENT") + QString::number(m_id).rightJustified(6, '0'); } payeeIdentifier::~payeeIdentifier() { delete m_payeeIdentifier; } payeeIdentifierData* payeeIdentifier::operator->() { if (m_payeeIdentifier == 0) throw empty(__FILE__, __LINE__); return m_payeeIdentifier; } const payeeIdentifierData* payeeIdentifier::operator->() const { if (m_payeeIdentifier == 0) throw empty(__FILE__, __LINE__); return m_payeeIdentifier; } payeeIdentifierData* payeeIdentifier::data() { return operator->(); } const payeeIdentifierData* payeeIdentifier::data() const { return operator->(); } bool payeeIdentifier::isValid() const { if (m_payeeIdentifier != 0) return m_payeeIdentifier->isValid(); return false; } QString payeeIdentifier::iid() const { if (m_payeeIdentifier != 0) return m_payeeIdentifier->payeeIdentifierId(); return QString(); } payeeIdentifier& payeeIdentifier::operator=(const payeeIdentifier & other) { if (this == &other) return *this; m_id = other.m_id; if (other.m_payeeIdentifier == 0) m_payeeIdentifier = 0; else m_payeeIdentifier = other.m_payeeIdentifier->clone(); return *this; } bool payeeIdentifier::operator==(const payeeIdentifier& other) { if (m_id != other.m_id) return false; if (isNull() || other.isNull()) { if (!isNull() || !other.isNull()) return false; return true; } return (*data() == *(other.data())); } void payeeIdentifier::writeXML(QDomDocument& document, QDomElement& parent, const QString& elemenName) const { // Important: type must be set before calling m_payeeIdentifier->writeXML() // the plugin for unavailable plugins must be able to set type itself QDomElement elem = document.createElement(elemenName); if (m_id != 0) elem.setAttribute("id", m_id); if (!isNull()) { elem.setAttribute("type", m_payeeIdentifier->payeeIdentifierId()); m_payeeIdentifier->writeXML(document, elem); } parent.appendChild(elem); } diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifier.h b/kmymoney/mymoney/payeeidentifier/payeeidentifier.h index 233444ecd..74515dc3c 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifier.h +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifier.h @@ -1,177 +1,177 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIER_H #define PAYEEIDENTIFIER_H #include /** @todo fix include path after upgrade to cmake 3 */ #include "payeeidentifier/kmm_payeeidentifier_export.h" #include "mymoneyexception.h" // Q_DECLARE_METATYPE requries this include #include "payeeidentifierdata.h" class MyMoneyPayeeIdentifierContainer; class KMM_PAYEEIDENTIFIER_EXPORT payeeIdentifier { public: typedef unsigned int id_t; explicit payeeIdentifier(); explicit payeeIdentifier(payeeIdentifierData *const data); explicit payeeIdentifier(const id_t& id, payeeIdentifierData *const data); explicit payeeIdentifier(const QString& id, payeeIdentifierData *const data); explicit payeeIdentifier(const id_t& id, const payeeIdentifier& other); payeeIdentifier(const payeeIdentifier& other); ~payeeIdentifier(); payeeIdentifier& operator=(const payeeIdentifier& other); bool operator==(const payeeIdentifier& other); /** @brief Check if any data is associated */ bool isNull() const { return (m_payeeIdentifier == 0); } /** * @brief create xml to save this payeeIdentifier * * It creates a new element below parent which is used to store all data. * * The counter part to load a payee identifier again is payeeIdentifierLoader::createPayeeIdentifierFromXML(). */ void writeXML(QDomDocument &document, QDomElement &parent, const QString& elementName = QLatin1String("payeeIdentifier")) const; /** * @throws payeeIdentifier::empty */ payeeIdentifierData* operator->(); /** @copydoc operator->() */ const payeeIdentifierData* operator->() const; /** @copydoc operator->() */ payeeIdentifierData* data(); /** @copydoc operator->() */ const payeeIdentifierData* data() const; template< class T > T* data(); template< class T > const T* data() const; bool isValid() const; id_t id() const { return m_id; } QString idString() const; void clearId() { m_id = 0; } /** * @brief Get payeeIdentifier Iid which identifiers the type * * @return An payeeIdentifier id or QString() if no data is associated */ QString iid() const; /** * @brief Base for exceptions thrown by payeeIdentifier * * @internal Using MyMoneyException instead is not possible because * it would lead to cyclic inter-target dependenies. We could create a new * shared library which includes MyMoneyException only, but this could be over- * powered. */ class exception {}; /** * @brief Thrown if a cast of a payeeIdentifier fails * * This is inspired by std::bad_cast * @todo inherit from MyMoneyException */ class badCast : public exception { public: badCast(const QString& file = "", const long unsigned int& line = 0) //: MyMoneyException("Casted payeeIdentifier with wrong type", file, line) { Q_UNUSED(file); Q_UNUSED(line); } }; /** * @brief Thrown if one tried to access the data of a null payeeIdentifier * @todo inherit from MyMoneyException */ class empty : public exception { public: empty(const QString& file = "", const long unsigned int& line = 0) //: MyMoneyException("Requested payeeIdentifierData of empty payeeIdentifier", file, line) { Q_UNUSED(file); Q_UNUSED(line); } }; private: /** * The id is only used in MyMoneyPayeeIdentifierContainer at the moment. */ id_t m_id; // Must access the id, but the id should not be used outside of that class at the moment friend class MyMoneyPayeeIdentifierContainer; friend class payeeIdentifierLoader; payeeIdentifierData* m_payeeIdentifier; }; template T* payeeIdentifier::data() { T *const ident = dynamic_cast(operator->()); if (ident == 0) throw badCast(__FILE__, __LINE__); return ident; } template const T* payeeIdentifier::data() const { const T *const ident = dynamic_cast(operator->()); if (ident == 0) throw badCast(__FILE__, __LINE__); return ident; } Q_DECLARE_METATYPE(payeeIdentifier) #endif // PAYEEIDENTIFIER_H diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.cpp b/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.cpp index 8dc0067ea..562ccbc7b 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.cpp +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.cpp @@ -1,136 +1,136 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "payeeidentifiermodel.h" #include "mymoney/mymoneyfile.h" #include "payeeidentifier/payeeidentifierloader.h" #include "payeeidentifier/payeeidentifier.h" #include #include payeeIdentifierContainerModel::payeeIdentifierModel(QObject* parent) : QAbstractListModel(parent), m_data(QSharedPointer()) { } QVariant payeeIdentifierContainerModel::data(const QModelIndex& index, int role) const { // Needed for the selection box and it prevents a crash if index is out of range if (m_data.isNull() || index.row() >= rowCount(index.parent()) - 1) return QVariant(); const ::payeeIdentifier ident = m_data->payeeIdentifiers().at(index.row()); if (role == payeeIdentifier) { return QVariant::fromValue< ::payeeIdentifier >(ident); } else if (ident.isNull()) { return QVariant(); } else if (role == payeeIdentifierType) { return ident.iid(); } else if (role == Qt::DisplayRole) { // The custom delegates won't ask for this role return QVariant::fromValue(i18n("The plugin to show this information could not be found.")); } return QVariant(); } bool payeeIdentifierContainerModel::setData(const QModelIndex& index, const QVariant& value, int role) { if (!m_data.isNull() && role == payeeIdentifier) { ::payeeIdentifier ident = value.value< ::payeeIdentifier >(); if (index.row() == rowCount(index.parent()) - 1) { // The new row will be the last but one beginInsertRows(index.parent(), index.row() - 1, index.row() - 1); m_data->addPayeeIdentifier(ident); endInsertRows(); } else { m_data->modifyPayeeIdentifier(index.row(), ident); emit dataChanged(createIndex(index.row(), 0), createIndex(index.row(), 0)); } return true; } return QAbstractItemModel::setData(index, value, role); } Qt::ItemFlags payeeIdentifierContainerModel::flags(const QModelIndex& index) const { Qt::ItemFlags flags = QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled; const QString type = data(index, payeeIdentifierType).toString(); // type.isEmpty() means the type selection can be shown if (!type.isEmpty() && payeeIdentifierLoader::instance()->hasItemEditDelegate(type)) flags |= Qt::ItemIsEditable; return flags; } int payeeIdentifierContainerModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent); if (m_data.isNull()) return 0; // Always a row more which creates new entries return m_data->payeeIdentifiers().count() + 1; } /** @brief unused at the moment */ bool payeeIdentifierContainerModel::insertRows(int row, int count, const QModelIndex& parent) { Q_UNUSED(row); Q_UNUSED(count); Q_UNUSED(parent); return false; } bool payeeIdentifierContainerModel::removeRows(int row, int count, const QModelIndex& parent) { if (m_data.isNull()) return false; if (count < 1 || row + count >= rowCount(parent)) return false; beginRemoveRows(parent, row, row + count - 1); for (int i = row; i < row + count; ++i) { m_data->removePayeeIdentifier(i); } endRemoveRows(); return true; } void payeeIdentifierContainerModel::setSource(const MyMoneyPayeeIdentifierContainer data) { beginResetModel(); m_data = QSharedPointer(new MyMoneyPayeeIdentifierContainer(data)); endResetModel(); } void payeeIdentifierContainerModel::closeSource() { beginResetModel(); m_data = QSharedPointer(); endResetModel(); } QList< ::payeeIdentifier > payeeIdentifierContainerModel::identifiers() const { if (m_data.isNull()) return QList< ::payeeIdentifier >(); return m_data->payeeIdentifiers(); } diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.h b/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.h index dc0ef192f..928c134fd 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.h +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifiercontainermodel.h @@ -1,84 +1,84 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERMODEL_H #define PAYEEIDENTIFIERMODEL_H #include #include "mymoney/mymoneypayeeidentifiercontainer.h" #include "payeeidentifier/payeeidentifier.h" /** * @brief Model for MyMoneyPayeeIdentifierContainer * * Changes the user does have initernal effect only. */ class payeeIdentifierContainerModel : public QAbstractListModel { Q_OBJECT public: enum roles { payeeIdentifierType = Qt::UserRole, /**< type of payeeIdentifier */ payeeIdentifier = Qt::UserRole + 1 /**< actual payeeIdentifier */ }; payeeIdentifierContainerModel(QObject* parent = 0); virtual QVariant data(const QModelIndex& index, int role) const; /** * This model only supports to edit payeeIdentifier role with a QVariant of type * payeeIdentifier. */ virtual bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual int rowCount(const QModelIndex& parent) const; virtual bool insertRows(int row, int count, const QModelIndex& parent); virtual bool removeRows(int row, int count, const QModelIndex& parent); /** * @brief Set source of data * * This makes the model editable. */ void setSource(MyMoneyPayeeIdentifierContainer data); /** @brief Get stored data */ QList< ::payeeIdentifier > identifiers() const; public slots: /** * @brief Removes all data from the model * * The model is not editable afterwards. */ void closeSource(); private: /** @internal * The use of a shared pointer makes this future prof. Because using identifier() causes * some unnecessary work. */ QSharedPointer m_data; }; #endif // PAYEEIDENTIFIERMODEL_H diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifierdata.h b/kmymoney/mymoney/payeeidentifier/payeeidentifierdata.h index 242f5656e..b54644a79 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifierdata.h +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifierdata.h @@ -1,138 +1,138 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERDATA_H #define PAYEEIDENTIFIERDATA_H #include "payeeidentifier/kmm_payeeidentifier_export.h" #include #include #include #include #include #include "storage/databasestoreableobject.h" class payeeIdentifier; class payeeIdentifierLoader; /** * @brief Define a unique identifier for an payeeIdentifier subclass * * Use this macro in your class's public section. * * This also defines the helper ::ptr, ::constPtr and className::ptr cloneSharedPtr() * * @param PIDID the payeeIdentifier id, e.g. "org.kmymoney.payeeIdentifier.swift". Must be * unique among all payeeIdentifiers as it is used internaly to store data, to compare * types and for type casting (there must not be more than one class which uses that pidid). */ #define PAYEEIDENTIFIER_IID(className, iid) \ /** @brief Returns the payeeIdentifier Iid */ \ static const QString& staticPayeeIdentifierIid() { \ static const QString _pidid = QLatin1String( iid ); \ return _pidid; \ } \ /** @brief Returns the payeeIdentifier Id */ \ virtual QString payeeIdentifierId() const { \ return className::staticPayeeIdentifierIid(); \ } /** * @brief "Something" that identifies a payee (or an account of a payee) * * The simplest form of this class is an identifier for an bank account (consisting of an account number * and a bank code). But also an e-mail address which is used by an online money-transfer service could be * such an identifier (that is the reason for the abstract name "payeeIdentifier"). * * But also the creditor identifier for debit-notes in sepa-countries can be a subclass. It does not * address an account but a company. * * Any payee (@ref MyMoneyPayee) can have several payeeIdentifiers. * * The online banking system uses payeeIdentifiers to dertermine if it is able so create a credit-transfer * to a given payee. During import the payeeIdentifiers are used to find a payee. * * You should use the shared pointer payeeIdentifier::ptr to handle payeeIdentifiers. To copy them used * cloneSharedPtr(). * * @intenal First this is more complex than creating a superset of all possible identifiers. But there * are many of them. And using this method it is a lot easier to create the comparison operators and * things like isValid(). * * @section Inheriting * * To identify the type of an payeeIdentifier you must use the macro @ref PAYEEIDENTIFIER_IID() * in the public section of your subclass. */ class KMM_PAYEEIDENTIFIER_EXPORT payeeIdentifierData : public databaseStoreableObject { public: virtual ~payeeIdentifierData() {} /** * Use PAYEEIDENTIFIER_ID(className, PIDID) to reimplement this method. */ virtual QString payeeIdentifierId() const = 0; /** * @brief Comparison operator */ virtual bool operator==(const payeeIdentifierData& other) const = 0; virtual bool operator!=(const payeeIdentifierData& other) const { return (!operator==(other)); } /** * @brief Check if this payeeIdentifier contains correct data * * You should be able to handle invalid data. It is the task of the ui to prevent * invalid data. But during several procedures invalid data could be used (e.g. * during import). */ virtual bool isValid() const = 0; /** * @brief Create a new payeeIdentifier form XML data * * @param element Note: there could be more data in that elemenet than you created in writeXML() */ virtual payeeIdentifierData* createFromXml(const QDomElement &element) const = 0; virtual payeeIdentifierData* createFromSqlDatabase(QSqlDatabase db, const QString& identId) const = 0; /** * @see MyMoneyObject::writeXML() * * @warning Do not set an attribute "type" or "id" to parent, it is used to store internal data and is * set automatically. */ virtual void writeXML(QDomDocument &document, QDomElement &parent) const = 0; protected: /** * @brief Create deep copy */ virtual payeeIdentifierData* clone() const = 0; friend class payeeIdentifierLoader; friend class payeeIdentifier; }; Q_DECLARE_INTERFACE(payeeIdentifierData, "org.kmymoney.payeeIdentifier") #endif // PAYEEIDENTIFIERDATA_H diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.cpp b/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.cpp index 2eb00b093..787396c2c 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.cpp +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.cpp @@ -1,135 +1,135 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "payeeidentifier/payeeidentifierloader.h" #include "payeeidentifier/unavailableplugin/unavailableplugin.h" #include "payeeidentifier/ibanandbic/ibanbic.h" #include "payeeidentifier/nationalaccount/nationalaccount.h" #include #include #include #include payeeIdentifierLoader payeeIdentifierLoader::m_self; payeeIdentifierLoader::payeeIdentifierLoader() : m_identifiers(QHash()) { addPayeeIdentifier(new payeeIdentifiers::ibanBic()); addPayeeIdentifier(new payeeIdentifiers::nationalAccount()); } payeeIdentifierLoader::~payeeIdentifierLoader() { qDeleteAll(m_identifiers); } void payeeIdentifierLoader::addPayeeIdentifier(payeeIdentifierData* const identifier) { Q_CHECK_PTR(identifier); m_identifiers.insertMulti(identifier->payeeIdentifierId(), identifier); } payeeIdentifier payeeIdentifierLoader::createPayeeIdentifier(const QString& payeeIdentifierId) { const payeeIdentifierData* ident = m_identifiers.value(payeeIdentifierId); if (ident != nullptr) { return payeeIdentifier(ident->clone()); } return payeeIdentifier(); } payeeIdentifier payeeIdentifierLoader::createPayeeIdentifierFromXML(const QDomElement& element) { const QString payeeIdentifierId = element.attribute("type"); const payeeIdentifierData* identData = m_identifiers.value(payeeIdentifierId); payeeIdentifier ident; if (identData != nullptr) { payeeIdentifierData* newIdent = identData->createFromXml(element); ident = payeeIdentifier(newIdent); } else { ident = payeeIdentifier(new payeeIdentifiers::payeeIdentifierUnavailable(element)); } ident.m_id = element.attribute("id", 0).toUInt(); return ident; } payeeIdentifier payeeIdentifierLoader::createPayeeIdentifierFromSqlDatabase(QSqlDatabase db, const QString& identifierType, const QString& identifierId) { const payeeIdentifierData* identData = m_identifiers.value(identifierType); if (identData != nullptr) { payeeIdentifierData* data = identData->createFromSqlDatabase(db, identifierId); return payeeIdentifier(identifierId, data); } return payeeIdentifier(identifierId, nullptr); } /** * @todo enable delegates again */ QAbstractItemDelegate* payeeIdentifierLoader::createItemDelegate(const QString& payeeIdentifierId, QObject* parent) { /** @todo escape ' in payeeIdentifierId */ KService::List offers = KServiceTypeTrader::self()->query(QLatin1String("KMyMoney/PayeeIdentifierDelegate"), QString("'%1' ~in [X-KMyMoney-payeeIdentifierIds]").arg(payeeIdentifierId)); if (!offers.isEmpty()) { QString error; QAbstractItemDelegate* ptr = offers.at(0)->createInstance(parent, QVariantList(), &error); if (ptr == nullptr) { qWarning() << "could not load delegate" << error << payeeIdentifierId; } return ptr; } return nullptr; } bool payeeIdentifierLoader::hasItemEditDelegate(const QString& payeeIdentifierId) { QAbstractItemDelegate* delegate = createItemDelegate(payeeIdentifierId); const bool ret = (delegate != nullptr); delete delegate; return ret; } QStringList payeeIdentifierLoader::availableDelegates() { QStringList list; KService::List offers = KServiceTypeTrader::self()->query(QLatin1String("KMyMoney/PayeeIdentifierDelegate")); foreach (KService::Ptr offer, offers) { list.append(offer->property("X-KMyMoney-payeeIdentifierIds", QVariant::StringList).toStringList()); } return list; } QString payeeIdentifierLoader::translatedDelegateName(const QString& payeeIdentifierId) { if (payeeIdentifierId == payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()) return i18n("IBAN and BIC"); else if (payeeIdentifierId == payeeIdentifiers::nationalAccount::staticPayeeIdentifierIid()) return i18n("National Account Number"); return QString(); } diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.h b/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.h index f3502532b..857499fb5 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.h +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifierloader.h @@ -1,83 +1,83 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERLOADER_H #define PAYEEIDENTIFIERLOADER_H #include "payeeidentifier.h" #include #include class QAbstractItemDelegate; /** * * @todo Load delegates dynamically */ class payeeIdentifierLoader { public: payeeIdentifierLoader(); ~payeeIdentifierLoader(); payeeIdentifier createPayeeIdentifier(const QString& payeeIdentifierId); payeeIdentifier createPayeeIdentifierFromXML(const QDomElement& element); payeeIdentifier createPayeeIdentifierFromSqlDatabase(QSqlDatabase db, const QString& identifierType, const QString& identifierId); /** * @brief Create a delegate to show/edit * * The payeeIdentifier to edit is identified by payeeIdentifierId. parent is set as parent of the created * Delegate. * * @return a pointer to a delegate or null_ptr. Caller takes ownership. */ QAbstractItemDelegate* createItemDelegate(const QString& payeeIdentifierId, QObject* parent = 0); /** * @brief Test if a delegate for editing is available */ bool hasItemEditDelegate(const QString& payeeIdentifierId); /** * @brief List availableDelegates delegates * * @return a list of payeeIdentifierIds for which a delegate exists. * @see createItemDelegate() */ QStringList availableDelegates(); /** * @brief Human readable name of a delegate for a given payeeIdentifierId */ QString translatedDelegateName(const QString& payeeIdentifierId); /** I take ownership */ void addPayeeIdentifier(payeeIdentifierData *const identifier); static payeeIdentifierLoader* instance() { return &m_self; } private: QHash m_identifiers; static payeeIdentifierLoader m_self; }; #endif // PAYEEIDENTIFIERLOADER_H diff --git a/kmymoney/mymoney/payeeidentifier/payeeidentifiertyped.h b/kmymoney/mymoney/payeeidentifier/payeeidentifiertyped.h index d06ada47c..763fdba94 100644 --- a/kmymoney/mymoney/payeeidentifier/payeeidentifiertyped.h +++ b/kmymoney/mymoney/payeeidentifier/payeeidentifiertyped.h @@ -1,119 +1,119 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERTYPED_H #define PAYEEIDENTIFIERTYPED_H #include "payeeidentifier.h" template class payeeIdentifierTyped : public payeeIdentifier { public: payeeIdentifierTyped(const payeeIdentifierTyped& other); payeeIdentifierTyped(T* pid); //explicit payeeIdentifierTyped(); explicit payeeIdentifierTyped(const payeeIdentifier& other); T* operator->(); const T* operator->() const; T* data() { return operator->(); } const T* data() const { return operator->(); } payeeIdentifierTyped& operator=(const payeeIdentifierTyped& other); bool operator==(const payeeIdentifierTyped& other); private: /** this method is not save in this class, so deactivate it */ void setData(payeeIdentifierData* dataPtr); T* m_payeeIdentifierTyped; }; #if 0 template< class T > payeeIdentifierTyped::payeeIdentifierTyped() : payeeIdentifier() { Q_ASSERT(false && "This method is not implemented yet"); throw payeeIdentifier::empty(); } #endif template< class T > payeeIdentifierTyped::payeeIdentifierTyped(T* pid) : payeeIdentifier(pid), m_payeeIdentifierTyped(pid) { if (m_payeeIdentifierTyped == 0) throw payeeIdentifier::empty(__FILE__, __LINE__); } template< class T > payeeIdentifierTyped::payeeIdentifierTyped(const payeeIdentifierTyped& other) : payeeIdentifier(other) { m_payeeIdentifierTyped = dynamic_cast(payeeIdentifier::data()); Q_CHECK_PTR(m_payeeIdentifierTyped); } template< class T > payeeIdentifierTyped& payeeIdentifierTyped::operator=(const payeeIdentifierTyped& other) { payeeIdentifierTyped& ret = static_cast&>(payeeIdentifier::operator=(other)); // This operation is save even if this == &other ret.m_payeeIdentifierTyped = dynamic_cast(ret.payeeIdentifier::data()); return ret; } template< class T > bool payeeIdentifierTyped::operator==(const payeeIdentifierTyped& other) { return payeeIdentifier::operator==(other); } template< class T > payeeIdentifierTyped::payeeIdentifierTyped(const payeeIdentifier& other) : payeeIdentifier(other) { m_payeeIdentifierTyped = dynamic_cast(payeeIdentifier::data()); if (m_payeeIdentifierTyped == 0) { if (payeeIdentifier::data() == 0) throw payeeIdentifier::empty(__FILE__, __LINE__); throw payeeIdentifier::badCast(__FILE__, __LINE__); } } template< class T > T* payeeIdentifierTyped::operator->() { return m_payeeIdentifierTyped; } template< class T > const T* payeeIdentifierTyped::operator->() const { return m_payeeIdentifierTyped; } #endif // PAYEEIDENTIFIERTYPED_H diff --git a/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.cpp b/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.cpp index 22bf0c1b1..6d0017ce7 100644 --- a/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.cpp +++ b/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.cpp @@ -1,88 +1,88 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2016 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "payeeidentifier-test.h" #include #include "mymoney/payeeidentifier/payeeidentifier.h" #include "mymoney/payeeidentifier/payeeidentifiertyped.h" #include "mymoney/payeeidentifier/payeeidentifierloader.h" #include "payeeidentifier/ibanandbic/ibanbic.h" QTEST_GUILESS_MAIN(payeeidentifier_test); void payeeidentifier_test::initTestCase() { // Called before the first testfunction is executed } void payeeidentifier_test::cleanupTestCase() { // Called after the last testfunction was executed } void payeeidentifier_test::init() { // Called before each testfunction is executed } void payeeidentifier_test::cleanup() { // Called after every testfunction } void payeeidentifier_test::createAndDeleteEmptyIdent() { payeeIdentifier ident{}; } void payeeidentifier_test::copyIdent() { try { const payeeIdentifier ident = payeeIdentifierLoader::instance()->createPayeeIdentifier(payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()); payeeIdentifier ident2 = ident; QVERIFY(!ident2.isNull()); QCOMPARE(ident2.iid(), payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()); } catch (...) { QFAIL("Unexpected exception"); } } void payeeidentifier_test::moveIdent() { try { payeeIdentifier ident = payeeIdentifierLoader::instance()->createPayeeIdentifier(payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()); payeeIdentifier ident2 = ident; } catch (...) { QFAIL("Unexpected exception"); } } void payeeidentifier_test::createTypedIdent() { try { payeeIdentifier ident = payeeIdentifierLoader::instance()->createPayeeIdentifier(payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()); payeeIdentifierTyped typedIdent{ident}; } catch (...) { QFAIL("Unexpected exception"); } } diff --git a/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.h b/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.h index 6828b7f65..a33f9b966 100644 --- a/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.h +++ b/kmymoney/mymoney/payeeidentifier/tests/payeeidentifier-test.h @@ -1,40 +1,40 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2016 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIER_TEST_H #define PAYEEIDENTIFIER_TEST_H #include class payeeidentifier_test : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void init(); void cleanup(); void createAndDeleteEmptyIdent(); void copyIdent(); void moveIdent(); void createTypedIdent(); }; #endif // PAYEEIDENTIFIER_TEST_H diff --git a/kmymoney/mymoney/payeeidentifiermodel.cpp b/kmymoney/mymoney/payeeidentifiermodel.cpp index 9440cfe4f..cbbfc15b0 100644 --- a/kmymoney/mymoney/payeeidentifiermodel.cpp +++ b/kmymoney/mymoney/payeeidentifiermodel.cpp @@ -1,162 +1,162 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015, 2016 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "payeeidentifiermodel.h" #include #include #include #include #include "mymoneyfile.h" /** * @brief create unique value for QModelIndex::internalId() to indicate "not set" */ static constexpr decltype(reinterpret_cast(0)->internalId()) invalidParent = std::numeric_limits(0)->internalId())>::max(); payeeIdentifierModel::payeeIdentifierModel(QObject* parent) : QAbstractItemModel(parent), m_payeeIdentifierIds(), m_typeFilter() { } void payeeIdentifierModel::setTypeFilter(QStringList filter) { m_typeFilter = filter; loadData(); } void payeeIdentifierModel::setTypeFilter(QString type) { setTypeFilter(QStringList(type)); } void payeeIdentifierModel::loadData() { beginResetModel(); const QList payees = MyMoneyFile::instance()->payeeList(); m_payeeIdentifierIds.clear(); m_payeeIdentifierIds.reserve(payees.count()); Q_FOREACH(const MyMoneyPayee& payee, payees) { m_payeeIdentifierIds.append(payee.id()); } endResetModel(); } MyMoneyPayee payeeIdentifierModel::payeeByIndex(const QModelIndex& index) const { if (index.isValid() && index.row() >= 0 && index.row() < m_payeeIdentifierIds.count()) { try { return MyMoneyFile::instance()->payee(m_payeeIdentifierIds.at(index.row())); } catch (MyMoneyException&) { } } return MyMoneyPayee(); } QVariant payeeIdentifierModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); const bool isPayeeIdentifier = index.parent().isValid(); if (role == payeeIdentifierModel::isPayeeIdentifier) return isPayeeIdentifier; const MyMoneyPayee payee = (isPayeeIdentifier) ? payeeByIndex(index.parent()) : payeeByIndex(index); if (role == payeeName || (!isPayeeIdentifier && role == Qt::DisplayRole)) { // Return data for MyMoneyPayee return payee.name(); } else if (isPayeeIdentifier) { // Return data for payeeIdentifier if (index.row() >= 0 && static_cast(index.row()) < payee.payeeIdentifierCount()) { ::payeeIdentifier ident = payee.payeeIdentifier(index.row()); if (role == payeeIdentifier) { return QVariant::fromValue< ::payeeIdentifier >(ident); } else if (ident.isNull()) { return QVariant(); } else if (role == payeeIdentifierType) { return ident.iid(); } else if (role == Qt::DisplayRole) { // The custom delegates won't ask for this role return QVariant::fromValue(i18n("The plugin to show this information could not be found.")); } } } return QVariant(); } Qt::ItemFlags payeeIdentifierModel::flags(const QModelIndex &index) const { Q_UNUSED(index) #if 0 if (!index.parent().isValid()) { if (payeeByIndex(index).payeeIdentifierCount() > 0) return Qt::ItemIsEnabled; } #endif return (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } /** * @intenal The internalId of QModelIndex is set to the row of the parent or invalidParent if there is no * parent. * * @todo Qt5: the type of the internal id changed! */ QModelIndex payeeIdentifierModel::index(int row, int column, const QModelIndex &parent) const { if (parent.isValid()) return createIndex(row, column, parent.row()); return createIndex(row, column, invalidParent); } int payeeIdentifierModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent); return 1; } int payeeIdentifierModel::rowCount(const QModelIndex& parent) const { if (parent.isValid()) { if (parent.internalId() != invalidParent) return 0; return payeeByIndex(parent).payeeIdentifierCount(); } return m_payeeIdentifierIds.count(); } QModelIndex payeeIdentifierModel::parent(const QModelIndex& child) const { if (child.internalId() != invalidParent) return createIndex(child.internalId(), 0, invalidParent); return QModelIndex(); } diff --git a/kmymoney/mymoney/payeeidentifiermodel.h b/kmymoney/mymoney/payeeidentifiermodel.h index 0278ef182..70104a780 100644 --- a/kmymoney/mymoney/payeeidentifiermodel.h +++ b/kmymoney/mymoney/payeeidentifiermodel.h @@ -1,76 +1,76 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERMODEL_H #define PAYEEIDENTIFIERMODEL_H #include "kmm_mymoney_export.h" #include #include #include "mymoney/mymoneypayee.h" /** * @brief Read-only model for stored payeeIdentifiers * * @note You must set an filter * * @internal if needed this can be extended to an read/write model */ class KMM_MYMONEY_EXPORT payeeIdentifierModel : public QAbstractItemModel { Q_OBJECT public: enum roles { payeeName = Qt::UserRole, /**< MyMoneyPayee::name() */ isPayeeIdentifier = Qt::UserRole + 1, /**< refers index to payeeIdentifier (true) or MyMoneyPayee (false) */ payeeIdentifierType = Qt::UserRole + 2, /**< type of payeeIdentifier */ payeeIdentifier = Qt::UserRole + 3, /**< actual payeeIdentifier */ payeeIdentifierUserRole = Qt::UserRole + 4 /**< role to start with for inheriting models */ }; explicit payeeIdentifierModel(QObject* parent = 0); virtual QVariant data(const QModelIndex& index, int role) const; virtual int columnCount(const QModelIndex& parent) const; virtual int rowCount(const QModelIndex& parent) const; virtual QModelIndex parent(const QModelIndex& child) const; virtual QModelIndex index(int row, int column, const QModelIndex &parent) const; virtual Qt::ItemFlags flags(const QModelIndex &index) const; /** * @brief Set which payeeIdentifier types to show * * @param filter list of payeeIdentifier types. An empty list leads to an empty model. */ void setTypeFilter(QStringList filter); /** convenience overload for setTypeFilter(QStringList) */ void setTypeFilter(QString type); void loadData(); private: typedef QPair identId_t; inline MyMoneyPayee payeeByIndex(const QModelIndex& index) const; QStringList m_payeeIdentifierIds; QStringList m_typeFilter; }; #endif // PAYEEIDENTIFIERMODEL_H diff --git a/kmymoney/mymoney/storage/databasestoreableobject.h b/kmymoney/mymoney/storage/databasestoreableobject.h index 5f7e9dc5a..c2929d79c 100644 --- a/kmymoney/mymoney/storage/databasestoreableobject.h +++ b/kmymoney/mymoney/storage/databasestoreableobject.h @@ -1,48 +1,48 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DATABASESTOREABLEOBJECT_H #define DATABASESTOREABLEOBJECT_H #include /** * @brief Base class for plugin based objects which are stored in the database */ class databaseStoreableObject { public: /** * Iid of the KMyMoneyPlugin::storagePlugin which is needed to save this * object. * * Can be QString() to signal that no such plugin is needed. */ virtual QString storagePluginIid() const = 0; virtual bool sqlSave(QSqlDatabase databaseConnection, const QString& objectId) const = 0; virtual bool sqlModify(QSqlDatabase databaseConnection, const QString& objectId) const = 0; virtual bool sqlRemove(QSqlDatabase databaseConnection, const QString& objectId) const = 0; virtual ~databaseStoreableObject() {} }; Q_DECLARE_INTERFACE(databaseStoreableObject, "org.kmymoney.databaseStoreableObject"); #endif // DATABASESTOREABLEOBJECT_H diff --git a/kmymoney/mymoney/storage/kmymoneystorageplugin.cpp b/kmymoney/mymoney/storage/kmymoneystorageplugin.cpp index b5cdcf7e7..d3da8883d 100644 --- a/kmymoney/mymoney/storage/kmymoneystorageplugin.cpp +++ b/kmymoney/mymoney/storage/kmymoneystorageplugin.cpp @@ -1,30 +1,30 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kmymoneystorageplugin.h" KMyMoneyPlugin::storagePlugin::storagePlugin(QObject* parent, const QVariantList& options) : QObject(parent) { Q_UNUSED(options); } KMyMoneyPlugin::storagePlugin::~storagePlugin() { } diff --git a/kmymoney/mymoney/storage/kmymoneystorageplugin.h b/kmymoney/mymoney/storage/kmymoneystorageplugin.h index 8a4ecd0ac..4c57063a2 100644 --- a/kmymoney/mymoney/storage/kmymoneystorageplugin.h +++ b/kmymoney/mymoney/storage/kmymoneystorageplugin.h @@ -1,67 +1,67 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KMYMONEYPLUGIN_STORAGEPLUGIN_H #define KMYMONEYPLUGIN_STORAGEPLUGIN_H #include #include #include namespace KMyMoneyPlugin { /** * @brief Interface for plugins which store data in an sql database * */ class storagePlugin : public QObject { Q_OBJECT public: /** * This is the constructor needed by KService */ explicit storagePlugin(QObject* parent = 0, const QVariantList& options = QVariantList()); /** * @brief Setup database to make it usable by the plugins * * This method is also called on the first usage in a session. You must check if your changes * were applied before. This also enables the plugin to upgrade the schema if needed. * * You must fill the kmmPluginInfo table with your plugins data. The version column is for your * usage. A higher number means a more recent version. * Use a transaction! */ virtual bool setupDatabase(QSqlDatabase connection) = 0; /** * @brief Remove all data belonging to the plugin from the database */ virtual bool removePluginData(QSqlDatabase connection) = 0; virtual ~storagePlugin(); }; } // end namespace KMyMoneyPlugin Q_DECLARE_INTERFACE(KMyMoneyPlugin::storagePlugin, "org.kmymoney.plugin.storageplugin") #endif // KMYMONEYPLUGIN_STORAGEPLUGIN_H diff --git a/kmymoney/mymoney/storage/mymoneystoragesql.h b/kmymoney/mymoney/storage/mymoneystoragesql.h index c736e8b64..d2f6ada2e 100644 --- a/kmymoney/mymoney/storage/mymoneystoragesql.h +++ b/kmymoney/mymoney/storage/mymoneystoragesql.h @@ -1,604 +1,604 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2005 Tony Bloomfield * Copyright (C) Fernando Vilas * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef MYMONEYSTORAGESQL_H #define MYMONEYSTORAGESQL_H #include #include #include #include #include #include #include #include #include class QIODevice; #include "imymoneystorageformat.h" #include "mymoneyinstitution.h" #include "mymoneypayee.h" #include "mymoneytag.h" #include "mymoneyaccount.h" #include "mymoneytransaction.h" #include "mymoneysplit.h" #include "mymoneyschedule.h" #include "mymoneysecurity.h" #include "mymoneyprice.h" #include "mymoneyreport.h" #include "mymoneybudget.h" #include "mymoneyfile.h" #include "mymoneykeyvaluecontainer.h" #include "mymoneymap.h" #include "mymoneymoney.h" #include "mymoneytransactionfilter.h" #include "mymoneydbdef.h" #include "mymoneydbdriver.h" #include "databasestoreableobject.h" class MyMoneyDbDriver; // This is a convenience functor to make it easier to use STL algorithms // It will return false if the MyMoneyTransaction DOES match the filter. // This functor may disappear when all filtering can be handled in SQL. class FilterFail { public: FilterFail(const MyMoneyTransactionFilter& filter) : m_filter(filter) {} inline bool operator()(const QPair& transactionPair) { return (*this)(transactionPair.second); } inline bool operator()(const MyMoneyTransaction& transaction) { return (! m_filter.match(transaction)) && (m_filter.matchingSplits().count() == 0); } private: MyMoneyTransactionFilter m_filter; }; class MyMoneyStorageSql; //***************************************************************************** // Create a class to handle db transactions using scope // // Don't let the database object get destroyed while this object exists, // that would result in undefined behavior. class MyMoneyDbTransaction { public: MyMoneyDbTransaction(MyMoneyStorageSql& db, const QString& name); ~MyMoneyDbTransaction(); private: MyMoneyStorageSql& m_db; QString m_name; }; /** * The MyMoneySqlQuery class is derived from QSqlQuery to provide * a way to adjust some queries based on database type and make * debugging easier by providing a place to put debug statements. */ class MyMoneySqlQuery : public QSqlQuery { public: MyMoneySqlQuery(MyMoneyStorageSql* db = 0); virtual ~MyMoneySqlQuery(); bool exec(); bool exec(const QString & query); bool prepare(const QString & query); }; class IMyMoneySerialize; /** * The MyMoneyDbColumn class is a base type for generic db columns. * Derived types exist for several common column types. * * @todo Remove unneeded columns which store the row count of tables from kmmFileInfo */ class MyMoneyStorageSql : public IMyMoneyStorageFormat, public QSqlDatabase, public QSharedData { friend class MyMoneyDbDef; KMM_MYMONEY_UNIT_TESTABLE public: explicit MyMoneyStorageSql(IMyMoneySerialize *storage, const QUrl& = QUrl()); virtual ~MyMoneyStorageSql(); unsigned int currentVersion() const { return (m_db.currentVersion()); }; /** * MyMoneyStorageSql - open database file * * @param url pseudo-URL of database to be opened * @param openMode open mode, same as for QFile::open * @param clear whether existing data can be deleted * @return 0 - database successfully opened * @return 1 - database not opened, use lastError function for reason * @return -1 - output database not opened, contains data, clean not specified * */ int open(const QUrl &url, int openMode, bool clear = false); /** * MyMoneyStorageSql close the database * * @return void * */ void close(bool logoff = true); /** * MyMoneyStorageSql read all the database into storage * * @return void * */ bool readFile(); /** * MyMoneyStorageSql write/update the database from storage * * @return void * */ bool writeFile(); /** * MyMoneyStorageSql generalized error routine * * @return : error message to be displayed * */ const QString& lastError() const { return (m_error); }; /** * MyMoneyStorageSql get highest ID number from the database * * @return : highest ID number */ long unsigned highestNumberFromIdString(QString tableName, QString tableField, int prefixLength); /** * This method is used when a database file is open, and the data is to * be saved in a different file or format. It will ensure that all data * from the database is available in memory to enable it to be written. */ virtual void fillStorage(); /** * The following functions correspond to the identically named (usually) functions * within the Storage Manager, and are called to update the database */ void modifyUserInfo(const MyMoneyPayee& payee); void addInstitution(const MyMoneyInstitution& inst); void modifyInstitution(const MyMoneyInstitution& inst); void removeInstitution(const MyMoneyInstitution& inst); void addPayee(const MyMoneyPayee& payee); void modifyPayee(MyMoneyPayee payee); void removePayee(const MyMoneyPayee& payee); void addTag(const MyMoneyTag& tag); void modifyTag(const MyMoneyTag& tag); void removeTag(const MyMoneyTag& tag); void addAccount(const MyMoneyAccount& acc); void modifyAccount(const MyMoneyAccount& acc); void removeAccount(const MyMoneyAccount& acc); void addTransaction(const MyMoneyTransaction& tx); void modifyTransaction(const MyMoneyTransaction& tx); void removeTransaction(const MyMoneyTransaction& tx); void addSchedule(const MyMoneySchedule& sch); void modifySchedule(const MyMoneySchedule& sch); void removeSchedule(const MyMoneySchedule& sch); void addSecurity(const MyMoneySecurity& sec); void modifySecurity(const MyMoneySecurity& sec); void removeSecurity(const MyMoneySecurity& sec); void addPrice(const MyMoneyPrice& p); void removePrice(const MyMoneyPrice& p); void addCurrency(const MyMoneySecurity& sec); void modifyCurrency(const MyMoneySecurity& sec); void removeCurrency(const MyMoneySecurity& sec); void addReport(const MyMoneyReport& rep); void modifyReport(const MyMoneyReport& rep); void removeReport(const MyMoneyReport& rep); void addBudget(const MyMoneyBudget& bud); void modifyBudget(const MyMoneyBudget& bud); void removeBudget(const MyMoneyBudget& bud); void addOnlineJob(const onlineJob& job); void modifyOnlineJob(const onlineJob& job); void removeOnlineJob(const onlineJob& job); void addPayeeIdentifier(payeeIdentifier& ident); void modifyPayeeIdentifier(const payeeIdentifier& ident); void removePayeeIdentifier(const payeeIdentifier& ident); unsigned long transactionCount(const QString& aid = QString()) const; inline const QHash transactionCountMap() const { return (m_transactionCountMap); }; /** * The following functions are perform the same operations as the * above functions, but on a QList of the items. * This reduces db round-trips, so should be the preferred method when * such a function exists. */ void modifyAccountList(const QList& acc); /** * the storage manager also needs the following read entry points */ const QMap fetchAccounts(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchBalance(const QStringList& id, const QDate& date) const; const QMap fetchBudgets(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchCurrencies(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchInstitutions(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchPayees(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchTags(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchOnlineJobs(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchCostCenters(const QStringList& idList = QStringList(), bool forUpdate = false) const; const MyMoneyPriceList fetchPrices(const QStringList& fromIdList = QStringList(), const QStringList& toIdList = QStringList(), bool forUpdate = false) const; MyMoneyPrice fetchSinglePrice(const QString& fromId, const QString& toId, const QDate& date_, bool exactDate, bool = false) const; const QMap fetchReports(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchSchedules(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchSecurities(const QStringList& idList = QStringList(), bool forUpdate = false) const; const QMap fetchTransactions(const QString& tidList = QString(), const QString& dateClause = QString(), bool forUpdate = false) const; const QMap fetchTransactions(const MyMoneyTransactionFilter& filter) const; payeeIdentifier fetchPayeeIdentifier(const QString& id) const; const QMap fetchPayeeIdentifiers(const QStringList& idList = QStringList()) const; bool isReferencedByTransaction(const QString& id) const; void readPayees(const QString&); void readPayees(const QList& payeeList = QList()); void readTags(const QString&); void readTags(const QList& tagList = QList()); void readTransactions(const MyMoneyTransactionFilter& filter); void setProgressCallback(void(*callback)(int, int, const QString&)); virtual void readFile(QIODevice* s, IMyMoneySerialize* storage) { Q_UNUSED(s); Q_UNUSED(storage) }; virtual void writeFile(QIODevice* s, IMyMoneySerialize* storage) { Q_UNUSED(s); Q_UNUSED(storage) }; void startCommitUnit(const QString& callingFunction); bool endCommitUnit(const QString& callingFunction); void cancelCommitUnit(const QString& callingFunction); long unsigned getRecCount(const QString& table) const; long unsigned getNextBudgetId() const; long unsigned getNextAccountId() const; long unsigned getNextInstitutionId() const; long unsigned getNextPayeeId() const; long unsigned getNextTagId() const; long unsigned getNextOnlineJobId() const; long unsigned getNextPayeeIdentifierId() const; long unsigned getNextReportId() const; long unsigned getNextScheduleId() const; long unsigned getNextSecurityId() const; long unsigned getNextTransactionId() const; long unsigned getNextCostCenterId() const; long unsigned incrementBudgetId(); long unsigned incrementAccountId(); long unsigned incrementInstitutionId(); long unsigned incrementPayeeId(); long unsigned incrementTagId(); long unsigned incrementReportId(); long unsigned incrementScheduleId(); long unsigned incrementSecurityId(); long unsigned incrementTransactionId(); long unsigned incrementOnlineJobId(); long unsigned incrementPayeeIdentfierId(); long unsigned incrementCostCenterId(); void loadAccountId(const unsigned long& id); void loadTransactionId(const unsigned long& id); void loadPayeeId(const unsigned long& id); void loadTagId(const unsigned long& id); void loadInstitutionId(const unsigned long& id); void loadScheduleId(const unsigned long& id); void loadSecurityId(const unsigned long& id); void loadReportId(const unsigned long& id); void loadBudgetId(const unsigned long& id); void loadOnlineJobId(const unsigned long& id); void loadPayeeIdentifierId(const unsigned long& id); void loadCostCenterId(const unsigned long& id); /** * This method allows to modify the precision with which prices * are handled within the object. The default of the precision is 4. */ static void setPrecision(int prec); /** * This method allows to modify the start date for transaction retrieval * The default of the precision is Jan 1st, 1900. */ static void setStartDate(const QDate &startDate); private: bool fileExists(const QString& dbName); /** @brief a function to build a comprehensive error message for an SQL error */ QString& buildError(const QSqlQuery& q, const QString& function, const QString& message) const; /** @copydoc buildError */ QString& buildError(const QSqlQuery& q, const QString& function, const QString& message, const QSqlDatabase*) const; /** * @name writeFromStorageMethods * @{ * These method write all data from m_storage to the database. Data which is * stored in the database is deleted. */ void writeUserInformation(); void writeInstitutions(); void writePayees(); void writeTags(); void writeAccounts(); void writeTransactions(); void writeSchedules(); void writeSecurities(); void writePrices(); void writeCurrencies(); void writeFileInfo(); void writeReports(); void writeBudgets(); void writeOnlineJobs(); /** @} */ /** * @name writeMethods * @{ * These methods bind the data fields of MyMoneyObjects to a given query and execute the query. * This is helpfull as the query has usually an update and a insert format. */ void writeInstitutionList(const QList& iList, QSqlQuery& q); void writePayee(const MyMoneyPayee& p, QSqlQuery& q, bool isUserInfo = false); void writeTag(const MyMoneyTag& p, QSqlQuery& q); void writeAccountList(const QList& accList, QSqlQuery& q); void writeTransaction(const QString& txId, const MyMoneyTransaction& tx, QSqlQuery& q, const QString& type); void writeSplits(const QString& txId, const QString& type, const QList& splitList); void writeTagSplitsList(const QString& txId, const QList& splitList, const QList& splitIdList); void writeSplitList(const QString& txId, const QList& splitList, const QString& type, const QList& splitIdList, QSqlQuery& q); void writeSchedule(const MyMoneySchedule& sch, QSqlQuery& q, bool insert); void writeSecurity(const MyMoneySecurity& security, QSqlQuery& q); void writePricePair(const MyMoneyPriceEntries& p); void writePrice(const MyMoneyPrice& p); void writeCurrency(const MyMoneySecurity& currency, QSqlQuery& q); void writeReport(const MyMoneyReport& rep, QSqlQuery& q); void writeBudget(const MyMoneyBudget& bud, QSqlQuery& q); void writeKeyValuePairs(const QString& kvpType, const QVariantList& kvpId, const QList >& pairs); void writeOnlineJob(const onlineJob& job, QSqlQuery& query); void writePayeeIdentifier(const payeeIdentifier& pid, QSqlQuery& query); /** @} */ /** * @name readMethods * @{ */ void readFileInfo(); void readLogonData(); void readUserInformation(); void readInstitutions(); void readAccounts(); void readTransactions(const QString& tidList = QString(), const QString& dateClause = QString()); void readSplit(MyMoneySplit& s, const QSqlQuery& q) const; const MyMoneyKeyValueContainer readKeyValuePairs(const QString& kvpType, const QString& kvpId) const; const QHash readKeyValuePairs(const QString& kvpType, const QStringList& kvpIdList) const; void readSchedules(); void readSecurities(); void readPrices(); void readCurrencies(); void readReports(); void readBudgets(); /** @} */ template long unsigned int getNextId(const QString& table, const QString& id, const int prefixLength) const; void deleteTransaction(const QString& id); void deleteTagSplitsList(const QString& txId, const QList& splitIdList); void deleteSchedule(const QString& id); void deleteKeyValuePairs(const QString& kvpType, const QVariantList& kvpId); long unsigned calcHighId(const long unsigned&, const QString&); void setVersion(const QString& version); void signalProgress(int current, int total, const QString& = "") const; void (*m_progressCallback)(int, int, const QString&); //void startCommitUnit (const QString& callingFunction); //void endCommitUnit (const QString& callingFunction); //void cancelCommitUnit (const QString& callingFunction); int splitState(const MyMoneyTransactionFilter::stateOptionE& state) const; inline const QDate getDate(const QString& date) const { return (date.isNull() ? QDate() : QDate::fromString(date, Qt::ISODate)); } inline const QDateTime getDateTime(const QString& date) const { return (date.isNull() ? QDateTime() : QDateTime::fromString(date, Qt::ISODate)); } // open routines /** * MyMoneyStorageSql create database * * @param url pseudo-URL of database to be opened * * @return true - creation successful * @return false - could not create * */ bool createDatabase(const QUrl &url); int upgradeDb(); int upgradeToV1(); int upgradeToV2(); int upgradeToV3(); int upgradeToV4(); int upgradeToV5(); int upgradeToV6(); int upgradeToV7(); int upgradeToV8(); int upgradeToV9(); int upgradeToV10(); int upgradeToV11(); int createTables(); void createTable(const MyMoneyDbTable& t, int version = std::numeric_limits::max()); bool alterTable(const MyMoneyDbTable& t, int fromVersion); void clean(); int isEmpty(); // for bug 252841 const QStringList tables(QSql::TableType tt) { return (m_driver->tables(tt, static_cast(*this))); }; /** * @brief Ensure the storagePlugin with iid was setup * * @throws MyMoneyException in case of an error which makes the use * of the plugin unavailable. */ bool setupStoragePlugin(QString iid); void insertStorableObject(const databaseStoreableObject& obj, const QString& id); void updateStorableObject(const databaseStoreableObject& obj, const QString& id); void deleteStorableObject(const databaseStoreableObject& obj, const QString& id); // data QExplicitlySharedDataPointer m_driver; MyMoneyDbDef m_db; unsigned int m_dbVersion; IMyMoneySerialize *m_storage; IMyMoneyStorage *m_storagePtr; // input options bool m_loadAll; // preload all data bool m_override; // override open if already in use // error message QString m_error; // record counts long unsigned m_institutions; long unsigned m_accounts; long unsigned m_payees; long unsigned m_tags; long unsigned m_transactions; long unsigned m_splits; long unsigned m_securities; long unsigned m_prices; long unsigned m_currencies; long unsigned m_schedules; long unsigned m_reports; long unsigned m_kvps; long unsigned m_budgets; long unsigned m_onlineJobs; long unsigned m_payeeIdentifier; // Cache for next id to use // value 0 means data is not available and has to be loaded from the database long unsigned m_hiIdInstitutions; long unsigned m_hiIdPayees; long unsigned m_hiIdTags; long unsigned m_hiIdAccounts; long unsigned m_hiIdTransactions; long unsigned m_hiIdSchedules; long unsigned m_hiIdSecurities; long unsigned m_hiIdReports; long unsigned m_hiIdBudgets; long unsigned m_hiIdOnlineJobs; long unsigned m_hiIdPayeeIdentifier; long unsigned m_hiIdCostCenter; // encrypt option - usage TBD QString m_encryptData; /** * This variable is used to suppress status messages except during * initial data load and final write */ bool m_displayStatus; void alert(QString s) const { qDebug() << s; }; // FIXME: remove... /** The following keeps track of commitment units (known as transactions in SQL * though it would be confusing to use that term within KMM). It is implemented * as a stack for debug purposes. Long term, probably a count would suffice */ QStack m_commitUnitStack; /** * This member variable is used to preload transactions for preferred accounts */ MyMoneyTransactionFilter m_preferred; /** * This member variable is used because reading prices from a file uses the 'add...' function rather than a * 'load...' function which other objects use. Having this variable allows us to avoid needing to check the * database to see if this really is a new or modified price */ bool m_readingPrices; /** * This member variable holds a map of transaction counts per account, indexed by * the account id. It is used * to avoid having to scan all transactions whenever a count is needed. It should * probably be moved into the MyMoneyAccount object; maybe we will do that once * the database code has been properly checked out */ QHash m_transactionCountMap; /** * These member variables hold the user name and date/time of logon */ QString m_logonUser; QDateTime m_logonAt; QDate m_txPostDate; // FIXME: remove when Tom puts date into split object //Disable copying MyMoneyStorageSql(const MyMoneyStorageSql& rhs); MyMoneyStorageSql& operator= (const MyMoneyStorageSql& rhs); bool m_newDatabase; /** * This member keeps the current precision to be used fro prices. * @sa setPrecision() */ static int m_precision; /** * This member keeps the current start date used for transaction retrieval. * @sa setStartDate() */ static QDate m_startDate; /** * */ QSet m_loadedStoragePlugins; }; #endif // MYMONEYSTORAGESQL_H diff --git a/kmymoney/mymoney/tests/onlinejob-test.cpp b/kmymoney/mymoney/tests/onlinejob-test.cpp index ed38827a2..6245c8537 100644 --- a/kmymoney/mymoney/tests/onlinejob-test.cpp +++ b/kmymoney/mymoney/tests/onlinejob-test.cpp @@ -1,103 +1,103 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejob-test.h" #include #define KMM_MYMONEY_UNIT_TESTABLE friend class onlineJobTest; #include "onlinejob.h" #include "onlinetasks/dummy/tasks/dummytask.h" QTEST_GUILESS_MAIN(onlineJobTest) void onlineJobTest::testDefaultConstructor() { const onlineJob job = onlineJob(); QVERIFY(job.id() == MyMoneyObject::emptyId()); QVERIFY(job.isNull()); QVERIFY(job.sendDate().isNull()); QVERIFY(job.bankAnswerDate().isNull()); QVERIFY(job.bankAnswerState() == onlineJob::noBankAnswer); QVERIFY(job.jobMessageList().isEmpty()); QVERIFY(job.isLocked() == false); } void onlineJobTest::testCopyConstructor() { onlineJob originalJob = onlineJob(new dummyTask, "O000001"); QVERIFY(!originalJob.isNull()); QVERIFY(originalJob.task()); onlineJob jobCopy = onlineJob(originalJob); QVERIFY(!jobCopy.isNull()); QCOMPARE(jobCopy.id(), QString("O000001")); QVERIFY(originalJob.task() != jobCopy.task()); } void onlineJobTest::testCopyAssignment() { onlineJob originalJob = onlineJob(new dummyTask, "O000001"); QVERIFY(!originalJob.isNull()); QVERIFY(originalJob.task()); onlineJob jobCopy; jobCopy = originalJob; QVERIFY(!jobCopy.isNull()); QCOMPARE(jobCopy.id(), QString("O000001")); QVERIFY(originalJob.task() != jobCopy.task()); } void onlineJobTest::testCopyConstructorWithNewId() { onlineJob originalJob = onlineJob(new dummyTask, "O000001"); originalJob.setBankAnswer(onlineJob::acceptedByBank); QVERIFY(!originalJob.isNull()); onlineJob jobCopy = onlineJob("O000002", originalJob); QVERIFY(!jobCopy.isNull()); QCOMPARE(jobCopy.id(), QString("O000002")); QVERIFY(originalJob.task() != jobCopy.task()); QVERIFY(jobCopy.bankAnswerDate().isNull()); } void onlineJobTest::testElementNames() { QMetaEnum e = QMetaEnum::fromType(); for (int i = 0; i < e.keyCount(); ++i) { bool isEmpty = onlineJob::getElName(static_cast(e.value(i))).isEmpty(); if (isEmpty) qWarning() << "Empty element's name" << e.key(i); QVERIFY(!isEmpty); } } void onlineJobTest::testAttributeNames() { QMetaEnum e = QMetaEnum::fromType(); for (int i = 0; i < e.keyCount(); ++i) { bool isEmpty = onlineJob::getAttrName(static_cast(e.value(i))).isEmpty(); if (isEmpty) qWarning() << "Empty attribute's name" << e.key(i); QVERIFY(!isEmpty); } } diff --git a/kmymoney/mymoney/tests/onlinejob-test.h b/kmymoney/mymoney/tests/onlinejob-test.h index b763d7334..45b261ccc 100644 --- a/kmymoney/mymoney/tests/onlinejob-test.h +++ b/kmymoney/mymoney/tests/onlinejob-test.h @@ -1,41 +1,41 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBTEST_H #define ONLINEJOBTEST_H #include #include class onlineJobTest : public QObject { Q_OBJECT private slots: // void initTestCase(); // void cleanupTestCase(); void testDefaultConstructor(); void testCopyConstructor(); void testCopyAssignment(); void testCopyConstructorWithNewId(); void testElementNames(); void testAttributeNames(); }; #endif // ONLINEJOBTEST_H diff --git a/kmymoney/mymoney/tests/onlinejobadministration-test.cpp b/kmymoney/mymoney/tests/onlinejobadministration-test.cpp index 1e8f075eb..d9b8befd8 100644 --- a/kmymoney/mymoney/tests/onlinejobadministration-test.cpp +++ b/kmymoney/mymoney/tests/onlinejobadministration-test.cpp @@ -1,72 +1,72 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobadministration-test.h" #include #include "onlinejobadministration.h" #include "mymoney/mymoneyfile.h" #include "mymoney/storage/mymoneyseqaccessmgr.h" #include "onlinetasks/dummy/tasks/dummytask.h" QTEST_GUILESS_MAIN(onlineJobAdministrationTest) void onlineJobAdministrationTest::initTestCase() { file = MyMoneyFile::instance(); storage = new MyMoneySeqAccessMgr; file->attachStorage(storage); try { MyMoneyAccount account = MyMoneyAccount(); account.setName("Test Account"); account.setAccountType(MyMoneyAccount::Savings); MyMoneyAccount asset = file->asset(); MyMoneyFileTransaction transaction; file->addAccount(account , asset); accountId = account.id(); transaction.commit(); } catch (const MyMoneyException& ex) { QFAIL(qPrintable("Unexpected exception " + ex.what())); } } void onlineJobAdministrationTest::cleanupTestCase() { file->detachStorage(storage); delete storage; } void onlineJobAdministrationTest::init() { qDeleteAll(onlineJobAdministration::instance()->m_onlineTasks); onlineJobAdministration::instance()->m_onlineTasks.clear(); } void onlineJobAdministrationTest::getSettings() { } void onlineJobAdministrationTest::registerOnlineTask() { dummyTask *task = new dummyTask; onlineJobAdministration::instance()->registerOnlineTask(task); QCOMPARE(onlineJobAdministration::instance()->m_onlineTasks.count(), 1); QVERIFY(onlineJobAdministration::instance()->m_onlineTasks.value(task->taskName())); } diff --git a/kmymoney/mymoney/tests/onlinejobadministration-test.h b/kmymoney/mymoney/tests/onlinejobadministration-test.h index 4170e5e44..d0d5b9fc2 100644 --- a/kmymoney/mymoney/tests/onlinejobadministration-test.h +++ b/kmymoney/mymoney/tests/onlinejobadministration-test.h @@ -1,45 +1,45 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBADMINISTRATIONTEST_H #define ONLINEJOBADMINISTRATIONTEST_H #include #include class MyMoneyFile; class IMyMoneyStorage; #define KMM_MYMONEY_UNIT_TESTABLE friend class onlineJobAdministrationTest; class onlineJobAdministrationTest : public QObject { Q_OBJECT IMyMoneyStorage* storage; MyMoneyFile* file; QString accountId; private slots: void initTestCase(); void cleanupTestCase(); void init(); void getSettings(); void registerOnlineTask(); }; #endif // ONLINEJOBADMINISTRATIONTEST_H diff --git a/kmymoney/mymoney/tests/onlinejobtyped-test.cpp b/kmymoney/mymoney/tests/onlinejobtyped-test.cpp index efb910947..b0609c0f4 100644 --- a/kmymoney/mymoney/tests/onlinejobtyped-test.cpp +++ b/kmymoney/mymoney/tests/onlinejobtyped-test.cpp @@ -1,135 +1,135 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobtyped-test.h" #include #include "onlinejobtyped.h" #include "onlinetasks/dummy/tasks/dummytask.h" QTEST_GUILESS_MAIN(onlineJobTypedTest) class dummyTask2 : public dummyTask {}; class onlineTaskInterface {}; class onlineTaskDummy3 : public onlineTask, public onlineTaskInterface { public: ONLINETASK_META(dummyTask, "org.kmymoney.onlinetasks.dummytask"); virtual bool isValid() const { return true; } virtual QString jobTypeName() const { return QLatin1String("Dummy credit transfer"); } virtual QString storagePluginIid() const { return QString(); } virtual bool sqlModify(QSqlDatabase, const QString&) const { return false; } virtual bool sqlSave(QSqlDatabase, const QString&) const { return false; } virtual bool sqlRemove(QSqlDatabase, const QString&) const { return false; } protected: virtual onlineTaskDummy3* clone() const { return (new onlineTaskDummy3); } virtual bool hasReferenceTo(const QString&) const { return false; } virtual void writeXML(QDomDocument&, QDomElement&) const {} virtual onlineTaskDummy3* createFromXml(const QDomElement &) const { return (new onlineTaskDummy3); } virtual onlineTask* createFromSqlDatabase(QSqlDatabase, const QString&) const { return (new onlineTaskDummy3); } virtual QString responsibleAccount() const { return QString(); }; }; void onlineJobTypedTest::initTestCase() { } void onlineJobTypedTest::cleanupTestCase() { } void onlineJobTypedTest::copyContructor() { dummyTask* task = new dummyTask; onlineJobTyped job(task); QVERIFY(!job.isNull()); QVERIFY(job.m_task == task); } void onlineJobTypedTest::constructWithIncompatibleType() { try { onlineJobTyped job(new dummyTask); QFAIL("Missing expected exception"); } catch (const onlineJob::badTaskCast&) { } catch (...) { QFAIL("Wrong exception thrown"); } } void onlineJobTypedTest::constructWithNull() { try { onlineJobTyped job(0); QFAIL("Missing expected exception"); } catch (const onlineJob::emptyTask&) { } catch (...) { QFAIL("Wrong exception thrown"); } } void onlineJobTypedTest::copyByAssignment() { dummyTask* task = new dummyTask; task->setTestNumber(8888); onlineJobTyped job(new dummyTask); job = onlineJobTyped(task); QVERIFY(!job.isNull()); QVERIFY(dynamic_cast(job.task())); QCOMPARE(job.task()->testNumber(), 8888); } void onlineJobTypedTest::constructWithManadtoryDynamicCast() { onlineJob job(new onlineTaskDummy3); try { onlineJobTyped jobTyped(job); } catch (...) { QFAIL("Unexpected exception"); } } diff --git a/kmymoney/mymoney/tests/onlinejobtyped-test.h b/kmymoney/mymoney/tests/onlinejobtyped-test.h index cf6f65f45..9d1bef81e 100644 --- a/kmymoney/mymoney/tests/onlinejobtyped-test.h +++ b/kmymoney/mymoney/tests/onlinejobtyped-test.h @@ -1,40 +1,40 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBTYPEDTEST_H #define ONLINEJOBTYPEDTEST_H #include "QtCore/QObject" #define KMM_MYMONEY_UNIT_TESTABLE friend class onlineJobTypedTest; class onlineJobTypedTest : public QObject { Q_OBJECT private slots: void initTestCase(); void cleanupTestCase(); void copyContructor(); void constructWithIncompatibleType(); void constructWithNull(); void copyByAssignment(); void constructWithManadtoryDynamicCast(); }; #endif // ONLINEJOBTYPEDTEST_H diff --git a/kmymoney/payeeidentifier/ibanandbic/bicmodel.cpp b/kmymoney/payeeidentifier/ibanandbic/bicmodel.cpp index 836d28efc..ed32e63a3 100644 --- a/kmymoney/payeeidentifier/ibanandbic/bicmodel.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/bicmodel.cpp @@ -1,112 +1,112 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "bicmodel.h" #include #include #include #include #include #include #include /** * @warning At the moment the completion may fail if bicModel was created in more than one thread * (it uses a QSqlDatabase object over all instances of bicModel, so the first created bicModel defines * the thread) * * @todo Make thread safe. */ bicModel::bicModel(QObject* parent) : QSqlQueryModel(parent) { QSqlDatabase db = QSqlDatabase::database("bicModel", true); // Save if the database was opened before bool attachDatabases = false; if (!db.isValid()) { db = QSqlDatabase::addDatabase("QSQLITE", "bicModel"); db.setDatabaseName(":memory:"); db.setConnectOptions("QSQLITE_OPEN_READONLY=1;QSQLITE_ENABLE_SHARED_CACHE=1;"); db.open(); // Database was not opened before attachDatabases = true; } if (!db.isOpen()) { qWarning() << QString("Could not open in-memory database for bic data."); } QSqlQuery query(db); // Get services which support iban2bic and have a database entry KService::List services = KServiceTypeTrader::self()->query("KMyMoney/IbanBicData", QString("exist [X-KMyMoney-Bankdata-Database]") ); if (services.isEmpty()) { // Set a valid query query.exec("SELECT null;"); setQuery(query); return; } QStringList databases; QStringList dbNames; unsigned int databaseCount = 0; foreach (KService::Ptr service, services) { QString database = service->property(QLatin1String("X-KMyMoney-Bankdata-Database")).toString(); // Locate database QString path = QStandardPaths::locate(QStandardPaths::DataLocation, QLatin1String("kmymoney/ibanbicdata/") + database); if (path.isEmpty()) { qWarning() << QString("Could not locate database file \"%1\" to receive BIC data.").arg(database); } else { databases << path; dbNames << QString("db%1").arg(++databaseCount); } } if (attachDatabases) { query.prepare("ATTACH DATABASE ? AS ?"); query.addBindValue(databases); query.addBindValue(dbNames); if (!query.execBatch()) { qWarning() << "Could not init bic for bicModel, last error:" << query.lastError().text(); dbNames = QStringList(); // clear so no query will be set } } QStringList queries; foreach (QString dbName, dbNames) { queries.append(QString("SELECT bic, name FROM %1.institutions").arg(dbName)); } query.exec(queries.join(QLatin1String(" UNION "))); setQuery(query); } QVariant bicModel::data(const QModelIndex& item, int role) const { if (role == InstitutionNameRole) return QSqlQueryModel::data(createIndex(item.row(), 1), Qt::DisplayRole); return QSqlQueryModel::data(item, role); } diff --git a/kmymoney/payeeidentifier/ibanandbic/bicmodel.h b/kmymoney/payeeidentifier/ibanandbic/bicmodel.h index 572963372..a85521ae5 100644 --- a/kmymoney/payeeidentifier/ibanandbic/bicmodel.h +++ b/kmymoney/payeeidentifier/ibanandbic/bicmodel.h @@ -1,40 +1,40 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BICMODEL_H #define BICMODEL_H #include #include "iban_bic_identifier_export.h" class IBAN_BIC_IDENTIFIER_EXPORT bicModel : public QSqlQueryModel { Q_OBJECT public: enum DisplayRole { InstitutionNameRole = Qt::UserRole }; explicit bicModel(QObject* parent = 0); virtual QVariant data(const QModelIndex& item, int role = Qt::DisplayRole) const; }; #endif // BICMODEL_H diff --git a/kmymoney/payeeidentifier/ibanandbic/ibanbic.cpp b/kmymoney/payeeidentifier/ibanandbic/ibanbic.cpp index 3bf4ff6dc..b269a1da4 100644 --- a/kmymoney/payeeidentifier/ibanandbic/ibanbic.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/ibanbic.cpp @@ -1,372 +1,372 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ibanbic.h" #include #include #include #include #include #include #include "ibanbicdata.h" #include "mymoney/mymoneyexception.h" namespace payeeIdentifiers { ibanBicData* ibanBic::m_ibanBicData = 0; const int ibanBic::ibanMaxLength = 30; ibanBic::ibanBic() { } ibanBic::ibanBic(const ibanBic& other) : payeeIdentifierData(other), m_bic(other.m_bic), m_iban(other.m_iban), m_ownerName(other.m_ownerName) { } bool ibanBic::operator==(const payeeIdentifierData& other) const { try { const ibanBic otherCasted = dynamic_cast(other); return operator==(otherCasted); } catch (const std::bad_cast&) { } return false; } bool ibanBic::operator==(const ibanBic& other) const { return (m_iban == other.m_iban && m_bic == other.m_bic && m_ownerName == other.m_ownerName); } ibanBic* ibanBic::clone() const { return (new ibanBic(*this)); } payeeIdentifierData* ibanBic::createFromSqlDatabase(QSqlDatabase db, const QString& identId) const { QSqlQuery query(db); query.prepare("SELECT iban, bic, name FROM kmmIbanBic WHERE id = ?;"); query.bindValue(0, identId); if (!query.exec() || !query.next()) { qWarning("Could load iban bic identifier from database"); return 0; } ibanBic *const ident = new ibanBic; ident->setIban(query.value(0).toString()); ident->setBic(query.value(1).toString()); ident->setOwnerName(query.value(2).toString()); return ident; } ibanBic* ibanBic::createFromXml(const QDomElement& element) const { ibanBic* ident = new ibanBic; ident->setBic(element.attribute("bic", QString())); ident->setIban(element.attribute("iban", QString())); ident->setOwnerName(element.attribute("ownerName", QString())); return ident; } void ibanBic::writeXML(QDomDocument& document, QDomElement& parent) const { Q_UNUSED(document); parent.setAttribute("iban", m_iban); if (!m_bic.isEmpty()) parent.setAttribute("bic", m_bic); if (!m_ownerName.isEmpty()) parent.setAttribute("ownerName", m_ownerName); } bool ibanBic::writeQuery(QSqlQuery& query, const QString& id) const { query.bindValue(":id", id); query.bindValue(":iban", electronicIban()); const QString bic = fullStoredBic(); query.bindValue(":bic", (bic.isEmpty()) ? QVariant(QVariant::String) : bic); query.bindValue(":name", ownerName()); if (!query.exec()) { qWarning("Error while saving ibanbic data for '%s': %s", qPrintable(id), qPrintable(query.lastError().text())); return false; } return true; } bool ibanBic::sqlSave(QSqlDatabase databaseConnection, const QString& objectId) const { QSqlQuery query(databaseConnection); query.prepare("INSERT INTO kmmIbanBic " " ( id, iban, bic, name )" " VALUES( :id, :iban, :bic, :name ) " ); return writeQuery(query, objectId); } bool ibanBic::sqlModify(QSqlDatabase databaseConnection, const QString& objectId) const { QSqlQuery query(databaseConnection); query.prepare("UPDATE kmmIbanBic SET iban = :iban, bic = :bic, name = :name WHERE id = :id;"); return writeQuery(query, objectId); } bool ibanBic::sqlRemove(QSqlDatabase databaseConnection, const QString& objectId) const { QSqlQuery query(databaseConnection); query.prepare("DELETE FROM kmmIbanBic WHERE id = ?;"); query.bindValue(0, objectId); if (!query.exec()) { qWarning("Error while deleting ibanbic data '%s': %s", qPrintable(objectId), qPrintable(query.lastError().text())); return false; } return true; } QString ibanBic::paperformatIban(const QString& seperator) const { return ibanToPaperformat(m_iban, seperator); } void ibanBic::setIban(const QString& iban) { m_iban = ibanToElectronic(iban); } void ibanBic::setBic(const QString& bic) { m_bic = canonizeBic(bic); } QString ibanBic::canonizeBic(const QString& bic) { QString canonizedBic = bic.toUpper(); if (canonizedBic.length() == 11 && canonizedBic.endsWith(QLatin1String("XXX"))) canonizedBic = canonizedBic.left(8); return canonizedBic; } QString ibanBic::fullStoredBic() const { if (m_bic.length() == 8) return (m_bic + QLatin1String("XXX")); return m_bic; } QString ibanBic::fullBic() const { if (m_bic.isNull()) { return getIbanBicData()->iban2Bic(m_iban); } return fullStoredBic(); } QString ibanBic::bic() const { if (m_bic.isNull()) { const QString bic = getIbanBicData()->iban2Bic(m_iban); if (bic.length() == 11 && bic.endsWith(QLatin1String("XXX"))) return bic.left(8); return bic; } return m_bic; } inline bool madeOfLettersAndNumbersOnly(const QString& string) { const int length = string.length(); for (int i = 0; i < length; ++i) { if (!string.at(i).isLetterOrNumber()) return false; } return true; } bool ibanBic::isValid() const { Q_ASSERT(m_iban == ibanToElectronic(m_iban)); // Check BIC const int bicLength = m_bic.length(); if (bicLength != 8 && bicLength != 11) return false; for (int i = 0; i < 6; ++i) { if (!m_bic.at(i).isLetter()) return false; } for (int i = 6; i < bicLength; ++i) { if (!m_bic.at(i).isLetterOrNumber()) return false; } // Check IBAN const int ibanLength = m_iban.length(); if (ibanLength < 5 || ibanLength > 32) return false; if (!madeOfLettersAndNumbersOnly(m_iban)) return false; /** @todo checksum */ return true; } bool ibanBic::isIbanValid() const { return isIbanValid(m_iban); } bool ibanBic::isIbanValid(const QString& iban) { return validateIbanChecksum(ibanToElectronic(iban)); } QString ibanBic::ibanToElectronic(const QString& iban) { QString canonicalIban; const int length = iban.length(); for (int i = 0; i < length; ++i) { const QChar letter = iban.at(i); if (letter.isLetterOrNumber()) canonicalIban.append(letter.toUpper()); } return canonicalIban; } QString ibanBic::ibanToPaperformat(const QString& iban, const QString& separator) { QString paperformat; const int length = iban.length(); int letterCounter = 0; for (int i = 0; i < length; ++i) { const QChar letter = iban.at(i); if (letter.isLetterOrNumber()) { ++letterCounter; if (letterCounter == 5) { paperformat.append(separator); letterCounter = 1; } paperformat.append(letter); } } if (paperformat.length() >= 2) { paperformat[0] = paperformat[0].toUpper(); paperformat[1] = paperformat[1].toUpper(); } return paperformat; } QString ibanBic::bban(const QString& iban) { return iban.mid(4); } bool ibanBic::validateIbanChecksum(const QString& iban) { Q_ASSERT(iban == ibanToElectronic(iban)); // Reorder QString reordered = iban.mid(4) + iban.left(4); // Replace letters for (int i = 0; i < reordered.length(); ++i) { if (reordered.at(i).isLetter()) { // Replace charactes A -> 10, ..., Z -> 35 reordered.replace(i, 1, QString::number(reordered.at(i).toLatin1() - 'A' + 10)); ++i; // the inserted number is always two characters long, jump beyond } } // Calculations try { mpz_class number(reordered.toLatin1().constData(), 10); return (number % 97 == 1); } catch (std::invalid_argument&) { // This can happen if the given iban contains incorrect data } return false; } ibanBicData* ibanBic::getIbanBicData() { if (m_ibanBicData == 0) m_ibanBicData = new ibanBicData; Q_CHECK_PTR(m_ibanBicData); return m_ibanBicData; } int ibanBic::ibanLengthByCountry(const QString& countryCode) { return (getIbanBicData()->bbanLength(countryCode) + 4); } QString ibanBic::bicByIban(const QString& iban) { return getIbanBicData()->iban2Bic(iban); } QString ibanBic::institutionNameByBic(const QString& bic) { return getIbanBicData()->bankNameByBic(bic); } QString ibanBic::bicToFullFormat(QString bic) { bic = bic.toUpper(); if (bic.length() == 8) return (bic + QLatin1String("XXX")); return bic; } ibanBic::bicAllocationStatus ibanBic::isCanonicalBicAllocated(const QString& bic) { Q_ASSERT(bic == bicToFullFormat(bic)); switch (getIbanBicData()->isBicAllocated(bic)) { case ibanBicData::bicAllocated: return bicAllocated; case ibanBicData::bicNotAllocated: return bicNotAllocated; case ibanBicData::bicAllocationUncertain: return bicAllocationUncertain; } return bicAllocationUncertain; } ibanBic::bicAllocationStatus ibanBic::isBicAllocated(const QString& bic) { if (bic.length() != 8 && bic.length() != 11) return bicNotAllocated; return isCanonicalBicAllocated(bicToFullFormat(bic)); } } // namespace payeeIdentifiers diff --git a/kmymoney/payeeidentifier/ibanandbic/ibanbic.h b/kmymoney/payeeidentifier/ibanandbic/ibanbic.h index 013048347..653731fa0 100644 --- a/kmymoney/payeeidentifier/ibanandbic/ibanbic.h +++ b/kmymoney/payeeidentifier/ibanandbic/ibanbic.h @@ -1,271 +1,271 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIER_IBANBIC_H #define PAYEEIDENTIFIER_IBANBIC_H #include #include #include "payeeidentifier/payeeidentifierdata.h" #include "mymoneyunittestable.h" #include "iban_bic_identifier_export.h" class ibanBicData; namespace payeeIdentifiers { /** * @brief Plugin to handle IBANs and BICs * * Can store a pair of an International Bank Account Number (ISO 13616) and Business Identifier Code (ISO 9362). * */ class IBAN_BIC_IDENTIFIER_EXPORT ibanBic : public payeeIdentifierData { KMM_MYMONEY_UNIT_TESTABLE public: PAYEEIDENTIFIER_IID(ibanBic, "org.kmymoney.payeeIdentifier.ibanbic"); enum bicAllocationStatus { bicAllocated = 0, bicNotAllocated, bicAllocationUncertain }; ibanBic(); ibanBic(const ibanBic& other); ibanBic* clone() const; ibanBic* createFromXml(const QDomElement& element) const; void writeXML(QDomDocument& document, QDomElement& parent) const; /** * @brief Set an owner name for this account */ void setOwnerName(const QString& ownerName) { m_ownerName = ownerName; } QString ownerName() const { return m_ownerName; } /** * @brief Set a IBAN * * The IBAN can contain spaces and other special chars. */ void setIban(const QString& iban); /** @copydoc m_iban * Use this method if you know that iban is in electronic format already. No futher checks are done. */ void setElectronicIban(const QString& iban) { Q_ASSERT(iban == ibanToElectronic(iban)); m_iban = iban; } /** @copydoc m_iban */ QString electronicIban() const { return m_iban; } /** * @brief Returns iban in human readable format * @see toPaperformatIban() */ QString paperformatIban(const QString& separator = QLatin1String(" ")) const; /** * @brief Set Business Identifier Code * * Call without parameter or QString() to remove bic * * @param bic will be normalized */ void setBic(const QString& bic = QString()); /** * @brief Business Identifier Code * According to ISO 9362 * * The returned bic is normalized: * A tailing XXX is omitted, all characters are uppercase. */ QString storedBic() const { return m_bic; } /** * @copydoc storedBic() * * Return a stored BIC (if there is any) or try to use the iban to get a BIC. */ QString bic() const; /** * @brief Business Identifier Code with tailing XXX * * Like @a bic() but always 11 characters long (if bic is invalid, it can have another length). */ QString fullBic() const; /** * @copydoc fullBic() * * This method will not try to use the iban to get a bic. */ QString fullStoredBic() const; /** * @brief Lookup institutions name * * Uses any available information to return an institutionName */ QString institutionName() const { return institutionNameByBic(bic()); } virtual bool operator==(const payeeIdentifierData& other) const; bool operator==(const ibanBic& other) const; virtual bool isValid() const; /** * @brief Extends a bic to 11 characters * * Also all characters are made upper case. */ static QString bicToFullFormat(QString bic); /** * @brief Converts an iban to canonical format for machines * * Will remove all white spaces. */ static QString ibanToElectronic(const QString& iban); /** * @brief Converts an iban to human readable format * * Grouped in four letters strings separated by a white space. * * @param iban an iban, not needed to be canonical, valid or completed * @param separator Overwrite the default separator (e.g. a smaller space) */ static QString ibanToPaperformat(const QString& iban, const QString& seperator = QLatin1String(" ")); /** * @brief Extract Basic Bank Account Number * * Returns the Basic Bank Account Number (BBAN) from the IBAN. * The BBAN is the IBAN without country code and the two digit checksum. */ static QString bban(const QString& iban); static int ibanLengthByCountry(const QString& countryCode); static QString institutionNameByBic(const QString& bic); static QString bicByIban(const QString& iban); static QString localBankCodeByIban(const QString& iban); /** * @brief Chech if IBAN is valid */ bool isIbanValid() const; /** * @brief Check if IBAN can be valid * * This method also checks if the given country code is valid. * * If also local aware checks are done (e.g. character set and length of BBAN). * * @todo Implement local aware checks */ static bool isIbanValid(const QString& iban); /** * @brief Check if this BIC is assigned to an bank * * This method does not check the given BIC but looks up in the database directly. * So it might be useful if time consumption is important but isBicAllocated() should * be your first option. * * @param bic BIC to test in canonical format (always 11 characters long, all characters uppercase) * @see isBicAllocated() */ static bicAllocationStatus isCanonicalBicAllocated(const QString& bic); /** @brief Check if this BIC is assigned to an bank * * @param bic BIC to test. */ static bicAllocationStatus isBicAllocated(const QString& bic); /** * @brief Check the checksum * * Test if the ISO 7064 mod 97-10 checksum of the iban is correct. * * @param iban An IBAN in electronic format (important!) */ static bool validateIbanChecksum(const QString& iban); static const int ibanMaxLength; QString storagePluginIid() const { return QLatin1String("org.kmymoney.payeeIdentifier.ibanbic.sqlStoragePlugin"); } bool sqlSave(QSqlDatabase databaseConnection, const QString& objectId) const; bool sqlModify(QSqlDatabase databaseConnection, const QString& objectId) const; bool sqlRemove(QSqlDatabase databaseConnection, const QString& objectId) const; private: /** * @brief Business Identifier Code * According to ISO 9362 * * A trailing XXX must be ommitted. All characters must be upper case. */ QString m_bic; /** * @brief International Bank Account Number * According to ISO 13616-1:2007 Part 1 * in normalized (electronic) format (no spaces etc.) */ QString m_iban; QString m_ownerName; static ::ibanBicData* getIbanBicData(); static ::ibanBicData* m_ibanBicData; bool writeQuery(QSqlQuery& query, const QString& id) const; payeeIdentifierData* createFromSqlDatabase(QSqlDatabase db, const QString& identId) const; static QString canonizeBic(const QString& bic); }; } // namespace payeeIdentifiers #endif // PAYEEIDENTIFIER_IBANBIC_H diff --git a/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.cpp b/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.cpp index 2bd5bd8b5..99ad4f95f 100644 --- a/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.cpp @@ -1,276 +1,276 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ibanbicdata.h" #include #include #include #include #include #include "ibanbic.h" ibanBicData::~ibanBicData() { } int ibanBicData::bankIdentifierLength(const QString& countryCode) { const QVariant value = findPropertyByCountry(countryCode, QLatin1String("X-KMyMoney-BankIdentifier-Length"), QVariant::Int); if (value.isValid()) return value.toInt(); return 0; } int ibanBicData::bankIdentifierPosition(const QString& countryCode) { const QVariant value = findPropertyByCountry(countryCode, QLatin1String("X-KMyMoney-BankIdentifier-Position"), QVariant::Int); if (value.isValid()) return value.toInt(); return -1; } int ibanBicData::bbanLength(const QString& countryCode) { const QVariant value = findPropertyByCountry(countryCode, QLatin1String("X-KMyMoney-BBAN-Length"), QVariant::Int); if (value.isValid()) return value.toInt(); // Something went wrong, so return the allowed maximum return 30; } QString ibanBicData::iban2Bic(const QString& iban) { Q_ASSERT(iban.length() < 1 || iban.at(0).isLetterOrNumber()); Q_ASSERT(iban.length() < 2 || iban.at(1).isLetterOrNumber()); Q_ASSERT(iban == payeeIdentifiers::ibanBic::ibanToElectronic(iban)); if (iban.length() <= 4) // This iban is to short to extract a BIC return QString(""); // Get bank identifier const QString bankCode = extractBankIdentifier(iban); if (bankCode.isEmpty()) return bankCode; // keep .isEmpty() or .isNull() // Get countryCode const QString countryCode = iban.left(2); // Get services which support iban2bic and have a database entry KService::List services = KServiceTypeTrader::self()->query("KMyMoney/IbanBicData", QString("(\'%1' ~in [X-KMyMoney-CountryCodes] or '*' in [X-KMyMoney-CountryCodes]) and true == [X-KMyMoney-IBAN-2-BIC-supported] and exist [X-KMyMoney-Bankdata-Database]").arg(countryCode) ); if (services.isEmpty()) return QString(); QSqlDatabase db = createDatabaseConnection(services.first()->property(QLatin1String("X-KMyMoney-Bankdata-Database"), QVariant::String).toString()); if (!db.isOpen()) // This is an error return QString(); QSqlQuery query = QSqlQuery(db); query.prepare("SELECT bic FROM institutions WHERE bankcode=? and country=?"); query.bindValue(0, bankCode); query.bindValue(1, countryCode); if (!query.exec()) { qWarning() << QString("Could not execute query on \"%1\" to receive BIC. Error: %2").arg(db.databaseName()).arg(query.lastError().text()); return QString(); } if (query.next()) { return query.value(0).toString(); } return QString(""); } QString ibanBicData::bankNameByBic(QString bic) { if (bic.length() == 8) bic += QLatin1String("XXX"); else if (bic.length() != 11) return QString(); const QString countryCode = bic.mid(4, 2); // Get services which have a database entry KService::List services = KServiceTypeTrader::self()->query("KMyMoney/IbanBicData", QString("(\'%1' ~in [X-KMyMoney-CountryCodes] or '*' in [X-KMyMoney-CountryCodes]) and exist [X-KMyMoney-Bankdata-Database]").arg(countryCode) ); if (services.isEmpty()) return QString(); QSqlDatabase db = createDatabaseConnection(services.first()->property("X-KMyMoney-Bankdata-Database", QVariant::String).toString()); if (!db.isOpen()) // This is an error return QString(); QSqlQuery query = QSqlQuery(db); query.prepare("SELECT name FROM institutions WHERE bic=?"); query.bindValue(0, bic); if (!query.exec()) { qWarning() << QString("Could not execute query on \"%1\" to receive bank name. Error: %2").arg(db.databaseName()).arg(query.lastError().text()); return QString(); } if (query.next()) { return query.value(0).toString(); } return QString(""); } QPair< QString, QString > ibanBicData::bankNameAndBic(const QString& iban) { Q_ASSERT(iban.length() < 1 || iban.at(0).isLetterOrNumber()); Q_ASSERT(iban.length() < 2 || iban.at(1).isLetterOrNumber()); Q_ASSERT(iban == payeeIdentifiers::ibanBic::ibanToElectronic(iban)); if (iban.length() <= 4) // This iban is to short to extract a BIC return QPair(); // Get bank identifier const QString bankCode = extractBankIdentifier(iban); if (bankCode.isEmpty()) return QPair(bankCode, bankCode); // keep .isEmpty() or .isNull() // Get countryCode const QString countryCode = iban.left(2); // Get services which support iban2bic and have a database entry KService::List services = KServiceTypeTrader::self()->query("KMyMoney/IbanBicData", QString("(\'%1' ~in [X-KMyMoney-CountryCodes] or '*' in [X-KMyMoney-CountryCodes]) and true == [X-KMyMoney-IBAN-2-BIC-supported] and exist [X-KMyMoney-Bankdata-Database]").arg(countryCode) ); if (services.isEmpty()) return QPair(); QSqlDatabase db = createDatabaseConnection(services.first()->property(QLatin1String("X-KMyMoney-Bankdata-Database"), QVariant::String).toString()); if (!db.isOpen()) // This is an error return QPair(); QSqlQuery query(db); query.prepare("SELECT bic, name FROM institutions WHERE bankcode=? and country=?"); query.bindValue(0, bankCode); query.bindValue(1, countryCode); if (!query.exec()) { qWarning() << QString("Could not execute query on \"%1\" to receive BIC and name. Error: %2").arg(db.databaseName()).arg(query.lastError().text()); return QPair(); } if (query.next()) { return QPair(query.value(0).toString(), query.value(1).toString()); } return QPair(QString(""), QString("")); } ibanBicData::bicAllocationStatus ibanBicData::isBicAllocated(const QString& bic) { // Get countryCode const QString countryCode = bic.mid(4, 2); if (countryCode.length() != 2) return bicNotAllocated; // Get services which have a database entry KService::List services = KServiceTypeTrader::self()->query("KMyMoney/IbanBicData", QString("(\'%1' ~in [X-KMyMoney-CountryCodes] or '*' in [X-KMyMoney-CountryCodes]) and exist [X-KMyMoney-Bankdata-Database]").arg(countryCode) ); if (services.isEmpty()) return bicAllocationUncertain; QSqlDatabase db = createDatabaseConnection(services.first()->property(QLatin1String("X-KMyMoney-Bankdata-Database"), QVariant::String).toString()); if (!db.isOpen()) // This is an error return bicAllocationUncertain; QSqlQuery query(db); query.prepare("SELECT ? IN (SELECT bic FROM institutions)"); query.bindValue(0, bic); if (!query.exec() || !query.next()) { qWarning() << QString("Could not execute query on \"%1\" to check if bic exists. Error: %2").arg(db.databaseName()).arg(query.lastError().text()); return bicAllocationUncertain; } if (query.value(0).toBool()) // Bic found return bicAllocated; // Bic not found, test if database is complete if (services.first()->property(QLatin1String("X-KMyMoney-Bankdata-IsComplete"), QVariant::Bool).toBool()) return bicNotAllocated; return bicAllocationUncertain; } QVariant ibanBicData::findPropertyByCountry(const QString& countryCode, const QString& property, const QVariant::Type type) { const KService::List services = KServiceTypeTrader::self()->query("KMyMoney/IbanBicData", QString("'%1' ~in [X-KMyMoney-CountryCodes] and exist [%2]").arg(countryCode).arg(property) ); if (!services.isEmpty()) return services.first()->property(property, type); // Something went wrong return QVariant(); } QString ibanBicData::extractBankIdentifier(const QString& iban) { const QString countryCode = iban.left(2); // Extract bank code const int start = bankIdentifierPosition(countryCode); if (start == -1) return QString(""); return iban.mid(start + 4, bankIdentifierLength(countryCode)); } QSqlDatabase ibanBicData::createDatabaseConnection(const QString& database) { Q_ASSERT(QSqlDatabase::drivers().contains("QSQLITE")); // Try to use already created connection const QString connectionName = QLatin1String("ibanBicData/") + database; QSqlDatabase storedConnection = QSqlDatabase::database(connectionName); if (storedConnection.isValid() && storedConnection.isOpen()) return storedConnection; // Need to create new connection, locate database QString path = QStandardPaths::locate(QStandardPaths::DataLocation, QLatin1String("kmymoney/ibanbicdata/") + database); if (path.isEmpty()) { qWarning() << QString("Could not locate database file \"%1\" to receive IBAN and BIC data.").arg(database); return QSqlDatabase(); } // Connect QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", connectionName); db.setDatabaseName(path); db.setConnectOptions("QSQLITE_OPEN_READONLY=1;QSQLITE_ENABLE_SHARED_CACHE=1;"); const bool opened = db.open(); if (!opened) { qWarning() << QString("Could not open database \"%1\" to receive IBAN and BIC data.").arg(path); } return db; } diff --git a/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.h b/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.h index 86eee0857..ac9e1557d 100644 --- a/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.h +++ b/kmymoney/payeeidentifier/ibanandbic/ibanbicdata.h @@ -1,94 +1,94 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IBANBICDATA_H #define IBANBICDATA_H #ifndef KMM_MYMONEY_UNIT_TESTABLE # define KMM_MYMONEY_UNIT_TESTABLE #endif #include #include #include /** * @brief This class implements everything that needs lookup * * Kind of a static private class of payeeIdentifier::ibanBic. It loads the iban/bic data and queries the * databases. * * @interal This class is made if a cache will be needed in future. */ class ibanBicData : public QObject { Q_OBJECT KMM_MYMONEY_UNIT_TESTABLE public: ~ibanBicData(); enum bicAllocationStatus { bicAllocated = 0, bicNotAllocated, bicAllocationUncertain }; int bbanLength(const QString& countryCode); int bankIdentifierPosition(const QString& countryCode); int bankIdentifierLength(const QString& countryCode); /** * @brief Create a BIC from a given IBAN * * The bic is always 11 characters long. * * @return QString::isNull() == true means an internal error occurred, QString::isEmpty() == true means there is no BIC */ QString iban2Bic(const QString& iban); QString bankNameByBic(QString bic); /** * @brief Create a BIC from a IBAN and get the institutes name * * first: bic, always 11 characters long. * second: instution name * * QString::isNull() == true means an internal error occurred, QString::isEmpty() == true means there is no data */ QPair bankNameAndBic(const QString& iban); QString extractBankIdentifier(const QString& iban); bicAllocationStatus isBicAllocated(const QString& bic); private: QVariant findPropertyByCountry(const QString& countryCode, const QString& property, const QVariant::Type type); /** * @brief Create/get QSqlDatabase * * Returns a QSqlDatabase. It is invalid if something went wrong. * * @param database This string is used to locate the database in the data dir */ QSqlDatabase createDatabaseConnection(const QString& database); }; #endif // IBANBICDATA_H diff --git a/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.cpp b/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.cpp index 8cb1c7f5a..3fc980c33 100644 --- a/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.cpp @@ -1,99 +1,99 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ibanbicstorageplugin.h" #include #include #include K_PLUGIN_FACTORY_WITH_JSON(ibanBicStoragePluginFactory, "ibanbicdata.json", registerPlugin();) QString ibanBicStoragePlugin::iid() { return QLatin1String("org.kmymoney.payeeIdentifier.ibanbic.sqlStoragePlugin"); } ibanBicStoragePlugin::ibanBicStoragePlugin(QObject* parent, const QVariantList& options) : storagePlugin(parent, options) { } /** @todo to be implemented */ bool ibanBicStoragePlugin::removePluginData(QSqlDatabase connection) { Q_UNUSED(connection); return false; } bool ibanBicStoragePlugin::setupDatabase(QSqlDatabase connection) { // Get current version QSqlQuery query = QSqlQuery(connection); query.prepare("SELECT versionMajor FROM kmmPluginInfo WHERE iid = ?"); query.bindValue(0, iid()); if (!query.exec()) { qWarning("Could not execute query for ibanBicStoragePlugin: %s", qPrintable(query.lastError().text())); return false; } int currentVersion = 0; if (query.next()) currentVersion = query.value(0).toInt(); // Create database in it's most recent version if version is 0 // (version 0 means the database was not installed) if (currentVersion == 0) { // If the database is recreated the table may be still there. So drop it if needed. No error handling needed // as this step is not necessary - only the creation is important. query.exec("DROP TABLE IF EXISTS kmmIbanBic;"); if (!query.exec( "CREATE TABLE kmmIbanBic (" " id varchar(32) NOT NULL PRIMARY KEY REFERENCES kmmPayeeIdentifier( id ) ON DELETE CASCADE ON UPDATE CASCADE," " iban varchar(32)," " bic char(11) CHECK(length(bic) = 11 OR bic IS NULL)," " name text" " );" )) { qWarning("Could not create table for ibanBicStoragePlugin: %s", qPrintable(query.lastError().text())); return false; } query.prepare("INSERT INTO kmmPluginInfo (iid, versionMajor, versionMinor, uninstallQuery) VALUES(?, ?, ?, ?)"); query.bindValue(0, iid()); query.bindValue(1, 1); query.bindValue(2, 0); query.bindValue(3, "DROP TABLE kmmIbanBic;"); if (query.exec()) return true; qWarning("Could not save plugin info for ibanBicStoragePlugin (%s): %s", qPrintable(iid()), qPrintable(query.lastError().text())); return false; } // Check if version is valid with this plugin switch (currentVersion) { case 1: return true; } return false; } #include "ibanbicstorageplugin.moc" diff --git a/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.h b/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.h index 27d14d0a5..18a195f96 100644 --- a/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.h +++ b/kmymoney/payeeidentifier/ibanandbic/ibanbicstorageplugin.h @@ -1,37 +1,37 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IBANBICSTORAGEPLUGIN_H #define IBANBICSTORAGEPLUGIN_H #include "mymoney/storage/kmymoneystorageplugin.h" class ibanBicStoragePlugin : public KMyMoneyPlugin::storagePlugin { Q_OBJECT Q_INTERFACES(KMyMoneyPlugin::storagePlugin) // Q_PLUGIN_METADATA(IID "org.kmymoney.payeeIdentifier.ibanbic.sqlStoragePlugin") public: explicit ibanBicStoragePlugin(QObject* parent = 0, const QVariantList& options = QVariantList()); virtual bool removePluginData(QSqlDatabase connection); virtual bool setupDatabase(QSqlDatabase connection); static QString iid(); }; #endif // IBANBICSTORAGEPLUGIN_H diff --git a/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.cpp b/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.cpp index a46eda009..72f3237bc 100644 --- a/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.cpp @@ -1,359 +1,359 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "internationalaccountidentifier-test.h" #include "../ibanbic.h" #include "../ibanbicdata.h" #include QTEST_GUILESS_MAIN(internationalAccountIdentifierTest); bool internationalAccountIdentifierTest::dataInstalled(const QString& countryCode) { // Not really implemented yet Q_UNUSED(countryCode); return false; } void internationalAccountIdentifierTest::initTestCase() { // Called before the first testfunction is executed } void internationalAccountIdentifierTest::cleanupTestCase() { // Called after the last testfunction was executed } void internationalAccountIdentifierTest::init() { // Called before each testfunction is executed } void internationalAccountIdentifierTest::cleanup() { // Called after every testfunction } void internationalAccountIdentifierTest::comparison() { } void internationalAccountIdentifierTest::ibanChecksum_data() { QTest::addColumn("iban"); QTest::addColumn("testResult"); QTest::newRow("KDE e.V.") << "DE82200700240066644600" << true; QTest::newRow("Invalid iban") << "DE82200700240066644601" << false; QTest::newRow("IBAN with letters") << "BH82AEHI21601643513576" << true; } void internationalAccountIdentifierTest::ibanChecksum() { QFETCH(QString, iban); QFETCH(bool, testResult); QCOMPARE(payeeIdentifiers::ibanBic::validateIbanChecksum(iban), testResult); } void internationalAccountIdentifierTest::paperformatIban_data() { QTest::addColumn("iban"); QTest::addColumn("paperformat"); /** Random ibans generated using http://www.mobilefish.com/services/random_iban_generator/random_iban_generator.php */ QTest::newRow("AL55359338525014419438694535") << "AL55359338525014419438694535" << "AL55 3593 3852 5014 4194 3869 4535"; QTest::newRow("AD6507599863323512292387") << "AD6507599863323512292387" << "AD65 0759 9863 3235 1229 2387"; QTest::newRow("AT550611200130969602") << "AT550611200130969602" << "AT55 0611 2001 3096 9602"; QTest::newRow("AZ45YKNN50322618666505570288") << "AZ45YKNN50322618666505570288" << "AZ45 YKNN 5032 2618 6665 0557 0288"; QTest::newRow("BH82AEHI21601643513576") << "BH82AEHI21601643513576" << "BH82 AEHI 2160 1643 5135 76"; QTest::newRow("FR1767089178626632115068411") << "FR1767089178626632115068411" << "FR17 6708 9178 6266 3211 5068 411"; QTest::newRow("GE87UH3052380574220575") << "GE87UH3052380574220575" << "GE87 UH30 5238 0574 2205 75"; QTest::newRow("DE88476823289460743695") << "DE88476823289460743695" << "DE88 4768 2328 9460 7436 95"; QTest::newRow("it81K2055156417927233643224") << "it81K2055156417927233643224" << "IT81 K205 5156 4179 2723 3643 224"; // Unfinished ibans QTest::newRow("PK") << "PK" << "PK"; QTest::newRow("NO5194556") << "NO5194556" << "NO51 9455 6"; // Non canonical ibans QTest::newRow("VG33 NRCC 0371 8957 2076 3593") << "VG33 NRCC 0371 8957 2076 3593" << "VG33 NRCC 0371 8957 2076 3593"; QTest::newRow(" SI 4523 946 27 23 327 14 9 ") << " SI 4523 946 27 23 327 14 9 " << "SI45 2394 6272 3327 149"; QTest::newRow("MK 3-27/3287/612--98207//26") << "MK 3-27/3287/612--98207//26" << "MK32 7328 7612 9820 726"; } void internationalAccountIdentifierTest::paperformatIban() { QFETCH(QString, iban); QFETCH(QString, paperformat); QCOMPARE(payeeIdentifiers::ibanBic::ibanToPaperformat(iban), paperformat); } void internationalAccountIdentifierTest::electronicformatIban_data() { QTest::addColumn("iban"); QTest::addColumn("electronic"); QTest::newRow("AL89 5112 2491 7164 1236 8777 7047") << "AL89 5112 2491 7164 1236 8777 7047" << "AL89511224917164123687777047"; QTest::newRow("AZ11 BIAH 1276 1568 9842 3064 6155") << "AZ11 BIAH 1276 1568 9842 3064 6155" << "AZ11BIAH12761568984230646155"; QTest::newRow("AZ73 WMRx 62 73 6 823 2803 9705") << "AZ73 WMRx 62 73 6 823 2803 9705" << "AZ73WMRX6273682328039705"; QTest::newRow("AZ55/MKDW-9866$8070(4022)5306 7865") << "AZ55/MKDW-9866$8070(4022)5306 7865" << "AZ55MKDW98668070402253067865"; QTest::newRow("AZ 57 ") << "AZ 57 " << "AZ57"; QTest::newRow("dk3958515811555611") << "dk3958515811555611" << "DK3958515811555611"; } void internationalAccountIdentifierTest::electronicformatIban() { QFETCH(QString, iban); QFETCH(QString, electronic); QCOMPARE(payeeIdentifiers::ibanBic::ibanToElectronic(iban), electronic); } void internationalAccountIdentifierTest::setIban_data() { QTest::addColumn("iban"); QTest::addColumn("electronic"); QTest::addColumn("paperformat"); QTest::newRow("AL89 5112 2491 7164 1236 8777 7047") << "AL89 5112 2491 7164 1236 8777 7047" << "AL89511224917164123687777047" << "AL89 5112 2491 7164 1236 8777 7047" ; QTest::newRow("AZ73 WMRX 62 73 6 823 2803 9705") << "AZ73 WMRX 62 73 6 823 2803 9705" << "AZ73WMRX6273682328039705" << "AZ73 WMRX 6273 6823 2803 9705"; QTest::newRow("AZ55/MKDW-9866$8070(4022)5306 7865") << "AZ55/MKDW-9866$8070(4022)5306 7865" << "AZ55MKDW98668070402253067865" << "AZ55 MKDW 9866 8070 4022 5306 7865"; QTest::newRow("AZ 57 ") << "AZ 57 " << "AZ57" << "AZ57"; QTest::newRow("DK3958515811555611") << "DK3958515811555611" << "DK3958515811555611" << "DK39 5851 5811 5556 11"; } void internationalAccountIdentifierTest::setIban() { QFETCH(QString, iban); QFETCH(QString, electronic); QFETCH(QString, paperformat); payeeIdentifiers::ibanBic ident; ident.setIban(iban); QCOMPARE(ident.electronicIban(), electronic); QCOMPARE(ident.paperformatIban(), paperformat); } void internationalAccountIdentifierTest::setBic_data() { QTest::addColumn("input"); QTest::addColumn("normalized"); QTest::addColumn("full"); QTest::newRow("Lower case") << "chasgb2lxXx" << "CHASGB2L" << "CHASGB2LXXX"; QTest::newRow("Arbitrary case") << "RZtIaT22263" << "RZTIAT22263" << "RZTIAT22263"; QTest::newRow("Without XXX") << "MARKDEFF" << "MARKDEFF" << "MARKDEFFXXX"; QTest::newRow("With XXX") << "MARKDEFFXXX" << "MARKDEFF" << "MARKDEFFXXX"; QTest::newRow("Arbitray bic") << "GENODEF1JEV" << "GENODEF1JEV" << "GENODEF1JEV"; } void internationalAccountIdentifierTest::setBic() { QFETCH(QString, input); QFETCH(QString, normalized); QFETCH(QString, full); payeeIdentifiers::ibanBic ident; ident.setBic(input); QCOMPARE(ident.bic(), normalized); QCOMPARE(ident.fullBic(), full); } void internationalAccountIdentifierTest::equalOperator_data() { QTest::addColumn("bic1"); QTest::addColumn("iban1"); QTest::addColumn("bic2"); QTest::addColumn("iban2"); QTest::addColumn("equals"); QTest::newRow("equal") << "MARKDEFFXXX" << "DE88476823289460743695" << "MARKDEFF" << " DE88 4768 2328 9460 7436 95" << true; QTest::newRow("BIC unequal") << "MARKDEFF001" << "DE884768 23289460743695" << "MARKDEFF" << "DE88 4768 2328 9460 7436 95" << false; QTest::newRow("IBAN unequal") << "MARKDEFFXXX" << "DE88476823289460743695" << "MARKDEFF" << "GE87UH3052380574220575" << false; } void internationalAccountIdentifierTest::equalOperator() { QFETCH(QString, bic1); QFETCH(QString, iban1); QFETCH(QString, bic2); QFETCH(QString, iban2); QFETCH(bool, equals); payeeIdentifiers::ibanBic ident1; ident1.setBic(bic1); ident1.setIban(iban1); payeeIdentifiers::ibanBic ident2; ident2.setBic(bic2); ident2.setIban(iban2); if (equals) QCOMPARE(ident1, ident2); else QVERIFY(!(ident1 == ident2)); } void internationalAccountIdentifierTest::uneqalOperator_data() { equalOperator_data(); } void internationalAccountIdentifierTest::uneqalOperator() { QFETCH(QString, bic1); QFETCH(QString, iban1); QFETCH(QString, bic2); QFETCH(QString, iban2); QFETCH(bool, equals); payeeIdentifiers::ibanBic ident1; ident1.setBic(bic1); ident1.setIban(iban1); payeeIdentifiers::ibanBic ident2; ident2.setBic(bic2); ident2.setIban(iban2); if (equals) QVERIFY(!(ident1 != ident2)); else QVERIFY(ident1 != ident2); } void internationalAccountIdentifierTest::getProperties_data() { QTest::addColumn("countryCode"); QTest::addColumn("bbanLength"); QTest::addColumn("bankIdentifierLength"); QTest::newRow("Germany") << "DE" << 18 << 8; QTest::newRow("France") << "FR" << 23 << 10; QTest::newRow("Switzerland") << "CH" << 17 << 5; } void internationalAccountIdentifierTest::getProperties() { QFETCH(QString, countryCode); QFETCH(int, bbanLength); if (!dataInstalled(countryCode)) QSKIP(qPrintable(QString("Could not find ibanBicData service for this country (was looking for \"%1\"). Did you install the services?").arg(countryCode)), SkipSingle); QCOMPARE(payeeIdentifiers::ibanBic::ibanLengthByCountry(countryCode), bbanLength + 4); } void internationalAccountIdentifierTest::iban2bic_data() { QTest::addColumn("iban"); QTest::addColumn("bic"); QTest::newRow("Germany (Unicef Germany)") << "DE57370205000000300000" << "BFSWDE33XXX"; QTest::newRow("Switzerland (Unicef Swiss)") << "CH8809000000800072119" << "POFICHBEXXX"; } void internationalAccountIdentifierTest::iban2bic() { QFETCH(QString, iban); QFETCH(QString, bic); if (!dataInstalled(iban.left(2))) QSKIP(qPrintable(QString("Could not find ibanBicData service for this country (was looking for \"%1\"). Did you install the services?").arg(iban)), SkipSingle); QCOMPARE(payeeIdentifiers::ibanBic::bicByIban(iban), bic); } void internationalAccountIdentifierTest::nameByBic_data() { QTest::addColumn("bic"); QTest::addColumn("name"); QTest::newRow("Germany (Bundesbank)") << "MARKDEF1100" << "Bundesbank"; } void internationalAccountIdentifierTest::nameByBic() { QFETCH(QString, bic); QFETCH(QString, name); if (!dataInstalled(bic.mid(4, 2))) QSKIP(qPrintable(QString("Could not find ibanBicData service for this country (was looking for \"%1\"). Did you install the services?").arg(bic)), SkipSingle); QCOMPARE(payeeIdentifiers::ibanBic::institutionNameByBic(bic), name); } void internationalAccountIdentifierTest::bicAndNameByIban_data() { QTest::addColumn("iban"); QTest::addColumn("bic"); QTest::addColumn("name"); QTest::newRow("Germany (Unicef Germany)") << "DE57370205000000300000" << "BFSWDE33XXX" << ""; } void internationalAccountIdentifierTest::bicAndNameByIban() { QTest::addColumn("iban"); QTest::addColumn("bic"); QTest::addColumn("name"); QSKIP("Test not implemented", SkipAll); //QPair pair = internationalAccountIdentifier::; } void internationalAccountIdentifierTest::qStringNullAndEmpty() { const QString nullStr1; QVERIFY(nullStr1.isNull()); QVERIFY(nullStr1.isEmpty()); const QString nullStr2 = QString(); QVERIFY(nullStr2.isEmpty()); QVERIFY(nullStr2.isNull()); const QString empty = QString(""); QVERIFY(empty.isEmpty()); QVERIFY(!empty.isNull()); } Q_DECLARE_METATYPE(payeeIdentifiers::ibanBic::bicAllocationStatus); void internationalAccountIdentifierTest::bicAllocated_data() { QTest::addColumn("bic"); QTest::addColumn("allocated"); QTest::newRow("Bundesbank") << "MARKDEFFXXX" << payeeIdentifiers::ibanBic::bicAllocated; QTest::newRow("Not existing") << "DOOFDE12NOT" << payeeIdentifiers::ibanBic::bicNotAllocated; QTest::newRow("Unknown") << "NODAFRTAFOR" << payeeIdentifiers::ibanBic::bicAllocationUncertain; } void internationalAccountIdentifierTest::bicAllocated() { QFETCH(QString, bic); QFETCH(payeeIdentifiers::ibanBic::bicAllocationStatus, allocated); if (!dataInstalled(bic.mid(4, 2))) QSKIP(qPrintable(QString("Could not find ibanBicData service for this country (was looking for \"%1\"). Did you install the services?").arg(bic)), SkipSingle); QCOMPARE(payeeIdentifiers::ibanBic::isBicAllocated(bic), allocated); } diff --git a/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.h b/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.h index af6f93557..706b6f3b8 100644 --- a/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.h +++ b/kmymoney/payeeidentifier/ibanandbic/tests/internationalaccountidentifier-test.h @@ -1,80 +1,80 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef INTERNATIONALACCOUNTIDENTIFIERTEST_H #define INTERNATIONALACCOUNTIDENTIFIERTEST_H #include #define KMM_MYMONEY_UNIT_TESTABLE friend class internationalAccountIdentifierTest; class internationalAccountIdentifierTest : public QObject { Q_OBJECT bool dataInstalled(const QString& countryCode); private slots: void initTestCase(); void cleanupTestCase(); void init(); void cleanup(); void comparison(); void ibanChecksum_data(); void ibanChecksum(); void paperformatIban_data(); void paperformatIban(); void electronicformatIban_data(); void electronicformatIban(); void setIban_data(); void setIban(); void setBic_data(); void setBic(); void equalOperator_data(); void equalOperator(); void uneqalOperator_data(); void uneqalOperator(); void getProperties_data(); void getProperties(); void iban2bic_data(); void iban2bic(); void nameByBic_data(); void nameByBic(); void bicAndNameByIban_data(); void bicAndNameByIban(); void qStringNullAndEmpty(); void bicAllocated_data(); void bicAllocated(); }; #endif // INTERNATIONALACCOUNTIDENTIFIERTEST_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp index a9ec4992a..427ae0528 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp @@ -1,65 +1,65 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "bicvalidator.h" #include #include "payeeidentifier/ibanandbic/ibanbic.h" bicValidator::bicValidator(QObject* parent) : QValidator(parent) { } QValidator::State bicValidator::validate(QString &string, int&) const { for (int i = 0; i < qMin(string.length(), 6); ++i) { if (!string.at(i).isLetter()) return Invalid; if (string.at(i).isLower()) string[i] = string.at(i).toUpper(); } for (int i = 6; i < string.length(); ++i) { if (!string.at(i).isLetterOrNumber()) return Invalid; if (string.at(i).isLower()) string[i] = string.at(i).toUpper(); } if (string.length() > 11) return Invalid; else if (string.length() == 8 || string.length() == 11) { return Acceptable; } return Intermediate; } QPair< KMyMoneyValidationFeedback::MessageType, QString > bicValidator::validateWithMessage(const QString& string) { // Do not show an error message if no BIC is given. if (string.length() != 8 && string.length() != 11) return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Error, i18n("A valid BIC is 8 or 11 characters long.")); if (payeeIdentifiers::ibanBic::isBicAllocated(string) == payeeIdentifiers::ibanBic::bicNotAllocated) return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Error, i18n("The given BIC is not assigned to any credit institute.")); return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::None, QString()); } diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h index 99f4f42ec..0ddf7c3e6 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h @@ -1,37 +1,37 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef BICVALIDATOR_H #define BICVALIDATOR_H #include #include "payeeidentifier_iban_bic_widgets_export.h" #include "kmymoneyvalidationfeedback.h" class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT bicValidator : public QValidator { Q_OBJECT public: explicit bicValidator(QObject* parent = 0); virtual QValidator::State validate(QString& , int&) const; static QPair validateWithMessage(const QString&); }; #endif // BICVALIDATOR_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.cpp index 1f04f2b04..de70b2bf3 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.cpp @@ -1,160 +1,160 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ibanbicitemdelegate.h" #include #include #include #include #include #include "models/payeeidentifiercontainermodel.h" #include "ibanbicitemedit.h" ibanBicItemDelegate::ibanBicItemDelegate(QObject* parent) : QStyledItemDelegate(parent) { } /** @todo elide texts */ void ibanBicItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // Background QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; const QRect textArea = QRect(opt.rect.x() + margin, opt.rect.y() + margin, opt.rect.width() - 2 * margin, opt.rect.height() - 2 * margin); // Do not paint text if the edit widget is shown const QAbstractItemView *view = qobject_cast(opt.widget); if (view && view->indexWidget(index)) return; // Get data payeeIdentifierTyped ibanBic = ibanBicByIndex(index); // Paint Bic painter->save(); const QFont smallFont = painter->font(); const QFontMetrics metrics(opt.font); const QFontMetrics smallMetrics(smallFont); const QRect bicRect = style->alignedRect((opt.direction == Qt::RightToLeft) ? Qt::LeftToRight : Qt::RightToLeft, Qt::AlignTop, QSize(textArea.width(), smallMetrics.lineSpacing()), QRect(textArea.left(), metrics.lineSpacing() + textArea.top(), textArea.width(), smallMetrics.lineSpacing()) ); painter->setFont(smallFont); style->drawItemText(painter, bicRect, Qt::AlignBottom | Qt::AlignRight, QApplication::palette(), true, ibanBic->storedBic(), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); // Paint Bank name painter->save(); const QRect nameRect = style->alignedRect(opt.direction, Qt::AlignTop, QSize(textArea.width(), smallMetrics.lineSpacing()), QRect(textArea.left(), metrics.lineSpacing() + textArea.top(), textArea.width(), smallMetrics.lineSpacing()) ); style->drawItemText(painter, nameRect, Qt::AlignBottom, QApplication::palette(), true, ibanBic->institutionName(), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); // Paint IBAN painter->save(); QFont normal = painter->font(); normal.setBold(true); painter->setFont(normal); const QRect ibanRect = style->alignedRect(opt.direction, Qt::AlignTop, QSize(textArea.width(), metrics.lineSpacing()), textArea); const QString bic = index.model()->data(index, Qt::DisplayRole).toString(); style->drawItemText(painter, ibanRect, Qt::AlignTop, QApplication::palette(), true, ibanBic->paperformatIban(), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); // Paint type painter->save(); QRect typeRect = style->alignedRect(opt.direction, Qt::AlignTop | Qt::AlignRight, QSize(textArea.width() / 5, metrics.lineSpacing()), textArea); style->drawItemText(painter, typeRect, Qt::AlignTop | Qt::AlignRight, QApplication::palette(), true, i18n("IBAN & BIC"), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); } QSize ibanBicItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // Test if current index is edited at the moment const QAbstractItemView *view = qobject_cast(opt.widget); if (view && view->indexWidget(index)) return view->indexWidget(index)->sizeHint(); QFontMetrics metrics(option.font); const QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; // A bic has maximal 11 characters, an IBAN 32 return QSize((32 + 11)*metrics.width(QLatin1Char('X')) + 3*margin, 2*metrics.lineSpacing() + metrics.leading() + 2*margin); } QWidget* ibanBicItemDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(option); ibanBicItemEdit* edit = new ibanBicItemEdit(parent); connect(edit, SIGNAL(commitData(QWidget*)), this, SIGNAL(commitData(QWidget*))); connect(edit, SIGNAL(closeEditor(QWidget*)), this, SIGNAL(closeEditor(QWidget*))); emit sizeHintChanged(index); return edit; } void ibanBicItemDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { payeeIdentifierTyped ibanBic = ibanBicByIndex(index); ibanBicItemEdit* ibanEditor = qobject_cast< ibanBicItemEdit* >(editor); Q_CHECK_PTR(ibanEditor); ibanEditor->setIdentifier(ibanBic); } void ibanBicItemDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { Q_CHECK_PTR(editor); Q_CHECK_PTR(model); Q_ASSERT(index.isValid()); ibanBicItemEdit* ibanEditor = qobject_cast< ibanBicItemEdit* >(editor); Q_CHECK_PTR(ibanEditor); model->setData(index, QVariant::fromValue(ibanEditor->identifier()), payeeIdentifierContainerModel::payeeIdentifier); } void ibanBicItemDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(index); editor->setGeometry(option.rect); } /** * Internal helper to direcly convert the QVariant into the correct pointer type. */ payeeIdentifierTyped ibanBicItemDelegate::ibanBicByIndex(const QModelIndex& index) const { payeeIdentifierTyped ibanBic{ index.model()->data(index, payeeIdentifierContainerModel::payeeIdentifier).value() }; Q_ASSERT(!ibanBic.isNull()); return ibanBic; } diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.h b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.h index faa545a8a..93297af2e 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.h @@ -1,50 +1,50 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IBANBICITEMDELEGATE_H #define IBANBICITEMDELEGATE_H #include "payeeidentifier_iban_bic_widgets_export.h" #include #include "payeeidentifier/payeeidentifiertyped.h" #include "payeeidentifier/ibanandbic/ibanbic.h" class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT ibanBicItemDelegate : public QStyledItemDelegate { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kmymoney.payeeIdentifier.ibanbic.delegate" FILE "kmymoney-ibanbic-delegate.json") public: ibanBicItemDelegate(QObject* parent = nullptr); virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void setEditorData(QWidget* editor, const QModelIndex& index) const; virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; Q_SIGNALS: void sizeHintChanged(const QModelIndex&) const; private: inline payeeIdentifierTyped ibanBicByIndex(const QModelIndex& index) const; }; #endif // IBANBICITEMDELEGATE_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.cpp index 45d48a381..2e9de0022 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.cpp @@ -1,115 +1,115 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ibanbicitemedit.h" #include "ui_ibanbicitemedit.h" #include "payeeidentifier/ibanandbic/ibanbic.h" #include "payeeidentifier/payeeidentifiertyped.h" struct ibanBicItemEdit::Private { Ui::ibanBicItemEdit* ui; payeeIdentifier m_identifier; }; ibanBicItemEdit::ibanBicItemEdit(QWidget* parent) : QWidget(parent), d(new Private) { d->ui = new Ui::ibanBicItemEdit; d->ui->setupUi(this); setFocusProxy(d->ui->ibanEdit); connect(d->ui->ibanEdit, SIGNAL(textChanged(QString)), this, SLOT(updateIdentifier())); connect(d->ui->bicEdit, SIGNAL(textChanged(QString)), this, SLOT(updateIdentifier())); connect(d->ui->ibanEdit, SIGNAL(textChanged(QString)), this, SIGNAL(ibanChanged(QString))); connect(d->ui->bicEdit, SIGNAL(textChanged(QString)), this, SIGNAL(bicChanged(QString))); connect(d->ui->ibanEdit, SIGNAL(returnPressed()), this, SLOT(editFinished())); connect(d->ui->bicEdit, SIGNAL(returnPressed()), this, SLOT(editFinished())); } void ibanBicItemEdit::editFinished() { emit commitData(this); emit closeEditor(this); } payeeIdentifier ibanBicItemEdit::identifier() const { return d->m_identifier; } QString ibanBicItemEdit::bic() const { return d->ui->bicEdit->text(); } QString ibanBicItemEdit::iban() const { return d->ui->ibanEdit->text(); } void ibanBicItemEdit::setIdentifier(const payeeIdentifier& ident) { try { payeeIdentifierTyped identTyped(ident); d->ui->bicEdit->setText(identTyped->storedBic()); d->ui->ibanEdit->setText(identTyped->paperformatIban()); d->m_identifier = ident; } catch (payeeIdentifier::exception&) { } } void ibanBicItemEdit::setBic(const QString& bic) { d->ui->bicEdit->setText(bic); } void ibanBicItemEdit::setIban(const QString& iban) { d->ui->ibanEdit->setText(payeeIdentifiers::ibanBic::ibanToPaperformat(iban)); } void ibanBicItemEdit::updateIdentifier() { if (d->m_identifier.isNull()) d->m_identifier = payeeIdentifier(d->m_identifier.id(), new payeeIdentifiers::ibanBic); const QString iban = payeeIdentifiers::ibanBic::ibanToElectronic(d->ui->ibanEdit->text()); const QString bic = d->ui->bicEdit->text(); bool changed = false; payeeIdentifierTyped ident(d->m_identifier); if (ident->storedBic() != bic) { ident->setBic(bic); changed = true; } if (ident->electronicIban() != iban) { ident->setElectronicIban(iban); changed = true; } d->m_identifier = ident; if (changed) { emit identifierChanged(d->m_identifier); emit commitData(this); } } diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.h b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.h index b7b55a16d..e68aae984 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanbicitemedit.h @@ -1,67 +1,67 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IBANBICITEMEDIT_H #define IBANBICITEMEDIT_H #include #include namespace Ui { class ibanBicItemEdit; } class ibanBicItemEdit : public QWidget { Q_OBJECT Q_PROPERTY(payeeIdentifier identifier READ identifier WRITE setIdentifier NOTIFY identifierChanged STORED true) Q_PROPERTY(QString iban READ iban WRITE setIban NOTIFY ibanChanged STORED false DESIGNABLE true) Q_PROPERTY(QString bic READ bic WRITE setBic NOTIFY bicChanged STORED false DESIGNABLE true) public: ibanBicItemEdit(QWidget* parent = 0); payeeIdentifier identifier() const; QString iban() const; QString bic() const; public Q_SLOTS: void setIdentifier(const payeeIdentifier&); void setIban(const QString&); void setBic(const QString&); Q_SIGNALS: void commitData(QWidget*); void closeEditor(QWidget* editor); void identifierChanged(payeeIdentifier); void ibanChanged(QString); void bicChanged(QString); private Q_SLOTS: void updateIdentifier(); /** @brief emits commitData(this) and closeEditor(this) */ void editFinished(); private: struct Private; Private* d; }; #endif // IBANBICITEMEDIT_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp index 1ad8adf04..3abdf8dee 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp @@ -1,82 +1,82 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ibanvalidator.h" #include "../ibanbic.h" #include ibanValidator::ibanValidator(QObject* parent) : QValidator(parent) { } QValidator::State ibanValidator::validate(QString& string, int&) const { // Check country code and set it uppercase if (string.length() >= 1) { if (!string.at(0).isLetter()) return Invalid; if (string.at(0).isLower()) string[0] = string.at(0).toUpper(); } if (string.length() >= 2) { if (!string.at(1).isLetterOrNumber()) return Invalid; if (string.at(1).isLower()) string[1] = string.at(1).toUpper(); } // Check rest of the iban int characterCount = qMin(string.length(), 2); for (int i = 2; i < string.length(); ++i) { if (string.at(i).isLetterOrNumber()) { ++characterCount; } else if (!string.at(i).isSpace()) { return Invalid; } } if (characterCount > 32) return Invalid; if (characterCount > 5) { return Acceptable; } return Intermediate; } QPair< KMyMoneyValidationFeedback::MessageType, QString > ibanValidator::validateWithMessage(const QString& string) { // string.length() > 32 should not happen because all line edits should have this validator installed if (string.length() < 5) return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Error, i18n("This IBAN is too short.")); if (!payeeIdentifiers::ibanBic::validateIbanChecksum(payeeIdentifiers::ibanBic::ibanToElectronic(string))) return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Warning, i18n("This IBAN is invalid.")); return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::None, QString()); } void ibanValidator::fixup(QString& string) const { string = payeeIdentifiers::ibanBic::ibanToPaperformat(string); } diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h index 9ff22cf3a..838fc20da 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h @@ -1,41 +1,41 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IBANVALIDATOR_H #define IBANVALIDATOR_H #include "payeeidentifier_iban_bic_widgets_export.h" #include #include "kmymoneyvalidationfeedback.h" class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT ibanValidator : public QValidator { Q_OBJECT public: explicit ibanValidator(QObject* parent = 0); virtual State validate(QString& , int&) const; State validate(const QString&) const; virtual void fixup(QString&) const; static QPair validateWithMessage(const QString&); }; #endif // IBANVALIDATOR_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp index 3c94e44a8..902590b28 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp @@ -1,120 +1,120 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kbicedit.h" #include #include #include #include #include #include #include #include "../bicmodel.h" #include "bicvalidator.h" class bicItemDelegate : public QStyledItemDelegate { public: explicit bicItemDelegate(QObject* parent = 0) : QStyledItemDelegate(parent) {} void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; private: inline QFont getSmallFont(const QStyleOptionViewItem& option) const; }; KBicEdit::KBicEdit(QWidget* parent) : KLineEdit(parent) { QCompleter* completer = new QCompleter(this); bicModel* model = new bicModel(this); completer->setModel(model); m_popupDelegate = new bicItemDelegate(this); completer->popup()->setItemDelegate(m_popupDelegate); setCompleter(completer); bicValidator *const validator = new bicValidator(this); setValidator(validator); } KBicEdit::~KBicEdit() { delete m_popupDelegate; } QFont bicItemDelegate::getSmallFont(const QStyleOptionViewItem& option) const { QFont smallFont = option.font; smallFont.setPointSize(0.9*smallFont.pointSize()); return smallFont; } QSize bicItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); QFontMetrics metrics(option.font); QFontMetrics smallMetrics(getSmallFont(option)); const QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; // A bic has maximal 11 characters. So we guess, we want to display 11 characters. The name of the institution has to adapt to what is given return QSize(metrics.width(QLatin1Char('X')) + 2*margin, metrics.lineSpacing() + smallMetrics.lineSpacing() + smallMetrics.leading() + 2*margin); } /** * @todo enable eliding (use QFontMetrics::elidedText() ) */ void bicItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // Background QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; const QRect textArea = QRect(opt.rect.x() + margin, opt.rect.y() + margin, opt.rect.width() - 2 * margin, opt.rect.height() - 2 * margin); // Paint name painter->save(); QFont smallFont = getSmallFont(opt); QFontMetrics metrics(opt.font); QFontMetrics smallMetrics(smallFont); QRect nameRect = style->alignedRect(opt.direction, Qt::AlignBottom, QSize(textArea.width(), smallMetrics.lineSpacing()), textArea); painter->setFont(smallFont); style->drawItemText(painter, nameRect, Qt::AlignBottom, QApplication::palette(), true, index.model()->data(index, bicModel::InstitutionNameRole).toString(), option.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Mid); painter->restore(); // Paint BIC painter->save(); QFont normal = painter->font(); normal.setBold(true); painter->setFont(normal); QRect bicRect = style->alignedRect(opt.direction, Qt::AlignTop, QSize(textArea.width(), metrics.lineSpacing()), textArea); const QString bic = index.model()->data(index, Qt::DisplayRole).toString(); style->drawItemText(painter, bicRect, Qt::AlignTop, QApplication::palette(), true, bic, option.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); } diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h index bf62c67a4..9109d61e7 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h @@ -1,42 +1,42 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KBICEDIT_H #define KBICEDIT_H #include #include #include "payeeidentifier_iban_bic_widgets_export.h" #include "kmymoneyvalidationfeedback.h" class QAbstractItemDelegate; class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT KBicEdit : public KLineEdit { Q_OBJECT public: KBicEdit(QWidget* parent = 0); virtual ~KBicEdit(); private: QAbstractItemDelegate* m_popupDelegate; }; #endif // KBICEDIT_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp index 2413c6fa8..9df3bc753 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp @@ -1,36 +1,36 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kibanlineedit.h" #include #include "ibanvalidator.h" KIbanLineEdit::KIbanLineEdit(QWidget* parent) : KLineEdit(parent) { ibanValidator *const validatorPtr = new ibanValidator; setValidator(validatorPtr); } const ibanValidator* KIbanLineEdit::validator() const { return qobject_cast(KLineEdit::validator()); } diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h index e755fd163..bb98a7223 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h @@ -1,39 +1,39 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KIBANLINEEDIT_H #define KIBANLINEEDIT_H #include "payeeidentifier_iban_bic_widgets_export.h" #include #include "kmymoneyvalidationfeedback.h" class ibanValidator; class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT KIbanLineEdit : public KLineEdit { Q_OBJECT public: KIbanLineEdit(QWidget* parent); const ibanValidator* validator() const; }; #endif // KIBANLINEEDIT_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/pluginfactory.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/pluginfactory.cpp index f4458547e..e6a2a55ee 100644 --- a/kmymoney/payeeidentifier/ibanandbic/widgets/pluginfactory.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/pluginfactory.cpp @@ -1,27 +1,27 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "ibanbicitemdelegate.h" // TODO: port KF5 /*K_PLUGIN_FACTORY(ibanAndBicPidDelegatesFactory, registerPlugin("ibanBicDelegate"); ) K_EXPORT_PLUGIN(ibanAndBicPidDelegatesFactory("payeeidentifier_iban_bic_delegates"))*/ diff --git a/kmymoney/payeeidentifier/nationalaccount/nationalaccount.cpp b/kmymoney/payeeidentifier/nationalaccount/nationalaccount.cpp index 974664439..d3a80d600 100644 --- a/kmymoney/payeeidentifier/nationalaccount/nationalaccount.cpp +++ b/kmymoney/payeeidentifier/nationalaccount/nationalaccount.cpp @@ -1,155 +1,155 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "nationalaccount.h" #include #include #include #include namespace payeeIdentifiers { nationalAccount::nationalAccount() : m_ownerName(), m_country(), m_bankCode(), m_accountNumber() { } nationalAccount::nationalAccount(const nationalAccount& other) : m_ownerName(other.m_ownerName), m_country(other.m_country), m_bankCode(other.m_bankCode), m_accountNumber(other.m_accountNumber) { } nationalAccount* nationalAccount::createFromXml(const QDomElement& element) const { nationalAccount* ident = new nationalAccount; ident->setBankCode(element.attribute("bankcode", QString())); ident->setAccountNumber(element.attribute("accountnumber", QString())); ident->setOwnerName(element.attribute("ownername", QString())); ident->setCountry(element.attribute("country", QString())); return ident; } void nationalAccount::writeXML(QDomDocument& document, QDomElement& parent) const { Q_UNUSED(document); parent.setAttribute("accountnumber", m_accountNumber); if (!m_bankCode.isEmpty()) parent.setAttribute("bankcode", m_bankCode); parent.setAttribute("ownername", m_ownerName); parent.setAttribute("country", m_country); } nationalAccount* nationalAccount::createFromSqlDatabase(QSqlDatabase db, const QString& identId) const { QSqlQuery query(db); query.prepare("SELECT countryCode, accountNumber, bankCode, name FROM kmmNationalAccountNumber WHERE id = ?;"); query.bindValue(0, identId); if (!query.exec() || !query.next()) { qWarning("Could load national account number from database"); return 0; } nationalAccount *const ident = new nationalAccount; ident->setCountry(query.value(0).toString()); ident->setAccountNumber(query.value(1).toString()); ident->setBankCode(query.value(2).toString()); ident->setOwnerName(query.value(3).toString()); return ident; } QString nationalAccount::storagePluginIid() const { return QLatin1String("org.kmymoney.payeeIdentifier.nationalAccount.sqlStoragePlugin"); } bool nationalAccount::sqlSave(QSqlDatabase databaseConnection, const QString& objectId) const { QSqlQuery query(databaseConnection); query.prepare("INSERT INTO kmmNationalAccountNumber " " ( id, countryCode, accountNumber, bankCode, name )" " VALUES( :id, :countryCode, :accountNumber, :bankCode, :name ) " ); return writeQuery(query, objectId); } bool nationalAccount::sqlModify(QSqlDatabase databaseConnection, const QString& objectId) const { QSqlQuery query(databaseConnection); query.prepare("UPDATE kmmNationalAccountNumber SET countryCode = :countryCode, accountNumber = :accountNumber, bankCode = :bankCode, name = :name WHERE id = :id;"); return writeQuery(query, objectId); } bool nationalAccount::sqlRemove(QSqlDatabase databaseConnection, const QString& objectId) const { QSqlQuery query(databaseConnection); query.prepare("DELETE FROM kmmNationalAccountNumber WHERE id = ?;"); query.bindValue(0, objectId); if (!query.exec()) { qWarning("Error while deleting national account number '%s': %s", qPrintable(objectId), qPrintable(query.lastError().text())); return false; } return true; } bool nationalAccount::writeQuery(QSqlQuery& query, const QString& id) const { query.bindValue(":id", id); query.bindValue(":countryCode", country()); query.bindValue(":accountNumber", accountNumber()); query.bindValue(":bankCode", (bankCode().isEmpty()) ? QVariant(QVariant::String) : bankCode()); query.bindValue(":name", ownerName()); if (!query.exec()) { qWarning("Error while saving national account number for '%s': %s", qPrintable(id), qPrintable(query.lastError().text())); return false; } return true; } /** @todo implement */ bool nationalAccount::isValid() const { return true; } bool nationalAccount::operator==(const payeeIdentifierData& other) const { try { const nationalAccount& otherCasted = dynamic_cast(other); return operator==(otherCasted); } catch (const std::bad_cast&) { } return false; } bool nationalAccount::operator==(const nationalAccount& other) const { return (m_accountNumber == other.m_accountNumber && m_bankCode == other.m_bankCode && m_ownerName == other.m_ownerName && m_country == other.m_country); } } // namespace payeeIdentifiers diff --git a/kmymoney/payeeidentifier/nationalaccount/nationalaccount.h b/kmymoney/payeeidentifier/nationalaccount/nationalaccount.h index 633ad44e7..2615c23a4 100644 --- a/kmymoney/payeeidentifier/nationalaccount/nationalaccount.h +++ b/kmymoney/payeeidentifier/nationalaccount/nationalaccount.h @@ -1,96 +1,96 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef NATIONALACCOUNTID_H #define NATIONALACCOUNTID_H #include "mymoney/payeeidentifier/payeeidentifierdata.h" #include "nationalaccount_identifier_export.h" namespace payeeIdentifiers { class NATIONALACCOUNT_IDENTIFIER_EXPORT nationalAccount : public payeeIdentifierData { public: PAYEEIDENTIFIER_IID(nationalAccount, "org.kmymoney.payeeIdentifier.national"); nationalAccount(); nationalAccount(const nationalAccount& other); virtual bool isValid() const; virtual bool operator==(const payeeIdentifierData& other) const; bool operator==(const nationalAccount& other) const; nationalAccount* clone() const { return new nationalAccount(*this); } nationalAccount* createFromXml(const QDomElement& element) const; void writeXML(QDomDocument& document, QDomElement& parent) const; QString storagePluginIid() const; bool sqlSave(QSqlDatabase databaseConnection, const QString& objectId) const; bool sqlModify(QSqlDatabase databaseConnection, const QString& objectId) const; bool sqlRemove(QSqlDatabase databaseConnection, const QString& objectId) const; nationalAccount* createFromSqlDatabase(QSqlDatabase db, const QString& identId) const; void setBankCode(const QString& bankCode) { m_bankCode = bankCode; } QString bankCode() const { return m_bankCode; } /** @todo implement */ QString bankName() const { return QString(); } void setAccountNumber(const QString& accountNumber) { m_accountNumber = accountNumber; } QString accountNumber() const { return m_accountNumber; } QString country() const { return m_country; } void setCountry(const QString& countryCode) { m_country = countryCode.toUpper(); } QString ownerName() const { return m_ownerName; } void setOwnerName(const QString& ownerName) { m_ownerName = ownerName; } private: bool writeQuery(QSqlQuery& query, const QString& id) const; QString m_ownerName; QString m_country; QString m_bankCode; QString m_accountNumber; }; } // namespace payeeIdentifiers #endif // NATIONALACCOUNTID_H diff --git a/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.cpp b/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.cpp index 867d73439..314ce7b99 100644 --- a/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.cpp +++ b/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.cpp @@ -1,101 +1,101 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "nationalaccountstorageplugin.h" #include #include #include /*K_PLUGIN_FACTORY(nationalAccountStoragePluginFactory, registerPlugin(); )*/ K_EXPORT_PLUGIN(nationalAccountStoragePluginFactory("ibanBicStoragePlugin")) QString nationalAccountStoragePlugin::iid() { return QLatin1String("org.kmymoney.payeeIdentifier.nationalAccount.sqlStoragePlugin"); } nationalAccountStoragePlugin::nationalAccountStoragePlugin(QObject* parent, const QVariantList& options) : storagePlugin(parent, options) { } /** @todo to be implemented */ bool nationalAccountStoragePlugin::removePluginData(QSqlDatabase connection) { Q_UNUSED(connection); return false; } bool nationalAccountStoragePlugin::setupDatabase(QSqlDatabase connection) { // Get current version QSqlQuery query = QSqlQuery(connection); query.prepare("SELECT versionMajor FROM kmmPluginInfo WHERE iid = ?"); query.bindValue(0, iid()); if (!query.exec()) { qWarning("Could not execute query for nationalAccountStoragePlugin: %s", qPrintable(query.lastError().text())); return false; } int currentVersion = 0; if (query.next()) currentVersion = query.value(0).toInt(); // Create database in it's most recent version if version is 0 // (version 0 means the database was not installed) if (currentVersion == 0) { // If the database is recreated the table may be still there. So drop it if needed. No error handling needed // as this step is not necessary - only the creation is important. query.exec("DROP TABLE IF EXISTS kmmNationalAccountNumber;"); if (!query.exec( "CREATE TABLE kmmNationalAccountNumber (" " id varchar(32) NOT NULL PRIMARY KEY REFERENCES kmmPayeeIdentifier( id ) ON DELETE CASCADE ON UPDATE CASCADE," " countryCode varchar(3)," " accountNumber TEXT," " bankCode TEXT," " name TEXT" " );" )) { qWarning("Could not create table for nationalAccountStoragePlugin: %s", qPrintable(query.lastError().text())); return false; } query.prepare("INSERT INTO kmmPluginInfo (iid, versionMajor, versionMinor, uninstallQuery) VALUES(?, ?, ?, ?)"); query.bindValue(0, iid()); query.bindValue(1, 1); query.bindValue(2, 0); query.bindValue(3, "DROP TABLE kmmNationalAccountNumber;"); if (query.exec()) return true; qWarning("Could not save plugin info for nationalAccountStoragePlugin (%s): %s", qPrintable(iid()), qPrintable(query.lastError().text())); return false; } // Check if version is valid with this plugin switch (currentVersion) { case 1: return true; } return false; } diff --git a/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.h b/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.h index 1ec1c17d1..8ef5bae6e 100644 --- a/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.h +++ b/kmymoney/payeeidentifier/nationalaccount/nationalaccountstorageplugin.h @@ -1,36 +1,36 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef NATIONALACCOUNTSTORAGEPLUGIN_H #define NATIONALACCOUNTSTORAGEPLUGIN_H #include "mymoney/storage/kmymoneystorageplugin.h" class nationalAccountStoragePlugin : public KMyMoneyPlugin::storagePlugin { Q_OBJECT Q_INTERFACES(KMyMoneyPlugin::storagePlugin) public: explicit nationalAccountStoragePlugin(QObject* parent = 0, const QVariantList& options = QVariantList()); virtual bool removePluginData(QSqlDatabase connection); virtual bool setupDatabase(QSqlDatabase connection); static QString iid(); }; #endif // NATIONALACCOUNTSTORAGEPLUGIN_H diff --git a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.cpp b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.cpp index 939235254..b51140261 100644 --- a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.cpp +++ b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.cpp @@ -1,162 +1,162 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "nationalaccountdelegate.h" #include #include #include #include #include "models/payeeidentifiercontainermodel.h" #include "nationalaccountedit.h" nationalAccountDelegate::nationalAccountDelegate(QObject* parent, const QVariantList&) : QStyledItemDelegate(parent) { } /** @todo elide texts */ void nationalAccountDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // Background QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; const QRect textArea = QRect(opt.rect.x() + margin, opt.rect.y() + margin, opt.rect.width() - 2 * margin, opt.rect.height() - 2 * margin); // Do not paint text if the edit widget is shown const QAbstractItemView *view = qobject_cast(opt.widget); if (view && view->indexWidget(index)) return; // Get data payeeIdentifierTyped ident = identByIndex(index); // Paint bank code painter->save(); const QFont smallFont = painter->font(); const QFontMetrics metrics(opt.font); const QFontMetrics smallMetrics(smallFont); const QRect bicRect = style->alignedRect(opt.direction, Qt::AlignTop, QSize(textArea.width(), smallMetrics.lineSpacing()), QRect(textArea.left(), metrics.lineSpacing() + textArea.top(), textArea.width(), smallMetrics.lineSpacing()) ); painter->setFont(smallFont); style->drawItemText(painter, bicRect, Qt::AlignBottom, QApplication::palette(), true, ident->bankCode(), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); // Paint bank name painter->save(); const QRect nameRect = style->alignedRect(opt.direction, Qt::AlignTop, QSize(textArea.width(), smallMetrics.lineSpacing()), QRect(textArea.left(), metrics.lineSpacing() + smallMetrics.lineSpacing() + textArea.top(), textArea.width(), smallMetrics.lineSpacing()) ); style->drawItemText(painter, nameRect, Qt::AlignBottom, QApplication::palette(), true, ident->bankName(), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); // Paint account number painter->save(); QFont normal = painter->font(); normal.setBold(true); painter->setFont(normal); const QRect ibanRect = style->alignedRect(opt.direction, Qt::AlignTop, QSize(textArea.width(), metrics.lineSpacing()), textArea); const QString bic = index.model()->data(index, Qt::DisplayRole).toString(); style->drawItemText(painter, ibanRect, Qt::AlignTop, QApplication::palette(), true, ident->accountNumber(), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); // Paint type painter->save(); QRect typeRect = style->alignedRect(opt.direction, Qt::AlignTop | Qt::AlignRight, QSize(textArea.width() / 5, metrics.lineSpacing()), textArea); style->drawItemText(painter, typeRect, Qt::AlignTop | Qt::AlignRight, QApplication::palette(), true, i18n("National Account"), opt.state & QStyle::State_Selected ? QPalette::HighlightedText : QPalette::Text); painter->restore(); } QSize nationalAccountDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QStyleOptionViewItem opt = option; initStyleOption(&opt, index); // QStyle::State_Editing is never set (seems to be a bug in Qt)! This code is here only because it was written already const QAbstractItemView *view = qobject_cast(opt.widget); if (view && view->indexWidget(index)) return view->indexWidget(index)->sizeHint(); QFontMetrics metrics(option.font); const QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); const int margin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1; // An iban has maximal 32 characters, so national accounts should be shorter than 28 return QSize((28)*metrics.width(QLatin1Char('X')) + 2*margin, 3*metrics.lineSpacing() + metrics.leading() + 2*margin); } QWidget* nationalAccountDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(option); nationalAccountEdit* edit = new nationalAccountEdit(parent); connect(edit, SIGNAL(commitData(QWidget*)), this, SIGNAL(commitData(QWidget*))); connect(edit, SIGNAL(closeEditor(QWidget*)), this, SIGNAL(closeEditor(QWidget*))); emit sizeHintChanged(index); return edit; } void nationalAccountDelegate::setEditorData(QWidget* editor, const QModelIndex& index) const { nationalAccountEdit* nationalEditor = qobject_cast< nationalAccountEdit* >(editor); Q_CHECK_PTR(nationalEditor); nationalEditor->setIdentifier(identByIndex(index)); } void nationalAccountDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { Q_CHECK_PTR(editor); Q_CHECK_PTR(model); Q_ASSERT(index.isValid()); nationalAccountEdit* nationalEditor = qobject_cast< nationalAccountEdit* >(editor); Q_CHECK_PTR(nationalEditor); payeeIdentifierTyped ident = identByIndex(index); ident->setAccountNumber(nationalEditor->accountNumber()); ident->setBankCode(nationalEditor->institutionCode()); model->setData(index, QVariant::fromValue(ident), payeeIdentifierContainerModel::payeeIdentifier); } void nationalAccountDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(index); editor->setGeometry(option.rect); } /** * Internal helper to direcly convert the QVariant into the correct pointer type. */ payeeIdentifierTyped nationalAccountDelegate::identByIndex(const QModelIndex& index) const { payeeIdentifierTyped ident = payeeIdentifierTyped( index.model()->data(index, payeeIdentifierContainerModel::payeeIdentifier).value() ); Q_ASSERT(!ident.isNull()); return ident; } diff --git a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.h b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.h index 20c867078..024312bfb 100644 --- a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.h +++ b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountdelegate.h @@ -1,48 +1,48 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef NATIONALACCOUNTDELEGATE_H #define NATIONALACCOUNTDELEGATE_H #include #include "../nationalaccount.h" #include "payeeidentifier/payeeidentifiertyped.h" class nationalAccountDelegate : public QStyledItemDelegate { Q_OBJECT public: nationalAccountDelegate(QObject* parent, const QVariantList& options = QVariantList()); virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void setEditorData(QWidget* editor, const QModelIndex& index) const; virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; signals: void sizeHintChanged(const QModelIndex&) const; private: inline payeeIdentifierTyped identByIndex(const QModelIndex& index) const; }; #endif // NATIONALACCOUNTDELEGATE_H diff --git a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.cpp b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.cpp index 60c0c65be..fce7357e2 100644 --- a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.cpp +++ b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.cpp @@ -1,93 +1,93 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "nationalaccountedit.h" #include "payeeidentifier/payeeidentifiertyped.h" #include "payeeidentifier/nationalaccount/nationalaccount.h" #include "ui_nationalaccountedit.h" struct nationalAccountEdit::Private { Ui::nationalAccountEdit ui; payeeIdentifier m_identifier; }; nationalAccountEdit::nationalAccountEdit(QWidget* parent) : QWidget(parent), d(new Private) { d->ui.setupUi(this); setFocusProxy(d->ui.accountNumberEdit); connect(d->ui.accountNumberEdit, SIGNAL(textChanged(QString)), this, SIGNAL(accountNumberChannged(QString))); connect(d->ui.institutionCodeEdit, SIGNAL(textChanged(QString)), this, SIGNAL(institutionCodeChanged(QString))); connect(d->ui.accountNumberEdit, SIGNAL(returnPressed()), this, SLOT(editFinished())); connect(d->ui.institutionCodeEdit, SIGNAL(returnPressed()), this, SLOT(editFinished())); } payeeIdentifier nationalAccountEdit::identifier() const { if (!d->m_identifier.isNull()) { try { payeeIdentifierTyped ident(d->m_identifier); ident->setAccountNumber(d->ui.accountNumberEdit->text()); ident->setBankCode(d->ui.institutionCodeEdit->text()); } catch (payeeIdentifier::exception&) { } } return d->m_identifier; } void nationalAccountEdit::editFinished() { emit commitData(this); emit closeEditor(this); } QString nationalAccountEdit::accountNumber() const { return d->ui.accountNumberEdit->text(); } QString nationalAccountEdit::institutionCode() const { return d->ui.institutionCodeEdit->text(); } void nationalAccountEdit::setIdentifier(const payeeIdentifier& ident) { try { payeeIdentifierTyped identTyped(ident); d->ui.accountNumberEdit->setText(identTyped->accountNumber()); d->ui.institutionCodeEdit->setText(identTyped->bankCode()); d->m_identifier = ident; } catch (payeeIdentifier::exception&) { } } void nationalAccountEdit::setAccountNumber(const QString& accountNumber) { d->ui.accountNumberEdit->setText(accountNumber); } void nationalAccountEdit::setInstitutionCode(const QString& institutionCode) { d->ui.institutionCodeEdit->setText(institutionCode); } diff --git a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.h b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.h index a64c49350..6efa8751e 100644 --- a/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.h +++ b/kmymoney/payeeidentifier/nationalaccount/ui/nationalaccountedit.h @@ -1,63 +1,63 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef NATIONALACCOUNTEDIT_H #define NATIONALACCOUNTEDIT_H #include #include "payeeidentifier/payeeidentifier.h" namespace Ui { class nationalAccountEdit; } class nationalAccountEdit : public QWidget { Q_OBJECT Q_PROPERTY(payeeIdentifier identifier READ identifier WRITE setIdentifier STORED true) Q_PROPERTY(QString accountNumber READ accountNumber WRITE setAccountNumber NOTIFY accountNumberChannged STORED false DESIGNABLE true) Q_PROPERTY(QString institutionCode READ institutionCode WRITE setInstitutionCode NOTIFY institutionCodeChanged STORED false DESIGNABLE true) public: nationalAccountEdit(QWidget* parent = 0); payeeIdentifier identifier() const; QString accountNumber() const; QString institutionCode() const; public Q_SLOTS: void setIdentifier(const payeeIdentifier&); void setAccountNumber(const QString&); void setInstitutionCode(const QString&); Q_SIGNALS: void institutionCodeChanged(QString); void accountNumberChannged(QString); void commitData(QWidget*); void closeEditor(QWidget*); private Q_SLOTS: void editFinished(); private: struct Private; Private* d; }; #endif // NATIONALACCOUNTEDIT_H diff --git a/kmymoney/payeeidentifier/nationalaccount/ui/pluginfactory.cpp b/kmymoney/payeeidentifier/nationalaccount/ui/pluginfactory.cpp index bb24fb4ad..bdf92ae65 100644 --- a/kmymoney/payeeidentifier/nationalaccount/ui/pluginfactory.cpp +++ b/kmymoney/payeeidentifier/nationalaccount/ui/pluginfactory.cpp @@ -1,27 +1,27 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "nationalaccountdelegate.h" // TODO: port KF5 /*K_PLUGIN_FACTORY(ibanAndBicPidWidgetsFactory, registerPlugin("delegate"); ) K_EXPORT_PLUGIN(ibanAndBicPidWidgetsFactory("payeeidentifier_nationalaccount_ui"))*/ diff --git a/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.cpp b/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.cpp index c4691d3eb..4a235506a 100644 --- a/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.cpp +++ b/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.cpp @@ -1,111 +1,111 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "unavailableplugin.h" #include namespace payeeIdentifiers { payeeIdentifierUnavailable::payeeIdentifierUnavailable() : payeeIdentifierData(), m_data(QDomElement()) { } payeeIdentifierUnavailable::payeeIdentifierUnavailable(QDomElement data) : payeeIdentifierData(), m_data(data) { } payeeIdentifierUnavailable* payeeIdentifierUnavailable::clone() const { return new payeeIdentifierUnavailable(m_data); } void payeeIdentifierUnavailable::writeXML(QDomDocument& document, QDomElement& parent) const { Q_UNUSED(document); parent = m_data; } payeeIdentifierUnavailable* payeeIdentifierUnavailable::createFromXml(const QDomElement& element) const { return new payeeIdentifierUnavailable(element); } QString payeeIdentifierUnavailable::storagePluginIid() const { return QString(); } bool payeeIdentifierUnavailable::sqlSave(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection) Q_UNUSED(onlineJobId) return false; } bool payeeIdentifierUnavailable::sqlModify(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection) Q_UNUSED(onlineJobId) return false; } bool payeeIdentifierUnavailable::sqlRemove(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection) Q_UNUSED(onlineJobId) return false; } payeeIdentifierData* payeeIdentifierUnavailable::createFromSqlDatabase(QSqlDatabase db, const QString& identId) const { Q_UNUSED(db); Q_UNUSED(identId); return 0; } bool payeeIdentifierUnavailable::isValid() const { return false; } bool payeeIdentifierUnavailable::operator==(const payeeIdentifierData& other) const { if (payeeIdentifierId() == other.payeeIdentifierId()) { try { const payeeIdentifierUnavailable& otherCasted = dynamic_cast(other); return operator==(otherCasted); } catch (const std::bad_cast&) { } } return false; } bool payeeIdentifierUnavailable::operator==(const payeeIdentifierUnavailable& other) const { return (m_data == other.m_data); } } // namespace payeeIdentifiers diff --git a/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.h b/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.h index 905fda112..29f31ba43 100644 --- a/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.h +++ b/kmymoney/payeeidentifier/unavailableplugin/unavailableplugin.h @@ -1,74 +1,74 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERS_PAYEEIDENTIFIERUNAVAILABLE_H #define PAYEEIDENTIFIERS_PAYEEIDENTIFIERUNAVAILABLE_H #include "payeeidentifier/payeeidentifierdata.h" #include class payeeIdentifierLoader; namespace payeeIdentifiers { /** * @brief A payeeIdentifier which is used to store the plain xml data * * To avoid data loss if a plugin could not be loaded this payeeIdentifier is used in the xml backend. * It stores the data in plain xml so it can be written back to the file. */ class payeeIdentifierUnavailable : public payeeIdentifierData { public: PAYEEIDENTIFIER_IID(payeeIdentifierUnavailable, "org.kmymoney.payeeIdentifier.payeeIdentifierUnavailable"); payeeIdentifierUnavailable(); virtual void writeXML(QDomDocument& document, QDomElement& parent) const; virtual payeeIdentifierUnavailable* createFromXml(const QDomElement& element) const; virtual bool isValid() const; virtual bool operator==(const payeeIdentifierData& other) const; bool operator==(const payeeIdentifierUnavailable& other) const; friend class payeeIdentifierLoader; /** @todo make private */ payeeIdentifierUnavailable(QDomElement data); /** * @name SqlMethods * @{ * For SQL databases this plugin is not needed nor used. So these functions * do not have a real implementation. */ virtual QString storagePluginIid() const; virtual bool sqlSave(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual bool sqlModify(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual bool sqlRemove(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual payeeIdentifierData* createFromSqlDatabase(QSqlDatabase db, const QString& identId) const; /** @} */ protected: virtual payeeIdentifierUnavailable* clone() const; private: QDomElement m_data; }; } // namespace payeeidentifiers #endif // PAYEEIDENTIFIERS_PAYEEIDENTIFIERUNAVAILABLE_H diff --git a/kmymoney/plugins/ibanbicdata/germany/germany.py b/kmymoney/plugins/ibanbicdata/germany/germany.py index eb1861c97..b6aba9d88 100755 --- a/kmymoney/plugins/ibanbicdata/germany/germany.py +++ b/kmymoney/plugins/ibanbicdata/germany/germany.py @@ -1,96 +1,96 @@ #/usr/bin/python3 # -*- coding: utf-8 -*- """ -This file is part of KMyMoney, A Personal Finance Manager for KDE +This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2014-2015 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ """ Uses the "Bankleitzahlendatei" of the german Bundesbank to create a bic lookup table for KMyMoney @author: Christian David """ import sqlite3 import codecs import argparse def createTable(): """ Create table structure """ cursor = db.cursor() cursor.execute("DROP TABLE IF EXISTS institutions") cursor.execute( "CREATE TABLE institutions (" " country CHAR(2) DEFAULT 'DE' CONSTRAINT germanCountryCode NOT NULL CHECK(country == 'DE')," " bankcode CHAR(8) NOT NULL PRIMARY KEY CHECK(length(bankcode) = 8)," " bic CHAR(11)," " name VARCHAR(60)" " )" ) db.commit() def processFile(fileName): """ Fills the database with institutions saved in fileName """ rowsInserted = 0 cursor = db.cursor() cursor.execute("BEGIN") def submitInstitute(bankCode, bankName, bic): try: cursor.execute("INSERT INTO institutions (bankcode, bic, name) VALUES(?,?,?)", (bankCode, bic, bankName)) except sqlite3.Error as e: print("Error: {0} while inserting {1} ({2})".format(e.args[0], bankCode, bic)) institutesFile = codecs.open(fileName, "r", encoding=args.encoding) for institute in institutesFile: if institute[8:9] == "1": submitInstitute(institute[0:8], institute[9:67].strip(), institute[139:150]) rowsInserted += 1 db.commit() return rowsInserted if __name__ == '__main__': parser = argparse.ArgumentParser(description="Creates a SQLite database for KMyMoney with information about IBAN and BICs based on a fixed-column text file from the german central bank." " You can download the source file at http://www.bundesbank.de/Redaktion/DE/Standardartikel/Aufgaben/Unbarer_Zahlungsverkehr/bankleitzahlen_download.html" ) parser.add_argument(dest='file', help='File to load') parser.add_argument('-o', '--output', default="bankdata.de.db", help='SQLite database to open/generate') parser.add_argument('-e', '--encoding', default="iso 8859-1", help='Charset of file') args = parser.parse_args() print("Read data from \"{0}\" with \"{1}\" encoding".format(args.file, args.encoding)) db = sqlite3.connect(args.output) createTable() institutions = processFile(args.file) print("Inserted {0} institutions into database \"{1}\"".format(institutions, args.output)) cursor = db.cursor() cursor.execute("ANALYZE institutions") cursor.execute("CREATE INDEX bic_index ON institutions (bic)") cursor.execute("REINDEX") cursor.execute("VACUUM") db.commit(); db.close() diff --git a/kmymoney/plugins/ibanbicdata/netherlands/netherlands.py b/kmymoney/plugins/ibanbicdata/netherlands/netherlands.py index d39b0bd98..716e17dc8 100644 --- a/kmymoney/plugins/ibanbicdata/netherlands/netherlands.py +++ b/kmymoney/plugins/ibanbicdata/netherlands/netherlands.py @@ -1,90 +1,90 @@ #!/usr/bin/python # -*- coding: utf-8 -*- """ -This file is part of KMyMoney, A Personal Finance Manager for KDE +This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2014-2015 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ """ Uses the " BIC-lijstvanNederlandsebankenvoorSEPA " of the dutch Betaalvereniging Nederland bank to create a bic lookup table for KMyMoney . @author: Christian David """ # importing important packages import sqlite3 import argparse import xlrd def createTable(): """ Create table structure """ cursor = db.cursor() cursor.execute("DROP TABLE IF EXISTS institutions") cursor.execute( "CREATE TABLE institutions (" " country CHAR(2) DEFAULT 'NL' CONSTRAINT dutchCountryCode NOT NULL CHECK(country == 'NL')," " bankcode CHAR(4) NOT NULL PRIMARY KEY CHECK(length(bankcode) = 4)," " bic CHAR(11)," " name VARCHAR(60)" " )" ) db.commit() def processFile(fileName): """ Fills the database with institutions saved in fileName """ cursor = db.cursor() cursor.execute("BEGIN") institutionCounter = 0 def submitInstitute(bankCode, bankName, bic): try: cursor.execute("INSERT INTO institutions (bankCode, bic, name) VALUES(?,?,?)", (bankCode, bic, bankName)) except sqlite3.Error as e: print("Sorry , Error: {0} while inserting {1} ({2})".format(e.args[0], bankCode, bic)) book = xlrd.open_workbook(fileName, 'r') sheet = book.sheet_by_index(0) for row_index in range(2, sheet.nrows): submitInstitute(sheet.cell(row_index,0).value, sheet.cell(row_index,2).value, sheet.cell(row_index,1).value) institutionCounter += 1 return institutionCounter if __name__ == '__main__': parser = argparse.ArgumentParser(description="Create an SQLite database for KMyMoney with information about IBAN and BICs based on an 'Excel 2007 sheet' from the Dutch Betaalvereniging for the banks in the netherlands." " You can download the source (.xlsx) file at http://www.betaalvereniging.nl/europees-betalen/sepa-documentatie/bic-afleiden-uit-iban/" ) parser.add_argument(dest='file', help='File to load') parser.add_argument('-o', '--output', default="bankdata.nl.db", help='SQLite database to open/generate') args = parser.parse_args() print("Read data from \"{0}\"".format(args.file)) db = sqlite3.connect(args.output) createTable() institutions = processFile(args.file) print("Inserted {0} institutions into database \"{1}\"".format(institutions, args.output)) cursor = db.cursor() cursor.execute("ANALYZE institutions") cursor.execute("CREATE INDEX bic_index ON institutions (bic)") cursor.execute("REINDEX") cursor.execute("VACUUM") db.commit() db.close() diff --git a/kmymoney/plugins/ibanbicdata/switzerland/switzerland.py b/kmymoney/plugins/ibanbicdata/switzerland/switzerland.py index d37f2ce00..4a93b375b 100644 --- a/kmymoney/plugins/ibanbicdata/switzerland/switzerland.py +++ b/kmymoney/plugins/ibanbicdata/switzerland/switzerland.py @@ -1,102 +1,102 @@ # -*- coding: utf-8 -*- """ -This file is part of KMyMoney, A Personal Finance Manager for KDE +This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2014-2015 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ """ Reads swiss a bank-clearing-number file to generate a SQLite lookup table for KMyMoney @author: Christian David """ import sqlite3 import codecs import argparse def createTable(): """ Create table structure """ cursor = db.cursor() cursor.execute("DROP TABLE IF EXISTS institutions") cursor.execute( "CREATE TABLE institutions (" " country CHAR(2) DEFAULT 'CH' CONSTRAINT switzerlandCountryCode NOT NULL CHECK( country = 'CH')," " bankcode CHAR(5) NOT NULL CONSTRAINT bcNumberLength CHECK(length(bankcode) == 5)," " bic CHAR(11) NOT NULL CONSTRAINT bicLength CHECK(length(bic) == 11)," " name VARCHAR(60)," " PRIMARY KEY(bankcode, bic)" " )" ) db.commit() def processFile(fileName): """ Fills the database with institutions saved in fileName """ rowsInserted = 0 cursor = db.cursor() cursor.execute("BEGIN") def submitInstitute(bankCode, bankName, bic): try: cursor.execute("INSERT INTO institutions (bankcode, bic, name) VALUES(?,?,?)", (bankCode, bic, bankName)) except sqlite3.Error as e: print("Error: {0} while inserting {1} ({2})".format(e.args[0], bankCode, bic)) institutesFile = codecs.open(fileName, "r", encoding=args.encoding) for institute in institutesFile: bic = institute[284:295].strip() if len(bic) > 0: bcNumber = "{:0>5}".format(institute[2:7].strip() if institute[11:16] == " " else institute[11:16].strip()) name = "%s (%s)" % (institute[54:114].strip(), institute[194:229].strip()) submitInstitute(bcNumber, name, bic) rowsInserted += 1 db.commit() return rowsInserted if __name__ == '__main__': parser = argparse.ArgumentParser(description="Creates a SQLite database for KMyMoney with information about IBAN and BICs based on a swiss BC-Bankenstamm file." " You can get the BC-Bankenstamm file from http://www.six-interbank-clearing.com/de/home/bank-master-data/download-bc-bank-master.html" ) parser.add_argument(dest='file', help='File to load') parser.add_argument('-o', '--output', default="bankdata.ch.db", help='SQLite database to open/generate') parser.add_argument('-e', '--encoding', default="iso 8859-15", help='Charset of file') args = parser.parse_args() print("Read data from \"{0}\" with \"{1}\" encoding".format(args.file, args.encoding)) db = sqlite3.connect(args.output) createTable() institutions = processFile(args.file) print("Inserted {0} institutions into database \"{1}\"".format(institutions, args.output)) cursor = db.cursor() cursor.execute("ANALYZE institutions") # This table is so small it should fit in the memory without any problems #cursor.execute("CREATE INDEX bic_index ON institutions (bic)") #cursor.execute("CREATE INDEX clearingnumber_index ON institutions (bankcode)") cursor.execute("REINDEX") cursor.execute("VACUUM") db.commit() db.close() diff --git a/kmymoney/plugins/ibanbicdata/target2/target-list_of_participants.py b/kmymoney/plugins/ibanbicdata/target2/target-list_of_participants.py index bf54152bd..f50ce7ca7 100644 --- a/kmymoney/plugins/ibanbicdata/target2/target-list_of_participants.py +++ b/kmymoney/plugins/ibanbicdata/target2/target-list_of_participants.py @@ -1,99 +1,99 @@ # -*- coding: utf-8 -*- """ -This file is part of KMyMoney, A Personal Finance Manager for KDE +This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2014-2015 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ """ @author: Christian David """ import sqlite3 import codecs import argparse import csv def createTable(): """ Create table structure """ cursor = db.cursor() cursor.execute("DROP TABLE IF EXISTS institutions") cursor.execute( "CREATE TABLE institutions (" " country CHAR(2) NOT NULL CONSTRAINT wrongCountryCode CHECK(length(country) = 2)," " bankcode CHAR(0) DEFAULT NULL CONSTRAINT noBankCodes CHECK(bankcode is NULL)," " bic CHAR(11) NOT NULL UNIQUE CONSTRAINT bicLength CHECK(length(bic) = 11)," " name VARCHAR(256)," " PRIMARY KEY(bic)" " )" ) db.commit() def processFile(fileName): """ Fills the database with institutions saved in fileName """ rowsInserted = 0 cursor = db.cursor() cursor.execute("BEGIN") def submitInstitute(country, bankName, bic): try: cursor.execute("INSERT INTO institutions (country, bic, name) VALUES(?,?,?)", (country, bic, bankName)) except sqlite3.Error as e: print("Error: {0} while inserting {1}-{2} (\"{3}\")".format(e.args[0], country, bic, bankName)) with codecs.open(fileName, "r", encoding=args.encoding) as csvfile: reader = csv.reader(csvfile) for institute in reader: submitInstitute(institute[0][4:6], institute[1], institute[0]) rowsInserted += 1 db.commit() return rowsInserted if __name__ == '__main__': parser = argparse.ArgumentParser(description="Creates a SQLite database for KMyMoney with information about IBAN and BICs based on the list of participants of Target2." " You can download the csv file from https://www.ecb.europa.eu/paym/t2/professional/participation/html/index.en.html" ) parser.add_argument(dest='file', help='File to load') parser.add_argument('-o', '--output', default="bankdata.target2.db", help='SQLite database to open/generate') parser.add_argument('-e', '--encoding', default="ascii", help='Charset of file') args = parser.parse_args() print("Read data from \"{0}\" with \"{1}\" encoding".format(args.file, args.encoding)) db = sqlite3.connect(args.output) createTable() institutions = processFile( args.file ) print("Inserted {0} institutions into database \"{1}\"".format(institutions, args.output)) cursor = db.cursor() cursor.execute("ANALYZE institutions") # This table is so small it should fit in the memory without any problems #cursor.execute("CREATE INDEX bic_index ON institutions (bic)") #cursor.execute("CREATE INDEX clearingnumber_index ON institutions (bankcode)") cursor.execute("REINDEX") cursor.execute("VACUUM") db.commit() db.close() diff --git a/kmymoney/plugins/interfaceloader.cpp b/kmymoney/plugins/interfaceloader.cpp index 2f7d074a9..1ad1ef815 100644 --- a/kmymoney/plugins/interfaceloader.cpp +++ b/kmymoney/plugins/interfaceloader.cpp @@ -1,29 +1,29 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2016 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "interfaceloader.h" namespace KMyMoneyPlugin { InterfaceLoader& pluginInterfaces() { static InterfaceLoader m_interfaces; return m_interfaces; } } diff --git a/kmymoney/plugins/interfaceloader.h b/kmymoney/plugins/interfaceloader.h index bb80f74eb..c8d85453f 100644 --- a/kmymoney/plugins/interfaceloader.h +++ b/kmymoney/plugins/interfaceloader.h @@ -1,58 +1,58 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2016 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kmymoneyplugin.h" #include "kmm_plugin_export.h" class KMyMoneyApp; namespace KMyMoneyPlugin { class Plugin; /** * @internal * * This class is used as dead drop to comunicate between two compile targets which cannot do * this directly. * It is only used by the classes which are named friends. To receive an instance of * this class @ref pluginInterfaces() is used. */ class InterfaceLoader { /** * @{ * This class is owner of these objects. However, the parent is somebody else. They are deleted by destruction of the parent only. */ KMyMoneyPlugin::ViewInterface* viewInterface; KMyMoneyPlugin::StatementInterface* statementInterface; KMyMoneyPlugin::ImportInterface* importInterface; /** @} */ friend KMyMoneyApp; friend KMyMoneyPlugin::Plugin; }; /** * @internal * * Returns an instance of @ref InterfaceLoader. It is created if needed. */ KMM_PLUGIN_EXPORT InterfaceLoader& pluginInterfaces(); } diff --git a/kmymoney/plugins/kbanking/aqbankingkmmoperators.cpp b/kmymoney/plugins/kbanking/aqbankingkmmoperators.cpp index 8b67bcbb5..d2759ea68 100644 --- a/kmymoney/plugins/kbanking/aqbankingkmmoperators.cpp +++ b/kmymoney/plugins/kbanking/aqbankingkmmoperators.cpp @@ -1,165 +1,165 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "aqbankingkmmoperators.h" #include #include #include #include #include "payeeidentifier/payeeidentifiertyped.h" #include "payeeidentifier/nationalaccount/nationalaccount.h" #include "tasksettings/credittransfersettingsbase.h" #include "onlinetasks/sepa/tasks/sepaonlinetransfer.h" #include "gwenhywfarqtoperators.h" /** * @brief DTAUS Chars * * @source http://www.hbci-zka.de/dokumente/spezifikation_deutsch/FinTS_3.0_Messages_Finanzdatenformate_2010-08-06_final_version.pdf * * @note This file is saved in UTF-8! * * Additional lower case letters were added, or should the input mask replaced them mit the uppercase version? The bank should do that * anyway. */ static const QString dtausChars = QString::fromUtf8("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜß .,&-+*%/$&abcdefghijklmnopqrstuvwxyzäöü"); /** * @brief Sepa Charset * * Additional lower case letters were added, or should the input mask replaced them mit the uppercase version? The bank should do that * anyway. */ static const QString sepaChars = QString("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz':?.,- (+)/"); /** @todo Check if AB_TransactionLimits_GetMaxLenCustomerReference really is the limit for the sepa reference */ QSharedPointer AB_TransactionLimits_toSepaOnlineTaskSettings(const AB_TRANSACTION_LIMITS* aqlimits) { Q_CHECK_PTR(aqlimits); QSharedPointer settings(new creditTransferSettingsBase); settings->setPurposeLimits(AB_TransactionLimits_GetMaxLinesPurpose(aqlimits), AB_TransactionLimits_GetMaxLenPurpose(aqlimits), AB_TransactionLimits_GetMinLenPurpose(aqlimits) ); // AqBanking returns 0 as min length even if it requires one int minLength = AB_TransactionLimits_GetMinLenRemoteName(aqlimits); if (minLength == 0) minLength = 1; settings->setRecipientNameLimits(AB_TransactionLimits_GetMaxLinesRemoteName(aqlimits), AB_TransactionLimits_GetMaxLenRemoteName(aqlimits), minLength ); // AqBanking returns 0 as min length even if it requires one minLength = AB_TransactionLimits_GetMinLenLocalName(aqlimits); if (minLength == 0) minLength = 1; settings->setPayeeNameLimits(1, AB_TransactionLimits_GetMaxLenLocalName(aqlimits), minLength); //settings->referenceLength = AB_TransactionLimits_GetMax( aqlimits ); settings->setEndToEndReferenceLength(32); settings->setAllowedChars(sepaChars); return settings.dynamicCast(); } void AB_Transaction_SetRemoteAccount(AB_TRANSACTION* transaction, const payeeIdentifiers::nationalAccount& ident) { Q_CHECK_PTR(transaction); AB_Transaction_SetRemoteAccountNumber(transaction, ident.accountNumber().toUtf8().constData()); AB_Transaction_SetRemoteBankCode(transaction, ident.bankCode().toUtf8().constData()); AB_Transaction_SetRemoteName(transaction, GWEN_StringList_fromQString(ident.ownerName())); } void AB_Transaction_SetRemoteAccount(AB_TRANSACTION* transaction, const payeeIdentifiers::ibanBic& ident) { Q_CHECK_PTR(transaction); AB_Transaction_SetRemoteAccountNumber(transaction, ident.electronicIban().toUtf8().constData()); AB_Transaction_SetRemoteBankCode(transaction, ident.fullStoredBic().toUtf8().constData()); AB_Transaction_SetRemoteName(transaction, GWEN_StringList_fromQString(ident.ownerName())); } void AB_Transaction_SetLocalAccount(AB_TRANSACTION* transaction, const AB_ACCOUNT* account) { Q_CHECK_PTR(transaction); Q_CHECK_PTR(account); AB_Transaction_SetLocalName(transaction, AB_Account_GetOwnerName(account)); AB_Transaction_SetLocalAccountNumber(transaction, AB_Account_GetAccountNumber(account)); AB_Transaction_SetLocalBankCode(transaction, AB_Account_GetBankCode(account)); AB_Transaction_SetLocalIban(transaction, AB_Account_GetIBAN(account)); AB_Transaction_SetLocalBic(transaction, AB_Account_GetBIC(account)); } void AB_Transaction_SetLocalAccount(AB_TRANSACTION* transaction, const payeeIdentifiers::nationalAccount& ident) { Q_CHECK_PTR(transaction); AB_Transaction_SetLocalName(transaction, ident.ownerName().toUtf8().constData()); AB_Transaction_SetLocalAccountNumber(transaction, ident.accountNumber().toUtf8().constData()); AB_Transaction_SetLocalBankCode(transaction, ident.bankCode().toUtf8().constData()); } bool AB_Transaction_SetLocalAccount(AB_TRANSACTION* transaction, const QList& accountNumbers) { Q_CHECK_PTR(transaction); bool validOriginAccountSet = false; foreach (payeeIdentifier accountNumber, accountNumbers) { if (!accountNumber.isValid()) continue; try { payeeIdentifierTyped iban(accountNumber); AB_Transaction_SetLocalIban(transaction, iban->electronicIban().toUtf8().constData()); AB_Transaction_SetLocalBic(transaction, iban->fullStoredBic().toUtf8().constData()); } catch (...) { } try { payeeIdentifierTyped national(accountNumber); AB_Transaction_SetLocalAccount(transaction, *(national.data())); validOriginAccountSet = true; } catch (...) { } } return validOriginAccountSet; } AB_VALUE* AB_Value_fromMyMoneyMoney(const MyMoneyMoney& input) { return (AB_Value_fromString(input.toString().toUtf8().constData())); } MyMoneyMoney AB_Value_toMyMoneyMoney(const AB_VALUE *const value) { // I've read somewhere that in M1 were about 12 trillion dollar in 2013. So the buffer length of 32 should be sufficient. char buffer[32]; memset(buffer, 0, sizeof(buffer)); AB_Value_GetNumDenomString(value, static_cast(buffer), 32); return MyMoneyMoney(QString::fromUtf8(buffer)); } diff --git a/kmymoney/plugins/kbanking/aqbankingkmmoperators.h b/kmymoney/plugins/kbanking/aqbankingkmmoperators.h index 289652748..e8943bfb5 100644 --- a/kmymoney/plugins/kbanking/aqbankingkmmoperators.h +++ b/kmymoney/plugins/kbanking/aqbankingkmmoperators.h @@ -1,93 +1,93 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /** * @file Helper functions for using aqbanking with KMyMoney * * These functions are similar to the ones in aqbanking. They are meant as glue between aqbanking and KMyMoney. * */ #ifndef AQBANKINGKMMOPERATORS_H #define AQBANKINGKMMOPERATORS_H #include #include "onlinetasks/interfaces/tasks/ionlinetasksettings.h" #include "onlinetasks/sepa/tasks/sepaonlinetransfer.h" struct AB_ACCOUNT; struct AB_TRANSACTION_LIMITS; struct AB_TRANSACTION; struct AB_VALUE; namespace payeeIdentifiers { class ibanBic; class nationalAccount; } /** * @brief AB_TransactionLimits_toSepaOnlineTaskSettings * @param aqlimits IN */ QSharedPointer AB_TransactionLimits_toSepaOnlineTaskSettings(const AB_TRANSACTION_LIMITS* aqlimits); /** * @brief AB_Transaction_SetRemoteAccount * @param transaction * @param ident */ void AB_Transaction_SetRemoteAccount(AB_TRANSACTION* transaction, const payeeIdentifiers::ibanBic& ident); void AB_Transaction_SetRemoteAccount(AB_TRANSACTION* transaction, const payeeIdentifiers::nationalAccount& ident); /** * @brief Set local account of transaction by aqBanking account ptr */ void AB_Transaction_SetLocalAccount(AB_TRANSACTION* transaction, const AB_ACCOUNT* account); /** * @brief AB_Transaction_SetLocalAccount * @param transaction * @param ident */ void AB_Transaction_SetLocalAccount(AB_TRANSACTION* transaction, const payeeIdentifiers::nationalAccount& ident); /** * @brief Set local account of transaction from list * * Will check if an element of accountNumbers is valid and if it is payeeIdentifiers::ibanBic or payeeIdentifiers::natinalAccount. * If such a payeeIdentifier is found, it is set as local account for @c transaction * * @return true if a valid payeeIdentifiers::natinalAccount was set */ bool AB_Transaction_SetLocalAccount(AB_TRANSACTION* transaction, const QList& accountNumbers); /** * @brief Create AB_VALUE from MyMoneyMoney * * @return caller gains ownership */ AB_VALUE* AB_Value_fromMyMoneyMoney(const MyMoneyMoney& input); /** * @brief Convert AB_VALUE to MyMoneyMoney */ MyMoneyMoney AB_Value_toMyMoneyMoney(const AB_VALUE *const value); #endif // AQBANKINGKMMOPERATORS_H diff --git a/kmymoney/plugins/kbanking/gwenhywfarqtoperators.cpp b/kmymoney/plugins/kbanking/gwenhywfarqtoperators.cpp index c1ab5769a..e26165eee 100644 --- a/kmymoney/plugins/kbanking/gwenhywfarqtoperators.cpp +++ b/kmymoney/plugins/kbanking/gwenhywfarqtoperators.cpp @@ -1,39 +1,39 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "gwenhywfarqtoperators.h" #include #include GWEN_STRINGLIST* GWEN_StringList_fromQStringList(const QStringList& input) { GWEN_STRINGLIST *ret = GWEN_StringList_new(); QString line; foreach (line, input) { GWEN_StringList_AppendString(ret, line.toUtf8().constData(), false, false); } return ret; } GWEN_STRINGLIST* GWEN_StringList_fromQString(const QString& input) { GWEN_STRINGLIST *ret = GWEN_StringList_new(); GWEN_StringList_AppendString(ret, input.toUtf8().constData(), false, false); return ret; } diff --git a/kmymoney/plugins/kbanking/gwenhywfarqtoperators.h b/kmymoney/plugins/kbanking/gwenhywfarqtoperators.h index db5c9378c..5e3169b2d 100644 --- a/kmymoney/plugins/kbanking/gwenhywfarqtoperators.h +++ b/kmymoney/plugins/kbanking/gwenhywfarqtoperators.h @@ -1,47 +1,47 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef GWENHYWFARQTOPERATORS_H #define GWENHYWFARQTOPERATORS_H #include class QString; class QStringList; /** * @defgroup gwenhywfarqtoperators Helper functions for using gwenhywfar with Qt * * These functions are similar to original gwenhywfar ones. They are meant to glue qt and gwenhywfar. * * @{ */ /** * @brief Create GWEN_STRINGLIST from QStringList */ GWEN_STRINGLIST* GWEN_StringList_fromQStringList(const QStringList& input); /** * @brief Create GWEN_STRINGLIST from QString */ GWEN_STRINGLIST* GWEN_StringList_fromQString(const QString& input); /** @} */ // end of gwenhywfarqtoperators #endif // GWENHYWFARQTOPERATORS_H diff --git a/kmymoney/plugins/kbanking/gwenkdegui.h b/kmymoney/plugins/kbanking/gwenkdegui.h index f0c4c2eea..493dec470 100644 --- a/kmymoney/plugins/kbanking/gwenkdegui.h +++ b/kmymoney/plugins/kbanking/gwenkdegui.h @@ -1,91 +1,91 @@ /* * A gwenhywfar gui for aqbanking using KDE widgets * Copyright 2014 - 2016 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License or (at your option) version 3 or any later version * accepted by the membership of KDE e.V. (or its successor approved * by the membership of KDE e.V.), which shall act as a proxy * defined in Section 14 of version 3 of the license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef GWENKDEGUI_H #define GWENKDEGUI_H #include #include "gwen-gui-qt5/qt5_gui.hpp" /** - * @brief Gwenhywfar Gui for KDE + * @brief Gwenhywfar Gui by KDE * * * @author Christian David */ class gwenKdeGui : public QT5_Gui { public: gwenKdeGui(); ~gwenKdeGui(); virtual int getPassword(uint32_t flags, const char *token, const char *title, const char *text, char *buffer, int minLen, int maxLen, uint32_t guiid); }; /** * @brief Helper class which is receiver for several signals */ class gwenKdeGuiTanResult : public QObject { Q_OBJECT public: gwenKdeGuiTanResult(QObject* parent = nullptr) : QObject(parent), m_tan(QString()), m_aborted(false) {} virtual ~gwenKdeGuiTanResult() {} QString tan() { return m_tan; } bool aborted() { return m_aborted; } public slots: void abort() { m_aborted = true; } void acceptTan(QString tan) { m_tan = tan; m_aborted = false; } private: QString m_tan; bool m_aborted; }; #endif // GWENKDEGUI_H diff --git a/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.cpp b/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.cpp index 840c91f97..bc3be63d1 100644 --- a/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.cpp +++ b/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.cpp @@ -1,145 +1,145 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "credittransfersettingsbase.h" #include validators::lengthStatus creditTransferSettingsBase::checkNameLength(const QString& name) const { if (name.length() > _payeeNameLength) return validators::tooLong; else if (name.length() < _payeeNameMinLength) return validators::tooShort; return validators::ok; } bool creditTransferSettingsBase::checkPurposeMaxLines(const QString& purpose) const { return (purpose.split('\n').count() <= _purposeMaxLines); } validators::lengthStatus creditTransferSettingsBase::checkPurposeLength(const QString& purpose) const { const int length = purpose.length(); if (length > (_purposeMaxLines*_purposeLineLength)) return validators::tooLong; else if (length < _purposeMinLength) return validators::tooShort; return validators::ok; } bool creditTransferSettingsBase::checkPurposeLineLength(const QString& purpose) const { return validators::checkLineLength(purpose, _purposeLineLength); } bool creditTransferSettingsBase::checkPurposeCharset(const QString& string) const { const QString chars = _allowedChars + QChar('\n'); return validators::checkCharset(string, chars); } validators::lengthStatus creditTransferSettingsBase::checkRecipientLength(const QString& name) const { const int length = name.length(); if (length > _recipientNameLength) return validators::tooLong; else if (length == 0 || length < _recipientNameMinLength) return validators::tooShort; return validators::ok; } bool creditTransferSettingsBase::checkNameCharset(const QString& name) const { return validators::checkCharset(name, _allowedChars); } bool creditTransferSettingsBase::checkRecipientCharset(const QString& name) const { return validators::checkCharset(name, _allowedChars); } bool creditTransferSettingsBase::isBicMandatory(const QString& payeeIban, const QString& beneficaryIban) const { const QString payeeContryCode = payeeIban.trimmed().left(2); const QString beneficaryCountryCode = beneficaryIban.trimmed().left(2); /** * Data source for sepa participants: * @url http://www.europeanpaymentscouncil.eu/index.cfm/knowledge-bank/epc-documents/epc-list-of-sepa-scheme-countries/ * EPC409-09 * Version 2.0 * Date issued: 20 January 2014 */ QStringList sepaParticipants; sepaParticipants << "FI" << "AT" << "PT" << "BE" << "BG" << "ES" << "HR" << "CY" << "CZ" << "DK" << "EE" << "FI" << "FR" << "DE" << "GI" << "GR" << "HU" << "IS" << "IE" << "IT" << "LV" << "LI" << "LT" << "LU" << "PT" << "MT" << "MC" << "NL" << "NO" << "PL" << "RO" << "SM" << "SK" << "SI" << "ES" << "SE" << "CH" << "GB"; // Starting form 1st Febuary 2016 no bic is needed between sepa countries if (QDate::currentDate() >= QDate(2016, 2, 1)) return (!sepaParticipants.contains(payeeContryCode, Qt::CaseInsensitive) || !sepaParticipants.contains(beneficaryCountryCode, Qt::CaseInsensitive)); // Before that date the bic is needed except for transfers within a single sepa country return (payeeContryCode.compare(beneficaryCountryCode, Qt::CaseInsensitive) != 0 || !sepaParticipants.contains(payeeContryCode, Qt::CaseInsensitive)); } bool creditTransferSettingsBase::checkRecipientBic(const QString& bic) const { const int length = bic.length(); for (int i = 0; i < std::min(length, 6); ++i) { if (!bic.at(i).isLetter()) return false; } for (int i = 6; i < length; ++i) { if (!bic.at(i).isLetterOrNumber()) return false; } if (length == 11 || length == 8) return true; return false; } validators::lengthStatus creditTransferSettingsBase::checkEndToEndReferenceLength(const QString& reference) const { if (reference.length() > m_endToEndReferenceLength) return validators::tooLong; return validators::ok; } validators::lengthStatus creditTransferSettingsBase::checkRecipientAccountNumber(const QString& accountNumber) const { const int length = accountNumber.length(); if (length == 0) return validators::tooShort; else if (length > 10) return validators::tooLong; return validators::ok; } validators::lengthStatus creditTransferSettingsBase::checkRecipientBankCode(const QString& bankCode) const { const int length = bankCode.length(); if (length < 8) return validators::tooShort; else if (length > 8) return validators::tooLong; return validators::ok; } diff --git a/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.h b/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.h index 3bac6ce82..3e35b8bf8 100644 --- a/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.h +++ b/kmymoney/plugins/kbanking/tasksettings/credittransfersettingsbase.h @@ -1,164 +1,164 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef CREDITTRANSFERSETTINGSBASE_H #define CREDITTRANSFERSETTINGSBASE_H #include "onlinetasks/sepa/tasks/sepaonlinetransfer.h" /** * @brief Base class for sepaCreditTransfer and germanCreditTransfer settings * * @internal Both credit transfers have similar fields */ class creditTransferSettingsBase : public sepaOnlineTransfer::settings { public: creditTransferSettingsBase() : _purposeMaxLines(0), _purposeLineLength(0), _purposeMinLength(0), _recipientNameMaxLines(0), _recipientNameLength(0), _recipientNameMinLength(0), _payeeNameMaxLines(0), _payeeNameLength(0), _payeeNameMinLength(0), _allowedChars(QString("")) {} // Limits getter int purposeMaxLines() const { return _purposeMaxLines; } int purposeLineLength() const { return _purposeLineLength; } int purposeMinLength() const { return _purposeMinLength; } int recipientNameLineLength() const { return _recipientNameLength; } int recipientNameMinLength() const { return _recipientNameMinLength; } int payeeNameLineLength() const { return _payeeNameLength; } int payeeNameMinLength() const { return _payeeNameMinLength; } QString allowedChars() const { return _allowedChars; } virtual int endToEndReferenceLength() const { return m_endToEndReferenceLength; } // Checker bool checkPurposeCharset(const QString& string) const; bool checkPurposeLineLength(const QString& purpose) const; validators::lengthStatus checkPurposeLength(const QString& purpose) const; bool checkPurposeMaxLines(const QString& purpose) const; validators::lengthStatus checkNameLength(const QString& name) const; bool checkNameCharset(const QString& name) const; validators::lengthStatus checkRecipientLength(const QString& name) const; bool checkRecipientCharset(const QString& name) const; virtual validators::lengthStatus checkEndToEndReferenceLength(const QString& reference) const; virtual bool checkRecipientBic(const QString& bic) const; /** * @brief Checks if the bic is mandatory for the given iban * * For the check usually only the first two chars are needed. So you do not * need to validate the IBAN. * * There is no need to format fromIban or toIban in any way (it is trimmed automatically). */ virtual bool isBicMandatory(const QString& fromIban, const QString& toIban) const; validators::lengthStatus checkRecipientAccountNumber(const QString& accountNumber) const; validators::lengthStatus checkRecipientBankCode(const QString& bankCode) const; // Limits setter void setEndToEndReferenceLength(const int& length) { m_endToEndReferenceLength = length; } void setPurposeLimits(const int& lines, const int& lineLength, const int& minLength) { _purposeMaxLines = lines; _purposeLineLength = lineLength; _purposeMinLength = minLength; } void setRecipientNameLimits(const int& lines, const int& lineLength, const int& minLength) { _recipientNameMaxLines = lines; _recipientNameLength = lineLength; _recipientNameMinLength = minLength; } void setPayeeNameLimits(const int& lines, const int& lineLength, const int& minLength) { _payeeNameMaxLines = lines; _payeeNameLength = lineLength; _payeeNameMinLength = minLength; } void setAllowedChars(QString characters) { _allowedChars = characters; } private: /** @brief number of lines allowed in purpose */ int _purposeMaxLines; /** @brief number of chars allowed in each purpose line */ int _purposeLineLength; /** @brief Minimal number of chars needed for purpose */ int _purposeMinLength; /** @brief number of lines allowed for recipient name */ int _recipientNameMaxLines; /** @brief number of chars allowed in each recipient line */ int _recipientNameLength; /** @brief Minimal number of chars needed as recipient name */ int _recipientNameMinLength; /** @brief number of lines allowed for payee name */ int _payeeNameMaxLines; /** @brief number of chars allowed in each payee line */ int _payeeNameLength; /** @brief Minibal number of chars for payee name */ int _payeeNameMinLength; /** @brief characters allowd in purpose and recipient name */ QString _allowedChars; /** @brief Number of chars allowed for sepa reference */ int m_endToEndReferenceLength; }; #endif // CREDITTRANSFERSETTINGSBASE_H diff --git a/kmymoney/plugins/kmymoneyplugin.h b/kmymoney/plugins/kmymoneyplugin.h index d8f69bbe0..d118c72ad 100644 --- a/kmymoney/plugins/kmymoneyplugin.h +++ b/kmymoney/plugins/kmymoneyplugin.h @@ -1,278 +1,278 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2005 Thomas Baumgart * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KMYMONEYPLUGIN_H #define KMYMONEYPLUGIN_H // ---------------------------------------------------------------------------- // QT Includes #include // ---------------------------------------------------------------------------- // KDE Includes #include class KAction; class KToggleAction; // ---------------------------------------------------------------------------- // Project Includes #include #include #include #include /** * @defgroup KMyMoneyPlugin * * KMyMoney knows several types of plugins. The most common and generic one is KMyMoneyPlugin::Plugin. * * Another group of plugins are just loaded on demand and offer special functions with a tight integration into KMyMoney. Whenever possible you should use this kind of plugins. * At the moment this are the onlineTask and payeeIdentifierData. * * @{ */ namespace KMyMoneyPlugin { /** * This class describes the interface between KMyMoney and it's plugins. * * The plugins are based on Qt 5's plugin system. So you must compile json information into the plugin. * KMyMoney looks into the folder "${PLUGIN_INSTALL_DIR}/kmymoney/" and loads all plugins found there (if the user did not deactivate the plugin). * * The json header of the plugin must comply with the requirements of KCoreAddon's KPluginMetaData class. * To load the plugin at start up the service type "KMyMoney/Plugin" must be set. * * @warning The plugin system for KMyMoney 5 is still in development. Especially the loading of the on-demand plugins (mainly undocumented :( ) will change. * * A basic json header is shown below. * @code{.json} { "KPlugin": { "Authors": [ { "Name": "Author's Names, Second Author", "Email": "E-Mail 1, E-Mail 2" } ], "Description": "Short description for plugin list (translateable)", "EnabledByDefault": true, "Icon": "icon to be shown in plugin list", "Id": "a unique identifier", "License": "see KPluginMetaData for list of predefined licenses (translateable)", "Name": "Name of the plugin (translateable)", "ServiceTypes": [ "KMyMoney/Plugin" ], "Version": "@PROJECT_VERSION@@PROJECT_VERSION_SUFFIX@", } } * @endcode * * This example assumes you are using * @code{.cmake} configure_file(${CMAKE_CURRENT_SOURCE_DIR}/... ${CMAKE_CURRENT_BINARY_DIR}/... @ONLY) @endcode * to replace the version variables using cmake. * * @see http://doc.qt.io/qt-5/plugins-howto.html * @see https://api.kde.org/frameworks/kcoreaddons/html/classKPluginMetaData.html * */ class KMM_PLUGIN_EXPORT Plugin : public QObject, public KXMLGUIClient { Q_OBJECT public: Plugin(QObject* parent = nullptr, const char* name = ""); virtual ~Plugin(); public slots: /** * @brief Called during plug in process */ virtual void plug(); /** * @brief Called before unloading */ virtual void unplug(); /** * @brief Called if the configuration of the plugin was changed * @todo Implement */ virtual void configurationChanged() ; protected: /** See KMyMoneyApp::toggleAction() for a description */ KToggleAction* toggleAction(const QString& name) const; // define interface classes here. The interface classes provide a mechanism // for the plugin to interact with KMyMoney // they are defined in the following form for an interface // named Xxx: // // XxxInterface* xxxInterface(); ViewInterface* viewInterface() const; StatementInterface* statementInterface() const; ImportInterface* importInterface() const; }; /** * This class describes the interface between the KMyMoney * application and it's ONLINE-BANKING plugins. All online banking plugins * must provide this interface. * * A good tutorial on how to design and develop a plugin * structure for a KDE application (e.g. KMyMoney) can be found at * http://developer.kde.org/documentation/tutorials/developing-a-plugin-structure/index.html * */ class KMM_PLUGIN_EXPORT OnlinePlugin { public: OnlinePlugin() {} virtual ~OnlinePlugin() {} virtual void protocols(QStringList& protocolList) const = 0; /** * This method returns a pointer to a widget representing an additional * tab that will be added to the KNewAccountDlg. The string referenced * with @a tabName will be filled with the text that should be placed * on the tab. It should return 0 if no additional tab is needed. * * Information about the account can be taken out of @a account. * * Once the pointer to the widget is returned to KMyMoney, it takes care * of destruction of all included widgets when the dialog is closed. The plugin * can access the widgets created after the call to storeConfigParameters() * happened. */ virtual QWidget* accountConfigTab(const MyMoneyAccount& account, QString& tabName) = 0; /** * This method is called by the framework whenever it is time to store * the configuration data maintained by the plugin. The plugin should use * the widgets created in accountConfigTab() to extract the current values. * * @param current The @a current container contains the current settings */ virtual MyMoneyKeyValueContainer onlineBankingSettings(const MyMoneyKeyValueContainer& current) = 0; /** * This method is called by the framework when the user wants to map * a KMyMoney account onto an online account. The KMyMoney account is identified * by @a acc and the online provider should store its data in @a onlineBankingSettings * upon success. * * @retval true if account is mapped * @retval false if account is not mapped */ virtual bool mapAccount(const MyMoneyAccount& acc, MyMoneyKeyValueContainer& onlineBankingSettings) = 0; /** * This method is called by the framework when the user wants to update * a KMyMoney account with data from an online account. The KMyMoney account is identified * by @a acc. The online provider should read its data from acc.onlineBankingSettings(). * @a true is returned upon success. The plugin might consider to stack the requests * in case @a moreAccounts is @p true. @a moreAccounts defaults to @p false. * * @retval true if account is updated * @retval false if account is not updated */ virtual bool updateAccount(const MyMoneyAccount& acc, bool moreAccounts = false) = 0; }; /** * This class describes the interface between the KMyMoney * application and it's IMPORTER plugins. All importer plugins * must provide this interface. * * A good tutorial on how to design and develop a plugin * structure for a KDE application (e.g. KMyMoney) can be found at * http://developer.kde.org/documentation/tutorials/developing-a-plugin-structure/index.html * */ class KMM_PLUGIN_EXPORT ImporterPlugin { public: ImporterPlugin() {} virtual ~ImporterPlugin() {} /** * This method returns the english-language name of the format * this plugin imports, e.g. "OFX" * * @return QString Name of the format */ virtual QString formatName() const = 0; /** * This method returns the filename filter suitable for passing to * KFileDialog::setFilter(), e.g. "*.ofx *.qfx" which describes how * files of this format are likely to be named in the file system * * @return QString Filename filter string */ virtual QString formatFilenameFilter() const = 0; /** * This method returns whether this plugin is able to import * a particular file. * * @param filename Fully-qualified pathname to a file * * @return bool Whether the indicated file is importable by this plugin */ virtual bool isMyFormat(const QString& filename) const = 0; /** * Import a file * * @param filename File to import * * @return bool Whether the import was successful. */ virtual bool import(const QString& filename) = 0; /** * Returns the error result of the last import * * @return QString English-language name of the error encountered in the * last import, or QString() if it was successful. * */ virtual QString lastError() const = 0; }; } // end of namespace Q_DECLARE_INTERFACE(KMyMoneyPlugin::OnlinePlugin, "org.kmymoney.plugin.onlineplugin") Q_DECLARE_INTERFACE(KMyMoneyPlugin::ImporterPlugin, "org.kmymoney.plugin.importerplugin") /** @} */ #endif diff --git a/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.cpp b/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.cpp index 83be16e87..88707915a 100644 --- a/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.cpp +++ b/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.cpp @@ -1,94 +1,94 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobpluginmockup.h" #include #include "mymoneyfile.h" #include "onlinejobadministration.h" #include "plugins/onlinetasks/sepa/tasks/sepaonlinetransfer.h" #include "sepacredittransfersettingsmockup.h" onlineJobPluginMockup::onlineJobPluginMockup() : OnlinePluginExtended(nullptr, "onlinejobpluginmockup") { qDebug("onlineJobPluginMockup should be used during development only!"); } void onlineJobPluginMockup::protocols(QStringList& protocolList) const { protocolList << QLatin1String("Imaginary debugging protocol"); } QWidget* onlineJobPluginMockup::accountConfigTab(const MyMoneyAccount&, QString&) { return 0; } bool onlineJobPluginMockup::mapAccount(const MyMoneyAccount& acc, MyMoneyKeyValueContainer& onlineBankingSettings) { Q_UNUSED(acc); onlineBankingSettings.setValue("provider", objectName()); return true; } MyMoneyKeyValueContainer onlineJobPluginMockup::onlineBankingSettings(const MyMoneyKeyValueContainer& current) { MyMoneyKeyValueContainer nextKvp(current); nextKvp.setValue("provider", objectName()); return nextKvp; } bool onlineJobPluginMockup::updateAccount(const MyMoneyAccount& acc, bool moreAccounts) { Q_UNUSED(moreAccounts); if (acc.onlineBankingSettings().value("provider") == objectName()) return true; return false; } QStringList onlineJobPluginMockup::availableJobs(QString accountId) { try { if (MyMoneyFile::instance()->account(accountId).onlineBankingSettings().value("provider") == objectName()) return onlineJobAdministration::instance()->availableOnlineTasks(); } catch (MyMoneyException&) { } return QStringList(); } IonlineTaskSettings::ptr onlineJobPluginMockup::settings(QString accountId, QString taskName) { try { if (taskName == sepaOnlineTransfer::name() && MyMoneyFile::instance()->account(accountId).onlineBankingSettings().value("provider") == objectName()) return IonlineTaskSettings::ptr(new sepaCreditTransferSettingsMockup); } catch (MyMoneyException&) { } return IonlineTaskSettings::ptr(); } void onlineJobPluginMockup::sendOnlineJob(QList< onlineJob >& jobs) { foreach (const onlineJob& job, jobs) { qDebug() << "Pretend to send: " << job.taskIid() << job.id(); } } diff --git a/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.h b/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.h index c9155872c..e0cd37db0 100644 --- a/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.h +++ b/kmymoney/plugins/onlinejobpluginmockup/onlinejobpluginmockup.h @@ -1,63 +1,63 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBPLUGINMOCKUP_H #define ONLINEJOBPLUGINMOCKUP_H // ---------------------------------------------------------------------------- // QT Includes // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes #include "kmymoneyplugin.h" #include "onlinepluginextended.h" #include "mymoneyaccount.h" #include "mymoneykeyvaluecontainer.h" #include "mymoney/onlinejob.h" /** * @short Mockup plugin which offers all online tasks */ class onlineJobPluginMockup : public KMyMoneyPlugin::OnlinePluginExtended { Q_OBJECT Q_PLUGIN_METADATA(IID "org.kmymoney.plugins.onlineJobPluginMockup" FILE "kmm_onlinejobpluginmockup.json") public: onlineJobPluginMockup(); void protocols(QStringList& protocolList) const; QWidget* accountConfigTab(const MyMoneyAccount& account, QString& tabName); MyMoneyKeyValueContainer onlineBankingSettings(const MyMoneyKeyValueContainer& current); bool mapAccount(const MyMoneyAccount& acc, MyMoneyKeyValueContainer& onlineBankingSettings); bool updateAccount(const MyMoneyAccount& acc, bool moreAccounts = false); QStringList availableJobs(QString accountId); IonlineTaskSettings::ptr settings(QString accountId, QString taskName); void sendOnlineJob(QList< onlineJob >& jobs); }; #endif // ONLINEJOBPLUGINMOCKUP_H diff --git a/kmymoney/plugins/onlinejobpluginmockup/sepacredittransfersettingsmockup.h b/kmymoney/plugins/onlinejobpluginmockup/sepacredittransfersettingsmockup.h index e51d307c1..61fc0b5a0 100644 --- a/kmymoney/plugins/onlinejobpluginmockup/sepacredittransfersettingsmockup.h +++ b/kmymoney/plugins/onlinejobpluginmockup/sepacredittransfersettingsmockup.h @@ -1,108 +1,108 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SEPACREDITTRANSFERSETTINGSMOCKUP_H #define SEPACREDITTRANSFERSETTINGSMOCKUP_H #include "onlinetasks/sepa/tasks/sepaonlinetransfer.h" class sepaCreditTransferSettingsMockup : public sepaOnlineTransfer::settings { public: virtual bool checkRecipientCharset(const QString&) const override { return true; } virtual validators::lengthStatus checkRecipientLength(const QString&) const override { return validators::ok; } virtual bool checkNameCharset(const QString&) const override { return true; } virtual validators::lengthStatus checkNameLength(const QString&) const override { return validators::ok; } virtual bool checkPurposeMaxLines(const QString&) const override { return true; } virtual validators::lengthStatus checkPurposeLength(const QString&) const override { return validators::ok; } virtual bool checkPurposeLineLength(const QString&) const override { return true; } virtual bool checkPurposeCharset(const QString&) const override { return true; } virtual QString allowedChars() const override { return QLatin1String("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"'_-{}()[]~\\/^!?+<>=&:@., "); } virtual int payeeNameMinLength() const override { return 0; } virtual int payeeNameLineLength() const override { return 27; } virtual int recipientNameMinLength() const override { return 0; } virtual int recipientNameLineLength() const override { return 27; } virtual int purposeMinLength() const override { return 0; } virtual int purposeLineLength() const override { return 27; } virtual int purposeMaxLines() const override { return 50; } virtual validators::lengthStatus checkEndToEndReferenceLength(const QString&) const override { return validators::lengthStatus::ok; } virtual bool checkRecipientBic(const QString&) const override { return true; } virtual int endToEndReferenceLength() const override { return 27; } virtual bool isBicMandatory(const QString&, const QString&) const override { return false; } }; #endif // SEPACREDITTRANSFERSETTINGSMOCKUP_H diff --git a/kmymoney/plugins/onlinetasks/dummy/tasks/dummytask.h b/kmymoney/plugins/onlinetasks/dummy/tasks/dummytask.h index 309a01831..a2afc241f 100644 --- a/kmymoney/plugins/onlinetasks/dummy/tasks/dummytask.h +++ b/kmymoney/plugins/onlinetasks/dummy/tasks/dummytask.h @@ -1,94 +1,94 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef DUMMYTASK_H #define DUMMYTASK_H #include "onlinetasks/interfaces/tasks/onlinetask.h" class dummyTask : public onlineTask { public: ONLINETASK_META(dummyTask, "org.kmymoney.onlinetasks.dummy"); dummyTask() : m_testNumber(0) { } dummyTask(const dummyTask& other) : onlineTask(other), m_testNumber(other.m_testNumber) { } /** * @brief Checks if the task is ready for sending */ virtual bool isValid() const { return true; }; /** * @brief Human readable type-name */ virtual QString jobTypeName() const { return QLatin1String("Dummy task"); }; void setTestNumber(const int& number) { m_testNumber = number; } int testNumber() { return m_testNumber; } virtual QString storagePluginIid() const { return QString(); } virtual bool sqlSave(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection); Q_UNUSED(onlineJobId); return false; } virtual bool sqlModify(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection); Q_UNUSED(onlineJobId); return false; } virtual bool sqlRemove(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection); Q_UNUSED(onlineJobId); return false; } protected: virtual dummyTask* clone() const { return (new dummyTask(*this)); } virtual bool hasReferenceTo(const QString &id) const { Q_UNUSED(id); return false; } virtual void writeXML(QDomDocument&, QDomElement&) const {} virtual dummyTask* createFromXml(const QDomElement&) const { return (new dummyTask); } virtual onlineTask* createFromSqlDatabase(QSqlDatabase connection, const QString& onlineJobId) const { Q_UNUSED(connection); Q_UNUSED(onlineJobId); return (new dummyTask); } virtual QString responsibleAccount() const { return QString(); }; int m_testNumber; }; #endif // DUMMYTASK_H diff --git a/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.cpp b/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.cpp index 4b76ace94..78b5c36a1 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.cpp +++ b/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.cpp @@ -1,27 +1,27 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinetaskconverter.h" onlineTaskConverter::onlineTaskConverter() { } onlineTaskConverter::~onlineTaskConverter() { } diff --git a/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.h b/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.h index cf81aef1f..fbd80ad07 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.h +++ b/kmymoney/plugins/onlinetasks/interfaces/converter/onlinetaskconverter.h @@ -1,98 +1,98 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINETASKCONVERTER_H #define ONLINETASKCONVERTER_H #include #include class onlineTask; /** * @brief Base to convert task of one type to another type. * * If you want to enable KMyMoney to convert a task to another task you must implement this * interface. */ class onlineTaskConverter { public: /** * @brief Type of convertion * * They are ordered. convertImpossible is 0, higher number means better. * * Used by canConvert(). */ enum convertType { /** Convert operation is not possible */ convertImpossible = 0, /** Convertion is accompanied with loss of data. The user is warned and has to confirm the changes. */ convertionLossyMajor, /** * Convertion is accompanied with change of data. The user must be informed and hast to confirm the changes. * Anyway the new task is quite equvalent to the old one. */ convertionLossyMinor, /** Convertion is possible without user interaction */ convertionLoseless }; onlineTaskConverter(); virtual ~onlineTaskConverter(); /** * @brief List of tasks you accept to convert * * @return list of task iids */ virtual QStringList convertibleTasks() const = 0; /** * @brief Task you convert into * * @return task iid */ virtual QString convertedTask() const = 0; /** * @brief Convert a task * * @return The returned task must be of type convertedTask() or 0. Caller takes ownership. * * @param source task to convert (do not modify it!). It is always of one of the types convertibleTasks() * @param convertResult OUT convertType, if convertionLossy you should provide a userInformation * @param userInformation OUT a translated string with description which data was lost during convertion. * This string is shown by the ui to the user using a KMessageWidget. * * Never forget to set convertResult! You should always set userInformation and convertResult. Code for copy & paste: * @code * userInformation = QString(); * convertResult = convertImpossible; * @endcode * * You must not throw exceptions. */ virtual onlineTask* convert(const onlineTask& source, convertType &convertResult, QString& userInformation) const = 0; }; Q_DECLARE_INTERFACE(onlineTaskConverter, "org.kmymoney.plugin.onlinetaskconverter"); #endif // ONLINETASKCONVERTER_H diff --git a/kmymoney/plugins/onlinetasks/interfaces/tasks/credittransfer.h b/kmymoney/plugins/onlinetasks/interfaces/tasks/credittransfer.h index a259c6b8f..bbe49083e 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/tasks/credittransfer.h +++ b/kmymoney/plugins/onlinetasks/interfaces/tasks/credittransfer.h @@ -1,68 +1,68 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef CREDITTRANSFER_H #define CREDITTRANSFER_H #include "mymoney/mymoneymoney.h" #include "mymoney/mymoneysecurity.h" #include "payeeidentifier/payeeidentifier.h" class QValidator; /** * @brief Describes an online credit-transfer (or similar) * * This class is used by KMyMoney to create a MyMoneySchedule * after a task was sent to the bank. */ class creditTransfer { public: virtual ~creditTransfer() {} virtual MyMoneyMoney value() const = 0; /** @brief The currency the transfer value is in */ virtual MyMoneySecurity currency() const = 0; virtual QString purpose() const = 0; virtual QString responsibleAccount() const = 0; /** * @brief payeeIdentifier of recipient * * The return must never be null_ptr! */ virtual payeeIdentifier beneficiary() const = 0; /** * @brief * @return * @todo Move (logic) to a utils class? */ virtual QString jobTypeName() const { return "Credit Transfer"; } }; Q_DECLARE_INTERFACE(creditTransfer, "org.kmymoney.onlineTasks.creditTransfer"); #endif // CREDITTRANSFER_H diff --git a/kmymoney/plugins/onlinetasks/interfaces/tasks/ionlinetasksettings.h b/kmymoney/plugins/onlinetasks/interfaces/tasks/ionlinetasksettings.h index 543b5d691..fbd278186 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/tasks/ionlinetasksettings.h +++ b/kmymoney/plugins/onlinetasks/interfaces/tasks/ionlinetasksettings.h @@ -1,57 +1,57 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IONLINETASKSETTINGS_H #define IONLINETASKSETTINGS_H #include /** * @brief Account/plugin dependent settings for an onlineTask * * Many onlineTasks settings vary due to multiple reasons. E.g. * a credit transfer could have a maximum amount it can transfer at * once. But this amount could depend on the account and the user's * contract with the bank. * * Therefor onlineTasks can offer thier own set of configurations. There * is no predifined behavior, only subclass onlineTask::settings. * Of course onlinePlugins and widgets which support that task * need to know how to handle that specific settings. * * Using @ref onlineJobAdministration::taskSettings() KMyMoney will * request the correct onlinePlugin to create the settings and return * them as shared pointer. Please note that KMyMoney will try to reuse * that pointer if possible, so do not edit it. */ class IonlineTaskSettings { public: typedef QSharedPointer ptr; /** * Ensure this class to be polymorph * Make gcc happy and prevent a warning */ virtual ~IonlineTaskSettings() {} }; Q_DECLARE_INTERFACE(IonlineTaskSettings, "org.kmymoney.onlinetask.settings") #endif // IONLINETASKSETTINGS_H diff --git a/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.cpp b/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.cpp index 50938c504..72b1adde3 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.cpp +++ b/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.cpp @@ -1,27 +1,27 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinetask.h" onlineTask::onlineTask() {} onlineTask::onlineTask(const onlineTask &other) { Q_UNUSED(other); } diff --git a/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.h b/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.h index 3300859f9..df0075ecd 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.h +++ b/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetask.h @@ -1,179 +1,179 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINETASK_H #define ONLINETASK_H #include #include #include #include "mymoneyaccount.h" #include "onlinejobmessage.h" #include "storage/databasestoreableobject.h" class onlineJob; /** * @brief Enables onlineTask meta system * * Use ONLINETASK_META in your onlineTask derived class to create an onlineTask type iid * (the name). This is should be like the plugin iid of Qt5 (ONLINATASK_META was written * for Qt4). * * Given this code * @code onlineTask* taskA = // unknown; onlineTaskB *taskB = new onlineTaskB; * @endcode * * The following constrains are used by KMyMoney: * - @c taskA->taskName() == onlineTaskA::name() => dynamic_cast() * - @c dynamic_cast(taskB) == 0 => taskB->taskName() != onlineTaskC::name() * * @param onlineTaskSubClass the class type (e.g. onlineTask) * @param IID A unique name for the task, should be replaced by IID of Qt5 plugins * * \section onlineTaskMeta The onlineTask Meta System * * To prevent accidently using a super-class if sub-class should be used, the onlineTasks * have a meta system. Each onlineTask has an iid which can be requested with a virtual * method or a static method. * * The task @b IID (type @c QString) is constant (even after a restart) and set by the programmer. * \code * // get the name of a known type * onlineTask::name() * // get the name of a pointer * onlineTask* unknownTask = new onlineTaskSubClass(); * unknownTask->taskName(); * \endcode * * Activate the meta system using ONLINETASK_META() in your classes public section. */ #define ONLINETASK_META(onlineTaskClass, IID) \ /** @brief Returns the iid of onlineTask type (part of @ref onlineTaskMeta) */ \ static const QString& name() { \ static const QString _name = IID; \ return _name; \ } \ /** @brief Returns the iid of onlineTask type (part of @ref onlineTaskMeta) */ \ virtual QString taskName() const { \ return onlineTaskClass::name(); \ } \ friend class onlineJobAdministration /** * @brief Base class for tasks which can be proceeded by online banking plugins * * @notice This docu describes the inteded way of the onlineTask/Job system. The loading during runtime or plugin * infrastructure is not realized yet (and needs further changes at the storage). The docu is just forward compatible. * * Everything an online plugin can do is represented as a task. But also imported data can be represented by an * onlineTask. * * Due to the huge amount of possible onlineTasks they are loaded during runtime. Which also allows a third party * online plugin to introduce its own tasks. However tasks are separated from the onlinePlugins to allow more than one * plugin to use the same task. Usually you will have an interface and an implementation (which derives from the * interface) to enable this. * * As user of an online Task you use @r onlineJobAdministration::createOnlineJob() to create a task (within an * onlineJob). * * The widgets to edit an onlineTask are created by subclassing @a IonlineJobEdit. To enable KMyMoney to convert * one task into another use @a onlineTaskConverter. * * @important Do not delete onlineTasks or use pointers to onlineTasks directly. Use @r onlineJob or @r onlineJobTyped instead! * This prevents common C++ pitfalls. * * If you inherit onlineTask, take care of clone() and @ref onlineTaskMeta. * Maybe you want to look at @ref onlineTask::settings as well. * * @see onlineJob */ class onlineTask : public databaseStoreableObject { public: ONLINETASK_META(onlineTask, "org.kmymoney.onlineTask"); onlineTask(); virtual ~onlineTask() {} /** * @brief Checks if the task is ready for sending */ virtual bool isValid() const = 0; /** * @brief Human readable type-name */ virtual QString jobTypeName() const = 0; protected: onlineTask(const onlineTask& other); /** * @brief Copy this instance including inherited information * * This method copies an onlineJob including all information which are stored in inherited classes * even if you do not know the final type of an reference or pointer. */ virtual onlineTask* clone() const = 0; /** @see MyMoneyObject::hasReferenceTo() */ virtual bool hasReferenceTo(const QString &id) const = 0; /** @see MyMoneyObject::writeXML() */ virtual void writeXML(QDomDocument &document, QDomElement &parent) const = 0; /** * @brief Create a new instance of this task based on xml data * * This method is used to load an onlineTask from a xml file. * * This method is created const as it should create a @emph new onlineTask. * @return A pointer to a new instance, caller takes ownership */ virtual onlineTask* createFromXml(const QDomElement &element) const = 0; /** * @brief Create new instance of this task from a SQL database * * Equivalent to createFromXml() */ virtual onlineTask* createFromSqlDatabase(QSqlDatabase connection, const QString& onlineJobId) const = 0; /** * @brief Account this job is related to * * Each task must have an account on which it operates. This is used to determine * the correct onlinePlugin which can execute this job. If the job is related to more * than one account (e.g. a password change) select a random one. * * You can make this method public if it is useful for you. * * @return accountId */ virtual QString responsibleAccount() const = 0; friend class onlineJob; }; Q_DECLARE_INTERFACE(onlineTask, "org.kmymoney.onlinetask"); #endif // ONLINETASK_H diff --git a/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetasksettingsfactory.h b/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetasksettingsfactory.h index def57f414..6aea9879c 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetasksettingsfactory.h +++ b/kmymoney/plugins/onlinetasks/interfaces/tasks/onlinetasksettingsfactory.h @@ -1,32 +1,32 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINETASKSETTINGSFACTORY_H #define ONLINETASKSETTINGSFACTORY_H #include "onlinetasks/interfaces/tasks/ionlinetasksettings.h" class onlineTaskSettingsFactory { protected: virtual IonlineTaskSettings::ptr createSettings() const = 0; }; Q_DECLARE_INTERFACE(onlineTaskSettingsFactory, "org.kmymoney.onlinetask.settingsFactory") #endif // ONLINETASKSETTINGSFACTORY_H diff --git a/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.cpp b/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.cpp index b3ab7889e..8f15969fa 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.cpp +++ b/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.cpp @@ -1,19 +1,19 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ionlinejobedit.h" diff --git a/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h b/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h index 9a085ed0d..a65404677 100644 --- a/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h +++ b/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h @@ -1,102 +1,102 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef IONLINEJOBEDIT_H #define IONLINEJOBEDIT_H #include #include #include "mymoney/onlinejob.h" /** * @brief Interface for widgets editing onlineTasks * * @since 4.8.0 */ class IonlineJobEdit : public QWidget { Q_OBJECT public: explicit IonlineJobEdit(QWidget* parent = 0, QVariantList args = QVariantList()) : QWidget(parent) { Q_UNUSED(args); } /** * @brief Reads interface and creates an onlineJob * * An null onlineJob can be returned. */ virtual onlineJob getOnlineJob() const = 0; /** * @brief Checks if the user input would generate a valid onlineJob */ virtual bool isValid() const = 0; /** * @brief List of supported onlineTasks * * Returns a list of all task ids which can be edited with this * widget. */ virtual QStringList supportedOnlineTasks() const = 0; /** * @brief Returns true if this widget is editable */ virtual bool isReadOnly() const = 0; public slots: /** * @brief Set an onlineJob to edit * * If the task is not compatible to the widget, return false. Do not throw * exceptions (and catch all of them). * * @return false if setting was not possible */ virtual bool setOnlineJob(const onlineJob&) = 0; virtual void setOriginAccount(const QString&) = 0; virtual void showAllErrorMessages(const bool) {} signals: /** * @brief Emitted if a job which transfers money changed it's value */ void transferValueChanged(MyMoneyMoney); /** * @brief Emitted if a job got valid or invalid * * @param valid status of onlineJob.isValid() */ void validityChanged(bool valid); /** * @brief Emitted if widget was set or unset read only */ void readOnlyChanged(bool); }; Q_DECLARE_INTERFACE(IonlineJobEdit, "org.kmymoney.plugin.ionlinejobedit"); #endif // IONLINEJOBEDIT_H diff --git a/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.cpp b/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.cpp index ffeeb1303..09a6da6f3 100644 --- a/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.cpp +++ b/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.cpp @@ -1,50 +1,50 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "sepaonlinetasksloader.h" #include #include "mymoney/onlinejobadministration.h" #include "tasks/sepaonlinetransferimpl.h" #include "ui/sepacredittransferedit.h" #include "sepastorageplugin.h" K_PLUGIN_FACTORY_WITH_JSON(sepaOnlineTasksFactory, "kmymoney-sepaorders.json", registerPlugin("sepaOnlineTasks"); registerPlugin("sepaCreditTransferUi"); registerPlugin("sepaSqlStoragePlugin"); ) sepaOnlineTasksLoader::sepaOnlineTasksLoader(QObject* parent, const QVariantList& /*options*/) : QObject(parent), onlineTaskFactory() { } onlineTask* sepaOnlineTasksLoader::createOnlineTask(const QString& taskId) const { if (taskId == sepaOnlineTransferImpl::name()) return new sepaOnlineTransferImpl; return nullptr; } // Needed for K_PLUGIN_FACTORY #include "sepaonlinetasksloader.moc" diff --git a/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.h b/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.h index 704abf9e8..c6fac6ef6 100644 --- a/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.h +++ b/kmymoney/plugins/onlinetasks/sepa/sepaonlinetasksloader.h @@ -1,34 +1,34 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SEPAONLINETASKSLOADER_H #define SEPAONLINETASKSLOADER_H #include class sepaOnlineTasksLoader : public QObject, public KMyMoneyPlugin::onlineTaskFactory { Q_OBJECT Q_INTERFACES(KMyMoneyPlugin::onlineTaskFactory) public: sepaOnlineTasksLoader(QObject* parent = nullptr, const QVariantList& options = QVariantList{}); virtual onlineTask* createOnlineTask(const QString& taskId) const; }; #endif // SEPAONLINETASKSLOADER_H diff --git a/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.cpp b/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.cpp index 25b8b919f..6d23a88ee 100644 --- a/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.cpp +++ b/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.cpp @@ -1,95 +1,95 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "sepastorageplugin.h" #include #include const QString sepaStoragePlugin::iid = QLatin1String("org.kmymoney.creditTransfer.sepa.sqlStoragePlugin"); sepaStoragePlugin::sepaStoragePlugin(QObject* parent, const QVariantList& options) : storagePlugin(parent) { Q_UNUSED(options); } /** @todo implement */ bool sepaStoragePlugin::removePluginData(QSqlDatabase connection) { Q_UNUSED(connection); return false; } bool sepaStoragePlugin::setupDatabase(QSqlDatabase connection) { // Get current version QSqlQuery query = QSqlQuery(connection); query.prepare("SELECT versionMajor FROM kmmPluginInfo WHERE iid = ?"); query.bindValue(0, iid); if (!query.exec()) { qWarning("Could not execute query for sepaStoragePlugin: %s", qPrintable(query.lastError().text())); return false; } int currentVersion = 0; if (query.next()) currentVersion = query.value(0).toInt(); // Create database in it's most recent version if version is 0 // (version 0 means the database was not installed) if (currentVersion == 0) { // If the database is recreated the table may be still there. So drop it if needed. No error handling needed // as this step is not necessary - only the creation is important. query.exec("DROP TABLE IF EXISTS kmmSepaOrders;"); if (!query.exec( "CREATE TABLE kmmSepaOrders (" " id varchar(32) NOT NULL PRIMARY KEY REFERENCES kmmOnlineJobs( id )," " originAccount varchar(32) REFERENCES kmmAccounts( id ) ON UPDATE CASCADE ON DELETE SET NULL," " value text DEFAULT '0'," " purpose text," " endToEndReference varchar(35)," " beneficiaryName varchar(27)," " beneficiaryIban varchar(32)," " beneficiaryBic char(11)," " textKey int," " subTextKey int" " );" )) { qWarning("Error while creating table kmmSepaOrders: %s", qPrintable(query.lastError().text())); return false; } query.prepare("INSERT INTO kmmPluginInfo (iid, versionMajor, versionMinor, uninstallQuery) VALUES(?, ?, ?, ?)"); query.bindValue(0, iid); query.bindValue(1, 1); query.bindValue(2, 0); query.bindValue(3, "DROP TABLE kmmSepaOrders;"); if (query.exec()) return true; qWarning("Error while inserting kmmPluginInfo for '%s': %s", qPrintable(iid), qPrintable(query.lastError().text())); return false; } // Check if version is valid with this plugin switch (currentVersion) { case 1: return true; } return false; } diff --git a/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.h b/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.h index 207dacba9..d44b68c24 100644 --- a/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.h +++ b/kmymoney/plugins/onlinetasks/sepa/sepastorageplugin.h @@ -1,39 +1,39 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SEPASTORAGEPLUGIN_H #define SEPASTORAGEPLUGIN_H #include "kmymoneystorageplugin.h" #include class sepaStoragePlugin : public KMyMoneyPlugin::storagePlugin { Q_OBJECT Q_INTERFACES(KMyMoneyPlugin::storagePlugin) public: sepaStoragePlugin(QObject* parent = 0, const QVariantList& options = QVariantList()); virtual bool removePluginData(QSqlDatabase connection); virtual bool setupDatabase(QSqlDatabase connection); static const QString iid; }; #endif // SEPASTORAGEPLUGIN_H diff --git a/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransfer.h b/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransfer.h index 437653b58..94f51930c 100644 --- a/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransfer.h +++ b/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransfer.h @@ -1,132 +1,132 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SEPAONLINETRANSFER_H #define SEPAONLINETRANSFER_H #include "misc/validators.h" #include "onlinetasks/interfaces/tasks/onlinetask.h" #include "onlinetasks/interfaces/tasks/credittransfer.h" #include "onlinetasks/interfaces/tasks/ionlinetasksettings.h" #include "payeeidentifier/ibanandbic/ibanbic.h" /** * @brief SEPA Credit Transfer */ class sepaOnlineTransfer : public onlineTask, public creditTransfer { Q_INTERFACES(creditTransfer); public: ONLINETASK_META(sepaOnlineTransfer, "org.kmymoney.creditTransfer.sepa"); sepaOnlineTransfer() : onlineTask(), creditTransfer() {} sepaOnlineTransfer(const sepaOnlineTransfer &other) : onlineTask(other), creditTransfer(other) {} virtual QString responsibleAccount() const = 0; virtual void setOriginAccount(const QString& accountId) = 0; virtual MyMoneyMoney value() const = 0; virtual void setValue(MyMoneyMoney value) = 0; virtual void setBeneficiary(const payeeIdentifiers::ibanBic& accountIdentifier) = 0; virtual payeeIdentifiers::ibanBic beneficiaryTyped() const = 0; virtual void setPurpose(const QString purpose) = 0; virtual QString purpose() const = 0; virtual void setEndToEndReference(const QString& reference) = 0; virtual QString endToEndReference() const = 0; /** * @brief Returns the origin account identifier * @return you are owner of the object */ virtual payeeIdentifier originAccountIdentifier() const = 0; /** * National account can handle the currency of the related account only. */ virtual MyMoneySecurity currency() const = 0; virtual bool isValid() const = 0; virtual QString jobTypeName() const = 0; virtual unsigned short int textKey() const = 0; virtual unsigned short int subTextKey() const = 0; virtual bool hasReferenceTo(const QString& id) const = 0; class settings : public IonlineTaskSettings { public: // Limits getter virtual int purposeMaxLines() const = 0; virtual int purposeLineLength() const = 0; virtual int purposeMinLength() const = 0; virtual int recipientNameLineLength() const = 0; virtual int recipientNameMinLength() const = 0; virtual int payeeNameLineLength() const = 0; virtual int payeeNameMinLength() const = 0; virtual QString allowedChars() const = 0; // Checker virtual bool checkPurposeCharset(const QString& string) const = 0; virtual bool checkPurposeLineLength(const QString& purpose) const = 0; virtual validators::lengthStatus checkPurposeLength(const QString& purpose) const = 0; virtual bool checkPurposeMaxLines(const QString& purpose) const = 0; virtual validators::lengthStatus checkNameLength(const QString& name) const = 0; virtual bool checkNameCharset(const QString& name) const = 0; virtual validators::lengthStatus checkRecipientLength(const QString& name) const = 0; virtual bool checkRecipientCharset(const QString& name) const = 0; virtual int endToEndReferenceLength() const = 0; virtual validators::lengthStatus checkEndToEndReferenceLength(const QString& reference) const = 0; virtual bool checkRecipientBic(const QString& bic) const = 0; /** * @brief Checks if the bic is mandatory for the given iban * * For the check usually only the first two chars are needed. So you do not * need to validate the IBAN. * * @todo LOW: Implement, should be simple to test: if the country code in iban is the same as in origin iban and * the iban belongs to a sepa country a bic is not necessary. Will change 1. Feb 2016. */ virtual bool isBicMandatory(const QString& payeeiban, const QString& beneficiaryIban) const = 0; }; virtual QSharedPointer getSettings() const = 0; protected: virtual sepaOnlineTransfer* clone() const = 0; virtual sepaOnlineTransfer* createFromXml(const QDomElement &element) const = 0; virtual void writeXML(QDomDocument& document, QDomElement& parent) const = 0; }; Q_DECLARE_INTERFACE(sepaOnlineTransfer, "org.kmymoney.creditTransfer.sepa") #endif // SEPAONLINETRANSFER_H diff --git a/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.cpp b/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.cpp index ee4450ef1..9723cd7e3 100644 --- a/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.cpp +++ b/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.cpp @@ -1,369 +1,369 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "sepaonlinetransferimpl.h" #include #include #include #include #include "mymoney/mymoneyfile.h" #include "mymoney/onlinejobadministration.h" #include "misc/validators.h" static const unsigned short defaultTextKey = 51; static const unsigned short defaultSubTextKey = 0; /** * @brief Fallback if plugin fails to create settings correctly */ class sepaOnlineTransferSettingsFallback : public sepaOnlineTransfer::settings { public: // Limits getter virtual int purposeMaxLines() const { return 1; } virtual int purposeLineLength() const { return 27; } virtual int purposeMinLength() const { return 0; } virtual int recipientNameLineLength() const { return 1; } virtual int recipientNameMinLength() const { return 0; } virtual int payeeNameLineLength() const { return 0; } virtual int payeeNameMinLength() const { return 0; } virtual QString allowedChars() const { return QString(); } // Checker virtual bool checkPurposeCharset(const QString&) const { return false; } virtual bool checkPurposeLineLength(const QString&) const { return false; } virtual validators::lengthStatus checkPurposeLength(const QString&) const { return validators::tooLong; } virtual bool checkPurposeMaxLines(const QString&) const { return false; } virtual validators::lengthStatus checkNameLength(const QString&) const { return validators::tooLong; } virtual bool checkNameCharset(const QString&) const { return false; } virtual validators::lengthStatus checkRecipientLength(const QString&) const { return validators::tooLong; } virtual bool checkRecipientCharset(const QString&) const { return false; } virtual int endToEndReferenceLength() const { return 0; } virtual validators::lengthStatus checkEndToEndReferenceLength(const QString&) const { return validators::tooLong; } virtual bool isIbanValid(const QString&) const { return false; } virtual bool checkRecipientBic(const QString&) const { return false; } virtual bool isBicMandatory(const QString&, const QString&) const { return true; } }; sepaOnlineTransferImpl::sepaOnlineTransferImpl() : sepaOnlineTransfer(), _settings(QSharedPointer()), _originAccount(QString()), _value(0), _purpose(QString("")), _endToEndReference(QString("")), _beneficiaryAccount(payeeIdentifiers::ibanBic()), _textKey(defaultTextKey), _subTextKey(defaultSubTextKey) { } sepaOnlineTransferImpl::sepaOnlineTransferImpl(const sepaOnlineTransferImpl& other) : sepaOnlineTransfer(other), _settings(other._settings), _originAccount(other._originAccount), _value(other._value), _purpose(other._purpose), _endToEndReference(other._endToEndReference), _beneficiaryAccount(other._beneficiaryAccount), _textKey(other._textKey), _subTextKey(other._subTextKey) { } sepaOnlineTransfer *sepaOnlineTransferImpl::clone() const { sepaOnlineTransfer *transfer = new sepaOnlineTransferImpl(*this); return transfer; } //! @todo add validation of local name bool sepaOnlineTransferImpl::isValid() const { QString iban; try { payeeIdentifier ident = originAccountIdentifier(); iban = ident.data()->electronicIban(); } catch (payeeIdentifier::exception&) { } QSharedPointer settings = getSettings(); if (settings->checkPurposeLength(_purpose) == validators::ok && settings->checkPurposeMaxLines(_purpose) && settings->checkPurposeLineLength(_purpose) && settings->checkPurposeCharset(_purpose) && settings->checkEndToEndReferenceLength(_endToEndReference) == validators::ok //&& settings->checkRecipientCharset( _beneficiaryAccount.ownerName() ) //&& settings->checkRecipientLength( _beneficiaryAccount.ownerName()) == validators::ok && _beneficiaryAccount.isIbanValid() // do not check the BIC, maybe it is not needed && (!settings->isBicMandatory(iban, _beneficiaryAccount.electronicIban()) || (settings->checkRecipientBic(_beneficiaryAccount.bic()) && _beneficiaryAccount.isValid() /** @todo double check of BIC here, fix that */)) && value().isPositive() ) return true; return false; } payeeIdentifier sepaOnlineTransferImpl::originAccountIdentifier() const { QList< payeeIdentifierTyped > idents = MyMoneyFile::instance()->account(_originAccount).payeeIdentifiersByType(); if (!idents.isEmpty()) { payeeIdentifierTyped ident = idents[0]; ident->setOwnerName(MyMoneyFile::instance()->user().name()); return ident; } return payeeIdentifier(new payeeIdentifiers::ibanBic); } /** @todo Return EUR */ MyMoneySecurity sepaOnlineTransferImpl::currency() const { #if 0 return MyMoneyFile::instance()->security(originMyMoneyAccount().currencyId()); #endif return MyMoneyFile::instance()->baseCurrency(); } /** * @internal To ensure that we never return a null_ptr, @a sepaOnlineTransferSettingsFallback is used if the online plugin fails * to give us an correct value */ QSharedPointer sepaOnlineTransferImpl::getSettings() const { if (_settings.isNull()) { _settings = onlineJobAdministration::instance()->taskSettings(name(), _originAccount); if (_settings.isNull()) _settings = QSharedPointer< const sepaOnlineTransfer::settings >(new sepaOnlineTransferSettingsFallback); } Q_CHECK_PTR(_settings); return _settings; } void sepaOnlineTransferImpl::setOriginAccount(const QString &accountId) { if (_originAccount != accountId) { _originAccount = accountId; _settings = QSharedPointer(); } } void sepaOnlineTransferImpl::writeXML(QDomDocument& document, QDomElement& parent) const { Q_UNUSED(document); parent.setAttribute("originAccount", _originAccount); parent.setAttribute("value", _value.toString()); parent.setAttribute("textKey", _textKey); parent.setAttribute("subTextKey", _subTextKey); if (!_purpose.isEmpty()) { parent.setAttribute("purpose", _purpose); } if (!_endToEndReference.isEmpty()) { parent.setAttribute("endToEndReference", _endToEndReference); } QDomElement beneficiaryEl = document.createElement("beneficiary"); _beneficiaryAccount.writeXML(document, beneficiaryEl); parent.appendChild(beneficiaryEl); } sepaOnlineTransfer* sepaOnlineTransferImpl::createFromXml(const QDomElement& element) const { sepaOnlineTransferImpl* task = new sepaOnlineTransferImpl(); task->setOriginAccount(element.attribute("originAccount", QString())); task->setValue(MyMoneyMoney(QStringEmpty(element.attribute("value", QString())))); task->_textKey = element.attribute("textKey", QString().setNum(defaultTextKey)).toUShort(); task->_subTextKey = element.attribute("subTextKey", QString().setNum(defaultSubTextKey)).toUShort(); task->setPurpose(element.attribute("purpose", QString())); task->setEndToEndReference(element.attribute("endToEndReference", QString())); payeeIdentifiers::ibanBic beneficiary; payeeIdentifiers::ibanBic* beneficiaryPtr = 0; QDomElement beneficiaryEl = element.firstChildElement("beneficiary"); if (!beneficiaryEl.isNull()) { beneficiaryPtr = beneficiary.createFromXml(beneficiaryEl); } if (beneficiaryPtr == 0) { task->_beneficiaryAccount = beneficiary; } else { task->_beneficiaryAccount = *beneficiaryPtr; } delete beneficiaryPtr; return task; } onlineTask* sepaOnlineTransferImpl::createFromSqlDatabase(QSqlDatabase connection, const QString& onlineJobId) const { Q_ASSERT(!onlineJobId.isEmpty()); Q_ASSERT(connection.isOpen()); QSqlQuery query = QSqlQuery( "SELECT originAccount, value, purpose, endToEndReference, beneficiaryName, beneficiaryIban, " " beneficiaryBic, textKey, subTextKey FROM kmmSepaOrders WHERE id = ?", connection ); query.bindValue(0, onlineJobId); if (query.exec() && query.next()) { sepaOnlineTransferImpl* task = new sepaOnlineTransferImpl(); task->setOriginAccount(query.value(0).toString()); task->setValue(MyMoneyMoney(query.value(1).toString())); task->setPurpose(query.value(2).toString()); task->setEndToEndReference(query.value(3).toString()); task->_textKey = query.value(7).toUInt(); task->_subTextKey = query.value(8).toUInt(); payeeIdentifiers::ibanBic beneficiary; beneficiary.setOwnerName(query.value(4).toString()); beneficiary.setIban(query.value(5).toString()); beneficiary.setBic(query.value(6).toString()); task->_beneficiaryAccount = beneficiary; return task; } return 0; } void sepaOnlineTransferImpl::bindValuesToQuery(QSqlQuery& query, const QString& id) const { query.bindValue(":id", id); query.bindValue(":originAccount", _originAccount); query.bindValue(":value", _value.toString()); query.bindValue(":purpose", _purpose); query.bindValue(":endToEndReference", (_endToEndReference.isEmpty()) ? QVariant() : QVariant::fromValue(_endToEndReference)); query.bindValue(":beneficiaryName", _beneficiaryAccount.ownerName()); query.bindValue(":beneficiaryIban", _beneficiaryAccount.electronicIban()); query.bindValue(":beneficiaryBic", (_beneficiaryAccount.storedBic().isEmpty()) ? QVariant() : QVariant::fromValue(_beneficiaryAccount.storedBic())); query.bindValue(":textKey", _textKey); query.bindValue(":subTextKey", _subTextKey); } bool sepaOnlineTransferImpl::sqlSave(QSqlDatabase databaseConnection, const QString& onlineJobId) const { QSqlQuery query = QSqlQuery(databaseConnection); query.prepare("INSERT INTO kmmSepaOrders (" " id, originAccount, value, purpose, endToEndReference, beneficiaryName, beneficiaryIban, " " beneficiaryBic, textKey, subTextKey) " " VALUES( :id, :originAccount, :value, :purpose, :endToEndReference, :beneficiaryName, :beneficiaryIban, " " :beneficiaryBic, :textKey, :subTextKey ) " ); bindValuesToQuery(query, onlineJobId); if (!query.exec()) { qWarning("Error while saving sepa order '%s': %s", qPrintable(onlineJobId), qPrintable(query.lastError().text())); return false; } return true; } bool sepaOnlineTransferImpl::sqlModify(QSqlDatabase databaseConnection, const QString& onlineJobId) const { QSqlQuery query = QSqlQuery(databaseConnection); query.prepare( "UPDATE kmmSepaOrders SET" " originAccount = :originAccount," " value = :value," " purpose = :purpose," " endToEndReference = :endToEndReference," " beneficiaryName = :beneficiaryName," " beneficiaryIban = :beneficiaryIban," " beneficiaryBic = :beneficiaryBic," " textKey = :textKey," " subTextKey = :subTextKey " " WHERE id = :id"); bindValuesToQuery(query, onlineJobId); if (!query.exec()) { qWarning("Could not modify sepaOnlineTransfer '%s': %s", qPrintable(onlineJobId), qPrintable(query.lastError().text())); return false; } return true; } bool sepaOnlineTransferImpl::sqlRemove(QSqlDatabase databaseConnection, const QString& onlineJobId) const { QSqlQuery query = QSqlQuery(databaseConnection); query.prepare("DELETE FROM kmmSepaOrders WHERE id = ?"); query.bindValue(0, onlineJobId); return query.exec(); } bool sepaOnlineTransferImpl::hasReferenceTo(const QString& id) const { return (id == _originAccount); } QString sepaOnlineTransferImpl::jobTypeName() const { return QLatin1String("SEPA Credit Transfer"); } diff --git a/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.h b/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.h index 5f60b9d7e..f35214f78 100644 --- a/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.h +++ b/kmymoney/plugins/onlinetasks/sepa/tasks/sepaonlinetransferimpl.h @@ -1,121 +1,121 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SEPAONLINETRANSFERIMPL_H #define SEPAONLINETRANSFERIMPL_H #include "sepaonlinetransfer.h" #include "../sepastorageplugin.h" /** * @brief SEPA Credit Transfer */ class sepaOnlineTransferImpl : public sepaOnlineTransfer { Q_INTERFACES(sepaOnlineTransfer) public: ONLINETASK_META(sepaOnlineTransfer, "org.kmymoney.creditTransfer.sepa"); sepaOnlineTransferImpl(); sepaOnlineTransferImpl(const sepaOnlineTransferImpl &other); QString responsibleAccount() const { return _originAccount; } void setOriginAccount(const QString& accountId); MyMoneyMoney value() const { return _value; } virtual void setValue(MyMoneyMoney value) { _value = value; } virtual void setBeneficiary(const payeeIdentifiers::ibanBic& accountIdentifier) { _beneficiaryAccount = accountIdentifier; }; virtual payeeIdentifier beneficiary() const { return payeeIdentifier(_beneficiaryAccount.clone()); } virtual payeeIdentifiers::ibanBic beneficiaryTyped() const { return _beneficiaryAccount; } virtual void setPurpose(const QString purpose) { _purpose = purpose; } QString purpose() const { return _purpose; } virtual void setEndToEndReference(const QString& reference) { _endToEndReference = reference; } QString endToEndReference() const { return _endToEndReference; } payeeIdentifier originAccountIdentifier() const; MyMoneySecurity currency() const; bool isValid() const; QString jobTypeName() const; virtual QString storagePluginIid() const { return sepaStoragePlugin::iid; } virtual bool sqlSave(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual bool sqlModify(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual bool sqlRemove(QSqlDatabase databaseConnection, const QString& onlineJobId) const; unsigned short int textKey() const { return _textKey; } unsigned short int subTextKey() const { return _subTextKey; } virtual bool hasReferenceTo(const QString& id) const; QSharedPointer getSettings() const; protected: sepaOnlineTransfer* clone() const; virtual sepaOnlineTransfer* createFromXml(const QDomElement &element) const; virtual onlineTask* createFromSqlDatabase(QSqlDatabase connection, const QString& onlineJobId) const; virtual void writeXML(QDomDocument& document, QDomElement& parent) const; private: void bindValuesToQuery(QSqlQuery& query, const QString& id) const; mutable QSharedPointer _settings; QString _originAccount; MyMoneyMoney _value; QString _purpose; QString _endToEndReference; payeeIdentifiers::ibanBic _beneficiaryAccount; unsigned short int _textKey; unsigned short int _subTextKey; }; #endif // SEPAONLINETRANSFERIMPL_H diff --git a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp index c497a65ef..9d91da329 100644 --- a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp +++ b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp @@ -1,533 +1,533 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "sepacredittransferedit.h" #include "ui_sepacredittransferedit.h" #include #include #include #include #include #include "kguiutils.h" #include "mymoney/payeeidentifiermodel.h" #include "onlinetasks/sepa/tasks/sepaonlinetransfer.h" #include "payeeidentifier/ibanandbic/widgets/ibanvalidator.h" #include "payeeidentifier/ibanandbic/widgets/bicvalidator.h" #include "payeeidentifier/payeeidentifiertyped.h" #include "misc/charvalidator.h" #include "payeeidentifier/ibanandbic/ibanbic.h" #include "styleditemdelegateforwarder.h" #include "payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.h" class ibanBicCompleterDelegate : public StyledItemDelegateForwarder { Q_OBJECT public: ibanBicCompleterDelegate(QObject *parent) : StyledItemDelegateForwarder(parent) {} protected: virtual QAbstractItemDelegate* getItemDelegate(const QModelIndex &index) const { static QPointer defaultDelegate; static QPointer ibanBicDelegate; const bool ibanBicRequested = index.model()->data(index, payeeIdentifierModel::isPayeeIdentifier).toBool(); QAbstractItemDelegate* delegate = (ibanBicRequested) ? ibanBicDelegate : defaultDelegate; if (delegate == 0) { if (ibanBicRequested) { // Use this->parent() as parent because "this" is const ibanBicDelegate = new ibanBicItemDelegate(this->parent()); delegate = ibanBicDelegate; } else { // Use this->parent() as parent because "this" is const defaultDelegate = new QStyledItemDelegate(this->parent()); delegate = defaultDelegate; } connectSignals(delegate, Qt::UniqueConnection); } Q_CHECK_PTR(delegate); return delegate; } }; class payeeIdentifierCompleterPopup : public QTreeView { Q_OBJECT public: payeeIdentifierCompleterPopup(QWidget* parent = 0) : QTreeView(parent) { setRootIsDecorated(false); setAlternatingRowColors(true); setAnimated(true); setHeaderHidden(true); setUniformRowHeights(false); expandAll(); } }; class ibanBicFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT public: enum roles { payeeIban = payeeIdentifierModel::payeeIdentifierUserRole, /**< electornic IBAN of payee */ }; ibanBicFilterProxyModel(QObject* parent = 0) : QSortFilterProxyModel(parent) {} virtual QVariant data(const QModelIndex &index, int role) const { if (role == payeeIban) { if (!index.isValid()) return QVariant(); try { payeeIdentifierTyped iban = payeeIdentifierTyped( index.model()->data(index, payeeIdentifierModel::payeeIdentifier).value() ); return iban->electronicIban(); } catch (payeeIdentifier::exception&) { return QVariant(); } } return QSortFilterProxyModel::data(index, role); } virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { if (!source_parent.isValid()) return true; QModelIndex index = source_parent.model()->index(source_row, 0, source_parent); return (source_parent.model()->data(index, payeeIdentifierModel::payeeIdentifierType).toString() == payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()); } }; class ibanBicCompleter : public QCompleter { Q_OBJECT public: ibanBicCompleter(QObject* parent = 0); Q_SIGNALS: void activatedName(const QString& name) const; void highlightedName(const QString& name) const; void activatedBic(const QString& bic) const; void highlightedBic(const QString& bic) const; void activatedIban(const QString& iban) const; void highlightedIban(const QString& iban) const; private Q_SLOTS: void slotActivated(const QModelIndex& index) const; void slotHighlighted(const QModelIndex& index) const; }; ibanBicCompleter::ibanBicCompleter(QObject *parent) : QCompleter(parent) { connect(this, SIGNAL(activated(QModelIndex)), SLOT(slotActivated(QModelIndex))); connect(this, SIGNAL(highlighted(QModelIndex)), SLOT(slotHighlighted(QModelIndex))); } void ibanBicCompleter::slotActivated(const QModelIndex &index) const { if (!index.isValid()) return; emit activatedName(index.model()->data(index, payeeIdentifierModel::payeeName).toString()); try { payeeIdentifierTyped iban = payeeIdentifierTyped( index.model()->data(index, payeeIdentifierModel::payeeIdentifier).value() ); emit activatedIban(iban->electronicIban()); emit activatedBic(iban->storedBic()); } catch (payeeIdentifier::exception&) { } } void ibanBicCompleter::slotHighlighted(const QModelIndex &index) const { if (!index.isValid()) return; emit highlightedName(index.model()->data(index, payeeIdentifierModel::payeeName).toString()); try { payeeIdentifierTyped iban = payeeIdentifierTyped( index.model()->data(index, payeeIdentifierModel::payeeIdentifier).value() ); emit highlightedIban(iban->electronicIban()); emit highlightedBic(iban->storedBic()); } catch (payeeIdentifier::exception&) { } } sepaCreditTransferEdit::sepaCreditTransferEdit(QWidget *parent, QVariantList args) : IonlineJobEdit(parent, args), ui(new Ui::sepaCreditTransferEdit), m_onlineJob(onlineJobTyped()), m_requiredFields(new kMandatoryFieldGroup(this)), m_readOnly(false), m_showAllErrors(false) { ui->setupUi(this); m_requiredFields->add(ui->beneficiaryIban); m_requiredFields->add(ui->value); // Other required fields are set in updateSettings() connect(m_requiredFields, SIGNAL(stateChanged(bool)), this, SLOT(requiredFieldsCompleted(bool))); connect(ui->beneficiaryName, SIGNAL(textChanged(QString)), this, SLOT(beneficiaryNameChanged(QString))); connect(ui->beneficiaryIban, SIGNAL(textChanged(QString)), this, SLOT(beneficiaryIbanChanged(QString))); connect(ui->beneficiaryBankCode, SIGNAL(textChanged(QString)), this, SLOT(beneficiaryBicChanged(QString))); connect(ui->value, SIGNAL(valueChanged(QString)), this, SLOT(valueChanged())); connect(ui->sepaReference, SIGNAL(textChanged(QString)), this, SLOT(endToEndReferenceChanged(QString))); connect(ui->purpose, SIGNAL(textChanged()), this, SLOT(purposeChanged())); connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), this, SLOT(updateEveryStatus())); connect(ui->beneficiaryName, SIGNAL(textChanged(QString)), this, SIGNAL(onlineJobChanged())); connect(ui->beneficiaryIban, SIGNAL(textChanged(QString)), this, SIGNAL(onlineJobChanged())); connect(ui->beneficiaryBankCode, SIGNAL(textChanged(QString)), this, SIGNAL(onlineJobChanged())); connect(ui->value, SIGNAL(valueChanged(QString)), this, SIGNAL(onlineJobChanged())); connect(ui->sepaReference, SIGNAL(textChanged(QString)), this, SIGNAL(onlineJobChanged())); connect(ui->purpose, SIGNAL(textChanged()), this, SIGNAL(onlineJobChanged())); // Connect signals for read only connect(this, SIGNAL(readOnlyChanged(bool)), ui->beneficiaryName, SLOT(setReadOnly(bool))); connect(this, SIGNAL(readOnlyChanged(bool)), ui->beneficiaryIban, SLOT(setReadOnly(bool))); connect(this, SIGNAL(readOnlyChanged(bool)), ui->beneficiaryBankCode, SLOT(setReadOnly(bool))); connect(this, SIGNAL(readOnlyChanged(bool)), ui->value, SLOT(setReadOnly(bool))); connect(this, SIGNAL(readOnlyChanged(bool)), ui->sepaReference, SLOT(setReadOnly(bool))); connect(this, SIGNAL(readOnlyChanged(bool)), ui->purpose, SLOT(setReadOnly(bool))); // Create models for completers payeeIdentifierModel* identModel = new payeeIdentifierModel(this); identModel->setTypeFilter(payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()); ibanBicFilterProxyModel* filterModel = new ibanBicFilterProxyModel(this); filterModel->setSourceModel(identModel); KDescendantsProxyModel* descendantsModel = new KDescendantsProxyModel(this); descendantsModel->setSourceModel(filterModel); // Set completers popup and bind them to the corresponding fields { // Beneficiary name field ibanBicCompleter* completer = new ibanBicCompleter(this); completer->setModel(descendantsModel); completer->setCompletionRole(payeeIdentifierModel::payeeName); completer->setCaseSensitivity(Qt::CaseInsensitive); connect(completer, SIGNAL(activatedIban(QString)), ui->beneficiaryIban, SLOT(setText(QString))); connect(completer, SIGNAL(activatedBic(QString)), ui->beneficiaryBankCode, SLOT(setText(QString))); ui->beneficiaryName->setCompleter(completer); QAbstractItemView *itemView = new payeeIdentifierCompleterPopup(); completer->setPopup(itemView); // setPopup() resets the delegate itemView->setItemDelegate(new ibanBicCompleterDelegate(this)); } { // IBAN field ibanBicCompleter* ibanCompleter = new ibanBicCompleter(this); ibanCompleter->setModel(descendantsModel); ibanCompleter->setCompletionRole(ibanBicFilterProxyModel::payeeIban); ibanCompleter->setCaseSensitivity(Qt::CaseInsensitive); connect(ibanCompleter, SIGNAL(activatedName(QString)), ui->beneficiaryName, SLOT(setText(QString))); connect(ibanCompleter, SIGNAL(activatedBic(QString)), ui->beneficiaryBankCode, SLOT(setText(QString))); ui->beneficiaryIban->setCompleter(ibanCompleter); QAbstractItemView *itemView = new payeeIdentifierCompleterPopup(); ibanCompleter->setPopup(itemView); // setPopup() resets the delegate itemView->setItemDelegate(new ibanBicCompleterDelegate(this)); } } sepaCreditTransferEdit::~sepaCreditTransferEdit() { delete ui; } void sepaCreditTransferEdit::showEvent(QShowEvent* event) { updateEveryStatus(); QWidget::showEvent(event); } void sepaCreditTransferEdit::showAllErrorMessages(const bool state) { if (m_showAllErrors != state) { m_showAllErrors = state; updateEveryStatus(); } } onlineJobTyped sepaCreditTransferEdit::getOnlineJobTyped() const { onlineJobTyped sepaJob(m_onlineJob); sepaJob.task()->setValue(ui->value->value()); sepaJob.task()->setPurpose(ui->purpose->toPlainText()); sepaJob.task()->setEndToEndReference(ui->sepaReference->text()); payeeIdentifiers::ibanBic accIdent; accIdent.setOwnerName(ui->beneficiaryName->text()); accIdent.setIban(ui->beneficiaryIban->text()); accIdent.setBic(ui->beneficiaryBankCode->text()); sepaJob.task()->setBeneficiary(accIdent); return sepaJob; } void sepaCreditTransferEdit::setOnlineJob(const onlineJobTyped& job) { m_onlineJob = job; updateSettings(); setReadOnly(!job.isEditable()); ui->purpose->setText(job.task()->purpose()); ui->sepaReference->setText(job.task()->endToEndReference()); ui->value->setValue(job.task()->value()); ui->beneficiaryName->setText(job.task()->beneficiaryTyped().ownerName()); ui->beneficiaryIban->setText(job.task()->beneficiaryTyped().paperformatIban()); ui->beneficiaryBankCode->setText(job.task()->beneficiaryTyped().storedBic()); } bool sepaCreditTransferEdit::setOnlineJob(const onlineJob& job) { if (!job.isNull() && job.task()->taskName() == sepaOnlineTransfer::name()) { setOnlineJob(onlineJobTyped(job)); return true; } return false; } void sepaCreditTransferEdit::setOriginAccount(const QString& accountId) { m_onlineJob.task()->setOriginAccount(accountId); updateSettings(); } void sepaCreditTransferEdit::updateEveryStatus() { beneficiaryNameChanged(ui->beneficiaryName->text()); beneficiaryIbanChanged(ui->beneficiaryIban->text()); beneficiaryBicChanged(ui->beneficiaryBankCode->text()); purposeChanged(); valueChanged(); endToEndReferenceChanged(ui->sepaReference->text()); } void sepaCreditTransferEdit::setReadOnly(const bool& readOnly) { // Only set writeable if it changes something and if it is possible if (readOnly != m_readOnly && (readOnly == true || getOnlineJobTyped().isEditable())) { m_readOnly = readOnly; emit readOnlyChanged(m_readOnly); } } void sepaCreditTransferEdit::updateSettings() { QSharedPointer settings = taskSettings(); // Reference ui->sepaReference->setMaxLength(settings->endToEndReferenceLength()); if (settings->endToEndReferenceLength() == 0) ui->sepaReference->setEnabled(false); else ui->sepaReference->setEnabled(true); // Purpose ui->purpose->setAllowedChars(settings->allowedChars()); ui->purpose->setMaxLineLength(settings->purposeLineLength()); ui->purpose->setMaxLines(settings->purposeMaxLines()); if (settings->purposeMinLength()) m_requiredFields->add(ui->purpose); else m_requiredFields->remove(ui->purpose); // Beneficiary Name ui->beneficiaryName->setValidator(new charValidator(ui->beneficiaryName, settings->allowedChars())); ui->beneficiaryName->setMaxLength(settings->recipientNameLineLength()); if (settings->recipientNameMinLength() != 0) m_requiredFields->add(ui->beneficiaryName); else m_requiredFields->remove(ui->beneficiaryName); updateEveryStatus(); } void sepaCreditTransferEdit::beneficiaryIbanChanged(const QString& iban) { // Check IBAN QPair answer = ibanValidator::validateWithMessage(iban); if (m_showAllErrors || iban.length() > 5 || (!ui->beneficiaryIban->hasFocus() && !iban.isEmpty())) ui->feedbackIban->setFeedback(answer.first, answer.second); else ui->feedbackIban->removeFeedback(); // Check if BIC is mandatory QSharedPointer settings = taskSettings(); QString payeeIban; try { payeeIdentifier ident = getOnlineJobTyped().task()->originAccountIdentifier(); payeeIban = ident.data()->electronicIban(); } catch (payeeIdentifier::exception&) { } if (settings->isBicMandatory(payeeIban, iban)) { m_requiredFields->add(ui->beneficiaryBankCode); beneficiaryBicChanged(ui->beneficiaryBankCode->text()); } else { m_requiredFields->remove(ui->beneficiaryBankCode); beneficiaryBicChanged(ui->beneficiaryBankCode->text()); } } void sepaCreditTransferEdit::beneficiaryBicChanged(const QString& bic) { if (bic.isEmpty() && !ui->beneficiaryIban->text().isEmpty()) { QSharedPointer settings = taskSettings(); const payeeIdentifier payee = getOnlineJobTyped().task()->originAccountIdentifier(); QString iban; try { iban = payee.data()->electronicIban(); } catch (payeeIdentifier::badCast&) { } if (settings->isBicMandatory(iban , ui->beneficiaryIban->text())) { ui->feedbackBic->setFeedback(KMyMoneyValidationFeedback::Error, i18n("For this beneficiary's country the BIC is mandatory.")); return; } } QPair answer = bicValidator::validateWithMessage(bic); if (m_showAllErrors || bic.length() >= 8 || (!ui->beneficiaryBankCode->hasFocus() && !bic.isEmpty())) ui->feedbackBic->setFeedback(answer.first, answer.second); else ui->feedbackBic->removeFeedback(); } void sepaCreditTransferEdit::beneficiaryNameChanged(const QString& name) { QSharedPointer settings = taskSettings(); if (name.length() < settings->recipientNameMinLength() && (m_showAllErrors || (!ui->beneficiaryName->hasFocus() && !name.isEmpty()))) { ui->feedbackName->setFeedback(KMyMoneyValidationFeedback::Error, i18np("A beneficiary name is needed.", "The beneficiary name must be at least %1 characters long", settings->recipientNameMinLength() )); } else { ui->feedbackName->removeFeedback(); } } void sepaCreditTransferEdit::valueChanged() { if ((!ui->value->isValid() && (m_showAllErrors || (!ui->value->hasFocus() && ui->value->value().toDouble() != 0))) || (!ui->value->value().isPositive() && ui->value->value().toDouble() != 0)) { ui->feedbackAmount->setFeedback(KMyMoneyValidationFeedback::Error, i18n("A positive amount to transfer is needed.")); return; } if (!ui->value->isValid()) return; const MyMoneyAccount account = getOnlineJob().responsibleMyMoneyAccount(); const MyMoneyMoney expectedBalance = account.balance() - ui->value->value(); if (expectedBalance < MyMoneyMoney(account.value("maxCreditAbsolute"))) { ui->feedbackAmount->setFeedback(KMyMoneyValidationFeedback::Warning, i18n("After this credit transfer the account's balance will be below your credit limit.")); } else if (expectedBalance < MyMoneyMoney(account.value("minBalanceAbsolute"))) { ui->feedbackAmount->setFeedback(KMyMoneyValidationFeedback::Information, i18n("After this credit transfer the account's balance will be below the minimal balance.")); } else { ui->feedbackAmount->removeFeedback(); } } void sepaCreditTransferEdit::endToEndReferenceChanged(const QString& reference) { QSharedPointer settings = taskSettings(); if (settings->checkEndToEndReferenceLength(reference) == validators::tooLong) { ui->feedbackReference->setFeedback(KMyMoneyValidationFeedback::Error, i18np("The end-to-end reference cannot contain more than one character.", "The end-to-end reference cannot contain more than %1 characters.", settings->endToEndReferenceLength() )); } else { ui->feedbackReference->removeFeedback(); } } void sepaCreditTransferEdit::purposeChanged() { const QString purpose = ui->purpose->toPlainText(); QSharedPointer settings = taskSettings(); QString message; if (!settings->checkPurposeLineLength(purpose)) message = i18np("The maximal line length of %1 character per line is exceeded.", "The maximal line length of %1 characters per line is exceeded.", settings->purposeLineLength()) .append('\n'); if (!settings->checkPurposeCharset(purpose)) message.append(i18n("The purpose can only contain the letters A-Z, spaces and ':?.,-()+ and /")).append('\n'); if (!settings->checkPurposeMaxLines(purpose)) { message.append(i18np("In the purpose only a single line is allowed.", "The purpose cannot contain more than %1 lines.", settings->purposeMaxLines())) .append('\n'); } else if (settings->checkPurposeLength(purpose) == validators::tooShort) { message.append(i18np("A purpose is needed.", "The purpose must be at least %1 characters long.", settings->purposeMinLength())) .append('\n'); } // Remove the last '\n' message.chop(1); if (!message.isEmpty()) { ui->feedbackPurpose->setFeedback(KMyMoneyValidationFeedback::Error, message); } else { ui->feedbackPurpose->removeFeedback(); } } QSharedPointer< const sepaOnlineTransfer::settings > sepaCreditTransferEdit::taskSettings() { return getOnlineJobTyped().constTask()->getSettings(); } #include "sepacredittransferedit.moc" diff --git a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h index f1474779c..8956e834c 100644 --- a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h +++ b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h @@ -1,126 +1,126 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef SEPACREDITTRANSFEREDIT_H #define SEPACREDITTRANSFEREDIT_H #include #include "mymoney/onlinejobtyped.h" #include "onlinetasks/sepa/tasks/sepaonlinetransfer.h" #include "onlinetasks/interfaces/ui/ionlinejobedit.h" class kMandatoryFieldGroup; namespace Ui { class sepaCreditTransferEdit; } /** * @brief Widget to edit sepaOnlineTransfer */ class sepaCreditTransferEdit : public IonlineJobEdit { Q_OBJECT Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged); Q_PROPERTY(onlineJob job READ getOnlineJob WRITE setOnlineJob); Q_INTERFACES(IonlineJobEdit); public: explicit sepaCreditTransferEdit(QWidget *parent = 0, QVariantList args = QVariantList()); ~sepaCreditTransferEdit(); onlineJobTyped getOnlineJobTyped() const; onlineJob getOnlineJob() const { return getOnlineJobTyped(); } QStringList supportedOnlineTasks() const { return QStringList(sepaOnlineTransfer::name()); } QString label() const { return i18n("SEPA Credit Transfer"); }; bool isValid() const { return getOnlineJobTyped().isValid(); }; bool isReadOnly() const { return m_readOnly; } virtual void showAllErrorMessages(const bool); virtual void showEvent(QShowEvent*); signals: void onlineJobChanged(); void readOnlyChanged(bool); public slots: void setOnlineJob(const onlineJobTyped &job); bool setOnlineJob(const onlineJob& job); void setOriginAccount(const QString& accountId); void setReadOnly(const bool&); private slots: void updateSettings(); void updateEveryStatus(); /** @{ * These slots are called when the corosponding field is changed * to start the validation. */ void purposeChanged(); void beneficiaryIbanChanged(const QString& iban); void beneficiaryBicChanged(const QString& bic); void beneficiaryNameChanged(const QString& name); void valueChanged(); void endToEndReferenceChanged(const QString& reference); /** @} */ /** * @brief Convenient slot to emit validityChanged() * * A default implementation to emit validityChanged() based on getOnlineJob().isValid(). * This is useful if you use @a kMandatoryFieldsGroup in your widget. Just connect kMandatoryFieldsGroup::stateChanged(bool) * to this slot. * * @param status if false, validityChanged(false) is emitted without further checks. */ void requiredFieldsCompleted(const bool& status = true) { if (status) { emit validityChanged(getOnlineJobTyped().isValid()); } else { emit validityChanged(false); } } private: Ui::sepaCreditTransferEdit *ui; onlineJobTyped m_onlineJob; kMandatoryFieldGroup* m_requiredFields; bool m_readOnly; bool m_showAllErrors; QSharedPointer taskSettings(); }; #endif // SEPACREDITTRANSFEREDIT_H diff --git a/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.cpp b/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.cpp index 7815f9723..84b1056b9 100644 --- a/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.cpp +++ b/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.cpp @@ -1,98 +1,98 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "unavailabletask.h" #include unavailableTask::unavailableTask(const QDomElement& element) : m_data(element) { } QString unavailableTask::jobTypeName() const { return i18n("Could not load responsible plugin to view this task."); } QString unavailableTask::storagePluginIid() const { return QString(); } bool unavailableTask::sqlSave(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection); Q_UNUSED(onlineJobId); Q_ASSERT(false); return false; } bool unavailableTask::sqlModify(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection); Q_UNUSED(onlineJobId); Q_ASSERT(false); return false; } bool unavailableTask::sqlRemove(QSqlDatabase databaseConnection, const QString& onlineJobId) const { Q_UNUSED(databaseConnection); Q_UNUSED(onlineJobId); Q_ASSERT(false); return false; } onlineTask* unavailableTask::createFromSqlDatabase(QSqlDatabase connection, const QString& onlineJobId) const { Q_UNUSED(connection); Q_UNUSED(onlineJobId); return 0; } QString unavailableTask::responsibleAccount() const { return QString(); } unavailableTask* unavailableTask::createFromXml(const QDomElement& element) const { return new unavailableTask(element); } void unavailableTask::writeXML(QDomDocument& document, QDomElement& parent) const { Q_UNUSED(document); parent = m_data; } bool unavailableTask::hasReferenceTo(const QString& id) const { Q_UNUSED(id); return false; } unavailableTask* unavailableTask::clone() const { return new unavailableTask(m_data); } bool unavailableTask::isValid() const { return true; } diff --git a/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.h b/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.h index 38693f1a3..d75f1ef4e 100644 --- a/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.h +++ b/kmymoney/plugins/onlinetasks/unavailabletask/tasks/unavailabletask.h @@ -1,68 +1,68 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef UNAVAILABLETASK_H #define UNAVAILABLETASK_H #include "onlinetasks/interfaces/tasks/onlinetask.h" /** * @brief Task which can be used if original task is unavailable * * This task simply stores the XML data given to it and can write it back. * * The XML storage backend needs to load all tasks into memory. To prevent * data corruption if the original task cannot be loaded, this task can be used. */ class unavailableTask : public onlineTask { public: ONLINETASK_META(unavailableTask, "org.kmymoney.onlineTask.unavailableTask"); virtual bool isValid() const; virtual QString jobTypeName() const; /** * @name SqlMethods * @{ * For sql databases this plugin is not needed nor used. So these functions * do not have a real implementation. */ virtual QString storagePluginIid() const; virtual bool sqlSave(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual bool sqlModify(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual bool sqlRemove(QSqlDatabase databaseConnection, const QString& onlineJobId) const; virtual onlineTask* createFromSqlDatabase(QSqlDatabase connection, const QString& onlineJobId) const; /** @} */ protected: virtual QString responsibleAccount() const; virtual unavailableTask* createFromXml(const QDomElement& element) const; virtual void writeXML(QDomDocument& document, QDomElement& parent) const; virtual bool hasReferenceTo(const QString& id) const; virtual unavailableTask* clone() const; private: explicit unavailableTask(const QDomElement& element); /** * The data received by createFromXml(). Written back by writeXML(). */ QDomElement m_data; }; #endif // UNAVAILABLETASK_H diff --git a/kmymoney/plugins/weboob/dialogs/mapaccount.cpp b/kmymoney/plugins/weboob/dialogs/mapaccount.cpp index 573a66360..1d959a127 100644 --- a/kmymoney/plugins/weboob/dialogs/mapaccount.cpp +++ b/kmymoney/plugins/weboob/dialogs/mapaccount.cpp @@ -1,155 +1,155 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "mapaccount.h" #include "../weboob.h" struct WbMapAccountDialog::Private { QFutureWatcher > watcher; QFutureWatcher > watcher2; std::unique_ptr progress; }; WbMapAccountDialog::WbMapAccountDialog(QWidget *parent): QWizard(parent), d(new Private), d2(new Private) { setupUi(this); checkNextButton(); connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(checkNextButton())); connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(newPage(int))); connect(backendsList, SIGNAL(itemSelectionChanged()), this, SLOT(checkNextButton())); connect(accountsList, SIGNAL(itemSelectionChanged()), this, SLOT(checkNextButton())); connect(&d->watcher, SIGNAL(finished()), this, SLOT(gotAccounts())); connect(&d2->watcher2, SIGNAL(finished()), this, SLOT(gotBackends())); // setup icons button(QWizard::FinishButton)->setIcon(KStandardGuiItem::ok().icon()); button(QWizard::CancelButton)->setIcon(KStandardGuiItem::cancel().icon()); button(QWizard::NextButton)->setIcon(KStandardGuiItem::forward(KStandardGuiItem::UseRTL).icon()); button(QWizard::BackButton)->setIcon(KStandardGuiItem::back(KStandardGuiItem::UseRTL).icon()); } /** * @internal Deconstructer stub needed to delete unique_ptrs with type Private */ WbMapAccountDialog::~WbMapAccountDialog() { } void WbMapAccountDialog::checkNextButton(void) { bool enableButton = false; switch (currentId()) { case BACKENDS_PAGE: enableButton = backendsList->currentItem() != 0 && backendsList->currentItem()->isSelected(); break; case ACCOUNTS_PAGE: enableButton = accountsList->currentItem() != 0 && accountsList->currentItem()->isSelected(); break; } button(QWizard::NextButton)->setEnabled(enableButton); } void WbMapAccountDialog::newPage(int id) { //! @Todo C++14: this should be make_unique d2->progress = std::unique_ptr(new QProgressDialog(this)); d2->progress->setModal(true); d2->progress->setCancelButton(nullptr); d2->progress->setMinimum(0); d2->progress->setMaximum(0); d2->progress->setMinimumDuration(0); switch (id) { case BACKENDS_PAGE: { backendsList->clear(); d2->progress->setWindowTitle(i18n("Loading Weboob backend...")); d2->progress->setLabelText(i18n("Getting list of backends.")); QCoreApplication::processEvents(); QFuture > future = QtConcurrent::run(weboob, &Weboob::getBackends); d2->watcher2.setFuture(future); break; } case ACCOUNTS_PAGE: { accountsList->clear(); d2->progress->setWindowTitle(i18n("Connecting to bank...")); d2->progress->setLabelText(i18n("Getting list of accounts from your bank.")); QCoreApplication::processEvents(); QFuture > future = QtConcurrent::run(weboob, &Weboob::getAccounts, backendsList->currentItem()->text(0)); d->watcher.setFuture(future); button(QWizard::BackButton)->setEnabled(false); accountsList->setEnabled(false); break; } default: // I do not know if this can actually happen. But to be safe: d2->progress.reset(); } } void WbMapAccountDialog::gotBackends() { QList backends = d2->watcher2.result(); for (QListIterator it(backends); it.hasNext();) { Weboob::Backend backend = it.next(); QStringList headers; headers << backend.name << backend.module; backendsList->addTopLevelItem(new QTreeWidgetItem(headers)); } d2->progress.reset(); } void WbMapAccountDialog::gotAccounts() { QList accounts = d->watcher.result(); for (QListIterator it(accounts); it.hasNext();) { Weboob::Account account = it.next(); QStringList headers; headers << account.id << account.name << account.balance.formatMoney(QString(), 2); accountsList->addTopLevelItem(new QTreeWidgetItem(headers)); } d->progress.reset(); button(QWizard::BackButton)->setEnabled(true); accountsList->setEnabled(true); } diff --git a/kmymoney/plugins/weboob/dialogs/mapaccount.h b/kmymoney/plugins/weboob/dialogs/mapaccount.h index f95b70fab..d65c85ec7 100644 --- a/kmymoney/plugins/weboob/dialogs/mapaccount.h +++ b/kmymoney/plugins/weboob/dialogs/mapaccount.h @@ -1,64 +1,64 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WEBOOB_MAPACCOUNT_HPP #define WEBOOB_MAPACCOUNT_HPP #include #include #include "../weboob.h" #include "ui_mapaccount.h" class WbMapAccountDialog : public QWizard, public Ui::WbMapAccountDialog { Q_OBJECT public: Weboob *weboob; WbMapAccountDialog(QWidget *parent = 0); virtual ~WbMapAccountDialog(); protected slots: void checkNextButton(void); void newPage(int id); void gotAccounts(); void gotBackends(); protected: bool finishAccountPage(void); bool finishLoginPage(void); bool finishFiPage(void); private: enum { BACKENDS_PAGE = 0, ACCOUNTS_PAGE }; struct Private; /// \internal d-pointer instance. const std::unique_ptr d; const std::unique_ptr d2; }; #endif /* WEBOOB_MAPACCOUNT_HPP */ diff --git a/kmymoney/plugins/weboob/dialogs/webaccount.cpp b/kmymoney/plugins/weboob/dialogs/webaccount.cpp index 30864a401..deb8377d4 100644 --- a/kmymoney/plugins/weboob/dialogs/webaccount.cpp +++ b/kmymoney/plugins/weboob/dialogs/webaccount.cpp @@ -1,58 +1,58 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include "mymoneykeyvaluecontainer.h" #include struct WebAccountSettings::Private { Ui::WebAccountSettings ui; }; WebAccountSettings::WebAccountSettings(const MyMoneyAccount& /*acc*/, QWidget* parent) : QWidget(parent), d(new Private) { d->ui.setupUi(this); } WebAccountSettings::~WebAccountSettings() { delete d; } void WebAccountSettings::loadUi(const MyMoneyKeyValueContainer& kvp) { d->ui.id->setText(kvp.value("wb-id")); d->ui.backend->setText(kvp.value("wb-backend")); d->ui.max_history->setText(kvp.value("wb-max")); } void WebAccountSettings::loadKvp(MyMoneyKeyValueContainer& kvp) { kvp.setValue("wb-id", d->ui.id->text()); kvp.setValue("wb-backend", d->ui.backend->text()); kvp.setValue("wb-max", d->ui.max_history->text()); } diff --git a/kmymoney/plugins/weboob/dialogs/webaccount.h b/kmymoney/plugins/weboob/dialogs/webaccount.h index 840d749b0..f19319948 100644 --- a/kmymoney/plugins/weboob/dialogs/webaccount.h +++ b/kmymoney/plugins/weboob/dialogs/webaccount.h @@ -1,45 +1,45 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WEBOOB_WEBACCOUNTSETTINGS_H #define WEBOOB_WEBACCOUNTSETTINGS_H #include class MyMoneyAccount; class MyMoneyKeyValueContainer; class WebAccountSettings: public QWidget { public: WebAccountSettings(const MyMoneyAccount& acc, QWidget* parent); ~WebAccountSettings(); void loadUi(const MyMoneyKeyValueContainer& kvp); void loadKvp(MyMoneyKeyValueContainer& kvp); private: /// \internal d-pointer class. struct Private; /// \internal d-pointer instance. Private* const d; }; #endif /* WEBOOB_WEBACCOUNTSETTINGS_H */ diff --git a/kmymoney/plugins/weboob/plugin.cpp b/kmymoney/plugins/weboob/plugin.cpp index c7388a137..9c7d9851d 100644 --- a/kmymoney/plugins/weboob/plugin.cpp +++ b/kmymoney/plugins/weboob/plugin.cpp @@ -1,172 +1,172 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * Copyright (C) 2016 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include "dialogs/mapaccount.h" #include "dialogs/webaccount.h" #include "plugin.h" #include "weboob.h" struct WeboobPlugin::Private { QFutureWatcher watcher; std::unique_ptr progress; WebAccountSettings* accountSettings; }; WeboobPlugin::WeboobPlugin() : KMyMoneyPlugin::Plugin(), KMyMoneyPlugin::OnlinePlugin(), d(new Private()) { setComponentName("kmm_weboob", i18n("Weboob")); setXMLFile("kmm_weboob.rc"); connect(&d->watcher, &QFutureWatcher::finished, this, &WeboobPlugin::gotAccount); } WeboobPlugin::~WeboobPlugin() { } void WeboobPlugin::protocols(QStringList& protocolList) const { protocolList << "weboob"; } QWidget* WeboobPlugin::accountConfigTab(const MyMoneyAccount& account, QString& tabName) { const MyMoneyKeyValueContainer& kvp = account.onlineBankingSettings(); tabName = i18n("Weboob configuration"); d->accountSettings = new WebAccountSettings(account, 0); d->accountSettings->loadUi(kvp); return d->accountSettings; } MyMoneyKeyValueContainer WeboobPlugin::onlineBankingSettings(const MyMoneyKeyValueContainer& current) { MyMoneyKeyValueContainer kvp(current); kvp["provider"] = objectName(); if (d->accountSettings) { d->accountSettings->loadKvp(kvp); } return kvp; } bool WeboobPlugin::mapAccount(const MyMoneyAccount& acc, MyMoneyKeyValueContainer& onlineBankingSettings) { Q_UNUSED(acc); WbMapAccountDialog w; w.weboob = &weboob; if (w.exec() == QDialog::Accepted) { onlineBankingSettings.setValue("wb-backend", w.backendsList->currentItem()->text(0)); onlineBankingSettings.setValue("wb-id", w.accountsList->currentItem()->text(0)); onlineBankingSettings.setValue("wb-max", "0"); return true; } return false; } bool WeboobPlugin::updateAccount(const MyMoneyAccount& kacc, bool moreAccounts) { Q_UNUSED(moreAccounts); QString bname = kacc.onlineBankingSettings().value("wb-backend"); QString id = kacc.onlineBankingSettings().value("wb-id"); QString max = kacc.onlineBankingSettings().value("wb-max"); //! @todo C++14 use make_unique() d->progress = std::unique_ptr(new QProgressDialog()); d->progress->setWindowTitle(i18n("Connecting to bank...")); d->progress->setLabelText(i18n("Retrieving transactions...")); d->progress->setModal(true); d->progress->setCancelButton(nullptr); d->progress->setMinimum(0); d->progress->setMaximum(0); d->progress->setMinimumDuration(0); QFuture future = QtConcurrent::run(&weboob, &Weboob::getAccount, bname, id, max); d->watcher.setFuture(future); d->progress->exec(); d->progress.reset(); return true; } void WeboobPlugin::gotAccount() { Weboob::Account acc = d->watcher.result(); MyMoneyAccount kacc = statementInterface()->account("wb-id", acc.id); MyMoneyStatement ks; ks.m_accountId = kacc.id(); ks.m_strAccountName = acc.name; ks.m_closingBalance = acc.balance; if (acc.transactions.length() > 0) ks.m_dateEnd = acc.transactions.front().date; #if 0 switch (acc.type) { case Weboob::Account::TYPE_CHECKING: ks.m_eType = MyMoneyStatement::etCheckings; break; case Weboob::Account::TYPE_SAVINGS: ks.m_eType = MyMoneyStatement::etSavings; break; case Weboob::Account::TYPE_MARKET: ks.m_eType = MyMoneyStatement::etInvestment; break; case Weboob::Account::TYPE_DEPOSIT: case Weboob::Account::TYPE_LOAN: case Weboob::Account::TYPE_JOINT: case Weboob::Account::TYPE_UNKNOWN: break; } #endif for (QListIterator it(acc.transactions); it.hasNext();) { Weboob::Transaction tr = it.next(); MyMoneyStatement::Transaction kt; kt.m_strBankID = QLatin1String("ID ") + tr.id; kt.m_datePosted = tr.rdate; kt.m_amount = tr.amount; kt.m_strMemo = tr.raw; kt.m_strPayee = tr.label; ks.m_listTransactions += kt; } statementInterface()->import(ks); d->progress->hide(); } diff --git a/kmymoney/plugins/weboob/plugin.h b/kmymoney/plugins/weboob/plugin.h index 65a358b33..b54d3c8fa 100644 --- a/kmymoney/plugins/weboob/plugin.h +++ b/kmymoney/plugins/weboob/plugin.h @@ -1,66 +1,66 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WEBOOB_PLUGIN_HPP #define WEBOOB_PLUGIN_HPP #include #ifdef HAVE_CONFIG_H #include #endif #include "kmymoneyplugin.h" #include "mymoneyaccount.h" #include "mymoneykeyvaluecontainer.h" #include "weboob.h" class WeboobPlugin : public KMyMoneyPlugin::Plugin, public KMyMoneyPlugin::OnlinePlugin { Q_OBJECT Q_INTERFACES(KMyMoneyPlugin::OnlinePlugin) Q_PLUGIN_METADATA(IID "org.kmymoney.plugins.weboob" FILE "kmm_weboob.json") public: Weboob weboob; WeboobPlugin(); virtual ~WeboobPlugin(); void protocols(QStringList& protocolList) const; QWidget* accountConfigTab(const MyMoneyAccount& account, QString& tabName); MyMoneyKeyValueContainer onlineBankingSettings(const MyMoneyKeyValueContainer& current); bool mapAccount(const MyMoneyAccount& acc, MyMoneyKeyValueContainer& onlineBankingSettings); bool updateAccount(const MyMoneyAccount& acc, bool moreAccounts = false); protected slots: void gotAccount(); private: struct Private; /// \internal d-pointer instance. const std::unique_ptr d; }; #endif /* WEBOOB_PLUGIN_HPP */ diff --git a/kmymoney/plugins/weboob/weboob.cpp b/kmymoney/plugins/weboob/weboob.cpp index ac6f5d9ff..8ba9f32e9 100644 --- a/kmymoney/plugins/weboob/weboob.cpp +++ b/kmymoney/plugins/weboob/weboob.cpp @@ -1,136 +1,136 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "weboob.h" Weboob::Weboob(QObject* parent) : QObject(parent) { mutex = new QMutex(); path = QStandardPaths::locate(QStandardPaths::GenericDataLocation, "kmm_weboob/weboob.py"); action = new Kross::Action(0, path); action->setFile(path); } Weboob::~Weboob() { delete mutex; action->finalize(); delete action; } QVariant Weboob::execute(QString method, QVariantList args) { QVariant result; mutex->lock(); result = action->callFunction(method, args); mutex->unlock(); return result; } QList Weboob::getBackends() { QList backendsList; QVariantList args; QVariant result = this->execute("get_backends", args); QMap list = result.toMap(); QMapIterator it(list); while (it.hasNext()) { it.next(); QMap params = it.value().toMap(); Weboob::Backend backend; backend.name = it.key(); backend.module = params["module"].toString(); backendsList.append(backend); } return backendsList; } QList Weboob::getAccounts(QString backend) { QList accountsList; QVariantList args; args << backend; QVariant result = this->execute("get_accounts", args); QMap list = result.toMap(); for (QMapIterator it(list); it.hasNext();) { it.next(); QMap params = it.value().toMap(); Weboob::Account account; account.id = it.key(); account.name = params["name"].toString(); account.balance = MyMoneyMoney(params["balance"].toInt(), 100); account.type = (Weboob::Account::type_t)params["type"].toInt(); accountsList.append(account); } return accountsList; } Weboob::Account Weboob::getAccount(QString backend, QString accid, QString max) { Weboob::Account acc; QVariantList args; args << backend; args << accid; args << max; QMap result = this->execute("get_transactions", args).toMap(); acc.id = result["id"].toString(); acc.name = result["name"].toString(); acc.balance = MyMoneyMoney(result["balance"].toInt(), 100); acc.type = (Weboob::Account::type_t)result["type"].toInt(); QList list = result["transactions"].toList(); for (QListIterator it(list); it.hasNext();) { QMap params = it.next().toMap(); Weboob::Transaction tr; tr.id = params["id"].toString(); tr.date = QDate::fromString(params["date"].toString(), "yyyy-MM-dd"); tr.rdate = QDate::fromString(params["rdate"].toString(), "yyyy-MM-dd"); tr.type = (Weboob::Transaction::type_t)params["type"].toInt(); tr.raw = params["raw"].toString(); tr.category = params["category"].toString(); tr.label = params["label"].toString(); tr.amount = MyMoneyMoney(params["amount"].toInt(), 100); acc.transactions.append(tr); } return acc; } diff --git a/kmymoney/plugins/weboob/weboob.h b/kmymoney/plugins/weboob/weboob.h index f768253f2..96081dd2d 100644 --- a/kmymoney/plugins/weboob/weboob.h +++ b/kmymoney/plugins/weboob/weboob.h @@ -1,100 +1,100 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014-2015 Romain Bignon * Copyright (C) 2014-2015 Florent Fourcot * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef WEBOOB_HPP #define WEBOOB_HPP #include #include #include #include #include "mymoneymoney.h" class Weboob : public QObject { Q_OBJECT Kross::Action* action; QMutex *mutex; QString path; public: struct Backend { QString name; QString module; }; struct Transaction { QString id; QDate date; QDate rdate; enum type_t { TYPE_UNKNOWN = 0, TYPE_TRANSFER, TYPE_ORDER, TYPE_CHECK, TYPE_DEPOSIT, TYPE_PAYBACK, TYPE_WITHDRAWAL, TYPE_CARD, TYPE_LOAN_PAYMENT, TYPE_BANK } type; QString raw; QString category; QString label; MyMoneyMoney amount; }; struct Account { QString id; QString name; enum type_t { TYPE_UNKNOWN = 0, TYPE_CHECKING, TYPE_SAVINGS, TYPE_DEPOSIT, TYPE_LOAN, TYPE_MARKET, TYPE_JOINT } type; MyMoneyMoney balance; QList transactions; }; Weboob(QObject* parent = 0); ~Weboob(); QStringList getProtocols(); QList getBackends(); QList getAccounts(QString backend); Account getAccount(QString backend, QString account, QString max); QVariant execute(QString method, QVariantList args); }; #endif /* WEBOOB_HPP */ diff --git a/kmymoney/plugins/weboob/weboob.py b/kmymoney/plugins/weboob/weboob.py index 24ba93e82..7283fb619 100644 --- a/kmymoney/plugins/weboob/weboob.py +++ b/kmymoney/plugins/weboob/weboob.py @@ -1,101 +1,101 @@ # -# This file is part of KMyMoney, A Personal Finance Manager for KDE +# This file is part of KMyMoney, A Personal Finance Manager by KDE # Copyright (C) 2014-2015 Romain Bignon # Copyright (C) 2014-2015 Florent Fourcot # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from weboob.core import Weboob from weboob.capabilities.bank import CapBank def get_protocols(): w = Weboob() return w.repositories.get_all_modules_info(CapBank).keys() def get_backends(): w = Weboob() result = {} for instance_name, name, params in sorted(w.backends_config.iter_backends()): module = w.modules_loader.get_or_load_module(name) if not module.has_caps(CapBank): continue result[instance_name] = {'module': name} return result def get_accounts(bname): w = Weboob() w.load_backends(names=[bname]) backend = w.get_backend(bname) results = {} for account in backend.iter_accounts(): # a unicode bigger than 8 characters used as key of the table make some bugs in the C++ code # convert to string before to use it results[str(account.id)] = {'name': account.label, 'balance': int(account.balance * 100), 'type': int(account.type), } return results def get_transactions(bname, accid, maximum): w = Weboob() w.load_backends(names=[bname]) backend = w.get_backend(bname) acc = backend.get_account(accid) results = {} results['id'] = acc.id results['name'] = acc.label results['balance'] = int(acc.balance * 100) results['type'] = int(acc.type) results['transactions'] = [] try: count = int(maximum) if count < 1: count = 0 except: count = 0 i = 0 first = True rewriteid = False seen = set() for tr in backend.iter_history(acc): if first: if tr.id == u'0' or tr.id == u'': rewriteid = True first = False if rewriteid: tr.id = tr.unique_id(seen) t = {'id': tr.id, 'date': tr.date.strftime('%Y-%m-%d'), 'rdate': tr.rdate.strftime('%Y-%m-%d'), 'type': int(tr.type), 'raw': tr.raw, 'category': tr.category, 'label': tr.label, 'amount': int(tr.amount * 100), } results['transactions'].append(t) i += 1 if count != 0 and i >= count: break return results diff --git a/kmymoney/tests/kmymoneyutils-test.cpp b/kmymoney/tests/kmymoneyutils-test.cpp index be4b1eefe..558d6fe60 100644 --- a/kmymoney/tests/kmymoneyutils-test.cpp +++ b/kmymoney/tests/kmymoneyutils-test.cpp @@ -1,70 +1,70 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2012 Thomas Baumgart * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kmymoneyutils-test.h" #include QTEST_GUILESS_MAIN(KMyMoneyUtilsTest) void KMyMoneyUtilsTest::init() { } void KMyMoneyUtilsTest::cleanup() { } void KMyMoneyUtilsTest::initTestCase() { } void KMyMoneyUtilsTest::testNextCheckNumber() { MyMoneyAccount acc; // make sure first check number is 1 acc.setValue("lastNumberUsed", QString()); QVERIFY(KMyMoneyUtils::nextCheckNumber(acc) == QLatin1String("1")); // a simple increment of a plain value acc.setValue("lastNumberUsed", QLatin1String("123")); QVERIFY(KMyMoneyUtils::nextCheckNumber(acc) == QLatin1String("124")); // a number preceded by text acc.setValue("lastNumberUsed", QLatin1String("No 123")); QVERIFY(KMyMoneyUtils::nextCheckNumber(acc) == QLatin1String("No 124")); // a number followed by text acc.setValue("lastNumberUsed", QLatin1String("123 ABC")); QVERIFY(KMyMoneyUtils::nextCheckNumber(acc) == QLatin1String("124 ABC")); // a number enclosed by text acc.setValue("lastNumberUsed", QLatin1String("No 123 ABC")); QVERIFY(KMyMoneyUtils::nextCheckNumber(acc) == QLatin1String("No 124 ABC")); // a number containig a dash (e.g. invoice number) acc.setValue("lastNumberUsed", QLatin1String("No 123-001 ABC")); QVERIFY(KMyMoneyUtils::nextCheckNumber(acc) == QLatin1String("No 123-002 ABC")); // a number containing a dot (e.g. invoice number) acc.setValue("lastNumberUsed", QLatin1String("2012.001")); QVERIFY(KMyMoneyUtils::nextCheckNumber(acc) == QLatin1String("2012.002")); } diff --git a/kmymoney/tests/kmymoneyutils-test.h b/kmymoney/tests/kmymoneyutils-test.h index 3faac41a7..860baffc1 100644 --- a/kmymoney/tests/kmymoneyutils-test.h +++ b/kmymoney/tests/kmymoneyutils-test.h @@ -1,42 +1,42 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2012 Thomas Baumgart * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KMYMONEYUTILSTEST_H #define KMYMONEYUTILSTEST_H #include #include #define KMM_MYMONEY_UNIT_TESTABLE friend class KMyMoneyUtilsTest; #include "kmymoneyutils.h" class KMyMoneyUtilsTest : public QObject { Q_OBJECT protected: private slots: void initTestCase(); void init(); void cleanup(); void testNextCheckNumber(); }; #endif diff --git a/kmymoney/views/konlinejoboutbox.cpp b/kmymoney/views/konlinejoboutbox.cpp index 63b0af38b..f44c2365b 100644 --- a/kmymoney/views/konlinejoboutbox.cpp +++ b/kmymoney/views/konlinejoboutbox.cpp @@ -1,252 +1,252 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013-2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "konlinejoboutbox.h" #include "ui_konlinejoboutbox.h" #include #include #include #include #include #include #include #include #include "models/models.h" #include "models/onlinejobmodel.h" #include "mymoney/mymoneyfile.h" #include "kmymoney.h" #include KOnlineJobOutbox::KOnlineJobOutbox(QWidget *parent) : QWidget(parent), ui(new Ui::KOnlineJobOutbox), m_needLoad(true) { } KOnlineJobOutbox::~KOnlineJobOutbox() { if (!m_needLoad) { // Save column state KConfigGroup configGroup = KSharedConfig::openConfig()->group("KOnlineJobOutbox"); configGroup.writeEntry("HeaderState", ui->m_onlineJobView->header()->saveState()); } } void KOnlineJobOutbox::setDefaultFocus() { QTimer::singleShot(0, ui->m_onlineJobView, SLOT(setFocus())); } void KOnlineJobOutbox::init() { m_needLoad = false; ui->setupUi(this); // Restore column state KConfigGroup configGroup = KSharedConfig::openConfig()->group("KOnlineJobOutbox"); QByteArray columns; columns = configGroup.readEntry("HeaderState", columns); ui->m_onlineJobView->header()->restoreState(columns); ui->m_onlineJobView->setModel(Models::instance()->onlineJobsModel()); connect(ui->m_buttonSend, SIGNAL(clicked()), this, SLOT(slotSendJobs())); connect(ui->m_buttonRemove, SIGNAL(clicked()), this, SLOT(slotRemoveJob())); connect(ui->m_buttonEdit, SIGNAL(clicked()), this, SLOT(slotEditJob())); connect(ui->m_onlineJobView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotEditJob(QModelIndex))); connect(ui->m_onlineJobView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(updateButtonState())); // Set new credit transfer button connect(kmymoney->actionCollection()->action(kmymoney->s_Actions[Action::AccountCreditTransfer]), SIGNAL(changed()), SLOT(updateNewCreditTransferButton())); connect(ui->m_buttonNewCreditTransfer, SIGNAL(clicked()), this, SIGNAL(newCreditTransfer())); updateNewCreditTransferButton(); } void KOnlineJobOutbox::updateButtonState() const { const QModelIndexList indexes = ui->m_onlineJobView->selectionModel()->selectedRows(); const int selectedItems = indexes.count(); // Send button //! @todo Enable button if it is useful //ui->m_buttonSend->setEnabled(selectedItems > 0); // Edit button/action bool editable = true; QString tooltip; if (selectedItems == 1) { const onlineJob job = ui->m_onlineJobView->model()->data(indexes.first(), onlineJobModel::OnlineJobRole).value(); if (!job.isEditable()) { editable = false; if (job.sendDate().isValid()) tooltip = i18n("This job cannot be edited anymore because is was sent already."); else if (job.isLocked()) tooltip = i18n("Job is being processed at the moment."); else Q_ASSERT(false); } else if (!onlineJobAdministration::instance()->canEditOnlineJob(job)) { editable = false; tooltip = i18n("The plugin to edit this job is not available."); } } else { editable = false; tooltip = i18n("You must select a single job for editing."); } QAction *const onlinejob_edit = kmymoney->actionCollection()->action(kmymoney->s_Actions[Action::OnlineJobEdit]); Q_CHECK_PTR(onlinejob_edit); onlinejob_edit->setEnabled(editable); onlinejob_edit->setToolTip(tooltip); ui->m_buttonEdit->setEnabled(editable); ui->m_buttonEdit->setToolTip(tooltip); // Delete button/action QAction *const onlinejob_delete = kmymoney->actionCollection()->action(kmymoney->s_Actions[Action::OnlineJobDelete]); Q_CHECK_PTR(onlinejob_delete); onlinejob_delete->setEnabled(selectedItems > 0); ui->m_buttonRemove->setEnabled(onlinejob_delete->isEnabled()); } void KOnlineJobOutbox::updateNewCreditTransferButton() { QAction* action = kmymoney->actionCollection()->action(kmymoney->s_Actions[Action::AccountCreditTransfer]); Q_CHECK_PTR(action); ui->m_buttonNewCreditTransfer->setEnabled(action->isEnabled()); } void KOnlineJobOutbox::slotRemoveJob() { QAbstractItemModel* model = ui->m_onlineJobView->model(); QModelIndexList indexes = ui->m_onlineJobView->selectionModel()->selectedRows(); while (!indexes.isEmpty()) { model->removeRow(indexes.at(0).row()); indexes = ui->m_onlineJobView->selectionModel()->selectedRows(); } } QStringList KOnlineJobOutbox::selectedOnlineJobs() const { QModelIndexList indexes = ui->m_onlineJobView->selectionModel()->selectedRows(); if (indexes.isEmpty()) return QStringList(); QStringList list; list.reserve(indexes.count()); const QAbstractItemModel *const model = ui->m_onlineJobView->model(); Q_FOREACH(const QModelIndex& index, indexes) { list.append(model->data(index, onlineJobModel::OnlineJobId).toString()); } return list; } void KOnlineJobOutbox::slotSendJobs() { if (ui->m_onlineJobView->selectionModel()->hasSelection()) slotSendSelectedJobs(); else slotSendAllSendableJobs(); } void KOnlineJobOutbox::slotSendAllSendableJobs() { QList validJobs; foreach (const onlineJob& job, MyMoneyFile::instance()->onlineJobList()) { if (job.isValid() && job.isEditable()) validJobs.append(job); } qDebug() << "I shall send " << validJobs.count() << "/" << MyMoneyFile::instance()->onlineJobList().count() << " onlineJobs"; if (!validJobs.isEmpty()) emit sendJobs(validJobs); } void KOnlineJobOutbox::slotSendSelectedJobs() { QModelIndexList indexes = ui->m_onlineJobView->selectionModel()->selectedRows(); if (indexes.isEmpty()) return; // Valid jobs to send QList validJobs; validJobs.reserve(indexes.count()); // Get valid jobs const QAbstractItemModel *const model = ui->m_onlineJobView->model(); foreach (const QModelIndex& index, indexes) { onlineJob job = model->data(index, onlineJobModel::OnlineJobRole).value(); if (job.isValid() && job.isEditable()) validJobs.append(job); } // Abort if not all jobs can be sent if (validJobs.count() != indexes.count()) { QMessageBox::information(this, i18nc("The user selected credit transfers to send. But they cannot be sent.", "Cannot send selection"), i18n("Not all selected credit transfers can be sent because some of them are invalid or were already sent.")); return; } emit sendJobs(validJobs); } void KOnlineJobOutbox::slotEditJob() { QModelIndexList indexes = ui->m_onlineJobView->selectionModel()->selectedIndexes(); if (!indexes.isEmpty()) { QString jobId = ui->m_onlineJobView->model()->data(indexes.first(), onlineJobModel::OnlineJobId).toString(); Q_ASSERT(!jobId.isEmpty()); emit editJob(jobId); } } void KOnlineJobOutbox::slotEditJob(const QModelIndex &index) { QString jobId = ui->m_onlineJobView->model()->data(index, onlineJobModel::OnlineJobId).toString(); emit editJob(jobId); } void KOnlineJobOutbox::contextMenuEvent(QContextMenuEvent*) { QModelIndexList indexes = ui->m_onlineJobView->selectionModel()->selectedIndexes(); if (!indexes.isEmpty()) { onlineJob job = ui->m_onlineJobView->model()->data(indexes.first(), onlineJobModel::OnlineJobRole).value(); emit showContextMenu(job); } } /** * Do not know why this is needed, but all other views in KMyMoney have it. */ void KOnlineJobOutbox::showEvent(QShowEvent* event) { if (m_needLoad) init(); emit aboutToShow(); // don't forget base class implementation QWidget::showEvent(event); } diff --git a/kmymoney/views/konlinejoboutbox.h b/kmymoney/views/konlinejoboutbox.h index 6933f46d7..184e1ecc7 100644 --- a/kmymoney/views/konlinejoboutbox.h +++ b/kmymoney/views/konlinejoboutbox.h @@ -1,91 +1,91 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2013 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KONLINEJOBOUTBOX_H #define KONLINEJOBOUTBOX_H #include #include #include #include "onlinejob.h" namespace Ui { class KOnlineJobOutbox; } class KOnlineJobOutbox : public QWidget { Q_OBJECT public: explicit KOnlineJobOutbox(QWidget *parent = 0); ~KOnlineJobOutbox(); void setDefaultFocus(); QStringList selectedOnlineJobs() const; void showEvent(QShowEvent* event); signals: void sendJobs(QList); void editJob(QString); void newCreditTransfer(); void aboutToShow(); void showContextMenu(onlineJob); protected: void contextMenuEvent(QContextMenuEvent*); private slots: void updateNewCreditTransferButton(); void updateButtonState() const; private: std::unique_ptr ui; /** * This member holds the load state of page */ bool m_needLoad; /** Initializes page and sets its load status to initialized */ void init(); private slots: void slotRemoveJob(); /** @brief If any job is selected, send it. Send all valid jobs otherwise. */ void slotSendJobs(); /** @brief Send all sendable online jobs */ void slotSendAllSendableJobs(); /** @brief Send only the selected jobs */ void slotSendSelectedJobs(); void slotEditJob(); void slotEditJob(const QModelIndex&); }; #endif // KONLINEJOBOUTBOX_H diff --git a/kmymoney/views/kpayeeidentifierview.cpp b/kmymoney/views/kpayeeidentifierview.cpp index 63efe2c1b..7523b9775 100644 --- a/kmymoney/views/kpayeeidentifierview.cpp +++ b/kmymoney/views/kpayeeidentifierview.cpp @@ -1,125 +1,125 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kpayeeidentifierview.h" #include "ui_kpayeeidentifierview.h" #include #include #include #include #include "kmymoney.h" #include "payeeidentifier/payeeidentifierloader.h" #include "payeeidentifiercontainermodel.h" #include "payeeidentifierselectiondelegate.h" payeeIdentifierDelegate::payeeIdentifierDelegate(QObject* parent) : StyledItemDelegateForwarder(parent) { } QAbstractItemDelegate* payeeIdentifierDelegate::getItemDelegate(const QModelIndex& index) const { static QPointer defaultDelegate; const QString type = (index.isValid()) ? index.model()->data(index, payeeIdentifierContainerModel::payeeIdentifierType).toString() : QString(); if (type.isEmpty()) { QAbstractItemDelegate* delegate = new payeeIdentifierSelectionDelegate(this->parent()); connectSignals(delegate); return delegate; } // Use this->parent() as parent because "this" is const QAbstractItemDelegate* delegate = payeeIdentifierLoader::instance()->createItemDelegate(type, this->parent()); if (delegate == 0) { if (defaultDelegate == 0) defaultDelegate = new QStyledItemDelegate(this->parent()); delegate = defaultDelegate; } connectSignals(delegate, Qt::UniqueConnection); Q_CHECK_PTR(delegate); return delegate; } KPayeeIdentifierView::KPayeeIdentifierView(QWidget* parent) : QWidget(parent), ui(new Ui::KPayeeIdentifierView) { ui->setupUi(this); ui->view->setItemDelegate(new payeeIdentifierDelegate(ui->view)); } KPayeeIdentifierView::~KPayeeIdentifierView() { delete ui; } void KPayeeIdentifierView::setSource(MyMoneyPayeeIdentifierContainer container) { if (ui->view->model() == 0) { payeeIdentifierContainerModel* model = new payeeIdentifierContainerModel(ui->view); connect(kmymoney, &KMyMoneyApp::fileLoaded, model, &payeeIdentifierContainerModel::closeSource); connect(model, &payeeIdentifierContainerModel::dataChanged, this, &KPayeeIdentifierView::dataChanged); connect(model, &payeeIdentifierContainerModel::rowsRemoved, this, &KPayeeIdentifierView::dataChanged); ui->view->setModel(model); } Q_CHECK_PTR(qobject_cast(ui->view->model())); // this should never fail but may help during debugging static_cast(ui->view->model())->setSource(container); // Open persistent editor for last row ui->view->openPersistentEditor(ui->view->model()->index(ui->view->model()->rowCount(QModelIndex()) - 1, 0)); } QList< payeeIdentifier > KPayeeIdentifierView::identifiers() const { const QAbstractItemModel* model = ui->view->model(); if (model != 0) return static_cast(model)->identifiers(); return QList< payeeIdentifier >(); } /** * @brief Helper to sort QModelIndexList in decreasing order. */ inline bool QModelIndexRowComparison(const QModelIndex& first, const QModelIndex& second) { return (first.row() > second.row()); } /** * @bug If the last row is removed the type selection editor (which is always behind that last row) closes. * Maybe that is a Qt bug?! */ void KPayeeIdentifierView::removeSelected() { QModelIndexList selectedRows = ui->view->selectionModel()->selectedRows(); // To keep the items valid during remove the data must be removed from highest row // to the lowes. Unfortunately QList has no reverse iterator. std::sort(selectedRows.begin(), selectedRows.end(), QModelIndexRowComparison); QAbstractItemModel* model = ui->view->model(); Q_CHECK_PTR(model); QModelIndexList::const_iterator end = selectedRows.constEnd(); for (QModelIndexList::const_iterator iter = selectedRows.constBegin(); iter != end; ++iter) model->removeRow(iter->row(), iter->parent()); } diff --git a/kmymoney/views/kpayeeidentifierview.h b/kmymoney/views/kpayeeidentifierview.h index 7e646beba..6518f5886 100644 --- a/kmymoney/views/kpayeeidentifierview.h +++ b/kmymoney/views/kpayeeidentifierview.h @@ -1,62 +1,62 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KPAYEEIDENTIFIERVIEW_H #define KPAYEEIDENTIFIERVIEW_H #include #include "mymoney/mymoneypayeeidentifiercontainer.h" #include "widgets/styleditemdelegateforwarder.h" namespace Ui { class KPayeeIdentifierView; }; class KPayeeIdentifierView : public QWidget { Q_OBJECT public: KPayeeIdentifierView(QWidget* parent); ~KPayeeIdentifierView(); QList identifiers() const; signals: void dataChanged(); public slots: void setSource(MyMoneyPayeeIdentifierContainer data); private slots: void removeSelected(); private: Ui::KPayeeIdentifierView* ui; }; class payeeIdentifierDelegate : public StyledItemDelegateForwarder { Q_OBJECT public: payeeIdentifierDelegate(QObject* parent = 0); virtual QAbstractItemDelegate* getItemDelegate(const QModelIndex& index) const; }; #endif // KPAYEEIDENTIFIERVIEW_H diff --git a/kmymoney/views/payeeidentifierselectiondelegate.cpp b/kmymoney/views/payeeidentifierselectiondelegate.cpp index 5fc7d738f..74cf6a77d 100644 --- a/kmymoney/views/payeeidentifierselectiondelegate.cpp +++ b/kmymoney/views/payeeidentifierselectiondelegate.cpp @@ -1,81 +1,81 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "payeeidentifierselectiondelegate.h" #include #include "payeeidentifier/payeeidentifierloader.h" #include "models/payeeidentifiercontainermodel.h" payeeIdentifierTypeSelectionWidget::payeeIdentifierTypeSelectionWidget(QWidget* parent) : QComboBox(parent) { connect(this, SIGNAL(activated(int)), this, SLOT(itemSelected(int))); } void payeeIdentifierTypeSelectionWidget::itemSelected(int index) { if (index != 0) { emit commitData(this); setCurrentIndex(0); } } payeeIdentifierSelectionDelegate::payeeIdentifierSelectionDelegate(QObject* parent) : QStyledItemDelegate(parent) { } QWidget* payeeIdentifierSelectionDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { Q_UNUSED(option); Q_UNUSED(index); payeeIdentifierTypeSelectionWidget* comboBox = new payeeIdentifierTypeSelectionWidget(parent); comboBox->setFrame(false); connect(comboBox, SIGNAL(commitData(QWidget*)), this, SIGNAL(commitData(QWidget*))); comboBox->addItem(i18n("Please select the account number type")); payeeIdentifierLoader *const loader = payeeIdentifierLoader::instance(); QStringList pidids = loader->availableDelegates(); Q_FOREACH(QString pidid, pidids) { comboBox->addItem(loader->translatedDelegateName(pidid), QVariant(pidid)); } return comboBox; } void payeeIdentifierSelectionDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { QComboBox *const comboBox = qobject_cast(editor); const QString selectedPidType = comboBox->model()->data(comboBox->model()->index(comboBox->currentIndex(), 0), Qt::UserRole).toString(); payeeIdentifier orig = model->data(index, payeeIdentifierContainerModel::payeeIdentifier).value(); payeeIdentifier ident(orig.id(), payeeIdentifierLoader::instance()->createPayeeIdentifier(selectedPidType)); model->setData(index, QVariant::fromValue(ident), payeeIdentifierContainerModel::payeeIdentifier); } void payeeIdentifierSelectionDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const { editor->setGeometry(option.rect); } QSize payeeIdentifierSelectionDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { return QStyledItemDelegate::sizeHint(option, index); } diff --git a/kmymoney/views/payeeidentifierselectiondelegate.h b/kmymoney/views/payeeidentifierselectiondelegate.h index 4b8b45b0d..78bd8bb6f 100644 --- a/kmymoney/views/payeeidentifierselectiondelegate.h +++ b/kmymoney/views/payeeidentifierselectiondelegate.h @@ -1,50 +1,50 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef PAYEEIDENTIFIERSELECTIONDELEGATE_H #define PAYEEIDENTIFIERSELECTIONDELEGATE_H #include #include class payeeIdentifierSelectionDelegate : public QStyledItemDelegate { Q_OBJECT public: payeeIdentifierSelectionDelegate(QObject* parent = 0); virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; }; class payeeIdentifierTypeSelectionWidget : public QComboBox { Q_OBJECT public: explicit payeeIdentifierTypeSelectionWidget(QWidget* parent = 0); signals: void commitData(QWidget* editor); private slots: void itemSelected(int index); }; #endif // PAYEEIDENTIFIERSELECTIONDELEGATE_H diff --git a/kmymoney/widgets/kmymoneytextedit.cpp b/kmymoney/widgets/kmymoneytextedit.cpp index d18b051f7..0888d1d57 100644 --- a/kmymoney/widgets/kmymoneytextedit.cpp +++ b/kmymoney/widgets/kmymoneytextedit.cpp @@ -1,227 +1,227 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "kmymoneytextedit.h" #include "kmymoneytextedit_p.h" #include #include /* The Higligther */ KMyMoneyTextEditHighlighter::KMyMoneyTextEditHighlighter(QTextEdit * parent) : Highlighter(parent), m_allowedChars(QString("")), m_maxLines(-1), m_maxLineLength(-1), m_maxLength(-1) { } void KMyMoneyTextEditHighlighter::setAllowedChars(const QString& chars) { m_allowedChars = chars; rehighlight(); } void KMyMoneyTextEditHighlighter::setMaxLength(const int& length) { m_maxLength = length; rehighlight(); } void KMyMoneyTextEditHighlighter::setMaxLines(const int& lines) { m_maxLines = lines; rehighlight(); } void KMyMoneyTextEditHighlighter::setMaxLineLength(const int& length) { m_maxLineLength = length; rehighlight(); } void KMyMoneyTextEdit::setReadOnly(bool readOnly) { KTextEdit::setReadOnly(readOnly); } void KMyMoneyTextEditHighlighter::highlightBlock(const QString& text) { // Spell checker first Highlighter::highlightBlock(text); QTextCharFormat invalidFormat; invalidFormat.setFontItalic(true); invalidFormat.setForeground(Qt::red); invalidFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); // Check used characters const int length = text.length(); for (int i = 0; i < length; ++i) { if (!m_allowedChars.contains(text.at(i))) { setFormat(i, 1, invalidFormat); } } if (m_maxLines != -1) { //! @todo Is using QTextBlock::blockNumber() as line number dangerous? if (currentBlock().blockNumber() >= m_maxLines) { setFormat(0, length, invalidFormat); return; } } if (m_maxLength != -1) { const int blockPosition = currentBlock().position(); if (m_maxLength < (length + blockPosition)) { setFormat(m_maxLength, length - m_maxLength - blockPosition, invalidFormat); return; } } if (m_maxLineLength != -1 && length >= m_maxLineLength) { setFormat(m_maxLineLength, length - m_maxLineLength, invalidFormat); return; } } /* KMyMoneyTextEdit */ KMyMoneyTextEdit::KMyMoneyTextEdit(QWidget* parent) : KTextEdit(parent), m_maxLength(-1), m_maxLineLength(-1), m_maxLines(-1), m_allowedChars(QString("")), m_highligther(0) { setWordWrapMode(QTextOption::ManualWrap); m_highligther = new KMyMoneyTextEditHighlighter(this); } bool KMyMoneyTextEdit::isEventAllowed(QKeyEvent* e) const { const QString text = e->text(); if (!text.isEmpty()) { if (text.at(0).isPrint()) { if (!m_allowedChars.contains(text)) return false; // Do not check max lengths etc if something is replaced if (textCursor().hasSelection()) return true; const QString plainText = toPlainText(); if (m_maxLength != -1 && plainText.length() >= m_maxLength) return false; if (m_maxLineLength != -1 && textCursor().block().length() - 1 >= m_maxLineLength) return false; } else if (m_maxLines != -1 && text.at(0) == '\r' && toPlainText().count('\n') + 1 >= m_maxLines) { // Does this work on non-linux OSes as well? return false; } } return true; } bool KMyMoneyTextEdit::isValid() const { const QString text = toPlainText(); if (m_maxLength != -1 && text.length() >= m_maxLength) return false; const QStringList lines = text.split('\n'); if (m_maxLines != -1 && lines.count() >= m_maxLines) { return false; } if (m_maxLineLength != -1) { foreach (QString line, lines) { if (line.length() > m_maxLineLength) return false; } } const int length = text.length(); for (int i = 0; i < length; ++i) { if (!m_allowedChars.contains(text.at(i))) return false; } return true; } void KMyMoneyTextEdit::keyReleaseEvent(QKeyEvent* e) { if (isEventAllowed(e)) KTextEdit::keyReleaseEvent(e); } void KMyMoneyTextEdit::keyPressEvent(QKeyEvent* e) { if (isEventAllowed(e)) KTextEdit::keyPressEvent(e); } int KMyMoneyTextEdit::maxLength() const { return m_maxLength; } void KMyMoneyTextEdit::setMaxLength(const int& maxLength) { m_maxLength = maxLength; m_highligther->setMaxLength(m_maxLength); } int KMyMoneyTextEdit::maxLineLength() const { return m_maxLineLength; } void KMyMoneyTextEdit::setMaxLineLength(const int& maxLineLength) { m_maxLineLength = maxLineLength; m_highligther->setMaxLineLength(maxLineLength); } int KMyMoneyTextEdit::maxLines() const { return m_maxLines; } void KMyMoneyTextEdit::setMaxLines(const int& maxLines) { m_maxLines = maxLines; m_highligther->setMaxLines(maxLines); } QString KMyMoneyTextEdit::allowedChars() const { return m_allowedChars; } void KMyMoneyTextEdit::setAllowedChars(const QString& allowedChars) { m_allowedChars = allowedChars; m_highligther->setAllowedChars(allowedChars); } diff --git a/kmymoney/widgets/kmymoneytextedit.h b/kmymoney/widgets/kmymoneytextedit.h index c44e67fd4..a1f24a097 100644 --- a/kmymoney/widgets/kmymoneytextedit.h +++ b/kmymoney/widgets/kmymoneytextedit.h @@ -1,92 +1,92 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KMYMONEYTEXTEDIT_H #define KMYMONEYTEXTEDIT_H #include #include "kmm_widgets_export.h" class KMyMoneyTextEditHighlighter; /** * @brief KTextEdit with restricted character set and length * * Used to set constraints on input. It allows to set readOnly property by * slots as well (not possible with KTextEdit). */ class KMM_WIDGETS_EXPORT KMyMoneyTextEdit : public KTextEdit { Q_OBJECT /** * @brief Maximal number of characters allowed */ Q_PROPERTY(int maxLength READ maxLength WRITE setMaxLength) /** * @brief Maximal number of characters allowed per line */ Q_PROPERTY(int maxLineLength READ maxLineLength WRITE setMaxLineLength) /** * @brief Maximal number of lines */ Q_PROPERTY(int maxLines READ maxLines WRITE setMaxLines) /** * @brief List of all allowed chars */ Q_PROPERTY(QString allowedChars READ allowedChars WRITE setAllowedChars) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly); public: KMyMoneyTextEdit(QWidget* parent = 0); int maxLength() const; int maxLineLength() const; int maxLines() const; QString allowedChars() const; bool isValid() const; public Q_SLOTS: void setMaxLength(const int& maxLength); void setMaxLineLength(const int& maxLineLength); void setMaxLines(const int& maxLines); void setAllowedChars(const QString& allowedChars); /** @brief Slot to set this text edit read only */ void setReadOnly(bool); protected: virtual void keyReleaseEvent(QKeyEvent* e); virtual void keyPressEvent(QKeyEvent* e); private: bool isEventAllowed(QKeyEvent* e) const; int m_maxLength; int m_maxLineLength; int m_maxLines; QString m_allowedChars; KMyMoneyTextEditHighlighter* m_highligther; }; #endif // KMYMONEYTEXTEDIT_H diff --git a/kmymoney/widgets/kmymoneytextedit_p.h b/kmymoney/widgets/kmymoneytextedit_p.h index 8f7719470..118f2f889 100644 --- a/kmymoney/widgets/kmymoneytextedit_p.h +++ b/kmymoney/widgets/kmymoneytextedit_p.h @@ -1,44 +1,44 @@ /* - This file is part of KMyMoney, A Personal Finance Manager for KDE + This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KMYMONEYTEXTEDITHIGHLIGHTER_H #define KMYMONEYTEXTEDITHIGHLIGHTER_H #include class KMyMoneyTextEditHighlighter : public Sonnet::Highlighter { public: KMyMoneyTextEditHighlighter(QTextEdit* parent = 0); void setAllowedChars(const QString& chars); void setMaxLength(const int& length); void setMaxLines(const int& lines); void setMaxLineLength(const int& length); protected: virtual void highlightBlock(const QString& text); private: QString m_allowedChars; int m_maxLines; int m_maxLineLength; int m_maxLength; }; #endif // KMYMONEYTEXTEDITHIGHLIGHTER_H diff --git a/kmymoney/widgets/kmymoneyvalidationfeedback.cpp b/kmymoney/widgets/kmymoneyvalidationfeedback.cpp index 390cdaa1b..213a76dd0 100644 --- a/kmymoney/widgets/kmymoneyvalidationfeedback.cpp +++ b/kmymoney/widgets/kmymoneyvalidationfeedback.cpp @@ -1,99 +1,99 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "kmymoneyvalidationfeedback.h" #include "ui_kmymoneyvalidationfeedback.h" #include #include using namespace Icons; class KMyMoneyValidationFeedback::Private { public: KMyMoneyValidationFeedback::MessageType type; }; KMyMoneyValidationFeedback::KMyMoneyValidationFeedback(QWidget *parent) : QWidget(parent), ui(new Ui::KMyMoneyValidationFeedback), d_ptr(new Private) { ui->setupUi(this); setHidden(true); QSizePolicy newSizePolicy = sizePolicy(); newSizePolicy.setControlType(QSizePolicy::Label); newSizePolicy.setHorizontalPolicy(QSizePolicy::MinimumExpanding); newSizePolicy.setVerticalPolicy(QSizePolicy::Fixed); setSizePolicy(newSizePolicy); } KMyMoneyValidationFeedback::~KMyMoneyValidationFeedback() { Q_D(); delete ui; delete d; } /** * @todo Set icon size according to text size */ void KMyMoneyValidationFeedback::setFeedback(KMyMoneyValidationFeedback::MessageType type, QString message) { Q_D(); d->type = type; if (type == None) { if (message.isEmpty() || message == ui->label->text()) setHidden(true); } else { setHidden(false); ui->label->setText(message); QIcon icon; switch (type) { case Error: icon = QIcon::fromTheme(g_Icons[Icon::DialogError]); break; case Positive: case Information: icon = QIcon::fromTheme(g_Icons[Icon::DialogInformation]); break; case Warning: default: icon = QIcon::fromTheme(g_Icons[Icon::DialogWarning]); } ui->icon->setPixmap(icon.pixmap(24)); } } void KMyMoneyValidationFeedback::removeFeedback() { setHidden(true); } void KMyMoneyValidationFeedback::removeFeedback(KMyMoneyValidationFeedback::MessageType type, QString message) { Q_D(); if (d->type == type && ui->label->text() == message) removeFeedback(); } diff --git a/kmymoney/widgets/kmymoneyvalidationfeedback.h b/kmymoney/widgets/kmymoneyvalidationfeedback.h index 9e064a861..52c6fa05e 100644 --- a/kmymoney/widgets/kmymoneyvalidationfeedback.h +++ b/kmymoney/widgets/kmymoneyvalidationfeedback.h @@ -1,77 +1,77 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KMYMONEYVALIDATIONFEEDBACK_H #define KMYMONEYVALIDATIONFEEDBACK_H #include #include "kmm_widgets_export.h" namespace Ui { class KMyMoneyValidationFeedback; } class KMM_WIDGETS_EXPORT KMyMoneyValidationFeedback : public QWidget { Q_OBJECT public: KMyMoneyValidationFeedback(QWidget *parent = 0); ~KMyMoneyValidationFeedback(); enum MessageType { None, Positive, Information, Warning, Error }; public slots: /** * @brief Removes the shown feedback */ void removeFeedback(); /** * @brief Removes a sepecific feedback * * Removes the feedback only if type and message fit. This is useful * if several objects are connected to setFeedback(). */ void removeFeedback(KMyMoneyValidationFeedback::MessageType type, QString message); /** * @brief Show a feedback * * If type == None and !message.isEmpty() holds, the feedback is only hidden if * the currently shown message equals message. */ void setFeedback(KMyMoneyValidationFeedback::MessageType type, QString message); private: Ui::KMyMoneyValidationFeedback* ui; class Private; Private* d_ptr; Q_DECLARE_PRIVATE(); }; #endif // KMYMONEYVALIDATIONFEEDBACK_H diff --git a/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp b/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp index 5bbc9d8b4..dfeb268da 100644 --- a/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp +++ b/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp @@ -1,42 +1,42 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "ktreewidgetfilterlinewidget.h" #include #include #include KTreeWidgetFilterLineWidget::KTreeWidgetFilterLineWidget(QWidget* parent, QTreeWidget* treeWidget) : KTreeWidgetSearchLineWidget(parent, treeWidget) { } void KTreeWidgetFilterLineWidget::createWidgets() { KTreeWidgetSearchLineWidget::createWidgets(); // The layout pointer is stored in the private class, so we do not have access to it directly // => use findChild() QLabel* label = findChild(); if (!label) return; label->setText(i18nc("Filter widget label", "Fi<er:")); } diff --git a/kmymoney/widgets/ktreewidgetfilterlinewidget.h b/kmymoney/widgets/ktreewidgetfilterlinewidget.h index 95b591bc0..d8f96be10 100644 --- a/kmymoney/widgets/ktreewidgetfilterlinewidget.h +++ b/kmymoney/widgets/ktreewidgetfilterlinewidget.h @@ -1,41 +1,41 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian David * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef KTREEWIDGETFILTERLINEWIDGET_H #define KTREEWIDGETFILTERLINEWIDGET_H #include #include "kmm_widgets_export.h" class KMM_WIDGETS_EXPORT KTreeWidgetFilterLineWidget : public KTreeWidgetSearchLineWidget { Q_OBJECT public: explicit KTreeWidgetFilterLineWidget(QWidget *parent = 0, QTreeWidget *treeWidget = 0); protected Q_SLOTS: /** * @copydoc KTreeWidgetSearchLineWidget::createWidgets() * * After widgets are created, this version finds the label and renames it to "Filter" */ virtual void createWidgets(); }; #endif // KTREEWIDGETFILTERLINEWIDGET_H diff --git a/kmymoney/widgets/onlinejobmessagesview.cpp b/kmymoney/widgets/onlinejobmessagesview.cpp index aa3126a47..edfe825fc 100644 --- a/kmymoney/widgets/onlinejobmessagesview.cpp +++ b/kmymoney/widgets/onlinejobmessagesview.cpp @@ -1,41 +1,41 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "onlinejobmessagesview.h" #include "ui_onlinejobmessagesview.h" onlineJobMessagesView::onlineJobMessagesView(QWidget* parent) : QWidget(parent), ui(new Ui::onlineJobMessageView) { ui->setupUi(this); connect(ui->closeButton, SIGNAL(pressed()), this, SLOT(close())); } void onlineJobMessagesView::setModel(QAbstractItemModel* model) { ui->tableView->setModel(model); // Enlarge the description column ui->tableView->setColumnWidth(2, 4*ui->tableView->columnWidth(2)); } onlineJobMessagesView::~onlineJobMessagesView() { delete ui; } diff --git a/kmymoney/widgets/onlinejobmessagesview.h b/kmymoney/widgets/onlinejobmessagesview.h index 973793bb0..7645912d4 100644 --- a/kmymoney/widgets/onlinejobmessagesview.h +++ b/kmymoney/widgets/onlinejobmessagesview.h @@ -1,45 +1,45 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef ONLINEJOBMESSAGESVIEW_H #define ONLINEJOBMESSAGESVIEW_H #include #include "kmm_widgets_export.h" class QAbstractItemModel; namespace Ui { class onlineJobMessageView; } class KMM_WIDGETS_EXPORT onlineJobMessagesView : public QWidget { Q_OBJECT public: onlineJobMessagesView(QWidget* parent = 0); ~onlineJobMessagesView(); void setModel(QAbstractItemModel* model); protected: Ui::onlineJobMessageView* ui; }; #endif // ONLINEJOBMESSAGESVIEW_H diff --git a/kmymoney/widgets/styleditemdelegateforwarder.cpp b/kmymoney/widgets/styleditemdelegateforwarder.cpp index 7ed2aa223..0c02b1930 100644 --- a/kmymoney/widgets/styleditemdelegateforwarder.cpp +++ b/kmymoney/widgets/styleditemdelegateforwarder.cpp @@ -1,63 +1,63 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "styleditemdelegateforwarder.h" StyledItemDelegateForwarder::StyledItemDelegateForwarder(QObject* parent) : QAbstractItemDelegate(parent) { } void StyledItemDelegateForwarder::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { getItemDelegate(index)->paint(painter, option, index); } QSize StyledItemDelegateForwarder::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { QAbstractItemDelegate* delegate = getItemDelegate(index); Q_CHECK_PTR(delegate); return delegate->sizeHint(option, index); } QWidget* StyledItemDelegateForwarder::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { return getItemDelegate(index)->createEditor(parent, option, index); } void StyledItemDelegateForwarder::setEditorData(QWidget* editor, const QModelIndex& index) const { getItemDelegate(index)->setEditorData(editor, index); } void StyledItemDelegateForwarder::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const { getItemDelegate(index)->setModelData(editor, model, index); } void StyledItemDelegateForwarder::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const { getItemDelegate(index)->updateEditorGeometry(editor, option, index); } void StyledItemDelegateForwarder::connectSignals(QAbstractItemDelegate* delegate, Qt::ConnectionType type) const { connect(delegate, SIGNAL(commitData(QWidget*)), this, SIGNAL(commitData(QWidget*)), type); connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), this, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), type); connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SIGNAL(sizeHintChanged(QModelIndex)), type); } diff --git a/kmymoney/widgets/styleditemdelegateforwarder.h b/kmymoney/widgets/styleditemdelegateforwarder.h index 3c99cf84d..2babcea24 100644 --- a/kmymoney/widgets/styleditemdelegateforwarder.h +++ b/kmymoney/widgets/styleditemdelegateforwarder.h @@ -1,66 +1,66 @@ /* - * This file is part of KMyMoney, A Personal Finance Manager for KDE + * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef STYLEDITEMDELEGATEFORWARDER_H #define STYLEDITEMDELEGATEFORWARDER_H #include #include "kmm_widgets_export.h" /** * @brief Helper to use multiple item delegates in a view * * This class allows to select the used item delegate based on the QModelIndex. * */ class KMM_WIDGETS_EXPORT StyledItemDelegateForwarder : public QAbstractItemDelegate { Q_OBJECT public: StyledItemDelegateForwarder(QObject* parent = 0); virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void setEditorData(QWidget* editor, const QModelIndex& index) const; virtual void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; virtual void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const; /** * @brief Return delegate for a given index * * If an method of this class is called, it uses this function to receive * the correct delegate where the call is forwarded to. * * @return You must return a valid item delegate. * @see connectSignals() */ virtual QAbstractItemDelegate* getItemDelegate(const QModelIndex& index) const = 0; protected: /** * @brief Connects all signals accordingly * * Call this function if you create a new delegate in getItemDelegate(). */ void connectSignals(QAbstractItemDelegate* delegate, Qt::ConnectionType type = Qt::AutoConnection) const; }; #endif // STYLEDITEMDELEGATEFORWARDER_H