|
|
|
|
@ -27,6 +27,7 @@
|
|
|
|
|
* @author Copyright (C) 2006 David Hampton <hampton@employees.org>
|
|
|
|
|
* @author Copyright (C) 2008 Andreas Koehler <andi5.py@gmx.net>
|
|
|
|
|
* @author Copyright (C) 2011 Robert Fewell
|
|
|
|
|
* @author Copyright (C) 2020 Peter Zimmerer <pkzw@web.de>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
@ -89,6 +90,10 @@ gboolean aai_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer
|
|
|
|
|
void aai_wizard_page_prepare (GtkAssistant *assistant, gpointer user_data);
|
|
|
|
|
void aai_wizard_button_clicked_cb(GtkButton *button, gpointer user_data);
|
|
|
|
|
|
|
|
|
|
#ifdef AQBANKING6
|
|
|
|
|
static guint aai_ab_account_hash(gconstpointer v);
|
|
|
|
|
static gboolean aai_ab_account_equal(gconstpointer v1, gconstpointer v2);
|
|
|
|
|
#endif
|
|
|
|
|
void aai_match_page_prepare (GtkAssistant *assistant, gpointer user_data);
|
|
|
|
|
|
|
|
|
|
static gboolean banking_has_accounts(AB_BANKING *banking);
|
|
|
|
|
@ -101,7 +106,9 @@ static gboolean find_gnc_acc_cb(gpointer key, gpointer value, gpointer user_data
|
|
|
|
|
static gboolean clear_line_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data);
|
|
|
|
|
static void account_list_clicked_cb (GtkTreeView *view, GtkTreePath *path,
|
|
|
|
|
GtkTreeViewColumn *col, gpointer user_data);
|
|
|
|
|
static void clear_kvp_acc_cb(Account *gnc_acc, gpointer user_data);
|
|
|
|
|
static void insert_acc_into_revhash_cb(gpointer ab_acc, gpointer gnc_acc, gpointer revhash);
|
|
|
|
|
static void remove_acc_from_revhash_cb(gpointer ab_acc, gpointer gnc_acc, gpointer revhash);
|
|
|
|
|
static void clear_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data);
|
|
|
|
|
static void save_kvp_acc_cb(gpointer key, gpointer value, gpointer user_data);
|
|
|
|
|
static void aai_close_handler(gpointer user_data);
|
|
|
|
|
|
|
|
|
|
@ -122,6 +129,8 @@ struct _ABInitialInfo
|
|
|
|
|
AB_BANKING *api;
|
|
|
|
|
/* AB_ACCOUNT* -> Account* -- DO NOT DELETE THE KEYS! */
|
|
|
|
|
GHashTable *gnc_hash;
|
|
|
|
|
/* Reverse hash table for lookup of matched GnuCash accounts */
|
|
|
|
|
GHashTable *gnc_revhash;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _DeferredInfo
|
|
|
|
|
@ -201,6 +210,12 @@ aai_destroy_cb(GtkWidget *object, gpointer user_data)
|
|
|
|
|
info->gnc_hash = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (info->gnc_revhash)
|
|
|
|
|
{
|
|
|
|
|
g_hash_table_destroy(info->gnc_revhash);
|
|
|
|
|
info->gnc_revhash = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (info->api)
|
|
|
|
|
{
|
|
|
|
|
gnc_AB_BANKING_delete(info->api);
|
|
|
|
|
@ -290,6 +305,46 @@ aai_wizard_button_clicked_cb(GtkButton *button, gpointer user_data)
|
|
|
|
|
LEAVE(" ");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef AQBANKING6
|
|
|
|
|
static guint
|
|
|
|
|
aai_ab_account_hash (gconstpointer v)
|
|
|
|
|
{
|
|
|
|
|
if (v == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
else
|
|
|
|
|
/* Use the account unique id as hash value */
|
|
|
|
|
return AB_AccountSpec_GetUniqueId((const GNC_AB_ACCOUNT_SPEC *) v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
|
aai_ab_account_equal (gconstpointer v1, gconstpointer v2)
|
|
|
|
|
{
|
|
|
|
|
if (v1 == NULL || v2 == NULL)
|
|
|
|
|
return v1 == v2;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* Use the account unique id to check for equality */
|
|
|
|
|
uint32_t uid1 = AB_AccountSpec_GetUniqueId((const GNC_AB_ACCOUNT_SPEC *) v1);
|
|
|
|
|
uint32_t uid2 = AB_AccountSpec_GetUniqueId((const GNC_AB_ACCOUNT_SPEC *) v2);
|
|
|
|
|
return uid1 == uid2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
insert_acc_into_revhash_cb(gpointer ab_acc, gpointer gnc_acc, gpointer revhash)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail(revhash && gnc_acc && ab_acc);
|
|
|
|
|
g_hash_table_insert((GHashTable *) revhash, gnc_acc, ab_acc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
remove_acc_from_revhash_cb(gpointer ab_acc, gpointer gnc_acc, gpointer revhash)
|
|
|
|
|
{
|
|
|
|
|
g_return_if_fail(revhash && gnc_acc);
|
|
|
|
|
g_hash_table_remove((GHashTable *) revhash, gnc_acc);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
aai_match_page_prepare (GtkAssistant *assistant, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
@ -311,11 +366,17 @@ aai_match_page_prepare (GtkAssistant *assistant, gpointer user_data)
|
|
|
|
|
#endif
|
|
|
|
|
/* Determine current mapping */
|
|
|
|
|
root = gnc_book_get_root_account(gnc_get_current_book());
|
|
|
|
|
#ifdef AQBANKING6
|
|
|
|
|
info->gnc_hash = g_hash_table_new(&aai_ab_account_hash, &aai_ab_account_equal);
|
|
|
|
|
#else
|
|
|
|
|
info->gnc_hash = g_hash_table_new(&g_direct_hash, &g_direct_equal);
|
|
|
|
|
#endif
|
|
|
|
|
data.api = info->api;
|
|
|
|
|
data.hash = info->gnc_hash;
|
|
|
|
|
gnc_account_foreach_descendant(
|
|
|
|
|
root, (AccountCb) hash_from_kvp_acc_cb, &data);
|
|
|
|
|
gnc_account_foreach_descendant(root, (AccountCb) hash_from_kvp_acc_cb, &data);
|
|
|
|
|
/* Memorize initial matches in reverse hash table */
|
|
|
|
|
info->gnc_revhash = g_hash_table_new(NULL, NULL);
|
|
|
|
|
g_hash_table_foreach(data.hash, (GHFunc) insert_acc_into_revhash_cb, (gpointer) info->gnc_revhash);
|
|
|
|
|
|
|
|
|
|
info->match_page_prepared = TRUE;
|
|
|
|
|
}
|
|
|
|
|
@ -330,13 +391,17 @@ void
|
|
|
|
|
aai_on_finish (GtkAssistant *assistant, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
ABInitialInfo *info = user_data;
|
|
|
|
|
Account *root;
|
|
|
|
|
|
|
|
|
|
g_return_if_fail(info && info->gnc_hash);
|
|
|
|
|
g_return_if_fail(info && info->gnc_hash && info->gnc_revhash);
|
|
|
|
|
|
|
|
|
|
/* Remove GnuCash accounts from reverse hash table which are still
|
|
|
|
|
* matched to an AqBanking account. For the remaining GnuCash accounts
|
|
|
|
|
* the KVPs must be cleared (i.e. deleted).
|
|
|
|
|
* Please note that the value (i.e. the GnuCash account) stored in info->gnc_hash
|
|
|
|
|
* is used as key for info->gnc_revhash */
|
|
|
|
|
g_hash_table_foreach(info->gnc_hash, (GHFunc) remove_acc_from_revhash_cb, info->gnc_revhash);
|
|
|
|
|
/* Commit the changes */
|
|
|
|
|
root = gnc_book_get_root_account(gnc_get_current_book());
|
|
|
|
|
gnc_account_foreach_descendant(root, (AccountCb) clear_kvp_acc_cb, NULL);
|
|
|
|
|
g_hash_table_foreach(info->gnc_revhash, (GHFunc) clear_kvp_acc_cb, NULL);
|
|
|
|
|
g_hash_table_foreach(info->gnc_hash, (GHFunc) save_kvp_acc_cb, NULL);
|
|
|
|
|
|
|
|
|
|
gtk_widget_destroy(info->window);
|
|
|
|
|
@ -510,7 +575,11 @@ clear_line_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter,
|
|
|
|
|
|
|
|
|
|
gtk_tree_model_get(model, iter, ACCOUNT_LIST_COL_AB_ACCT, &ab_acc, -1);
|
|
|
|
|
|
|
|
|
|
#ifdef AQBANKING6
|
|
|
|
|
if (aai_ab_account_equal(ab_acc, data->ab_acc))
|
|
|
|
|
#else
|
|
|
|
|
if (ab_acc == data->ab_acc)
|
|
|
|
|
#endif
|
|
|
|
|
{
|
|
|
|
|
gtk_list_store_set(store, iter, ACCOUNT_LIST_COL_GNC_NAME, "",
|
|
|
|
|
ACCOUNT_LIST_COL_CHECKED, TRUE, -1);
|
|
|
|
|
@ -610,14 +679,11 @@ account_list_clicked_cb (GtkTreeView *view, GtkTreePath *path,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
clear_kvp_acc_cb(Account *gnc_acc, gpointer user_data)
|
|
|
|
|
clear_kvp_acc_cb(gpointer gnc_acc, gpointer ab_acc, gpointer user_data)
|
|
|
|
|
{
|
|
|
|
|
if (gnc_ab_get_account_uid(gnc_acc))
|
|
|
|
|
gnc_ab_set_account_uid(gnc_acc, 0);
|
|
|
|
|
if (gnc_ab_get_account_accountid(gnc_acc))
|
|
|
|
|
gnc_ab_set_account_accountid(gnc_acc, "");
|
|
|
|
|
if (gnc_ab_get_account_bankcode(gnc_acc))
|
|
|
|
|
gnc_ab_set_account_bankcode(gnc_acc, "");
|
|
|
|
|
g_return_if_fail(gnc_acc);
|
|
|
|
|
/* Delete complete "hbci..." KVPs for GnuCash account */
|
|
|
|
|
gnc_account_delete_map_entry((Account *) gnc_acc, "hbci", NULL, NULL, FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
|