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" 64 static 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;
154 static void gnc_xfer_update_to_amount (XferDialog *xferData);
155 static void gnc_xfer_dialog_update_conv_info(XferDialog *xferData);
157 static Account *gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
158 XferDirection direction);
159 static void gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
161 XferDirection direction);
164 void gnc_xfer_description_insert_cb(GtkEditable *editable,
165 const gchar *insert_text,
166 const gint insert_text_len,
168 XferDialog *xferData);
169 gboolean gnc_xfer_description_key_press_cb( GtkEntry *entry,
171 XferDialog *xferData );
172 void gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData);
173 gboolean gnc_xfer_dialog_inc_exp_filter_func (
Account *account,
175 void price_amount_radio_toggled_cb(GtkToggleButton *togglebutton, gpointer data);
177 void gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data);
178 void gnc_xfer_dialog_close_cb(GtkDialog *dialog, gpointer data);
184 gnc_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));
201 round_price(gnc_commodity *from, gnc_commodity *to, gnc_numeric value)
239 price_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));
252 lookup_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",
307 gnc_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);
338 gnc_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;
353 gnc_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));
370 gnc_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);
408 gnc_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,
"");
448 price_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)));
468 gnc_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))
486 gnc_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);
518 gnc_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);
548 gnc_xfer_dialog_inc_exp_filter_func (
Account *account,
558 if (info->show_inc_exp)
568 gnc_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);
659 gnc_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"),
686 gnc_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;
780 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_button), TRUE);
782 gnc_transfer_dialog_set_selected_account (xferData, other_acct, other_direction);
791 idle_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;
810 gnc_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,
874 gnc_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 );
915 gnc_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);
959 gnc_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);
975 gnc_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();
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);
1020 gnc_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;
1032 gnc_xfer_date_changed_cb(GtkWidget *widget, gpointer data)
1034 auto xferData =
static_cast<XferDialog *
> (data);
1037 gnc_xfer_dialog_update_price (xferData);
1043 gnc_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);
1069 gnc_xfer_dialog_select_from_account(XferDialog *xferData,
Account *account)
1071 gnc_transfer_dialog_set_selected_account (xferData, account, XFER_DIALOG_FROM);
1084 gnc_xfer_dialog_select_to_account(XferDialog *xferData,
Account *account)
1086 gnc_transfer_dialog_set_selected_account (xferData, account, XFER_DIALOG_TO);
1090 gnc_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);
1108 gnc_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);
1124 gnc_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) );
1170 gnc_xfer_dialog_lock_from_account_tree(XferDialog *xferData)
1172 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_FROM, FALSE);
1184 gnc_xfer_dialog_lock_to_account_tree(XferDialog *xferData)
1186 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_TO, FALSE);
1198 gnc_xfer_dialog_hide_from_account_tree(XferDialog *xferData)
1200 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_FROM, TRUE);
1212 gnc_xfer_dialog_hide_to_account_tree(XferDialog *xferData)
1214 gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_TO, TRUE);
1229 gnc_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;
1264 gnc_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);
1278 void 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);
1286 gnc_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."));
1308 gnc_xfer_dialog_set_description(XferDialog *xferData,
const char *description)
1310 if (xferData == NULL)
1313 gtk_entry_set_text(GTK_ENTRY(xferData->description_entry), description);
1326 gnc_xfer_dialog_set_memo(XferDialog *xferData,
const char *memo)
1328 if (xferData == NULL)
1331 gtk_entry_set_text(GTK_ENTRY(xferData->memo_entry), memo);
1344 gnc_xfer_dialog_set_num(XferDialog *xferData,
const char *num)
1346 if (xferData == NULL)
1349 gtk_entry_set_text(GTK_ENTRY(xferData->num_entry), num);
1362 gnc_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 );
1369 void gnc_xfer_dialog_set_date_sensitive(XferDialog *xferData,
1370 gboolean is_sensitive)
1373 gtk_widget_set_sensitive (xferData->date_entry, is_sensitive);
1377 gnc_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);
1392 check_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");
1445 check_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");
1473 create_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);
1539 swap_commodities(gnc_commodity **from, gnc_commodity **to, gnc_numeric value)
1541 gnc_commodity *tmp = *to;
1550 update_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",
1591 new_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);
1623 create_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);
1642 gnc_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);
1738 gnc_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");
1779 gnc_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");
1816 gnc_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));
2012 close_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);
2039 gnc_xfer_dialog (GtkWidget * parent,
Account * initial)
2041 XferDialog *xferData;
2043 GtkWidget *amount_entry;
2044 QofBook *book = NULL;
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));
2090 gnc_xfer_dialog_close( XferDialog *xferData )
2094 DEBUG(
"close component");
2095 gtk_dialog_response( GTK_DIALOG(xferData->dialog), GTK_RESPONSE_NONE );
2100 gnc_xfer_dialog_set_title( XferDialog *xferData,
const gchar *title )
2102 if ( xferData && title )
2104 gtk_window_set_title (GTK_WINDOW (xferData->dialog), title);
2109 gnc_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);
2122 gnc_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);
2138 gnc_xfer_dialog_set_from_account_label( XferDialog *xferData,
2139 const gchar *label )
2141 gnc_xfer_dialog_set_account_label (xferData, label, XFER_DIALOG_FROM);
2145 gnc_xfer_dialog_set_to_account_label( XferDialog *xferData,
2146 const gchar *label )
2148 gnc_xfer_dialog_set_account_label (xferData, label, XFER_DIALOG_TO);
2152 gnc_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),
2163 gnc_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),
2174 void 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 );
2191 void 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);
2206 find_xfer (gpointer
find_data, gpointer user_data)
2215 gboolean 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();
2279 gnc_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 );
2292 gnc_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 ();
2316 gnc_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),
2352 void 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;
2363 gboolean 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);
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)
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.
GNCPrice * gnc_price_create(QofBook *book)
gnc_price_create - returns a newly allocated and initialized price with a reference count of 1...
void gnc_quickfill_insert(QuickFill *qf, const char *text, QuickFillSort sort)
Add the string "text" to the collection of searchable strings.
#define xaccTransAppendSplit(t, s)
Add a split to the transaction.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
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...
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
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...
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Determine whether this transaction should use commodity trading accounts.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
a simple price database for gnucash
Expense accounts are used to denote expenses.
#define PINFO(format, args...)
Print an informational note.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
void gnc_price_unref(GNCPrice *p)
gnc_price_unref - indicate you're finished with a price (i.e.
Structure passed to "filter tree accounts" function to provide it information.
#define DEBUG(format, args...)
Print a debugging message.
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
gboolean show_inc_exp
Show income/expense accounts in tree.
#define PERR(format, args...)
Log a serious error.
#define ENTER(format, args...)
Print a function entry debugging message.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
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.
gdouble gnc_numeric_to_double(gnc_numeric n)
Convert numeric to floating-point value.
gnc_numeric gnc_numeric_invert(gnc_numeric num)
Invert a gnc_numeric.
void gnc_tree_view_account_set_filter(GncTreeViewAccount *view, gnc_tree_view_account_filter_func func, gpointer data, GSourceFunc destroy)
This function attaches a filter function to the given account tree.
gchar * gnc_account_get_full_name(const Account *account)
The gnc_account_get_full_name routine returns the fully qualified name of the account using the given...
Account handling public routines.
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Change the denominator of a gnc_numeric value to the specified denominator under standard arguments '...
void gnc_tree_view_account_refilter(GncTreeViewAccount *view)
This function forces the account tree filter to be evaluated.
Reduce the result value by common factor elimination, using the smallest possible value for the denom...
GtkTreeView implementation for gnucash account tree.
Income accounts are used to denote income.
Account public routines (C++ api)
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
void xaccSplitSetMemo(Split *split, const char *memo)
The memo is an arbitrary string associated with a split.
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...
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
Create a new account tree view.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
Argument is not a valid number.
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
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...
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...
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
Division.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
All type declarations for the whole Gnucash engine.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
Split * xaccMallocSplit(QofBook *book)
Constructor.
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.
Generic api to store and retrieve preferences.
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.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
void gnc_tree_view_account_set_selected_account(GncTreeViewAccount *view, Account *account)
This function selects an account in the account tree view.
const char * gnc_quickfill_string(QuickFill *qf)
For the given node 'qf', return the best-guess matching string.
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
void fetch(QofBook *book)
Fetch quotes for all commodities in our db that have a quote source set.
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
#define xaccAccountInsertSplit(acc, s)
The xaccAccountInsertSplit() method will insert the indicated split into the indicated account...
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
PriceSource
Price source enum.
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...
Split * xaccSplitGetOtherSplit(const Split *split)
The xaccSplitGetOtherSplit() is a convenience routine that returns the other of a pair of splits...
#define LEAVE(format, args...)
Print a function exit debugging message.
QuickFill is used to auto-complete typed user entries.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
gboolean show_hidden
Show hidden accounts in tree.
const char * xaccSplitGetMemo(const Split *split)
Returns the memo string.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
GNCPrice * gnc_pricedb_lookup_latest(GNCPriceDB *db, const gnc_commodity *commodity, const gnc_commodity *currency)
Find the most recent price between the two commodities.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
API for Transactions and Splits (journal entries)
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
Commodity handling public routines.
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_is_iso(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency.
gboolean gnc_quote_source_fq_installed(void)
This function indicates whether or not the Finance::Quote module is installed on a user's computer...