mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Fix Imap Editor to reflect the changes in kvp paths
There were several problems that broke the Imap Editor that have been fixed due to kvp changes. The import-map-bayes entries were being added to the tree view based on the number token entries squared. Retrieving import-map entries resulted in an empty list and also deleting entries from the tree view failed.
This commit is contained in:
parent
dfb5de91ff
commit
6c43c3afe0
@ -46,7 +46,7 @@
|
||||
|
||||
/** Enumeration for the tree-store */
|
||||
enum GncImapColumn {SOURCE_FULL_ACC, SOURCE_ACCOUNT, BASED_ON, MATCH_STRING,
|
||||
MAP_FULL_ACC, MAP_ACCOUNT, FULL_CATEGORY, COUNT, FILTER};
|
||||
MAP_FULL_ACC, MAP_ACCOUNT, HEAD, CATEGORY, COUNT, FILTER};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
@ -139,39 +139,27 @@ are_you_sure (ImapDialog *imap_dialog)
|
||||
}
|
||||
|
||||
static void
|
||||
delete_info_bayes (Account *source_account, gchar *match_string, gint depth)
|
||||
delete_info_bayes (Account *source_account, gchar *head, gint depth)
|
||||
{
|
||||
gchar *full_category;
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME_BAYES "/%s", match_string);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME_BAYES);
|
||||
if (depth == 1) // top level, delete all below
|
||||
gnc_account_delete_map_entry (source_account, full_category, FALSE);
|
||||
if (depth != 1) // below top level
|
||||
gnc_account_delete_map_entry (source_account, head, NULL, NULL, FALSE);
|
||||
else
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
gnc_account_delete_all_bayes_maps (source_account);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_info_nbayes (Account *source_account, gint depth)
|
||||
delete_info_nbayes (Account *source_account, gchar *head,
|
||||
gchar *category, gchar *match_string, gint depth)
|
||||
{
|
||||
gchar *full_category;
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME "/%s", IMAP_FRAME_DESC);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME "/%s", IMAP_FRAME_MEMO);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME "/%s", IMAP_FRAME_CSV);
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
|
||||
full_category = g_strdup_printf (IMAP_FRAME);
|
||||
if (depth == 1) // top level, delete all below
|
||||
gnc_account_delete_map_entry (source_account, full_category, FALSE);
|
||||
if (depth != 1) // below top level
|
||||
{
|
||||
gnc_account_delete_map_entry (source_account, head, category, match_string, FALSE);
|
||||
gnc_account_delete_map_entry (source_account, head, category, NULL, TRUE);
|
||||
}
|
||||
else
|
||||
gnc_account_delete_map_entry (source_account, full_category, TRUE);
|
||||
gnc_account_delete_map_entry (source_account, head, category, NULL, FALSE);
|
||||
|
||||
gnc_account_delete_map_entry (source_account, head, NULL, NULL, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -179,13 +167,15 @@ delete_selected_row (GtkTreeModel *model, GtkTreeIter *iter, ImapDialog *imap_di
|
||||
{
|
||||
Account *source_account = NULL;
|
||||
gchar *full_source_account;
|
||||
gchar *full_category;
|
||||
gchar *head;
|
||||
gchar *category;
|
||||
gchar *match_string;
|
||||
|
||||
gtk_tree_model_get (model, iter, SOURCE_ACCOUNT, &source_account, SOURCE_FULL_ACC, &full_source_account,
|
||||
FULL_CATEGORY, &full_category, MATCH_STRING, &match_string, -1);
|
||||
HEAD, &head, CATEGORY, &category, MATCH_STRING, &match_string, -1);
|
||||
|
||||
PINFO("Account is '%s', Full Category is '%s', Match String is '%s'", full_source_account, full_category, match_string);
|
||||
PINFO("Account is '%s', Head is '%s', Category is '%s', Match String is '%s'",
|
||||
full_source_account, head, category, match_string);
|
||||
|
||||
if (source_account != NULL)
|
||||
{
|
||||
@ -197,19 +187,23 @@ delete_selected_row (GtkTreeModel *model, GtkTreeIter *iter, ImapDialog *imap_di
|
||||
depth = gtk_tree_path_get_depth (tree_path);
|
||||
gtk_tree_path_free (tree_path);
|
||||
|
||||
gnc_account_delete_map_entry (source_account, full_category, FALSE);
|
||||
if (imap_dialog->type == ONLINE)
|
||||
gnc_account_delete_map_entry (source_account, head, NULL, NULL, FALSE);
|
||||
|
||||
if (imap_dialog->type == BAYES)
|
||||
delete_info_bayes (source_account, match_string, depth);
|
||||
delete_info_bayes (source_account, head, depth);
|
||||
|
||||
if (imap_dialog->type == NBAYES)
|
||||
delete_info_nbayes (source_account, depth);
|
||||
delete_info_nbayes (source_account, head, category, match_string, depth);
|
||||
}
|
||||
else
|
||||
g_free (full_category);
|
||||
|
||||
g_free (match_string);
|
||||
g_free (full_source_account);
|
||||
if (head)
|
||||
g_free (head);
|
||||
if (category)
|
||||
g_free (category);
|
||||
if (match_string)
|
||||
g_free (match_string);
|
||||
if (full_source_account)
|
||||
g_free (full_source_account);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -239,7 +233,7 @@ gnc_imap_dialog_delete (ImapDialog *imap_dialog)
|
||||
// Walk the list
|
||||
for (row = g_list_first (list); row; row = g_list_next (row))
|
||||
{
|
||||
if (gtk_tree_model_get_iter (model, &iter, row->data))
|
||||
if (gtk_tree_model_get_iter (model, &iter, row->data))
|
||||
delete_selected_row (model, &iter, imap_dialog);
|
||||
}
|
||||
g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
|
||||
@ -413,14 +407,15 @@ add_to_store (GtkTreeModel *model, GtkTreeIter *iter, const gchar *text, GncImap
|
||||
else
|
||||
map_fullname = gnc_account_get_full_name (imapInfo->map_account);
|
||||
|
||||
PINFO("Add to Store: Source Acc '%s', Match '%s', Map Acc '%s'", fullname, imapInfo->match_string, map_fullname);
|
||||
PINFO("Add to Store: Source Acc '%s', Head is '%s', Category is '%s', Match '%s', Map Acc '%s', Count is %s",
|
||||
fullname, imapInfo->head, imapInfo->category, imapInfo->match_string, map_fullname, imapInfo->count);
|
||||
|
||||
gtk_tree_store_set (GTK_TREE_STORE(model), iter,
|
||||
SOURCE_FULL_ACC, fullname, SOURCE_ACCOUNT, imapInfo->source_account,
|
||||
BASED_ON, text,
|
||||
MATCH_STRING, imapInfo->match_string,
|
||||
MAP_FULL_ACC, map_fullname, MAP_ACCOUNT, imapInfo->map_account,
|
||||
FULL_CATEGORY, imapInfo->full_category, COUNT, imapInfo->count,
|
||||
HEAD, imapInfo->head, CATEGORY, imapInfo->category, COUNT, imapInfo->count,
|
||||
FILTER, TRUE, -1);
|
||||
|
||||
g_free (fullname);
|
||||
@ -433,6 +428,7 @@ get_imap_info (Account *acc, const gchar *category, GtkTreeModel *model, const g
|
||||
GtkTreeIter toplevel, child;
|
||||
GList *imap_list, *node;
|
||||
gchar *acc_name = NULL;
|
||||
gchar *head = NULL;
|
||||
|
||||
acc_name = gnc_account_get_full_name (acc);
|
||||
PINFO("Source Acc '%s', Based on '%s', Path Head '%s'", acc_name, text, category);
|
||||
@ -442,6 +438,11 @@ get_imap_info (Account *acc, const gchar *category, GtkTreeModel *model, const g
|
||||
else
|
||||
imap_list = gnc_account_imap_get_info (acc, category);
|
||||
|
||||
if (category == NULL)
|
||||
head = IMAP_FRAME_BAYES;
|
||||
else
|
||||
head = IMAP_FRAME;
|
||||
|
||||
if (g_list_length (imap_list) > 0)
|
||||
{
|
||||
PINFO("List length is %d", g_list_length (imap_list));
|
||||
@ -449,7 +450,8 @@ get_imap_info (Account *acc, const gchar *category, GtkTreeModel *model, const g
|
||||
// Add top level entry of Source full Account and Based on.
|
||||
gtk_tree_store_append (GTK_TREE_STORE(model), &toplevel, NULL);
|
||||
gtk_tree_store_set (GTK_TREE_STORE(model), &toplevel,
|
||||
SOURCE_ACCOUNT, acc, SOURCE_FULL_ACC, acc_name, BASED_ON, text, FILTER, TRUE, -1);
|
||||
SOURCE_ACCOUNT, acc, SOURCE_FULL_ACC, acc_name,
|
||||
HEAD, head, CATEGORY, category, BASED_ON, text, FILTER, TRUE, -1);
|
||||
|
||||
for (node = imap_list; node; node = g_list_next (node))
|
||||
{
|
||||
@ -460,8 +462,8 @@ get_imap_info (Account *acc, const gchar *category, GtkTreeModel *model, const g
|
||||
add_to_store (model, &child, text, imapInfo);
|
||||
|
||||
// Free the members and structure
|
||||
g_free (imapInfo->category_head);
|
||||
g_free (imapInfo->full_category);
|
||||
g_free (imapInfo->head);
|
||||
g_free (imapInfo->category);
|
||||
g_free (imapInfo->match_string);
|
||||
g_free (imapInfo->count);
|
||||
g_free (imapInfo);
|
||||
@ -541,10 +543,10 @@ get_account_info_online (GList *accts, GtkTreeModel *model)
|
||||
|
||||
// Save source account
|
||||
imapInfo.source_account = acc;
|
||||
imapInfo.head = "online_id";
|
||||
imapInfo.category = " ";
|
||||
|
||||
imapInfo.full_category = "online_id";
|
||||
|
||||
text = gnc_account_get_map_entry (acc, imapInfo.full_category);
|
||||
text = gnc_account_get_map_entry (acc, imapInfo.head);
|
||||
|
||||
if (text != NULL)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generated with glade 3.20.0 -->
|
||||
<!-- Generated with glade 3.20.2 -->
|
||||
<interface>
|
||||
<requires lib="gtk+" version="3.10"/>
|
||||
<object class="GtkTreeStore" id="tree-store">
|
||||
@ -16,7 +16,9 @@
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name map_account -->
|
||||
<column type="gpointer"/>
|
||||
<!-- column-name full_category -->
|
||||
<!-- column-name head -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name category -->
|
||||
<column type="gchararray"/>
|
||||
<!-- column-name count -->
|
||||
<column type="gchararray"/>
|
||||
@ -235,7 +237,7 @@
|
||||
<property name="alignment">center</property>
|
||||
</object>
|
||||
<attributes>
|
||||
<attribute name="text">7</attribute>
|
||||
<attribute name="text">8</attribute>
|
||||
</attributes>
|
||||
</child>
|
||||
</object>
|
||||
@ -372,5 +374,8 @@
|
||||
<action-widget response="-10">delete_button</action-widget>
|
||||
<action-widget response="-6">close_button</action-widget>
|
||||
</action-widgets>
|
||||
<child>
|
||||
<placeholder/>
|
||||
</child>
|
||||
</object>
|
||||
</interface>
|
||||
|
@ -5544,7 +5544,6 @@ build_non_bayes (const char *key, const GValue *value, gpointer user_data)
|
||||
return;
|
||||
QofBook *book;
|
||||
GncGUID *guid = NULL;
|
||||
gchar *kvp_path;
|
||||
gchar *guid_string = NULL;
|
||||
auto imapInfo = (GncImapInfo*)user_data;
|
||||
// Get the book
|
||||
@ -5553,25 +5552,20 @@ build_non_bayes (const char *key, const GValue *value, gpointer user_data)
|
||||
guid = (GncGUID*)g_value_get_boxed (value);
|
||||
guid_string = guid_to_string (guid);
|
||||
|
||||
PINFO("build_non_bayes: account '%s', match account guid: '%s'",
|
||||
PINFO("build_non_bayes: match string '%s', match account guid: '%s'",
|
||||
(char*)key, guid_string);
|
||||
|
||||
kvp_path = g_strconcat (imapInfo->category_head, "/", key, NULL);
|
||||
|
||||
PINFO("build_non_bayes: kvp_path is '%s'", kvp_path);
|
||||
|
||||
auto imapInfo_node = static_cast <GncImapInfo*> (g_malloc(sizeof(GncImapInfo)));
|
||||
|
||||
imapInfo_node->source_account = imapInfo->source_account;
|
||||
imapInfo_node->map_account = xaccAccountLookup (guid, book);
|
||||
imapInfo_node->full_category = g_strdup (kvp_path);
|
||||
imapInfo_node->head = g_strdup (imapInfo->head);
|
||||
imapInfo_node->match_string = g_strdup (key);
|
||||
imapInfo_node->category_head = g_strdup (imapInfo->category_head);
|
||||
imapInfo_node->category = g_strdup (imapInfo->category);
|
||||
imapInfo_node->count = g_strdup (" ");
|
||||
|
||||
imapInfo->list = g_list_append (imapInfo->list, imapInfo_node);
|
||||
|
||||
g_free (kvp_path);
|
||||
g_free (guid_string);
|
||||
}
|
||||
|
||||
@ -5589,25 +5583,19 @@ parse_bayes_imap_info (std::string const & imap_bayes_entry)
|
||||
static void
|
||||
build_bayes (const char *key, KvpValue * value, GncImapInfo & imapInfo)
|
||||
{
|
||||
auto slots = qof_instance_get_slots_prefix (QOF_INSTANCE (imapInfo.source_account), IMAP_FRAME_BAYES);
|
||||
if (!slots.size()) return;
|
||||
for (auto const & entry : slots)
|
||||
{
|
||||
auto parsed_key = parse_bayes_imap_info (entry.first);
|
||||
auto temp_guid = gnc::GUID::from_string (std::get <2> (parsed_key));
|
||||
GncGUID guid = temp_guid;
|
||||
auto map_account = xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
|
||||
std::string category_head {std::get <0> (parsed_key) + "/" + std::get <1> (parsed_key)};
|
||||
auto imap_node = static_cast <GncImapInfo*> (g_malloc (sizeof (GncImapInfo)));
|
||||
auto count = entry.second->get <int64_t> ();
|
||||
imap_node->source_account = imapInfo.source_account;
|
||||
imap_node->map_account = map_account;
|
||||
imap_node->full_category = g_strdup (key);
|
||||
imap_node->match_string = g_strdup (std::get <1> (parsed_key).c_str ());
|
||||
imap_node->category_head = g_strdup (category_head.c_str ());
|
||||
imap_node->count = g_strdup_printf ("%" G_GINT64_FORMAT, count);
|
||||
imapInfo.list = g_list_append (imapInfo.list, imap_node);
|
||||
};
|
||||
auto parsed_key = parse_bayes_imap_info (key);
|
||||
auto temp_guid = gnc::GUID::from_string (std::get <2> (parsed_key));
|
||||
GncGUID guid = temp_guid;
|
||||
auto map_account = xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
|
||||
auto imap_node = static_cast <GncImapInfo*> (g_malloc (sizeof (GncImapInfo)));
|
||||
auto count = value->get <int64_t> ();
|
||||
imap_node->source_account = imapInfo.source_account;
|
||||
imap_node->map_account = map_account;
|
||||
imap_node->head = g_strdup (key);
|
||||
imap_node->match_string = g_strdup (std::get <1> (parsed_key).c_str ());
|
||||
imap_node->category = g_strdup(" ");
|
||||
imap_node->count = g_strdup_printf ("%" G_GINT64_FORMAT, count);
|
||||
imapInfo.list = g_list_append (imapInfo.list, imap_node);
|
||||
}
|
||||
|
||||
GList *
|
||||
@ -5625,22 +5613,24 @@ GList *
|
||||
gnc_account_imap_get_info (Account *acc, const char *category)
|
||||
{
|
||||
GList *list = NULL;
|
||||
gchar *category_head = NULL;
|
||||
|
||||
GncImapInfo imapInfo;
|
||||
|
||||
std::vector<std::string> path {IMAP_FRAME};
|
||||
if (category)
|
||||
path.emplace_back (category);
|
||||
|
||||
imapInfo.source_account = acc;
|
||||
imapInfo.list = list;
|
||||
|
||||
category_head = g_strdup_printf (IMAP_FRAME "/%s", category);
|
||||
imapInfo.category_head = category_head;
|
||||
imapInfo.head = g_strdup (IMAP_FRAME);
|
||||
imapInfo.category = g_strdup (category);
|
||||
|
||||
if (qof_instance_has_slot (QOF_INSTANCE(acc), category_head))
|
||||
qof_instance_foreach_slot (QOF_INSTANCE(acc), category_head,
|
||||
if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
|
||||
{
|
||||
qof_instance_foreach_slot (QOF_INSTANCE(acc), IMAP_FRAME, category,
|
||||
build_non_bayes, &imapInfo);
|
||||
|
||||
g_free (category_head);
|
||||
|
||||
}
|
||||
return imapInfo.list;
|
||||
}
|
||||
|
||||
@ -5667,22 +5657,44 @@ gnc_account_get_map_entry (Account *acc, const char *full_category)
|
||||
|
||||
|
||||
void
|
||||
gnc_account_delete_map_entry (Account *acc, char *full_category, gboolean empty)
|
||||
gnc_account_delete_map_entry (Account *acc, char *head, char *category,
|
||||
char *match_string, gboolean empty)
|
||||
{
|
||||
gchar *kvp_path = g_strdup (full_category);
|
||||
if ((acc != NULL) && qof_instance_has_slot (QOF_INSTANCE(acc), kvp_path))
|
||||
if (acc != NULL)
|
||||
{
|
||||
xaccAccountBeginEdit (acc);
|
||||
if (empty)
|
||||
qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), {kvp_path});
|
||||
else
|
||||
qof_instance_slot_path_delete (QOF_INSTANCE(acc), {kvp_path});
|
||||
PINFO("Account is '%s', path is '%s'", xaccAccountGetName (acc), kvp_path);
|
||||
qof_instance_set_dirty (QOF_INSTANCE(acc));
|
||||
xaccAccountCommitEdit (acc);
|
||||
std::vector<std::string> path {head};
|
||||
if (category)
|
||||
path.emplace_back (category);
|
||||
if (match_string)
|
||||
path.emplace_back (match_string);
|
||||
|
||||
if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
|
||||
{
|
||||
xaccAccountBeginEdit (acc);
|
||||
if (empty)
|
||||
qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), path);
|
||||
else
|
||||
qof_instance_slot_path_delete (QOF_INSTANCE(acc), path);
|
||||
PINFO("Account is '%s', head is '%s', category is '%s', match_string is'%s'",
|
||||
xaccAccountGetName (acc), head, category, match_string);
|
||||
qof_instance_set_dirty (QOF_INSTANCE(acc));
|
||||
xaccAccountCommitEdit (acc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gnc_account_delete_all_bayes_maps (Account *acc)
|
||||
{
|
||||
if (acc != NULL)
|
||||
{
|
||||
auto slots = qof_instance_get_slots_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES);
|
||||
if (!slots.size()) return;
|
||||
for (auto const & entry : slots)
|
||||
{
|
||||
qof_instance_slot_path_delete (QOF_INSTANCE (acc), {entry.first});
|
||||
}
|
||||
}
|
||||
g_free (kvp_path);
|
||||
g_free (full_category);
|
||||
}
|
||||
|
||||
/* ================================================================ */
|
||||
|
@ -1423,8 +1423,8 @@ typedef struct imap_info
|
||||
Account *source_account;
|
||||
Account *map_account;
|
||||
GList *list;
|
||||
char *category_head;
|
||||
char *full_category;
|
||||
char *head;
|
||||
char *category;
|
||||
char *match_string;
|
||||
char *count;
|
||||
}GncImapInfo;
|
||||
@ -1444,10 +1444,15 @@ GList *gnc_account_imap_get_info (Account *acc, const char *category);
|
||||
*/
|
||||
gchar *gnc_account_get_map_entry (Account *acc, const char *full_category);
|
||||
|
||||
/** Delete the entry for Account pointed to by full_category, if empty is TRUE then use
|
||||
* delete if empty, full_category is freed
|
||||
/** Delete the entry for Account pointed to by head,category and match_string,
|
||||
* if empty is TRUE then use delete if empty
|
||||
*/
|
||||
void gnc_account_delete_map_entry (Account *acc, char *full_category, gboolean empty);
|
||||
void gnc_account_delete_map_entry (Account *acc, char *head, char *category,
|
||||
char *match_string, gboolean empty);
|
||||
|
||||
/** Delete all bayes entries for Account
|
||||
*/
|
||||
void gnc_account_delete_all_bayes_maps (Account *acc);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -155,9 +155,9 @@ void qof_instance_kvp_merge_guids (const QofInstance *target,
|
||||
gboolean qof_instance_has_slot (const QofInstance *inst, const char *path);
|
||||
void qof_instance_slot_delete (const QofInstance *, const char * path);
|
||||
void qof_instance_slot_delete_if_empty (const QofInstance *, const char * path);
|
||||
void qof_instance_foreach_slot (const QofInstance *inst, const char *path,
|
||||
void(*proc)(const char*, const GValue*, void*),
|
||||
void* data);
|
||||
void qof_instance_foreach_slot (const QofInstance *inst, const char *head,
|
||||
const char *category, void(*proc)(const char*,
|
||||
const GValue*, void*), void* data);
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
|
@ -1359,11 +1359,14 @@ wrap_gvalue_function (const char* key, KvpValue *val, wrap_param & param)
|
||||
}
|
||||
|
||||
void
|
||||
qof_instance_foreach_slot (const QofInstance *inst, const char* path,
|
||||
void (*proc)(const char*, const GValue*, void*),
|
||||
void* data)
|
||||
qof_instance_foreach_slot (const QofInstance *inst, const char* head, const char* category,
|
||||
void (*proc)(const char*, const GValue*, void*), void* data)
|
||||
{
|
||||
auto slot = inst->kvp_data->get_slot({path});
|
||||
std::vector<std::string> path {head};
|
||||
if (category)
|
||||
path.emplace_back (category);
|
||||
|
||||
auto slot = inst->kvp_data->get_slot(path);
|
||||
if (slot == nullptr || slot->get_type() != KvpValue::Type::FRAME)
|
||||
return;
|
||||
auto frame = slot->get<KvpFrame*>();
|
||||
|
Loading…
Reference in New Issue
Block a user