TEST_F(ImapBayesTest, FindAccountBayes) { auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); auto acct1_guid = guid_to_string (xaccAccountGetGUID(t_expense_account1)); auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2)); auto value = new KvpValue(INT64_C(42)); root->set_path({IMAP_FRAME_BAYES, foo, acct1_guid}, value); root->set_path({IMAP_FRAME_BAYES, bar, acct1_guid}, value); root->set_path({IMAP_FRAME_BAYES, baz, acct2_guid}, value); root->set_path({IMAP_FRAME_BAYES, waldo, acct2_guid}, value); root->set_path({IMAP_FRAME_BAYES, pepper, acct1_guid}, value); root->set_path({IMAP_FRAME_BAYES, salt, acct2_guid}, value); auto account = gnc_account_imap_find_account_bayes(t_imap, t_list1); EXPECT_EQ(t_expense_account1, account); account = gnc_account_imap_find_account_bayes(t_imap, t_list2); EXPECT_EQ(t_expense_account2, account); account = gnc_account_imap_find_account_bayes(t_imap, t_list3); EXPECT_EQ(t_expense_account1, account); account = gnc_account_imap_find_account_bayes(t_imap, t_list4); EXPECT_EQ(t_expense_account2, account); account = gnc_account_imap_find_account_bayes(t_imap, t_list5); EXPECT_EQ(nullptr, account); }
static void gnc_template_register_save_xfrm_cell (BasicCell * cell, gpointer save_data, gpointer user_data) { SRSaveData *sd = save_data; SplitRegister *reg = user_data; SRInfo *info = gnc_split_register_get_info (reg); Account *template_acc; const GncGUID *acctGUID; kvp_frame *kvpf; Account *acct; g_return_if_fail (gnc_basic_cell_has_name (cell, XFRM_CELL)); /* save the account GncGUID into the kvp_data. */ acct = gnc_split_register_get_account (reg, XFRM_CELL); if (!acct) { PERR ("unknown account"); return; } acctGUID = xaccAccountGetGUID (acct); kvpf = xaccSplitGetSlots (sd->split); kvp_frame_set_slot_path (kvpf, kvp_value_new_guid(acctGUID), GNC_SX_ID, GNC_SX_ACCOUNT, NULL); template_acc = xaccAccountLookup (&info->template_account, gnc_get_current_book ()); /* set the actual account to the fake account for these templates */ xaccAccountInsertSplit (template_acc, sd->split); qof_instance_set_dirty (QOF_INSTANCE (sd->split)); }
TEST_F(ImapPlainTest, FindAccount) { auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); auto acc1_val = new KvpValue(const_cast<GncGUID*>(xaccAccountGetGUID(t_expense_account1))); auto acc2_val = new KvpValue(const_cast<GncGUID*>(xaccAccountGetGUID(t_expense_account2))); root->set_path({IMAP_FRAME, "foo", "bar"}, acc1_val); root->set_path({IMAP_FRAME, "baz", "waldo"}, acc2_val); root->set_path({IMAP_FRAME, "pepper"}, acc1_val); root->set_path({IMAP_FRAME, "salt"}, acc2_val); EXPECT_EQ(t_expense_account1, gnc_account_imap_find_account(t_imap, "foo", "bar")); EXPECT_EQ(t_expense_account2, gnc_account_imap_find_account(t_imap, "baz", "waldo")); EXPECT_EQ(t_expense_account1, gnc_account_imap_find_account(t_imap, NULL, "pepper")); EXPECT_EQ(t_expense_account2, gnc_account_imap_find_account(t_imap, NULL, "salt")); EXPECT_EQ(nullptr, gnc_account_imap_find_account(t_imap, "salt", NULL)); }
TEST_F(ImapBayesTest, AddAccountBayes) { // prevent the embedded beginedit/commitedit from doing anything qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); gnc_account_imap_add_account_bayes(t_imap, t_list1, t_expense_account1); gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); gnc_account_imap_add_account_bayes(t_imap, t_list3, t_expense_account1); gnc_account_imap_add_account_bayes(t_imap, t_list4, t_expense_account2); EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account))); EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); gnc_account_imap_add_account_bayes(t_imap, t_list5, NULL); EXPECT_FALSE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); auto acct1_guid = guid_to_string (xaccAccountGetGUID(t_expense_account1)); auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2)); auto value = root->get_slot({IMAP_FRAME_BAYES, "foo", "bar"}); auto check_account = [this](KvpValue* v) { return (v->get<const char*>(), this->t_imap->book); }; value = root->get_slot({IMAP_FRAME_BAYES, foo, acct1_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, bar, acct1_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, waldo, acct2_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, pepper, acct1_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, salt, acct2_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, baz, acct1_guid}); EXPECT_EQ(nullptr, value); qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); qof_instance_reset_editlevel(QOF_INSTANCE(t_bank_account)); value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_guid}); EXPECT_EQ(2, value->get<int64_t>()); }
static void gnc_payment_dialog_remember_account (PaymentWindow *pw, Account *acc) { QofInstance *owner = qofOwnerGetOwner (&pw->owner); const GncGUID *guid; if (!acc) return; guid = xaccAccountGetGUID(acc); qof_begin_edit (owner); qof_instance_set (owner, "payment-last-account", guid, NULL); qof_commit_edit (owner); }
static xmlNodePtr find_appropriate_node (xmlNodePtr node, Split* spl) { xmlNodePtr mark; for (mark = node->xmlChildrenNode; mark; mark = mark->next) { gboolean account_guid_good = FALSE; gboolean amount_good = FALSE; xmlNodePtr mark2; for (mark2 = mark->xmlChildrenNode; mark2; mark2 = mark2->next) { if (g_strcmp0 ((char*)mark2->name, "split:value") == 0) { gnc_numeric* num = dom_tree_to_gnc_numeric (mark2); if (gnc_numeric_equal (*num, xaccSplitGetValue (spl))) { amount_good = TRUE; } g_free (num); } else if (g_strcmp0 ((char*)mark2->name, "split:account") == 0) { GncGUID* accid = dom_tree_to_guid (mark2); Account* account = xaccSplitGetAccount (spl); if (guid_equal (accid, xaccAccountGetGUID (account))) { account_guid_good = TRUE; } g_free (accid); } if (account_guid_good && amount_good) { return mark; } } } return NULL; }
static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe) { GNCSearchAccountPrivate *priv; GNCSearchAccount *fi = (GNCSearchAccount *)fe; GList *l = NULL, *node; g_return_val_if_fail (fi, NULL); g_return_val_if_fail (IS_GNCSEARCH_ACCOUNT (fi), NULL); priv = _PRIVATE(fi); for (node = priv->selected_accounts; node; node = node->next) { Account *acc = node->data; const GncGUID *guid = xaccAccountGetGUID (acc); l = g_list_prepend (l, (gpointer)guid); } l = g_list_reverse (l); return qof_query_guid_predicate (fi->how, l); }
void gnc_ofx_kvp_set_assoc_account(Account* investment_account, const Account *income_account) { kvp_frame * acc_frame; kvp_value * kvp_val; const GncGUID * income_acc_guid; g_assert(investment_account); g_assert(income_account); acc_frame = xaccAccountGetSlots(investment_account); g_assert(acc_frame); // Must not be NULL, but the QofInstance doc is unclear about this income_acc_guid = xaccAccountGetGUID(income_account); kvp_val = kvp_value_new_guid(income_acc_guid); xaccAccountBeginEdit(investment_account); kvp_frame_set_slot_nc(acc_frame, KEY_ASSOC_INCOME_ACCOUNT, kvp_val); qof_instance_set_dirty(QOF_INSTANCE (investment_account)); xaccAccountCommitEdit(investment_account); }
/********************************************************************\ * gnc_split_scm_set_account * * set the account of a scheme representation of a split. * * * * Args: split_scm - the scheme split * * account - the account to set * * Returns: Nothing * \********************************************************************/ void gnc_split_scm_set_account(SCM split_scm, Account *account) { const char *guid_string; SCM arg; initialize_scm_functions(); if (!gnc_is_split_scm(split_scm)) return; if (account == NULL) return; guid_string = guid_to_string(xaccAccountGetGUID(account)); if (guid_string == NULL) return; arg = scm_makfrom0str(guid_string); scm_call_2(setters.split_scm_account_guid, split_scm, arg); }
/********************************************************************\ * gnc_split_scm_set_account * * set the account of a scheme representation of a split. * * * * Args: split_scm - the scheme split * * account - the account to set * * Returns: Nothing * \********************************************************************/ void gnc_split_scm_set_account(SCM split_scm, Account *account) { gchar guid_string[GUID_ENCODING_LENGTH+1]; SCM arg; initialize_scm_functions(); if (!gnc_is_split_scm(split_scm)) return; if (account == NULL) return; guid_to_string_buff(xaccAccountGetGUID(account), guid_string); if (strlen(guid_string) == 0) return; arg = scm_from_utf8_string(guid_string); scm_call_2(setters.split_scm_account_guid, split_scm, arg); }
static void test_transaction (void) { int i; for (i = 0; i < 50; i++) { Transaction* ran_trn; xmlNodePtr test_node; gnc_commodity* com, *new_com; gchar* filename1; int fd; /* The next line exists for its side effect of creating the * account tree. */ get_random_account_tree (book); ran_trn = get_random_transaction (book); new_com = get_random_commodity (book); if (!ran_trn) { failure_args ("transaction_xml", __FILE__, __LINE__, "get_random_transaction returned NULL"); return; } { /* xaccAccountInsertSplit can reorder the splits. */ GList* list = g_list_copy (xaccTransGetSplitList (ran_trn)); GList* node = list; for (; node; node = node->next) { Split* s = static_cast<decltype (s)> (node->data); Account* a = xaccMallocAccount (book); xaccAccountBeginEdit (a); xaccAccountSetCommodity (a, new_com); xaccAccountSetCommoditySCU (a, xaccSplitGetAmount (s).denom); xaccAccountInsertSplit (a, s); xaccAccountCommitEdit (a); } g_list_free (list); } com = xaccTransGetCurrency (ran_trn); test_node = gnc_transaction_dom_tree_create (ran_trn); if (!test_node) { failure_args ("transaction_xml", __FILE__, __LINE__, "gnc_transaction_dom_tree_create returned NULL"); really_get_rid_of_transaction (ran_trn); continue; } auto compare_msg = node_and_transaction_equal (test_node, ran_trn); if (compare_msg != nullptr) { failure_args ("transaction_xml", __FILE__, __LINE__, "node and transaction were not equal: %s", compare_msg); xmlElemDump (stdout, NULL, test_node); printf ("\n"); fflush (stdout); xmlFreeNode (test_node); really_get_rid_of_transaction (ran_trn); continue; } else { success_args ("transaction_xml", __FILE__, __LINE__, "%d", i); } filename1 = g_strdup_printf ("test_file_XXXXXX"); fd = g_mkstemp (filename1); write_dom_node_to_file (test_node, fd); close (fd); { GList* node = xaccTransGetSplitList (ran_trn); for (; node; node = node->next) { Split* s = static_cast<decltype (s)> (node->data); Account* a1 = xaccSplitGetAccount (s); Account* a2 = xaccMallocAccount (book); xaccAccountBeginEdit (a2); xaccAccountSetCommoditySCU (a2, xaccAccountGetCommoditySCU (a1)); xaccAccountSetGUID (a2, xaccAccountGetGUID (a1)); xaccAccountCommitEdit (a2); } } { sixtp* parser; tran_data data; const char* msg = "[xaccAccountScrubCommodity()] Account \"\" does not have a commodity!"; const char* logdomain = "gnc.engine.scrub"; GLogLevelFlags loglevel = static_cast<decltype (loglevel)> (G_LOG_LEVEL_CRITICAL); TestErrorStruct check = { loglevel, const_cast<char*> (logdomain), const_cast<char*> (msg) }; g_log_set_handler (logdomain, loglevel, (GLogFunc)test_checked_handler, &check); data.trn = ran_trn; data.com = com; data.value = i; parser = gnc_transaction_sixtp_parser_create (); if (!gnc_xml_parse_file (parser, filename1, test_add_transaction, (gpointer)&data, book)) { failure_args ("gnc_xml_parse_file returned FALSE", __FILE__, __LINE__, "%d", i); } else really_get_rid_of_transaction (data.new_trn); } /* no handling of circular data structures. We'll do that later */ /* sixtp_destroy(parser); */ g_unlink (filename1); g_free (filename1); really_get_rid_of_transaction (ran_trn); xmlFreeNode (test_node); } }
static const char* equals_node_val_vs_split_internal (xmlNodePtr node, Split* spl) { xmlNodePtr mark; for (mark = node->children; mark != NULL; mark = mark->next) { if (g_strcmp0 ((char*)mark->name, "split:id") == 0) { GncGUID* id = dom_tree_to_guid (mark); if (!guid_equal (id, xaccSplitGetGUID (spl))) { g_free (id); return "ids differ"; } g_free (id); } else if (g_strcmp0 ((char*)mark->name, "split:memo") == 0) { char* memo = dom_tree_to_text (mark); if (g_strcmp0 (memo, xaccSplitGetMemo (spl)) != 0) { g_free (memo); return "memos differ"; } g_free (memo); } else if (g_strcmp0 ((char*)mark->name, "split:reconciled-state") == 0) { char* rs = dom_tree_to_text (mark); if (rs[0] != xaccSplitGetReconcile (spl)) { g_free (rs); return "states differ"; } g_free (rs); } else if (g_strcmp0 ((char*)mark->name, "split:value") == 0) { gnc_numeric* num = dom_tree_to_gnc_numeric (mark); gnc_numeric val = xaccSplitGetValue (spl); if (!gnc_numeric_equal (*num, val)) { g_free (num); return g_strdup_printf ("values differ: %" G_GINT64_FORMAT "/%" G_GINT64_FORMAT " v %" G_GINT64_FORMAT "/%" G_GINT64_FORMAT, (*num).num, (*num).denom, val.num, val.denom); } g_free (num); } else if (g_strcmp0 ((char*)mark->name, "split:quantity") == 0) { gnc_numeric* num = dom_tree_to_gnc_numeric (mark); gnc_numeric val = xaccSplitGetAmount (spl); if (!gnc_numeric_equal (*num, val)) { return g_strdup_printf ("quantities differ under _equal: %" G_GINT64_FORMAT "/%" G_GINT64_FORMAT " v %" G_GINT64_FORMAT "/%" G_GINT64_FORMAT, (*num).num, (*num).denom, val.num, val.denom); } if (!gnc_numeric_equal (*num, val)) { g_free (num); return g_strdup_printf ("quantities differ: %" G_GINT64_FORMAT "/%" G_GINT64_FORMAT " v %" G_GINT64_FORMAT "/%" G_GINT64_FORMAT, (*num).num, (*num).denom, val.num, val.denom); } g_free (num); } else if (g_strcmp0 ((char*)mark->name, "split:account") == 0) { GncGUID* id = dom_tree_to_guid (mark); Account* account = xaccSplitGetAccount (spl); if (!guid_equal (id, xaccAccountGetGUID (account))) { g_free (id); return "accounts differ"; } g_free (id); } } return NULL; }
static GNCLedgerDisplay * gnc_ledger_display_internal (Account *lead_account, Query *q, GNCLedgerDisplayType ld_type, SplitRegisterType reg_type, SplitRegisterStyle style, gboolean use_double_line, gboolean is_template ) { GNCLedgerDisplay *ld; gint limit; const char *klass; GList *splits; switch (ld_type) { case LD_SINGLE: klass = REGISTER_SINGLE_CM_CLASS; if (reg_type >= NUM_SINGLE_REGISTER_TYPES) { PERR ("single-account register with wrong split register type"); return NULL; } if (!lead_account) { PERR ("single-account register with no account specified"); return NULL; } if (q) { PWARN ("single-account register with external query"); q = NULL; } ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account); if (ld) return ld; break; case LD_SUBACCOUNT: klass = REGISTER_SUBACCOUNT_CM_CLASS; if (!lead_account) { PERR ("sub-account register with no lead account"); return NULL; } if (q) { PWARN ("account register with external query"); q = NULL; } ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account); if (ld) return ld; break; case LD_GL: klass = REGISTER_GL_CM_CLASS; if (!q) { PWARN ("general journal with no query"); } break; default: PERR ("bad ledger type: %d", ld_type); return NULL; } ld = g_new (GNCLedgerDisplay, 1); ld->leader = *xaccAccountGetGUID (lead_account); ld->query = NULL; ld->ld_type = ld_type; ld->loading = FALSE; ld->destroy = NULL; ld->get_parent = NULL; ld->user_data = NULL; limit = gnc_prefs_get_float(GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_MAX_TRANS); /* set up the query filter */ if (q) ld->query = qof_query_copy (q); else gnc_ledger_display_make_query (ld, limit, reg_type); ld->component_id = gnc_register_gui_component (klass, refresh_handler, close_handler, ld); /******************************************************************\ * The main register window itself * \******************************************************************/ ld->use_double_line_default = use_double_line; ld->reg = gnc_split_register_new (reg_type, style, use_double_line, is_template); gnc_split_register_set_data (ld->reg, ld, gnc_ledger_display_parent); splits = qof_query_run (ld->query); gnc_ledger_display_set_watches (ld, splits); gnc_ledger_display_refresh_internal (ld, splits); return ld; }
static void gsr2_create_table (GNCSplitReg2 *gsr) { GncTreeViewSplitReg *view; GncTreeModelSplitReg *model; GtkTreeModel *s_model; GtkWidget *scrolled_window; GtkTreeViewColumn *col; GNCLedgerDisplay2Type ledger_type; GtkWidget *hbox; gdouble num_of_trans; gchar *state_section; GKeyFile *state_file = gnc_state_get_current(); const GncGUID * guid; Account * account; account = gnc_ledger_display2_leader (gsr->ledger); guid = xaccAccountGetGUID (account); ENTER("create table gsr=%p", gsr); gnc_ledger_display2_set_user_data (gsr->ledger, (gpointer)gsr); gnc_ledger_display2_set_handlers (gsr->ledger, gnc_split_reg2_ld_destroy, gnc_split_reg2_get_parent); model = gnc_ledger_display2_get_split_model_register (gsr->ledger); view = gnc_tree_view_split_reg_new_with_model (model); g_object_unref (G_OBJECT (model)); /* State_section is used to store per register state: column widths, sort order,... */ ledger_type = gnc_ledger_display2_type (gsr->ledger); if (ledger_type == LD2_GL && model->type == GENERAL_JOURNAL2) state_section = g_strdup (STATE_SECTION_GEN_JOURNAL); else if (ledger_type == LD2_SUBACCOUNT) { gchar guidstr[GUID_ENCODING_LENGTH+1]; guid_to_string_buff (guid, guidstr); state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, " w/subaccounts", NULL); } else { gchar guidstr[GUID_ENCODING_LENGTH+1]; guid_to_string_buff (guid, guidstr); state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL); } g_object_set (G_OBJECT (view), "state-section", state_section, "show-column-menu", FALSE, NULL); // Create a hbox for treeview and scrollbar. hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE); gtk_widget_show (hbox); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show (scrolled_window); gtk_box_pack_start (GTK_BOX (gsr), hbox, TRUE, TRUE, 0); num_of_trans = model->number_of_trans_in_full_tlist - 1; gsr->scroll_adj = GTK_ADJUSTMENT (gtk_adjustment_new (model->position_of_trans_in_full_tlist, 0.0, num_of_trans + 10, 1.0, 10.0, 10.0)); gsr->scroll_bar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (gsr->scroll_adj)); gtk_widget_show (gsr->scroll_bar); gtk_box_pack_start (GTK_BOX (hbox), gsr->scroll_bar, FALSE, FALSE, 2); gtk_box_pack_start (GTK_BOX (hbox), scrolled_window, TRUE, TRUE, 0); gnc_ledger_display2_set_split_view_register (gsr->ledger, view); /* Synchronize model state with view state * (needed to properly set up the internal query) */ /* Restore the sort depth from saved state */ model->sort_depth = g_key_file_get_integer (state_file, state_section, "sort_depth", NULL); g_free(state_section); s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); if (s_model) { gint sort_col; GtkSortType type; if (gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (s_model), &sort_col, &type)) { model->sort_col = sort_col; model->sort_direction = type; } } gnc_tree_view_configure_columns (GNC_TREE_VIEW (view)); if (ledger_type == LD2_GL && model->type == GENERAL_JOURNAL2) gnc_tree_view_set_show_column_menu (GNC_TREE_VIEW (view), TRUE); else gnc_tree_view_set_show_column_menu (GNC_TREE_VIEW (view), FALSE); /* This column gets all the free space */ gnc_tree_view_expand_columns (GNC_TREE_VIEW (view), "descnotes", NULL); /* This sets the status color column, 4 is the minimum */ col = gnc_tree_view_find_column_by_name (GNC_TREE_VIEW (view), "status"); if (col != NULL) g_object_set (G_OBJECT(col), "resizable", FALSE, "sizing", GTK_TREE_VIEW_COLUMN_FIXED, "fixed-width", 4, NULL); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), TRUE); gtk_widget_show (GTK_WIDGET (view)); gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (view)); gtk_widget_show (GTK_WIDGET (gsr)); /* Should this be read only */ gnc_tree_view_split_reg_set_read_only (view, gsr->read_only); /* This tells the ledger that we have a valid tree view */ gnc_ledger_display2_set_split_view_refresh (gsr->ledger, TRUE); /* This triggers the update of the summary bar */ g_signal_connect_after (model, "refresh_status_bar", G_CALLBACK (gsr2_redraw_all_cb), gsr); //this works // This will keep scrollbar in sync. g_signal_connect (model, "scroll_sync", G_CALLBACK (gsr2_scroll_sync_cb), gsr); /* This triggers the update of the help text */ g_signal_connect (view, "help_signal", G_CALLBACK (gsr2_emit_help_changed), gsr); // this works gsr2_scroll_value_changed_cb (GTK_ADJUSTMENT (gsr->scroll_adj), gsr); /* This triggers the tooltip to change when scrolling */ g_signal_connect (gsr->scroll_adj, "value-changed", G_CALLBACK (gsr2_scroll_value_changed_cb), gsr); // this works /* This triggers the model update when mouse button released */ g_signal_connect (gsr->scroll_bar, "button-release-event", G_CALLBACK (gsr2_scroll_button_event_cb), gsr); // Connect a call back to update the sort settings. g_signal_connect (GTK_TREE_SORTABLE (s_model), "sort-column-changed", G_CALLBACK (gnc_split_reg2_sort_changed_cb), gsr); LEAVE(" "); }
void gnc_split_register_load (SplitRegister *reg, GList * slist, Account *default_account) { SRInfo *info; Transaction *pending_trans; CursorBuffer *cursor_buffer; GHashTable *trans_table = NULL; CellBlock *cursor_header; CellBlock *lead_cursor; CellBlock *split_cursor; Transaction *blank_trans; Transaction *find_trans; Transaction *trans; CursorClass find_class; Split *find_trans_split; Split *blank_split; Split *find_split; Split *split; Table *table; GList *node; gboolean start_primary_color = TRUE; gboolean found_pending = FALSE; gboolean need_divider_upper = FALSE; gboolean found_divider_upper = FALSE; gboolean found_divider = FALSE; gboolean has_last_num = FALSE; gboolean multi_line; gboolean dynamic; gboolean we_own_slist = FALSE; gboolean use_autoreadonly = qof_book_uses_autoreadonly(gnc_get_current_book()); VirtualCellLocation vcell_loc; VirtualLocation save_loc; int new_trans_split_row = -1; int new_trans_row = -1; int new_split_row = -1; time64 present, autoreadonly_time = 0; g_return_if_fail(reg); table = reg->table; g_return_if_fail(table); info = gnc_split_register_get_info (reg); g_return_if_fail(info); ENTER("reg=%p, slist=%p, default_account=%p", reg, slist, default_account); blank_split = xaccSplitLookup (&info->blank_split_guid, gnc_get_current_book ()); pending_trans = xaccTransLookup (&info->pending_trans_guid, gnc_get_current_book ()); /* make sure we have a blank split */ if (blank_split == NULL) { /* Wouldn't it be a bug to open the new transaction if there was * already a pending transaction? */ g_assert(pending_trans == NULL); blank_split = create_blank_split (default_account, info); } blank_trans = xaccSplitGetParent (blank_split); DEBUG("blank_split=%p, blank_trans=%p, pending_trans=%p", blank_split, blank_trans, pending_trans); info->default_account = *xaccAccountGetGUID (default_account); // gnc_table_leave_update (table, table->current_cursor_loc); multi_line = (reg->style == REG_STYLE_JOURNAL); dynamic = (reg->style == REG_STYLE_AUTO_LEDGER); lead_cursor = gnc_split_register_get_passive_cursor (reg); split_cursor = gnc_table_layout_get_cursor (table->layout, CURSOR_SPLIT); /* figure out where we are going to. */ if (info->traverse_to_new) { find_trans = blank_trans; find_split = NULL; find_trans_split = blank_split; find_class = CURSOR_CLASS_SPLIT; } else { find_trans = info->cursor_hint_trans; find_split = info->cursor_hint_split; find_trans_split = info->cursor_hint_trans_split; find_class = info->cursor_hint_cursor_class; } save_loc = table->current_cursor_loc; /* If the current cursor has changed we save the values for later * possible restoration. */ if (gnc_table_current_cursor_changed (table, TRUE) && (find_split == gnc_split_register_get_current_split (reg))) { cursor_buffer = gnc_cursor_buffer_new (); gnc_table_save_current_cursor (table, cursor_buffer); } else cursor_buffer = NULL; /* disable move callback -- we don't want the cascade of * callbacks while we are fiddling with loading the register */ gnc_table_control_allow_move (table->control, FALSE); /* invalidate the cursor */ { VirtualLocation virt_loc; gnc_virtual_location_init(&virt_loc); gnc_table_move_cursor_gui (table, virt_loc); } /* make sure that the header is loaded */ vcell_loc.virt_row = 0; vcell_loc.virt_col = 0; cursor_header = gnc_table_layout_get_cursor (table->layout, CURSOR_HEADER); gnc_table_set_vcell (table, cursor_header, NULL, TRUE, TRUE, vcell_loc); vcell_loc.virt_row++; /* get the current time and reset the dividing row */ present = gnc_time64_get_today_end (); if (use_autoreadonly) { GDate *d = qof_book_get_autoreadonly_gdate(gnc_get_current_book()); // "d" is NULL if use_autoreadonly is FALSE autoreadonly_time = d ? timespecToTime64(gdate_to_timespec(*d)) : 0; g_date_free(d); } if (info->first_pass) { if (default_account) { const char *last_num = xaccAccountGetLastNum (default_account); if (last_num) { NumCell *cell; cell = (NumCell *) gnc_table_layout_get_cell(table->layout, NUM_CELL); gnc_num_cell_set_last_num (cell, last_num); has_last_num = TRUE; } } /* load up account names into the transfer combobox menus */ gnc_split_register_load_xfer_cells (reg, default_account); gnc_split_register_load_recn_cells (reg); gnc_split_register_load_type_cells (reg); } if (info->separator_changed) change_account_separator (info, table, reg); table->model->dividing_row_upper = -1; table->model->dividing_row = -1; // Ensure that the transaction and splits being edited are in the split // list we're about to load. if (pending_trans != NULL) { for (node = xaccTransGetSplitList(pending_trans); node; node = node->next) { Split *pending_split = (Split*)node->data; if (!xaccTransStillHasSplit(pending_trans, pending_split)) continue; if (g_list_find(slist, pending_split) != NULL) continue; if (g_list_find_custom(slist, pending_trans, _find_split_with_parent_txn) != NULL) continue; if (!we_own_slist) { // lazy-copy slist = g_list_copy(slist); we_own_slist = TRUE; } slist = g_list_append(slist, pending_split); } } if (multi_line) trans_table = g_hash_table_new (g_direct_hash, g_direct_equal); /* populate the table */ for (node = slist; node; node = node->next) { split = node->data; trans = xaccSplitGetParent (split); if (!xaccTransStillHasSplit(trans, split)) continue; if (pending_trans == trans) found_pending = TRUE; /* If the transaction has only one split, and it's not our * pending_trans, then it's another register's blank split and * we don't want to see it. */ else if (xaccTransCountSplits (trans) == 1 && xaccSplitGetAccount (split) == NULL) continue; /* Do not load splits from the blank transaction. */ if (trans == blank_trans) continue; if (multi_line) { /* Skip this split if its transaction has already been loaded. */ if (g_hash_table_lookup (trans_table, trans)) continue; g_hash_table_insert (trans_table, trans, trans); } if (info->show_present_divider && use_autoreadonly && !found_divider_upper) { if (xaccTransGetDate (trans) >= autoreadonly_time) { table->model->dividing_row_upper = vcell_loc.virt_row; found_divider_upper = TRUE; } else { need_divider_upper = TRUE; } } if (info->show_present_divider && !found_divider && (xaccTransGetDate (trans) > present)) { table->model->dividing_row = vcell_loc.virt_row; found_divider = TRUE; } /* If this is the first load of the register, * fill up the quickfill cells. */ if (info->first_pass) add_quickfill_completions(reg->table->layout, trans, split, has_last_num); if (trans == find_trans) new_trans_row = vcell_loc.virt_row; if (split == find_trans_split) new_trans_split_row = vcell_loc.virt_row; gnc_split_register_add_transaction (reg, trans, split, lead_cursor, split_cursor, multi_line, start_primary_color, TRUE, find_trans, find_split, find_class, &new_split_row, &vcell_loc); if (!multi_line) start_primary_color = !start_primary_color; } if (multi_line) g_hash_table_destroy (trans_table); /* add the blank split at the end. */ if (pending_trans == blank_trans) found_pending = TRUE; /* No upper divider yet? Store it now */ if (info->show_present_divider && use_autoreadonly && !found_divider_upper && need_divider_upper) { table->model->dividing_row_upper = vcell_loc.virt_row; found_divider_upper = TRUE; } if (blank_trans == find_trans) new_trans_row = vcell_loc.virt_row; if (blank_split == find_trans_split) new_trans_split_row = vcell_loc.virt_row; /* If we didn't find the pending transaction, it was removed * from the account. */ if (!found_pending) { info->pending_trans_guid = *guid_null (); if (xaccTransIsOpen (pending_trans)) xaccTransCommitEdit (pending_trans); else if (pending_trans) g_assert_not_reached(); pending_trans = NULL; } /* go to blank on first pass */ if (info->first_pass) { new_split_row = -1; new_trans_split_row = -1; new_trans_row = -1; save_loc.vcell_loc = vcell_loc; save_loc.phys_row_offset = 0; save_loc.phys_col_offset = 0; } gnc_split_register_add_transaction (reg, blank_trans, blank_split, lead_cursor, split_cursor, multi_line, start_primary_color, info->blank_split_edited, find_trans, find_split, find_class, &new_split_row, &vcell_loc); /* resize the table to the sizes we just counted above */ /* num_virt_cols is always one. */ gnc_table_set_size (table, vcell_loc.virt_row, 1); /* restore the cursor to its rightful position */ { VirtualLocation trans_split_loc; if (new_split_row > 0) save_loc.vcell_loc.virt_row = new_split_row; else if (new_trans_split_row > 0) save_loc.vcell_loc.virt_row = new_trans_split_row; else if (new_trans_row > 0) save_loc.vcell_loc.virt_row = new_trans_row; trans_split_loc = save_loc; gnc_split_register_get_trans_split (reg, save_loc.vcell_loc, &trans_split_loc.vcell_loc); if (dynamic || multi_line || info->trans_expanded) { gnc_table_set_virt_cell_cursor( table, trans_split_loc.vcell_loc, gnc_split_register_get_active_cursor (reg)); gnc_split_register_set_trans_visible (reg, trans_split_loc.vcell_loc, TRUE, multi_line); info->trans_expanded = (reg->style == REG_STYLE_LEDGER); } else { save_loc = trans_split_loc; info->trans_expanded = FALSE; } if (gnc_table_find_close_valid_cell (table, &save_loc, FALSE)) { gnc_table_move_cursor_gui (table, save_loc); new_split_row = save_loc.vcell_loc.virt_row; if (find_split == gnc_split_register_get_current_split (reg)) gnc_table_restore_current_cursor (table, cursor_buffer); } } gnc_cursor_buffer_destroy (cursor_buffer); cursor_buffer = NULL; update_info (info, reg); gnc_split_register_set_cell_fractions( reg, gnc_split_register_get_current_split (reg)); gnc_table_refresh_gui (table, TRUE); gnc_split_register_show_trans (reg, table->current_cursor_loc.vcell_loc); /* enable callback for cursor user-driven moves */ gnc_table_control_allow_move (table->control, TRUE); if (we_own_slist) g_list_free(slist); LEAVE(" "); }
void xaccTransWriteLog (Transaction *trans, char flag) { GList *node; char trans_guid_str[GUID_ENCODING_LENGTH + 1]; char split_guid_str[GUID_ENCODING_LENGTH + 1]; const char *trans_notes; char dnow[100], dent[100], dpost[100], drecn[100]; Timespec ts; if (!gen_logs) return; if (!trans_log) return; timespecFromTime_t(&ts, time(NULL)); gnc_timespec_to_iso8601_buff (ts, dnow); timespecFromTime_t(&ts, trans->date_entered.tv_sec); gnc_timespec_to_iso8601_buff (ts, dent); timespecFromTime_t(&ts, trans->date_posted.tv_sec); gnc_timespec_to_iso8601_buff (ts, dpost); guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str); trans_notes = xaccTransGetNotes(trans); fprintf (trans_log, "===== START\n"); for (node = trans->splits; node; node = node->next) { Split *split = node->data; const char * accname = ""; char acc_guid_str[GUID_ENCODING_LENGTH + 1]; gnc_numeric amt, val; if (xaccSplitGetAccount(split)) { accname = xaccAccountGetName (xaccSplitGetAccount(split)); guid_to_string_buff(xaccAccountGetGUID(xaccSplitGetAccount(split)), acc_guid_str); } else { acc_guid_str[0] = '\0'; } timespecFromTime_t(&ts, split->date_reconciled.tv_sec); gnc_timespec_to_iso8601_buff (ts, drecn); guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str); amt = xaccSplitGetAmount (split); val = xaccSplitGetValue (split); /* use tab-separated fields */ fprintf (trans_log, "%c\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t" "%s\t%s\t%s\t%s\t%c\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%s\n", flag, trans_guid_str, split_guid_str, /* trans+split make up unique id */ /* Note that the next three strings always exist, * so we don't need to test them. */ dnow, dent, dpost, acc_guid_str, accname ? accname : "", trans->num ? trans->num : "", trans->description ? trans->description : "", trans_notes ? trans_notes : "", split->memo ? split->memo : "", split->action ? split->action : "", split->reconciled, gnc_numeric_num(amt), gnc_numeric_denom(amt), gnc_numeric_num(val), gnc_numeric_denom(val), /* The next string always exists. No need to test it. */ drecn); } fprintf (trans_log, "===== END\n"); /* get data out to the disk */ fflush (trans_log); }
xmlNodePtr gnc_schedXaction_dom_tree_create(SchedXaction *sx) { xmlNodePtr ret; const GDate *date; gint instCount; const GncGUID *templ_acc_guid; gboolean allow_2_2_incompat = TRUE; gchar *name = g_strdup (xaccSchedXactionGetName(sx)); templ_acc_guid = xaccAccountGetGUID(sx->template_acct); /* FIXME: this should be the same as the def in io-gncxml-v2.c */ ret = xmlNewNode (NULL, BAD_CAST GNC_SCHEDXACTION_TAG); if (allow_2_2_incompat) xmlSetProp(ret, BAD_CAST "version", BAD_CAST schedxaction_version2_string); else xmlSetProp(ret, BAD_CAST "version", BAD_CAST schedxaction_version_string); xmlAddChild( ret, guid_to_dom_tree(SX_ID, xaccSchedXactionGetGUID(sx)) ); xmlNewTextChild( ret, NULL, BAD_CAST SX_NAME, checked_char_cast (name)); g_free (name); if (allow_2_2_incompat) { xmlNewTextChild( ret, NULL, BAD_CAST SX_ENABLED, BAD_CAST ( sx->enabled ? "y" : "n" ) ); } xmlNewTextChild( ret, NULL, BAD_CAST SX_AUTOCREATE, BAD_CAST ( sx->autoCreateOption ? "y" : "n" ) ); xmlNewTextChild( ret, NULL, BAD_CAST SX_AUTOCREATE_NOTIFY, BAD_CAST ( sx->autoCreateNotify ? "y" : "n" ) ); xmlAddChild(ret, int_to_dom_tree(SX_ADVANCE_CREATE_DAYS, sx->advanceCreateDays)); xmlAddChild(ret, int_to_dom_tree(SX_ADVANCE_REMIND_DAYS, sx->advanceRemindDays)); instCount = gnc_sx_get_instance_count( sx, NULL ); xmlAddChild( ret, int_to_dom_tree( SX_INSTANCE_COUNT, instCount ) ); xmlAddChild( ret, gdate_to_dom_tree( SX_START, xaccSchedXactionGetStartDate(sx) ) ); date = xaccSchedXactionGetLastOccurDate(sx); if ( g_date_valid( date ) ) { xmlAddChild( ret, gdate_to_dom_tree( SX_LAST, date ) ); } if ( xaccSchedXactionHasOccurDef(sx) ) { xmlAddChild(ret, int_to_dom_tree( SX_NUM_OCCUR, xaccSchedXactionGetNumOccur(sx))); xmlAddChild(ret, int_to_dom_tree( SX_REM_OCCUR, xaccSchedXactionGetRemOccur(sx))); } else if ( xaccSchedXactionHasEndDate(sx) ) { xmlAddChild( ret, gdate_to_dom_tree( SX_END, xaccSchedXactionGetEndDate(sx) ) ); } /* output template account GncGUID */ xmlAddChild( ret, guid_to_dom_tree(SX_TEMPL_ACCT, templ_acc_guid)); if (allow_2_2_incompat) { xmlNodePtr schedule_node = xmlNewNode(NULL, BAD_CAST "sx:schedule"); GList *schedule = gnc_sx_get_schedule(sx); for (; schedule != NULL; schedule = schedule->next) { xmlAddChild(schedule_node, recurrence_to_dom_tree("gnc:recurrence", (Recurrence*)schedule->data)); } xmlAddChild(ret, schedule_node); } /* Output deferred-instance list. */ { xmlNodePtr instNode; SXTmpStateData *tsd; GList *l; for ( l = gnc_sx_get_defer_instances( sx ); l; l = l->next ) { tsd = (SXTmpStateData*)l->data; instNode = xmlNewNode( NULL, BAD_CAST SX_DEFER_INSTANCE ); if ( g_date_valid( &tsd->last_date ) ) { xmlAddChild( instNode, gdate_to_dom_tree( SX_LAST, &tsd->last_date ) ); } xmlAddChild( instNode, int_to_dom_tree( SX_REM_OCCUR, tsd->num_occur_rem ) ); xmlAddChild( instNode, int_to_dom_tree( SX_INSTANCE_COUNT, tsd->num_inst ) ); xmlAddChild( ret, instNode ); } } /* output kvp_frame */ { xmlNodePtr kvpnode = kvp_frame_to_dom_tree( SX_SLOTS, xaccSchedXactionGetSlots(sx) ); if ( kvpnode ) { xmlAddChild(ret, kvpnode); } } return ret; }
static void test_transaction(void) { int i; for (i = 0; i < 50; i++) { Transaction *ran_trn; Account *root; xmlNodePtr test_node; gnc_commodity *com, *new_com; gchar *compare_msg; gchar *filename1; int fd; /* The next line exists for its side effect of creating the * account tree. */ root = get_random_account_tree(book); ran_trn = get_random_transaction(book); new_com = get_random_commodity( book ); if (!ran_trn) { failure_args("transaction_xml", __FILE__, __LINE__, "get_random_transaction returned NULL"); return; } { /* xaccAccountInsertSplit can reorder the splits. */ GList * list = g_list_copy(xaccTransGetSplitList (ran_trn)); GList * node = list; for ( ; node; node = node->next) { Split * s = node->data; Account * a = xaccMallocAccount(book); xaccAccountBeginEdit (a); xaccAccountSetCommodity( a, new_com ); xaccAccountSetCommoditySCU (a, xaccSplitGetAmount (s).denom); xaccAccountInsertSplit (a, s); xaccAccountCommitEdit (a); } g_list_free(list); } com = xaccTransGetCurrency (ran_trn); test_node = gnc_transaction_dom_tree_create(ran_trn); if (!test_node) { failure_args("transaction_xml", __FILE__, __LINE__, "gnc_transaction_dom_tree_create returned NULL"); really_get_rid_of_transaction(ran_trn); continue; } if ((compare_msg = node_and_transaction_equal(test_node, ran_trn)) != NULL) { failure_args("transaction_xml", __FILE__, __LINE__, "node and transaction were not equal: %s", compare_msg); xmlElemDump(stdout, NULL, test_node); printf("\n"); fflush(stdout); xmlFreeNode(test_node); really_get_rid_of_transaction(ran_trn); continue; } else { success_args("transaction_xml", __FILE__, __LINE__, "%d", i ); } filename1 = g_strdup_printf("test_file_XXXXXX"); fd = g_mkstemp(filename1); write_dom_node_to_file(test_node, fd); close(fd); { GList * node = xaccTransGetSplitList (ran_trn); for ( ; node; node = node->next) { Split * s = node->data; Account * a1 = xaccSplitGetAccount(s); Account * a2 = xaccMallocAccount(book); xaccAccountBeginEdit (a2); xaccAccountSetCommoditySCU (a2, xaccAccountGetCommoditySCU (a1)); xaccAccountSetGUID (a2, xaccAccountGetGUID (a1)); xaccAccountCommitEdit (a2); } } { sixtp *parser; tran_data data; data.trn = ran_trn; data.com = com; data.value = i; g_print(" There will follow a bunch of CRIT scrub errors about the account not having a commodity. There isn't an account in the XML, so of course not. Ignore the errors\n"); parser = gnc_transaction_sixtp_parser_create(); if (!gnc_xml_parse_file(parser, filename1, test_add_transaction, (gpointer)&data, book)) { failure_args("gnc_xml_parse_file returned FALSE", __FILE__, __LINE__, "%d", i); } else really_get_rid_of_transaction (data.new_trn); /* no handling of circular data structures. We'll do that later */ /* sixtp_destroy(parser); */ } g_unlink(filename1); g_free(filename1); really_get_rid_of_transaction(ran_trn); xmlFreeNode(test_node); } }
static GNCLedgerDisplay2 * gnc_ledger_display2_internal (Account *lead_account, Query *q, GNCLedgerDisplay2Type ld_type, SplitRegisterType2 reg_type, SplitRegisterStyle2 style, gboolean use_double_line, gboolean is_template ) { GNCLedgerDisplay2 *ld; gint limit; const char *klass; // GList *splits; gboolean display_subaccounts = FALSE; gboolean is_gl = FALSE; switch (ld_type) { case LD2_SINGLE: klass = REGISTER_SINGLE_CM_CLASS; if (reg_type >= NUM_SINGLE_REGISTER_TYPES2) { PERR ("single-account register with wrong split register type"); return NULL; } if (!lead_account) { PERR ("single-account register with no account specified"); return NULL; } if (q) { PWARN ("single-account register with external query"); q = NULL; } ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account); if (ld) return ld; break; case LD2_SUBACCOUNT: klass = REGISTER_SUBACCOUNT_CM_CLASS; if (!lead_account) { PERR ("sub-account register with no lead account"); return NULL; } if (q) { PWARN ("account register with external query"); q = NULL; } ld = gnc_find_first_gui_component (klass, find_by_leader, lead_account); if (ld) return ld; display_subaccounts = TRUE; break; case LD2_GL: klass = REGISTER_GL_CM_CLASS; if (!q) { PWARN ("general journal with no query"); } is_gl = TRUE; break; default: PERR ("bad ledger type: %d", ld_type); return NULL; } ld = g_new (GNCLedgerDisplay2, 1); ld->leader = *xaccAccountGetGUID (lead_account); ld->query = NULL; ld->ld_type = ld_type; ld->loading = FALSE; ld->refresh_ok = FALSE; ld->destroy = NULL; ld->get_parent = NULL; ld->user_data = NULL; limit = gnc_prefs_get_float(GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_MAX_TRANS); /* set up the query filter */ if (q) ld->query = qof_query_copy (q); else gnc_ledger_display2_make_query (ld, limit, reg_type); ld->component_id = gnc_register_gui_component (klass, refresh_handler, close_handler, ld); /******************************************************************\ * The main register window itself * \******************************************************************/ ld->use_double_line_default = use_double_line; ld->model = gnc_tree_model_split_reg_new (reg_type, style, use_double_line, is_template); gnc_tree_model_split_reg_set_data (ld->model, ld, gnc_ledger_display2_parent); gnc_tree_model_split_reg_set_display (ld->model, display_subaccounts, is_gl); // This sets up a call back to reload after changes g_signal_connect (G_OBJECT (ld->model), "refresh_trans", G_CALLBACK (gnc_ledger_display2_refresh_cb), ld ); //FIXME Not Needed ? gnc_ledger_display2_set_watches (ld, splits); // gnc_ledger_display2_set_watches (ld, splits); // Populate the model with an empty split // An empty model could cause our gui callbacks to crash gnc_ledger_display2_refresh_internal (ld, NULL); return ld; }
static gchar* node_and_account_equal (xmlNodePtr node, Account* act) { xmlNodePtr mark; while (g_strcmp0 ((char*)node->name, "text") == 0) { node = node->next; } if (!check_dom_tree_version (node, "2.0.0")) { return g_strdup ("version wrong. Not 2.0.0 or not there"); } if (!node->name || g_strcmp0 ((char*)node->name, "gnc:account")) { return g_strdup ("Name of toplevel node is bad"); } for (mark = node->xmlChildrenNode; mark; mark = mark->next) { if (g_strcmp0 ((char*)mark->name, "text") == 0) { } else if (g_strcmp0 ((char*)mark->name, "act:name") == 0) { if (!equals_node_val_vs_string (mark, xaccAccountGetName (act))) { return g_strdup ("names differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:id") == 0) { if (!equals_node_val_vs_guid (mark, xaccAccountGetGUID (act))) { return g_strdup ("ids differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:type") == 0) { gchar* txt; GNCAccountType type; txt = dom_tree_to_text (mark); if (!txt) { return g_strdup ("couldn't get type string"); } else if (!xaccAccountStringToType (txt, &type)) { g_free (txt); return g_strdup ("couldn't convert type string to int"); } else if (type != xaccAccountGetType (act)) { g_free (txt); return g_strdup ("types differ"); } else { g_free (txt); } } else if (g_strcmp0 ((char*)mark->name, "act:commodity") == 0) { /* This is somewhat BS, because if the commodity isn't a currency (and therefore built in) there isn't a corresponding currency in the XML, skip the test. jralls 2010-11-02 */ if (xaccAccountGetCommodity (act) == NULL) continue; if (!equals_node_val_vs_commodity ( mark, xaccAccountGetCommodity (act), gnc_account_get_book (act))) { return g_strdup ("commodities differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:code") == 0) { if (!equals_node_val_vs_string (mark, xaccAccountGetCode (act))) { return g_strdup ("codes differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:description") == 0) { if (!equals_node_val_vs_string ( mark, xaccAccountGetDescription (act))) { return g_strdup ("descriptions differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:slots") == 0) { /* xaccAccountDeleteOldData (act); */ if (!equals_node_val_vs_kvp_frame (mark, qof_instance_get_slots (QOF_INSTANCE (act)))) { return g_strdup ("slots differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:parent") == 0) { if (!equals_node_val_vs_guid ( mark, xaccAccountGetGUID (gnc_account_get_parent (act)))) { return g_strdup ("parent ids differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:commodity-scu") == 0) { if (!equals_node_val_vs_int (mark, xaccAccountGetCommoditySCU (act))) { return g_strdup ("commodity scus differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:hidden") == 0) { if (!equals_node_val_vs_boolean (mark, xaccAccountGetHidden (act))) { return g_strdup ("Hidden flags differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:placeholder") == 0) { if (!equals_node_val_vs_boolean (mark, xaccAccountGetPlaceholder (act))) { return g_strdup ("Placeholder flags differ"); } } else if (g_strcmp0 ((char*)mark->name, "act:security") == 0) { return NULL; // This tag is ignored. } else { return g_strdup_printf ("unknown node in dom tree: %s", mark->name); } } return NULL; }
TEST_F(ImapBayesTest, ConvertAccountBayes) { // prevent the embedded beginedit/commitedit from doing anything qof_instance_increase_editlevel(QOF_INSTANCE(t_bank_account)); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); gnc_account_imap_add_account_bayes(t_imap, t_list1, t_expense_account1); //Food gnc_account_imap_add_account_bayes(t_imap, t_list2, t_expense_account2); //Drink auto root = qof_instance_get_slots(QOF_INSTANCE(t_bank_account)); auto book = qof_instance_get_slots(QOF_INSTANCE(t_imap->book)); auto acct1_guid = guid_to_string (xaccAccountGetGUID(t_expense_account1)); //Food auto acct2_guid = guid_to_string (xaccAccountGetGUID(t_expense_account2)); //Drink auto acct3_guid = guid_to_string (xaccAccountGetGUID(t_asset_account2)); //Asset-Bank auto acct4_guid = guid_to_string (xaccAccountGetGUID(t_sav_account)); //Sav Bank auto val1 = new KvpValue(static_cast<int64_t>(10)); auto val2 = new KvpValue(static_cast<int64_t>(5)); auto val3 = new KvpValue(static_cast<int64_t>(2)); // Test for existing entries, all will be 1 auto value = root->get_slot({IMAP_FRAME_BAYES, foo, acct1_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, bar, acct1_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, baz, acct2_guid}); EXPECT_EQ(1, value->get<int64_t>()); value = root->get_slot({IMAP_FRAME_BAYES, waldo, acct2_guid}); EXPECT_EQ(1, value->get<int64_t>()); // Set up some old entries root->set_path({IMAP_FRAME_BAYES, pepper, "Asset-Bank"}, val1); root->set_path({IMAP_FRAME_BAYES, salt, "Asset-Bank#Bank"}, val1); root->set_path({IMAP_FRAME_BAYES, salt, "Asset>Bank#Bank"}, val2); root->set_path({IMAP_FRAME_BAYES, pork, "Expense#Food"}, val2); root->set_path({IMAP_FRAME_BAYES, sausage, "Expense#Drink"}, val3); root->set_path({IMAP_FRAME_BAYES, foo, "Expense#Food"}, val2); EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account))); EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); qof_instance_mark_clean(QOF_INSTANCE(t_bank_account)); // Start Convert gnc_account_imap_convert_bayes (t_imap->book); // convert from 'Asset-Bank' to 'Asset-Bank' guid value = root->get_slot({IMAP_FRAME_BAYES, pepper, acct3_guid}); EXPECT_EQ(10, value->get<int64_t>()); // convert from 'Asset-Bank#Bank' to 'Sav Bank' guid value = root->get_slot({IMAP_FRAME_BAYES, salt, acct4_guid}); EXPECT_EQ(10, value->get<int64_t>()); // convert from 'Expense#Food' to 'Food' guid value = root->get_slot({IMAP_FRAME_BAYES, pork, acct1_guid}); EXPECT_EQ(5, value->get<int64_t>()); // convert from 'Expense#Drink' to 'Drink' guid value = root->get_slot({IMAP_FRAME_BAYES, sausage, acct2_guid}); EXPECT_EQ(2, value->get<int64_t>()); // convert from 'Expense#Food' to 'Food' guid but add to original value value = root->get_slot({IMAP_FRAME_BAYES, foo, acct1_guid}); EXPECT_EQ(6, value->get<int64_t>()); // Check for run once flag auto vals = book->get_slot("changed-bayesian-to-guid"); EXPECT_STREQ("true", vals->get<const char*>()); EXPECT_EQ(1, qof_instance_get_editlevel(QOF_INSTANCE(t_bank_account))); EXPECT_TRUE(qof_instance_get_dirty_flag(QOF_INSTANCE(t_bank_account))); }
static xmlNodePtr split_to_dom_tree (const gchar* tag, Split* spl) { xmlNodePtr ret; ret = xmlNewNode (NULL, BAD_CAST tag); xmlAddChild (ret, guid_to_dom_tree ("split:id", xaccSplitGetGUID (spl))); { char* memo = g_strdup (xaccSplitGetMemo (spl)); if (memo && g_strcmp0 (memo, "") != 0) { xmlNewTextChild (ret, NULL, BAD_CAST "split:memo", checked_char_cast (memo)); } g_free (memo); } { char* action = g_strdup (xaccSplitGetAction (spl)); if (action && g_strcmp0 (action, "") != 0) { xmlNewTextChild (ret, NULL, BAD_CAST "split:action", checked_char_cast (action)); } g_free (action); } { char tmp[2]; tmp[0] = xaccSplitGetReconcile (spl); tmp[1] = '\0'; xmlNewTextChild (ret, NULL, BAD_CAST "split:reconciled-state", BAD_CAST tmp); } add_timespec (ret, "split:reconcile-date", xaccSplitRetDateReconciledTS (spl), FALSE); add_gnc_num (ret, "split:value", xaccSplitGetValue (spl)); add_gnc_num (ret, "split:quantity", xaccSplitGetAmount (spl)); { Account* account = xaccSplitGetAccount (spl); xmlAddChild (ret, guid_to_dom_tree ("split:account", xaccAccountGetGUID (account))); } { GNCLot* lot = xaccSplitGetLot (spl); if (lot) { xmlAddChild (ret, guid_to_dom_tree ("split:lot", gnc_lot_get_guid (lot))); } } /* xmlAddChild won't do anything with a NULL, so tests are superfluous. */ xmlAddChild (ret, qof_instance_slots_to_dom_tree ("split:slots", QOF_INSTANCE (spl))); return ret; }
static xmlNodePtr split_to_dom_tree(const gchar *tag, Split *spl) { xmlNodePtr ret; ret = xmlNewNode(NULL, BAD_CAST tag); xmlAddChild(ret, guid_to_dom_tree("split:id", xaccSplitGetGUID(spl))); { char *memo = g_strdup (xaccSplitGetMemo(spl)); if (memo && g_strcmp0(memo, "") != 0) { xmlNewTextChild(ret, NULL, BAD_CAST "split:memo", checked_char_cast (memo)); } g_free (memo); } { char *action = g_strdup (xaccSplitGetAction(spl)); if (action && g_strcmp0(action, "") != 0) { xmlNewTextChild(ret, NULL, BAD_CAST "split:action", checked_char_cast (action)); } g_free (action); } { char tmp[2]; tmp[0] = xaccSplitGetReconcile(spl); tmp[1] = '\0'; xmlNewTextChild(ret, NULL, BAD_CAST "split:reconciled-state", BAD_CAST tmp); } add_timespec(ret, "split:reconcile-date", xaccSplitRetDateReconciledTS(spl), FALSE); add_gnc_num(ret, "split:value", xaccSplitGetValue(spl)); add_gnc_num(ret, "split:quantity", xaccSplitGetAmount(spl)); { Account * account = xaccSplitGetAccount (spl); xmlAddChild (ret, guid_to_dom_tree("split:account", xaccAccountGetGUID (account))); } { GNCLot * lot = xaccSplitGetLot (spl); if (lot) { xmlAddChild (ret, guid_to_dom_tree("split:lot", gnc_lot_get_guid(lot))); } } { xmlNodePtr kvpnode = kvp_frame_to_dom_tree("split:slots", xaccSplitGetSlots(spl)); if (kvpnode) { xmlAddChild(ret, kvpnode); } } return ret; }