28#include <gdk/gdkkeysyms.h>
29#include <glib/gi18n.h>
30#include <gnc-quotes.hpp>
32#include "dialog-transfer.h"
33#include "dialog-utils.h"
34#include "gnc-amount-edit.h"
35#include "gnc-component-manager.h"
36#include "gnc-date-edit.h"
39#include "gnc-exp-parser.h"
41#include "gnc-gui-query.h"
48#include "engine-helpers.h"
53#define DIALOG_TRANSFER_CM_CLASS "dialog-transfer"
54#define GNC_PREFS_GROUP "dialogs.transfer"
64static QofLogModule log_module = GNC_MOD_GUI;
69 GtkWidget *amount_edit;
70 GtkWidget *date_entry;
72 GtkWidget *description_entry;
73 GtkWidget *notes_entry;
74 GtkWidget *memo_entry;
75 GtkWidget *conv_forward;
76 GtkWidget *conv_reverse;
78 GtkWidget *from_window;
79 GtkTreeView * from_tree_view;
80 gnc_commodity *from_commodity;
82 GtkTreeView *to_tree_view;
83 gnc_commodity *to_commodity;
88 XferDirection quickfill;
91 gint desc_start_selection;
92 gint desc_end_selection;
93 guint desc_selection_source_id;
95 GtkWidget *transferinfo_label;
97 GtkWidget *from_transfer_label;
98 GtkWidget *to_transfer_label;
100 GtkWidget *from_currency_label;
101 GtkWidget *to_currency_label;
103 GtkWidget *from_show_button;
104 GtkWidget *to_show_button;
106 GtkWidget *curr_xfer_table;
108 GtkWidget *price_edit;
109 GtkWidget *to_amount_edit;
111 GtkWidget *price_radio;
112 GtkWidget *amount_radio;
114 GtkWidget *fetch_button;
122 gnc_numeric *exch_rate;
124 const char *price_type;
127 gnc_xfer_dialog_cb transaction_cb;
129 gpointer transaction_user_data;
147 char *acct_full_name;
154static void gnc_xfer_update_to_amount (XferDialog *xferData);
155static void gnc_xfer_dialog_update_conv_info(XferDialog *xferData);
157static Account *gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
158 XferDirection direction);
159static void gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
161 XferDirection direction);
164void gnc_xfer_description_insert_cb(GtkEditable *editable,
165 const gchar *insert_text,
166 const gint insert_text_len,
168 XferDialog *xferData);
169gboolean gnc_xfer_description_key_press_cb( GtkEntry *entry,
171 XferDialog *xferData );
172void gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData);
173gboolean gnc_xfer_dialog_inc_exp_filter_func (
Account *account,
175void price_amount_radio_toggled_cb(GtkToggleButton *togglebutton, gpointer data);
177void gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data);
178void gnc_xfer_dialog_close_cb(GtkDialog *dialog, gpointer data);
184gnc_xfer_dialog_compute_price_value (XferDialog *xferData)
186 gnc_numeric from_amt, to_amt;
189 from_amt = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
190 to_amt = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit));
201round_price(gnc_commodity *from, gnc_commodity *to, gnc_numeric value)
204 value = gnc_numeric_convert(value, CURRENCY_DENOM,
205 GNC_HOW_RND_ROUND_HALF_UP);
209 value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
210 GNC_HOW_RND_ROUND_HALF_UP);
215 value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
216 GNC_HOW_RND_ROUND_HALF_UP);
239price_request_from_xferData(
PriceReq *pr, XferDialog *xd)
241 g_return_if_fail (pr != NULL);
242 g_return_if_fail (xd != NULL);
244 pr->pricedb = xd->pricedb;
245 pr->from = xd->from_commodity;
246 pr->to = xd->to_commodity;
247 pr->time = gnc_date_edit_get_date (GNC_DATE_EDIT (xd->date_entry));
252lookup_price(
PriceReq *pr, PriceDate pd)
254 GNCPrice *prc = NULL;
255 g_return_val_if_fail (pr != NULL, FALSE);
256 g_return_val_if_fail (pr->pricedb != NULL, FALSE);
257 g_return_val_if_fail (pr->from != NULL, FALSE);
258 g_return_val_if_fail (pr->to != NULL, FALSE);
279 PINFO(
"No price Found for %s, %s",
289 PINFO(
"Found reverse price: 1 %s = %f %s",
296 PINFO(
"Found price: 1 %s = %f %s",
307gnc_xfer_dialog_update_price (XferDialog *xferData)
310 gnc_numeric price_value;
312 if (!xferData)
return;
313 if (!GNC_IS_COMMODITY (xferData->from_commodity) ||
314 !GNC_IS_COMMODITY (xferData->to_commodity))
return;
317 if (!xferData->pricedb)
return;
319 price_request_from_xferData(&pr, xferData);
320 if (!lookup_price(&pr, SAME_DAY))
321 if (!lookup_price(&pr, NEAREST))
325 price_value = gnc_price_get_value (pr.price);
331 gnc_xfer_dialog_set_price_edit(xferData, price_value);
334 gnc_xfer_update_to_amount (xferData);
338gnc_xfer_dialog_toggle_cb(GtkToggleButton *button, gpointer data)
340 GncTreeViewAccount* treeview = GNC_TREE_VIEW_ACCOUNT (data);
342 auto info =
static_cast<AccountTreeFilterInfo*
> (g_object_get_data (G_OBJECT(treeview),
"filter-info"));
345 info->show_inc_exp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
346 info->show_hidden = FALSE;
353gnc_xfer_dialog_key_press_cb (GtkWidget *widget,
357 if ((event->keyval == GDK_KEY_Return) || (event->keyval == GDK_KEY_KP_Enter))
359 auto toplevel = gtk_widget_get_toplevel (widget);
360 if (gtk_widget_is_toplevel(toplevel) && GTK_IS_WINDOW(toplevel))
362 gtk_window_activate_default(GTK_WINDOW(toplevel));
370gnc_xfer_dialog_set_price_auto (XferDialog *xferData,
371 gboolean currency_active,
372 const gnc_commodity *from_currency,
373 const gnc_commodity *to_currency)
375 if (!currency_active)
377 gnc_xfer_dialog_set_price_edit(xferData, gnc_numeric_zero());
378 auto entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
379 (GNC_AMOUNT_EDIT(xferData->price_edit)));
380 gtk_entry_set_text(entry,
"");
382 gnc_xfer_update_to_amount (xferData);
387 if (!gnc_is_euro_currency (from_currency) ||
388 !gnc_is_euro_currency (to_currency))
390 gnc_xfer_dialog_update_price (xferData);
394 auto from_rate = gnc_euro_currency_get_rate (from_currency);
395 auto to_rate = gnc_euro_currency_get_rate (to_currency);
398 gnc_xfer_dialog_update_price (xferData);
402 gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(xferData->price_edit), price_value);
404 gnc_xfer_update_to_amount (xferData);
408gnc_xfer_dialog_curr_acct_activate(XferDialog *xferData)
410 g_return_if_fail (xferData != NULL);
412 gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
415 gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
417 gboolean curr_active =
418 (xferData->exch_rate ||
419 ((from_account != NULL) && (to_account != NULL))) &&
422 gtk_widget_set_sensitive(xferData->curr_xfer_table, curr_active);
423 gtk_widget_set_sensitive(xferData->price_edit,
424 curr_active && gtk_toggle_button_get_active
425 (GTK_TOGGLE_BUTTON(xferData->price_radio)));
426 gtk_widget_set_sensitive(xferData->to_amount_edit,
427 curr_active && gtk_toggle_button_get_active
428 (GTK_TOGGLE_BUTTON(xferData->amount_radio)));
429 gtk_widget_set_sensitive(xferData->price_radio, curr_active);
430 gtk_widget_set_sensitive(xferData->amount_radio, curr_active);
432 gnc_xfer_dialog_set_price_auto (xferData, curr_active,
433 xferData->from_commodity, xferData->to_commodity);
434 gnc_xfer_dialog_update_conv_info(xferData);
438 gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
439 gnc_numeric_zero ());
440 auto entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
441 (GNC_AMOUNT_EDIT(xferData->to_amount_edit)));
442 gtk_entry_set_text(entry,
"");
448price_amount_radio_toggled_cb(GtkToggleButton *togglebutton, gpointer data)
450 g_return_if_fail (data);
452 auto xferData =
static_cast<XferDialog *
> (data);
453 gtk_widget_set_sensitive(xferData->price_edit, gtk_toggle_button_get_active
454 (GTK_TOGGLE_BUTTON(xferData->price_radio)));
455 gtk_widget_set_sensitive(xferData->to_amount_edit,
456 gtk_toggle_button_get_active
457 (GTK_TOGGLE_BUTTON(xferData->amount_radio)));
468gnc_xfer_dialog_reload_quickfill( XferDialog *xferData )
470 auto account = gnc_transfer_dialog_get_selected_account (xferData, xferData->quickfill);
473 gnc_quickfill_destroy( xferData->qf );
474 xferData->qf = gnc_quickfill_new();
476 for (
auto split : xaccAccountGetSplits (account))
486gnc_xfer_dialog_from_tree_selection_changed_cb (GtkTreeSelection *selection,
489 auto xferData =
static_cast<XferDialog *
> (data);
491 auto account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
496 gtk_label_set_text(GTK_LABEL(xferData->from_currency_label),
499 xferData->from_commodity = commodity;
501 auto print_info = gnc_account_print_info (account, FALSE);
502 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (xferData->amount_edit),
504 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (xferData->amount_edit),
507 gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit), NULL);
509 gnc_xfer_dialog_curr_acct_activate(xferData);
512 if (xferData->quickfill == XFER_DIALOG_FROM)
513 gnc_xfer_dialog_reload_quickfill(xferData);
518gnc_xfer_dialog_to_tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
520 auto xferData =
static_cast<XferDialog *
> (data);
522 auto account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
527 gtk_label_set_text(GTK_LABEL(xferData->to_currency_label),
530 xferData->to_commodity = commodity;
532 auto print_info = gnc_account_print_info (account, FALSE);
533 gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (xferData->to_amount_edit),
535 gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (xferData->to_amount_edit),
538 gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit), NULL);
540 gnc_xfer_dialog_curr_acct_activate(xferData);
543 if (xferData->quickfill == XFER_DIALOG_TO)
544 gnc_xfer_dialog_reload_quickfill(xferData);
548gnc_xfer_dialog_inc_exp_filter_func (
Account *account,
558 if (info->show_inc_exp)
564 return ((type != ACCT_TYPE_INCOME) && (type != ACCT_TYPE_EXPENSE));
568gnc_xfer_dialog_fill_tree_view(XferDialog *xferData,
569 XferDirection direction)
571 const char *show_inc_exp_message =
_(
"Show the income and expense accounts");
573 GtkWidget *scroll_win;
574 auto builder =
static_cast<GtkBuilder *
> (g_object_get_data (G_OBJECT (xferData->dialog),
"builder"));
576 g_return_if_fail (xferData != NULL);
578 GNC_PREF_ACCOUNTING_LABELS);
591 if (use_accounting_labels)
593 button = GTK_WIDGET(gtk_builder_get_object (builder,
594 (direction == XFER_DIALOG_TO) ?
595 "left_show_button" :
"right_show_button"));
596 scroll_win = GTK_WIDGET(gtk_builder_get_object (builder,
597 (direction == XFER_DIALOG_TO) ?
598 "left_trans_window" :
"right_trans_window"));
602 button = GTK_WIDGET(gtk_builder_get_object (builder,
603 (direction == XFER_DIALOG_TO) ?
604 "right_show_button" :
"left_show_button"));
605 scroll_win = GTK_WIDGET(gtk_builder_get_object (builder,
606 (direction == XFER_DIALOG_TO) ?
607 "right_trans_window" :
"left_trans_window"));
612 if (direction == XFER_DIALOG_TO)
618 gtk_container_add(GTK_CONTAINER(scroll_win), GTK_WIDGET(tree_view));
619 info->show_inc_exp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
620 info->show_hidden = FALSE;
622 gnc_xfer_dialog_inc_exp_filter_func,
625 g_object_set_data (G_OBJECT(tree_view),
"filter-info", info);
627 gtk_widget_show(GTK_WIDGET(tree_view));
628 g_signal_connect (G_OBJECT (tree_view),
"key-press-event",
629 G_CALLBACK (gnc_xfer_dialog_key_press_cb), NULL);
631 auto selection = gtk_tree_view_get_selection (tree_view);
632 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
634 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
635 gtk_widget_set_tooltip_text (button, show_inc_exp_message);
637 if (direction == XFER_DIALOG_TO)
639 xferData->to_tree_view = tree_view;
640 xferData->to_window = scroll_win;
641 xferData->to_show_button = GTK_WIDGET (button);
642 g_signal_connect (G_OBJECT (selection),
"changed",
643 G_CALLBACK (gnc_xfer_dialog_to_tree_selection_changed_cb), xferData);
647 xferData->from_tree_view = tree_view;
648 xferData->from_window = scroll_win;
649 xferData->from_show_button = GTK_WIDGET (button);
650 g_signal_connect (G_OBJECT (selection),
"changed",
651 G_CALLBACK (gnc_xfer_dialog_from_tree_selection_changed_cb), xferData);
653 g_signal_connect (G_OBJECT (button),
"toggled",
654 G_CALLBACK (gnc_xfer_dialog_toggle_cb), tree_view);
659gnc_parse_error_dialog (XferDialog *xferData,
const char *error_string)
661 const char * parse_error_string;
662 g_return_if_fail (xferData != NULL);
664 parse_error_string = gnc_exp_parser_error_string ();
665 if (parse_error_string == NULL)
666 parse_error_string =
"";
668 if (error_string == NULL)
671 gnc_error_dialog (GTK_WINDOW (xferData->dialog),
673 error_string,
_(
"Error"),
686gnc_xfer_dialog_quickfill( XferDialog *xferData )
693 gboolean changed = FALSE;
695 ENTER(
"xferData=%p", xferData);
702 match_account = gnc_transfer_dialog_get_selected_account (xferData, xferData->quickfill);
704 desc = gtk_entry_get_text( GTK_ENTRY(xferData->description_entry) );
706 if ( !desc || desc[0] ==
'\0' )
713 LEAVE(
"split not found");
716 DEBUG(
"split=%p", split);
724 gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit))))
727 DEBUG(
"updating amount");
738 gnc_amount_edit_set_amount( GNC_AMOUNT_EDIT(xferData->amount_edit), amt );
742 if ( !g_strcmp0(gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry)),
"" ))
744 DEBUG(
"updating memo");
745 gtk_entry_set_text( GTK_ENTRY(xferData->memo_entry),
759 GtkWidget *other_button;
760 XferDirection other_direction;
762 DEBUG(
"updating other split");
763 if (xferData->quickfill == XFER_DIALOG_FROM)
765 other_button = xferData->to_show_button;
766 other_direction = XFER_DIALOG_TO;
770 other_button = xferData->from_show_button;
771 other_direction = XFER_DIALOG_FROM;
779 if ( (other_type == ACCT_TYPE_EXPENSE) || (other_type == ACCT_TYPE_INCOME) )
780 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_button), TRUE);
782 gnc_transfer_dialog_set_selected_account (xferData, other_acct, other_direction);
791idle_select_region(gpointer data)
793 g_return_val_if_fail(data, FALSE);
795 auto xferData =
static_cast<XferDialog *
> (data);
797 gtk_editable_select_region(GTK_EDITABLE(xferData->description_entry),
798 xferData->desc_start_selection,
799 xferData->desc_end_selection);
801 xferData->desc_selection_source_id = 0;
810gnc_xfer_description_insert_cb(GtkEditable *editable,
811 const gchar *insert_text,
812 const gint insert_text_len,
814 XferDialog *xferData)
816 gchar *prefix, *suffix, *new_text;
818 const gchar *match_str;
819 gint prefix_len, new_text_len, match_str_len;
821 g_return_if_fail (xferData != NULL);
823 if (insert_text_len <= 0)
826 suffix = gtk_editable_get_chars(editable, *start_pos, -1);
836 prefix = gtk_editable_get_chars(editable, 0, *start_pos);
837 new_text = g_strconcat(prefix, insert_text, (gchar*) NULL);
838 prefix_len = strlen(prefix);
839 new_text_len = prefix_len + insert_text_len;
844 && ((match_str_len = strlen(match_str)) > new_text_len))
846 g_signal_handlers_block_matched (G_OBJECT (editable),
847 G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, xferData);
849 gtk_editable_insert_text(editable,
850 match_str + prefix_len,
851 match_str_len - prefix_len,
854 g_signal_handlers_unblock_matched (G_OBJECT (editable),
855 G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, xferData);
858 g_signal_stop_emission_by_name (G_OBJECT (editable),
"insert_text");
861 *start_pos = g_utf8_strlen(new_text, -1);
865 xferData->desc_start_selection = *start_pos;
866 xferData->desc_end_selection = -1;
867 xferData->desc_selection_source_id = g_idle_add(idle_select_region,
874gnc_xfer_description_key_press_cb( GtkEntry *entry,
876 XferDialog *xferData )
878 gboolean done_with_input = FALSE;
885 switch ( event->keyval )
888 case GDK_KEY_KP_Enter:
889 gnc_xfer_dialog_quickfill( xferData );
894 case GDK_KEY_ISO_Left_Tab:
895 if ( !( event->state & GDK_SHIFT_MASK) )
898 gnc_xfer_dialog_quickfill( xferData );
902 gtk_editable_select_region( GTK_EDITABLE(xferData->description_entry),
908 LEAVE(
"done=%d", done_with_input);
909 return( done_with_input );
915gnc_xfer_dialog_update_conv_info (XferDialog *xferData)
917 const gchar *to_mnemonic, *from_mnemonic;
929 if (!from_mnemonic || !to_mnemonic)
932 rate = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
935 string = g_strdup_printf(
"1 %s = x %s", from_mnemonic, to_mnemonic);
936 gtk_label_set_text(GTK_LABEL(xferData->conv_forward),
string);
939 string = g_strdup_printf(
"1 %s = x %s", to_mnemonic, from_mnemonic);
940 gtk_label_set_text(GTK_LABEL(xferData->conv_reverse),
string);
945 string = g_strdup_printf(
"1 %s = %f %s", from_mnemonic,
947 gtk_label_set_text(GTK_LABEL(xferData->conv_forward),
string);
951 string = g_strdup_printf(
"1 %s = %f %s", to_mnemonic,
953 gtk_label_set_text(GTK_LABEL(xferData->conv_reverse),
string);
959gnc_xfer_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
962 g_return_val_if_fail (data, FALSE);
964 auto xferData =
static_cast<XferDialog *
> (data);
966 gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit), NULL);
968 gnc_xfer_update_to_amount (xferData);
975gnc_xfer_update_to_amount (XferDialog *xferData)
977 GNCAmountEdit *amount_edit, *price_edit, *to_amount_edit;
978 gnc_numeric price_value, to_amount;
982 g_return_if_fail(xferData);
984 xferData->price_source = PRICE_SOURCE_USER_PRICE;
987 amount_edit = GNC_AMOUNT_EDIT(xferData->amount_edit);
988 price_edit = GNC_AMOUNT_EDIT(xferData->price_edit);
989 to_amount_edit = GNC_AMOUNT_EDIT(xferData->to_amount_edit);
992 account = gnc_transfer_dialog_get_selected_account(xferData, XFER_DIALOG_TO);
994 account = gnc_transfer_dialog_get_selected_account(xferData,
998 else if (xferData->to_commodity != NULL)
1002 if (!gnc_amount_edit_evaluate(price_edit, NULL) ||
1004 to_amount = gnc_numeric_zero();
1007 price_value, scu, GNC_HOW_RND_ROUND_HALF_UP);
1010 gnc_amount_edit_set_amount(to_amount_edit, to_amount);
1012 gtk_entry_set_text(GTK_ENTRY(gnc_amount_edit_gtk_entry(to_amount_edit)),
1015 gnc_xfer_dialog_update_conv_info(xferData);
1020gnc_xfer_price_update_cb(GtkWidget *widget, GdkEventFocus *event,
1023 auto xferData =
static_cast<XferDialog *
> (data);
1025 gnc_xfer_update_to_amount (xferData);
1026 xferData->price_type = PRICE_TYPE_TRN;
1032gnc_xfer_date_changed_cb(GtkWidget *widget, gpointer data)
1034 auto xferData =
static_cast<XferDialog *
> (data);
1037 gnc_xfer_dialog_update_price (xferData);
1043gnc_xfer_to_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
1046 auto xferData =
static_cast<XferDialog *
> (data);
1048 gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit), NULL);
1049 auto price_value = gnc_xfer_dialog_compute_price_value (xferData);
1050 gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
1052 xferData->price_source = PRICE_SOURCE_XFER_DLG_VAL;
1053 xferData->price_type = PRICE_TYPE_TRN;
1054 gnc_xfer_dialog_update_conv_info(xferData);
1069gnc_xfer_dialog_select_from_account(XferDialog *xferData,
Account *account)
1071 gnc_transfer_dialog_set_selected_account (xferData, account, XFER_DIALOG_FROM);
1084gnc_xfer_dialog_select_to_account(XferDialog *xferData,
Account *account)
1086 gnc_transfer_dialog_set_selected_account (xferData, account, XFER_DIALOG_TO);
1090gnc_xfer_dialog_select_from_currency(XferDialog *xferData, gnc_commodity *cur)
1092 if (!xferData)
return;
1095 gtk_label_set_text(GTK_LABEL(xferData->from_currency_label),
1098 gnc_amount_edit_set_print_info(GNC_AMOUNT_EDIT(xferData->amount_edit),
1099 gnc_commodity_print_info(cur, FALSE));
1100 gnc_amount_edit_set_fraction(GNC_AMOUNT_EDIT(xferData->amount_edit),
1103 xferData->from_commodity = cur;
1104 gnc_xfer_dialog_curr_acct_activate(xferData);
1108gnc_xfer_dialog_select_to_currency(XferDialog *xferData, gnc_commodity *cur)
1110 g_return_if_fail (cur && GNC_IS_COMMODITY (cur));
1111 gtk_label_set_text(GTK_LABEL(xferData->to_currency_label),
1114 gnc_amount_edit_set_print_info(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
1115 gnc_commodity_print_info(cur, FALSE));
1116 gnc_amount_edit_set_fraction(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
1119 xferData->to_commodity = cur;
1120 gnc_xfer_dialog_curr_acct_activate(xferData);
1124gnc_xfer_dialog_lock_account_tree(XferDialog *xferData,
1125 XferDirection direction,
1128 GtkTreeView *tree_view;
1129 GtkWidget *show_button;
1130 GtkWidget *scroll_win;
1132 if (xferData == NULL)
1137 case XFER_DIALOG_FROM:
1138 tree_view = xferData->from_tree_view;
1139 scroll_win = xferData->from_window;
1140 show_button = xferData->from_show_button;
1142 case XFER_DIALOG_TO:
1143 tree_view = xferData->to_tree_view;
1144 scroll_win = xferData->to_window;
1145 show_button = xferData->to_show_button;
1151 gtk_widget_set_sensitive( GTK_WIDGET(tree_view), FALSE );
1152 gtk_widget_set_sensitive( GTK_WIDGET(show_button), FALSE );
1156 gtk_widget_hide( scroll_win );
1157 gtk_widget_hide( GTK_WIDGET(show_button) );
1170gnc_xfer_dialog_lock_from_account_tree(XferDialog *xferData)
1172 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_FROM, FALSE);
1184gnc_xfer_dialog_lock_to_account_tree(XferDialog *xferData)
1186 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_TO, FALSE);
1198gnc_xfer_dialog_hide_from_account_tree(XferDialog *xferData)
1200 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_FROM, TRUE);
1212gnc_xfer_dialog_hide_to_account_tree(XferDialog *xferData)
1214 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_TO, TRUE);
1229gnc_xfer_dialog_is_exchange_dialog (XferDialog *xferData,
1230 gnc_numeric *exch_rate)
1234 g_return_if_fail(xferData);
1235 ENTER(
"xferData=%p, exch_rate=%p (%s)", xferData, exch_rate,
1237 gnc_default_print_info(FALSE)));
1239 gtk_widget_set_sensitive (xferData->amount_edit, FALSE);
1240 gtk_widget_set_sensitive (xferData->date_entry, FALSE);
1241 gtk_widget_set_sensitive (xferData->num_entry, FALSE);
1242 gtk_widget_set_sensitive (xferData->description_entry, FALSE);
1243 gtk_widget_set_sensitive (xferData->notes_entry, FALSE);
1244 gtk_widget_set_sensitive (xferData->memo_entry, FALSE);
1247 gae = GNC_AMOUNT_EDIT (xferData->price_edit);
1248 gtk_widget_grab_focus (gnc_amount_edit_gtk_entry (gae));
1250 xferData->exch_rate = exch_rate;
1264gnc_xfer_dialog_set_amount(XferDialog *xferData, gnc_numeric amount)
1268 if (xferData == NULL)
1271 account = gnc_transfer_dialog_get_selected_account (xferData,
1273 if (account == NULL)
1274 gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
1276 gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->amount_edit), amount);
1278void gnc_xfer_dialog_set_amount_sensitive(XferDialog *xferData,
1279 gboolean is_sensitive)
1282 gtk_widget_set_sensitive(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT (xferData->amount_edit)), is_sensitive);
1286gnc_xfer_dialog_set_fetch_sensitive (GtkWidget *fetch)
1290 gtk_widget_set_sensitive (fetch, TRUE);
1291 gtk_widget_set_tooltip_text (fetch,
_(
"Retrieve the current online quote. This will fail if there is a manually-created price for today."));
1294 gtk_widget_set_sensitive (fetch, FALSE);
1295 gtk_widget_set_tooltip_text (fetch,
_(
"Finance::Quote must be installed to enable this button."));
1308gnc_xfer_dialog_set_description(XferDialog *xferData,
const char *description)
1310 if (xferData == NULL)
1313 gtk_entry_set_text(GTK_ENTRY(xferData->description_entry), description);
1326gnc_xfer_dialog_set_memo(XferDialog *xferData,
const char *memo)
1328 if (xferData == NULL)
1331 gtk_entry_set_text(GTK_ENTRY(xferData->memo_entry), memo);
1344gnc_xfer_dialog_set_num(XferDialog *xferData,
const char *num)
1346 if (xferData == NULL)
1349 gtk_entry_set_text(GTK_ENTRY(xferData->num_entry), num);
1362gnc_xfer_dialog_set_date(XferDialog *xferData,
time64 set_date)
1364 if (xferData == NULL)
1367 gnc_date_edit_set_time( GNC_DATE_EDIT(xferData->date_entry), set_date );
1369void gnc_xfer_dialog_set_date_sensitive(XferDialog *xferData,
1370 gboolean is_sensitive)
1373 gtk_widget_set_sensitive (xferData->date_entry, is_sensitive);
1377gnc_xfer_dialog_set_price_edit(XferDialog *xferData, gnc_numeric price_value)
1379 if (xferData == NULL)
1385 gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->price_edit),
1388 gnc_xfer_update_to_amount (xferData);
1392check_accounts (XferDialog* xferData,
Account* from_account,
1395 if ((from_account == NULL) || (to_account == NULL))
1397 const char *message =
_(
"You must specify an account to transfer from, "
1398 "or to, or both, for this transaction. "
1399 "Otherwise, it will not be recorded.");
1400 gnc_error_dialog (GTK_WINDOW (xferData->dialog),
"%s", message);
1401 LEAVE(
"bad account");
1405 if (from_account == to_account)
1407 const char *message =
_(
"You can't transfer from and to the same "
1409 gnc_error_dialog (GTK_WINDOW (xferData->dialog),
"%s", message);
1410 LEAVE(
"same account");
1417 const char *placeholder_format =
1418 _(
"The account %s does not allow transactions.");
1425 gnc_error_dialog (GTK_WINDOW (xferData->dialog), placeholder_format, name);
1427 LEAVE(
"placeholder");
1433 const char *message =
1434 _(
"You can't transfer from a non-currency account. "
1435 "Try reversing the \"from\" and \"to\" accounts "
1436 "and making the \"amount\" negative.");
1437 gnc_error_dialog (GTK_WINDOW (xferData->dialog),
"%s", message);
1438 LEAVE(
"non-currency");
1445check_edit(XferDialog *xferData)
1447 if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->price_edit), NULL))
1449 if (gtk_toggle_button_get_active
1450 (GTK_TOGGLE_BUTTON(xferData->price_radio)))
1452 gnc_parse_error_dialog (xferData,
_(
"You must enter a valid price."));
1453 LEAVE(
"invalid price");
1458 if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit), NULL))
1460 if (gtk_toggle_button_get_active
1461 (GTK_TOGGLE_BUTTON(xferData->amount_radio)))
1463 gnc_parse_error_dialog (xferData,
1464 _(
"You must enter a valid 'to' amount."));
1465 LEAVE(
"invalid to amount");
1473create_transaction(XferDialog *xferData,
time64 time,
1475 gnc_numeric amount, gnc_numeric to_amount)
1492 string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
1510 xferData->from_commodity);
1515 string = gtk_entry_get_text(GTK_ENTRY(xferData->num_entry));
1516 gnc_set_num_action (trans, from_split,
string, NULL);
1519 string = gtk_entry_get_text(GTK_ENTRY(xferData->notes_entry));
1523 string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
1534 if (xferData->transaction_cb)
1535 xferData->transaction_cb(trans, xferData->transaction_user_data);
1539swap_commodities(gnc_commodity **from, gnc_commodity **to, gnc_numeric value)
1541 gnc_commodity *tmp = *to;
1550update_price(XferDialog *xferData,
PriceReq *pr)
1552 gnc_commodity *from = xferData->from_commodity;
1553 gnc_commodity *to = xferData->to_commodity;
1554 gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
1555 gnc_numeric price_value = gnc_price_get_value(pr->price);
1556 gnc_numeric rounded_pr_value = round_price(pr->from, pr->to, price_value);
1557 gnc_numeric rounded_value;
1559 if (gnc_price_get_source(pr->price) < xferData->price_source)
1561 PINFO(
"Existing price is preferred, so won't supersede.");
1567 value = swap_commodities(&from, &to, value);
1569 rounded_value = round_price(from, to, value);
1572 PINFO(
"Same price for %s in %s",
1578 gnc_price_begin_edit (pr->price);
1579 gnc_price_set_time64 (pr->price, pr->time);
1580 gnc_price_set_typestr(pr->price, xferData->price_type);
1581 gnc_price_set_value (pr->price, value);
1582 gnc_price_commit_edit (pr->price);
1583 PINFO(
"Updated price: 1 %s = %f %s",
1591new_price(XferDialog *xferData,
time64 time)
1593 GNCPrice *price = NULL;
1594 gnc_commodity *from = xferData->from_commodity;
1595 gnc_commodity *to = xferData->to_commodity;
1596 gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
1602 value = swap_commodities (&from, &to, value);
1605 value = swap_commodities (&from, &to, value);
1608 gnc_price_begin_edit (price);
1609 gnc_price_set_commodity (price, from);
1610 gnc_price_set_currency (price, to);
1611 gnc_price_set_time64 (price, time);
1612 gnc_price_set_source (price, xferData->price_source);
1613 gnc_price_set_typestr (price, xferData->price_type);
1614 gnc_price_set_value (price, value);
1616 gnc_price_commit_edit (price);
1623create_price(XferDialog *xferData,
time64 time)
1628 if (gnc_is_euro_currency (xferData->from_commodity) &&
1629 gnc_is_euro_currency (xferData->to_commodity))
1632 price_request_from_xferData(&pr, xferData);
1633 if (lookup_price(&pr, SAME_DAY))
1635 update_price(xferData, &pr);
1638 new_price (xferData, time);
1642gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
1644 g_return_if_fail (data);
1645 auto xferData =
static_cast<XferDialog *
> (data);
1649 if (response == GTK_RESPONSE_APPLY)
1651 LEAVE(
"fetching exchange rate");
1658 g_signal_handlers_disconnect_by_func (G_OBJECT (xferData->date_entry),
1659 (gpointer)gnc_xfer_date_changed_cb,
1662 if (response != GTK_RESPONSE_OK)
1664 gnc_close_gui_component_by_data (DIALOG_TRANSFER_CM_CLASS, xferData);
1665 LEAVE(
"cancel, etc.");
1669 auto from_account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
1670 auto to_account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
1672 if (xferData->exch_rate == NULL &&
1673 !check_accounts(xferData, from_account, to_account))
1676 if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit), NULL))
1678 gnc_parse_error_dialog (xferData,
_(
"You must enter a valid amount."));
1683 auto amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
1687 const char *message =
_(
"You must enter an amount to transfer.");
1688 gnc_error_dialog (GTK_WINDOW (xferData->dialog),
"%s", message);
1689 LEAVE(
"invalid from amount");
1694 g_date_clear (&date, 1);
1695 gnc_date_edit_get_gdate (GNC_DATE_EDIT (xferData->date_entry), &date);
1698 auto to_amount = amount;
1701 if (!check_edit(xferData))
1703 to_amount = gnc_amount_edit_get_amount
1704 (GNC_AMOUNT_EDIT(xferData->to_amount_edit));
1707 gnc_suspend_gui_refresh ();
1709 if (xferData->exch_rate)
1714 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(xferData->price_radio)))
1715 gnc_xfer_update_to_amount(xferData);
1717 auto price_value = gnc_xfer_dialog_compute_price_value(xferData);
1718 gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
1723 create_transaction (xferData, time, from_account, to_account,
1727 xferData->to_commodity))
1728 create_price(xferData, time);
1730 gnc_resume_gui_refresh ();
1732 DEBUG(
"close component");
1733 gnc_close_gui_component_by_data (DIALOG_TRANSFER_CM_CLASS, xferData);
1738gnc_xfer_dialog_close_cb(GtkDialog *dialog, gpointer data)
1740 auto xferData =
static_cast<XferDialog *
> (data);
1743 if (xferData->transaction_cb)
1744 xferData->transaction_cb(NULL, xferData->transaction_user_data);
1746 auto entry = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(xferData->amount_edit));
1747 g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
1748 0, 0, NULL, NULL, xferData);
1750 entry = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(xferData->price_edit));
1751 g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
1752 0, 0, NULL, NULL, xferData);
1754 entry = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(xferData->to_amount_edit));
1755 g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
1756 0, 0, NULL, NULL, xferData);
1758 entry = xferData->description_entry;
1759 g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
1760 0, 0, NULL, NULL, xferData);
1762 DEBUG(
"unregister component");
1763 gnc_unregister_gui_component_by_data (DIALOG_TRANSFER_CM_CLASS, xferData);
1765 gnc_quickfill_destroy (xferData->qf);
1766 xferData->qf = NULL;
1768 if (xferData->desc_selection_source_id)
1769 g_source_remove (xferData->desc_selection_source_id);
1774 DEBUG(
"xfer dialog destroyed");
1779gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData)
1781 g_return_if_fail (xferData);
1788 gnc_set_busy_cursor(
nullptr, TRUE);
1789 quotes.
fetch(xferData->book);
1790 gnc_unset_busy_cursor(
nullptr);
1794 gnc_unset_busy_cursor(
nullptr);
1795 PERR(
"Price retrieval failed: %s", err.what());
1796 gnc_error_dialog(GTK_WINDOW(xferData->dialog),
_(
"Price retrieval failed: %s"), err.what());
1801 price_request_from_xferData(&pr, xferData);
1802 if (lookup_price(&pr, LATEST))
1804 gnc_numeric price_value = gnc_price_get_value(pr.price);
1807 gnc_xfer_dialog_set_price_edit(xferData, price_value);
1811 LEAVE(
"quote retrieved");
1816gnc_xfer_dialog_create(GtkWidget *parent, XferDialog *xferData)
1818 GtkBuilder *builder;
1819 gboolean use_accounting_labels;
1820 g_return_if_fail(to_info == NULL && from_info == NULL);
1823 GNC_PREF_ACCOUNTING_LABELS);
1826 builder = gtk_builder_new();
1827 gnc_builder_add_from_file (builder,
"dialog-transfer.glade",
"transfer_dialog");
1829 xferData->dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"transfer_dialog"));
1830 g_object_set_data_full (G_OBJECT (xferData->dialog),
"builder", builder, g_object_unref);
1833 gtk_widget_set_name (GTK_WIDGET(xferData->dialog),
"gnc-id-transfer");
1834 gnc_widget_style_context_add_class (GTK_WIDGET(xferData->dialog),
"gnc-class-securities");
1838 gtk_window_set_transient_for (GTK_WINDOW (xferData->dialog), GTK_WINDOW (parent));
1841 xferData->quickfill = XFER_DIALOG_FROM;
1843 xferData->transferinfo_label = GTK_WIDGET(gtk_builder_get_object (builder,
"transferinfo-label"));
1845 xferData->fetch_button = GTK_WIDGET(gtk_builder_get_object (builder,
"fetch"));
1846 gnc_xfer_dialog_set_fetch_sensitive (xferData->fetch_button);
1855 amount = gnc_amount_edit_new();
1856 hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"amount_hbox"));
1857 gtk_box_pack_end(GTK_BOX(hbox), amount, TRUE, TRUE, 0);
1858 gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (amount), TRUE);
1859 xferData->amount_edit = amount;
1861 entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (amount));
1862 gtk_entry_set_activates_default (GTK_ENTRY(entry), TRUE);
1863 g_signal_connect (G_OBJECT (entry),
"focus-out-event",
1864 G_CALLBACK (gnc_xfer_amount_update_cb), xferData);
1866 date = gnc_date_edit_new(time (NULL), FALSE, FALSE);
1867 gnc_date_activates_default (GNC_DATE_EDIT(date), TRUE);
1868 hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"date_hbox"));
1870 gtk_box_pack_end(GTK_BOX(hbox), date, TRUE, TRUE, 0);
1871 xferData->date_entry = date;
1872 g_signal_connect (G_OBJECT (date),
"date_changed",
1873 G_CALLBACK (gnc_xfer_date_changed_cb), xferData);
1879 entry = GTK_WIDGET(gtk_builder_get_object (builder,
"num_entry"));
1880 xferData->num_entry = entry;
1882 entry = GTK_WIDGET(gtk_builder_get_object (builder,
"description_entry"));
1883 xferData->description_entry = entry;
1885 entry = GTK_WIDGET(gtk_builder_get_object (builder,
"notes_entry"));
1886 xferData->notes_entry = entry;
1888 entry = GTK_WIDGET(gtk_builder_get_object (builder,
"memo_entry"));
1889 xferData->memo_entry = entry;
1900 gnc_xfer_dialog_fill_tree_view (xferData, XFER_DIALOG_TO);
1901 gnc_xfer_dialog_fill_tree_view (xferData, XFER_DIALOG_FROM);
1905 if (use_accounting_labels)
1907 label = GTK_WIDGET(gtk_builder_get_object (builder,
"right_trans_label"));
1908 xferData->from_transfer_label = label;
1910 label = GTK_WIDGET(gtk_builder_get_object (builder,
"left_trans_label"));
1911 xferData->to_transfer_label = label;
1913 text = g_strconcat (
"<b>",
_(
"Credit Account"),
"</b>", NULL);
1914 gtk_label_set_markup (GTK_LABEL (xferData->from_transfer_label), text);
1917 text = g_strconcat (
"<b>",
_(
"Debit Account"),
"</b>", NULL);
1918 gtk_label_set_markup (GTK_LABEL (xferData->to_transfer_label), text);
1921 label = GTK_WIDGET(gtk_builder_get_object (builder,
"right_currency_label"));
1922 xferData->from_currency_label = label;
1924 label = GTK_WIDGET(gtk_builder_get_object (builder,
"left_currency_label"));
1925 xferData->to_currency_label = label;
1929 label = GTK_WIDGET(gtk_builder_get_object (builder,
"left_trans_label"));
1930 xferData->from_transfer_label = label;
1932 label = GTK_WIDGET(gtk_builder_get_object (builder,
"right_trans_label"));
1933 xferData->to_transfer_label = label;
1935 text = g_strconcat (
"<b>",
_(
"Transfer From"),
"</b>", NULL);
1936 gtk_label_set_markup (GTK_LABEL (xferData->from_transfer_label), text);
1939 text = g_strconcat (
"<b>",
_(
"Transfer To"),
"</b>", NULL);
1940 gtk_label_set_markup (GTK_LABEL (xferData->to_transfer_label), text);
1942 label = GTK_WIDGET(gtk_builder_get_object (builder,
"left_currency_label"));
1943 xferData->from_currency_label = label;
1945 label = GTK_WIDGET(gtk_builder_get_object (builder,
"right_currency_label"));
1946 xferData->to_currency_label = label;
1949 label = GTK_WIDGET(gtk_builder_get_object (builder,
"conv_forward"));
1950 xferData->conv_forward = label;
1952 label = GTK_WIDGET(gtk_builder_get_object (builder,
"conv_reverse"));
1953 xferData->conv_reverse = label;
1964 table = GTK_WIDGET(gtk_builder_get_object (builder,
"curr_transfer_table"));
1965 xferData->curr_xfer_table =
table;
1967 edit = gnc_amount_edit_new();
1968 gnc_amount_edit_set_print_info(GNC_AMOUNT_EDIT(edit),
1969 gnc_default_print_info (FALSE));
1970 hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"price_hbox"));
1971 gtk_box_pack_start(GTK_BOX(hbox), edit, TRUE, TRUE, 0);
1972 xferData->price_edit = edit;
1973 entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (edit));
1974 g_signal_connect (G_OBJECT (entry),
"focus-out-event",
1975 G_CALLBACK (gnc_xfer_price_update_cb), xferData);
1976 gtk_entry_set_activates_default(GTK_ENTRY (entry), TRUE);
1978 edit = gnc_amount_edit_new();
1979 hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"right_amount_hbox"));
1980 gtk_box_pack_start(GTK_BOX(hbox), edit, TRUE, TRUE, 0);
1981 xferData->to_amount_edit = edit;
1982 entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (edit));
1983 g_signal_connect (G_OBJECT (entry),
"focus-out-event",
1984 G_CALLBACK (gnc_xfer_to_amount_update_cb), xferData);
1985 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
1987 button = GTK_WIDGET(gtk_builder_get_object (builder,
"price_radio"));
1988 xferData->price_radio = button;
1990 button = GTK_WIDGET(gtk_builder_get_object (builder,
"amount_radio"));
1991 xferData->amount_radio = button;
1993 if (use_accounting_labels)
1995 gtk_label_set_text(GTK_LABEL(gtk_bin_get_child (GTK_BIN(xferData->amount_radio))),
2000 gtk_label_set_text(GTK_LABEL(gtk_bin_get_child (GTK_BIN(xferData->amount_radio))),
2005 gtk_builder_connect_signals(builder, xferData);
2006 gnc_restore_window_size (GNC_PREFS_GROUP,
2007 GTK_WINDOW (xferData->dialog), GTK_WINDOW (parent));
2012close_handler (gpointer user_data)
2014 auto xferData =
static_cast<XferDialog *
> (user_data);
2017 auto dialog = GTK_WIDGET (xferData->dialog);
2019 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW (dialog));
2020 gtk_widget_hide (dialog);
2021 gnc_xfer_dialog_close_cb(GTK_DIALOG(dialog), xferData);
2022 gtk_widget_destroy (dialog);
2039gnc_xfer_dialog (GtkWidget * parent,
Account * initial)
2041 XferDialog *xferData;
2043 GtkWidget *amount_entry;
2046 xferData = g_new0 (XferDialog, 1);
2048 xferData->desc_start_selection = 0;
2049 xferData->desc_end_selection = 0;
2050 xferData->desc_selection_source_id = 0;
2051 xferData->quickfill = XFER_DIALOG_FROM;
2052 xferData->transaction_cb = NULL;
2056 book = gnc_account_get_book (initial);
2060 book = gnc_get_current_book ();
2063 xferData->book = book;
2066 gnc_xfer_dialog_create(parent, xferData);
2068 DEBUG(
"register component");
2069 gnc_register_gui_component (DIALOG_TRANSFER_CM_CLASS,
2070 NULL, close_handler, xferData);
2072 gae = GNC_AMOUNT_EDIT(xferData->amount_edit);
2073 amount_entry = gnc_amount_edit_gtk_entry (gae);
2075 gtk_widget_grab_focus(amount_entry);
2077 gnc_xfer_dialog_select_from_account(xferData, initial);
2078 gnc_xfer_dialog_select_to_account(xferData, initial);
2080 gnc_xfer_dialog_curr_acct_activate(xferData);
2082 gtk_widget_show_all(xferData->dialog);
2084 gnc_window_adjust_for_screen(GTK_WINDOW(xferData->dialog));
2090gnc_xfer_dialog_close( XferDialog *xferData )
2094 DEBUG(
"close component");
2095 gtk_dialog_response( GTK_DIALOG(xferData->dialog), GTK_RESPONSE_NONE );
2100gnc_xfer_dialog_set_title( XferDialog *xferData,
const gchar *title )
2102 if ( xferData && title )
2104 gtk_window_set_title (GTK_WINDOW (xferData->dialog), title);
2109gnc_xfer_dialog_set_information_label( XferDialog *xferData,
2112 if (xferData && text)
2114 gchar *markup_text = g_strdup_printf (
"<b>%s</b>", text);
2115 gtk_label_set_markup (GTK_LABEL (xferData->transferinfo_label), markup_text);
2116 g_free (markup_text);
2122gnc_xfer_dialog_set_account_label( XferDialog *xferData,
2124 XferDirection direction )
2126 if (xferData && text)
2128 gchar *markup_text = g_strdup_printf (
"<b>%s</b>", text);
2129 gtk_label_set_markup (GTK_LABEL ((direction == XFER_DIALOG_FROM ?
2130 xferData->from_transfer_label :
2131 xferData->to_transfer_label)),
2133 g_free (markup_text);
2138gnc_xfer_dialog_set_from_account_label( XferDialog *xferData,
2139 const gchar *label )
2141 gnc_xfer_dialog_set_account_label (xferData, label, XFER_DIALOG_FROM);
2145gnc_xfer_dialog_set_to_account_label( XferDialog *xferData,
2146 const gchar *label )
2148 gnc_xfer_dialog_set_account_label (xferData, label, XFER_DIALOG_TO);
2152gnc_xfer_dialog_set_from_show_button_active( XferDialog *xferData,
2153 gboolean set_value )
2155 if ( xferData && xferData->from_show_button )
2157 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(xferData->from_show_button),
2163gnc_xfer_dialog_set_to_show_button_active( XferDialog *xferData,
2164 gboolean set_value )
2166 if ( xferData && xferData->to_show_button )
2168 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(xferData->to_show_button),
2174void gnc_xfer_dialog_add_user_specified_button( XferDialog *xferData,
2177 gpointer user_data )
2179 if ( xferData && label && callback )
2181 auto builder =
static_cast<GtkBuilder *
> (g_object_get_data (G_OBJECT (xferData->dialog),
"builder"));
2182 auto button = gtk_button_new_with_label( label );
2183 auto box = GTK_WIDGET (gtk_builder_get_object (builder,
2184 "transfermain-vbox" ));
2185 gtk_box_pack_end( GTK_BOX(box), button, FALSE, FALSE, 0 );
2186 g_signal_connect (G_OBJECT (button),
"clicked", G_CALLBACK (callback), user_data);
2187 gtk_widget_show( button );
2191void gnc_xfer_dialog_toggle_currency_table( XferDialog *xferData,
2192 gboolean show_table )
2194 if (xferData && xferData->curr_xfer_table)
2197 gtk_widget_show(xferData->curr_xfer_table);
2199 gtk_widget_hide(xferData->curr_xfer_table);
2206find_xfer (gpointer
find_data, gpointer user_data)
2215gboolean gnc_xfer_dialog_run_until_done( XferDialog *xferData )
2218 gint count, response;
2220 ENTER(
"xferData=%p", xferData);
2221 if ( xferData == NULL )
2227 dialog = GTK_DIALOG (xferData->dialog);
2234 count = g_signal_handlers_disconnect_by_func(dialog,
2235 (gpointer) gnc_xfer_dialog_response_cb,
2237 g_assert(count == 1);
2241 DEBUG(
"calling gtk_dialog_run");
2242 response = gtk_dialog_run (dialog);
2243 DEBUG(
"gtk_dialog_run returned %d", response);
2244 gnc_xfer_dialog_response_cb (dialog, response, xferData);
2246 if ((response != GTK_RESPONSE_OK) && (response != GTK_RESPONSE_APPLY))
2258 if ( !gnc_find_first_gui_component( DIALOG_TRANSFER_CM_CLASS,
2259 find_xfer, xferData ) )
2269 g_assert_not_reached();
2279gnc_xfer_dialog_quickfill_to_account(XferDialog *xferData,
2280 gboolean qf_to_account )
2282 XferDirection old = xferData->quickfill;
2284 xferData->quickfill = qf_to_account ? XFER_DIALOG_TO : XFER_DIALOG_FROM;
2287 if ( old != xferData->quickfill )
2288 gnc_xfer_dialog_reload_quickfill( xferData );
2292gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
2293 XferDirection direction)
2295 GtkTreeView *tree_view;
2300 case XFER_DIALOG_FROM:
2301 tree_view = dialog->from_tree_view;
2303 case XFER_DIALOG_TO:
2304 tree_view = dialog->to_tree_view;
2307 g_assert_not_reached ();
2316gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
2318 XferDirection direction)
2320 GtkTreeView *tree_view;
2321 GtkCheckButton *show_button;
2324 if (account == NULL)
2329 case XFER_DIALOG_FROM:
2330 tree_view = dialog->from_tree_view;
2331 show_button = GTK_CHECK_BUTTON (dialog->from_show_button);
2333 case XFER_DIALOG_TO:
2334 tree_view = dialog->to_tree_view;
2335 show_button = GTK_CHECK_BUTTON (dialog->to_show_button);
2338 g_assert_not_reached ();
2343 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_button),
2344 (type == ACCT_TYPE_EXPENSE) ||
2345 (type == ACCT_TYPE_INCOME));
2352void gnc_xfer_dialog_set_txn_cb(XferDialog *xferData,
2353 gnc_xfer_dialog_cb handler,
2357 xferData->transaction_cb = handler;
2358 xferData->transaction_user_data = user_data;
2363gboolean gnc_xfer_dialog_run_exchange_dialog(
2364 XferDialog *xfer, gnc_numeric *exch_rate, gnc_numeric amount,
2365 Account *reg_acc, Transaction *txn, gnc_commodity *xfer_com,
2368 gboolean swap_amounts = FALSE;
2372 g_return_val_if_fail(txn_cur && GNC_IS_COMMODITY (txn_cur), TRUE);
2373 g_return_val_if_fail(xfer_com && GNC_IS_COMMODITY (xfer_com), TRUE);
2385 *exch_rate = gnc_numeric_create(1, 1);
2388 swap_amounts = expanded;
2401 swap_amounts = FALSE;
2408 swap_amounts = TRUE;
2419 gnc_numeric rate = xaccTransGetAccountConvRate(txn, reg_acc);
2424 GNC_HOW_DENOM_REDUCE);
2430 gnc_xfer_dialog_select_to_currency(xfer, txn_cur);
2431 gnc_xfer_dialog_select_from_currency(xfer, xfer_com);
2438 gnc_xfer_dialog_select_to_currency(xfer, xfer_com);
2439 gnc_xfer_dialog_select_from_currency(xfer, txn_cur);
2443 gnc_xfer_dialog_hide_to_account_tree(xfer);
2444 gnc_xfer_dialog_hide_from_account_tree(xfer);
2446 gnc_xfer_dialog_set_amount(xfer, amount);
2448 gnc_xfer_update_to_amount(xfer);
2456 gnc_xfer_dialog_set_price_edit(xfer, *exch_rate);
2459 if (gnc_xfer_dialog_run_until_done(xfer) == FALSE)
Account handling public routines.
Account public routines (C++ api)
QuickFill is used to auto-complete typed user entries.
API for Transactions and Splits (journal entries)
void fetch(QofBook *book)
Fetch quotes for all commodities in our db that have a quote source set.
Commodity handling public routines.
All type declarations for the whole Gnucash engine.
Generic api to store and retrieve preferences.
a simple price database for gnucash
GtkTreeView implementation for gnucash account tree.
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
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.
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.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
gboolean gnc_quote_source_fq_installed(void)
This function indicates whether or not the Finance::Quote module is installed on a user's computer.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
gboolean gnc_commodity_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency or a legacy currency.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
#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...
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
gboolean xaccAccountIsHidden(const Account *acc)
Should this account be "hidden".
Split * xaccAccountFindSplitByDesc(const Account *acc, const char *description)
Returns a pointer to the split, not a copy.
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.
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Determine whether this transaction should use commodity trading accounts.
#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 xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
void gnc_tree_view_account_refilter(GncTreeViewAccount *view)
This function forces the account tree filter to be evaluated.
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_selected_account(GncTreeViewAccount *view, Account *account)
This function selects an account 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_account_or_default_currency(const Account *account, gboolean *currency_from_account_found)
Returns a gnc_commodity that is a currency, suitable for being a Transaction's currency.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
#define PINFO(format, args...)
Print an informational note.
#define DEBUG(format, args...)
Print a debugging message.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
double gnc_numeric_to_double(gnc_numeric in)
Convert numeric to floating-point value.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
Create a gnc_numeric object that signals the error condition noted by error_code, rather than a numbe...
gnc_numeric gnc_numeric_abs(gnc_numeric a)
Returns a newly created gnc_numeric that is the absolute value of the given gnc_numeric value.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
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_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
gnc_numeric gnc_numeric_invert(gnc_numeric num)
Invert a gnc_numeric.
@ GNC_ERROR_ARG
Argument is not a valid number.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
GNCPrice * gnc_pricedb_lookup_nearest_in_time64(GNCPriceDB *db, const gnc_commodity *c, const gnc_commodity *currency, time64 t)
Return the price between the two commoditiesz nearest to the given time.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
GNCPrice * gnc_pricedb_lookup_latest(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
Find the most recent price between the two commodities.
GNCPrice * gnc_pricedb_lookup_day_t64(GNCPriceDB *db, const gnc_commodity *c, const gnc_commodity *currency, time64 t)
Return the price between the two commodities on the indicated day.
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
PriceSource
Price source enum.
GNCPrice * gnc_price_create(QofBook *book)
gnc_price_create - returns a newly allocated and initialized price with a reference count of 1.
void gnc_price_unref(GNCPrice *p)
gnc_price_unref - indicate you're finished with a price (i.e.
QuickFill * gnc_quickfill_get_string_match(QuickFill *qf, const char *str)
Return a subnode in the tree whose strings all match the string 'str' as the next substring.
const char * gnc_quickfill_string(QuickFill *qf)
For the given node 'qf', return the best-guess matching string.
void gnc_quickfill_insert(QuickFill *qf, const char *text, QuickFillSort sort)
Add the string "text" to the collection of searchable strings.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
Split * xaccMallocSplit(QofBook *book)
Constructor.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
void xaccSplitSetBaseValue(Split *s, gnc_numeric value, const gnc_commodity *base_currency)
Depending on the base_currency, set either the value or the amount of this split or both: If the base...
Split * xaccSplitGetOtherSplit(const Split *split)
The xaccSplitGetOtherSplit() is a convenience routine that returns the other of a pair of splits.
Structure passed to "filter tree accounts" function to provide it information.
gboolean show_inc_exp
Show income/expense accounts in tree.
gboolean show_hidden
Show hidden accounts in tree.