mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge Christian Wehling's 'gnucash-flicker' into maint.
This commit is contained in:
commit
2b01bde2b6
@ -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
|
||||
)
|
||||
|
@ -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>
|
||||
|
445
gnucash/import-export/aqb/gnc-flicker-gui.c
Normal file
445
gnucash/import-export/aqb/gnc-flicker-gui.c
Normal 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));
|
||||
}
|
63
gnucash/import-export/aqb/gnc-flicker-gui.h
Normal file
63
gnucash/import-export/aqb/gnc-flicker-gui.h
Normal 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 */
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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>
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user