GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dialog-fincalc.c
1 /********************************************************************\
2  * dialog-fincalc.c : dialog for a financial calculator *
3  * Copyright (C) 2000 Dave Peticolas <[email protected]> *
4  * Copyright (c) 2006 David Hampton <[email protected]> *
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 [email protected] *
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-gui-query.h"
41 #include "gnc-locale-utils.h"
42 
43 
44 #define DIALOG_FINCALC_CM_CLASS "dialog-fincalc"
45 #define GNC_PREFS_GROUP "dialogs.fincalc"
46 
47 typedef enum
48 {
49  PAYMENT_PERIODS = 0,
50  INTEREST_RATE,
51  PRESENT_VALUE,
52  PERIODIC_PAYMENT,
53  FUTURE_VALUE,
54  NUM_FIN_CALC_VALUES
55 } FinCalcValue;
56 
57 
60 {
61  GtkWidget *dialog;
62 
63  GtkWidget *amounts[NUM_FIN_CALC_VALUES];
64 
65  GtkWidget *calc_button;
66 
67  GtkWidget *compounding_combo;
68  GtkWidget *payment_combo;
69 
70  GtkWidget *end_of_period_radio;
71  GtkWidget *discrete_compounding_radio;
72 
73  GtkWidget *payment_total_label;
74 
76 };
77 
78 static unsigned int periods[] =
79 {
80  1, /* annual */
81  2, /* semi-annual */
82  3, /* tri-annual */
83  4, /* quarterly */
84  6, /* bi-monthly */
85  12, /* monthly */
86  24, /* semi-monthly */
87  26, /* bi-weekly */
88  52, /* weekly */
89  360, /* daily (360) */
90  365, /* daily (365) */
91 };
92 
93 /* This static indicates the debugging module that this .o belongs to. */
94 static QofLogModule log_module = GNC_MOD_GUI;
95 
96 
98 void fincalc_update_calc_button_cb(GtkWidget *unused, FinCalcDialog *fcd);
99 void fincalc_calc_clicked_cb(GtkButton *button, FinCalcDialog *fcd);
100 void fincalc_compounding_radio_toggled(GtkToggleButton *togglebutton, gpointer data);
101 void fincalc_amount_clear_clicked_cb(GtkButton *button, FinCalcDialog *fcd);
102 void fincalc_response_cb (GtkDialog *dialog, gint response, FinCalcDialog *fcd);
103 
106 /* Ensure the given argument is one of the values in the periods array
107  * above and return the index of the value. */
108 static int
109 normalize_period(unsigned int *period)
110 {
111  int i;
112 
113  g_return_val_if_fail (period, 0);
114 
115  for (i = (sizeof(periods) / sizeof(unsigned int)) - 1; i >= 0; i--)
116  if (*period >= periods[i])
117  {
118  *period = periods[i];
119  return i;
120  }
121 
122  *period = periods[0];
123 
124  return 0;
125 }
126 
127 /* Copy the values in the financial_info structure to the GUI */
128 static void
129 fi_to_gui(FinCalcDialog *fcd)
130 {
131  const gnc_commodity *commodity;
132  static char string[64];
133  gnc_numeric total;
134  gnc_numeric npp;
135  gnc_numeric pmt;
136  int i;
137 
138  if (fcd == NULL)
139  return;
140 
141  npp = gnc_numeric_create (fcd->financial_info.npp, 1);
142 
143  gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(fcd->amounts[PAYMENT_PERIODS]),
144  npp);
145  gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]),
146  fcd->financial_info.ir);
147  gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]),
148  fcd->financial_info.pv);
149  gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]),
150  fcd->financial_info.pmt);
151  gnc_amount_edit_set_damount (GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]),
152  -fcd->financial_info.fv);
153 
154  pmt = double_to_gnc_numeric (fcd->financial_info.pmt, 100000, GNC_HOW_RND_ROUND_HALF_UP);
155 
156  commodity = gnc_default_currency ();
157 
158  total = gnc_numeric_mul (npp, pmt, gnc_commodity_get_fraction (commodity),
160 
161  xaccSPrintAmount (string, total, gnc_default_print_info (FALSE));
162  gtk_label_set_text (GTK_LABEL(fcd->payment_total_label), string);
163 
164  i = normalize_period(&fcd->financial_info.CF);
165  gtk_combo_box_set_active(GTK_COMBO_BOX(fcd->compounding_combo), i);
166 
167  i = normalize_period(&fcd->financial_info.PF);
168  gtk_combo_box_set_active(GTK_COMBO_BOX(fcd->payment_combo), i);
169 
170  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fcd->end_of_period_radio),
171  !fcd->financial_info.bep);
172 
173  gtk_toggle_button_set_active
174  (GTK_TOGGLE_BUTTON(fcd->discrete_compounding_radio),
175  fcd->financial_info.disc);
176 }
177 
178 /* Copy the values in the GUI to the financial_info structure */
179 static void
180 gui_to_fi(FinCalcDialog *fcd)
181 {
182  GtkToggleButton *toggle;
183  gnc_numeric npp;
184  int i;
185 
186  if (fcd == NULL)
187  return;
188 
189  npp =
190  gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(fcd->amounts[PAYMENT_PERIODS]));
191  fcd->financial_info.npp = npp.num;
192 
193  fcd->financial_info.ir =
194  gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[INTEREST_RATE]));
195 
196  fcd->financial_info.pv =
197  gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[PRESENT_VALUE]));
198 
199  fcd->financial_info.pmt =
200  gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[PERIODIC_PAYMENT]));
201 
202  fcd->financial_info.fv =
203  gnc_amount_edit_get_damount(GNC_AMOUNT_EDIT(fcd->amounts[FUTURE_VALUE]));
204  fcd->financial_info.fv = -fcd->financial_info.fv;
205 
206  i = gtk_combo_box_get_active(GTK_COMBO_BOX(fcd->compounding_combo));
207  fcd->financial_info.CF = periods[i];
208 
209  i = gtk_combo_box_get_active(GTK_COMBO_BOX(fcd->payment_combo));
210  fcd->financial_info.PF = periods[i];
211 
212  toggle = GTK_TOGGLE_BUTTON(fcd->end_of_period_radio);
213  fcd->financial_info.bep = !gtk_toggle_button_get_active(toggle);
214 
215  toggle = GTK_TOGGLE_BUTTON(fcd->discrete_compounding_radio);
216  fcd->financial_info.disc = gtk_toggle_button_get_active(toggle);
217 
218  fcd->financial_info.prec = gnc_locale_decimal_places ();
219 }
220 
221 /* Set the sensitivity of the calculation buttons based on the argument. */
222 void
223 fincalc_update_calc_button_cb(GtkWidget *unused, FinCalcDialog *fcd)
224 {
225  const gchar *text;
226  gint i;
227 
228  if (fcd == NULL)
229  return;
230 
231  for (i = 0; i < NUM_FIN_CALC_VALUES; i++)
232  {
233  text = gtk_entry_get_text(GTK_ENTRY(fcd->amounts[i]));
234  if ((text == NULL) || (*text == '\0'))
235  {
236  gtk_widget_set_sensitive(GTK_WIDGET(fcd->calc_button), TRUE);
237  return;
238  }
239  }
240 
241  gtk_widget_set_sensitive(GTK_WIDGET(fcd->calc_button), FALSE);
242 }
243 
244 /* Free the calc button list and free the FinCalcDialog structure. */
245 static void
246 fincalc_dialog_destroy(GtkObject *object, gpointer data)
247 {
248  FinCalcDialog *fcd = data;
249 
250  if (fcd == NULL)
251  return;
252 
253  gnc_unregister_gui_component_by_data (DIALOG_FINCALC_CM_CLASS, fcd);
254 
255  g_free(fcd);
256 }
257 
258 void
259 fincalc_compounding_radio_toggled(GtkToggleButton *togglebutton, gpointer data)
260 {
261  FinCalcDialog *fcd = data;
262  gboolean sensitive;
263 
264  if (fcd == NULL)
265  return;
266 
267  fincalc_update_calc_button_cb(GTK_WIDGET(togglebutton), fcd);
268 
269  sensitive = gtk_toggle_button_get_active (togglebutton);
270 
271  gtk_widget_set_sensitive (fcd->compounding_combo, sensitive);
272 }
273 
274 void
275 fincalc_amount_clear_clicked_cb(GtkButton *button, FinCalcDialog *fcd)
276 {
277  GtkEntry * edit = GTK_ENTRY(g_object_get_data(G_OBJECT(button), "edit"));
278 
279  if (edit && GTK_IS_ENTRY(edit))
280  gtk_entry_set_text(edit, "");
281 }
282 
283 static void
284 init_fi(FinCalcDialog *fcd)
285 {
286  struct lconv *lc;
287 
288  if (fcd == NULL)
289  return;
290 
291  lc = gnc_localeconv();
292 
293  fcd->financial_info.npp = 12;
294  fcd->financial_info.ir = 8.5;
295  fcd->financial_info.pv = 15000.0;
296  fcd->financial_info.pmt = -400.0;
297  fcd->financial_info.CF = 12;
298  fcd->financial_info.PF = 12;
299  fcd->financial_info.bep = FALSE;
300  fcd->financial_info.disc = TRUE;
301  fcd->financial_info.prec = lc->frac_digits;
302 
303  fi_calc_future_value(&fcd->financial_info);
304 }
305 
306 /* Determine whether the value can be calculated. If it can, return
307  * NULL. Otherwise, return a string describing the reason and the offending
308  * entry in error_item. */
309 static const char *
310 can_calc_value(FinCalcDialog *fcd, FinCalcValue value, int *error_item)
311 {
312  const char *missing = _("This program can only calculate one value at a time. "
313  "You must enter values for all but one quantity.");
314  const char *bad_exp = _("GnuCash cannot determine the value in one of the fields. "
315  "You must enter a valid expression.");
316  const char *string;
317  gnc_numeric nvalue;
318  unsigned int i;
319 
320  if (fcd == NULL)
321  return NULL;
322 
323  /* Check for missing values */
324  for (i = 0; i < NUM_FIN_CALC_VALUES; i++)
325  if (i != value)
326  {
327  string = gtk_entry_get_text(GTK_ENTRY(fcd->amounts[i]));
328  if ((string == NULL) || (*string == '\0'))
329  {
330  *error_item = i;
331  return missing;
332  }
333 
334  if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (fcd->amounts[i])))
335  {
336  *error_item = i;
337  return bad_exp;
338  }
339  }
340 
341  /* Check for zero interest */
342  switch (value)
343  {
344  case PAYMENT_PERIODS:
345  case PRESENT_VALUE:
346  case PERIODIC_PAYMENT:
347  case FUTURE_VALUE:
348  nvalue = gnc_amount_edit_get_amount
349  (GNC_AMOUNT_EDIT (fcd->amounts[INTEREST_RATE]));
350  if (gnc_numeric_zero_p (nvalue))
351  {
352  *error_item = INTEREST_RATE;
353  return _("The interest rate cannot be zero.");
354  }
355  break;
356  default:
357  break;
358  }
359 
360  /* Check for zero payment periods */
361  switch (value)
362  {
363  case INTEREST_RATE:
364  case PRESENT_VALUE:
365  case PERIODIC_PAYMENT:
366  case FUTURE_VALUE:
367  nvalue = gnc_amount_edit_get_amount
368  (GNC_AMOUNT_EDIT(fcd->amounts[PAYMENT_PERIODS]));
369  if (gnc_numeric_zero_p (nvalue))
370  {
371  *error_item = PAYMENT_PERIODS;
372  return _("The number of payments cannot be zero.");
373  }
374  if (gnc_numeric_negative_p (nvalue))
375  {
376  *error_item = PAYMENT_PERIODS;
377  return _("The number of payments cannot be negative.");
378  }
379  break;
380  default:
381  break;
382  }
383 
384  return NULL;
385 }
386 
387 static void
388 calc_value(FinCalcDialog *fcd, FinCalcValue value)
389 {
390  const char *string;
391  int error_item = 0;
392 
393  if (fcd == NULL)
394  return;
395 
396  string = can_calc_value(fcd, value, &error_item);
397  if (string != NULL)
398  {
399  GtkWidget *entry;
400 
401  gnc_error_dialog(fcd->dialog, "%s", string);
402  if (error_item == 0)
403  entry = fcd->amounts[0];
404  else
405  entry = fcd->amounts[error_item];
406  gtk_widget_grab_focus (entry);
407  return;
408  }
409 
410  gui_to_fi(fcd);
411 
412  switch (value)
413  {
414  case PAYMENT_PERIODS:
415  fi_calc_num_payments(&fcd->financial_info);
416  break;
417  case INTEREST_RATE:
418  fi_calc_interest(&fcd->financial_info);
419  break;
420  case PRESENT_VALUE:
421  fi_calc_present_value(&fcd->financial_info);
422  break;
423  case PERIODIC_PAYMENT:
424  fi_calc_payment(&fcd->financial_info);
425  break;
426  case FUTURE_VALUE:
427  fi_calc_future_value(&fcd->financial_info);
428  break;
429  default:
430  PERR("Unknown financial variable");
431  break;
432  }
433 
434  fi_to_gui(fcd);
435 
436  gtk_widget_set_sensitive(GTK_WIDGET(fcd->calc_button), FALSE);
437 }
438 
439 void
440 fincalc_calc_clicked_cb(GtkButton *button, FinCalcDialog *fcd)
441 {
442  const gchar *text;
443  gint i;
444 
445  for (i = 0; i < NUM_FIN_CALC_VALUES; i++)
446  {
447  text = gtk_entry_get_text(GTK_ENTRY(fcd->amounts[i]));
448  if ((text != NULL) && (*text != '\0'))
449  continue;
450  calc_value(fcd, i);
451  return;
452  }
453 }
454 
455 void fincalc_response_cb (GtkDialog *dialog,
456  gint response,
457  FinCalcDialog *fcd)
458 {
459  switch (response)
460  {
461  case GTK_RESPONSE_OK:
462  /* Do something here whenever the hidden schedule button is clicked. */
463  /* Fall through */
464 
465  case GTK_RESPONSE_CLOSE:
466  gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(dialog));
467  break;
468 
469  default:
470  /* Cancel, destroy, etc. Do nothing. */
471  break;
472  }
473 
474  gnc_close_gui_component_by_data (DIALOG_FINCALC_CM_CLASS, fcd);
475 }
476 
477 
478 static void
479 close_handler (gpointer user_data)
480 {
481  FinCalcDialog *fcd = user_data;
482 
483  gtk_widget_destroy (fcd->dialog);
484 }
485 
486 static gboolean
487 show_handler (const char *klass, gint component_id,
488  gpointer user_data, gpointer iter_data)
489 {
490  FinCalcDialog *fcd = user_data;
491 
492  if (!fcd)
493  return(FALSE);
494  gtk_window_present (GTK_WINDOW(fcd->dialog));
495  return(TRUE);
496 }
497 
498 
511 static void
512 fincalc_init_gae (GNCAmountEdit *edit,
513  gint min_places,
514  gint max_places,
515  gint fraction)
516 {
517  GNCPrintAmountInfo print_info;
518 
519  print_info = gnc_integral_print_info ();
520  print_info.min_decimal_places = min_places;
521  print_info.max_decimal_places = max_places;
522 
523  gnc_amount_edit_set_print_info (edit, print_info);
524  gnc_amount_edit_set_fraction (edit, fraction);
525  gnc_amount_edit_set_evaluate_on_enter (edit, TRUE);
526  gtk_entry_set_alignment (GTK_ENTRY(edit), 1.0);
527 }
528 
534 static void
535 fincalc_init_commodity_gae (GNCAmountEdit *edit)
536 {
537  GNCPrintAmountInfo print_info;
538  gnc_commodity *commodity;
539  gint fraction;
540 
541  commodity = gnc_default_currency();
542  fraction = gnc_commodity_get_fraction(commodity);
543  print_info = gnc_commodity_print_info (commodity, FALSE);
544 
545  gnc_amount_edit_set_print_info (edit, print_info);
546  gnc_amount_edit_set_fraction (edit, fraction);
547  gnc_amount_edit_set_evaluate_on_enter (edit, TRUE);
548  gtk_entry_set_alignment (GTK_ENTRY(edit), 1.0);
549 }
550 
551 void
552 gnc_ui_fincalc_dialog_create(void)
553 {
554  FinCalcDialog *fcd;
555  GtkWidget *button;
556  GtkWidget *combo;
557  GtkWidget *edit;
558  GtkWidget *hbox;
559  GtkBuilder *builder;
560 
561  if (gnc_forall_gui_components (DIALOG_FINCALC_CM_CLASS,
562  show_handler, NULL))
563  return;
564 
565 
566  fcd = g_new0(FinCalcDialog, 1);
567 
568  builder = gtk_builder_new();
569  gnc_builder_add_from_file (builder, "dialog-fincalc.glade", "liststore1");
570  gnc_builder_add_from_file (builder, "dialog-fincalc.glade", "liststore2");
571  gnc_builder_add_from_file (builder, "dialog-fincalc.glade", "Financial Calculator Dialog");
572 
573  fcd->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "Financial Calculator Dialog"));
574 
575  gnc_register_gui_component (DIALOG_FINCALC_CM_CLASS,
576  NULL, close_handler, fcd);
577 
578  g_signal_connect (G_OBJECT (fcd->dialog), "destroy",
579  G_CALLBACK (fincalc_dialog_destroy), fcd);
580 
581 
582  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "payment_periods_hbox"));
583  edit = gnc_amount_edit_new();
584  fincalc_init_gae (GNC_AMOUNT_EDIT (edit), 0, 0, 1);
585  fcd->amounts[PAYMENT_PERIODS] = edit;
586  gtk_box_pack_end(GTK_BOX(hbox), edit, FALSE, FALSE, 0);
587  g_signal_connect (G_OBJECT(edit), "changed",
588  G_CALLBACK (fincalc_update_calc_button_cb), fcd);
589 
590  button = GTK_WIDGET(gtk_builder_get_object (builder, "payment_periods_clear_button"));
591  g_object_set_data(G_OBJECT(button), "edit", edit);
592 
593  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "interest_rate_hbox"));
594  edit = gnc_amount_edit_new();
595  fincalc_init_gae (GNC_AMOUNT_EDIT (edit), 2, 5, 100000);
596  fcd->amounts[INTEREST_RATE] = edit;
597  gtk_box_pack_end(GTK_BOX(hbox), edit, FALSE, FALSE, 0);
598  g_signal_connect (G_OBJECT(edit), "changed",
599  G_CALLBACK (fincalc_update_calc_button_cb), fcd);
600 
601  button = GTK_WIDGET(gtk_builder_get_object (builder, "interest_rate_clear_button"));
602  g_object_set_data(G_OBJECT(button), "edit", edit);
603 
604  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "present_value_hbox"));
605  edit = gnc_amount_edit_new();
606  fincalc_init_commodity_gae (GNC_AMOUNT_EDIT (edit));
607  fcd->amounts[PRESENT_VALUE] = edit;
608  gtk_box_pack_end(GTK_BOX(hbox), edit, FALSE, FALSE, 0);
609  g_signal_connect (G_OBJECT(edit), "changed",
610  G_CALLBACK (fincalc_update_calc_button_cb), fcd);
611 
612  button = GTK_WIDGET(gtk_builder_get_object (builder, "present_value_clear_button"));
613  g_object_set_data(G_OBJECT(button), "edit", edit);
614 
615  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "periodic_payment_hbox"));
616  edit = gnc_amount_edit_new();
617  fincalc_init_commodity_gae (GNC_AMOUNT_EDIT (edit));
618  fcd->amounts[PERIODIC_PAYMENT] = edit;
619  gtk_box_pack_end(GTK_BOX(hbox), edit, FALSE, FALSE, 0);
620  g_signal_connect (G_OBJECT(edit), "changed",
621  G_CALLBACK (fincalc_update_calc_button_cb), fcd);
622 
623  button = GTK_WIDGET(gtk_builder_get_object (builder, "periodic_payment_clear_button"));
624  g_object_set_data(G_OBJECT(button), "edit", edit);
625 
626  hbox = GTK_WIDGET(gtk_builder_get_object (builder, "future_value_hbox"));
627  edit = gnc_amount_edit_new();
628  fincalc_init_commodity_gae (GNC_AMOUNT_EDIT (edit));
629  fcd->amounts[FUTURE_VALUE] = edit;
630  gtk_box_pack_end(GTK_BOX(hbox), edit, FALSE, FALSE, 0);
631  g_signal_connect (G_OBJECT(edit), "changed",
632  G_CALLBACK (fincalc_update_calc_button_cb), fcd);
633 
634  button = GTK_WIDGET(gtk_builder_get_object (builder, "future_value_clear_button"));
635  g_object_set_data(G_OBJECT(button), "edit", edit);
636 
637 
638  fcd->calc_button = GTK_WIDGET(gtk_builder_get_object (builder, "calc_button"));
639 
640 
641  combo = GTK_WIDGET(gtk_builder_get_object (builder, "compounding_combo"));
642  fcd->compounding_combo = combo;
643  g_signal_connect(fcd->compounding_combo, "changed",
644  G_CALLBACK (fincalc_update_calc_button_cb), fcd);
645 
646  combo = GTK_WIDGET(gtk_builder_get_object (builder, "payment_combo"));
647  fcd->payment_combo = combo;
648  g_signal_connect(fcd->compounding_combo, "changed",
649  G_CALLBACK (fincalc_update_calc_button_cb), fcd);
650 
651  button = GTK_WIDGET(gtk_builder_get_object (builder, "period_payment_radio"));
652  fcd->end_of_period_radio = button;
653 
654  button = GTK_WIDGET(gtk_builder_get_object (builder, "discrete_compounding_radio"));
655  fcd->discrete_compounding_radio = button;
656 
657  fcd->payment_total_label = GTK_WIDGET(gtk_builder_get_object (builder, "payment_total_label"));
658 
659  button = GTK_WIDGET(gtk_builder_get_object (builder, "schedule_button"));
660  gtk_widget_hide (button);
661 
662  init_fi(fcd);
663 
664  fi_to_gui(fcd);
665 
666  gtk_widget_grab_focus(fcd->amounts[PAYMENT_PERIODS]);
667 
668  /* Connect all signals specified in glade. */
669  gtk_builder_connect_signals(builder, fcd);
670  g_object_unref(G_OBJECT(builder));
671 
672  gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(fcd->dialog));
673  gtk_widget_show(fcd->dialog);
674 }
675 
676 void
677 gnc_ui_fincalc_dialog_destroy(FinCalcDialog *fcd)
678 {
679  if (fcd == NULL)
680  return;
681 
682  gnc_close_gui_component_by_data (DIALOG_FINCALC_CM_CLASS, fcd);
683 }
int gnc_commodity_get_fraction(const gnc_commodity *cm)
gnc_numeric double_to_gnc_numeric(double n, gint64 denom, gint how)
gboolean gnc_numeric_zero_p(gnc_numeric a)
#define PERR(format, args...)
Definition: qoflog.h:237
gboolean gnc_numeric_negative_p(gnc_numeric a)
gnc_commodity * gnc_default_currency(void)
Definition: gnc-ui-util.c:939
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
All type declarations for the whole Gnucash engine.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Definition: gnc-ui-util.c:1437
Commodity handling public routines.
const gchar * QofLogModule
Definition: qofid.h:89