diff --git a/kmymoney/plugins/kbanking/gwenkdegui.cpp b/kmymoney/plugins/kbanking/gwenkdegui.cpp index 943c8e7c9..527d8a273 100644 --- a/kmymoney/plugins/kbanking/gwenkdegui.cpp +++ b/kmymoney/plugins/kbanking/gwenkdegui.cpp @@ -1,155 +1,237 @@ /* * A gwenhywfar gui for aqbanking using KDE widgets * Copyright 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) 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 . * */ #include "gwenkdegui.h" #include #include #include #include #include #include #include #include #include "widgets/chiptandialog.h" +#include "widgets/phototandialog.h" + + +#define KBANKING_TANMETHOD_TEXT 0x00000001 +#define KBANKING_TANMETHOD_CHIPTAN 0x00000002 +#define KBANKING_TANMETHOD_CHIPTAN_OPTIC 0x00000003 +#define KBANKING_TANMETHOD_CHIPTAN_USB 0x00000004 +#define KBANKING_TANMETHOD_CHIPTAN_QR 0x00000005 +#define KBANKING_TANMETHOD_PHOTOTAN 0x00000006 + gwenKdeGui::gwenKdeGui() : QT4_Gui() { } gwenKdeGui::~gwenKdeGui() { } int gwenKdeGui::getPasswordText(uint32_t flags, const char *token, const char *title, const char *text, char *buffer, int minLen, int maxLen, GWEN_GUI_PASSWORD_METHOD methodId, GWEN_DB_NODE *methodParams, uint32_t guiid) { return QT4_Gui::getPassword(flags, token, title, text, buffer, minLen, maxLen, methodId, methodParams, guiid); } int gwenKdeGui::getPasswordHhd(uint32_t /*flags*/, const char * /*token*/, const char * /*title*/, const char *text, char *buffer, int minLen, int maxLen, GWEN_GUI_PASSWORD_METHOD /*methodId*/, GWEN_DB_NODE *methodParams, uint32_t /*guiid*/) { QString hhdCode; QString infoText; const char *sChallenge; sChallenge=GWEN_DB_GetCharValue(methodParams, "challenge", 0, NULL); if (! (sChallenge && *sChallenge)) { DBG_ERROR(0, "Empty optical data"); return GWEN_ERROR_NO_DATA; } hhdCode = QString::fromUtf8(sChallenge); infoText = QString::fromUtf8(text); //! @todo: Memory leak? QPointer dialog = new chipTanDialog(getParentWidget()); dialog->setInfoText(infoText); dialog->setHhdCode(hhdCode); dialog->setTanLimits(minLen, maxLen); const int rv = dialog->exec(); if (rv == chipTanDialog::Rejected) return GWEN_ERROR_USER_ABORTED; else if (rv == chipTanDialog::InternalError || dialog.isNull()) return GWEN_ERROR_INTERNAL; QString tan = dialog->tan(); if (tan.length() >= minLen && tan.length() <= maxLen) { strncpy(buffer, tan.toUtf8().constData() , tan.length()); buffer[tan.length()] = 0; return 0; } qDebug("Received Tan with incorrect length by ui."); return GWEN_ERROR_INTERNAL; } +int gwenKdeGui::getPasswordPhoto(uint32_t /*flags*/, + const char * /*token*/, + const char * /*title*/, + const char *text, + char *buffer, + int minLen, + int maxLen, + GWEN_GUI_PASSWORD_METHOD /*methodId*/, + GWEN_DB_NODE *methodParams, + uint32_t /*guiid*/) { + QPixmap picture; + QString infoText; + const uchar * pictureData; + unsigned int pictureDataSize; + + pictureData = (const uchar *)GWEN_DB_GetBinValue(methodParams, "imageData", 0, NULL, 0, &pictureDataSize); + if (! (pictureData && pictureDataSize > 0)) { + DBG_ERROR(0, "Empty optical data"); + return GWEN_ERROR_NO_DATA; + } + + bool loadSuccessful = picture.loadFromData(pictureData, pictureDataSize); + if (! loadSuccessful) { + DBG_ERROR(0, "Unable to read tan picture from image data"); + return GWEN_ERROR_NO_DATA; + } + + infoText = QString::fromUtf8(text); + + //! @todo: Memory leak? + QPointer dialog = new photoTanDialog(getParentWidget()); + dialog->setInfoText(infoText); + dialog->setPicture(picture); + dialog->setTanLimits(minLen, maxLen); + + const int rv = dialog->exec(); + + if (rv == photoTanDialog::Rejected) + return GWEN_ERROR_USER_ABORTED; + else if (rv == photoTanDialog::InternalError || dialog.isNull()) + return GWEN_ERROR_INTERNAL; + + QString tan = dialog->tan(); + if (tan.length() >= minLen && tan.length() <= maxLen) { + strncpy(buffer, tan.toUtf8().constData() , tan.length()); + buffer[tan.length()] = 0; + return 0; + } + qDebug("Received Tan with incorrect length by ui."); + return GWEN_ERROR_INTERNAL; +} + + + int gwenKdeGui::getPassword(uint32_t flags, const char* token, const char* title, const char* text, char* buffer, int minLen, int maxLen, GWEN_GUI_PASSWORD_METHOD methodId, GWEN_DB_NODE *methodParams, uint32_t guiid) { switch((methodId & GWEN_Gui_PasswordMethod_Mask)) { case GWEN_Gui_PasswordMethod_Unknown: case GWEN_Gui_PasswordMethod_Mask: DBG_ERROR(0, "Invalid password method id %08x", methodId); return GWEN_ERROR_INVALID; case GWEN_Gui_PasswordMethod_Text: return getPasswordText(flags, token, title, text, buffer, minLen, maxLen, methodId, methodParams, guiid); case GWEN_Gui_PasswordMethod_OpticalHHD: - return getPasswordHhd(flags, - token, - title, - text, - buffer, - minLen, - maxLen, - methodId, methodParams, - guiid); + int tanMethodId = GWEN_DB_GetIntValue(methodParams, "tanMethodId", 0, 0); + switch(tanMethodId) { + case KBANKING_TANMETHOD_CHIPTAN_OPTIC: + return getPasswordHhd(flags, + token, + title, + text, + buffer, + minLen, + maxLen, + methodId, methodParams, + guiid); + case KBANKING_TANMETHOD_PHOTOTAN: + return getPasswordPhoto(flags, + token, + title, + text, + buffer, + minLen, + maxLen, + methodId, methodParams, + guiid); + default: + DBG_ERROR(0, "Unknown tan method ID %i", tanMethodId); + return GWEN_ERROR_NO_DATA; + } + /* intentionally omit "default:" here to be informed when new password methods are added to * gwen which have not been implemented. */ } DBG_ERROR(0, "Unhandled password method id %08x", methodId); return GWEN_ERROR_INVALID; } diff --git a/kmymoney/plugins/kbanking/gwenkdegui.h b/kmymoney/plugins/kbanking/gwenkdegui.h index a2363d2af..33922a509 100644 --- a/kmymoney/plugins/kbanking/gwenkdegui.h +++ b/kmymoney/plugins/kbanking/gwenkdegui.h @@ -1,112 +1,121 @@ /* * A gwenhywfar gui for aqbanking using KDE widgets * Copyright 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) 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 "gwen-gui-qt4/qt4_gui.hpp" /** * @brief Gwenhywfar Gui for KDE * * * @author Christian David */ class gwenKdeGui : public QT4_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, GWEN_GUI_PASSWORD_METHOD methodId, GWEN_DB_NODE *methodParams, uint32_t guiid); private: int getPasswordText(uint32_t flags, const char *token, const char *title, const char *text, char *buffer, int minLen, int maxLen, GWEN_GUI_PASSWORD_METHOD methodId, GWEN_DB_NODE *methodParams, uint32_t guiid); int getPasswordHhd(uint32_t flags, const char *token, const char *title, const char *text, char *buffer, int minLen, int maxLen, GWEN_GUI_PASSWORD_METHOD methodId, GWEN_DB_NODE *methodParams, uint32_t guiid); - + int getPasswordPhoto(uint32_t flags, + const char *token, + const char *title, + const char *text, + char *buffer, + int minLen, + int maxLen, + GWEN_GUI_PASSWORD_METHOD methodId, + GWEN_DB_NODE *methodParams, + uint32_t guiid); }; #include /** * @brief Helper class which is receiver for several signals */ class gwenKdeGuiTanResult : public QObject { Q_OBJECT public: gwenKdeGuiTanResult(QObject* parent = 0) : 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/widgets/CMakeLists.txt b/kmymoney/plugins/kbanking/widgets/CMakeLists.txt index 8918141d9..7bbbafd98 100644 --- a/kmymoney/plugins/kbanking/widgets/CMakeLists.txt +++ b/kmymoney/plugins/kbanking/widgets/CMakeLists.txt @@ -1,11 +1,16 @@ ########### next target ############### set(kmm_kbanking_widgets_la_SOURCES chiptandialog.cpp kbaccountlist.cpp kbjoblist.cpp + phototandialog.cpp +) + +kde4_add_ui_files(kmm_kbanking_widgets_la_SOURCES + chiptandialog.ui + phototandialog.ui ) -kde4_add_ui_files(kmm_kbanking_widgets_la_SOURCES chiptandialog.ui) kde4_add_library(kmm_kbanking_widgets STATIC ${kmm_kbanking_widgets_la_SOURCES}) diff --git a/kmymoney/plugins/kbanking/widgets/chiptandialog.cpp b/kmymoney/plugins/kbanking/widgets/chiptandialog.cpp index 656b8f560..129eb9a06 100644 --- a/kmymoney/plugins/kbanking/widgets/chiptandialog.cpp +++ b/kmymoney/plugins/kbanking/widgets/chiptandialog.cpp @@ -1,174 +1,173 @@ /* * A tan input dialog for optical chipTan used in online banking * Copyright 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) 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 . * */ #include "chiptandialog.h" #include "ui_chiptandialog.h" // Qt Includes #include #include #include #include // KDE Includes #include // Prject Includes #include "kbankingsettings.h" chipTanDialog::chipTanDialog(QWidget* parent) - : QDialog(parent), - m_tan(""), - m_accepted(true) + : QDialog(parent) + , m_accepted(true) { ui = new Ui::chipTanDialog; ui->setupUi(this); connect(ui->dialogButtonBox, SIGNAL(accepted()), SLOT(accept())); connect(ui->dialogButtonBox, SIGNAL(rejected()), SLOT(reject())); - connect(ui->tanInput, SIGNAL(userTextChanged(QString)), SLOT(tanInputChanged(QString))); + connect(ui->tanInput, SIGNAL(textChanged(QString)), SLOT(tanInputChanged(QString))); ui->declarativeView->setSource(KGlobal::dirs()->findResource("data", QLatin1String("kmm_kbanking/qml/chipTan/ChipTan.qml"))); setFlickerFieldWidth(KBankingSettings::width()); setFlickerFieldClockSetting(KBankingSettings::clocksetting()); connect(ui->decelerateButton, SIGNAL(clicked(bool)), ui->declarativeView->rootObject(), SLOT(decelerateTransmission())); connect(ui->accelerateButton, SIGNAL(clicked(bool)), ui->declarativeView->rootObject(), SLOT(accelerateTransmission())); connect(ui->enlargeButton, SIGNAL(clicked(bool)), ui->declarativeView->rootObject(), SLOT(enlargeFlickerField())); connect(ui->reduceButton, SIGNAL(clicked(bool)), ui->declarativeView->rootObject(), SLOT(reduceFlickerField())); connect(ui->declarativeView->rootObject(), SIGNAL(flickerFieldWidthChanged(int)), SLOT(flickerFieldWidthChanged(int))); connect(ui->declarativeView->rootObject(), SIGNAL(flickerFieldClockSettingChanged(int)), SLOT(flickerFieldClockSettingChanged(int))); if (ui->declarativeView->status() == QDeclarativeView::Error) done(InternalError); tanInputChanged(QString()); } chipTanDialog::~chipTanDialog() { delete ui; } void chipTanDialog::accept() { m_tan = ui->tanInput->text(); m_accepted = true; done(Accepted); } void chipTanDialog::reject() { m_accepted = false; done(Rejected); } void chipTanDialog::setInfoText(const QString& text) { ui->infoText->setText(text); } QString chipTanDialog::infoText() { return ui->infoText->toPlainText(); } void chipTanDialog::setHhdCode(const QString& code) { setRootObjectProperty("transferData", code); } QString chipTanDialog::hhdCode() { QGraphicsObject* rootObject = ui->declarativeView->rootObject(); if (rootObject) return rootObject->property("transferData").toString(); return QString(); } QString chipTanDialog::tan() { return m_tan; } void chipTanDialog::setTanLimits(const int& minLength, const int& maxLength) { ui->tanInput->setValidator(new QRegExpValidator(QRegExp(QString("\\d{%1,%2}").arg(minLength).arg(maxLength)), ui->tanInput)); } void chipTanDialog::setFlickerFieldWidth(const int& width) { QGraphicsObject* rootObject = ui->declarativeView->rootObject(); if (rootObject) QMetaObject::invokeMethod(rootObject, "setFlickerFieldWidth", Q_ARG(QVariant, QVariant(width))); } int chipTanDialog::flickerFieldWidth() { QGraphicsObject* rootObject = ui->declarativeView->rootObject(); QVariant width; if (rootObject) QMetaObject::invokeMethod(rootObject, "flickerFieldWidth", Qt::DirectConnection, Q_RETURN_ARG(QVariant, width)); return width.toInt(); } void chipTanDialog::setFlickerFieldClockSetting(const int& width) { QGraphicsObject* rootObject = ui->declarativeView->rootObject(); if (rootObject) QMetaObject::invokeMethod(rootObject, "setFlickerClockSetting", Q_ARG(QVariant, QVariant(width))); } void chipTanDialog::flickerFieldClockSettingChanged(const int& takt) { KBankingSettings::setClocksetting(takt); KBankingSettings::self()->writeConfig(); } void chipTanDialog::flickerFieldWidthChanged(const int& width) { KBankingSettings::setWidth(width); KBankingSettings::self()->writeConfig(); } void chipTanDialog::tanInputChanged(const QString& input) { QPushButton *button = ui->dialogButtonBox->button(QDialogButtonBox::Ok); Q_ASSERT(button); if (input.isEmpty() || !ui->tanInput->hasAcceptableInput()) { button->setEnabled(false); button->setToolTip(i18n("A valid tan is required to proceed.")); } else { button->setEnabled(true); button->setToolTip(""); } } void chipTanDialog::setRootObjectProperty(const char* property, const QVariant& value) { QGraphicsObject* rootObject = ui->declarativeView->rootObject(); if (rootObject) rootObject->setProperty(property, value); } diff --git a/kmymoney/plugins/kbanking/widgets/phototandialog.cpp b/kmymoney/plugins/kbanking/widgets/phototandialog.cpp new file mode 100644 index 000000000..6057a4480 --- /dev/null +++ b/kmymoney/plugins/kbanking/widgets/phototandialog.cpp @@ -0,0 +1,114 @@ +/* + * A tan input dialog for optical photoTan used in online banking + * Copyright 2019 Jürgen Diez + * + * 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 . + * + */ + +#include "phototandialog.h" +#include "ui_phototandialog.h" + +// Qt Includes +#include +#include + +// KDE Includes +#include +#include + +// Project Includes +#include "kbankingsettings.h" + +photoTanDialog::photoTanDialog(QWidget* parent) + : QDialog(parent) + , m_accepted(true) +{ + ui = new Ui::photoTanDialog; + ui->setupUi(this); + + connect(ui->buttonBox, SIGNAL(accepted()), SLOT(accept())); + connect(ui->buttonBox, SIGNAL(rejected()), SLOT(reject())); + connect(ui->tanInput, SIGNAL(textChanged(QString)), SLOT(tanInputChanged(QString))); + + tanInputChanged(QString()); + ui->tanInput->setFocus(); +} + +photoTanDialog::~photoTanDialog() +{ + if (ui!=0) + delete ui; +} + +void photoTanDialog::accept() +{ + m_tan = ui->tanInput->text(); + m_accepted = true; + done(Accepted); +} + +void photoTanDialog::reject() +{ + m_accepted = false; + done(Rejected); +} + +void photoTanDialog::setInfoText(const QString& text) +{ + ui->infoText->setText(text); +} + +QString photoTanDialog::infoText() +{ + return ui->infoText->toPlainText(); +} + +void photoTanDialog::setPicture(const QPixmap &picture) +{ + QGraphicsScene *scene = new QGraphicsScene(); + pictureItem = scene->addPixmap(picture); + ui->graphicsView->setScene(scene); +} + +QPixmap photoTanDialog::picture() +{ + return pictureItem->pixmap(); +} + +QString photoTanDialog::tan() +{ + return m_tan; +} + +void photoTanDialog::setTanLimits(const int& minLength, const int& maxLength) +{ + ui->tanInput->setValidator(new QRegExpValidator(QRegExp(QString("\\d{%1,%2}").arg(minLength).arg(maxLength)), ui->tanInput)); +} + +void photoTanDialog::tanInputChanged(const QString& input) +{ + QPushButton *const button = ui->buttonBox->button(QDialogButtonBox::Ok); + Q_ASSERT(button); + if (input.isEmpty() || !ui->tanInput->hasAcceptableInput()) { + button->setEnabled(false); + button->setToolTip(i18n("A valid tan is required to proceed.")); + } else { + button->setEnabled(true); + button->setToolTip(QString()); + } +} diff --git a/kmymoney/plugins/kbanking/widgets/phototandialog.h b/kmymoney/plugins/kbanking/widgets/phototandialog.h new file mode 100644 index 000000000..00c7f762a --- /dev/null +++ b/kmymoney/plugins/kbanking/widgets/phototandialog.h @@ -0,0 +1,71 @@ +/* + * A tan input dialog for optical photoTan used in online banking + * Copyright 2019 Jürgen Diez + * + * 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 PHOTOTANDIALOG_H +#define PHOTOTANDIALOG_H + +#include + +#include +#include + +namespace Ui +{ +class photoTanDialog; +} + +class photoTanDialog : public QDialog +{ + Q_OBJECT + Q_PROPERTY(QString infoText READ infoText() WRITE setInfoText) + Q_PROPERTY(QPixmap picture READ picture() WRITE setPicture) + +public: + photoTanDialog(QWidget* parent = 0); + ~photoTanDialog(); + + enum Result { Accepted = 0, Rejected, InternalError }; + + QString infoText(); + QString tan(); + QPixmap picture(); + +public slots: + void accept(); + void reject(); + + void setInfoText(const QString&); + void setPicture(const QPixmap&); + + void setTanLimits(const int& minLength, const int& maxLength); + +private slots: + void tanInputChanged(const QString&); + +private: + Ui::photoTanDialog* ui; + QGraphicsPixmapItem *pictureItem; + QString m_tan; + bool m_accepted; +}; + +#endif // PHOTOTANDIALOG_H diff --git a/kmymoney/plugins/kbanking/widgets/phototandialog.ui b/kmymoney/plugins/kbanking/widgets/phototandialog.ui new file mode 100644 index 000000000..ab36b677b --- /dev/null +++ b/kmymoney/plugins/kbanking/widgets/phototandialog.ui @@ -0,0 +1,89 @@ + + + photoTanDialog + + + + 0 + 0 + 656 + 421 + + + + Order confirmation + + + + + + + + + + + background:transparent + + + QFrame::NoFrame + + + QFrame::Plain + + + true + + + false + + + + + + + + + + + To confirm this order enter the tan displayed by your &generator + + + tanInput + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + tanInput + buttonBox + infoText + + + +