GnuCash c935c2f+
Loading...
Searching...
No Matches
assistant-stock-split.c
1/********************************************************************\
2 * assistant-stock-split.c -- stock split assistant for GnuCash *
3 * Copyright (C) 2001 Gnumatic, Inc. *
4 * Copyright (c) 2001 Dave Peticolas <dave@krondo.com> *
5 * Copyright (c) 2006 David Hampton <hampton@employees.org> *
6 * Copyright (C) 2011 Robert Fewell *
7 * *
8 * This program is free software; you can redistribute it and/or *
9 * modify it under the terms of the GNU General Public License as *
10 * published by the Free Software Foundation; either version 2 of *
11 * the License, or (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License*
19 * along with this program; if not, contact: *
20 * *
21 * Free Software Foundation Voice: +1-617-542-5942 *
22 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
23 * Boston, MA 02110-1301, USA gnu@gnu.org *
24\********************************************************************/
25
26#include <config.h>
27
28#include <gtk/gtk.h>
29#include <glib/gi18n.h>
30
31#include "Transaction.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"
37#include "gnc-currency-edit.h"
38#include "gnc-date-edit.h"
39#include "qof.h"
40#include "gnc-gui-query.h"
42#include "gnc-ui.h"
43#include "gnc-ui-util.h"
44
45
46#define ASSISTANT_STOCK_SPLIT_CM_CLASS "assistant-stock-split"
47
48enum split_cols
49{
50 SPLIT_COL_ACCOUNT = 0,
51 SPLIT_COL_FULLNAME,
52 SPLIT_COL_MNEMONIC,
53 SPLIT_COL_SHARES,
54 NUM_SPLIT_COLS
55};
56
58typedef struct
59{
60 GtkWidget * window;
61 GtkWidget * assistant;
62
63 /* account page data */
64 GtkWidget * account_view;
65 Account * acct;
66
67 /* info page data */
68 GtkWidget * date_edit;
69 GtkWidget * distribution_edit;
70 GtkWidget * description_entry;
71 GtkWidget * price_edit;
72 GtkWidget * price_currency_edit;
73
74 /* cash in lieu page data */
75 GtkWidget * cash_edit;
76 GtkWidget * memo_entry;
77 GtkWidget * income_tree;
78 GtkWidget * asset_tree;
80
81
83void gnc_stock_split_assistant_window_destroy_cb (GtkWidget *object, gpointer user_data);
84void gnc_stock_split_assistant_prepare (GtkAssistant *assistant,
85 GtkWidget *page,
86 gpointer user_data);
87void gnc_stock_split_assistant_details_prepare (GtkAssistant *assistant,
88 gpointer user_data);
89gboolean gnc_stock_split_assistant_details_complete (GtkAssistant *assistant,
90 gpointer user_data);
91gboolean gnc_stock_split_assistant_cash_complete (GtkAssistant *assistant,
92 gpointer user_data);
93void gnc_stock_split_assistant_finish (GtkAssistant *assistant,
94 gpointer user_data);
95void gnc_stock_split_assistant_cancel (GtkAssistant *gtkassistant,
96 gpointer user_data);
97
98/******* implementations ***********************************************/
99void
100gnc_stock_split_assistant_window_destroy_cb (GtkWidget *object, gpointer user_data)
101{
102 StockSplitInfo *info = user_data;
103
104 gnc_unregister_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
105
106 g_free (info);
107}
108
109
110static int
111fill_account_list (StockSplitInfo *info, Account *selected_account)
112{
113 GtkTreeRowReference *reference = NULL;
114 GtkTreeView *view;
115 GtkListStore *list;
116 GtkTreeIter iter;
117 GtkTreePath *path;
118 GList *accounts;
119 GList *node;
120 gint rows = 0;
121 gchar *full_name;
122
123 view = GTK_TREE_VIEW(info->account_view);
124 list = GTK_LIST_STORE(gtk_tree_view_get_model(view));
125
126 gtk_list_store_clear (list);
127
128 accounts = gnc_account_get_descendants_sorted (gnc_get_current_root_account ());
129 for (node = accounts; node; node = node->next)
130 {
131 Account *account = node->data;
132 GNCPrintAmountInfo print_info;
133 const gnc_commodity *commodity;
134 gnc_numeric balance;
135
136 if (!xaccAccountIsPriced(account))
137 continue;
138
139 balance = xaccAccountGetBalance (account);
140 if (gnc_numeric_zero_p (balance))
141 continue;
142
143 if (xaccAccountGetPlaceholder (account))
144 continue;
145
146 commodity = xaccAccountGetCommodity (account);
147
148 full_name = gnc_account_get_full_name (account);
149 print_info = gnc_account_print_info (account, FALSE);
150
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,
155 SPLIT_COL_MNEMONIC, gnc_commodity_get_mnemonic(commodity),
156 SPLIT_COL_SHARES, xaccPrintAmount(balance, print_info),
157 -1);
158
159 if (account == selected_account)
160 {
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);
164 }
165
166 g_free (full_name);
167
168 rows++;
169 }
170 g_list_free(accounts);
171
172 if (reference)
173 {
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);
177 if (path)
178 {
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);
182 }
183 }
184
185 return rows;
186}
187
188
189static void
190selection_changed_cb (GtkTreeSelection *selection,
191 gpointer user_data)
192{
193 StockSplitInfo *info = user_data;
194 GtkTreeModel *list;
195 GtkTreeIter iter;
196
197 if (!gtk_tree_selection_get_selected(selection, &list, &iter))
198 return;
199 gtk_tree_model_get(list, &iter,
200 SPLIT_COL_ACCOUNT, &info->acct,
201 -1);
202}
203
204
205static void
206refresh_details_page (StockSplitInfo *info)
207{
208 GNCPrintAmountInfo print_info;
209 gnc_commodity *commodity, *currency;
210 Account *account;
211 QofBook *book;
212 GNCPriceDB *db;
213 GList *prices;
214
215 account = info->acct;
216
217 g_return_if_fail (account != NULL);
218
219 print_info = gnc_account_print_info (account, FALSE);
220
221 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (info->distribution_edit),
222 print_info);
223 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (info->distribution_edit),
225
226 commodity = xaccAccountGetCommodity (account);
227 book = gnc_account_get_book (account);
228 db = gnc_pricedb_get_db(book);
229
230 prices = gnc_pricedb_lookup_latest_any_currency(db, commodity);
231 if (prices)
232 {
233 /* Use the first existing price */
234 if (gnc_commodity_equiv (commodity, gnc_price_get_currency(prices->data)))
235 currency = gnc_price_get_commodity(prices->data);
236 else
237 currency = gnc_price_get_currency(prices->data);
238 }
239 else
240 {
241 /* Take a wild guess. */
242 currency = gnc_default_currency ();
243 }
245
247 (GNC_CURRENCY_EDIT (info->price_currency_edit),
248 currency);
249}
250
251
252void gnc_stock_split_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
253 gpointer user_data)
254{
255 gint currentpage = gtk_assistant_get_current_page(assistant);
256
257 if (currentpage == 2) /* Current page is details page */
258 gnc_stock_split_assistant_details_prepare(assistant, user_data);
259}
260
261
262void
263gnc_stock_split_assistant_details_prepare (GtkAssistant *assistant,
264 gpointer user_data)
265{
266 StockSplitInfo *info = user_data;
267
268 refresh_details_page(info);
269}
270
271
272gboolean
273gnc_stock_split_assistant_details_complete (GtkAssistant *assistant,
274 gpointer user_data)
275{
276 StockSplitInfo *info = user_data;
277 GNCPrintAmountInfo print_info;
278 gnc_commodity *currency;
279 gnc_numeric amount;
280 gint result;
281
282 result = gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->distribution_edit),
283 &amount, TRUE, NULL);
284 if ( result != 0)
285 return FALSE; /* Parsing error or field is empty */
286
287 if (gnc_numeric_zero_p (amount))
288 return FALSE; /* field value is 0 */
289
290 currency = gnc_currency_edit_get_currency (GNC_CURRENCY_EDIT(info->price_currency_edit));
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);
294
295 result = gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT(info->price_edit),
296 &amount, TRUE, NULL);
297 if (result == -1)
298 return TRUE; /* Optional field is empty */
299 else if ( result > 0)
300 return FALSE; /* Parsing error */
301 else if (gnc_numeric_negative_p (amount))
302 return FALSE; /* Negative price is not allowed */
303 else
304 return TRUE; /* Valid positive price */
305}
306
307
308gboolean
309gnc_stock_split_assistant_cash_complete (GtkAssistant *assistant,
310 gpointer user_data)
311{
312 StockSplitInfo *info = user_data;
313 gnc_numeric amount;
314 gint result;
315 Account *account;
316
317 result = gnc_amount_edit_expr_is_valid (GNC_AMOUNT_EDIT (info->cash_edit), &amount, TRUE, NULL);
318 if (result == -1)
319 return TRUE; /* Optional field is empty */
320 else if ( result > 0)
321 return FALSE; /* Parsing error */
322 else if (gnc_numeric_negative_p (amount))
323 return FALSE; /* Negative cash amount is not allowed */
324
325 /* We have a positive cash amount */
326 account = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT(info->income_tree));
327 if (!account)
328 return FALSE;
329
330 account = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT(info->asset_tree));
331 if (!account)
332 return FALSE;
333
334 return TRUE;
335}
336
337
338void
339gnc_stock_split_assistant_finish (GtkAssistant *assistant,
340 gpointer user_data)
341{
342 StockSplitInfo *info = user_data;
343 GList *account_commits;
344 GList *node;
345
346 gnc_numeric amount;
347 Transaction *trans;
348 Account *account;
349 Split *split;
350 time64 date;
351
352 account = info->acct;
353 g_return_if_fail (account != NULL);
354
355 amount = gnc_amount_edit_get_amount
356 (GNC_AMOUNT_EDIT (info->distribution_edit));
357 g_return_if_fail (!gnc_numeric_zero_p (amount));
358
359 gnc_suspend_gui_refresh ();
360
361 trans = xaccMallocTransaction (gnc_get_current_book ());
362
363 xaccTransBeginEdit (trans);
364
366
367 date = gnc_date_edit_get_date (GNC_DATE_EDIT (info->date_edit));
369
370 {
371 const char *description;
372
373 description = gtk_entry_get_text (GTK_ENTRY (info->description_entry));
374 xaccTransSetDescription (trans, description);
375 }
376
377 split = xaccMallocSplit (gnc_get_current_book ());
378
379 xaccAccountBeginEdit (account);
380 account_commits = g_list_prepend (NULL, account);
381
382 xaccTransAppendSplit (trans, split);
383
384 xaccAccountInsertSplit (account, split);
385
386 xaccSplitSetAmount (split, amount);
388 /* Set split-action with gnc_set_num_action which is the same as
389 * xaccSplitSetAction with these arguments */
390
391 gnc_set_num_action (NULL, split, NULL, C_("Action Column", "Split"));
392
393 amount = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (info->price_edit));
394 if (gnc_numeric_positive_p (amount))
395 {
396 QofBook *book;
397 GNCPrice *price;
398 GNCPriceDB *pdb;
399 GNCCurrencyEdit *ce;
400
401 ce = GNC_CURRENCY_EDIT (info->price_currency_edit);
402 price = gnc_price_create (gnc_get_current_book ());
403
404 gnc_price_begin_edit (price);
405 gnc_price_set_commodity (price, xaccAccountGetCommodity (account));
406 gnc_price_set_currency (price, gnc_currency_edit_get_currency (ce));
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);
412
413 book = gnc_get_current_book ();
414 pdb = gnc_pricedb_get_db (book);
415
416 if (!gnc_pricedb_add_price (pdb, price))
417 gnc_error_dialog (GTK_WINDOW (info->window), "%s", _("Error adding price."));
418
419 }
420
421 amount = gnc_amount_edit_get_amount (GNC_AMOUNT_EDIT (info->cash_edit));
422 if (gnc_numeric_positive_p (amount))
423 {
424 const char *memo;
425
426 memo = gtk_entry_get_text (GTK_ENTRY (info->memo_entry));
427
428 /* asset split */
429 account = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT(info->asset_tree));
430
431 split = xaccMallocSplit (gnc_get_current_book ());
432
433 xaccAccountBeginEdit (account);
434 account_commits = g_list_prepend (account_commits, account);
435
436 xaccAccountInsertSplit (account, split);
437
438 xaccTransAppendSplit (trans, split);
439
440 xaccSplitSetAmount (split, amount);
441 xaccSplitSetValue (split, amount);
442
443 xaccSplitSetMemo (split, memo);
444
445
446 /* income split */
447 account = gnc_tree_view_account_get_selected_account (GNC_TREE_VIEW_ACCOUNT(info->income_tree));
448
449 split = xaccMallocSplit (gnc_get_current_book ());
450
451 xaccAccountBeginEdit (account);
452 account_commits = g_list_prepend (account_commits, account);
453
454 xaccAccountInsertSplit (account, split);
455
456 xaccTransAppendSplit (trans, split);
457
458 xaccSplitSetAmount (split, gnc_numeric_neg (amount));
459 xaccSplitSetValue (split, gnc_numeric_neg (amount));
460
461 xaccSplitSetMemo (split, memo);
462 }
463
464 xaccTransCommitEdit (trans);
465
466 for (node = account_commits; node; node = node->next)
467 xaccAccountCommitEdit (node->data);
468 g_list_free (account_commits);
469
470 gnc_resume_gui_refresh ();
471
472 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
473}
474
475
476void
477gnc_stock_split_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
478{
479 StockSplitInfo *info = user_data;
480 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
481}
482
483
484static gboolean
485gnc_stock_split_assistant_view_filter_income (Account *account,
486 gpointer data)
487{
488 GNCAccountType type;
489
490 type = xaccAccountGetType(account);
491 return (type == ACCT_TYPE_INCOME);
492}
493
494
495static gboolean
496gnc_stock_split_assistant_view_filter_asset (Account *account,
497 gpointer data)
498{
499 GNCAccountType type;
500
501 type = xaccAccountGetType(account);
502 return ((type == ACCT_TYPE_BANK) || (type == ACCT_TYPE_CASH) ||
503 (type == ACCT_TYPE_ASSET));
504}
505
506
507static void
508gnc_stock_split_details_valid_cb (GtkWidget *widget, gpointer user_data)
509{
510 StockSplitInfo *info = 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);
514
515 gtk_assistant_set_page_complete (assistant, page,
516 gnc_stock_split_assistant_details_complete (assistant, user_data));
517}
518
519
520static void
521gnc_stock_split_cash_valid_cb (GtkWidget *widget, gpointer user_data)
522{
523 StockSplitInfo *info = 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);
527
528 gtk_assistant_set_page_complete (assistant, page,
529 gnc_stock_split_assistant_cash_complete (assistant, user_data));
530}
531
532
533static GtkWidget *
534gnc_stock_split_assistant_create (StockSplitInfo *info)
535{
536 GtkBuilder *builder;
537 GtkWidget *window;
538
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;
543
544 // Set the name for this assistant so it can be easily manipulated with css
545 gtk_widget_set_name (GTK_WIDGET(window), "gnc-id-assistant-stock-split");
546
547 /* Enable buttons on first, second, fourth and last page. */
548 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
549 GTK_WIDGET(gtk_builder_get_object(builder, "intro_page_label")),
550 TRUE);
551 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
552 GTK_WIDGET(gtk_builder_get_object(builder, "stock_account_page")),
553 TRUE);
554 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
555 GTK_WIDGET(gtk_builder_get_object(builder, "stock_cash_page")),
556 TRUE);
557 gtk_assistant_set_page_complete (GTK_ASSISTANT (window),
558 GTK_WIDGET(gtk_builder_get_object(builder, "finish_page_label")),
559 TRUE);
560
561 /* Account page Widgets */
562 {
563 GtkTreeView *view;
564 GtkListStore *store;
565 GtkTreeSelection *selection;
566 GtkCellRenderer *renderer;
567 GtkTreeViewColumn *column;
568
569 info->account_view = GTK_WIDGET(gtk_builder_get_object(builder, "account_view"));
570
571 view = GTK_TREE_VIEW(info->account_view);
572
573 // Set grid lines option to preference
574 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(view), gnc_tree_view_get_grid_lines_pref ());
575
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);
580
581 renderer = gtk_cell_renderer_text_new();
582 column = gtk_tree_view_column_new_with_attributes(_("Account"), renderer,
583 "text", SPLIT_COL_FULLNAME,
584 NULL);
585 gtk_tree_view_append_column(view, column);
586
587 renderer = gtk_cell_renderer_text_new();
588 column = gtk_tree_view_column_new_with_attributes(_("Symbol"), renderer,
589 "text", SPLIT_COL_MNEMONIC,
590 NULL);
591 gtk_tree_view_append_column(view, column);
592
593 renderer = gtk_cell_renderer_text_new();
594 column = gtk_tree_view_column_new_with_attributes(_("Shares"), renderer,
595 "text", SPLIT_COL_SHARES,
596 NULL);
597 gtk_tree_view_append_column(view, column);
598
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);
603
604 }
605
606 /* Details Page Widgets */
607 {
608 GtkWidget *table;
609 GtkWidget *amount;
610 GtkWidget *date;
611 GtkWidget *label;
612
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"));
615
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;
620
621 label = GTK_WIDGET(gtk_builder_get_object(builder, "date_label"));
622 gnc_date_make_mnemonic_target (GNC_DATE_EDIT(date), label);
623
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;
631
632 label = GTK_WIDGET(gtk_builder_get_object(builder, "distribution_label"));
633 gnc_amount_edit_make_mnemonic_target (GNC_AMOUNT_EDIT(amount), label);
634
635 amount = gnc_amount_edit_new ();
636 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (amount),
637 gnc_default_price_print_info (gnc_default_currency()));
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;
644
645 label = GTK_WIDGET(gtk_builder_get_object(builder, "price_label"));
646 gnc_amount_edit_make_mnemonic_target (GNC_AMOUNT_EDIT(amount), label);
647
648 info->price_currency_edit = gnc_currency_edit_new();
649 gnc_currency_edit_set_currency (GNC_CURRENCY_EDIT(info->price_currency_edit), gnc_default_currency());
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);
654 }
655
656 /* Cash page Widgets */
657 {
658 GtkWidget *box;
659 GtkWidget *tree;
660 GtkWidget *amount;
661 GtkWidget *label;
662 GtkWidget *scroll;
663 GtkTreeSelection *selection;
664
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;
672
673 label = GTK_WIDGET(gtk_builder_get_object(builder, "cash_label"));
674 gtk_label_set_mnemonic_widget(GTK_LABEL(label), amount);
675
676 info->memo_entry = GTK_WIDGET(gtk_builder_get_object(builder, "memo_entry"));
677
678 /* income tree */
679 tree = GTK_WIDGET(gnc_tree_view_account_new (FALSE));
680 info->income_tree = tree;
681 gnc_tree_view_account_set_filter (GNC_TREE_VIEW_ACCOUNT (tree),
682 gnc_stock_split_assistant_view_filter_income,
683 NULL, /* user data */
684 NULL /* destroy callback */);
685
686 gtk_widget_show (tree);
687
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);
693
694 label = GTK_WIDGET(gtk_builder_get_object(builder, "income_label"));
695 gtk_label_set_mnemonic_widget (GTK_LABEL(label), tree);
696
697 scroll = GTK_WIDGET(gtk_builder_get_object(builder, "income_scroll"));
698 gtk_container_add (GTK_CONTAINER (scroll), tree);
699
700 /* asset tree */
701 tree = GTK_WIDGET(gnc_tree_view_account_new (FALSE));
702 info->asset_tree = tree;
703 gnc_tree_view_account_set_filter (GNC_TREE_VIEW_ACCOUNT (tree),
704 gnc_stock_split_assistant_view_filter_asset,
705 NULL /* user data */,
706 NULL /* destroy callback */);
707
708 gtk_widget_show (tree);
709
710 label = GTK_WIDGET(gtk_builder_get_object(builder, "asset_label"));
711 gtk_label_set_mnemonic_widget (GTK_LABEL(label), tree);
712
713 scroll = GTK_WIDGET(gtk_builder_get_object(builder, "asset_scroll"));
714 gtk_container_add (GTK_CONTAINER (scroll), tree);
715
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);
721 }
722
723 g_signal_connect (G_OBJECT(window), "destroy",
724 G_CALLBACK (gnc_stock_split_assistant_window_destroy_cb), info);
725
726 gtk_builder_connect_signals(builder, info);
727 g_object_unref(G_OBJECT(builder));
728 return window;
729
730}
731
732static void
733refresh_handler (GHashTable *changes, gpointer user_data)
734{
735 StockSplitInfo *info = user_data;
736 Account *old_account;
737
738 old_account = info->acct;
739
740 if (fill_account_list (info, info->acct) == 0)
741 {
742 gnc_close_gui_component_by_data (ASSISTANT_STOCK_SPLIT_CM_CLASS, info);
743 return;
744 }
745
746 if (NULL == info->acct || old_account == info->acct) return;
747}
748
749static void
750close_handler (gpointer user_data)
751{
752 StockSplitInfo *info = user_data;
753
754 gtk_widget_destroy (info->window);
755}
756
757/********************************************************************\
758 * gnc_stock_split_dialog *
759 * opens up a window to record a stock split *
760 * *
761 * Args: parent - the parent ofthis window *
762 * initial - the initial account to use *
763 * Return: nothing *
764\********************************************************************/
765void
766gnc_stock_split_dialog (GtkWidget *parent, Account * initial)
767{
768 StockSplitInfo *info;
769 gint component_id;
770
771 info = g_new0 (StockSplitInfo, 1);
772
773 info->acct = NULL;
774
775 gnc_stock_split_assistant_create (info);
776
777 component_id = gnc_register_gui_component (ASSISTANT_STOCK_SPLIT_CM_CLASS,
778 refresh_handler, close_handler,
779 info);
780
781 gnc_gui_component_watch_entity_type (component_id,
782 GNC_ID_ACCOUNT,
783 QOF_EVENT_MODIFY | QOF_EVENT_DESTROY);
784
785 if (fill_account_list (info, initial) == 0)
786 {
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);
789 return;
790 }
791
792 gtk_window_set_transient_for (GTK_WINDOW (info->window), GTK_WINDOW(parent));
793 gtk_widget_show_all (info->window);
794
795 gnc_window_adjust_for_screen (GTK_WINDOW(info->window));
796}
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...
Definition Account.cpp:1516
GList * gnc_account_get_descendants_sorted(const Account *account)
This function returns a GList containing all the descendants of the specified account,...
Definition Account.cpp:3052
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Definition Account.cpp:1475
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed.
Definition Account.h:103
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...
Definition Account.cpp:3305
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
Definition Account.cpp:3267
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
Definition Account.cpp:2745
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false.
Definition Account.cpp:4551
gnc_numeric xaccAccountGetBalance(const Account *acc)
Get the current balance of the account, which may include future splits.
Definition Account.cpp:3467
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity
Definition Account.cpp:3408
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...
Definition gnc-date.h:87
time64 gnc_time(time64 *tbuf)
get the current time
Definition gnc-date.cpp:262
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
Definition Account.cpp:4119
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.
Definition Account.h:1069
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,...
Definition Split.cpp:2063
STRUCTS.
QofBook reference.
Definition qofbook-p.hpp:47