29 #include <glib/gi18n.h> 32 #include "engine-helpers.h" 33 #include "dialog-utils.h" 34 #include "assistant-stock-split.h" 35 #include "gnc-amount-edit.h" 36 #include "gnc-component-manager.h" 38 #include "gnc-date-edit.h" 40 #include "gnc-gui-query.h" 46 #define ASSISTANT_STOCK_SPLIT_CM_CLASS "assistant-stock-split" 50 SPLIT_COL_ACCOUNT = 0,
61 GtkWidget * assistant;
64 GtkWidget * account_view;
68 GtkWidget * date_edit;
69 GtkWidget * distribution_edit;
70 GtkWidget * description_entry;
71 GtkWidget * price_edit;
72 GtkWidget * price_currency_edit;
75 GtkWidget * cash_edit;
76 GtkWidget * memo_entry;
77 GtkWidget * income_tree;
78 GtkWidget * asset_tree;
83 void gnc_stock_split_assistant_window_destroy_cb (GtkWidget *
object, gpointer user_data);
84 void gnc_stock_split_assistant_prepare (GtkAssistant *assistant,
87 void gnc_stock_split_assistant_details_prepare (GtkAssistant *assistant,
89 gboolean gnc_stock_split_assistant_details_complete (GtkAssistant *assistant,
91 gboolean gnc_stock_split_assistant_cash_complete (GtkAssistant *assistant,
93 void gnc_stock_split_assistant_finish (GtkAssistant *assistant,
95 void gnc_stock_split_assistant_cancel (GtkAssistant *gtkassistant,
100 gnc_stock_split_assistant_window_destroy_cb (GtkWidget *
object, gpointer user_data)
104 gnc_unregister_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
113 GtkTreeRowReference *reference = NULL;
123 view = GTK_TREE_VIEW(info->account_view);
124 list = GTK_LIST_STORE(gtk_tree_view_get_model(view));
126 gtk_list_store_clear (list);
129 for (node = accounts; node; node = node->next)
133 const gnc_commodity *commodity;
149 print_info = gnc_account_print_info (account, FALSE);
151 gtk_list_store_append(list, &iter);
152 gtk_list_store_set(list, &iter,
153 SPLIT_COL_ACCOUNT, account,
154 SPLIT_COL_FULLNAME, full_name,
159 if (account == selected_account)
161 path = gtk_tree_model_get_path(GTK_TREE_MODEL(list), &iter);
162 reference = gtk_tree_row_reference_new(GTK_TREE_MODEL(list), path);
163 gtk_tree_path_free(path);
170 g_list_free(accounts);
174 GtkTreeSelection* selection = gtk_tree_view_get_selection(view);
175 path = gtk_tree_row_reference_get_path(reference);
176 gtk_tree_row_reference_free(reference);
179 gtk_tree_selection_select_path(selection, path);
180 gtk_tree_view_scroll_to_cell(view, path, NULL, TRUE, 0.5, 0.0);
181 gtk_tree_path_free(path);
190 selection_changed_cb (GtkTreeSelection *selection,
197 if (!gtk_tree_selection_get_selected(selection, &list, &iter))
199 gtk_tree_model_get(list, &iter,
200 SPLIT_COL_ACCOUNT, &info->acct,
209 gnc_commodity *commodity, *currency;
215 account = info->acct;
217 g_return_if_fail (account != NULL);
219 print_info = gnc_account_print_info (account, FALSE);
221 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (info->distribution_edit),
223 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (info->distribution_edit),
227 book = gnc_account_get_book (account);
235 currency = gnc_price_get_commodity(prices->data);
237 currency = gnc_price_get_currency(prices->data);
247 (GNC_CURRENCY_EDIT (info->price_currency_edit),
252 void gnc_stock_split_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
255 gint currentpage = gtk_assistant_get_current_page(assistant);
257 if (currentpage == 2)
258 gnc_stock_split_assistant_details_prepare(assistant, user_data);
263 gnc_stock_split_assistant_details_prepare (GtkAssistant *assistant,
268 refresh_details_page(info);
273 gnc_stock_split_assistant_details_complete (GtkAssistant *assistant,
278 gnc_commodity *currency;
282 result = gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->distribution_edit),
283 &amount, TRUE, NULL);
291 print_info = gnc_commodity_print_info (currency, FALSE);
292 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (info->price_edit), print_info);
293 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (info->price_edit), 0);
295 result = gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT(info->price_edit),
296 &amount, TRUE, NULL);
299 else if ( result > 0)
309 gnc_stock_split_assistant_cash_complete (GtkAssistant *assistant,
317 result = gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->cash_edit), &amount, TRUE, NULL);
320 else if ( result > 0)
339 gnc_stock_split_assistant_finish (GtkAssistant *assistant,
343 GList *account_commits;
352 account = info->acct;
353 g_return_if_fail (account != NULL);
355 amount = gnc_amount_edit_get_amount
356 (GNC_AMOUNT_EDIT (info->distribution_edit));
359 gnc_suspend_gui_refresh ();
367 date = gnc_date_edit_get_date (GNC_DATE_EDIT (info->date_edit));
371 const char *description;
373 description = gtk_entry_get_text (GTK_ENTRY (info->description_entry));
380 account_commits = g_list_prepend (NULL, account);
391 gnc_set_num_action (NULL, split, NULL, C_(
"Action Column",
"Split"));
393 amount = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (info->price_edit));
401 ce = GNC_CURRENCY_EDIT (info->price_currency_edit);
404 gnc_price_begin_edit (price);
407 gnc_price_set_time64 (price, date);
408 gnc_price_set_source (price, PRICE_SOURCE_STOCK_SPLIT);
409 gnc_price_set_typestr (price, PRICE_TYPE_UNK);
410 gnc_price_set_value (price, amount);
411 gnc_price_commit_edit (price);
413 book = gnc_get_current_book ();
417 gnc_error_dialog (GTK_WINDOW (info->window),
"%s", _(
"Error adding price."));
421 amount = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (info->cash_edit));
426 memo = gtk_entry_get_text (GTK_ENTRY (info->memo_entry));
434 account_commits = g_list_prepend (account_commits, account);
452 account_commits = g_list_prepend (account_commits, account);
466 for (node = account_commits; node; node = node->next)
468 g_list_free (account_commits);
470 gnc_resume_gui_refresh ();
472 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
477 gnc_stock_split_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
480 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
485 gnc_stock_split_assistant_view_filter_income (
Account *account,
496 gnc_stock_split_assistant_view_filter_asset (
Account *account,
508 gnc_stock_split_details_valid_cb (GtkWidget *widget, gpointer user_data)
511 GtkAssistant *assistant = GTK_ASSISTANT(info->window);
512 gint num = gtk_assistant_get_current_page (assistant);
513 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
515 gtk_assistant_set_page_complete (assistant, page,
516 gnc_stock_split_assistant_details_complete (assistant, user_data));
521 gnc_stock_split_cash_valid_cb (GtkWidget *widget, gpointer user_data)
524 GtkAssistant *assistant = GTK_ASSISTANT(info->window);
525 gint num = gtk_assistant_get_current_page (assistant);
526 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
528 gtk_assistant_set_page_complete (assistant, page,
529 gnc_stock_split_assistant_cash_complete (assistant, user_data));
539 builder = gtk_builder_new();
540 gnc_builder_add_from_file (builder ,
"assistant-stock-split.glade",
"stock_split_assistant");
541 window = GTK_WIDGET(gtk_builder_get_object (builder,
"stock_split_assistant"));
542 info->window = window;
545 gtk_widget_set_name (GTK_WIDGET(window),
"gnc-id-assistant-stock-split");
548 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
549 GTK_WIDGET(gtk_builder_get_object(builder,
"intro_page_label")),
551 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
552 GTK_WIDGET(gtk_builder_get_object(builder,
"stock_account_page")),
554 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
555 GTK_WIDGET(gtk_builder_get_object(builder,
"stock_cash_page")),
557 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
558 GTK_WIDGET(gtk_builder_get_object(builder,
"finish_page_label")),
565 GtkTreeSelection *selection;
566 GtkCellRenderer *renderer;
567 GtkTreeViewColumn *column;
569 info->account_view = GTK_WIDGET(gtk_builder_get_object(builder,
"account_view"));
571 view = GTK_TREE_VIEW(info->account_view);
574 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(view), gnc_tree_view_get_grid_lines_pref ());
576 store = gtk_list_store_new(NUM_SPLIT_COLS, G_TYPE_POINTER, G_TYPE_STRING,
577 G_TYPE_STRING, G_TYPE_STRING);
578 gtk_tree_view_set_model(view, GTK_TREE_MODEL(store));
579 g_object_unref(store);
581 renderer = gtk_cell_renderer_text_new();
582 column = gtk_tree_view_column_new_with_attributes(_(
"Account"), renderer,
583 "text", SPLIT_COL_FULLNAME,
585 gtk_tree_view_append_column(view, column);
587 renderer = gtk_cell_renderer_text_new();
588 column = gtk_tree_view_column_new_with_attributes(_(
"Symbol"), renderer,
589 "text", SPLIT_COL_MNEMONIC,
591 gtk_tree_view_append_column(view, column);
593 renderer = gtk_cell_renderer_text_new();
594 column = gtk_tree_view_column_new_with_attributes(_(
"Shares"), renderer,
595 "text", SPLIT_COL_SHARES,
597 gtk_tree_view_append_column(view, column);
599 selection = gtk_tree_view_get_selection(view);
600 gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
601 g_signal_connect (selection,
"changed",
602 G_CALLBACK (selection_changed_cb), info);
613 table = GTK_WIDGET(gtk_builder_get_object(builder,
"stock_details_table"));
614 info->description_entry = GTK_WIDGET(gtk_builder_get_object(builder,
"description_entry"));
616 date = gnc_date_edit_new (
gnc_time (NULL), FALSE, FALSE);
617 gtk_grid_attach (GTK_GRID(
table), date, 1, 0, 1, 1);
618 gtk_widget_show (date);
619 info->date_edit = date;
621 label = GTK_WIDGET(gtk_builder_get_object(builder,
"date_label"));
622 gnc_date_make_mnemonic_target (GNC_DATE_EDIT(date), label);
624 amount = gnc_amount_edit_new ();
625 g_signal_connect (amount,
"changed",
626 G_CALLBACK (gnc_stock_split_details_valid_cb), info);
627 gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (amount), TRUE);
628 gtk_grid_attach (GTK_GRID(
table), amount, 1, 1, 1, 1);
629 gtk_widget_show (amount);
630 info->distribution_edit = amount;
632 label = GTK_WIDGET(gtk_builder_get_object(builder,
"distribution_label"));
633 gnc_amount_edit_make_mnemonic_target (GNC_AMOUNT_EDIT(amount), label);
635 amount = gnc_amount_edit_new ();
636 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (amount),
638 g_signal_connect (amount,
"changed",
639 G_CALLBACK (gnc_stock_split_details_valid_cb), info);
640 gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (amount), TRUE);
641 gtk_grid_attach (GTK_GRID(
table), amount, 1, 5, 1, 1);
642 gtk_widget_show (amount);
643 info->price_edit = amount;
645 label = GTK_WIDGET(gtk_builder_get_object(builder,
"price_label"));
646 gnc_amount_edit_make_mnemonic_target (GNC_AMOUNT_EDIT(amount), label);
650 gtk_widget_show (info->price_currency_edit);
651 gtk_grid_attach (GTK_GRID(
table), info->price_currency_edit, 1, 6, 1, 1);
652 g_signal_connect (info->price_currency_edit,
"changed",
653 G_CALLBACK (gnc_stock_split_details_valid_cb), info);
663 GtkTreeSelection *selection;
665 box = GTK_WIDGET(gtk_builder_get_object(builder,
"cash_box"));
666 amount = gnc_amount_edit_new ();
667 g_signal_connect (amount,
"changed",
668 G_CALLBACK (gnc_stock_split_cash_valid_cb), info);
669 gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (amount), TRUE);
670 gtk_box_pack_start (GTK_BOX (box), amount, TRUE, TRUE, 0);
671 info->cash_edit = amount;
673 label = GTK_WIDGET(gtk_builder_get_object(builder,
"cash_label"));
674 gtk_label_set_mnemonic_widget(GTK_LABEL(label), amount);
676 info->memo_entry = GTK_WIDGET(gtk_builder_get_object(builder,
"memo_entry"));
680 info->income_tree = tree;
682 gnc_stock_split_assistant_view_filter_income,
686 gtk_widget_show (tree);
688 gtk_tree_view_expand_all (GTK_TREE_VIEW(tree));
689 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
690 gtk_tree_selection_unselect_all (selection);
691 g_signal_connect (selection,
"changed",
692 G_CALLBACK (gnc_stock_split_cash_valid_cb), info);
694 label = GTK_WIDGET(gtk_builder_get_object(builder,
"income_label"));
695 gtk_label_set_mnemonic_widget (GTK_LABEL(label), tree);
697 scroll = GTK_WIDGET(gtk_builder_get_object(builder,
"income_scroll"));
698 gtk_container_add (GTK_CONTAINER (scroll), tree);
702 info->asset_tree = tree;
704 gnc_stock_split_assistant_view_filter_asset,
708 gtk_widget_show (tree);
710 label = GTK_WIDGET(gtk_builder_get_object(builder,
"asset_label"));
711 gtk_label_set_mnemonic_widget (GTK_LABEL(label), tree);
713 scroll = GTK_WIDGET(gtk_builder_get_object(builder,
"asset_scroll"));
714 gtk_container_add (GTK_CONTAINER (scroll), tree);
716 gtk_tree_view_expand_all (GTK_TREE_VIEW(tree));
717 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
718 gtk_tree_selection_unselect_all (selection);
719 g_signal_connect (selection,
"changed",
720 G_CALLBACK (gnc_stock_split_cash_valid_cb), info);
723 g_signal_connect (G_OBJECT(window),
"destroy",
724 G_CALLBACK (gnc_stock_split_assistant_window_destroy_cb), info);
726 gtk_builder_connect_signals(builder, info);
727 g_object_unref(G_OBJECT(builder));
733 refresh_handler (GHashTable *changes, gpointer user_data)
738 old_account = info->acct;
740 if (fill_account_list (info, info->acct) == 0)
742 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
746 if (NULL == info->acct || old_account == info->acct)
return;
750 close_handler (gpointer user_data)
754 gtk_widget_destroy (info->window);
766 gnc_stock_split_dialog (GtkWidget *parent,
Account * initial)
775 gnc_stock_split_assistant_create (info);
777 component_id = gnc_register_gui_component (ASSISTANT_STOCK_SPLIT_CM_CLASS,
778 refresh_handler, close_handler,
781 gnc_gui_component_watch_entity_type (component_id,
783 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
785 if (fill_account_list (info, initial) == 0)
787 gnc_warning_dialog (GTK_WINDOW (parent),
"%s", _(
"You don't have any stock accounts with balances!"));
788 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
792 gtk_window_set_transient_for (GTK_WINDOW (info->window), GTK_WINDOW(parent));
793 gtk_widget_show_all (info->window);
795 gnc_window_adjust_for_screen (GTK_WINDOW(info->window));
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
void gnc_price_list_destroy(PriceList *prices)
gnc_price_list_destroy - destroy the given price list, calling gnc_price_unref on all the prices incl...
GNCPrice * gnc_price_create(QofBook *book)
gnc_price_create - returns a newly allocated and initialized price with a reference count of 1...
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
void xaccSplitMakeStockSplit(Split *s)
Mark a split to be of type stock split - after this, you shouldn't modify the value anymore...
GList * gnc_account_get_descendants_sorted(const Account *account)
This function returns a GList containing all the descendants of the specified account, sorted at each level.
void gnc_currency_edit_set_currency(GNCCurrencyEdit *gce, const gnc_commodity *currency)
Set the widget to display a certain currency name.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false. ...
utility functions for the GnuCash UI
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
Currency selection widget.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
void gnc_tree_view_account_set_filter(GncTreeViewAccount *view, gnc_tree_view_account_filter_func func, gpointer data, GSourceFunc destroy)
This function attaches a filter function to the given account tree.
gchar * gnc_account_get_full_name(const Account *account)
The gnc_account_get_full_name routine returns the fully qualified name of the account using the given...
GtkTreeView implementation for gnucash account tree.
Income accounts are used to denote income.
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
Create a new account tree view.
The bank account type denotes a savings or checking account held at a bank.
gnc_commodity * gnc_currency_edit_get_currency(GNCCurrencyEdit *gce)
Retrieve the displayed currency of the widget.
PriceList * gnc_pricedb_lookup_latest_any_currency(GNCPriceDB *db, const gnc_commodity *commodity)
Find the most recent price between a commodity and all other commodities.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
gnc_numeric xaccAccountGetBalance(const Account *acc)
Get the current balance of the account, which may include future splits.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
gboolean gnc_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
Split * xaccMallocSplit(QofBook *book)
Constructor.
GtkWidget * gnc_currency_edit_new(void)
Create a new GNCCurrencyEdit widget which can be used to provide an easy way to enter ISO currency co...
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
Account * gnc_tree_view_account_get_selected_account(GncTreeViewAccount *view)
This function returns the account associated with the selected item in the account tree view...
time64 gnc_time(time64 *tbuf)
get the current time
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
API for Transactions and Splits (journal entries)
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equivalent.