diff --git a/kmymoney/models/payeeidentifiercontainermodel.cpp b/kmymoney/models/payeeidentifiercontainermodel.cpp --- a/kmymoney/models/payeeidentifiercontainermodel.cpp +++ b/kmymoney/models/payeeidentifiercontainermodel.cpp @@ -18,6 +18,8 @@ #include "payeeidentifiercontainermodel.h" #include "payeeidentifier/payeeidentifierloader.h" #include "payeeidentifier/payeeidentifier.h" +#include "payeeidentifier/ibanbic/ibanbic.h" +#include "payeeidentifier/nationalaccount/nationalaccount.h" #include @@ -68,10 +70,15 @@ Qt::ItemFlags payeeIdentifierContainerModel::flags(const QModelIndex& index) const { - Qt::ItemFlags flags = QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled; - const QString type = data(index, payeeIdentifierType).toString(); + static const QVector editableDelegates { + payeeIdentifiers::ibanBic::staticPayeeIdentifierIid(), + payeeIdentifiers::nationalAccount::staticPayeeIdentifierIid() + }; + auto flags = QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled; + const auto type = data(index, payeeIdentifierType).toString(); + // type.isEmpty() means the type selection can be shown - if (!type.isEmpty() && payeeIdentifierLoader::instance()->hasItemEditDelegate(type)) + if (!type.isEmpty() && editableDelegates.contains(type)) flags |= Qt::ItemIsEditable; return flags; } diff --git a/kmymoney/views/kpayeeidentifierview.cpp b/kmymoney/views/kpayeeidentifierview.cpp --- a/kmymoney/views/kpayeeidentifierview.cpp +++ b/kmymoney/views/kpayeeidentifierview.cpp @@ -28,6 +28,8 @@ #include "payeeidentifier/payeeidentifierloader.h" #include "payeeidentifiercontainermodel.h" #include "payeeidentifierselectiondelegate.h" +#include "widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.h" +#include "widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.h" payeeIdentifierDelegate::payeeIdentifierDelegate(QObject* parent) : StyledItemDelegateForwarder(parent) @@ -45,8 +47,13 @@ return delegate; } + QAbstractItemDelegate* delegate = nullptr; // Use this->parent() as parent because "this" is const - QAbstractItemDelegate* delegate = payeeIdentifierLoader::instance()->createItemDelegate(type, this->parent()); + if (type == payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()) { + delegate = new ibanBicItemDelegate(this->parent()); + } else if (type == payeeIdentifiers::nationalAccount::staticPayeeIdentifierIid()) { + delegate = new nationalAccountDelegate(this->parent()); + } if (delegate == 0) { if (defaultDelegate == 0) diff --git a/kmymoney/views/payeeidentifierselectiondelegate.cpp b/kmymoney/views/payeeidentifierselectiondelegate.cpp --- a/kmymoney/views/payeeidentifierselectiondelegate.cpp +++ b/kmymoney/views/payeeidentifierselectiondelegate.cpp @@ -55,16 +55,14 @@ connect(comboBox, SIGNAL(commitData(QWidget*)), this, SIGNAL(commitData(QWidget*))); comboBox->addItem(i18n("Please select the account number type")); - payeeIdentifierLoader *const loader = payeeIdentifierLoader::instance(); - - for (const auto &pidid : loader->availableDelegates()) { - QString delegateName; - if (pidid == payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()) - delegateName = i18n("IBAN and BIC"); - else if (pidid == payeeIdentifiers::nationalAccount::staticPayeeIdentifierIid()) - delegateName = i18n("National Account Number"); - comboBox->addItem(delegateName, QVariant(pidid)); - } + + const QMap availableDelegates { + {payeeIdentifiers::ibanBic::staticPayeeIdentifierIid(), i18n("IBAN and BIC")}, + {payeeIdentifiers::nationalAccount::staticPayeeIdentifierIid(), i18n("National Account Number")} + }; + + for (auto delegate = availableDelegates.cbegin(); delegate != availableDelegates.cend(); ++delegate ) + comboBox->addItem(delegate.value(), delegate.key()); return comboBox; } diff --git a/kmymoney/widgets/CMakeLists.txt b/kmymoney/widgets/CMakeLists.txt --- a/kmymoney/widgets/CMakeLists.txt +++ b/kmymoney/widgets/CMakeLists.txt @@ -61,11 +61,46 @@ kmymoneyaccountsviewbase.cpp ) +set(nationalAccountWidget_SOURCES + ./payeeidentifier/nationalaccount/nationalaccountedit.cpp + ./payeeidentifier/nationalaccount/nationalaccountdelegate.cpp +) + +set(nationalAccountWidget_HEADERS + ./payeeidentifier/nationalaccount/nationalaccountdelegate.h + ./payeeidentifier/nationalaccount/nationalaccountedit.h +) + +set(IBANBICWidget_SOURCES + ./payeeidentifier/ibanbic/kibanlineedit.cpp + ./payeeidentifier/ibanbic/kbicedit.cpp + ./payeeidentifier/ibanbic/ibanvalidator.cpp + ./payeeidentifier/ibanbic/bicvalidator.cpp + ./payeeidentifier/ibanbic/ibanbicitemdelegate.cpp + ./payeeidentifier/ibanbic/ibanbicitemedit.cpp +) + +set(IBANBICWidget_HEADERS + ./payeeidentifier/ibanbic/kibanlineedit.h + ./payeeidentifier/ibanbic/kbicedit.h + ./payeeidentifier/ibanbic/ibanvalidator.h + ./payeeidentifier/ibanbic/bicvalidator.h + ./payeeidentifier/ibanbic/ibanbicitemdelegate.h +) + +list(APPEND kmm_widgets_sources ${nationalAccountWidget_SOURCES}) +list(APPEND kmymoney_STAT_HEADERS ${nationalAccountWidget_HEADERS}) + +list(APPEND kmm_widgets_sources ${IBANBICWidget_SOURCES}) +list(APPEND kmymoney_STAT_HEADERS ${IBANBICWidget_HEADERS}) + ki18n_wrap_ui(kmm_widgets_sources kmymoneyvalidationfeedback.ui onlinejobmessagesview.ui daterangedlg.ui ktransactionfilter.ui + ./payeeidentifier/nationalaccount/nationalaccountedit.ui + ./payeeidentifier/ibanbic/ibanbicitemedit.ui ) add_library(kmm_widgets SHARED ${kmm_widgets_sources}) @@ -82,6 +117,7 @@ Alkimia::alkimia kmm_mymoney kmm_models + kmm_plugin ) set_target_properties(kmm_widgets PROPERTIES diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/bicvalidator.h b/kmymoney/widgets/payeeidentifier/ibanbic/bicvalidator.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/bicvalidator.h @@ -0,0 +1,38 @@ +/* + * Copyright 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 BICVALIDATOR_H +#define BICVALIDATOR_H + +#include +#include "payeeidentifier_iban_bic_widgets_export.h" +#include "kmymoneyvalidationfeedback.h" + +namespace eWidgets { namespace ValidationFeedback { enum class MessageType; } } + +class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT bicValidator : public QValidator +{ + Q_OBJECT + +public: + explicit bicValidator(QObject* parent = 0); + QValidator::State validate(QString& , int&) const final override; + + static QPair validateWithMessage(const QString&); +}; + +#endif // BICVALIDATOR_H diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/bicvalidator.cpp b/kmymoney/widgets/payeeidentifier/ibanbic/bicvalidator.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/bicvalidator.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 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 "bicvalidator.h" + +#include + +#include "payeeidentifier/ibanbic/ibanbic.h" +#include "widgetenums.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< eWidgets::ValidationFeedback::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< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Error, i18n("A valid BIC is 8 or 11 characters long.")); + + if (payeeIdentifiers::ibanBic::isBicAllocated(string) == payeeIdentifiers::ibanBic::bicNotAllocated) + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Error, i18n("The given BIC is not assigned to any credit institute.")); + + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::None, QString()); + +} diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.h b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.h @@ -0,0 +1,49 @@ +/* + * Copyright 2014-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 IBANBICITEMDELEGATE_H +#define IBANBICITEMDELEGATE_H + +#include "kmm_widgets_export.h" + +#include + +#include "payeeidentifier/payeeidentifiertyped.h" +#include "payeeidentifier/ibanbic/ibanbic.h" + +class KMM_WIDGETS_EXPORT ibanBicItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT + +public: + explicit ibanBicItemDelegate(QObject* parent = nullptr, const QVariantList& args = QVariantList()); + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override; + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + void setEditorData(QWidget* editor, const QModelIndex& index) const override; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const override; + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const override; + +Q_SIGNALS: + void sizeHintChanged(const QModelIndex&) const; + +private: + inline payeeIdentifierTyped ibanBicByIndex(const QModelIndex& index) const; + +}; + +#endif // IBANBICITEMDELEGATE_H diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.cpp b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.cpp @@ -0,0 +1,158 @@ +/* + * Copyright 2014-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 "ibanbicitemdelegate.h" + +#include +#include +#include + +#include + +#include "models/payeeidentifiercontainermodel.h" +#include "ibanbicitemedit.h" + +ibanBicItemDelegate::ibanBicItemDelegate(QObject* parent, const QVariantList&) + : 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, 3*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/widgets/payeeidentifier/ibanbic/ibanbicitemedit.h b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemedit.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemedit.h @@ -0,0 +1,66 @@ +/* + * Copyright 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 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: + explicit 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/widgets/payeeidentifier/ibanbic/ibanbicitemedit.cpp b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemedit.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemedit.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 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 "ibanbicitemedit.h" +#include "ui_ibanbicitemedit.h" + +#include "payeeidentifier/ibanbic/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 (const payeeIdentifier::empty &) { + } catch (const payeeIdentifier::badCast &) { + } +} + +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/widgets/payeeidentifier/ibanbic/ibanbicitemedit.ui b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemedit.ui new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/ibanbicitemedit.ui @@ -0,0 +1,56 @@ + + + ibanBicItemEdit + + + + 0 + 0 + 86 + 84 + + + + + + + IBAN + + + + + + + + + + BIC + + + + + + + + + + + KIbanLineEdit + QLineEdit +
widgets/payeeidentifier/ibanbic/kibanlineedit.h
+
+ + KBicEdit + QLineEdit +
widgets/payeeidentifier/ibanbic/kbicedit.h
+
+ + KMyMoneyValidationFeedback + QWidget +
kmymoneyvalidationfeedback.h
+ 1 +
+
+ + +
diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/ibanvalidator.h b/kmymoney/widgets/payeeidentifier/ibanbic/ibanvalidator.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/ibanvalidator.h @@ -0,0 +1,42 @@ +/* + * Copyright 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 IBANVALIDATOR_H +#define IBANVALIDATOR_H + +#include "payeeidentifier_iban_bic_widgets_export.h" + +#include + +#include "kmymoneyvalidationfeedback.h" + +namespace eWidgets { namespace ValidationFeedback { enum class MessageType; } } + +class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT ibanValidator : public QValidator +{ + Q_OBJECT + +public: + explicit ibanValidator(QObject* parent = 0); + State validate(QString& , int&) const final override; + State validate(const QString&) const; + void fixup(QString&) const final override; + + static QPair validateWithMessage(const QString&); +}; + +#endif // IBANVALIDATOR_H diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/ibanvalidator.cpp b/kmymoney/widgets/payeeidentifier/ibanbic/ibanvalidator.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/ibanvalidator.cpp @@ -0,0 +1,83 @@ +/* + * Copyright 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 "ibanvalidator.h" + +#include "payeeidentifier/ibanbic/ibanbic.h" +#include + +#include "widgetenums.h" + +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< eWidgets::ValidationFeedback::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< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Error, i18n("This IBAN is too short.")); + + if (!payeeIdentifiers::ibanBic::validateIbanChecksum(payeeIdentifiers::ibanBic::ibanToElectronic(string))) + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Warning, i18n("This IBAN is invalid.")); + + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::None, QString()); +} + +void ibanValidator::fixup(QString& string) const +{ + string = payeeIdentifiers::ibanBic::ibanToPaperformat(string); +} diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/kbicedit.h b/kmymoney/widgets/payeeidentifier/ibanbic/kbicedit.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/kbicedit.h @@ -0,0 +1,40 @@ +/* + * Copyright 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 KBICEDIT_H +#define KBICEDIT_H + +#include +#include + +#include "payeeidentifier_iban_bic_widgets_export.h" + +class QAbstractItemDelegate; + +class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT KBicEdit : public KLineEdit +{ + Q_OBJECT + +public: + explicit KBicEdit(QWidget* parent = 0); + virtual ~KBicEdit(); + +private: + QAbstractItemDelegate* m_popupDelegate; +}; + +#endif // KBICEDIT_H diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/kbicedit.cpp b/kmymoney/widgets/payeeidentifier/ibanbic/kbicedit.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/kbicedit.cpp @@ -0,0 +1,121 @@ +/* + * Copyright 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 "kbicedit.h" + +#include +#include +#include +#include +#include +#include + +#include "kmymoneyplugin.h" +#include "bicvalidator.h" +#include "kmymoneyvalidationfeedback.h" +#include "plugins/ibanbicdata/ibanbicdataenums.h" + +class bicItemDelegate : public QStyledItemDelegate +{ +public: + explicit bicItemDelegate(QObject* parent = 0) : QStyledItemDelegate(parent) {} + void paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const final override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const final override; + +private: + inline QFont getSmallFont(const QStyleOptionViewItem& option) const; +}; + +KBicEdit::KBicEdit(QWidget* parent) + : KLineEdit(parent) +{ + QCompleter* completer = new QCompleter(this); + if (auto plugin = pPlugins.data.value(QString::fromLatin1("ibanbicdata"), nullptr)) + if (auto model = plugin->requestData(QString(), eIBANBIC::DataType::bicModel).value()) + 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, eIBANBIC::DisplayRole::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/widgets/payeeidentifier/ibanbic/kibanlineedit.h b/kmymoney/widgets/payeeidentifier/ibanbic/kibanlineedit.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/kibanlineedit.h @@ -0,0 +1,36 @@ +/* + * Copyright 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 KIBANLINEEDIT_H +#define KIBANLINEEDIT_H + +#include "payeeidentifier_iban_bic_widgets_export.h" + +#include + +class ibanValidator; + +class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT KIbanLineEdit : public KLineEdit +{ + Q_OBJECT + +public: + explicit KIbanLineEdit(QWidget* parent); + const ibanValidator* validator() const; +}; + +#endif // KIBANLINEEDIT_H diff --git a/kmymoney/widgets/payeeidentifier/ibanbic/kibanlineedit.cpp b/kmymoney/widgets/payeeidentifier/ibanbic/kibanlineedit.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/ibanbic/kibanlineedit.cpp @@ -0,0 +1,33 @@ +/* + * Copyright 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 "kibanlineedit.h" + +#include "ibanvalidator.h" +#include "kmymoneyvalidationfeedback.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/widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.h b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.h @@ -0,0 +1,49 @@ +/* + * Copyright 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 NATIONALACCOUNTDELEGATE_H +#define NATIONALACCOUNTDELEGATE_H + +#include "kmm_widgets_export.h" + +#include + +#include "payeeidentifier/nationalaccount/nationalaccount.h" +#include "payeeidentifier/payeeidentifiertyped.h" + +class KMM_WIDGETS_EXPORT nationalAccountDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + explicit nationalAccountDelegate(QObject* parent, const QVariantList& options = QVariantList()); + + void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const final override; + QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const final override; + QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const final override; + void setEditorData(QWidget* editor, const QModelIndex& index) const final override; + void setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const final override; + void updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const final override; + +Q_SIGNALS: + void sizeHintChanged(const QModelIndex&) const; + +private: + inline payeeIdentifierTyped identByIndex(const QModelIndex& index) const; + +}; + +#endif // NATIONALACCOUNTDELEGATE_H diff --git a/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.cpp b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.cpp @@ -0,0 +1,161 @@ +/* + * Copyright 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 "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/widgets/payeeidentifier/nationalaccount/nationalaccountedit.h b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountedit.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountedit.h @@ -0,0 +1,62 @@ +/* + * Copyright 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 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: + explicit 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/widgets/payeeidentifier/nationalaccount/nationalaccountedit.cpp b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountedit.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountedit.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 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 "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 (const payeeIdentifier::empty &) { + } catch (const payeeIdentifier::badCast &) { + } + } + 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 (const payeeIdentifier::empty &) { + } catch (const payeeIdentifier::badCast &) { + } +} + +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/widgets/payeeidentifier/nationalaccount/nationalaccountedit.ui b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountedit.ui new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/payeeidentifier/nationalaccount/nationalaccountedit.ui @@ -0,0 +1,32 @@ + + + nationalAccountEdit + + + + 0 + 0 + 86 + 84 + + + + + + + account number + + + + + + + institution code + + + + + + + +