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;
83void gnc_stock_split_assistant_window_destroy_cb (GtkWidget *
object, gpointer user_data);
84void gnc_stock_split_assistant_prepare (GtkAssistant *assistant,
87void gnc_stock_split_assistant_details_prepare (GtkAssistant *assistant,
89gboolean gnc_stock_split_assistant_details_complete (GtkAssistant *assistant,
91gboolean gnc_stock_split_assistant_cash_complete (GtkAssistant *assistant,
93void gnc_stock_split_assistant_finish (GtkAssistant *assistant,
95void gnc_stock_split_assistant_cancel (GtkAssistant *gtkassistant,
100gnc_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);
190selection_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),
252void 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);
263gnc_stock_split_assistant_details_prepare (GtkAssistant *assistant,
268 refresh_details_page(info);
273gnc_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)
309gnc_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)
339gnc_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);
477gnc_stock_split_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
480 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
485gnc_stock_split_assistant_view_filter_income (
Account *account,
491 return (type == ACCT_TYPE_INCOME);
496gnc_stock_split_assistant_view_filter_asset (
Account *account,
502 return ((type == ACCT_TYPE_BANK) || (type == ACCT_TYPE_CASH) ||
503 (type == ACCT_TYPE_ASSET));
508gnc_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));
521gnc_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));
733refresh_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;
750close_handler (gpointer user_data)
754 gtk_widget_destroy (info->window);
766gnc_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));
API for Transactions and Splits (journal entries)
Currency selection widget.
GtkTreeView implementation for gnucash account tree.
utility functions for the GnuCash UI
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
GList * gnc_account_get_descendants_sorted(const Account *account)
This function returns a GList containing all the descendants of the specified account,...
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed.
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...
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false.
gnc_numeric xaccAccountGetBalance(const Account *acc)
Get the current balance of the account, which may include future splits.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equivalent.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
time64 gnc_time(time64 *tbuf)
get the current time
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
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 xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
void gnc_currency_edit_set_currency(GNCCurrencyEdit *gce, const gnc_commodity *currency)
Set the widget to display a certain currency name.
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...
gnc_commodity * gnc_currency_edit_get_currency(GNCCurrencyEdit *gce)
Retrieve the displayed currency of the widget.
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
Create a new account tree view.
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.
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.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
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_numeric_positive_p(gnc_numeric a)
Returns 1 if a > 0, otherwise returns 0.
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.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
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.
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
Split * xaccMallocSplit(QofBook *book)
Constructor.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
void xaccSplitMakeStockSplit(Split *s)
Mark a split to be of type stock split - after this, you shouldn't modify the value anymore,...