Merge Christian Wehling's 'gnucash-flicker' into maint.

This commit is contained in:
John Ralls 2020-12-12 17:00:47 -08:00
commit 2b01bde2b6
8 changed files with 739 additions and 25 deletions

View File

@ -13,6 +13,7 @@ set (aqbanking_SOURCES
gnc-ab-transfer.c
gnc-ab-utils.c
gnc-file-aqb-import.c
gnc-flicker-gui.c
gnc-gwen-gui.c
gnc-plugin-aqbanking.c
gncmod-aqbanking.c
@ -31,6 +32,7 @@ set (aqbanking_noinst_HEADERS
gnc-ab-transfer.h
gnc-ab-utils.h
gnc-file-aqb-import.h
gnc-flicker-gui.h
gnc-gwen-gui.h
gnc-plugin-aqbanking.h
)

View File

@ -634,14 +634,90 @@
</packing>
</child>
<child>
<object class="GtkImage" id="optical_challenge">
<property name="name">optical_challenge</property>
<object class="GtkBox" id="flicker_hbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">7</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Bar_width</property>
<property name="xalign">0.7</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">spin_barwidth</property>
<attributes>
<attribute name="gravity" value="west"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spin_barwidth">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip-text" translatable="yes" comments="TAN generator with flicker interface common in DE only">Setting the bar width, adapting to the size of the TAN generator.</property>
<property name="numeric">True</property>
<property name="update_policy">if-valid</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Delay</property>
<property name="xalign">0.7</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">spin_delay</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spin_delay">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip-text" translatable="yes" comments="TAN generator with flicker interface common in DE only">Setting the delay time, with small values the flicker graphic is repeated faster.</property>
<property name="numeric">True</property>
<property name="update_policy">if-valid</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="flicker_marker">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="icon_name">image-missing</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">False</property>
@ -649,6 +725,48 @@
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImage" id="optical_challenge">
<property name="name">optical_challenge</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="icon_name">image-missing</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkDrawingArea" id="flicker_challenge">
<property name="visible">True</property>
<property name="app_paintable">True</property>
<property name="tooltip_text" translatable="yes" comments="TAN generator with flicker interface common in DE only">Hold the TAN generator in front of the animated graphic. The markings (triangles) on the graphic must match those on the TAN generator.</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
@ -736,7 +854,7 @@
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
<property name="position">4</property>
</packing>
</child>
</object>

View File

@ -0,0 +1,445 @@
/*
* gnc-flicker-gui.c --
*
* 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
/**
* @internal
* @file gnc-flicker-gui.c
* @brief GUI callbacks for Flicker and ChipTAN(optisch)
* @author Copyright (C) 2020 Christian Wehling <christian.wehling@web.de>
*/
#include <config.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "dialog-utils.h"
#include "gnc-flicker-gui.h"
#include "gnc-state.h"
#include "gnc-ui.h"
#define GNC_PREFS_GROUP "dialogs.flicker"
#define GNC_STATE_SECTION "Flicker"
#define STATE_KEY_BAR_WIDTH "barwidth"
#define STATE_KEY_DELAY "delay"
#define BAR_WIDTH 44 /* Width of the flicker bars */
#define BAR_HEIGHT 200 /* Height of the flicker bars */
#define MARGIN 12 /* Distance between the flicker bars */
#define DELAY 50 /* Pause between the flickering painting */
static char *flicker_data (char const *challenge);
static gboolean time_handler (GtkWidget *widget);
static void do_marker_drawing (cairo_t *cr);
static void draw_bit (cairo_t *cr, _Bool bit, int i);
static void do_flicker_drawing (GtkWidget *widget, cairo_t *cr);
static void do_flicker_load_state (GtkWidget *dialog);
static void do_flicker_store_state (GtkWidget *dialog);
static gboolean on_flicker_challenge_draw (GtkWidget *widget, cairo_t *cr,
gpointer user_data);
static void on_flicker_challenge_map (GtkWidget *widget);
static void on_flicker_challenge_destroy (GtkWidget *widget, gpointer user_data);
static gboolean on_flicker_marker_draw (GtkWidget *widget, cairo_t *cr,
gpointer user_data);
static void on_flicker_marker_map (GtkWidget *widget);
static void on_spin_barwidth_value_changed (GtkSpinButton *spin, GtkWidget *widget);
static void on_spin_delay_value_changed (GtkSpinButton *spin, GtkWidget *widget);
static void on_dialog_destroy (GtkWidget *dialog, gpointer user_data);
/* structured data for the flicker variables */
struct Flickerdraw {
const char *challenge;
guint challenge_length;
guint margin; /* Distance between bars */
guint barwidth; /* Bar width */
guint barheight; /* Bar height */
guint x_barpos; /* x-value for the position of the bar */
guint y_barpos; /* y-value for the position of the bar */
guint x_drawpos; /* x-value of the first painting position */
guint y_drawpos; /* y-value of the first painting position */
guint height; /* Height of the drawing area */
guint width; /* Width of the drawing area */
guint delay; /* Waiting time between frames in milliseconds */
guint halfbyteid;
guint clock;
guint interval;
gboolean change_interval;
};
static struct Flickerdraw flickerdraw;
static GncFlickerGui *flickergui = NULL;
static _Bool bitarray[255][5];
/* this function will return number corresponding 0,1,2..,9,A,B,C,D,E,F */
static uint
get_num (const char ch)
{
int num =0;
if (ch >= '0' && ch <= '9')
num = ch - 0x30;
else
{
switch (ch)
{
case 'A': case 'a': num = 10; break;
case 'B': case 'b': num = 11; break;
case 'C': case 'c': num = 12; break;
case 'D': case 'd': num = 13; break;
case 'E': case 'e': num = 14; break;
case 'F': case 'f': num = 15; break;
default: num = 0;
}
}
/* The bank challenge has been verified by Aqbanking,
* so I assume that no error can occur. */
return num;
}
/* convert the bank challenge into the 5 bits for the flicker data */
static char
*flicker_data (const char *challenge)
{
/* bitfield is a clock bit and a 4-bit code with the bits reversed
(bit 1 is the least significant and bit 4 the most
so 0x1 is 1000 and 0x8 is 0001) */
static const _Bool bits[16][5] =
{
{0, 0, 0, 0, 0}, {0, 1, 0, 0, 0}, {0, 0, 1, 0, 0}, {0, 1, 1, 0, 0},
{0, 0, 0, 1, 0}, {0, 1, 0, 1, 0}, {0, 0, 1, 1, 0}, {0, 1, 1, 1, 0},
{0, 0, 0, 0, 1}, {0, 1, 0, 0, 1}, {0, 0, 1, 0, 1}, {0, 1, 1, 0, 1},
{0, 0, 0, 1, 1}, {0, 1, 0, 1, 1}, {0, 0, 1, 1, 1}, {0, 1, 1, 1, 1}
};
/* prepend synchronization identifier */
const char pre[] = {'0', 'F', 'F', 'F'};
size_t len = sizeof (pre) + strlen (challenge) + 1;
char* code = (char*)malloc (len);
memcpy (code, pre, sizeof (pre));
memcpy (code + sizeof (pre), challenge, strlen (challenge));
/* Swap the position of the bits in pairs throughout the bank challenge
(low-order nibble first). */
for (uint i = 0; i < len - 1; i += 2)
{
u_int val1 = get_num (code[i]);
u_int val2 = get_num (code[i+1]);
memcpy (&bitarray[i], bits[val2], sizeof(bits[val2]));
memcpy (&bitarray[i+1], bits[val1], sizeof(bits[val1]));
}
return code;
}
/* A timer for redrawing the flickering painting, is started here and
* called up again when the "Delay" value is changed */
static gboolean
time_handler (GtkWidget *widget)
{
/* Change of waiting time */
if (flickerdraw.change_interval)
{
g_source_remove (flickerdraw.interval);
flickerdraw.interval = g_timeout_add (flickerdraw.delay,
(GSourceFunc) time_handler,
(gpointer) widget);
flickerdraw.change_interval = FALSE;
return FALSE;
}
gtk_widget_queue_draw (widget);
return TRUE;
}
/* Show the colored triangle as a pointer for the position of the TAN generator */
static void
do_marker_drawing (cairo_t *cr)
{
guint pos1;
guint pos2;
/* Initialize the drawing area to black */
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_paint (cr);
cairo_set_source_rgb (cr, 0.9, 0.1, 0.1);
/* draw the left triangle */
pos1 = flickerdraw.x_drawpos + flickerdraw.barwidth / 2;
cairo_move_to (cr, pos1, 20);
cairo_line_to (cr, pos1 + 10, 2);
cairo_line_to (cr, pos1 - 10, 2);
cairo_close_path (cr);
cairo_stroke_preserve (cr);
cairo_fill (cr);
/* draw the right triangle */
pos2 = flickerdraw.x_drawpos + 4 * flickerdraw.margin + 4 * flickerdraw.barwidth +
flickerdraw.barwidth / 2;
cairo_move_to (cr, pos2, 20);
cairo_line_to (cr, pos2 + 10, 2);
cairo_line_to (cr, pos2 - 10, 2);
cairo_close_path (cr);
cairo_stroke_preserve (cr);
cairo_fill (cr);
}
/* draws the 5 flickering bars of the bank data into the drawing area */
static void
draw_bit (cairo_t *cr, _Bool bit, int i)
{
if (bit & 1)
cairo_set_source_rgb (cr, 1, 1, 1);
else
cairo_set_source_rgb (cr, 0, 0, 0);
flickerdraw.x_barpos = flickerdraw.x_drawpos + i * flickerdraw.margin +
i * flickerdraw.barwidth;
cairo_rectangle (cr, flickerdraw.x_barpos, flickerdraw.y_barpos,
flickerdraw.barwidth, flickerdraw.barheight);
cairo_fill (cr);
}
/* Prepares the drawing area for the flicker graphic. */
static void
do_flicker_drawing (GtkWidget *widget, cairo_t *cr)
{
/* Always align the flicker display in the middle of the drawing area */
flickerdraw.width = gtk_widget_get_allocated_width (widget);
/* Start position of the first bar */
flickerdraw.x_drawpos = (flickerdraw.width - 4 * flickerdraw.margin -
5 * flickerdraw.barwidth) / 2;
/* Initialize the drawing area to black */
cairo_set_source_rgb (cr, 0, 0, 0);
cairo_paint (cr);
/* paint the flicker graphic */
bitarray[flickerdraw.halfbyteid][0] = flickerdraw.clock;
draw_bit (cr, flickerdraw.clock, 0);
for (int i = 1; i <= 4; i++)
draw_bit (cr, bitarray[flickerdraw.halfbyteid][i], i);
/* Each flicker point is drawn twice. Once with clock = 1 and once with clock = 0 */
if (!flickerdraw.clock)
{
flickerdraw.clock = 1;
flickerdraw.halfbyteid++;
if (flickerdraw.halfbyteid >= flickerdraw.challenge_length)
flickerdraw.halfbyteid = 0;
}
else if (flickerdraw.clock)
flickerdraw.clock = 0;
}
/* Load the state of the GUI (Size of the Dialog, Value of the Spinbutton) */
static void
do_flicker_load_state (GtkWidget *dialog)
{
/* Load the values in the spin button */
GKeyFile *state_file = gnc_state_get_current ();
if (g_key_file_has_key (state_file, GNC_STATE_SECTION, STATE_KEY_BAR_WIDTH, NULL))
flickerdraw.barwidth = g_key_file_get_integer (state_file,
GNC_STATE_SECTION,
STATE_KEY_BAR_WIDTH, NULL);
else
flickerdraw.barwidth = BAR_WIDTH;
if (g_key_file_has_key (state_file, GNC_STATE_SECTION, STATE_KEY_DELAY, NULL))
flickerdraw.delay = g_key_file_get_integer (state_file,
GNC_STATE_SECTION,
STATE_KEY_DELAY, NULL);
else
flickerdraw.delay = DELAY;
/* Load window size and position */
gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW (dialog),
gnc_ui_get_main_window (NULL));
}
/* Stores the state of the GUI (Size of the Dialog, Value of the Spinbutton) */
static void
do_flicker_store_state (GtkWidget *dialog)
{
/* Save the values in the spin button */
GKeyFile *state_file = gnc_state_get_current ();
if (flickerdraw.barwidth != BAR_WIDTH)
g_key_file_set_integer (state_file, GNC_STATE_SECTION,
STATE_KEY_BAR_WIDTH, flickerdraw.barwidth);
else if (g_key_file_has_key (state_file, GNC_STATE_SECTION,
STATE_KEY_BAR_WIDTH, NULL))
g_key_file_remove_key (state_file, GNC_STATE_SECTION,
STATE_KEY_BAR_WIDTH, NULL);
if (flickerdraw.delay != DELAY)
g_key_file_set_integer (state_file, GNC_STATE_SECTION,
STATE_KEY_DELAY, flickerdraw.delay);
else if (g_key_file_has_key (state_file, GNC_STATE_SECTION,
STATE_KEY_DELAY, NULL))
g_key_file_remove_key (state_file, GNC_STATE_SECTION,
STATE_KEY_DELAY, NULL);
/* Save window size and position */
gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW (dialog));
}
/* This signal is emitted when the drawing area "flicker challenge" is visible */
static void
on_flicker_challenge_map (GtkWidget *widget)
{
gchar *code = g_malloc (strlen (flickerdraw.challenge) + 4);
code = flicker_data (flickerdraw.challenge);
flickerdraw.challenge_length = strlen (code);
/* Set the height of the drawing area */
flickerdraw.height = flickerdraw.barheight + 2 * flickerdraw.y_barpos;
gtk_widget_set_size_request (widget, -1, flickerdraw.height);
/* Call up the time function and start the flicker display */
flickerdraw.interval = g_timeout_add (flickerdraw.delay,
(GSourceFunc) time_handler,
(gpointer) widget);
}
/* Initialize the drawingarea to black and paint the flickerchallenge */
static gboolean
on_flicker_challenge_draw (GtkWidget *widget, cairo_t *cr,
__attribute__((unused)) gpointer user_data)
{
do_flicker_drawing (widget, cr);
return FALSE;
}
/* called when the drawing area is destroyed */
static void
on_flicker_challenge_destroy (GtkWidget *widget,
__attribute__((unused)) gpointer user_data)
{
/* remove the timeout function */
g_source_remove (flickerdraw.interval);
}
/* Initialize the drawing area "flicker marker" in black and draw the marker for
* the position of the TAN-Generator */
static gboolean
on_flicker_marker_draw (__attribute__((unused)) GtkWidget *widget, cairo_t *cr,
__attribute__((unused)) gpointer data)
{
do_marker_drawing (cr);
return FALSE;
}
/* This signal is emitted when the drawing area "flicker marker" is visible */
static void
on_flicker_marker_map (GtkWidget *widget)
{
/* Set the height of the drawing area */
gtk_widget_set_size_request (widget, -1, flickerdraw.y_barpos);
}
/* The value for "Field width" has been changed on the spin button and the
* flicker display is updated */
static void
on_spin_barwidth_value_changed (GtkSpinButton *spin, GtkWidget *widget)
{
flickerdraw.barwidth = gtk_spin_button_get_value_as_int (spin);
flickerdraw.x_drawpos = (flickerdraw.width - 4 * flickerdraw.margin -
5 * flickerdraw.barwidth) / 2;
/* Moving the position triangles */
gtk_widget_queue_draw (widget);
}
/* The value for "waiting time" was changed on the spin button and
* the speed of the flickering display is updated */
static void
on_spin_delay_value_changed (GtkSpinButton *spin, GtkWidget *widget)
{
flickerdraw.delay = gtk_spin_button_get_value_as_int (spin);
flickerdraw.change_interval = TRUE;
time_handler (widget);
}
static void
on_dialog_destroy (GtkWidget *dialog, __attribute__((unused)) gpointer user_data)
{
/* Store window size and initial setting values */
do_flicker_store_state (dialog);
}
/* The widgets for the GUI are prepared and the first parameters are set */
void
ini_flicker_gui (const char *pChallenge, GncFlickerGui *gui)
{
/* Establish reference to the dialog widgets created in gnc_gwen_gui */
flickergui = gui;
/* Load window size and initial setting values */
do_flicker_load_state (GTK_WIDGET (flickergui->dialog));
/* Initialize application */
flickerdraw.barheight = BAR_HEIGHT;
flickerdraw.margin = MARGIN;
flickerdraw.y_barpos = 20; /* First painting position */
flickerdraw.halfbyteid = 0;
flickerdraw.clock = 1;
flickerdraw.challenge = pChallenge;
g_signal_connect (GTK_WINDOW (flickergui->dialog), "destroy",
G_CALLBACK (on_dialog_destroy), NULL);
g_signal_connect (GTK_WIDGET (flickergui->flicker_challenge), "map",
G_CALLBACK (on_flicker_challenge_map), NULL);
g_signal_connect (GTK_WIDGET (flickergui->flicker_challenge), "draw",
G_CALLBACK (on_flicker_challenge_draw), NULL);
g_signal_connect (GTK_WIDGET (flickergui->flicker_challenge), "destroy",
G_CALLBACK (on_flicker_challenge_destroy), NULL);
g_signal_connect (GTK_WIDGET (flickergui->flicker_marker), "map",
G_CALLBACK (on_flicker_marker_map), NULL);
g_signal_connect (GTK_WIDGET (flickergui->flicker_marker), "draw",
G_CALLBACK (on_flicker_marker_draw), NULL);
flickergui->adj_barwidth = gtk_adjustment_new (0.0, 10.0, 80.0, 1.0, 10.0, 0.0);
gtk_spin_button_set_adjustment (flickergui->spin_barwidth, flickergui->adj_barwidth);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (flickergui->spin_barwidth),
flickerdraw.barwidth);
g_signal_connect (GTK_WIDGET (flickergui->spin_barwidth), "value-changed",
G_CALLBACK (on_spin_barwidth_value_changed),
flickergui->flicker_marker);
gtk_widget_set_focus_on_click (GTK_WIDGET (flickergui->spin_barwidth), FALSE);
flickergui->adj_delay = gtk_adjustment_new (0.0, 10.0, 100.0, 10.0, 10.0, 0.0);
gtk_spin_button_set_adjustment (flickergui->spin_delay, flickergui->adj_delay);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (flickergui->spin_delay),
flickerdraw.delay);
g_signal_connect (GTK_WIDGET (flickergui->spin_delay), "value-changed",
G_CALLBACK (on_spin_delay_value_changed),
flickergui->flicker_challenge);
gtk_widget_set_focus_on_click (GTK_WIDGET (flickergui->spin_delay), FALSE);
gtk_widget_grab_focus (GTK_WIDGET (flickergui->input_entry));
}

View File

@ -0,0 +1,63 @@
/*
* gnc-flicker-gui.h
*
* 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, contact:
*
* Free Software Foundation Voice: +1-617-542-5942
* 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
* Boston, MA 02110-1301, USA gnu@gnu.org
*/
/**
* @addtogroup Import_Export
* @{
* @addtogroup AqBanking
* @{
* @file gnc-flicker-gui.h
* @brief GUI callbacks for Flicker and ChipTAN(optisch)
* @author Copyright (C) 2020 Christian Wehling <christian.wehling@web.de>
*/
#ifndef GNC_FLICKER_GUI_H
#define GNC_FLICKER_GUI_H
#include <gtk/gtk.h>
G_BEGIN_DECLS
// structured data for the GUI
typedef struct
{
GtkWidget *dialog;
GtkWidget *input_entry;
GtkWidget *flicker_challenge;
GtkWidget *flicker_marker;
GtkWidget *flicker_hbox;
GtkAdjustment *adj_barwidth;
GtkAdjustment *adj_delay;
GtkSpinButton *spin_barwidth;
GtkSpinButton *spin_delay;
} GncFlickerGui;
/**
* Initialize the dialog and drawing area
*
* @param pChallenge: The answer from the bank which is shown as a flickering picture
* @param gui: The structure of the Dialog-Widgets
*/
void ini_flicker_gui (const char *pChallenge, GncFlickerGui *gui);
G_END_DECLS
#endif /* GNC_FLICKER_GUI_H */

View File

@ -46,6 +46,8 @@
#include "gnc-plugin-aqbanking.h"
#include "qof.h"
#include "gnc-flicker-gui.h"
# define GNC_GWENHYWFAR_CB GWENHYWFAR_CB
#define GWEN_GUI_CM_CLASS "dialog-hbcilog"
@ -928,6 +930,9 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
GtkWidget *confirm_label;
GtkWidget *remember_pin_checkbutton;
GtkImage *optical_challenge;
static GncFlickerGui *flickergui = NULL;
const gchar *internal_input, *internal_confirmed;
gboolean confirm = (flags & GWEN_GUI_INPUT_FLAGS_CONFIRM) != 0;
gboolean is_tan = (flags & GWEN_GUI_INPUT_FLAGS_TAN) != 0;
@ -949,9 +954,46 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
remember_pin_checkbutton = GTK_WIDGET(gtk_builder_get_object (builder, "remember_pin"));
optical_challenge = GTK_IMAGE(gtk_builder_get_object (builder, "optical_challenge"));
gtk_widget_set_visible(GTK_WIDGET(optical_challenge), FALSE);
flickergui = g_slice_new(GncFlickerGui);
flickergui->flicker_challenge = GTK_WIDGET(gtk_builder_get_object(builder, "flicker_challenge"));
flickergui->flicker_marker = GTK_WIDGET(gtk_builder_get_object(builder, "flicker_marker"));
flickergui->flicker_hbox = GTK_WIDGET(gtk_builder_get_object(builder, "flicker_hbox"));
flickergui->spin_barwidth = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "spin_barwidth"));
flickergui->spin_delay = GTK_SPIN_BUTTON(gtk_builder_get_object(builder, "spin_delay"));
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_challenge), FALSE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_marker), FALSE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_hbox), FALSE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_barwidth), FALSE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_delay), FALSE);
#ifdef AQBANKING6
if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
if (g_strcmp0(mimeType,"text/x-flickercode") == 0 && pChallenge != NULL)
<<<<<<< Updated upstream
{
/* Chiptan Optic (aka Flicker) */
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_challenge), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_marker), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_hbox), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_barwidth), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_delay), TRUE);
}
else if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
{
=======
{
/* Chiptan Optic (aka Flicker) */
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_challenge), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_marker), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->flicker_hbox), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_barwidth), TRUE);
gtk_widget_set_visible(GTK_WIDGET(flickergui->spin_delay), TRUE);
}
else if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
{
>>>>>>> Stashed changes
/* Phototan or Chiptan QR */
gtk_widget_set_visible(GTK_WIDGET(optical_challenge), TRUE);
}
#endif
@ -969,6 +1011,7 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
if ((flags & (GWEN_GUI_INPUT_FLAGS_TAN | GWEN_GUI_INPUT_FLAGS_SHOW)) != 0)
{
gtk_widget_set_visible(input_entry, TRUE);
gtk_entry_set_visibility(GTK_ENTRY(input_entry), TRUE);
}
if (gui->dialog)
@ -993,9 +1036,22 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
}
#ifdef AQBANKING6
//if (optical_challenge)
if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
/* Optical challenge. Flickercode sets the mimetype to
* x-flickercode and doesn't set the challenge length */
if (g_strcmp0(mimeType,"text/x-flickercode") == 0 && pChallenge != NULL)
{
/* Chiptan Optic (aka Flicker) */
flickergui->dialog = dialog;
flickergui->input_entry = input_entry;
ini_flicker_gui(pChallenge, flickergui);
g_slice_free(GncFlickerGui, flickergui);
}
/* While phototan has multiple mimetypes and does set the
* challenge length. */
else if(mimeType != NULL && pChallenge != NULL && lChallenge > 0)
{
/* Phototan or Chiptan QR */
// convert PNG and load into widget
// TBD: check mimeType?
guchar *gudata = (guchar*)pChallenge;
@ -1019,7 +1075,7 @@ get_input(GncGWENGui *gui, guint32 flags, const gchar *title,
gtk_image_set_from_pixbuf(optical_challenge, pixbuf);
}
#endif
#endif
if (*input)
{
@ -1425,28 +1481,43 @@ getpassword_cb(GWEN_GUI *gwen_gui, guint32 flags, const gchar *token,
if(is_tan && methodId == GWEN_Gui_PasswordMethod_OpticalHHD)
{
/**
* TODO: How to handle Flicker code (use WebView and JS???)
*
* use GWEN_Gui_PasswordMethod_Mask to get the basic method id
* cf. gui/gui.h of gwenhywfar
*/
opticalMethodId=GWEN_DB_GetIntValue(methodParams, "tanMethodId", 0, AB_BANKING_TANMETHOD_TEXT);
switch(opticalMethodId)
{
case AB_BANKING_TANMETHOD_CHIPTAN:
break;
case AB_BANKING_TANMETHOD_CHIPTAN_OPTIC:
mimeType = "text/x-flickercode";
pChallenge = GWEN_DB_GetCharValue(methodParams, "challenge", 0, NULL);
if ((pChallenge == NULL) || (pChallenge[0] == '\0'))
{
/* empty flicker-data */
return GWEN_ERROR_NO_DATA;
}
break;
case AB_BANKING_TANMETHOD_CHIPTAN_USB:
/**
* ToDo: is this the same as CHIPTAN_OPTIC ?
*/
break;
case AB_BANKING_TANMETHOD_PHOTOTAN:
case AB_BANKING_TANMETHOD_CHIPTAN_QR:
/**
* image data is in methodParams
*/
mimeType=GWEN_DB_GetCharValue(methodParams, "mimeType", 0, NULL);
pChallenge=(const char*) GWEN_DB_GetBinValue(methodParams, "imageData", 0, NULL, 0, &lChallenge);
if (!(pChallenge && lChallenge)) {
/* empty optical data */
return GWEN_ERROR_NO_DATA;
}
break;
default:
break;
/**
* image data is in methodParams
*/
mimeType=GWEN_DB_GetCharValue(methodParams, "mimeType", 0, NULL);
pChallenge=(const char*) GWEN_DB_GetBinValue(methodParams, "imageData", 0, NULL, 0, &lChallenge);
if (!(pChallenge && lChallenge))
{
/* empty optical data */
return GWEN_ERROR_NO_DATA;
}
break;
default:
break;
}
}
#endif

View File

@ -1,8 +1,8 @@
if (WITH_AQBANKING)
set(aqb_GSCHEMA org.gnucash.dialogs.import.hbci.gschema.xml)
set(aqb_GSCHEMA org.gnucash.dialogs.import.hbci.gschema.xml org.gnucash.dialogs.flicker.gschema.xml)
add_gschema_targets("${aqb_GSCHEMA}")
endif()
set_dist_list(aqbanking_gschema_DIST CMakeLists.txt org.gnucash.dialogs.import.hbci.gschema.xml.in)
set_dist_list(aqbanking_gschema_DIST CMakeLists.txt org.gnucash.dialogs.import.hbci.gschema.xml.in org.gnucash.dialogs.flicker.gschema.xml.in)

View File

@ -0,0 +1,13 @@
<schemalist gettext-domain="@PROJECT_NAME@">
<schema id="org.gnucash.dialogs.flicker" path="/org/gnucash/dialogs/flicker/">
<key name="last-geometry" type="(iiii)">
<default>(-1,-1,-1,-1)</default>
<summary>Last window position and size</summary>
<description>This setting describes the size and position of the window when it was last closed.
The numbers are the X and Y coordinates of the top left corner of the window
followed by the width and height of the window.</description>
</key>
</schema>
</schemalist>

View File

@ -315,9 +315,11 @@ gnucash/import-export/aqb/gnc-ab-kvp.c
gnucash/import-export/aqb/gnc-ab-transfer.c
gnucash/import-export/aqb/gnc-ab-utils.c
gnucash/import-export/aqb/gnc-file-aqb-import.c
gnucash/import-export/aqb/gnc-flicker-gui.c
gnucash/import-export/aqb/gnc-gwen-gui.c
gnucash/import-export/aqb/gncmod-aqbanking.c
gnucash/import-export/aqb/gnc-plugin-aqbanking.c
gnucash/import-export/aqb/gschemas/org.gnucash.dialogs.flicker.gschema.xml.in
gnucash/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in
gnucash/import-export/bi-import/dialog-bi-import.c
gnucash/import-export/bi-import/dialog-bi-import-gui.c