[kde-doc-english] [kmymoney/add-onlinebanking] kmymoney/plugins/kbanking: Added a chipTan dialog for the KBanking plugin

Christian Dávid christian-david at web.de
Thu Jan 23 15:12:05 UTC 2014


Git commit 02469324b15674e4c205f69d9ba53e04e473449f by Christian Dávid.
Committed on 23/01/2014 at 14:54.
Pushed by christiand into branch 'add-onlinebanking'.

Added a chipTan dialog for the KBanking plugin

Implemented the "flicker field" ("animierte Grafik") for HandHeldDevices
(HHD) used for tan creation in chipTan-orders. Should be compatible with
the standard by Zentraler Kreditausschuss.

GUI: chipTan Tan input dialog, only visible under certain circumstances.
Only interesting for german translations as this is supported only by
german banks.

M  +4    -2    kmymoney/plugins/kbanking/CMakeLists.txt
A  +86   -0    kmymoney/plugins/kbanking/gwenkdegui.cpp     [License: GPL (v2/3)]
A  +78   -0    kmymoney/plugins/kbanking/gwenkdegui.h     [License: GPL (v2/3)]
M  +3    -3    kmymoney/plugins/kbanking/mymoneybanking.cpp
A  +1    -0    kmymoney/plugins/kbanking/qml/CMakeLists.txt
A  +7    -0    kmymoney/plugins/kbanking/qml/chipTan/CMakeLists.txt
A  +165  -0    kmymoney/plugins/kbanking/qml/chipTan/ChipTan.qml     [License: GPL (v2/3)]
A  +140  -0    kmymoney/plugins/kbanking/qml/chipTan/ChipTanFlickerField.qml     [License: GPL (v2/3)]
A  +88   -0    kmymoney/plugins/kbanking/qml/chipTan/chipTan.js
M  +17   -0    kmymoney/plugins/kbanking/views/kbjobview.cpp
M  +5    -0    kmymoney/plugins/kbanking/views/kbjobview.h
M  +1    -1    kmymoney/plugins/kbanking/views/kbjobview.ui
M  +3    -2    kmymoney/plugins/kbanking/widgets/CMakeLists.txt
A  +148  -0    kmymoney/plugins/kbanking/widgets/chiptandialog.cpp     [License: GPL (v2/3)]
A  +73   -0    kmymoney/plugins/kbanking/widgets/chiptandialog.h     [License: GPL (v2/3)]
A  +213  -0    kmymoney/plugins/kbanking/widgets/chiptandialog.ui

http://commits.kde.org/kmymoney/02469324b15674e4c205f69d9ba53e04e473449f

diff --git a/kmymoney/plugins/kbanking/CMakeLists.txt b/kmymoney/plugins/kbanking/CMakeLists.txt
index 17586f8..3112519 100644
--- a/kmymoney/plugins/kbanking/CMakeLists.txt
+++ b/kmymoney/plugins/kbanking/CMakeLists.txt
@@ -14,14 +14,16 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
 ADD_SUBDIRECTORY( dialogs )
 ADD_SUBDIRECTORY( views )
 ADD_SUBDIRECTORY( widgets )
+ADD_SUBDIRECTORY( qml )
 
 ########### next target ###############
 
-SET(kmm_kbanking_PART_SRCS 
+SET(kmm_kbanking_PART_SRCS
     mymoneybanking.cpp
     banking.cpp
     aqbankingkmmoperators.cpp
     gwenhywfarqtoperators.cpp
+    gwenkdegui.cpp
     )
 
 SET(kmm_kbanking_HEADERS
@@ -39,6 +41,7 @@ TARGET_LINK_LIBRARIES(kmm_kbanking
                       kmm_widgets
                       kmm_plugin
                       ${KDE4_KDEUI_LIBS}
+                      ${QT_QTDECLARATIVE_LIBRARY}
                       ${GWENHYWFAR_LIBRARIES}
                       ${AQBANKING_LIBRARIES}
                       ${GMP_LIBRARIES}
@@ -56,4 +59,3 @@ INSTALL(TARGETS kmm_kbanking
 
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/kmm_kbanking.desktop
         DESTINATION ${SERVICES_INSTALL_DIR})
-
diff --git a/kmymoney/plugins/kbanking/gwenkdegui.cpp b/kmymoney/plugins/kbanking/gwenkdegui.cpp
new file mode 100644
index 0000000..1b4acd8
--- /dev/null
+++ b/kmymoney/plugins/kbanking/gwenkdegui.cpp
@@ -0,0 +1,86 @@
+/*
+ * A gwenhywfar gui for aqbanking using KDE widgets
+ * Copyright 2014  Christian David <c.david at christian-david.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "gwenkdegui.h"
+
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QRegExp>
+
+#include <QDebug>
+#include <QEventLoop>
+#include <unistd.h>
+#include <KUrl>
+
+#include "widgets/chiptandialog.h"
+
+gwenKdeGui::gwenKdeGui()
+ : QT4_Gui()
+{
+
+}
+
+gwenKdeGui::~gwenKdeGui()
+{
+
+}
+
+int gwenKdeGui::getPassword(uint32_t flags, const char* token, const char* title, const char* text, char* buffer, int minLen, int maxLen, uint32_t guiid)
+{
+  if ((flags & GWEN_GUI_INPUT_FLAGS_OPTICAL) && text && *text) {
+    // Optical Tan (chipTan)
+    
+    // Extract text to display and hhd code
+    QString infoText = QString::fromUtf8(text);
+    QRegExp hhdRegExp = QRegExp("^(.*)\\$OBEGIN\\$(.*)\\$OEND\\$(.*)$", Qt::CaseInsensitive);
+    hhdRegExp.setMinimal(true);
+    hhdRegExp.indexIn(infoText);
+    QStringList captured = hhdRegExp.capturedTexts();
+    QString hhdCode = captured.at(2);
+    infoText = captured.at(1) + captured.at(3);
+    
+    chipTanDialog dialog(getParentWidget());
+    dialog.setInfoText(infoText);
+    dialog.setHhdCode(hhdCode);
+    dialog.setTanLimits(minLen, maxLen);
+    //! @todo save flicker field width
+    //dialog.setFlickerFieldWidth( dialog.flickerFieldWidth() );
+    
+    int rv = dialog.exec();
+
+    if (rv == chipTanDialog::Rejected)
+      return GWEN_ERROR_USER_ABORTED;
+    else if (rv == chipTanDialog::InternalError)
+      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( "Recieved Tan with incorrect length by ui." );
+    return GWEN_ERROR_INTERNAL;
+  }
+  
+  return QT4_Gui::getPassword(flags, token, title, text, buffer, minLen, maxLen, guiid);
+}
diff --git a/kmymoney/plugins/kbanking/gwenkdegui.h b/kmymoney/plugins/kbanking/gwenkdegui.h
new file mode 100644
index 0000000..b1027a0
--- /dev/null
+++ b/kmymoney/plugins/kbanking/gwenkdegui.h
@@ -0,0 +1,78 @@
+/*
+ * A gwenhywfar gui for aqbanking using KDE widgets
+ * Copyright 2014  Christian David <c.david at christian-david.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#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,
+                          uint32_t guiid);
+};
+
+#include <QObject>
+/**
+ * @brief Helper class which is reciever 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/mymoneybanking.cpp b/kmymoney/plugins/kbanking/mymoneybanking.cpp
index 3c63d3a..bfcdd5d 100644
--- a/kmymoney/plugins/kbanking/mymoneybanking.cpp
+++ b/kmymoney/plugins/kbanking/mymoneybanking.cpp
@@ -70,7 +70,6 @@
 #include <aqbanking/transactionlimits.h>
 #include <gwenhywfar/logger.h>
 #include <gwenhywfar/debug.h>
-#include <gwen-gui-qt4/qt4_gui.hpp>
 
 // ----------------------------------------------------------------------------
 // Project Includes
@@ -87,6 +86,7 @@
 #include "kmymoneyview.h"
 #include "kbpickstartdate.h"
 
+#include "gwenkdegui.h"
 #include "gwenhywfarqtoperators.h"
 #include "aqbankingqtoperators.h"
 #include "aqbankingkmmoperators.h"
@@ -146,7 +146,7 @@ KBankingPlugin::KBankingPlugin(QObject *parent, const QVariantList&) :
   connect(d->passwordCacheTimer, SIGNAL(timeout()), this, SLOT(slotClearPasswordCache()));
 
   if (m_kbanking) {
-    QT4_Gui *gui;
+    gwenKdeGui *gui;
 
     if (AB_Banking_HasConf4(m_kbanking->getCInterface())) {
       qDebug("KBankingPlugin: No AqB4 config found.");
@@ -162,7 +162,7 @@ KBankingPlugin::KBankingPlugin(QObject *parent, const QVariantList&) :
       }
     }
 
-    gui = new QT4_Gui();
+    gui = new gwenKdeGui();
     GWEN_Gui_SetGui(gui->getCInterface());
     GWEN_Logger_SetLevel(0, GWEN_LoggerLevel_Info);
     GWEN_Logger_SetLevel(AQBANKING_LOGDOMAIN, GWEN_LoggerLevel_Debug);
diff --git a/kmymoney/plugins/kbanking/qml/CMakeLists.txt b/kmymoney/plugins/kbanking/qml/CMakeLists.txt
new file mode 100644
index 0000000..2b1db43
--- /dev/null
+++ b/kmymoney/plugins/kbanking/qml/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory( chipTan )
\ No newline at end of file
diff --git a/kmymoney/plugins/kbanking/qml/chipTan/CMakeLists.txt b/kmymoney/plugins/kbanking/qml/chipTan/CMakeLists.txt
new file mode 100644
index 0000000..bed6abe
--- /dev/null
+++ b/kmymoney/plugins/kbanking/qml/chipTan/CMakeLists.txt
@@ -0,0 +1,7 @@
+set( kbanking_qml_files
+  chipTan.js
+  ChipTan.qml
+  ChipTanFlickerField.qml
+)
+
+install(FILES ${kbanking_qml_files} DESTINATION ${DATA_INSTALL_DIR}/kmm_kbanking/qml/chipTan/)
\ No newline at end of file
diff --git a/kmymoney/plugins/kbanking/qml/chipTan/ChipTan.qml b/kmymoney/plugins/kbanking/qml/chipTan/ChipTan.qml
new file mode 100644
index 0000000..5949f1e
--- /dev/null
+++ b/kmymoney/plugins/kbanking/qml/chipTan/ChipTan.qml
@@ -0,0 +1,165 @@
+/*
+ * A tan input dialog for optical chipTan used in online banking
+ * Copyright 2014  Christian David <c.david at christian-david.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import QtQuick 1.1
+
+Rectangle {
+    width: 360
+    height: 300
+    id: "chipTan"
+
+    color: "#00FFFFFF"
+    
+    property string transferData: ""
+    
+    function setFlickerFieldWidth( width )
+    {
+      chipTanFlickerField.userWidth = width;
+    }
+    
+    function flickerFieldWidth()
+    {
+      return chipTanFlickerField.width
+    }
+
+    function enlargeFlickerField()
+    {
+      chipTanFlickerField.userWidth = chipTanFlickerField.width+10
+    }
+    
+    function reduceFlickerField()
+    {
+      chipTanFlickerField.userWidth = chipTanFlickerField.width-10
+    }
+    
+    function accelerateTransmission()
+    {
+      chipTanFlickerField.userTaktLength =  chipTanFlickerField.taktLengt - 20
+    }
+    
+    function decelerateTransmission()
+    {
+      chipTanFlickerField.userTaktLength =  chipTanFlickerField.taktLengt + 20
+    }
+    
+    /*
+    // Toolbar
+    Rectangle {
+        id: toolbar
+
+        anchors {
+            margins: 10
+            left: parent.left
+        }
+
+        width: buttonRow.width+10
+        height: buttonRow.height+10
+
+        // Toolbar
+        Row {
+            id: buttonRow
+            spacing: 5
+
+            anchors {
+                verticalCenter: parent.verticalCenter
+                left: parent.left
+            }
+
+            Image {
+                source: "/usr/share/icons/default.kde4/22x22/actions/zoom-in.png"
+                MouseArea {
+                    anchors.fill: parent
+                    onClicked: chipTanFlickerField.userWidth = chipTanFlickerField.width+10
+                }
+            }
+
+            Image {
+                source: "/usr/share/icons/default.kde4/22x22/actions/zoom-out.png"
+                MouseArea {
+                    anchors.fill: parent
+                    onClicked: chipTanFlickerField.userWidth = chipTanFlickerField.width-10
+                }
+            }
+
+            Image {
+                source: "/usr/share/icons/default.kde4/22x22/actions/media-playback-start.png"
+                MouseArea {
+                    anchors.fill: parent
+                    onClicked: chipTanFlickerField.userTaktLength =  chipTanFlickerField.taktLengt + 20
+                }
+            }
+
+            Image {
+                source: "/usr/share/icons/default.kde4/22x22/actions/media-seek-forward.png"
+                MouseArea {
+                    anchors.fill: parent
+                    onClicked: chipTanFlickerField.userTaktLength =  chipTanFlickerField.taktLengt - 20
+                }
+            }
+        }
+    }
+    */
+    ChipTanFlickerField {
+        id: chipTanFlickerField
+        anchors {
+            left: parent.left
+            verticalCenter: parent.verticalCenter
+        }
+
+        transferData: chipTan.transferData
+
+        property int userWidth: parent.width
+        width: Math.max( userWidth, minimumWidth )
+
+        property int userTaktLength: 100
+        taktLengt: Math.min(Math.max(10, userTaktLength), 2000)
+
+        MouseArea {
+            id: resizeMouseArea
+            anchors.fill: parent
+        }
+        
+        states:
+            State {
+                name: "resizeWidth"
+                when: resizeMouseArea.pressed
+                extend: "paused"
+
+                StateChangeScript {
+                    script: {
+                        resizePropertyChanger.oldWidth = chipTanFlickerField.width
+                        resizePropertyChanger.mouseStartPosition = resizeMouseArea.mouseX
+                    }
+                }
+
+                PropertyChanges {
+                    id: resizePropertyChanger
+                    target: chipTanFlickerField
+                    restoreEntryValues: false
+                    property real oldWidth: 0
+                    property real mouseStartPosition: 0
+
+                    userWidth: resizePropertyChanger.oldWidth + resizeMouseArea.mouseX - resizePropertyChanger.mouseStartPosition
+                }
+            }
+    }
+}
diff --git a/kmymoney/plugins/kbanking/qml/chipTan/ChipTanFlickerField.qml b/kmymoney/plugins/kbanking/qml/chipTan/ChipTanFlickerField.qml
new file mode 100644
index 0000000..3238f85
--- /dev/null
+++ b/kmymoney/plugins/kbanking/qml/chipTan/ChipTanFlickerField.qml
@@ -0,0 +1,140 @@
+/*
+ * A tan input dialog for optical chipTan used in online banking
+ * Copyright 2014  Christian David <c.david at christian-david.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+import QtQuick 1.1
+import "chipTan.js" as Logic
+
+Rectangle {
+    id: chipTanFlickerField
+
+    /** You should set the width only, hight is set accordingly */
+    width: 260
+
+    /** @brief Duration of each takt in ms */
+    property int taktLengt: 50
+
+    /** @brief suggested minumum with of this component */
+    property int minimumWidth: 100
+
+    /** @brief Data to transfer as HEX code in a string */
+    property string transferData: ""
+
+    color: "black"
+
+    height: 0.6*width
+    radius: 0.1*width
+
+    border {
+        width: 0.01*width
+        color: "red"
+    }
+
+    function toggleStart()
+    {
+        if (state == "")
+            state = "paused"
+        else
+            state = ""
+    }
+
+
+    Row {
+        id: flickerFields
+        height: 0.7*parent.height
+        anchors.centerIn: parent
+
+        property int fieldWidth: 0.15*parent.width
+        spacing: 0.1*fieldWidth
+
+        Repeater {
+            model: 5
+
+            Rectangle {
+                width: flickerFields.fieldWidth
+                property color colorOn: "white"
+                property color colorOff: "black"
+                property color colorStopped: colorOn
+
+                color: colorStopped
+                height: parent.height
+                anchors.verticalCenter: parent.verticalCenter
+
+                MouseArea {
+                    anchors.fill: parent
+                    onClicked: Logic.timerTriggered(flickerFields)
+                }
+            }
+        }
+    }
+
+    Timer {
+        id: timer
+        interval: parent.taktLengt
+        repeat: true
+        running: true
+        onTriggered: Logic.timerTriggered(flickerFields)
+        onRunningChanged: Logic.timerStarted(chipTanFlickerField.transferData, flickerFields )
+    }
+    
+    onTransferDataChanged: {
+      if ( timer.running == true )  {
+        timer.stop()
+        timer.start()
+      }
+    }
+
+    states: [
+        State {
+            name: "paused"
+
+            PropertyChanges {
+                target: flickerFields.children[0]
+                color: colorStopped
+            }
+
+            PropertyChanges {
+                target: flickerFields.children[1]
+                color: colorStopped
+            }
+
+            PropertyChanges {
+                target: flickerFields.children[2]
+                color: colorStopped
+            }
+
+            PropertyChanges {
+                target: flickerFields.children[3]
+                color: colorStopped
+            }
+
+            PropertyChanges {
+                target: flickerFields.children[4]
+                color: colorStopped
+            }
+            
+            PropertyChanges {
+                target: timer
+                running: false
+            }
+        }
+    ]
+}
diff --git a/kmymoney/plugins/kbanking/qml/chipTan/chipTan.js b/kmymoney/plugins/kbanking/qml/chipTan/chipTan.js
new file mode 100644
index 0000000..6432bb9
--- /dev/null
+++ b/kmymoney/plugins/kbanking/qml/chipTan/chipTan.js
@@ -0,0 +1,88 @@
+/*
+ * A tan input dialog for optical chipTan used in online banking
+ * Copyright 2014  Christian David <c.david at christian-david.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+var transmitCode = []
+
+var currentIndex = 0
+var currentIntervalStarted = true
+
+function checkData(dataString)
+{
+  return true;
+}
+
+function timerStarted( data, parentItem )
+{
+  // Startcode
+  transmitCode = [ 0xF, 0x0, 0xF, 0xF ]
+
+  // Set Code (half-bytes are switched)
+  for (var i = 0; i < data.length; i+=2) {
+      transmitCode.push(parseInt(data[i+1], 16))
+      transmitCode.push(parseInt(data[i], 16))
+  }
+}
+
+function charToHex( char )
+{
+  switch(data[i]) {
+  case '0': return 0x0
+  case '1': return 0x1
+  case '2': return 0x2
+  case '3': return 0x3
+  case '4': return 0x4
+  case '5': return 0x5
+  case '6': return 0x6
+  case '7': return 0x7
+  case '8': return 0x8
+  case '9': return 0x9
+  case 'A': return 0xA
+  case 'B': return 0xB
+  case 'C': return 0xC
+  case 'D': return 0xD
+  case 'E': return 0xE
+  case 'F': return 0xF
+  }
+}
+
+function timerTriggered( parentItem )
+{
+  var colorOn = parentItem.children[0].colorOn
+  var colorOff = parentItem.children[0].colorOff
+
+  if (currentIntervalStarted == true) {
+      parentItem.children[0].color = colorOff
+      currentIntervalStarted = false;
+      return;
+  }
+
+  ++currentIndex
+  currentIntervalStarted = true
+  if (currentIndex >= transmitCode.length)
+      currentIndex = 0
+
+  parentItem.children[0].color = colorOn
+  parentItem.children[1].color = (transmitCode[currentIndex] & 1) ? colorOn : colorOff
+  parentItem.children[2].color = (transmitCode[currentIndex] & 2) ? colorOn : colorOff
+  parentItem.children[3].color = (transmitCode[currentIndex] & 4) ? colorOn : colorOff
+  parentItem.children[4].color = (transmitCode[currentIndex] & 8) ? colorOn : colorOff
+}
diff --git a/kmymoney/plugins/kbanking/views/kbjobview.cpp b/kmymoney/plugins/kbanking/views/kbjobview.cpp
index 5482fe1..2305b09 100644
--- a/kmymoney/plugins/kbanking/views/kbjobview.cpp
+++ b/kmymoney/plugins/kbanking/views/kbjobview.cpp
@@ -97,8 +97,25 @@ KBJobView::KBJobView(KMyMoneyBanking *kb,
 
   d->ui.dequeueButton->setEnabled(false);
   d->ui.executeButton->setEnabled(false);
+  
+#ifdef CHIPTAN_INPUT_TEST
+  KPushButton* chipTanButton = new KPushButton("Open ChipTan Input", this);
+  d->ui.buttonLayout->addWidget(chipTanButton);
+  connect(chipTanButton, SIGNAL(clicked()), this, SLOT(slotOpenChipTanInput()));
+#endif
 }
 
+#ifdef CHIPTAN_INPUT_TEST
+#include "chiptandialog.h"
+void KBJobView::slotOpenChipTanInput()
+{
+  chipTanDialog dialog;
+  dialog.setHhdCode("1042481200");
+  dialog.setInfoText("This function is for debug purposes only. You can enter a tan which is between three and six characters long.");
+  dialog.setTanLimits(3,6);
+  dialog.exec();
+}
+#endif
 
 
 KBJobView::~KBJobView()
diff --git a/kmymoney/plugins/kbanking/views/kbjobview.h b/kmymoney/plugins/kbanking/views/kbjobview.h
index 32a3522..78fcf59 100644
--- a/kmymoney/plugins/kbanking/views/kbjobview.h
+++ b/kmymoney/plugins/kbanking/views/kbjobview.h
@@ -31,6 +31,8 @@ class KBankingPlugin;
 #include "kbjoblist.h"
 #include "mymoneybanking.h"
 
+/* For easier debugging and testing this makro adds a button to open the chiptan dialog */
+#define CHIPTAN_INPUT_TEST
 
 class KBJobView: public QWidget
 {
@@ -59,6 +61,9 @@ protected slots:
   void slotExecute();
   void slotDequeue();
   void slotSelectionChanged();
+#ifdef CHIPTAN_INPUT_TEST
+  void slotOpenChipTanInput();
+#endif
 };
 
 
diff --git a/kmymoney/plugins/kbanking/views/kbjobview.ui b/kmymoney/plugins/kbanking/views/kbjobview.ui
index e1d8a5d..f3dda37 100644
--- a/kmymoney/plugins/kbanking/views/kbjobview.ui
+++ b/kmymoney/plugins/kbanking/views/kbjobview.ui
@@ -22,7 +22,7 @@
     </widget>
    </item>
    <item>
-    <layout class="QVBoxLayout">
+    <layout class="QVBoxLayout" name="buttonLayout">
      <item>
       <widget class="KPushButton" name="dequeueButton">
        <property name="enabled">
diff --git a/kmymoney/plugins/kbanking/widgets/CMakeLists.txt b/kmymoney/plugins/kbanking/widgets/CMakeLists.txt
index 2e0ba79..4d3554e 100644
--- a/kmymoney/plugins/kbanking/widgets/CMakeLists.txt
+++ b/kmymoney/plugins/kbanking/widgets/CMakeLists.txt
@@ -1,9 +1,10 @@
 
 ########### next target ###############
 
-SET(kmm_kbanking_widgets_la_SOURCES
+SET(kmm_kbanking_widgets_la_SOURCES 
+    chiptandialog.cpp
     kbaccountlist.cpp
     kbjoblist.cpp
     )
-
+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
new file mode 100644
index 0000000..cda42ce
--- /dev/null
+++ b/kmymoney/plugins/kbanking/widgets/chiptandialog.cpp
@@ -0,0 +1,148 @@
+/*
+ * A tan input dialog for optical chipTan used in online banking
+ * Copyright 2014  Christian David <c.david at christian-david.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "chiptandialog.h"
+#include "ui_chiptandialog.h"
+
+// Qt Includes
+#include <QtCore/QMetaObject>
+#include <QtDeclarative/QDeclarativeView>
+#include <QGraphicsObject>
+#include <QPushButton>
+
+// KDE Includes
+#include <KStandardDirs>
+
+// Prject Includes
+
+
+chipTanDialog::chipTanDialog(QWidget* parent)
+  : QDialog(parent),
+  m_tan( "" ),
+  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)));
+  
+  ui->declarativeView->setSource(KGlobal::dirs()->findResource("data", QString("kmm_kbanking/qml/chipTan/ChipTan.qml")));
+  
+  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()));
+  
+  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(QString text)
+{
+  ui->infoText->setText(text);
+}
+
+QString chipTanDialog::infoText()
+{
+  return ui->infoText->toPlainText();
+}
+
+void chipTanDialog::setHhdCode(QString code)
+{
+  setRootObjectProperty("transferData", code);
+}
+
+QString chipTanDialog::hhdCode()
+{
+  QGraphicsObject* rootObject = ui->declarativeView->rootObject();
+  if (rootObject)
+    return rootObject->property("transferData").toString();
+}
+
+QString chipTanDialog::tan()
+{
+  return m_tan;
+}
+
+void chipTanDialog::setTanLimits(int minLength, int maxLength)
+{
+  ui->tanInput->setValidator( new QRegExpValidator(QRegExp(QString("\\d{%1,%2}").arg(minLength).arg(maxLength)), ui->tanInput) );
+}
+
+void chipTanDialog::setFlickerFieldWidth(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::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/chiptandialog.h b/kmymoney/plugins/kbanking/widgets/chiptandialog.h
new file mode 100644
index 0000000..83c010f
--- /dev/null
+++ b/kmymoney/plugins/kbanking/widgets/chiptandialog.h
@@ -0,0 +1,73 @@
+/*
+ * A tan input dialog for optical chipTan used in online banking
+ * Copyright 2014  Christian David <c.david at christian-david.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef CHIPTANDIALOG_H
+#define CHIPTANDIALOG_H
+
+#include <QtGui/QDialog>
+#include <QtGui/QDialog>
+
+namespace Ui
+{
+class chipTanDialog;
+}
+
+class chipTanDialog : public QDialog
+{
+  Q_OBJECT
+  Q_PROPERTY(QString infoText READ infoText() WRITE setInfoText)
+  Q_PROPERTY(QString hhdCode READ hhdCode() WRITE setHhdCode)
+  Q_PROPERTY(int flickerFieldWidth READ flickerFieldWidth WRITE setFlickerFieldWidth)
+
+public:
+  chipTanDialog(QWidget* parent = 0);
+  ~chipTanDialog();
+  
+  enum Result { Accepted=0, Rejected, InternalError };
+  
+  QString infoText();
+  QString hhdCode();
+  QString tan();
+  int flickerFieldWidth();
+  
+public slots:
+  void accept();
+  void reject();
+  
+  void setInfoText(QString);
+  void setHhdCode(QString);
+  
+  void setTanLimits(int minLength, int maxLength);
+  void setFlickerFieldWidth(int width);
+
+private slots:
+  void tanInputChanged(const QString&);
+  
+private:
+  Ui::chipTanDialog* ui;
+  QString m_tan;
+  bool m_accepted;
+  
+  void setRootObjectProperty(const char* property, const QVariant& value);
+  };
+
+#endif // CHIPTANDIALOG_H
diff --git a/kmymoney/plugins/kbanking/widgets/chiptandialog.ui b/kmymoney/plugins/kbanking/widgets/chiptandialog.ui
new file mode 100644
index 0000000..c24c3fd
--- /dev/null
+++ b/kmymoney/plugins/kbanking/widgets/chiptandialog.ui
@@ -0,0 +1,213 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>chipTanDialog</class>
+ <widget class="QWidget" name="chipTanDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>656</width>
+    <height>405</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Order confirmation</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0">
+      <layout class="QHBoxLayout" name="horizontalLayout_2">
+       <item>
+        <widget class="QToolButton" name="reduceButton">
+         <property name="toolTip">
+          <string>Reduce optical tan area in size</string>
+         </property>
+         <property name="text">
+          <string>Reduce</string>
+         </property>
+         <property name="icon">
+          <iconset theme="zoom-out">
+           <normaloff/>
+          </iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="enlargeButton">
+         <property name="toolTip">
+          <string>Enlarge optical tan field</string>
+         </property>
+         <property name="text">
+          <string>Enlarge</string>
+         </property>
+         <property name="icon">
+          <iconset theme="zoom-in">
+           <normaloff/>
+          </iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_2">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeType">
+          <enum>QSizePolicy::Minimum</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>5</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item>
+        <widget class="QToolButton" name="decelerateButton">
+         <property name="toolTip">
+          <string/>
+         </property>
+         <property name="text">
+          <string>Decelerate</string>
+         </property>
+         <property name="icon">
+          <iconset theme="media-seek-backward">
+           <normaloff/>
+          </iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="accelerateButton">
+         <property name="text">
+          <string>Accelerate</string>
+         </property>
+         <property name="icon">
+          <iconset theme="media-seek-forward">
+           <normaloff/>
+          </iconset>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <spacer name="horizontalSpacer_3">
+         <property name="orientation">
+          <enum>Qt::Horizontal</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>40</width>
+           <height>20</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </item>
+     <item row="0" column="1" rowspan="2">
+      <widget class="QTextBrowser" name="infoText">
+       <property name="styleSheet">
+        <string notr="true">background:transparent</string>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::NoFrame</enum>
+       </property>
+       <property name="frameShadow">
+        <enum>QFrame::Plain</enum>
+       </property>
+       <property name="readOnly">
+        <bool>true</bool>
+       </property>
+       <property name="acceptRichText">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="0">
+      <widget class="QDeclarativeView" name="declarativeView">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="minimumSize">
+        <size>
+         <width>360</width>
+         <height>300</height>
+        </size>
+       </property>
+       <property name="styleSheet">
+        <string notr="true">background:transparent</string>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="label">
+       <property name="text">
+        <string>To confirm this order enter the tan displayed by your generator</string>
+       </property>
+       <property name="buddy">
+        <cstring>tanInput</cstring>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>40</width>
+         <height>20</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+     <item>
+      <widget class="KLineEdit" name="tanInput"/>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="KDialogButtonBox" name="dialogButtonBox">
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>QDeclarativeView</class>
+   <extends>QGraphicsView</extends>
+   <header>QtDeclarative/QDeclarativeView</header>
+  </customwidget>
+  <customwidget>
+   <class>KDialogButtonBox</class>
+   <extends>QDialogButtonBox</extends>
+   <header>kdialogbuttonbox.h</header>
+  </customwidget>
+  <customwidget>
+   <class>KLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>klineedit.h</header>
+  </customwidget>
+ </customwidgets>
+ <tabstops>
+  <tabstop>tanInput</tabstop>
+  <tabstop>infoText</tabstop>
+  <tabstop>declarativeView</tabstop>
+  <tabstop>dialogButtonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>


More information about the kde-doc-english mailing list