1 /* ************************************************************************** */
2 /*                                                                            */
3 /*     Copyright (C)    2000-2007 Cédric Auger (cedric@grisbi.org)            */
4 /*          2003-2009 Benjamin Drieu (bdrieu@april.org)                       */
5 /*                      2009 Pierre Biava (grisbi@pierre.biava.name)          */
6 /*          https://www.grisbi.org/                                           */
7 /*                                                                            */
8 /*  This program is free software; you can redistribute it and/or modify      */
9 /*  it under the terms of the GNU General Public License as published by      */
10 /*  the Free Software Foundation; either version 2 of the License, or         */
11 /*  (at your option) any later version.                                       */
12 /*                                                                            */
13 /*  This program is distributed in the hope that it will be useful,           */
14 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of            */
15 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             */
16 /*  GNU General Public License for more details.                              */
17 /*                                                                            */
18 /*  You should have received a copy of the GNU General Public License         */
19 /*  along with this program; if not, write to the Free Software               */
20 /*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
21 /*                                                                            */
22 /* ************************************************************************** */
23 
24 /**
25  * \file gsb_currency.c
26  * contains tools to work with the currencies
27  */
28 
29 
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33 
34 #include "include.h"
35 #include <glib/gi18n.h>
36 
37 /*START_INCLUDE*/
38 #include "gsb_currency.h"
39 #include "dialog.h"
40 #include "grisbi_app.h"
41 #include "gsb_autofunc.h"
42 #include "gsb_currency_popup.h"
43 #include "gsb_data_account.h"
44 #include "gsb_data_currency.h"
45 #include "gsb_data_currency_link.h"
46 #include "gsb_data_form.h"
47 #include "gsb_data_transaction.h"
48 #include "gsb_dirs.h"
49 #include "gsb_form_widget.h"
50 #include "gsb_real.h"
51 #include "prefs_page_metatree.h"
52 #include "structures.h"
53 #include "utils.h"
54 #include "utils_files.h"
55 #include "utils_prefs.h"
56 #include "utils_real.h"
57 #include "erreur.h"
58 #include "widget_currency_details.h"
59 /*END_INCLUDE*/
60 
61  /** This structure holds information needed for exchange rates cache. */
62 typedef struct	_CachedExchangeRate		CachedExchangeRate;
63 struct _CachedExchangeRate {
64     gint 		currency1_number;	/** First currency */
65     gint 		currency2_number;	/** Second currency */
66     GsbReal		rate;				/** Exchange rate between currency1 and currency 2 */
67     GsbReal		fees;				/** Fees associated with exchange rate */
68 };
69 
70 /*START_STATIC*/
71 static GtkWidget *gsb_currency_make_combobox_exchange_dialog (gint transaction_currency_number,
72                         gint account_currency_number,
73                         gint set_index);
74 /*END_STATIC*/
75 
76 /**
77  * the currency list store, contains 3 columns :
78  * 1 : the code of the currency
79  * 2 : the name(code) of the currency
80  * 3 : the number of the currency
81  * used to be set in the combobox */
82 static GtkListStore *combobox_currency_store;
83 
84 enum CurrencyComboColumns
85 {
86     CURRENCY_COL_CODE = 0,
87     CURRENCY_COL_NAME,
88     CURRENCY_COL_NUMBER,
89     CURRENCY_COL_FLAG,
90     CURRENCY_NUM_COL		 /** Number of columns */
91 };
92 
93 /** Exchange rates cache, used by
94  * gsb_currency_config_set_cached_exchange
95  * and
96  * gsb_currency_get_cached_exchange */
97 static GSList *cached_exchange_rates = NULL;
98 
99 /**
100  * the 2 next variables are filled by gsb_currency_exchange_dialog
101  * and permit to the form to get the result by the functions
102  * gsb_currency_get_current_exchange
103  * gsb_currency_get_current_exchange_fees
104  * */
105 static GsbReal current_exchange;
106 static GsbReal current_exchange_fees;
107 
108 /*START_EXTERN*/
109 extern GtkWidget *detail_devise_compte;
110 /*END_EXTERN*/
111 
112 /******************************************************************************/
113 /* Private functions                                                          */
114 /******************************************************************************/
115 /**
116  * met à jour value à chaque changement du check_button
117  *
118  * \param
119  * \param
120  *
121  * \return
122  **/
gsb_currency_checkbutton_link_changed(GtkWidget * checkbutton,gboolean * value)123 static void gsb_currency_checkbutton_link_changed (GtkWidget *checkbutton,
124 												   gboolean *value)
125 {
126     if (value)
127         *value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
128 }
129 
130 /**
131  * Find whether echange rate between two currencies is known.  If so,
132  * returns a cached_exchange_rate structure with exchange rate
133  * information.
134  *
135  * \param currency1 		First currency
136  * \param currency2 		Second currency
137  *
138  * \return NULL on failure	a pointer to a cached_exchange_rate structure on success.
139  **/
gsb_currency_get_cached_exchange(gint currency1_number,gint currency2_number)140 static CachedExchangeRate *gsb_currency_get_cached_exchange (gint currency1_number,
141 															 gint currency2_number)
142 {
143     GSList *tmp_list;
144 
145     tmp_list = cached_exchange_rates;
146     while (tmp_list)
147     {
148 		CachedExchangeRate *tmp;
149 
150 		tmp = tmp_list->data;
151 		if (currency1_number == tmp->currency1_number && currency2_number == tmp->currency2_number)
152 			return tmp;
153 
154 		tmp_list = tmp_list->next;
155     }
156 
157 	return NULL;
158 }
159 
160 /**
161  * Update exchange rate cache according to arguments.
162  *
163  * \param currency1 	First currency.
164  * \param currency2 	Second currency.
165  * \param change    	Exchange rate between two currencies.
166  * \param fees      	Fees of transaction.
167  *
168  * \return
169  **/
gsb_currency_config_set_cached_exchange(gint currency1_number,gint currency2_number,GsbReal change,GsbReal fees)170 static void gsb_currency_config_set_cached_exchange (gint currency1_number,
171 													 gint currency2_number,
172 													 GsbReal change,
173 													 GsbReal fees)
174 {
175     CachedExchangeRate *tmp;
176 
177     tmp = (CachedExchangeRate *) g_malloc0 (sizeof(CachedExchangeRate));
178 
179     tmp->currency1_number = currency1_number;
180     tmp->currency2_number = currency2_number;
181     tmp->rate = change;
182     tmp->fees = fees;
183 
184     cached_exchange_rates = g_slist_append (cached_exchange_rates, tmp);
185 }
186 
187 /**
188  * create and fill the list store of the currency
189  * come here mean that combobox_currency_store is NULL
190  *
191  * \param
192  *
193  * \return TRUE ok, FALSE problem
194  **/
gsb_currency_create_combobox_store(void)195 static gboolean gsb_currency_create_combobox_store (void)
196 {
197     combobox_currency_store = gtk_list_store_new (CURRENCY_NUM_COL,
198 											      G_TYPE_STRING,		/* CURRENCY_COL_CODE */
199 											      G_TYPE_STRING,		/* CURRENCY_COL_NAME */
200 											      G_TYPE_INT,			/* CURRENCY_COL_NUMBER */
201 											      GDK_TYPE_PIXBUF);		/* CURRENCY_COL_FLAG */
202     gsb_currency_update_combobox_currency_list ();
203 
204 	return TRUE;
205 }
206 
207 /**
208  * Handler that change the entries and calculate the exchange_rate
209  *
210  *
211  * \param entry_1 	the entry which receive the signal
212  * \param entry_2 	the other entry
213  *
214  * \return FALSE
215  **/
gsb_currency_select_double_amount_changed(GtkWidget * entry_1,GtkWidget * entry_2)216 static void gsb_currency_select_double_amount_changed (GtkWidget *entry_1,
217 													   GtkWidget *entry_2)
218 {
219     GtkWidget *entry;
220     GtkWidget *entry_3;
221     GtkWidget *entry_4;
222     GsbReal amount_1;
223     GsbReal amount_2;
224 	GsbReal taux;
225     gboolean link_currency;
226     gboolean valide;
227 
228     entry = g_object_get_data (G_OBJECT (entry_1), "exchange_rate");
229     link_currency = GPOINTER_TO_INT (g_object_get_data ( G_OBJECT (entry_1), "link_currency"));
230 
231     if (link_currency)
232     {
233         entry_3 = entry_2;
234         entry_4 = entry_1;
235     }
236     else
237     {
238         entry_3 = entry_1;
239         entry_4 = entry_2;
240     }
241 
242     valide = gsb_form_widget_get_valide_amout_entry (
243                 gtk_entry_get_text (GTK_ENTRY (entry_1)));
244     if (valide)
245     {
246         /* the entry is valid, make it normal */
247         gtk_widget_set_name (entry_1, "form_entry");
248     }
249     else
250     {
251         /* the entry is not valid, make it red */
252         gtk_widget_set_name (entry_1, "form_entry_error");
253         return;
254     }
255 
256     valide = gsb_form_widget_get_valide_amout_entry (
257                 gtk_entry_get_text (GTK_ENTRY (entry_2)));
258     if (valide)
259     {
260         /* the entry is valid, make it normal */
261         gtk_widget_set_name (entry_2, "form_entry");
262     }
263     else
264     {
265         /* the entry is not valid, make it red */
266         gtk_widget_set_name (entry_2, "form_entry_error");
267         return;
268     }
269 
270     if (strlen (gtk_entry_get_text (GTK_ENTRY (entry_3))) > 0)
271     {
272         if (!strlen (gtk_entry_get_text (GTK_ENTRY (entry_4))))
273 		{
274             gtk_entry_set_text (GTK_ENTRY (entry), "");
275 			gtk_widget_set_sensitive (GTK_WIDGET (entry), TRUE);
276 		}
277 		else
278         {
279             gtk_widget_set_sensitive (GTK_WIDGET (entry), FALSE);
280             amount_1 = utils_real_get_from_string (gtk_entry_get_text (GTK_ENTRY (entry_1)));
281             amount_2 = utils_real_get_from_string (gtk_entry_get_text (GTK_ENTRY (entry_2)));
282             taux = gsb_real_div (amount_2, amount_1);
283             gtk_entry_set_text (GTK_ENTRY (entry), utils_real_get_string (taux));
284         }
285     }
286 }
287 
288 /**
289  * Handler that change the second combobox of a window that ask for
290  * change.
291  *
292  * \param combobox_1 	the combobox which receive the signal
293  * \param combobox_2 	the combobox we want to change
294  *
295  * \return
296  **/
gsb_currency_select_change_currency(GtkWidget * combobox_1,GtkWidget * combobox_2)297 static void gsb_currency_select_change_currency (GtkWidget *combobox_1,
298 												 GtkWidget *combobox_2)
299 {
300     GtkWidget *entry_1;
301     GtkWidget *entry_2;
302     gchar *string = NULL;
303 
304     /* we just need to set the same active menu on the second combobox */
305     g_signal_handlers_block_by_func (G_OBJECT (combobox_1),
306 									 G_CALLBACK (gsb_currency_select_change_currency),
307 									 combobox_2);
308     g_signal_handlers_block_by_func (G_OBJECT (combobox_2),
309 									 G_CALLBACK (gsb_currency_select_change_currency),
310 									 combobox_1);
311 
312     gtk_combo_box_set_active (GTK_COMBO_BOX (combobox_2),
313 							  !gtk_combo_box_get_active (GTK_COMBO_BOX (combobox_1)));
314 
315     entry_1 = g_object_get_data (G_OBJECT (combobox_1), "amount_1_entry");
316     entry_2 = g_object_get_data (G_OBJECT (combobox_1), "amount_2_entry");
317 
318     g_signal_handlers_block_by_func (G_OBJECT (entry_1),
319 									 G_CALLBACK (gsb_currency_select_double_amount_changed),
320 									 entry_2);
321     g_signal_handlers_block_by_func (G_OBJECT (entry_2),
322 									 G_CALLBACK (gsb_currency_select_double_amount_changed),
323 									 entry_1);
324 
325     string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_1)));
326     if (string && strlen (string) > 0)
327     {
328         gtk_entry_set_text (GTK_ENTRY (entry_1), "");
329         gtk_entry_set_text (GTK_ENTRY (entry_2), string);
330         g_free (string);
331     }
332     else
333     {
334         string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_2)));
335         if (string && strlen (string) > 0)
336         {
337             gtk_entry_set_text (GTK_ENTRY (entry_2), "");
338             gtk_entry_set_text (GTK_ENTRY (entry_1), string);
339             g_free (string);
340         }
341     }
342 
343     g_signal_handlers_unblock_by_func (G_OBJECT (entry_1),
344 									   G_CALLBACK (gsb_currency_select_double_amount_changed),
345                     				   entry_2);
346     g_signal_handlers_unblock_by_func (G_OBJECT (entry_2),
347 									   G_CALLBACK (gsb_currency_select_double_amount_changed),
348                     				   entry_1);
349 
350     g_signal_handlers_unblock_by_func (G_OBJECT (combobox_1),
351 									   G_CALLBACK (gsb_currency_select_change_currency),
352                         			   combobox_2);
353     g_signal_handlers_unblock_by_func (G_OBJECT (combobox_2),
354 									   G_CALLBACK (gsb_currency_select_change_currency),
355                         			   combobox_1);
356 }
357 
358 /*
359  * create the exchange rate dialog
360  *
361  * \param
362  * \param
363  *
364  * \return
365  **/
gsb_currency_make_combobox_exchange_dialog(gint transaction_currency_number,gint account_currency_number,gint set_index)366 static GtkWidget *gsb_currency_make_combobox_exchange_dialog (gint transaction_currency_number,
367 															  gint account_currency_number,
368 															  gint set_index)
369 {
370     GtkWidget *combo_box = NULL;
371     GtkListStore *combobox_store;
372     GtkCellRenderer *text_renderer, *flag_renderer;
373     GtkTreeIter iter;
374     GdkPixbuf *pixbuf;
375     gchar *string;
376     gchar *tmp_dir;
377     gint xpad;
378     gint ypad;
379 
380     combobox_store = gtk_list_store_new (3, G_TYPE_INT, GDK_TYPE_PIXBUF,
381 						G_TYPE_STRING);
382 
383     string = g_strconcat (gsb_data_currency_get_code_iso4217 (transaction_currency_number), ".png", NULL);
384 
385     tmp_dir = g_build_filename (gsb_dirs_get_pixmaps_dir (), "flags", string, NULL);
386     pixbuf = gdk_pixbuf_new_from_file (tmp_dir, NULL);
387     g_free (string);
388     g_free (tmp_dir);
389 
390     gtk_list_store_append (GTK_LIST_STORE (combobox_store), &iter);
391     gtk_list_store_set (combobox_store, &iter,
392                     0, transaction_currency_number,
393                     1, pixbuf,
394                     2, gsb_data_currency_get_name (transaction_currency_number),
395                     -1);
396 
397     string = g_strconcat(gsb_data_currency_get_code_iso4217 (account_currency_number), ".png", NULL);
398 
399     tmp_dir = g_build_filename (gsb_dirs_get_pixmaps_dir (), "flags", string, NULL);
400     pixbuf = gdk_pixbuf_new_from_file (tmp_dir, NULL);
401     g_free (string);
402     g_free (tmp_dir);
403 
404     gtk_list_store_append (GTK_LIST_STORE (combobox_store), &iter);
405     gtk_list_store_set (combobox_store, &iter,
406                     0, account_currency_number,
407                     1, pixbuf,
408                     2, gsb_data_currency_get_name (account_currency_number),
409                     -1);
410 
411     combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL
412                         (combobox_store));
413 
414     /* Flag renderer */
415     flag_renderer = gtk_cell_renderer_pixbuf_new ();
416     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), flag_renderer, FALSE);
417     gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), flag_renderer,
418 				    "pixbuf", 1, NULL);
419 
420     gtk_cell_renderer_get_padding (GTK_CELL_RENDERER (flag_renderer), &xpad, &ypad);
421     gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (flag_renderer), 3, ypad);
422 
423     text_renderer = gtk_cell_renderer_text_new ();
424     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), text_renderer, FALSE);
425 
426 	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), text_renderer,
427 					"text", 2, NULL);
428 
429     gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), set_index);
430 
431     return (combo_box);
432 }
433 
434 /**
435  * Set an integer to the value of a menu.  Normally called via a GTK
436  * "changed" signal handler.
437  *
438  * \param menu 		a pointer to a menu widget.
439  * \param dummy 	unused
440  *
441  * \return
442  **/
gsb_currency_combobox_value_changed(GtkWidget * combobox,gint * dummy)443 static gboolean gsb_currency_combobox_value_changed (GtkWidget *combobox,
444 													 gint *dummy)
445 {
446     gint *data;
447 
448     data = g_object_get_data (G_OBJECT(combobox), "pointer");
449 
450     if (data)
451     {
452 		*data = gsb_currency_get_currency_from_combobox (combobox);
453     }
454 
455     /* Mark file as modified */
456     utils_prefs_gsb_file_set_modified ();
457 
458     return (FALSE);
459 }
460 
461 /******************************************************************************/
462 /* Public functions                                                           */
463 /******************************************************************************/
464 /**
465  * set to NULL the static variables
466  *
467  * \param
468  *
469  * \return
470  * */
gsb_currency_init_variables(void)471 void gsb_currency_init_variables (void)
472 {
473     if (combobox_currency_store
474     &&
475     GTK_IS_LIST_STORE (combobox_currency_store))
476     gtk_list_store_clear (combobox_currency_store);
477 
478     combobox_currency_store = NULL;
479     current_exchange = null_real;
480     current_exchange_fees = null_real;
481 }
482 
483 /**
484  * create and return a combobox with the currencies
485  * for automatic value changed in memory, see gsb_autofunc_currency_new
486  *
487  * \param set_name if TRUE, the currencies in the combobox will be name(code), else it will be only the code
488  *
489  * \return a widget combobox or NULL
490  * */
gsb_currency_make_combobox(gboolean set_name)491 GtkWidget *gsb_currency_make_combobox (gboolean set_name)
492 {
493     GtkCellRenderer *text_renderer, *flag_renderer;
494     GtkWidget *combo_box;
495     gint xpad;
496     gint ypad;
497 
498     if (!combobox_currency_store)
499         gsb_currency_create_combobox_store ();
500 
501     combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL
502                         (combobox_currency_store));
503 
504     /* Flag renderer */
505     flag_renderer = gtk_cell_renderer_pixbuf_new ();
506     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), flag_renderer, FALSE);
507     gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), flag_renderer,
508 				    "pixbuf", CURRENCY_COL_FLAG, NULL);
509 
510     gtk_cell_renderer_get_padding (GTK_CELL_RENDERER (flag_renderer), &xpad, &ypad);
511     gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (flag_renderer), 3, ypad);
512 
513     text_renderer = gtk_cell_renderer_text_new ();
514     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), text_renderer, FALSE);
515 
516     if (set_name)
517 	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), text_renderer,
518 					"text", CURRENCY_COL_NAME,
519 					NULL);
520     else
521 	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), text_renderer,
522 					"text", CURRENCY_COL_CODE,
523 					NULL);
524 
525     gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box),
526 			       0);
527 
528     return (combo_box);
529 }
530 
531 /**
532  * create and return a combobox with the currencies
533  * for automatic value changed in memory, see gsb_autofunc_currency_new
534  *
535  * \param combo		a combobox
536  * \param set_name if TRUE, the currencies in the combobox will be name(code), else it will be only the code
537  *
538  * \return a widget combobox or NULL
539  **/
gsb_currency_make_combobox_from_ui(GtkWidget * combo_box,gboolean set_name)540 void gsb_currency_make_combobox_from_ui (GtkWidget *combo_box,
541 										 gboolean set_name)
542 {
543     GtkCellRenderer *text_renderer, *flag_renderer;
544     gint xpad;
545     gint ypad;
546 
547     if (!combobox_currency_store)
548         gsb_currency_create_combobox_store ();
549 
550      gtk_combo_box_set_model (GTK_COMBO_BOX (combo_box), GTK_TREE_MODEL (combobox_currency_store));
551 
552     /* Flag renderer */
553     flag_renderer = gtk_cell_renderer_pixbuf_new ();
554     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), flag_renderer, FALSE);
555     gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box),
556 									flag_renderer,
557 									"pixbuf", CURRENCY_COL_FLAG,
558 									NULL);
559 
560     gtk_cell_renderer_get_padding (GTK_CELL_RENDERER (flag_renderer), &xpad, &ypad);
561     gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (flag_renderer), 3, ypad);
562 
563     text_renderer = gtk_cell_renderer_text_new ();
564     gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), text_renderer, FALSE);
565 
566     if (set_name)
567 		gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box),
568 										text_renderer,
569 										"text", CURRENCY_COL_NAME,
570 										NULL);
571     else
572 		gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box),
573 										text_renderer,
574 										"text", CURRENCY_COL_CODE,
575 										NULL);
576 
577     gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0);
578 }
579 
580 /**
581  * set the combobox on the currency given in param
582  *
583  * \combo_box the combo-box to set
584  * \currency_number the currency we want to set on the combo-box
585  *
586  * \return TRUE currency found, FALSE currency not found, nothing change
587  * */
gsb_currency_set_combobox_history(GtkWidget * combo_box,gint currency_number)588 gboolean gsb_currency_set_combobox_history (GtkWidget *combo_box,
589                         gint currency_number)
590 {
591     GtkTreeIter iter;
592     gint result;
593 
594     if (!combobox_currency_store)
595 	gsb_currency_create_combobox_store ();
596 
597     result = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (combobox_currency_store),
598 					     &iter);
599     while (result)
600     {
601 	gint value;
602 
603 	gtk_tree_model_get (GTK_TREE_MODEL (combobox_currency_store),
604 			     &iter,
605 			     CURRENCY_COL_NUMBER, &value,
606 			     -1);
607 
608 	if (value == currency_number)
609 	{
610 	    gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo_box),
611 					    &iter);
612 	    return TRUE;
613 	}
614 	result = gtk_tree_model_iter_next (GTK_TREE_MODEL (combobox_currency_store),
615 					    &iter);
616     }
617     return FALSE;
618 }
619 
620 
621 /**
622  * Get and return the number of the currency in the option_menu given
623  * in param
624  *
625  * \param currency_option_menu an option menu with the currencies
626  *
627  * \return the number of currency
628  * */
gsb_currency_get_currency_from_combobox(GtkWidget * combo_box)629 gint gsb_currency_get_currency_from_combobox (GtkWidget *combo_box)
630 {
631     gint currency_number = 0;
632     GtkTreeIter iter;
633 
634     if (!combobox_currency_store)
635 	gsb_currency_create_combobox_store ();
636 
637     if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_box),
638 					&iter))
639 	gtk_tree_model_get (GTK_TREE_MODEL (combobox_currency_store),
640 			     &iter,
641 			     CURRENCY_COL_NUMBER, &currency_number,
642 			     -1);
643     return currency_number;
644 }
645 
646 
647 
648 /**
649  * update the list of the currencies for combobox, which change all
650  * the current combobox content
651  *
652  * \param
653  *
654  * \return FALSE
655  */
gsb_currency_update_combobox_currency_list(void)656 gboolean gsb_currency_update_combobox_currency_list (void)
657 {
658 	GtkWidget *combo_devise_totaux_categ;
659 	GtkWidget *combo_devise_totaux_ib;
660 	GtkWidget *combo_devise_totaux_tiers;
661     GSList *list_tmp;
662     gulong handler_id;
663     gint old_currency_number = -1;
664 	gchar* tmpstr;
665 
666 	if (!combobox_currency_store || !gsb_data_currency_get_currency_list ())
667 		return FALSE;
668 
669 	combo_devise_totaux_categ = prefs_page_metatree_get_currency_combobox ("combo_totaux_categ");
670 	combo_devise_totaux_ib = prefs_page_metatree_get_currency_combobox ("combo_totaux_ib");
671 	combo_devise_totaux_tiers = prefs_page_metatree_get_currency_combobox ("combo_totaux_tiers");
672 
673 	/* XXX still buggy, very slow on the gtk_list_store_clear() call, try to find why. */
674     if (detail_devise_compte && G_IS_OBJECT (detail_devise_compte))
675     {
676         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (detail_devise_compte), "changed-hook"));
677         if (handler_id > 0)
678         {
679             g_signal_handler_block ((gpointer *) detail_devise_compte, handler_id);
680             old_currency_number = gtk_combo_box_get_active (GTK_COMBO_BOX (detail_devise_compte));
681         }
682     }
683     if (combo_devise_totaux_tiers && G_IS_OBJECT (combo_devise_totaux_tiers))
684     {
685         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_tiers), "changed-hook"));
686         if (handler_id > 0)
687             g_signal_handler_block ((gpointer *) combo_devise_totaux_tiers,
688 									GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_tiers),
689 																		 "changed-hook")));
690     }
691     if (combo_devise_totaux_categ  && G_IS_OBJECT (combo_devise_totaux_categ))
692     {
693         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_categ), "changed-hook"));
694         if (handler_id > 0)
695             g_signal_handler_block ((gpointer *) combo_devise_totaux_categ,
696 									GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_categ),
697 																		 "changed-hook")));
698     }
699     if (combo_devise_totaux_ib  && G_IS_OBJECT (combo_devise_totaux_ib))
700     {
701         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_ib), "changed-hook"));
702         if (handler_id > 0)
703             g_signal_handler_block ((gpointer *) combo_devise_totaux_ib,
704 									GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_ib),
705 																		 "changed-hook")));
706     }
707 
708     gtk_list_store_clear (GTK_LIST_STORE (combobox_currency_store));
709     list_tmp = gsb_data_currency_get_currency_list ();
710 
711     while (list_tmp)
712     {
713         GtkTreeIter iter;
714         GdkPixbuf * pixbuf;
715         gchar * string;
716         gint currency_number;
717 
718         currency_number = gsb_data_currency_get_no_currency (list_tmp->data);
719         string = g_strconcat (gsb_dirs_get_pixmaps_dir (),
720 							  G_DIR_SEPARATOR_S,
721 							  "flags",
722 							  G_DIR_SEPARATOR_S,
723 							  gsb_data_currency_get_code_iso4217 (currency_number),
724 							  ".png",
725 							  NULL);
726         pixbuf = gdk_pixbuf_new_from_file (string, NULL);
727         g_free (string);
728 
729 
730         gtk_list_store_append (GTK_LIST_STORE (combobox_currency_store), &iter);
731         tmpstr = g_strconcat (gsb_data_currency_get_name (currency_number),
732 							  " (",
733 							  gsb_data_currency_get_nickname_or_code_iso (currency_number),
734 							  ")",
735 							  NULL);
736         gtk_list_store_set (combobox_currency_store,
737 							&iter,
738 							CURRENCY_COL_FLAG, pixbuf,
739 							CURRENCY_COL_CODE, gsb_data_currency_get_nickname_or_code_iso (currency_number),
740 							CURRENCY_COL_NAME, tmpstr,
741 							CURRENCY_COL_NUMBER, currency_number,
742 							-1);
743         g_free (tmpstr);
744         list_tmp = list_tmp->next;
745     }
746 
747     run.mise_a_jour_liste_comptes_accueil = TRUE;
748     run.mise_a_jour_liste_echeances_manuelles_accueil = TRUE;
749     run.mise_a_jour_liste_echeances_auto_accueil = TRUE;
750 
751     if (detail_devise_compte && G_IS_OBJECT (detail_devise_compte))
752     {
753         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (detail_devise_compte), "changed-hook"));
754         if (handler_id > 0)
755         {
756             gtk_combo_box_set_active (GTK_COMBO_BOX (detail_devise_compte), old_currency_number);
757             g_signal_handler_unblock (detail_devise_compte,
758 									  GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (detail_devise_compte),
759 																		   "changed-hook")));
760         }
761     }
762     if (combo_devise_totaux_tiers && G_IS_OBJECT (combo_devise_totaux_tiers))
763     {
764         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_tiers), "changed-hook"));
765         if (handler_id > 0)
766         {
767             gtk_combo_box_set_active (GTK_COMBO_BOX (combo_devise_totaux_tiers), old_currency_number);
768             g_signal_handler_unblock ((gpointer *) combo_devise_totaux_tiers,
769 									  GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_tiers),
770 																		   "changed-hook")));
771         }
772     }
773     if (combo_devise_totaux_categ  && G_IS_OBJECT (combo_devise_totaux_categ))
774     {
775         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_categ), "changed-hook"));
776         if (handler_id > 0)
777         {
778             gtk_combo_box_set_active (GTK_COMBO_BOX (combo_devise_totaux_categ), old_currency_number);
779             g_signal_handler_unblock ((gpointer *) combo_devise_totaux_categ,
780 									  GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_categ),
781 																		   "changed-hook")));
782         }
783     }
784     if (combo_devise_totaux_ib  && G_IS_OBJECT (combo_devise_totaux_ib))
785     {
786         handler_id = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_ib), "changed-hook"));
787         if (handler_id > 0)
788         {
789             gtk_combo_box_set_active (GTK_COMBO_BOX (combo_devise_totaux_ib), old_currency_number);
790             g_signal_handler_unblock ((gpointer *) combo_devise_totaux_ib,
791 									  GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (combo_devise_totaux_ib),
792 																		   "changed-hook")));
793         }
794     }
795 
796     return FALSE;
797 }
798 
799 
800 /**
801  * Check if a transaction need an exchange rate and fees with its
802  * account
803  * if yes, ask for that and set the in the transaction.
804  *
805  * \param transaction_number
806  */
gsb_currency_check_for_change(gint transaction_number)807 void gsb_currency_check_for_change (gint transaction_number)
808 {
809     gint transaction_currency_number;
810     gint account_currency_number;
811     gint link_number;
812 
813     account_currency_number = gsb_data_account_get_currency (
814                         gsb_data_transaction_get_account_number (transaction_number));
815     transaction_currency_number = gsb_data_transaction_get_currency_number (
816                         transaction_number);
817 
818 	if (transaction_currency_number == account_currency_number)
819 	{
820 		gsb_data_transaction_set_exchange_rate (transaction_number, null_real);
821 		gsb_data_transaction_set_change_between (transaction_number, 0);
822 		gsb_data_transaction_set_exchange_fees (transaction_number, null_real);
823 		return;
824 	}
825 
826     link_number = gsb_data_currency_link_search (account_currency_number,
827                         transaction_currency_number);
828 
829     if (link_number)
830     {
831         if (current_exchange_fees.mantissa)
832             gsb_data_transaction_set_exchange_fees (transaction_number,
833                         current_exchange_fees);
834         else
835             gsb_data_transaction_set_exchange_fees (transaction_number,
836                         null_real);
837 
838         if (current_exchange.mantissa == 0)
839             gsb_data_transaction_set_exchange_rate (transaction_number,
840                     gsb_real_abs (
841                     gsb_data_currency_link_get_change_rate (
842                     link_number)));
843         else
844             gsb_data_transaction_set_exchange_rate (transaction_number,
845                     current_exchange);
846 
847         if (gsb_data_currency_link_get_first_currency (
848          link_number) == account_currency_number)
849             gsb_data_transaction_set_change_between (transaction_number, 1);
850         else
851             gsb_data_transaction_set_change_between (transaction_number, 0);
852 
853         return;
854     }
855 
856     if (current_exchange.mantissa == 0)
857         gsb_currency_exchange_dialog (account_currency_number,
858                         transaction_currency_number,
859                         0,
860                         null_real,
861                         null_real,
862                         TRUE);
863 
864     gsb_data_transaction_set_exchange_rate (transaction_number,
865                         gsb_real_abs (current_exchange));
866     if (current_exchange_fees.mantissa)
867         gsb_data_transaction_set_exchange_fees (transaction_number,
868                         current_exchange_fees);
869     else
870         gsb_data_transaction_set_exchange_fees (transaction_number,
871                         null_real);
872 
873     gsb_data_transaction_set_change_between (transaction_number, 0);
874 }
875 
876 
877 /**
878  * ask to the user the exchange and the fees for a transaction
879  * fill the variables current_exchange and current_exchange_fees with
880  * the data of the user
881  * if this was asked before, will use the buffer cached exchange rate, except
882  * if force is set to TRUE
883  *
884  * \param account_currency_number
885  * \param transaction_currency_number
886  * \param link_currency si = TRUE : 1 nom_devise = "change" devise_en_rapport
887  * \param exchange_rate
888  * \param exchange_fees
889  * \param force if TRUE will not get the cached exchange rate and will really ask to the user
890  *
891  * \return
892  * */
gsb_currency_exchange_dialog(gint account_currency_number,gint transaction_currency_number,gboolean link_currency,GsbReal exchange_rate,GsbReal exchange_fees,gboolean force)893 void gsb_currency_exchange_dialog (gint account_currency_number,
894                         gint transaction_currency_number ,
895                         gboolean link_currency,
896                         GsbReal exchange_rate,
897                         GsbReal exchange_fees,
898                         gboolean force)
899 {
900     GtkWidget *dialog, *label, *hbox, *paddingbox, *table, *widget;
901     GtkWidget *entry, *amount_entry, *amount_1_entry, *amount_2_entry, *fees_entry;
902     GtkWidget *combobox_1;
903     GtkWidget *combobox_2;
904     CachedExchangeRate *cache;
905     gchar* tmpstr;
906     gint row = 0;
907     gint result;
908     gint link_number;
909     gint change_link_currency = 1;
910 
911     if (account_currency_number == 0 || transaction_currency_number == 0)
912         return;
913 
914     if (!force
915      &&
916      (cache = gsb_currency_get_cached_exchange (
917      account_currency_number, transaction_currency_number)))
918     {
919         current_exchange = cache->rate;
920         current_exchange_fees = cache->fees;
921         return;
922     }
923 
924     dialog = gtk_dialog_new_with_buttons (_("Enter exchange rate"),
925                         GTK_WINDOW (grisbi_app_get_active_window (NULL)),
926                         GTK_DIALOG_MODAL,
927                         "gtk-cancel", GTK_RESPONSE_CANCEL,
928                         "gtk-ok", GTK_RESPONSE_OK,
929                         NULL);
930 
931     gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT);
932     gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
933 
934     /* text for paddingbox */
935     tmpstr = g_strdup_printf (_("Please enter data for the transaction"));
936 
937     /* Ugly dance to avoid side effects on dialog's vbox. */
938     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
939     gtk_box_pack_start (GTK_BOX (dialog_get_content_area (dialog)), hbox, FALSE, FALSE, 0);
940     paddingbox = new_paddingbox_with_title (hbox, TRUE, tmpstr);
941     gtk_container_set_border_width (GTK_CONTAINER(hbox), 6);
942     gtk_container_set_border_width (GTK_CONTAINER(paddingbox), 6);
943     g_free (tmpstr);
944 
945     /* table for layout */
946     table = gtk_grid_new ();
947     gtk_box_pack_start (GTK_BOX (paddingbox), table, FALSE, FALSE, 6);
948     gtk_grid_set_column_spacing (GTK_GRID (table), 6);
949     gtk_grid_set_row_spacing (GTK_GRID (table), 6);
950 
951     /* echange line label */
952     label = gtk_label_new (_("Currencies"));
953     utils_labels_set_alignment (GTK_LABEL (label), 0.0, 0.0);
954     gtk_grid_attach (GTK_GRID (table), label, 0, row, 1, 1);
955 
956     /* echange line currency 1 */
957     combobox_1 = gsb_currency_make_combobox_exchange_dialog (
958                         transaction_currency_number,
959                         account_currency_number,
960                         link_currency);
961     gtk_grid_attach (GTK_GRID (table), combobox_1, 1, row, 1, 1);
962 
963     /* echange line label */
964     label = gtk_label_new (_("Exchange rate"));
965     utils_labels_set_alignment (GTK_LABEL (label), 0.5, 0.0);
966     gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);
967 
968     /* echange line currency 2 */
969     combobox_2 = gsb_currency_make_combobox_exchange_dialog (
970                         transaction_currency_number,
971                         account_currency_number,
972                         !link_currency);
973     gtk_grid_attach (GTK_GRID (table), combobox_2, 3, row, 1, 1);
974     row++;
975 
976     link_number = gsb_data_currency_link_search (account_currency_number,
977                         transaction_currency_number);
978     if (link_number)
979     {
980         gtk_widget_set_sensitive (combobox_1, FALSE);
981         gtk_widget_set_sensitive (combobox_2, FALSE);
982     }
983 
984     /* amount line */
985     label = gtk_label_new (_("Amounts: "));
986     utils_labels_set_alignment (GTK_LABEL (label), 0.0, 0.0);
987     gtk_grid_attach (GTK_GRID (table), label, 0, row, 1, 1);
988 
989     amount_1_entry = gtk_entry_new ();
990     gtk_entry_set_activates_default (GTK_ENTRY (amount_1_entry), TRUE);
991     gtk_grid_attach (GTK_GRID (table), amount_1_entry, 1, row, 1, 1);
992 
993     /* echange line input field */
994     entry = gtk_entry_new ();
995     gtk_widget_set_size_request (entry, 100, -1);
996     gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
997     gtk_grid_attach (GTK_GRID (table), entry, 2, row, 1, 1);
998 
999     amount_2_entry = gtk_entry_new ();
1000     gtk_entry_set_activates_default (GTK_ENTRY (amount_2_entry), TRUE);
1001     gtk_grid_attach (GTK_GRID (table), amount_2_entry, 3, row, 1, 1);
1002 
1003     /* if amount exist already, fill them here */
1004     if (link_currency)
1005         amount_entry = amount_2_entry;
1006     else
1007         amount_entry = amount_1_entry;
1008 
1009     widget = gsb_form_widget_get_widget (TRANSACTION_FORM_DEBIT);
1010     if (!gsb_form_widget_check_empty (widget))
1011         gtk_entry_set_text (GTK_ENTRY (amount_entry),
1012                         gtk_entry_get_text (GTK_ENTRY (widget)));
1013     else
1014     {
1015         widget = gsb_form_widget_get_widget (TRANSACTION_FORM_CREDIT);
1016         if (!gsb_form_widget_check_empty (widget))
1017             gtk_entry_set_text (GTK_ENTRY (amount_entry),
1018                         gtk_entry_get_text (GTK_ENTRY (widget)));
1019     }
1020 
1021     /* set the connections */
1022     g_signal_connect (G_OBJECT (combobox_1),
1023                         "changed",
1024                         G_CALLBACK (gsb_currency_select_change_currency),
1025                         combobox_2);
1026     g_signal_connect (G_OBJECT (combobox_2),
1027                         "changed",
1028                         G_CALLBACK (gsb_currency_select_change_currency),
1029                         combobox_1);
1030     g_object_set_data (G_OBJECT (combobox_1),
1031                         "amount_1_entry", amount_1_entry);
1032     g_object_set_data (G_OBJECT (combobox_1),
1033                         "amount_2_entry", amount_2_entry);
1034 
1035     g_object_set_data (G_OBJECT (combobox_2),
1036                         "amount_1_entry", amount_1_entry);
1037     g_object_set_data (G_OBJECT (combobox_2),
1038                         "amount_2_entry", amount_2_entry);
1039 
1040     g_signal_connect (G_OBJECT (amount_1_entry),
1041                         "changed",
1042                         G_CALLBACK (gsb_currency_select_double_amount_changed),
1043                         amount_2_entry);
1044     g_signal_connect_swapped (G_OBJECT (amount_2_entry),
1045                         "changed",
1046                         G_CALLBACK (gsb_currency_select_double_amount_changed),
1047                         amount_1_entry);
1048     g_object_set_data (G_OBJECT (amount_1_entry), "exchange_rate", entry);
1049     g_object_set_data (G_OBJECT (amount_1_entry), "link_currency",
1050                         GINT_TO_POINTER (link_currency));
1051     row++;
1052 
1053     /* exchange fees line label */
1054     label = gtk_label_new (_("Exchange fees: "));
1055     utils_labels_set_alignment (GTK_LABEL (label), 0.0, 0.0);
1056     gtk_grid_attach (GTK_GRID (table), label, 0, row, 1, 1);
1057 
1058     /* exchange fees line input field */
1059     fees_entry = gtk_entry_new ();
1060     gtk_entry_set_activates_default (GTK_ENTRY (fees_entry), TRUE);
1061     gtk_grid_attach (GTK_GRID (table), fees_entry, 1, row, 1, 1);
1062 
1063     /* exchange fees currency for fees */
1064     label = gtk_label_new (gsb_data_currency_get_name (account_currency_number));
1065     utils_labels_set_alignment (GTK_LABEL (label), 0.0, 0.0);
1066     gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);
1067 
1068     if (link_number)
1069     {
1070         GtkWidget *checkbox;
1071 
1072         change_link_currency = !gsb_data_currency_link_get_fixed_link (link_number);
1073         checkbox = gtk_check_button_new_with_label (_("Change the link"));
1074         if (change_link_currency)
1075             gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbox), TRUE);
1076         gtk_widget_set_sensitive (checkbox, TRUE);
1077         g_signal_connect (G_OBJECT (checkbox),
1078                         "toggled",
1079                         G_CALLBACK (gsb_currency_checkbutton_link_changed),
1080                         &change_link_currency);
1081 
1082         gtk_grid_attach (GTK_GRID (table), checkbox, 3, row, 1, 1);
1083     }
1084 
1085     /* if the rate or fees exist already, fill them here */
1086     if (exchange_rate.mantissa)
1087     {
1088         tmpstr = utils_real_get_string (exchange_rate);
1089         gtk_entry_set_text (GTK_ENTRY (entry), tmpstr);
1090         g_free (tmpstr);
1091     }
1092 
1093     if (exchange_fees.mantissa)
1094     {
1095         tmpstr = utils_real_get_string (gsb_real_abs (exchange_fees));
1096         gtk_entry_set_text (GTK_ENTRY (fees_entry), tmpstr);
1097         g_free (tmpstr);
1098     }
1099 
1100     gtk_widget_show_all (dialog);
1101 
1102     /* show the dialog */
1103 dialog_return:
1104     result = gtk_dialog_run (GTK_DIALOG (dialog));
1105 
1106     if (result == GTK_RESPONSE_OK)
1107     {
1108         gint new_link_number;
1109         gint new_link_currency;
1110 
1111         current_exchange = utils_real_get_from_string (
1112                         gtk_entry_get_text (GTK_ENTRY (entry)));
1113 
1114         if (strlen (gtk_entry_get_text (GTK_ENTRY (fees_entry))) > 0
1115          ||
1116          strcmp (gtk_entry_get_text (GTK_ENTRY (fees_entry)), "0") != 0)
1117         {
1118             current_exchange_fees = utils_real_get_from_string (
1119                         gtk_entry_get_text (GTK_ENTRY (fees_entry)));
1120         }
1121         else
1122             current_exchange_fees = null_real ;
1123 
1124         if (current_exchange.mantissa == 0)
1125         {
1126             tmpstr = g_strdup_printf (_("The exchange rate or the transaction amount in "
1127                         "%s must be filled."),
1128                         gsb_data_currency_get_name (account_currency_number));
1129             dialogue_warning_hint (tmpstr, _("One field is not filled in"));
1130 
1131             goto dialog_return;
1132         }
1133 
1134         gsb_currency_config_set_cached_exchange (account_currency_number,
1135                         transaction_currency_number,
1136                         current_exchange, current_exchange_fees);
1137 
1138         if (link_number)
1139         {
1140             if (change_link_currency
1141              &&
1142              gsb_real_cmp (current_exchange,
1143              gsb_data_currency_link_get_change_rate (link_number)) != 0)
1144                 gsb_data_currency_link_set_change_rate (link_number,
1145                         current_exchange);
1146         }
1147         else
1148         {
1149             new_link_number = gsb_data_currency_link_new (0);
1150             new_link_currency = gtk_combo_box_get_active (
1151                         GTK_COMBO_BOX (combobox_1));
1152             if (new_link_currency)
1153             {
1154                 gsb_data_currency_link_set_first_currency (new_link_number,
1155                         account_currency_number);
1156                 gsb_data_currency_link_set_second_currency (new_link_number,
1157                         transaction_currency_number);
1158             }
1159             else
1160             {
1161                 gsb_data_currency_link_set_first_currency (new_link_number,
1162                         transaction_currency_number);
1163                 gsb_data_currency_link_set_second_currency (new_link_number,
1164                         account_currency_number);
1165             }
1166             gsb_data_currency_link_set_change_rate (new_link_number,
1167                         current_exchange);
1168         }
1169     }
1170     else
1171         gsb_currency_init_exchanges ();
1172 
1173     gtk_widget_destroy (GTK_WIDGET (dialog));
1174 }
1175 
1176 /*
1177  * initialize current_exchange and current_exchange_fees
1178  *
1179  */
gsb_currency_init_exchanges(void)1180 void gsb_currency_init_exchanges (void)
1181 {
1182     current_exchange = null_real;
1183     current_exchange_fees = null_real;
1184 }
1185 
1186 
1187 
1188 
1189 /**
1190  *
1191  *
1192 **/
gsb_currency_get_current_exchange(void)1193 GsbReal gsb_currency_get_current_exchange (void)
1194 {
1195     return current_exchange;
1196 }
1197 
1198 
1199 /**
1200  *
1201  *
1202 **/
gsb_currency_set_current_exchange(GsbReal exchange)1203 gboolean gsb_currency_set_current_exchange (GsbReal exchange)
1204 {
1205     current_exchange.mantissa = exchange.mantissa;
1206     current_exchange.exponent = exchange.exponent;
1207 
1208     return FALSE;
1209 }
1210 
1211 
1212 /**
1213  *
1214  *
1215 **/
gsb_currency_get_current_exchange_fees(void)1216 GsbReal gsb_currency_get_current_exchange_fees (void)
1217 {
1218     return current_exchange_fees;
1219 }
1220 
1221 
1222 /**
1223  *
1224  *
1225 **/
gsb_currency_set_current_exchange_fees(GsbReal fees)1226 gboolean gsb_currency_set_current_exchange_fees (GsbReal fees)
1227 {
1228     current_exchange_fees.mantissa = fees.mantissa;
1229     current_exchange_fees.exponent = fees.exponent;
1230 
1231     return FALSE;
1232 }
1233 
1234 
1235 
1236 /**
1237  *
1238  *
1239  * \param
1240  * \param
1241  *
1242  * \return
1243  **/
gsb_currency_add_currency_set_combobox(GtkWidget * button,GtkWidget * combobox)1244 gboolean gsb_currency_add_currency_set_combobox (GtkWidget *button,
1245 												 GtkWidget *combobox)
1246 {
1247     gsb_currency_dialog_list_iso_4217_new (NULL, TRUE);
1248     gsb_currency_set_combobox_history (combobox, gsb_data_currency_max_number ());
1249 
1250     return FALSE;
1251 }
1252 
1253 /**
1254  * Create a new GtkComboBox with a pointer to an integer that will be
1255  * modified according to the entry's value.
1256  *
1257  * \param value		A pointer to a gint which contains the currency number
1258  * \param hook 		An optional function to execute as a handler
1259  *
1260  * \return A newly allocated option menu.
1261  **/
gsb_currency_combobox_new(gint * value,GCallback hook)1262 GtkWidget *gsb_currency_combobox_new (gint *value,
1263 									  GCallback hook)
1264 {
1265     GtkWidget *combo_box;
1266 
1267     combo_box = gsb_currency_make_combobox (FALSE);
1268 
1269     if (value && *value)
1270 		gsb_currency_set_combobox_history (combo_box, *value);
1271 
1272     g_signal_connect (G_OBJECT (combo_box),
1273 					  "changed",
1274 					  (GCallback) gsb_currency_combobox_value_changed,
1275 					  value);
1276     g_object_set_data (G_OBJECT (combo_box), "pointer", value);
1277 
1278     if (hook)
1279 		g_object_set_data (G_OBJECT (combo_box),
1280 						   "changed-hook",
1281 						   GUINT_TO_POINTER (g_signal_connect_after (G_OBJECT(combo_box),
1282 																	 "changed",
1283 																	 G_CALLBACK (hook),
1284 																	 value)));
1285     return combo_box;
1286 }
1287 
1288 /**
1289  *
1290  *
1291  * \param
1292  * \param
1293  *
1294  * \return
1295  **/
gsb_currency_dialog_list_iso_4217_new(GtkWidget * page_currency,gboolean no_callback)1296 gint gsb_currency_dialog_list_iso_4217_new (GtkWidget *page_currency,
1297 											gboolean no_callback)
1298 {
1299     GtkWidget *dialog;
1300     GtkWidget *content_area;
1301     GtkWidget *details;
1302     GtkWidget *popup;
1303 	GtkWidget *tree_view;
1304     GtkWidget *vbox;
1305     GtkTreeSelection *selection;
1306     gint currency_number = 0;
1307     gint result;
1308 
1309 	dialog = gtk_dialog_new_with_buttons (_("Add a currency"),
1310 										  GTK_WINDOW (grisbi_app_get_active_window (NULL)),
1311 										  GTK_DIALOG_MODAL,
1312 										  "gtk-close", 1,
1313 										  NULL);
1314 
1315     gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT);
1316     gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
1317 	gtk_widget_set_size_request (dialog, 650, 500);
1318 
1319 	content_area = dialog_get_content_area (dialog);
1320 	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1321     gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
1322 	utils_widget_set_padding (vbox, MARGIN_BOX, MARGIN_BOX);
1323 
1324 	/* get currency_popup */
1325 	popup = gsb_popup_list_iso_4217_new (NULL, NULL);
1326 	tree_view = g_object_get_data (G_OBJECT (popup), "tree_view" );
1327     gtk_box_pack_start (GTK_BOX (vbox), popup, TRUE, TRUE, MARGIN_BOX);
1328 
1329 	/* get currentcy_details */
1330 	details = GTK_WIDGET (widget_currency_details_new (page_currency, no_callback));
1331 	widget_currency_details_set_entry_editable (details, FALSE);
1332     gtk_box_pack_start (GTK_BOX (vbox), details, FALSE, FALSE, MARGIN_BOX);
1333 
1334 	/* set selection signal to update first currency */
1335 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
1336 	g_signal_connect (G_OBJECT (selection),
1337 					  "changed",
1338 					  G_CALLBACK (gsb_popup_list_selection_changed),
1339 					  details);
1340 
1341 	/* Select default currency. */
1342     gtk_tree_model_foreach (GTK_TREE_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view))),
1343 										   (GtkTreeModelForeachFunc) gsb_popup_list_select_default,
1344 										   tree_view);
1345 
1346 	gtk_widget_show_all (dialog);
1347     gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1348 
1349     result = gtk_dialog_run (GTK_DIALOG (dialog));
1350 
1351     if (result)
1352     {
1353 		currency_number = gsb_popup_list_selected_currency_new (selection);
1354 		if (currency_number)
1355 		{
1356 			/* update the currencies list in account properties */
1357 			gsb_currency_update_combobox_currency_list ();
1358 		}
1359     }
1360     gtk_widget_destroy (GTK_WIDGET (dialog));
1361 
1362 	return currency_number;
1363 }
1364 
1365 /**
1366  *
1367  *
1368  * \param
1369  *
1370  * \return
1371  **/
1372 /* Local Variables: */
1373 /* c-basic-offset: 4 */
1374 /* End: */
1375