GnuCash c935c2f+
Loading...
Searching...
No Matches
dialog-fincalc.c
1/********************************************************************\
2 * dialog-fincalc.c : dialog for a financial calculator *
3 * Copyright (C) 2000 Dave Peticolas <dave@krondo.com> *
4 * Copyright (c) 2006 David Hampton <hampton@employees.org> *
5 * *
6 * This program is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU General Public License as *
8 * published by the Free Software Foundation; either version 2 of *
9 * the License, or (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License*
17 * along with this program; if not, contact: *
18 * *
19 * Free Software Foundation Voice: +1-617-542-5942 *
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21 * Boston, MA 02110-1301, USA gnu@gnu.org *
22\********************************************************************/
23
24#include <config.h>
25
26#include <gtk/gtk.h>
27#include <glib/gi18n.h>
28#include <locale.h>
29#include <time.h>
30
31#include "dialog-fincalc.h"
32#include "dialog-utils.h"
33#include "finproto.h"
34#include "finvar.h"
35#include "gnc-amount-edit.h"
36#include "gnc-commodity.h"
37#include "gnc-component-manager.h"
38#include "gnc-date-edit.h"
39#include "gnc-engine.h"
40#include "gnc-ui.h"
41#include "gnc-gui-query.h"
42#include "gnc-locale-utils.h"
43
44
45#define DIALOG_FINCALC_CM_CLASS "dialog-fincalc"
46#define GNC_PREFS_GROUP "dialogs.fincalc"
47
48typedef enum
49{
50 PAYMENT_PERIODS = 0,
51 INTEREST_RATE,
52 PRESENT_VALUE,
53 PERIODIC_PAYMENT,
54 FUTURE_VALUE,
55 NUM_FIN_CALC_VALUES
56} FinCalcValue;
57
58
61{
62 GtkWidget *dialog;
63
64 GtkWidget *amounts[NUM_FIN_CALC_VALUES];
65
66 GtkWidget *calc_button;
67
68 GtkWidget *compounding_combo;
69 GtkWidget *payment_combo;
70
71 GtkWidget *end_of_period_radio;
72 GtkWidget *precision;
73 GtkWidget *discrete_compounding_radio;
74
75 GtkWidget *payment_total_label;
76
78};
79
80static unsigned int periods[] =
81{
82 1, /* annual */
83 2, /* semi-annual */
84 3, /* tri-annual */
85 4, /* quarterly */
86 6, /* bi-monthly */
87 12, /* monthly */
88 24, /* semi-monthly */
89 26, /* bi-weekly */
90 52, /* weekly */
91 360, /* daily (360) */
92 365, /* daily (365) */
93};
94
95/* This static indicates the debugging module that this .o belongs to. */
96__attribute__((unused)) static QofLogModule log_module = GNC_MOD_GUI;
97
98
100void fincalc_update_calc_button_cb (GtkWidget *unused, FinCalcDialog *fcd);
101void fincalc_calc_clicked_cb (GtkButton *button, FinCalcDialog *fcd);
102void fincalc_compounding_radio_toggled (GtkToggleButton *togglebutton, gpointer user_data);
103void fincalc_amount_clear_clicked_cb (GtkButton *button, FinCalcDialog *fcd);
104void fincalc_precision_spin_value_changed_cb (GtkButton *button, FinCalcDialog *fcd);
105void fincalc_response_cb (GtkDialog *dialog, gint response, FinCalcDialog *fcd);
106
109/* Ensure the given argument is one of the values in the periods array
110 * above and return the index of the value. */
111static int
112normalize_period (unsigned int *period)
113{
114 int i;
115
116 g_return_val_if_fail (period, 0);
117
118 for (i = (sizeof (periods) / sizeof (unsigned int)) - 1; i >= 0; i--)
119 if (*period >= periods[i])
120 {
121 *period = periods[i];
122 return i;
123 }
124
125 *period = periods[0];
126
127 return 0;
128}
129
130/* Copy the values in the financial_info structure to the GUI */
131static void
132fi_to_gui (FinCalcDialog *fcd)
133{
134 int precision;
135 static char string[64];
136 gnc_numeric total;
137 gnc_numeric npp;
138 gnc_numeric pmt;
139 int i;
140
141 if (fcd == NULL)
142 return;
143
144 npp = gnc_numeric_create (fcd->financial_info.npp, 1);
145
146 gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(fcd->amounts[PAYMENT_PERIODS]),
147 npp);
148 gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]),
149 fcd->financial_info.ir);
150 gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]),
151 fcd->financial_info.pv);
152 gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]),
153 fcd->financial_info.pmt);
154 gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]),
155 -fcd->financial_info.fv);
156
157 pmt = double_to_gnc_numeric (fcd->financial_info.pmt, 100000, GNC_HOW_RND_ROUND_HALF_UP);
158
159 precision = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(fcd->precision));
160
161 total = gnc_numeric_mul (npp, pmt, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
162
163 xaccSPrintAmount (string, total, gnc_share_print_info_places (precision));
164 gtk_label_set_text (GTK_LABEL(fcd->payment_total_label), string);
165
166 i = normalize_period (&fcd->financial_info.CF);
167 gtk_combo_box_set_active (GTK_COMBO_BOX(fcd->compounding_combo), i);
168
169 i = normalize_period (&fcd->financial_info.PF);
170 gtk_combo_box_set_active (GTK_COMBO_BOX(fcd->payment_combo), i);
171
172 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(fcd->end_of_period_radio),
173 !fcd->financial_info.bep);
174
175 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(fcd->discrete_compounding_radio),
176 fcd->financial_info.disc);
177}
178
179/* Copy the values in the GUI to the financial_info structure */
180static void
181gui_to_fi (FinCalcDialog *fcd)
182{
183 GtkToggleButton *toggle;
184 GtkWidget *entry;
185 gnc_numeric npp;
186 int i;
187 const gchar *text;
188
189 if (fcd == NULL)
190 return;
191
192 /* treat PAYMENT_PERIODS as a plain GtkEntry */
193 entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT(fcd->amounts[PAYMENT_PERIODS]));
194 text = gtk_entry_get_text (GTK_ENTRY(entry));
195 if (text && *text)
196 {
197 gnc_numeric out = gnc_numeric_from_string (text);
198 if (!gnc_numeric_check (out))
199 npp = gnc_numeric_convert (out, 1, GNC_HOW_RND_TRUNC);
200 else
201 npp = gnc_numeric_zero ();
202 }
203 else
204 npp = gnc_numeric_zero ();
205 fcd->financial_info.npp = npp.num;
206
207 fcd->financial_info.ir =
208 gnc_amount_edit_get_damount (GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]));
209
210 fcd->financial_info.pv =
211 gnc_amount_edit_get_damount (GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]));
212
213 fcd->financial_info.pmt =
214 gnc_amount_edit_get_damount (GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]));
215
216 fcd->financial_info.fv =
217 gnc_amount_edit_get_damount (GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]));
218 fcd->financial_info.fv = -fcd->financial_info.fv;
219
220 i = gtk_combo_box_get_active (GTK_COMBO_BOX(fcd->compounding_combo));
221 fcd->financial_info.CF = periods[i];
222
223 i = gtk_combo_box_get_active (GTK_COMBO_BOX(fcd->payment_combo));
224 fcd->financial_info.PF = periods[i];
225
226 toggle = GTK_TOGGLE_BUTTON(fcd->end_of_period_radio);
227 fcd->financial_info.bep = !gtk_toggle_button_get_active (toggle);
228
229 toggle = GTK_TOGGLE_BUTTON(fcd->discrete_compounding_radio);
230 fcd->financial_info.disc = gtk_toggle_button_get_active (toggle);
231
232 fcd->financial_info.prec = gnc_locale_decimal_places ();
233}
234
235/* Set the sensitivity of the calculation buttons based on the argument. */
236void
237fincalc_update_calc_button_cb (GtkWidget *unused, FinCalcDialog *fcd)
238{
239 const gchar *text;
240 gint i;
241
242 if (fcd == NULL)
243 return;
244
245 for (i = 0; i < NUM_FIN_CALC_VALUES; i++)
246 {
247 GtkWidget *entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT(fcd->amounts[i]));
248 text = gtk_entry_get_text (GTK_ENTRY(entry));
249 if ((text == NULL) || (*text == '\0'))
250 {
251 gtk_widget_set_sensitive (GTK_WIDGET(fcd->calc_button), TRUE);
252 return;
253 }
254 }
255
256 gtk_widget_set_sensitive (GTK_WIDGET(fcd->calc_button), FALSE);
257}
258
259/* Free the calc button list and free the FinCalcDialog structure. */
260static void
261fincalc_dialog_destroy (GObject *object, gpointer user_data)
262{
263 FinCalcDialog *fcd = user_data;
264
265 if (fcd == NULL)
266 return;
267
268 gnc_unregister_gui_component_by_data (DIALOG_FINCALC_CM_CLASS, fcd);
269
270 g_free (fcd);
271}
272
273void
274fincalc_compounding_radio_toggled (GtkToggleButton *togglebutton, gpointer user_data)
275{
276 FinCalcDialog *fcd = user_data;
277 gboolean sensitive;
278
279 if (fcd == NULL)
280 return;
281
282 fincalc_update_calc_button_cb (GTK_WIDGET(togglebutton), fcd);
283
284 sensitive = gtk_toggle_button_get_active (togglebutton);
285
286 gtk_widget_set_sensitive (fcd->compounding_combo, sensitive);
287}
288
289void
290fincalc_amount_clear_clicked_cb (GtkButton *button, FinCalcDialog *fcd)
291{
292 GNCAmountEdit * edit = GNC_AMOUNT_EDIT(g_object_get_data (G_OBJECT(button), "edit"));
293 GtkWidget * entry = gnc_amount_edit_gtk_entry (edit);
294 gnc_numeric value;
295
296 if (entry && GTK_IS_ENTRY(entry))
297 gtk_entry_set_text (GTK_ENTRY(entry), "");
298
299 gnc_amount_edit_expr_is_valid (edit, &value, TRUE, NULL);
300}
301
302void
303fincalc_precision_spin_value_changed_cb (GtkButton *button, FinCalcDialog *fcd)
304{
305 gtk_widget_set_sensitive (GTK_WIDGET(fcd->calc_button), TRUE);
306}
307
308static void
309init_fi (FinCalcDialog *fcd)
310{
311 struct lconv *lc;
312
313 if (fcd == NULL)
314 return;
315
316 lc = gnc_localeconv ();
317
318 fcd->financial_info.npp = 12;
319 fcd->financial_info.ir = 8.5;
320 fcd->financial_info.pv = 15000.0;
321 fcd->financial_info.pmt = -400.0;
322 fcd->financial_info.CF = 12;
323 fcd->financial_info.PF = 12;
324 fcd->financial_info.bep = FALSE;
325 fcd->financial_info.disc = TRUE;
326 fcd->financial_info.prec = lc->frac_digits;
327
328 fi_calc_future_value (&fcd->financial_info);
329}
330
331/* Determine whether the value can be calculated. If it can, return
332 * NULL. Otherwise, return a string describing the reason and the offending
333 * entry in error_item. */
334static const char *
335can_calc_value (FinCalcDialog *fcd, FinCalcValue value, int *error_item)
336{
337 const char *missing = _("This program can only calculate one value at a time. "
338 "You must enter values for all but one quantity.");
339 const char *bad_exp = _("GnuCash cannot determine the value in one of the fields. "
340 "You must enter a valid expression.");
341 const char *string;
342 gnc_numeric nvalue;
343 unsigned int i;
344
345 if (fcd == NULL)
346 return NULL;
347
348 /* Check for missing values */
349 for (i = 0; i < NUM_FIN_CALC_VALUES; i++)
350 if (i != value)
351 {
352 GtkWidget *entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT(fcd->amounts[i]));
353 string = gtk_entry_get_text (GTK_ENTRY(entry));
354 if ((string == NULL) || (*string == '\0'))
355 {
356 *error_item = i;
357 return missing;
358 }
359
360 /* treat PAYMENT_PERIODS as a plain GtkEntry */
361 if (i != PAYMENT_PERIODS)
362 {
363 if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT(fcd->amounts[i]), NULL))
364 {
365 *error_item = i;
366 return bad_exp;
367 }
368 }
369 }
370
371 /* Check for zero interest */
372 switch (value)
373 {
374 case PAYMENT_PERIODS:
375 case PRESENT_VALUE:
376 case PERIODIC_PAYMENT:
377 case FUTURE_VALUE:
378 nvalue = gnc_amount_edit_get_amount
379 (GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]));
380 if (gnc_numeric_zero_p (nvalue))
381 {
382 *error_item = INTEREST_RATE;
383 return _("The interest rate cannot be zero.");
384 }
385 break;
386 default:
387 break;
388 }
389
390 /* Check for zero payment periods */
391 switch (value)
392 {
393 case INTEREST_RATE:
394 case PRESENT_VALUE:
395 case PERIODIC_PAYMENT:
396 case FUTURE_VALUE:
397 {
398 /* treat PAYMENT_PERIODS as a plain GtkEntry */
399 GNCAmountEdit *edit = GNC_AMOUNT_EDIT(fcd->amounts[PAYMENT_PERIODS]);
400 gint result = gnc_amount_edit_expr_is_valid (edit, &nvalue, TRUE, NULL);
401
402 if (result == 1)
403 {
404 *error_item = PAYMENT_PERIODS;
405 return bad_exp;
406 }
407 if (gnc_numeric_zero_p (nvalue))
408 {
409 *error_item = PAYMENT_PERIODS;
410 return _("The number of payments cannot be zero.");
411 }
412 if (gnc_numeric_negative_p (nvalue))
413 {
414 *error_item = PAYMENT_PERIODS;
415 return _("The number of payments cannot be negative.");
416 }
417 }
418 break;
419 default:
420 break;
421 }
422
423 return NULL;
424}
425
426static void
427calc_value (FinCalcDialog *fcd, FinCalcValue value)
428{
429 const char *string;
430 int error_item = 0;
431
432 if (fcd == NULL)
433 return;
434
435 string = can_calc_value (fcd, value, &error_item);
436 if (string != NULL)
437 {
438 GtkWidget *entry;
439
440 gnc_error_dialog (GTK_WINDOW (fcd->dialog), "%s", string);
441 if (error_item == 0)
442 entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT(fcd->amounts[0]));
443 else
444 entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT(fcd->amounts[error_item]));
445 gtk_widget_grab_focus (entry);
446 return;
447 }
448
449 gui_to_fi (fcd);
450
451 switch (value)
452 {
453 case PAYMENT_PERIODS:
454 fi_calc_num_payments (&fcd->financial_info);
455 break;
456 case INTEREST_RATE:
457 fi_calc_interest (&fcd->financial_info);
458 break;
459 case PRESENT_VALUE:
460 fi_calc_present_value (&fcd->financial_info);
461 break;
462 case PERIODIC_PAYMENT:
463 fi_calc_payment (&fcd->financial_info);
464 break;
465 case FUTURE_VALUE:
466 fi_calc_future_value (&fcd->financial_info);
467 break;
468 default:
469 break;
470 }
471
472 fi_to_gui (fcd);
473
474 gtk_widget_set_sensitive (GTK_WIDGET(fcd->calc_button), FALSE);
475}
476
477void
478fincalc_calc_clicked_cb (GtkButton *button, FinCalcDialog *fcd)
479{
480 const gchar *text;
481 gint i;
482
483 for (i = 0; i < NUM_FIN_CALC_VALUES; i++)
484 {
485 GtkWidget *entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT(fcd->amounts[i]));
486 text = gtk_entry_get_text (GTK_ENTRY(entry));
487 if ((text != NULL) && (*text != '\0'))
488 continue;
489 calc_value (fcd, i);
490 return;
491 }
492 calc_value (fcd, NUM_FIN_CALC_VALUES);
493}
494
495void fincalc_response_cb (GtkDialog *dialog,
496 gint response,
497 FinCalcDialog *fcd)
498{
499 switch (response)
500 {
501 case GTK_RESPONSE_HELP:
502 gnc_gnome_help (GTK_WINDOW(dialog), DF_MANUAL, DL_FIN_CALC);
503 return;
504
505 case GTK_RESPONSE_OK:
506 /* Do something here whenever the hidden schedule button is clicked. */
507 /* Fall through */
508
509 case GTK_RESPONSE_CLOSE:
510 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(dialog));
511 break;
512
513 default:
514 /* Cancel, destroy, etc. Do nothing. */
515 break;
516 }
517
518 gnc_close_gui_component_by_data (DIALOG_FINCALC_CM_CLASS, fcd);
519}
520
521
522static void
523close_handler (gpointer user_data)
524{
525 FinCalcDialog *fcd = user_data;
526
527 gtk_widget_destroy (fcd->dialog);
528}
529
530static gboolean
531show_handler (const char *klass, gint component_id,
532 gpointer user_data, gpointer iter_data)
533{
534 FinCalcDialog *fcd = user_data;
535
536 if (!fcd)
537 return FALSE;
538 gtk_window_present (GTK_WINDOW(fcd->dialog));
539 return TRUE;
540}
541
542
555static void
556fincalc_init_gae (GNCAmountEdit *edit,
557 gint min_places,
558 gint max_places,
559 gint fraction)
560{
561 GNCPrintAmountInfo print_info;
562 GtkWidget *entry;
563
564 print_info = gnc_integral_print_info ();
565 print_info.min_decimal_places = min_places;
566 print_info.max_decimal_places = max_places;
567
568 gnc_amount_edit_set_print_info (edit, print_info);
569 gnc_amount_edit_set_fraction (edit, fraction);
570 gnc_amount_edit_set_evaluate_on_enter (edit, TRUE);
571 entry = gnc_amount_edit_gtk_entry (edit);
572 gtk_entry_set_alignment (GTK_ENTRY(entry), 1.0);
573}
574
580static void
581fincalc_init_commodity_gae (GNCAmountEdit *edit)
582{
583 GNCPrintAmountInfo print_info;
584 gnc_commodity *commodity;
585 gint fraction;
586 GtkWidget *entry;
587
588 commodity = gnc_default_currency ();
589 fraction = gnc_commodity_get_fraction (commodity);
590 print_info = gnc_commodity_print_info (commodity, FALSE);
591
592 gnc_amount_edit_set_print_info (edit, print_info);
593 gnc_amount_edit_set_fraction (edit, fraction);
594 gnc_amount_edit_set_evaluate_on_enter (edit, TRUE);
595 entry = gnc_amount_edit_gtk_entry (edit);
596 gtk_entry_set_alignment (GTK_ENTRY(entry), 1.0);
597}
598
599void
600gnc_ui_fincalc_dialog_create (GtkWindow *parent)
601{
602 FinCalcDialog *fcd;
603 GtkWidget *button;
604 GtkWidget *combo;
605 GtkWidget *edit;
606 GtkWidget *spin;
607 GtkWidget *hbox;
608 GtkBuilder *builder;
609 GtkAdjustment *adjustment;
610
611 if (gnc_forall_gui_components (DIALOG_FINCALC_CM_CLASS,
612 show_handler, NULL))
613 return;
614
615
616 fcd = g_new0 (FinCalcDialog, 1);
617
618 builder = gtk_builder_new ();
619 gnc_builder_add_from_file (builder, "dialog-fincalc.glade", "liststore1");
620 gnc_builder_add_from_file (builder, "dialog-fincalc.glade", "liststore2");
621 gnc_builder_add_from_file (builder, "dialog-fincalc.glade", "financial_calculator_dialog");
622
623 fcd->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "financial_calculator_dialog"));
624
625 // Set the name for this dialog so it can be easily manipulated with css
626 gtk_widget_set_name (GTK_WIDGET(fcd->dialog), "gnc-id-financial-calc");
627
628 /* parent */
629 if (parent != NULL)
630 gtk_window_set_transient_for (GTK_WINDOW(fcd->dialog), GTK_WINDOW(parent));
631
632 gnc_register_gui_component (DIALOG_FINCALC_CM_CLASS,
633 NULL, close_handler, fcd);
634
635 g_signal_connect (G_OBJECT(fcd->dialog), "destroy",
636 G_CALLBACK(fincalc_dialog_destroy), fcd);
637
638 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "payment_periods_hbox"));
639 edit = gnc_amount_edit_new ();
640 fincalc_init_gae (GNC_AMOUNT_EDIT(edit), 0, 0, 1);
641 fcd->amounts[PAYMENT_PERIODS] = edit;
642 gtk_box_pack_end (GTK_BOX(hbox), edit, TRUE, TRUE, 0);
643 g_signal_connect (G_OBJECT(edit), "changed",
644 G_CALLBACK(fincalc_update_calc_button_cb), fcd);
645
646 button = GTK_WIDGET(gtk_builder_get_object (builder, "payment_periods_clear_button"));
647 g_object_set_data (G_OBJECT(button), "edit", edit);
648
649 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "interest_rate_hbox"));
650 edit = gnc_amount_edit_new ();
651 fincalc_init_gae (GNC_AMOUNT_EDIT(edit), 2, 5, 100000);
652 fcd->amounts[INTEREST_RATE] = edit;
653 gtk_box_pack_end (GTK_BOX(hbox), edit, TRUE, TRUE, 0);
654 g_signal_connect (G_OBJECT(edit), "changed",
655 G_CALLBACK(fincalc_update_calc_button_cb), fcd);
656
657 button = GTK_WIDGET(gtk_builder_get_object (builder, "interest_rate_clear_button"));
658 g_object_set_data (G_OBJECT(button), "edit", edit);
659
660 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "present_value_hbox"));
661 edit = gnc_amount_edit_new ();
662 fincalc_init_commodity_gae (GNC_AMOUNT_EDIT(edit));
663 fcd->amounts[PRESENT_VALUE] = edit;
664 gtk_box_pack_end (GTK_BOX(hbox), edit, TRUE, TRUE, 0);
665 g_signal_connect (G_OBJECT(edit), "changed",
666 G_CALLBACK(fincalc_update_calc_button_cb), fcd);
667
668 button = GTK_WIDGET(gtk_builder_get_object (builder, "present_value_clear_button"));
669 g_object_set_data (G_OBJECT(button), "edit", edit);
670
671 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "periodic_payment_hbox"));
672 edit = gnc_amount_edit_new ();
673 fincalc_init_commodity_gae (GNC_AMOUNT_EDIT(edit));
674 fcd->amounts[PERIODIC_PAYMENT] = edit;
675 gtk_box_pack_end (GTK_BOX(hbox), edit, TRUE, TRUE, 0);
676 g_signal_connect (G_OBJECT(edit), "changed",
677 G_CALLBACK(fincalc_update_calc_button_cb), fcd);
678
679 button = GTK_WIDGET(gtk_builder_get_object (builder, "periodic_payment_clear_button"));
680 g_object_set_data (G_OBJECT(button), "edit", edit);
681
682 hbox = GTK_WIDGET(gtk_builder_get_object (builder, "future_value_hbox"));
683 edit = gnc_amount_edit_new ();
684 fincalc_init_commodity_gae (GNC_AMOUNT_EDIT(edit));
685 fcd->amounts[FUTURE_VALUE] = edit;
686 gtk_box_pack_end (GTK_BOX(hbox), edit, TRUE, TRUE, 0);
687 g_signal_connect (G_OBJECT(edit), "changed",
688 G_CALLBACK(fincalc_update_calc_button_cb), fcd);
689
690 button = GTK_WIDGET(gtk_builder_get_object (builder, "future_value_clear_button"));
691 g_object_set_data (G_OBJECT(button), "edit", edit);
692
693 fcd->calc_button = GTK_WIDGET(gtk_builder_get_object (builder, "calc_button"));
694
695 combo = GTK_WIDGET(gtk_builder_get_object (builder, "compounding_combo"));
696 fcd->compounding_combo = combo;
697 g_signal_connect(fcd->compounding_combo, "changed",
698 G_CALLBACK (fincalc_update_calc_button_cb), fcd);
699
700 combo = GTK_WIDGET(gtk_builder_get_object (builder, "payment_combo"));
701 fcd->payment_combo = combo;
702 g_signal_connect (fcd->compounding_combo, "changed",
703 G_CALLBACK(fincalc_update_calc_button_cb), fcd);
704
705 spin = GTK_WIDGET(gtk_builder_get_object (builder, "precision_spin"));
706 adjustment = gtk_adjustment_new (2, 0, 10, 1, 1, 1);
707 gtk_spin_button_set_adjustment (GTK_SPIN_BUTTON(spin), adjustment);
708 fcd->precision = spin;
709
710 button = GTK_WIDGET(gtk_builder_get_object (builder, "period_payment_radio"));
711 fcd->end_of_period_radio = button;
712
713 button = GTK_WIDGET(gtk_builder_get_object (builder, "discrete_compounding_radio"));
714 fcd->discrete_compounding_radio = button;
715
716 fcd->payment_total_label = GTK_WIDGET(gtk_builder_get_object (builder, "payment_total_label"));
717
718 button = GTK_WIDGET(gtk_builder_get_object (builder, "schedule_button"));
719 gtk_widget_hide (button);
720
721 init_fi (fcd);
722
723 fi_to_gui (fcd);
724
725 gtk_widget_grab_focus (fcd->amounts[PAYMENT_PERIODS]);
726
727 /* Connect all signals specified in glade. */
728 gtk_builder_connect_signals (builder, fcd);
729 g_object_unref (G_OBJECT(builder));
730
731 gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(fcd->dialog), parent);
732 gtk_widget_show (fcd->dialog);
733}
734
735void
736gnc_ui_fincalc_dialog_destroy (FinCalcDialog *fcd)
737{
738 if (fcd == NULL)
739 return;
740
741 gnc_close_gui_component_by_data (DIALOG_FINCALC_CM_CLASS, fcd);
742}
Commodity handling public routines.
All type declarations for the whole Gnucash engine.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
void gnc_gnome_help(GtkWindow *parent, const char *file_name, const char *anchor)
Launch the systems default help browser, gnome's yelp for linux, and open to a given link within a gi...
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
gnc_numeric double_to_gnc_numeric(double in, gint64 denom, gint how)
Convert a floating-point number to a gnc_numeric.
gnc_numeric gnc_numeric_from_string(const gchar *str)
Read a gnc_numeric from str, skipping any leading whitespace.
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.