"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "gnucash/import-export/import-main-matcher.c" between
gnucash-5.0.tar.bz2 and gnucash-5.1.tar.bz2

About: GnuCash is personal and small-business financial-accounting software.

import-main-matcher.c  (gnucash-5.0.tar.bz2):import-main-matcher.c  (gnucash-5.1.tar.bz2)
skipping to change at line 516 skipping to change at line 516
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (info->append_text), gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON (info->append_text),
xaccAccountGetAppendText(account)); xaccAccountGetAppendText(account));
gnc_gen_trans_list_create_matches (info); gnc_gen_trans_list_create_matches (info);
load_hash_tables (info); load_hash_tables (info);
resolve_conflicts (info); resolve_conflicts (info);
gtk_widget_show_all (GTK_WIDGET(info->main_widget)); gtk_widget_show_all (GTK_WIDGET(info->main_widget));
gnc_gen_trans_list_show_accounts_column (info); gnc_gen_trans_list_show_accounts_column (info);
} }
static void acc_begin_edit (GList **accounts_modified, Account *acc)
{
if (!acc || !accounts_modified || g_list_find (*accounts_modified, acc))
return;
DEBUG ("xaccAccountBeginEdit for acc %s", xaccAccountGetName (acc));
xaccAccountBeginEdit (acc);
*accounts_modified = g_list_prepend (*accounts_modified, acc);
}
void void
on_matcher_ok_clicked (GtkButton *button, GNCImportMainMatcher *info) on_matcher_ok_clicked (GtkButton *button, GNCImportMainMatcher *info)
{ {
g_assert (info); g_assert (info);
/* DEBUG ("Begin") */ /* DEBUG ("Begin") */
GtkTreeModel *model = gtk_tree_view_get_model (info->view); GtkTreeModel *model = gtk_tree_view_get_model (info->view);
GtkTreeIter iter; GtkTreeIter iter;
if (!gtk_tree_model_get_iter_first (model, &iter)) if (!gtk_tree_model_get_iter_first (model, &iter))
skipping to change at line 537 skipping to change at line 546
// No transaction, we can just close the dialog. // No transaction, we can just close the dialog.
gnc_gen_trans_list_delete (info); gnc_gen_trans_list_delete (info);
return; return;
} }
/* Don't run any queries and/or split sorts while processing the matcher /* Don't run any queries and/or split sorts while processing the matcher
results. */ results. */
gnc_suspend_gui_refresh (); gnc_suspend_gui_refresh ();
bool first_tran = true; bool first_tran = true;
bool append_text = gtk_toggle_button_get_active ((GtkToggleButton*) info->ap pend_text); bool append_text = gtk_toggle_button_get_active ((GtkToggleButton*) info->ap pend_text);
GList *accounts_modified = NULL;
do do
{ {
GNCImportTransInfo *trans_info; GNCImportTransInfo *trans_info;
gtk_tree_model_get (model, &iter, gtk_tree_model_get (model, &iter,
DOWNLOADED_COL_DATA, &trans_info, DOWNLOADED_COL_DATA, &trans_info,
-1); -1);
Split* first_split = gnc_import_TransInfo_get_fsplit (trans_info);
Transaction *trans = xaccSplitGetParent (first_split);
for (GList *n = xaccTransGetSplitList (trans); n; n = g_list_next (n))
acc_begin_edit (&accounts_modified, xaccSplitGetAccount (n->data));
// Allow the backend to know if the Append checkbox is ticked or unticke d // Allow the backend to know if the Append checkbox is ticked or unticke d
// by propagating info->append_text to every trans_info->append_text // by propagating info->append_text to every trans_info->append_text
gnc_import_TransInfo_set_append_text( trans_info, append_text); gnc_import_TransInfo_set_append_text( trans_info, append_text);
// When processing the first transaction, // When processing the first transaction,
// save the state of the Append checkbox to an account kvp so the same s tate can be // save the state of the Append checkbox to an account kvp so the same s tate can be
// defaulted next time this account is imported. // defaulted next time this account is imported.
// Get the import account from the first split. // Get the import account from the first split.
if (first_tran) if (first_tran)
{ {
Split* first_split = gnc_import_TransInfo_get_fsplit (trans_info);
xaccAccountSetAppendText (xaccSplitGetAccount(first_split), append_t ext); xaccAccountSetAppendText (xaccSplitGetAccount(first_split), append_t ext);
first_tran = false; first_tran = false;
} }
// Note: if there's only 1 split (unbalanced) one will be created with t
he unbalanced account, Account *dest_acc = gnc_import_TransInfo_get_destacc (trans_info);
// and for that account the defer balance will not be set. So things wil acc_begin_edit (&accounts_modified, dest_acc);
l be slow.
if (gnc_import_process_trans_item (NULL, trans_info)) if (gnc_import_process_trans_item (NULL, trans_info))
{ {
if (info->transaction_processed_cb) if (info->transaction_processed_cb)
{ {
info->transaction_processed_cb (trans_info, true, info->transaction_processed_cb (trans_info, true,
info->user_data); info->user_data);
} }
} }
} }
while (gtk_tree_model_iter_next (model, &iter)); while (gtk_tree_model_iter_next (model, &iter));
gnc_gen_trans_list_delete (info); gnc_gen_trans_list_delete (info);
/* Allow GUI refresh again. */ /* Allow GUI refresh again. */
gnc_resume_gui_refresh (); gnc_resume_gui_refresh ();
/* DEBUG ("End") */ /* DEBUG ("End") */
g_list_free_full (accounts_modified, (GDestroyNotify)xaccAccountCommitEdit);
} }
void void
on_matcher_cancel_clicked (GtkButton *button, gpointer user_data) on_matcher_cancel_clicked (GtkButton *button, gpointer user_data)
{ {
GNCImportMainMatcher *info = user_data; GNCImportMainMatcher *info = user_data;
gnc_gen_trans_list_delete (info); gnc_gen_trans_list_delete (info);
} }
bool bool
skipping to change at line 927 skipping to change at line 944
bool ret = false; bool ret = false;
gtk_tree_model_get (model, iter, gtk_tree_model_get (model, iter,
COMPLETION_LIST_NORMALIZED_FOLDED, &existing_str, COMPLETION_LIST_NORMALIZED_FOLDED, &existing_str,
-1); -1);
if (existing_str && *existing_str && strstr (existing_str, entry_str)) if (existing_str && *existing_str && strstr (existing_str, entry_str))
ret = true; ret = true;
g_free (existing_str); g_free (existing_str);
return ret; return ret;
} }
static void typedef struct
setup_entry (GtkWidget *entry, bool sensitive, GHashTable *hash,
const char *initial)
{ {
GtkWidget *entry;
GObject *override;
bool *can_edit;
GHashTable *hash;
const char *initial;
} EntryInfo;
static void override_clicked (GtkWidget *widget, EntryInfo *entryinfo)
{
gtk_widget_set_visible (GTK_WIDGET (entryinfo->override), false);
gtk_widget_set_sensitive (entryinfo->entry, true);
gtk_entry_set_text (GTK_ENTRY (entryinfo->entry), "");
gtk_widget_grab_focus (entryinfo->entry);
*entryinfo->can_edit = true;
}
static void
setup_entry (EntryInfo *entryinfo)
{
bool sensitive = *entryinfo->can_edit;
GtkWidget *entry = entryinfo->entry;
GtkWidget *override = GTK_WIDGET (entryinfo->override);
GHashTable *hash = entryinfo->hash;
const char *initial = entryinfo->initial;
gtk_widget_set_sensitive (entry, sensitive); gtk_widget_set_sensitive (entry, sensitive);
gtk_widget_set_visible (override, !sensitive);
if (sensitive && initial && *initial) if (sensitive && initial && *initial)
gtk_entry_set_text (GTK_ENTRY (entry), initial); gtk_entry_set_text (GTK_ENTRY (entry), initial);
else if (!sensitive) else if (!sensitive)
{ {
gtk_entry_set_text (GTK_ENTRY (entry), _("Disabled")); gtk_entry_set_text (GTK_ENTRY (entry), _("Click Edit to modify"));
return; g_signal_connect (override, "clicked", G_CALLBACK (override_clicked),
entryinfo);
} }
GtkListStore *list = gtk_list_store_new (NUM_COMPLETION_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); GtkListStore *list = gtk_list_store_new (NUM_COMPLETION_COLS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
g_hash_table_foreach (hash, (GHFunc)populate_list, list); g_hash_table_foreach (hash, (GHFunc)populate_list, list);
if (initial && *initial && !g_hash_table_lookup (hash, (gpointer)initial)) if (initial && *initial && !g_hash_table_lookup (hash, (gpointer)initial))
populate_list ((gpointer)initial, NULL, list); populate_list ((gpointer)initial, NULL, list);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list), gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (list),
COMPLETION_LIST_ORIGINAL, COMPLETION_LIST_ORIGINAL,
GTK_SORT_ASCENDING); GTK_SORT_ASCENDING);
skipping to change at line 976 skipping to change at line 1019
// Set the name for this dialog so it can be easily manipulated with css // Set the name for this dialog so it can be easily manipulated with css
gtk_widget_set_name (GTK_WIDGET(dialog), "gnc-id-import-matcher-edits"); gtk_widget_set_name (GTK_WIDGET(dialog), "gnc-id-import-matcher-edits");
gnc_widget_style_context_add_class (GTK_WIDGET(dialog), "gnc-class-imports") ; gnc_widget_style_context_add_class (GTK_WIDGET(dialog), "gnc-class-imports") ;
GtkWidget *desc_entry = GTK_WIDGET(gtk_builder_get_object (builder, "desc_en try")); GtkWidget *desc_entry = GTK_WIDGET(gtk_builder_get_object (builder, "desc_en try"));
GtkWidget *memo_entry = GTK_WIDGET(gtk_builder_get_object (builder, "memo_en try")); GtkWidget *memo_entry = GTK_WIDGET(gtk_builder_get_object (builder, "memo_en try"));
GtkWidget *notes_entry = GTK_WIDGET(gtk_builder_get_object (builder, "notes_ entry")); GtkWidget *notes_entry = GTK_WIDGET(gtk_builder_get_object (builder, "notes_ entry"));
Transaction *trans = gnc_import_TransInfo_get_trans (rowinfo->trans_info); Transaction *trans = gnc_import_TransInfo_get_trans (rowinfo->trans_info);
Split *split = gnc_import_TransInfo_get_fsplit (rowinfo->trans_info); Split *split = gnc_import_TransInfo_get_fsplit (rowinfo->trans_info);
setup_entry (desc_entry, info->can_edit_desc, info->desc_hash, xaccTransGetD
escription (trans)); EntryInfo entries[] = {
setup_entry (notes_entry, info->can_edit_notes, info->notes_hash, xaccTransG { desc_entry, gtk_builder_get_object (builder, "desc_override"), &info->
etNotes (trans)); can_edit_desc, info->desc_hash, xaccTransGetDescription (trans) },
setup_entry (memo_entry, info->can_edit_memo, info->memo_hash, xaccSplitGetM { notes_entry, gtk_builder_get_object (builder, "notes_override"), &info
emo (split)); ->can_edit_notes, info->notes_hash, xaccTransGetNotes (trans) },
{ memo_entry, gtk_builder_get_object (builder, "memo_override"), &info->
can_edit_memo, info->memo_hash, xaccSplitGetMemo (split) },
{ NULL } };
for (guint i = 0; entries[i].entry; i++)
setup_entry (&entries[i]);
/* ensure that an override button doesn't have focus. find the
first available entry and give it focus. */
for (guint i = 0; entries[i].entry; i++)
if (*entries[i].can_edit)
{
gtk_widget_grab_focus (entries[i].entry);
break;
}
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (info->main_wi dget)); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (info->main_wi dget));
// run the dialog // run the dialog
gtk_widget_show_all (dialog); gtk_widget_show (dialog);
bool retval = false; bool retval = false;
switch (gtk_dialog_run (GTK_DIALOG(dialog))) switch (gtk_dialog_run (GTK_DIALOG(dialog)))
{ {
case GTK_RESPONSE_OK: case GTK_RESPONSE_OK:
*new_desc = g_strdup (gtk_entry_get_text (GTK_ENTRY (desc_entry))); *new_desc = g_strdup (gtk_entry_get_text (GTK_ENTRY (desc_entry)));
*new_notes = g_strdup (gtk_entry_get_text (GTK_ENTRY (notes_entry))); *new_notes = g_strdup (gtk_entry_get_text (GTK_ENTRY (notes_entry)));
*new_memo = g_strdup (gtk_entry_get_text (GTK_ENTRY (memo_entry))); *new_memo = g_strdup (gtk_entry_get_text (GTK_ENTRY (memo_entry)));
retval = true; retval = true;
break; break;
skipping to change at line 2203 skipping to change at line 2261
gnc_gen_trans_list_add_trans_internal (gui, trans, ref_id, NULL); gnc_gen_trans_list_add_trans_internal (gui, trans, ref_id, NULL);
} }
void gnc_gen_trans_list_add_trans_with_split_data (GNCImportMainMatcher *gui, void gnc_gen_trans_list_add_trans_with_split_data (GNCImportMainMatcher *gui,
Transaction *trans, Transaction *trans,
GNCImportLastSplitInfo *lspli t) GNCImportLastSplitInfo *lspli t)
{ {
gnc_gen_trans_list_add_trans_internal (gui, trans, 0, lsplit); gnc_gen_trans_list_add_trans_internal (gui, trans, 0, lsplit);
} }
/* Query the accounts used by the imported transactions to find a list of /* Return a list of splits from already existing transactions for
* candidate matching transactions. * which the account matches an account used by the transactions to
* import. The matching range is also date-limited (configurable
* via preferences) to not go too far in the past or future.
*/ */
static GList* static GList*
query_imported_transaction_accounts (GNCImportMainMatcher *gui) filter_existing_splits_on_account_and_date (GNCImportMainMatcher *gui)
{ {
static const int secs_per_day = 86400; static const int secs_per_day = 86400;
gint match_date_limit = gint match_date_limit =
gnc_import_Settings_get_match_date_hardlimit (gui->user_settings); gnc_import_Settings_get_match_date_hardlimit (gui->user_settings);
time64 min_time=G_MAXINT64, max_time=0; time64 min_time=G_MAXINT64, max_time=0;
time64 match_timelimit = match_date_limit * secs_per_day; time64 match_timelimit = match_date_limit * secs_per_day;
GList *all_accounts = NULL; GList *all_accounts = NULL;
/* Go through all imported transactions, gather the list of accounts, and /* Go through all imported transactions, gather the list of accounts, and
* min/max date range. * min/max date range.
skipping to change at line 2253 skipping to change at line 2313
GList *retval = g_list_copy (query_results); GList *retval = g_list_copy (query_results);
qof_query_destroy (query); qof_query_destroy (query);
return retval; return retval;
} }
/* Create a hash by account of all splits that could match one of the imported /* Create a hash by account of all splits that could match one of the imported
* transactions based on their account and date and organized per account. * transactions based on their account and date and organized per account.
*/ */
static GHashTable* static GHashTable*
create_hash_of_potential_matches (GList *candidate_txns, create_hash_of_potential_matches (GList *candidate_splits,
GHashTable *account_hash) GHashTable *account_hash)
{ {
for (GList* candidate = candidate_txns; candidate != NULL; for (GList* candidate = candidate_splits; candidate != NULL;
candidate = g_list_next (candidate)) candidate = g_list_next (candidate))
{ {
if (gnc_import_split_has_online_id (candidate->data)) if (gnc_import_split_has_online_id (candidate->data))
continue; continue;
/* In this context an open transaction represents a freshly /* In this context an open transaction represents a freshly
* downloaded one. That can't possibly be a match yet */ * downloaded one. That can't possibly be a match yet */
if (xaccTransIsOpen(xaccSplitGetParent(candidate->data))) if (xaccTransIsOpen(xaccSplitGetParent(candidate->data)))
continue; continue;
Account *split_account = xaccSplitGetAccount (candidate->data); Account *split_account = xaccSplitGetAccount (candidate->data);
/* g_hash_table_steal_extended would do the two calls in one shot but is /* g_hash_table_steal_extended would do the two calls in one shot but is
skipping to change at line 2349 skipping to change at line 2409
} }
} }
void void
gnc_gen_trans_list_create_matches (GNCImportMainMatcher *gui) gnc_gen_trans_list_create_matches (GNCImportMainMatcher *gui)
{ {
GHashTable* account_hash = GHashTable* account_hash =
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
(GDestroyNotify)g_slist_free); (GDestroyNotify)g_slist_free);
g_assert (gui); g_assert (gui);
GList *candidate_txns = query_imported_transaction_accounts (gui); GList *candidate_splits = filter_existing_splits_on_account_and_date (gui);
create_hash_of_potential_matches (candidate_txns, account_hash); create_hash_of_potential_matches (candidate_splits, account_hash);
perform_matching (gui, account_hash); perform_matching (gui, account_hash);
g_list_free (candidate_txns); g_list_free (candidate_splits);
g_hash_table_destroy (account_hash); g_hash_table_destroy (account_hash);
return; return;
} }
GtkWidget * GtkWidget *
gnc_gen_trans_list_widget (GNCImportMainMatcher *info) gnc_gen_trans_list_widget (GNCImportMainMatcher *info)
{ {
g_assert (info); g_assert (info);
return info->main_widget; return info->main_widget;
} }
 End of changes. 19 change blocks. 
25 lines changed or deleted 83 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)