1 /* ************************************************************************** */
2 /* */
3 /* copyright (c) 2000-2008 Cédric Auger (cedric@grisbi.org) */
4 /* 2004-2008 Benjamin Drieu (bdrieu@april.org) */
5 /* 2008-2020 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 data_partial_balance.c
26 */
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "include.h"
33 #include <gdk/gdkkeysyms.h>
34 #include <glib/gi18n.h>
35
36 /*START_INCLUDE*/
37 #include "gsb_data_partial_balance.h"
38 #include "dialog.h"
39 #include "grisbi_app.h"
40 #include "gsb_currency.h"
41 #include "gsb_data_account.h"
42 #include "gsb_data_currency.h"
43 #include "gsb_data_currency_link.h"
44 #include "gsb_data_transaction.h"
45 #include "navigation.h"
46 #include "gsb_real.h"
47 #include "gsb_rgba.h"
48 #include "utils_real.h"
49 #include "utils_str.h"
50 #include "utils.h"
51 #include "structures.h"
52 #include "utils_prefs.h"
53 #include "utils_widgets.h"
54 #include "erreur.h"
55 /*END_INCLUDE*/
56
57 /** \struct
58 * contenant les éléments d'un solde partiel
59 * */
60 typedef struct
61 {
62 gint partial_balance_number;
63 gchar *balance_name;
64 gchar *liste_cptes;
65 KindAccount kind;
66 gint currency;
67 gboolean colorise;
68 } struct_partial_balance;
69
70
71 /*START_STATIC*/
72 static void _gsb_data_partial_balance_free ( struct_partial_balance *partial_balance);
73 static gpointer gsb_data_partial_balance_get_structure ( gint partial_balance_number );
74 static gboolean gsb_data_partial_balance_init_from_liste_cptes ( gint partial_balance_number,
75 GtkWidget *parent );
76 static gboolean gsb_data_partial_balance_move ( gint orig_partial_number, gint dest_pos );
77 static GtkWidget *gsb_partial_balance_create_dialog ( gint action, gint spin_value );
78 static GtkWidget *gsb_partial_balance_create_list_accounts ( GtkWidget *entry );
79 static gint gsb_partial_balance_new ( const gchar *name );
80 static void gsb_partial_balance_renumerote ( void );
81 static gint gsb_partial_balance_request_currency ( GtkWidget *parent );
82 static gboolean gsb_partial_balance_select_account ( GtkTreeSelection *selection,
83 GtkTreeModel *model,
84 GtkTreePath *path,
85 gboolean path_currently_selected,
86 GObject *entry );
87 static void gsb_partial_balance_selectionne_cptes ( GtkWidget *tree_view,
88 const gchar *liste_cptes );
89 /*END_STATIC*/
90
91 /*START_EXTERN*/
92 /*END_EXTERN*/
93
94 /* devise de base des soldes partiels de comptes ayant des devises différentes */
95 gint no_devise_solde_partiels;
96
97 /** contains the g_slist of struct_partial_balance */
98 static GSList *partial_balance_list = NULL;
99
100 /** a pointer to the last partial_balance used (to increase the speed) */
101 static struct_partial_balance *partial_balance_buffer;
102
103 static GtkListStore *model_accueil;
104
105 /*********************************************************************************************/
106 /* Fonctions générales */
107 /*********************************************************************************************/
108 /**
109 * create a new partial_balance, give him a number, append it to the list
110 * and return the number
111 *
112 * \param name the name of the partial_balance (can be freed after, it's a copy) or NULL
113 *
114 * \return the number of the new partial_balance
115 * */
gsb_partial_balance_new(const gchar * name)116 gint gsb_partial_balance_new ( const gchar *name )
117 {
118 struct_partial_balance *partial_balance;
119
120 partial_balance = g_malloc0 ( sizeof ( struct_partial_balance ) );
121 if ( ! partial_balance )
122 {
123 dialogue_error_memory ( );
124 return 0;
125 }
126 partial_balance -> partial_balance_number = g_slist_length ( partial_balance_list ) + 1;
127
128 if ( name )
129 partial_balance -> balance_name = my_strdup ( name );
130 else
131 partial_balance -> balance_name = NULL;
132
133 partial_balance_list = g_slist_append ( partial_balance_list, partial_balance );
134
135 partial_balance_buffer = partial_balance;
136
137 return partial_balance -> partial_balance_number;
138 }
139
140
141 /**
142 * create a new partial balance and insert it at position "pos"
143 * and return the number
144 *
145 * \param name the name of the partial_balance (can be freed after, it's a copy) or NULL
146 * \param pos
147 *
148 * \return the number of the new partial_balance
149 * */
gsb_partial_balance_new_at_position(const gchar * name,gint pos)150 gint gsb_partial_balance_new_at_position ( const gchar *name, gint pos )
151 {
152 struct_partial_balance *partial_balance;
153
154 partial_balance = g_malloc0 ( sizeof ( struct_partial_balance ) );
155 if ( ! partial_balance )
156 {
157 dialogue_error_memory ( );
158 return 0;
159 }
160
161 if ( name )
162 partial_balance -> balance_name = my_strdup ( name );
163 else
164 partial_balance -> balance_name = NULL;
165
166 partial_balance_list = g_slist_insert ( partial_balance_list, partial_balance, pos - 1 );
167 gsb_partial_balance_renumerote ( );
168
169 partial_balance_buffer = partial_balance;
170
171 return partial_balance -> partial_balance_number;
172 }
173
174
175 /**
176 *
177 * \param
178 * \param
179 *
180 * */
gsb_partial_balance_create_model(void)181 GtkListStore *gsb_partial_balance_create_model ( void )
182 {
183
184 model_accueil = gtk_list_store_new (7, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
185 G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN, GDK_TYPE_RGBA);
186
187 return model_accueil;
188 }
189
190 /**
191 *
192 * \param
193 * \param
194 *
195 * */
gsb_partial_balance_fill_model(GtkListStore * list_store)196 void gsb_partial_balance_fill_model ( GtkListStore *list_store )
197 {
198 GSList *list_tmp;
199 GtkTreeIter iter;
200
201 list_tmp = partial_balance_list;
202 gtk_list_store_clear ( GTK_LIST_STORE (list_store) );
203
204 while ( list_tmp )
205 {
206 struct_partial_balance *partial_balance;
207 gchar *kind_str;
208 gchar *currency_str = (gchar*)"";
209
210 partial_balance = list_tmp -> data;
211
212 switch ( partial_balance -> kind )
213 {
214 case GSB_TYPE_BALANCE:
215 kind_str = g_strdup ( _("Additional balance") );
216 break;
217
218 case GSB_TYPE_CASH:
219 kind_str = g_strdup ( _("Cash account") );
220 break;
221
222 case GSB_TYPE_LIABILITIES:
223 kind_str = g_strdup ( _("Liabilities account") );
224 break;
225
226 case GSB_TYPE_ASSET:
227 kind_str = g_strdup ( _("Assets account") );
228 break;
229
230 case GSB_TYPE_BANK:
231 default:
232 kind_str = g_strdup ( _("Bank account") );
233 }
234 currency_str = gsb_data_currency_get_name ( partial_balance -> currency );
235
236 gtk_list_store_append (GTK_LIST_STORE (list_store), &iter);
237 gtk_list_store_set (GTK_LIST_STORE (list_store), &iter,
238 0, partial_balance -> balance_name,
239 1, partial_balance -> liste_cptes,
240 2, kind_str,
241 3, currency_str,
242 4, partial_balance -> partial_balance_number,
243 5, partial_balance -> colorise,
244 -1);
245 g_free (kind_str);
246
247 list_tmp = list_tmp -> next;
248 }
249 }
250
251
252 /**
253 * add a partial_balance
254 *
255 * */
gsb_partial_balance_add(GtkWidget * button,GtkWidget * main_widget)256 void gsb_partial_balance_add ( GtkWidget *button, GtkWidget *main_widget )
257 {
258 GtkWidget *dialog;
259 GtkWidget *entry_name;
260 GtkWidget *entry_list;
261 GtkWidget *spin_bouton;
262 GtkWidget *colorise_bouton;
263 gint action = 1; /* 1 create 2 modify */
264 gint result;
265
266 devel_debug ( NULL);
267
268 dialog = gsb_partial_balance_create_dialog ( action,
269 g_slist_length ( partial_balance_list ) + 1 );
270
271 entry_name = g_object_get_data ( G_OBJECT ( dialog ), "entry_name" );
272 entry_list = g_object_get_data ( G_OBJECT ( dialog ), "entry_list" );
273 spin_bouton = g_object_get_data ( G_OBJECT ( dialog ), "spin_bouton" );
274 colorise_bouton = g_object_get_data ( G_OBJECT ( dialog ), "colorise_bouton" );
275
276 gtk_widget_show_all ( GTK_WIDGET ( dialog ) );
277
278 dialog_return:
279 result = gtk_dialog_run ( GTK_DIALOG ( dialog ) );
280
281 if ( result == 1)
282 {
283 GtkTreeView *treeview;
284 GtkTreeModel *model;
285 const gchar *name, *liste_cptes;
286 gint partial_balance_number;
287 gint position;
288
289 name = gtk_entry_get_text ( GTK_ENTRY ( entry_name ) );
290 liste_cptes = gtk_entry_get_text ( GTK_ENTRY ( entry_list ) );
291
292 if ( strlen ( name ) && strlen ( liste_cptes )
293 &&
294 g_utf8_strchr ( liste_cptes, -1, ';' ) )
295 {
296 position = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON ( spin_bouton ) );
297 if ( position > (gint) g_slist_length ( partial_balance_list ) )
298 partial_balance_number = gsb_partial_balance_new ( name );
299 else
300 partial_balance_number = gsb_partial_balance_new_at_position (
301 name, position );
302
303 gsb_data_partial_balance_set_liste_cptes ( partial_balance_number,
304 liste_cptes );
305 gsb_data_partial_balance_init_from_liste_cptes ( partial_balance_number,
306 dialog );
307 gsb_data_partial_balance_set_colorise ( partial_balance_number,
308 gtk_toggle_button_get_active (
309 GTK_TOGGLE_BUTTON ( colorise_bouton ) ) );
310
311 /* on met à jour le model */
312 treeview = g_object_get_data ( G_OBJECT (main_widget), "treeview" );
313 model = gtk_tree_view_get_model ( treeview );
314 gsb_partial_balance_fill_model ( GTK_LIST_STORE ( model ) );
315
316 /* MAJ HOME_PAGE */
317 gsb_gui_navigation_update_home_page ( );
318 }
319 else if ( g_utf8_strchr ( liste_cptes, -1, ';' ) == NULL )
320 {
321 dialogue_warning_hint ( _("You must select at least two accounts."),
322 _("Only one account is selected.") );
323 goto dialog_return;
324 }
325 else
326 {
327 dialogue_warning_hint ( _("The name of the partial balance "
328 "and the list of accounts must be completed."),
329 _("All fields are not filled in") );
330 goto dialog_return;
331 }
332 }
333 gtk_widget_destroy ( GTK_WIDGET ( dialog ) );
334 }
335
336
337 /**
338 * Edit a partial_balance
339 *
340 * */
gsb_partial_balance_edit(GtkWidget * button,GtkWidget * main_widget)341 void gsb_partial_balance_edit ( GtkWidget *button, GtkWidget *main_widget )
342 {
343 GtkWidget *dialog;
344 GtkWidget *entry_name;
345 GtkWidget *entry_list;
346 GtkWidget *spin_bouton;
347 GtkWidget *colorise_bouton;
348 GtkWidget *account_list;
349 GtkWidget *treeview;
350 GtkWidget *account_treeview;
351 GtkTreeSelection *selection;
352 GtkTreeModel *model;
353 GtkTreeIter iter;
354 gchar *balance_name;
355 gchar *liste_cptes;
356 gint partial_balance_number;
357 gint action = 2; /* 1 create 2 modify */
358 gint result;
359
360 devel_debug ( NULL);
361
362 dialog = gsb_partial_balance_create_dialog ( action,
363 g_slist_length ( partial_balance_list ) + 1 );
364
365 entry_name = g_object_get_data ( G_OBJECT ( dialog ), "entry_name" );
366 entry_list = g_object_get_data ( G_OBJECT ( dialog ), "entry_list" );
367 account_list = g_object_get_data ( G_OBJECT ( dialog ), "account_list" );
368 spin_bouton = g_object_get_data ( G_OBJECT ( dialog ), "spin_bouton" );
369 colorise_bouton = g_object_get_data ( G_OBJECT ( dialog ), "colorise_bouton" );
370
371 gtk_widget_show_all ( GTK_WIDGET ( dialog ) );
372
373 /* initialisation des données */
374 treeview = g_object_get_data ( G_OBJECT ( main_widget ), "treeview" );
375 selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW (treeview) );
376 if ( !gtk_tree_selection_get_selected ( selection, &model, &iter) )
377 return ;
378
379 gtk_tree_model_get ( model, &iter,
380 0, &balance_name,
381 1, &liste_cptes,
382 4, &partial_balance_number,
383 -1);
384
385 gtk_entry_set_text ( GTK_ENTRY ( entry_name ), balance_name );
386 gtk_entry_set_text ( GTK_ENTRY ( entry_list ), liste_cptes );
387 gtk_spin_button_set_value ( GTK_SPIN_BUTTON ( spin_bouton ),
388 (gdouble) partial_balance_number );
389 gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( colorise_bouton ),
390 gsb_data_partial_balance_get_colorise (
391 partial_balance_number ) );
392 account_treeview = g_object_get_data ( G_OBJECT ( account_list ), "account_treeview");
393 gsb_partial_balance_selectionne_cptes ( account_treeview, liste_cptes );
394
395 gtk_widget_show_all ( GTK_WIDGET ( dialog ) );
396
397 dialog_return:
398 result = gtk_dialog_run ( GTK_DIALOG ( dialog ));
399
400 if ( result == 1)
401 {
402 const gchar *name, *new_liste_cptes;
403 gint position;
404
405 name = gtk_entry_get_text ( GTK_ENTRY ( entry_name ) );
406 new_liste_cptes = gtk_entry_get_text ( GTK_ENTRY ( entry_list ) );
407
408 if ( strlen ( name ) && strlen (new_liste_cptes) &&
409 g_utf8_strchr (new_liste_cptes, -1, ';' ) )
410 {
411 gsb_data_partial_balance_set_name ( partial_balance_number, name );
412 gsb_data_partial_balance_set_liste_cptes ( partial_balance_number, new_liste_cptes);
413 gsb_data_partial_balance_init_from_liste_cptes ( partial_balance_number,
414 dialog );
415 gsb_data_partial_balance_set_colorise ( partial_balance_number,
416 gtk_toggle_button_get_active (
417 GTK_TOGGLE_BUTTON ( colorise_bouton ) ) );
418
419 position = gtk_spin_button_get_value_as_int ( GTK_SPIN_BUTTON ( spin_bouton ) );
420 if ( position != partial_balance_number )
421 gsb_data_partial_balance_move ( partial_balance_number, position );
422
423 /* on met à jour le model */
424 gsb_partial_balance_fill_model ( GTK_LIST_STORE ( model ) );
425
426 /* MAJ HOME_PAGE */
427 gsb_gui_navigation_update_home_page ( );
428 }
429 else if ( g_utf8_strchr (new_liste_cptes, -1, ';' ) == NULL )
430 {
431 dialogue_warning_hint ( _("You must select at least two accounts."),
432 _("Only one account is selected.") );
433 goto dialog_return;
434 }
435 else
436 {
437 dialogue_warning_hint ( _("The name of the partial balance "
438 "and the list of accounts must be completed."),
439 _("All fields are not filled in") );
440 goto dialog_return;
441 }
442 }
443 gtk_widget_destroy ( GTK_WIDGET ( dialog ) );
444 }
445
446
447 /**
448 * remove a partial_balance
449 *
450 * */
gsb_partial_balance_remove(GtkWidget * button,GtkWidget * main_widget)451 void gsb_partial_balance_remove ( GtkWidget *button, GtkWidget *main_widget )
452 {
453 GtkTreeView *treeview;
454 GtkTreeModel *model;
455 GtkTreeIter iter;
456 GSList *list_tmp;
457 gint partial_balance_number;
458
459 treeview = g_object_get_data ( G_OBJECT (main_widget), "treeview" );
460 if ( !gtk_tree_selection_get_selected (
461 gtk_tree_view_get_selection (treeview),
462 &model,
463 &iter ))
464 return;
465
466 gtk_tree_model_get ( model, &iter, 4, &partial_balance_number, -1 );
467
468 if ( partial_balance_number > 0 )
469 {
470 list_tmp = partial_balance_list;
471 while ( list_tmp )
472 {
473 struct_partial_balance *partial_balance;
474
475 partial_balance = list_tmp -> data;
476
477 if ( partial_balance -> partial_balance_number == partial_balance_number )
478 {
479 GtkWidget *edit_button;
480
481 partial_balance_list = g_slist_remove (
482 partial_balance_list, partial_balance );
483 gsb_partial_balance_renumerote ( );
484 gtk_list_store_remove ( GTK_LIST_STORE ( model ), &iter );
485
486 /* MAJ HOME_PAGE */
487 gsb_gui_navigation_update_home_page ( );
488
489 edit_button = g_object_get_data ( G_OBJECT (main_widget), "edit_button" );
490 gtk_widget_set_sensitive ( edit_button, FALSE );
491 gtk_widget_set_sensitive ( button, FALSE );
492 break;
493 }
494 list_tmp = list_tmp -> next;
495 }
496 }
497 }
498
499
500 /**
501 * renumerote la liste des soldes partiels
502 *
503 * */
gsb_partial_balance_renumerote(void)504 void gsb_partial_balance_renumerote ( void )
505 {
506 GSList *list_tmp;
507 gint i = 1;
508
509 list_tmp = partial_balance_list;
510 while ( list_tmp )
511 {
512 struct_partial_balance *partial_balance;
513
514 partial_balance = list_tmp -> data;
515 partial_balance -> partial_balance_number = i;
516 i++;
517 list_tmp = list_tmp -> next;
518 }
519 }
520
521
522 /**
523 * Fonction appellée quand on sélectionne un solde partiel
524 *
525 * */
gsb_partial_balance_select_func(GtkTreeSelection * selection,GtkTreeModel * model,GtkTreePath * path,gboolean path_currently_selected,GObject * main_widget)526 gboolean gsb_partial_balance_select_func ( GtkTreeSelection *selection,
527 GtkTreeModel *model,
528 GtkTreePath *path,
529 gboolean path_currently_selected,
530 GObject *main_widget )
531 {
532 GtkWidget *button;
533
534 button = g_object_get_data ( G_OBJECT (main_widget), "edit_button" );
535 gtk_widget_set_sensitive ( button, TRUE );
536 button = g_object_get_data ( G_OBJECT (main_widget), "remove_button" );
537 gtk_widget_set_sensitive ( button, TRUE );
538
539 return TRUE;
540 }
541
542
543 /**
544 * sélectionne les comptes donnés en paramètre
545 *
546 * */
gsb_partial_balance_selectionne_cptes(GtkWidget * tree_view,const gchar * liste_cptes)547 void gsb_partial_balance_selectionne_cptes ( GtkWidget *tree_view,
548 const gchar *liste_cptes )
549 {
550 GtkTreeModel *model;
551 GtkTreeIter iter;
552 GtkTreeSelection *selection;
553 gchar **tab;
554 gint i;
555 gint num_cpte;
556 gboolean valid;
557
558 model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( tree_view ) );
559 selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( tree_view ) );
560
561 if ( liste_cptes == NULL || strlen ( liste_cptes ) == 0 )
562 return;
563
564 tab = g_strsplit ( liste_cptes, ";", 0 );
565 for ( i = 0; tab[i]; i++ )
566 {
567 num_cpte = utils_str_atoi ( tab[i] );
568
569 valid = gtk_tree_model_get_iter_first ( model, &iter);
570 while ( valid )
571 {
572 gint account_nb;
573
574 gtk_tree_model_get ( model, &iter, 1, &account_nb, -1 );
575 if ( account_nb == num_cpte )
576 gtk_tree_selection_select_iter ( selection, &iter);
577
578 valid = gtk_tree_model_iter_next ( model, &iter );
579 }
580 }
581 g_strfreev ( tab );
582 }
583
584
585 /**
586 * gère le clavier sur la liste des soldes partiels
587 *
588 **/
gsb_partial_balance_key_press(GtkWidget * tree_view,GdkEventKey * ev)589 gboolean gsb_partial_balance_key_press ( GtkWidget *tree_view, GdkEventKey *ev )
590 {
591 switch ( ev -> keyval )
592 {
593 case GDK_KEY_Return : /* entrée */
594 case GDK_KEY_KP_Enter :
595 case GDK_KEY_Tab :
596 g_object_set_data ( G_OBJECT ( tree_view ), "treeview", tree_view );
597 gsb_partial_balance_edit ( NULL, tree_view );
598 return TRUE;
599 break;
600 case GDK_KEY_Delete: /* del */
601 g_object_set_data ( G_OBJECT ( tree_view ), "treeview", tree_view );
602 gsb_partial_balance_remove ( NULL, tree_view );
603 return TRUE;
604 break;
605 }
606
607 return FALSE;
608 }
609
610
611 /**
612 * called when press a mouse button on the partial_balance_list
613 *
614 * \param tree_view
615 * \param ev a GdkEventButton
616 *
617 * \return TRUE if double - click else FALSE
618 * */
gsb_partial_balance_button_press(GtkWidget * tree_view,GdkEventButton * ev,gpointer null)619 gboolean gsb_partial_balance_button_press ( GtkWidget *tree_view,
620 GdkEventButton *ev,
621 gpointer null )
622 {
623 /* if we are not in the list, go away */
624 if ( ev -> window != gtk_tree_view_get_bin_window ( GTK_TREE_VIEW ( tree_view ) ) )
625 return FALSE;
626
627 /* if double - click */
628 if ( ev -> type == GDK_2BUTTON_PRESS )
629 {
630 g_object_set_data ( G_OBJECT ( tree_view ), "treeview", tree_view );
631 gsb_partial_balance_edit ( NULL, tree_view );
632 return TRUE;
633 }
634
635 return FALSE;
636 }
637
638
639 /**
640 *
641 *
642 **/
gsb_partial_balance_colorise_toggled(GtkCellRendererToggle * cell,gchar * path_str,GtkWidget * tree_view)643 void gsb_partial_balance_colorise_toggled ( GtkCellRendererToggle *cell,
644 gchar *path_str,
645 GtkWidget *tree_view )
646 {
647 GtkTreePath * treepath;
648 GtkTreeIter iter;
649 gboolean toggle;
650 gint partial_number;
651 GtkTreeModel *model;
652
653 devel_debug (NULL);
654
655 model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( tree_view ) );
656
657 /* invert the toggle */
658 treepath = gtk_tree_path_new_from_string ( path_str );
659 gtk_tree_model_get_iter ( GTK_TREE_MODEL (model), &iter, treepath );
660
661 gtk_tree_model_get ( GTK_TREE_MODEL ( model ), &iter,
662 4, &partial_number,
663 5, &toggle,
664 -1);
665 toggle ^= 1;
666 gtk_list_store_set (GTK_LIST_STORE ( model ), &iter, 5, toggle, -1);
667
668 /* and save it */
669 gsb_data_partial_balance_set_colorise ( partial_number, toggle );
670
671 /* MAJ HOME_PAGE */
672 gsb_gui_navigation_update_home_page ( );
673 }
674
675
676 /*********************************************************************************************/
677 /* Données */
678 /*********************************************************************************************/
679 /**
680 * set the partial_balance global variables to NULL,
681 * usually when we init all the global variables
682 *
683 * \param
684 *
685 * \return FALSE
686 * */
gsb_data_partial_balance_init_variables(void)687 gboolean gsb_data_partial_balance_init_variables ( void )
688 {
689 if ( partial_balance_list )
690 {
691 GSList* tmp_list = partial_balance_list;
692 while ( tmp_list )
693 {
694 struct_partial_balance *partial_balance;
695
696 partial_balance = tmp_list -> data;
697 tmp_list = tmp_list -> next;
698 _gsb_data_partial_balance_free ( partial_balance );
699 }
700 g_slist_free ( partial_balance_list );
701 }
702 partial_balance_list = NULL;
703 partial_balance_buffer = NULL;
704
705 return FALSE;
706 }
707
708
709 /**
710 * find and return the structure of the partial_balance asked
711 *
712 * \param partial_balance_number number of partial_balance
713 *
714 * \return the adr of the struct of the partial_balance (NULL if doesn't exit)
715 * */
gsb_data_partial_balance_get_structure(gint partial_balance_number)716 gpointer gsb_data_partial_balance_get_structure ( gint partial_balance_number )
717 {
718 GSList *tmp;
719
720 if ( !partial_balance_number )
721 return NULL;
722
723 /* before checking all the import rule, we check the buffer */
724 if ( partial_balance_buffer
725 &&
726 partial_balance_buffer -> partial_balance_number == partial_balance_number )
727 return partial_balance_buffer;
728
729 tmp = partial_balance_list;
730
731 while ( tmp )
732 {
733 struct_partial_balance *partial_balance;
734
735 partial_balance = tmp -> data;
736
737 if ( partial_balance -> partial_balance_number == partial_balance_number )
738 {
739 partial_balance_buffer = partial_balance;
740 return partial_balance;
741 }
742
743 tmp = tmp -> next;
744 }
745 return NULL;
746 }
747
748
749 /**
750 * give the g_slist of partial_balance structure
751 * usefull when want to check all partial_balance
752 * carrefull : it's not a copy, so we must not free or change it
753 *
754 * \param none
755 *
756 * \return the g_slist of partial_balance structure
757 * */
gsb_data_partial_balance_get_list(void)758 GSList *gsb_data_partial_balance_get_list ( void )
759 {
760 return partial_balance_list;
761 }
762
763
764 /**
765 * return the number of the partial_balance given in param
766 *
767 * \param balance_ptr a pointer to the struct of the partial_balance
768 *
769 * \return the number of the partial_balance, 0 if problem
770 * */
gsb_data_partial_balance_get_number(gpointer balance_ptr)771 gint gsb_data_partial_balance_get_number ( gpointer balance_ptr )
772 {
773 struct_partial_balance *partial_balance;
774
775 if ( !balance_ptr )
776 return 0;
777
778 partial_balance = balance_ptr;
779 partial_balance_buffer = partial_balance;
780 return partial_balance -> partial_balance_number;
781 }
782
783
784 /**
785 * This internal function is called to free the memory used by an
786 * struct_partial_balance structure
787 */
_gsb_data_partial_balance_free(struct_partial_balance * partial_balance)788 static void _gsb_data_partial_balance_free ( struct_partial_balance *partial_balance)
789 {
790 if ( ! partial_balance )
791 return;
792 if ( partial_balance -> balance_name
793 &&
794 strlen ( partial_balance -> balance_name ) )
795 g_free ( partial_balance -> balance_name );
796 if ( partial_balance -> liste_cptes
797 &&
798 strlen ( partial_balance -> liste_cptes ) )
799 g_free ( partial_balance -> liste_cptes );
800
801 g_free ( partial_balance );
802
803 if ( partial_balance_buffer == partial_balance )
804 partial_balance_buffer = NULL;
805 }
806
807
808 /**
809 * return the liste_cptes of the partial_balance
810 *
811 * \param partial_balance_number the number of the partial_balance
812 *
813 * \return the liste_cptes of the partial_balance or NULL if fail
814 * */
gsb_data_partial_balance_get_liste_cptes(gint partial_balance_number)815 const gchar *gsb_data_partial_balance_get_liste_cptes ( gint partial_balance_number )
816 {
817 struct_partial_balance *partial_balance;
818
819 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
820
821 if ( !partial_balance )
822 return NULL;
823
824 return partial_balance -> liste_cptes;
825 }
826
827
828 /**
829 * set the liste_cptes of the partial_balance
830 * the value is dupplicate in memory
831 *
832 * \param partial_balance_number the number of the partial_balance
833 * \param liste_cptes of the partial_balance
834 *
835 * \return TRUE if ok or FALSE if problem
836 * */
gsb_data_partial_balance_set_liste_cptes(gint partial_balance_number,const gchar * liste_cptes)837 gboolean gsb_data_partial_balance_set_liste_cptes ( gint partial_balance_number,
838 const gchar *liste_cptes )
839 {
840 struct_partial_balance *partial_balance;
841
842 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
843
844 if ( !partial_balance )
845 return FALSE;
846
847 /* we free the last name */
848 if ( partial_balance -> liste_cptes )
849 g_free (partial_balance -> liste_cptes);
850
851 /* and copy the new one */
852 partial_balance -> liste_cptes = my_strdup ( liste_cptes );
853
854 return TRUE;
855 }
856
857
858 /**
859 * return the name of the partial_balance
860 *
861 * \param partial_balance_number the number of the partial_balance
862 *
863 * \return the name of the partial_balance or NULL if fail
864 * */
gsb_data_partial_balance_get_name(gint partial_balance_number)865 const gchar *gsb_data_partial_balance_get_name ( gint partial_balance_number )
866 {
867 struct_partial_balance *partial_balance;
868
869 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
870
871 if ( !partial_balance )
872 return NULL;
873
874 return partial_balance -> balance_name;
875 }
876
877
878 /**
879 * set the name of the import_rule
880 * the value is dupplicate in memory
881 *
882 * \param import_rule_number the number of the import_rule
883 * \param name the name of the import_rule
884 *
885 * \return TRUE if ok or FALSE if problem
886 * */
gsb_data_partial_balance_set_name(gint partial_balance_number,const gchar * name)887 gboolean gsb_data_partial_balance_set_name ( gint partial_balance_number,
888 const gchar *name )
889 {
890 struct_partial_balance *partial_balance;
891
892 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
893
894 if ( !partial_balance )
895 return FALSE;
896
897 /* we free the last name */
898 if ( partial_balance -> balance_name )
899 g_free (partial_balance -> balance_name);
900
901 /* and copy the new one */
902 partial_balance -> balance_name = my_strdup ( name );
903
904 return TRUE;
905 }
906
907
908 /**
909 * get the kind of the partial_balance
910 * \param partial_balance_number no of the partial_balance
911 *
912 * \return partial_balance type or 0 if the partial_balance doesn't exist
913 * */
gsb_data_partial_balance_get_kind(gint partial_balance_number)914 KindAccount gsb_data_partial_balance_get_kind ( gint partial_balance_number )
915 {
916 struct_partial_balance *partial_balance;
917
918 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
919
920 if ( !partial_balance )
921 return 0;
922
923 return partial_balance -> kind;
924 }
925
926
927 /**
928 * set the kind of the partial_balance
929 * \param partial_balance_number no of the partial_balance
930 * \param kind type to set
931 *
932 * \return TRUE, ok ; FALSE, problem
933 * */
gsb_data_partial_balance_set_kind(gint partial_balance_number,KindAccount kind)934 gboolean gsb_data_partial_balance_set_kind ( gint partial_balance_number,
935 KindAccount kind )
936 {
937 struct_partial_balance *partial_balance;
938
939 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
940
941 if ( !partial_balance )
942 return FALSE;
943
944 partial_balance -> kind = kind;
945
946 return TRUE;
947 }
948
949
950 /**
951 * get the currency of the partial_balance
952 *
953 * \param partial_balance_number no of the partial_balance
954 *
955 * \return partial_balance currency or 0 if the partial_balance doesn't exist
956 * */
gsb_data_partial_balance_get_currency(gint partial_balance_number)957 gint gsb_data_partial_balance_get_currency ( gint partial_balance_number )
958 {
959 struct_partial_balance *partial_balance;
960
961 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
962
963 if ( !partial_balance )
964 return 0;
965
966 return partial_balance -> currency;
967 }
968
969
970 /**
971 * set the currency of the partial_balance
972 *
973 * \param partial_balance_number no of the partial_balance
974 * \param currency to set
975 *
976 * \return TRUE, ok ; FALSE, problem
977 * */
gsb_data_partial_balance_set_currency(gint partial_balance_number,gint currency)978 gboolean gsb_data_partial_balance_set_currency ( gint partial_balance_number,
979 gint currency )
980 {
981 struct_partial_balance *partial_balance;
982
983 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
984
985 if ( !partial_balance )
986 return FALSE;
987
988 partial_balance -> currency = currency;
989
990 return TRUE;
991 }
992
993
994 /**
995 *
996 *
997 * \param partial_balance_number no of the partial_balance
998 *
999 * \return
1000 * */
gsb_data_partial_balance_get_colorise(gint partial_balance_number)1001 gboolean gsb_data_partial_balance_get_colorise ( gint partial_balance_number )
1002 {
1003 struct_partial_balance *partial_balance;
1004
1005 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1006
1007 if ( !partial_balance )
1008 return 0;
1009
1010 return partial_balance -> colorise;
1011 }
1012
1013
1014 /**
1015 * \param partial_balance_number no of the partial_balance
1016 * \param colorise
1017 *
1018 * \return TRUE, ok ; FALSE, problem
1019 * */
gsb_data_partial_balance_set_colorise(gint partial_balance_number,gboolean colorise)1020 gboolean gsb_data_partial_balance_set_colorise ( gint partial_balance_number,
1021 gboolean colorise )
1022 {
1023 struct_partial_balance *partial_balance;
1024
1025 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1026
1027 if ( !partial_balance )
1028 return FALSE;
1029
1030 partial_balance -> colorise = colorise;
1031
1032 return TRUE;
1033 }
1034
1035
1036 /**
1037 *
1038 *
1039 * */
gsb_data_partial_balance_get_marked_balance(gint partial_balance_number)1040 gchar *gsb_data_partial_balance_get_marked_balance ( gint partial_balance_number )
1041 {
1042 struct_partial_balance *partial_balance;
1043 GsbReal solde = null_real;
1044 gchar **tab;
1045 gchar *string;
1046 gint i;
1047
1048 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1049
1050 if ( !partial_balance )
1051 return NULL;
1052
1053 if ( partial_balance -> liste_cptes == NULL ||
1054 strlen ( partial_balance -> liste_cptes ) == 0 )
1055 return NULL;
1056
1057 tab = g_strsplit ( partial_balance -> liste_cptes, ";", 0 );
1058 for ( i = 0; tab[i]; i++ )
1059 {
1060 GsbReal tmp_real;
1061 gint account_nb;
1062 gint account_currency;
1063 gint link_number;
1064
1065 account_nb = utils_str_atoi ( tab[i] );
1066 account_currency = gsb_data_account_get_currency ( account_nb );
1067 tmp_real = gsb_data_account_get_marked_balance ( account_nb );
1068
1069 if ( tmp_real.mantissa != 0 && partial_balance -> currency != account_currency )
1070 {
1071 if ( ( link_number = gsb_data_currency_link_search ( account_currency,
1072 partial_balance -> currency ) ) )
1073 {
1074 if ( gsb_data_currency_link_get_first_currency (
1075 link_number) == account_currency )
1076 tmp_real = gsb_real_mul ( tmp_real,
1077 gsb_data_currency_link_get_change_rate ( link_number ) );
1078 else
1079 tmp_real = gsb_real_div ( tmp_real,
1080 gsb_data_currency_link_get_change_rate ( link_number ) );
1081 }
1082
1083 }
1084 solde = gsb_real_add ( solde, tmp_real );
1085 }
1086 g_strfreev ( tab );
1087
1088 if (partial_balance->colorise)
1089 {
1090 gchar *color;
1091 gchar *tmp_str;
1092
1093 if (solde.mantissa < 0)
1094 color = g_strdup ("red");
1095 else
1096 {
1097 gchar *str_to_free;
1098
1099 str_to_free = gsb_rgba_get_couleur_to_hexa_string ("text_gsetting_option_normal");
1100 color = g_strdup (str_to_free);
1101 g_free (str_to_free);
1102 }
1103
1104 tmp_str = utils_real_get_string_with_currency (solde, partial_balance -> currency, TRUE);
1105 string = g_strdup_printf ("<span color=\"%s\">%s</span>", color, tmp_str);
1106 g_free ( color );
1107 g_free (tmp_str);
1108 }
1109 else
1110 string = utils_real_get_string_with_currency (
1111 solde, partial_balance -> currency, TRUE );
1112
1113 return string;
1114 }
1115
1116
1117 /**
1118 *
1119 *
1120 * */
gsb_data_partial_balance_get_current_amount(gint partial_balance_number)1121 GsbReal gsb_data_partial_balance_get_current_amount ( gint partial_balance_number )
1122 {
1123 struct_partial_balance *partial_balance;
1124 GsbReal solde = null_real;
1125 gchar **tab;
1126 gint i;
1127
1128 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1129
1130 if ( !partial_balance )
1131 return null_real;
1132
1133 if ( partial_balance -> liste_cptes == NULL ||
1134 strlen ( partial_balance -> liste_cptes ) == 0 )
1135 return null_real;
1136
1137 tab = g_strsplit ( partial_balance -> liste_cptes, ";", 0 );
1138 for ( i = 0; tab[i]; i++ )
1139 {
1140 GsbReal tmp_real;
1141 gint account_nb;
1142 gint account_currency;
1143 gint link_number;
1144
1145 account_nb = utils_str_atoi ( tab[i] );
1146 account_currency = gsb_data_account_get_currency ( account_nb );
1147 tmp_real = gsb_data_account_get_current_balance ( account_nb );
1148
1149 if ( tmp_real.mantissa != 0 && partial_balance -> currency != account_currency )
1150 {
1151 if ( ( link_number = gsb_data_currency_link_search ( account_currency,
1152 partial_balance -> currency ) ) )
1153 {
1154 if ( gsb_data_currency_link_get_first_currency (
1155 link_number) == account_currency )
1156 tmp_real = gsb_real_mul ( tmp_real,
1157 gsb_data_currency_link_get_change_rate ( link_number ) );
1158 else
1159 tmp_real = gsb_real_div ( tmp_real,
1160 gsb_data_currency_link_get_change_rate ( link_number ) );
1161 }
1162 }
1163 solde = gsb_real_add ( solde, tmp_real );
1164 }
1165 g_strfreev ( tab );
1166
1167 return solde;
1168 }
1169
1170
1171 /**
1172 *
1173 *
1174 * */
gsb_data_partial_balance_get_current_balance(gint partial_balance_number)1175 gchar *gsb_data_partial_balance_get_current_balance ( gint partial_balance_number )
1176 {
1177 struct_partial_balance *partial_balance;
1178 GsbReal solde = null_real;
1179 gchar *string;
1180
1181 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1182
1183 if ( !partial_balance )
1184 return NULL;
1185
1186 solde = gsb_data_partial_balance_get_current_amount ( partial_balance_number );
1187
1188 if (partial_balance->colorise)
1189 {
1190 gchar *color;
1191 gchar *tmp_str;
1192
1193 if (solde.mantissa < 0)
1194 color = g_strdup ("red");
1195 else
1196 {
1197 gchar *str_to_free;
1198
1199 str_to_free = gsb_rgba_get_couleur_to_hexa_string ("text_gsetting_option_normal");
1200 color = g_strdup (str_to_free);
1201 g_free (str_to_free);
1202 }
1203
1204 tmp_str = utils_real_get_string_with_currency (solde, partial_balance -> currency, TRUE);
1205 string = g_strdup_printf ( "<span color=\"%s\">%s</span>", color, tmp_str);
1206 g_free ( color );
1207 g_free (tmp_str);
1208 }
1209 else
1210 string = utils_real_get_string_with_currency (
1211 solde, partial_balance -> currency, TRUE );
1212
1213 return string;
1214 }
1215
1216
1217 /**
1218 *
1219 *
1220 * */
gsb_partial_balance_select_account(GtkTreeSelection * selection,GtkTreeModel * model,GtkTreePath * path,gboolean path_currently_selected,GObject * entry)1221 gboolean gsb_partial_balance_select_account ( GtkTreeSelection *selection,
1222 GtkTreeModel *model,
1223 GtkTreePath *path,
1224 gboolean path_currently_selected,
1225 GObject *entry )
1226 {
1227 GList *list;
1228
1229 if ( strlen ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ) > 0 )
1230 gtk_entry_set_text ( GTK_ENTRY ( entry ), "" );
1231
1232 list = gtk_tree_selection_get_selected_rows ( selection, NULL );
1233
1234 if ( path_currently_selected )
1235 {
1236 while ( list )
1237 {
1238 GtkTreeIter iter;
1239 gint account_nb;
1240
1241 if ( gtk_tree_path_compare ( path, list -> data ) != 0 )
1242 {
1243 gtk_tree_model_get_iter ( model, &iter, list -> data );
1244 gtk_tree_model_get ( model, &iter, 1, &account_nb, -1);
1245 if ( strlen ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ) > 0 )
1246 {
1247 gtk_entry_set_text ( GTK_ENTRY ( entry ),
1248 g_strconcat ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ), ";",
1249 g_strdup_printf ( "%d", account_nb ), NULL ) );
1250 }
1251 else
1252 gtk_entry_set_text ( GTK_ENTRY ( entry ), g_strdup_printf ( "%d", account_nb ) );
1253 }
1254 list = list -> next;
1255 }
1256 }
1257 else
1258 {
1259 list = g_list_append ( list, gtk_tree_path_copy ( path ) );
1260
1261 while ( list )
1262 {
1263 GtkTreeIter iter;
1264 gint account_nb;
1265
1266 gtk_tree_model_get_iter ( model, &iter, list -> data );
1267 gtk_tree_model_get ( model, &iter, 1, &account_nb, -1);
1268 if ( strlen ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ) > 0 )
1269 {
1270 gtk_entry_set_text ( GTK_ENTRY ( entry ),
1271 g_strconcat ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ), ";",
1272 g_strdup_printf ( "%d", account_nb ), NULL ) );
1273 }
1274 else
1275 gtk_entry_set_text ( GTK_ENTRY ( entry ), g_strdup_printf ( "%d", account_nb ) );
1276
1277 list = list -> next;
1278 }
1279 }
1280
1281 g_list_free_full ( list, ( GDestroyNotify ) gtk_tree_path_free );
1282
1283 return TRUE;
1284 }
1285
1286
1287 /**
1288 * Détermine la devise et le type de compte pour le solde partiel
1289 *
1290 * \param partial_balance_number
1291 *
1292 * \return FALSE si tous les comptes n'ont pas les mêmes données sinon TRUE
1293 * */
gsb_data_partial_balance_init_from_liste_cptes(gint partial_balance_number,GtkWidget * parent)1294 gboolean gsb_data_partial_balance_init_from_liste_cptes ( gint partial_balance_number,
1295 GtkWidget *parent )
1296 {
1297 struct_partial_balance *partial_balance;
1298 gchar **tab;
1299 gint i;
1300 gint account_nb;
1301 gint currency_nb = 0;
1302 KindAccount kind = -1;
1303 KindAccount kind_nb = -1;
1304 gchar *tmp_str;
1305 gboolean return_val = TRUE;
1306 gboolean currency_mixte = FALSE;
1307
1308 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1309
1310 if ( !partial_balance )
1311 return FALSE;
1312
1313 if ( partial_balance -> liste_cptes == NULL ||
1314 strlen ( partial_balance -> liste_cptes ) == 0 )
1315 return FALSE;
1316
1317 tab = g_strsplit ( partial_balance -> liste_cptes, ";", 0 );
1318 for ( i = 0; tab[i]; i++ )
1319 {
1320 gint account_currency;
1321
1322 account_nb = utils_str_atoi ( tab[i] );
1323 account_currency = gsb_data_account_get_currency ( account_nb );
1324 if ( currency_nb == 0 )
1325 currency_nb = account_currency;
1326 else if ( currency_nb != account_currency )
1327 {
1328 if ( currency_mixte == FALSE )
1329 {
1330 no_devise_solde_partiels = gsb_partial_balance_request_currency ( parent );
1331 if ( gsb_data_currency_link_search ( currency_nb, account_currency ) == 0 )
1332 {
1333 tmp_str = g_strdup_printf (
1334 _("You need to create a link between currency %s and %s."),
1335 gsb_data_currency_get_name ( currency_nb ),
1336 gsb_data_currency_get_name ( account_currency ) );
1337 dialogue_warning_hint ( tmp_str,
1338 _("Attention missing link between currencies") );
1339 }
1340 }
1341 currency_mixte = TRUE;
1342 return_val = FALSE;
1343 }
1344 if ( kind == -1 )
1345 kind = gsb_data_account_get_kind ( account_nb );
1346 else if ( ( kind_nb = gsb_data_account_get_kind ( account_nb ) ) != kind )
1347 {
1348 switch ( kind )
1349 {
1350 case GSB_TYPE_BALANCE:
1351 break;
1352
1353 case GSB_TYPE_BANK:
1354 case GSB_TYPE_CASH:
1355 if ( kind_nb >= GSB_TYPE_LIABILITIES )
1356 return_val = FALSE;
1357 break;
1358
1359 case GSB_TYPE_LIABILITIES:
1360 return_val = FALSE;
1361 break;
1362
1363 case GSB_TYPE_ASSET:
1364 return_val = FALSE;
1365 break;
1366 }
1367 }
1368 }
1369 g_strfreev ( tab );
1370
1371 if ( currency_mixte )
1372 gsb_data_partial_balance_set_currency ( partial_balance_number,
1373 no_devise_solde_partiels );
1374 else
1375 gsb_data_partial_balance_set_currency ( partial_balance_number, currency_nb );
1376 if ( return_val == FALSE )
1377 gsb_data_partial_balance_set_kind ( partial_balance_number, -1 );
1378 else
1379 gsb_data_partial_balance_set_kind ( partial_balance_number, kind );
1380
1381 return return_val;
1382 }
1383
1384
1385 /**
1386 * callback when tree_view Home tab receive a drag and drop signal
1387 *
1388 * \param drag_dest
1389 * \param dest_path
1390 * \param selection_data
1391 *
1392 * \return FALSE
1393 */
gsb_data_partial_balance_drag_data_received(GtkTreeDragDest * drag_dest,GtkTreePath * dest_path,GtkSelectionData * selection_data)1394 gboolean gsb_data_partial_balance_drag_data_received ( GtkTreeDragDest * drag_dest,
1395 GtkTreePath * dest_path,
1396 GtkSelectionData * selection_data )
1397 {
1398 gchar *tmpstr = gtk_tree_path_to_string ( dest_path );
1399 gchar *tmpstr2 = g_strdup_printf ( "Dest path : %s", tmpstr);
1400 devel_debug (tmpstr2);
1401 g_free (tmpstr);
1402 g_free (tmpstr2);
1403
1404 if ( dest_path && selection_data )
1405 {
1406 GtkTreeModel * model;
1407 GtkTreeIter iter;
1408 GtkTreePath * orig_path;
1409 gint orig_partial_number = 0;
1410 gint dest_pos;
1411
1412 /* On récupère le model et le path d'origine */
1413 gtk_tree_get_row_drag_data (selection_data, &model, &orig_path);
1414
1415 if ( gtk_tree_model_get_iter ( model, &iter, orig_path ) )
1416 gtk_tree_model_get ( model, &iter, 4, &orig_partial_number, -1 );
1417
1418 dest_pos = utils_str_atoi ( gtk_tree_path_to_string ( dest_path ) );
1419
1420 gsb_data_partial_balance_move ( orig_partial_number, dest_pos );
1421 gsb_partial_balance_fill_model ( GTK_LIST_STORE ( model ) );
1422
1423 /* MAJ HOME_PAGE */
1424 gsb_gui_navigation_update_home_page ( );
1425 }
1426 return FALSE;
1427 }
1428
1429
1430 /**
1431 * Fill the drag & drop structure with the path of selected column.
1432 * This is an interface function called from GTK, much like a callback.
1433 *
1434 * \param drag_source Not used.
1435 * \param path Original path for the gtk selection.
1436 * \param selection_data A pointer to the drag & drop structure.
1437 *
1438 * \return FALSE, to allow future processing by the callback chain.
1439 */
gsb_data_partial_balance_drag_data_get(GtkTreeDragSource * drag_source,GtkTreePath * path,GtkSelectionData * selection_data)1440 gboolean gsb_data_partial_balance_drag_data_get ( GtkTreeDragSource * drag_source,
1441 GtkTreePath * path,
1442 GtkSelectionData * selection_data )
1443 {
1444 if ( path )
1445 gtk_tree_set_row_drag_data ( selection_data, GTK_TREE_MODEL( model_accueil ), path );
1446
1447 return FALSE;
1448 }
1449
1450
1451 /**
1452 * change the position of partial_balance in the list
1453 *
1454 * \param account_number the partial_balance we want to move
1455 * \param dest_account_number partial_balance before we want to move
1456 *
1457 * \return FALSE
1458 * */
gsb_data_partial_balance_move(gint orig_partial_number,gint dest_pos)1459 gboolean gsb_data_partial_balance_move ( gint orig_partial_number, gint dest_pos )
1460 {
1461 struct_partial_balance *partial_balance;
1462
1463 partial_balance = gsb_data_partial_balance_get_structure ( orig_partial_number );
1464
1465 if ( !orig_partial_number )
1466 return FALSE;
1467
1468 partial_balance_list = g_slist_remove ( partial_balance_list, partial_balance );
1469 partial_balance_list = g_slist_insert ( partial_balance_list, partial_balance, dest_pos );
1470 gsb_partial_balance_renumerote ( );
1471
1472 return FALSE;
1473 }
1474
1475
1476 /**
1477 * calcule le solde des comptes d'un solde partiel à une date donnée
1478 *
1479 * \param account_number numéro du compte concerné
1480 * \param date date de calcul du solde
1481 *
1482 * \return GPtrArray un tableau avec le solde de chaque compte concerné
1483 * */
gsb_data_partial_balance_calculate_balances_at_date(gint partial_balance_number,GDate * date)1484 GPtrArray *gsb_data_partial_balance_calculate_balances_at_date ( gint partial_balance_number,
1485 GDate *date )
1486 {
1487 GSList *tmp_list;
1488 GPtrArray *current_balances;
1489 GPtrArray *current_balances_later;
1490 GArray *floating_points;
1491 GArray *account_numbers;
1492 gchar **tab;
1493 gint i;
1494 gint nbre_comptes;
1495 struct_partial_balance *partial_balance;
1496
1497 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1498
1499 if ( !partial_balance )
1500 return NULL;
1501
1502 tab = g_strsplit ( partial_balance->liste_cptes, ";", 0 );
1503
1504 nbre_comptes = g_strv_length ( tab );
1505 if ( nbre_comptes )
1506 {
1507 floating_points = g_array_new ( FALSE, TRUE, sizeof ( gint ) );
1508 account_numbers = g_array_new ( FALSE, TRUE, sizeof ( gint ) );
1509 current_balances = g_ptr_array_new ();
1510 current_balances_later = g_ptr_array_new ();
1511 }
1512 else
1513 return NULL;
1514
1515 for ( i = 0; tab[i]; i++ )
1516 {
1517 gint account_number;
1518 gint floating_point;
1519 GsbReal *balance;
1520 GsbReal tmp_balance;
1521
1522 /* on remplit le tableau des numeros des comptes */
1523 account_number = utils_str_atoi ( tab[i] );
1524 g_array_append_val ( account_numbers, account_number );
1525
1526 /* on remplit le tableau des données des devises */
1527 floating_point = gsb_data_account_get_currency_floating_point ( account_number );
1528 g_array_append_val ( floating_points, floating_point );
1529
1530 /* on initialise le tableau des soldes de chaque compte */
1531 balance = g_malloc0 ( sizeof ( GsbReal ) );
1532 tmp_balance = gsb_data_account_get_init_balance ( account_number, floating_point );
1533 balance->mantissa = tmp_balance.mantissa;
1534 balance->exponent = tmp_balance.exponent;
1535 g_ptr_array_add ( current_balances, balance );
1536
1537 /* on initialise le tableau des soldes en erreur de chaque compte */
1538 balance = g_malloc0 ( sizeof ( GsbReal ) );
1539 balance->mantissa = null_real.mantissa;
1540 balance->exponent = null_real.exponent;
1541 g_ptr_array_add ( current_balances_later, balance );
1542 }
1543
1544 tmp_list = gsb_data_transaction_get_complete_transactions_list ();
1545
1546 while (tmp_list)
1547 {
1548 gint transaction_number;
1549
1550 transaction_number = gsb_data_transaction_get_transaction_number ( tmp_list->data );
1551
1552 for ( i = 0; i < nbre_comptes; i++ )
1553 {
1554 gint account_number;
1555 gboolean trouve = FALSE;
1556
1557 account_number = g_array_index ( account_numbers, gint, i );
1558
1559 if ( gsb_data_transaction_get_account_number ( transaction_number ) == account_number )
1560 {
1561 if ( g_date_compare ( gsb_data_transaction_get_value_date_or_date ( transaction_number ),
1562 date ) <= 0 )
1563 {
1564 if ( gsb_data_transaction_get_mother_transaction_number ( transaction_number ) == 0 )
1565 {
1566 trouve = TRUE;
1567 }
1568 }
1569 }
1570 if ( trouve )
1571 {
1572 gint floating_point;
1573 GsbReal adjusted_amout;
1574 GsbReal tmp_balance;
1575 GsbReal *balance;
1576 GsbReal current_balance;
1577
1578 floating_point = g_array_index ( floating_points, gint, i );
1579 balance = (GsbReal *) g_ptr_array_index ( current_balances, i );
1580 current_balance.mantissa = balance->mantissa;
1581 current_balance.exponent = balance->exponent;
1582
1583 adjusted_amout = gsb_data_transaction_get_adjusted_amount ( transaction_number, floating_point );
1584 tmp_balance = gsb_real_add ( current_balance, adjusted_amout );
1585
1586 if ( tmp_balance.mantissa != error_real.mantissa )
1587 {
1588 balance->mantissa = tmp_balance.mantissa;
1589 balance->exponent = tmp_balance.exponent;
1590 }
1591 else
1592 {
1593 GsbReal *balance_later;
1594
1595 balance_later = (GsbReal *) g_ptr_array_index ( current_balances_later, i );
1596 balance_later->mantissa = G_MININT64;
1597 balance_later->exponent = 0;
1598 }
1599 }
1600 }
1601 tmp_list = tmp_list->next;
1602 }
1603 g_array_free ( account_numbers, TRUE );
1604 g_array_free ( floating_points, TRUE );
1605
1606 return current_balances;
1607 }
1608
1609 /**
1610 *
1611 *
1612 * \param
1613 *
1614 * \return
1615 **/
gsb_data_partial_balance_renum_account_number_0(gint account_number)1616 void gsb_data_partial_balance_renum_account_number_0 (gint account_number)
1617 {
1618 GSList *tmp_list;
1619
1620 tmp_list = partial_balance_list;
1621 while (tmp_list)
1622 {
1623 gchar *liste_cptes;
1624 struct_partial_balance *partial_balance;
1625
1626 partial_balance = tmp_list->data;
1627 liste_cptes = partial_balance->liste_cptes;
1628 printf ("liste_cptes = %s\n", liste_cptes);
1629 if (g_strstr_len (liste_cptes, -1, "0"))
1630 {
1631 gchar **tab;
1632 gint i;
1633
1634 tab = g_strsplit (liste_cptes, ";", 0);
1635 for ( i = 0; tab[i]; i++ )
1636 {
1637 gint account_nb;
1638
1639 account_nb = utils_str_atoi (tab[i]);
1640 if (account_nb == 0)
1641 {
1642 gchar *tmp_number_str;
1643 gchar *str_to_free;
1644 gchar *new_str;
1645
1646 tmp_number_str = utils_str_itoa (account_number);
1647 str_to_free = tab[i];
1648 tab[i] = tmp_number_str;
1649 g_free (str_to_free);
1650 new_str = g_strjoinv (";", tab);
1651 g_free (partial_balance->liste_cptes);
1652 partial_balance->liste_cptes = new_str;
1653 g_strfreev (tab);
1654 break;
1655 }
1656 }
1657 }
1658 tmp_list = tmp_list->next;
1659 }
1660 }
1661
1662 /*********************************************************************************************/
1663 /* Interface */
1664 /*********************************************************************************************/
1665 /**
1666 *
1667 *
1668 * */
gsb_partial_balance_create_list_accounts(GtkWidget * entry)1669 GtkWidget *gsb_partial_balance_create_list_accounts ( GtkWidget *entry )
1670 {
1671 GtkWidget *vbox;
1672 GtkWidget *sw;
1673 GtkWidget *treeview;
1674 GtkListStore *list_store;
1675 GtkTreeIter iter;
1676 GSList *list_tmp;
1677 GtkTreeViewColumn *column;
1678 GtkCellRenderer *cell;
1679 GtkTreeSelection *selection;
1680 gint i = 0;
1681
1682 vbox = gtk_box_new ( GTK_ORIENTATION_VERTICAL, MARGIN_BOX );
1683 sw = gtk_scrolled_window_new (NULL, NULL);
1684 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
1685 GTK_SHADOW_ETCHED_IN);
1686 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
1687 GTK_POLICY_NEVER,
1688 GTK_POLICY_ALWAYS);
1689 gtk_widget_set_size_request( sw, 600, 200 );
1690
1691 /* create the model */
1692 list_store = gtk_list_store_new ( 2, G_TYPE_STRING, G_TYPE_INT );
1693 list_tmp = gsb_data_account_get_list_accounts ();
1694
1695 while ( list_tmp )
1696 {
1697 gint account_number;
1698
1699 account_number = gsb_data_account_get_no_account ( list_tmp -> data );
1700
1701 if ( !gsb_data_account_get_closed_account ( account_number ) )
1702 {
1703 gtk_list_store_append ( GTK_LIST_STORE ( list_store), &iter );
1704 gtk_list_store_set ( GTK_LIST_STORE ( list_store ), &iter,
1705 0, gsb_data_account_get_name ( account_number ),
1706 1, account_number,
1707 -1 );
1708 i++;
1709 }
1710 list_tmp = list_tmp -> next;
1711 }
1712 if ( i > 10 )
1713 i = 10;
1714 /* create the treeview */
1715 treeview = gtk_tree_view_new_with_model ( GTK_TREE_MODEL ( list_store ) );
1716 gtk_widget_set_name (treeview, "tree_view");
1717 g_object_unref ( list_store );
1718
1719 gtk_widget_set_size_request ( treeview, -1, i*20 );
1720 selection = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( treeview ) );
1721 gtk_tree_selection_set_mode ( selection, GTK_SELECTION_MULTIPLE );
1722 gtk_tree_selection_set_select_function ( selection,
1723 (GtkTreeSelectionFunc) gsb_partial_balance_select_account,
1724 entry, NULL );
1725 gtk_container_add ( GTK_CONTAINER ( sw ), treeview );
1726 gtk_box_pack_start ( GTK_BOX ( vbox ), sw, FALSE, FALSE, 0 );
1727 g_object_set_data ( G_OBJECT (vbox), "account_treeview", treeview );
1728
1729 /* account name */
1730 cell = gtk_cell_renderer_text_new ( );
1731 column = gtk_tree_view_column_new_with_attributes ( _("Account name"),
1732 cell,
1733 "text",
1734 0,
1735 NULL );
1736 gtk_tree_view_column_set_expand ( column, TRUE );
1737 gtk_tree_view_column_set_sort_column_id ( column, 0 );
1738 gtk_tree_view_append_column ( GTK_TREE_VIEW ( treeview ), column );
1739
1740 /* account number */
1741 cell = gtk_cell_renderer_text_new ();
1742 column = gtk_tree_view_column_new_with_attributes (_("Account number"), cell, "text", 1, NULL);
1743 gtk_tree_view_column_set_expand (column, TRUE);
1744 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview ), column);
1745
1746 return vbox;
1747 }
1748
1749
1750 /**
1751 *
1752 *
1753 * */
gsb_partial_balance_create_dialog(gint action,gint spin_value)1754 GtkWidget *gsb_partial_balance_create_dialog ( gint action, gint spin_value )
1755 {
1756 GtkWidget *dialog, *label, *main_vbox;
1757 GtkWidget *paddinggrid;
1758 GtkWidget *entry_name, *entry_list, *account_list, *bouton;
1759
1760 devel_debug ( NULL);
1761
1762 if ( action == 1 )
1763 dialog = gtk_dialog_new_with_buttons ( _("Add a partial balance"),
1764 GTK_WINDOW ( grisbi_app_get_active_window (NULL) ),
1765 GTK_DIALOG_MODAL,
1766 "gtk-cancel", 0,
1767 "gtk-ok", 1,
1768 NULL );
1769 else
1770 dialog = gtk_dialog_new_with_buttons ( _("Modify a partial balance"),
1771 GTK_WINDOW ( grisbi_app_get_active_window (NULL) ),
1772 GTK_DIALOG_MODAL,
1773 "gtk-cancel", 0,
1774 "gtk-ok", 1,
1775 NULL );
1776 gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
1777
1778 main_vbox = new_vbox_with_title_and_icon ( _("Partial balance details"), "gsb-payment-32.png" );
1779 gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area ( dialog ) ), main_vbox, TRUE, TRUE, 0 );
1780
1781 /* Create paddinggrid */
1782 paddinggrid = utils_prefs_paddinggrid_new_with_title ( main_vbox, _("Details") );
1783 gtk_grid_set_column_spacing (GTK_GRID (paddinggrid), 5);
1784 gtk_grid_set_row_spacing (GTK_GRID (paddinggrid), 5);
1785
1786 /* Partial balance name */
1787 label = gtk_label_new ( _("Name: ") );
1788 utils_labels_set_alignment ( GTK_LABEL ( label ), 0, 1 );
1789 gtk_label_set_justify ( GTK_LABEL ( label ), GTK_JUSTIFY_RIGHT );
1790 gtk_grid_attach (GTK_GRID (paddinggrid), label, 0, 0, 1, 1);
1791
1792 entry_name = gtk_entry_new ( );
1793 gtk_entry_set_activates_default ( GTK_ENTRY ( entry_name ), TRUE );
1794 gtk_grid_attach (GTK_GRID (paddinggrid), entry_name, 1, 0, 1, 1);
1795
1796 /* List of the accounts */
1797 label = gtk_label_new ( _("Accounts list: ") );
1798 utils_labels_set_alignment ( GTK_LABEL ( label ), 0, 1);
1799 gtk_label_set_justify ( GTK_LABEL ( label ), GTK_JUSTIFY_LEFT );
1800 gtk_grid_attach (GTK_GRID (paddinggrid), label, 0, 1, 1, 1);
1801
1802 entry_list = gtk_entry_new ( );
1803 gtk_editable_set_editable ( GTK_EDITABLE ( entry_list ), FALSE );
1804 gtk_widget_set_sensitive ( entry_list, FALSE );
1805 gtk_grid_attach (GTK_GRID (paddinggrid), entry_list, 1, 1, 1, 1);
1806
1807 account_list = gsb_partial_balance_create_list_accounts ( entry_list );
1808 gtk_grid_attach (GTK_GRID (paddinggrid), account_list, 0, 2, 2, 2);
1809
1810 /* create the position */
1811 label = gtk_label_new ( _("Position in the list of accounts: ") );
1812 gtk_widget_set_margin_top (label, MARGIN_TOP);
1813 utils_labels_set_alignment ( GTK_LABEL ( label ), 0, 1);
1814 gtk_label_set_justify ( GTK_LABEL ( label ), GTK_JUSTIFY_LEFT );
1815 gtk_grid_attach (GTK_GRID (paddinggrid), label, 0, 4, 1, 1);
1816
1817 bouton = gtk_spin_button_new_with_range ( 1.0, spin_value, 1.0);
1818 gtk_widget_set_margin_top (bouton, MARGIN_TOP);
1819 gtk_spin_button_set_value ( GTK_SPIN_BUTTON ( bouton ),
1820 g_slist_length ( partial_balance_list ) + 1 );
1821 gtk_grid_attach (GTK_GRID (paddinggrid), bouton, 1, 4, 1, 1);
1822 g_object_set_data ( G_OBJECT ( dialog ), "spin_bouton", bouton );
1823
1824 /* create the colorized button */
1825 bouton = gtk_check_button_new_with_label ( _("Colorized in red if the balance is negative") );
1826 gtk_widget_set_margin_top (bouton, MARGIN_TOP);
1827 g_object_set_data ( G_OBJECT ( dialog ), "colorise_bouton", bouton );
1828 gtk_grid_attach (GTK_GRID (paddinggrid), bouton, 0, 5, 2, 1);
1829
1830 g_object_set_data ( G_OBJECT ( dialog ), "entry_name", entry_name );
1831 g_object_set_data ( G_OBJECT ( dialog ), "entry_list", entry_list );
1832 g_object_set_data ( G_OBJECT ( dialog ), "account_list", account_list );
1833
1834 return dialog;
1835 }
1836
1837
1838 /**
1839 *
1840 *
1841 * */
gsb_partial_balance_request_currency(GtkWidget * parent)1842 gint gsb_partial_balance_request_currency ( GtkWidget *parent )
1843 {
1844 GtkWidget *dialog, *hbox, *label, *combo_devise;
1845 gint currency_nb = 1; /* Initialisation avec la première devise : fixe bug 1881 */
1846
1847 dialog = gtk_dialog_new_with_buttons ( _("Enter the currency of the balance part"),
1848 GTK_WINDOW ( parent ),
1849 GTK_DIALOG_MODAL,
1850 "gtk-cancel", 0,
1851 "gtk-ok", 1,
1852 NULL );
1853 gtk_widget_set_size_request ( dialog, -1, 150 );
1854 gtk_window_set_position ( GTK_WINDOW ( dialog ), GTK_WIN_POS_CENTER_ON_PARENT );
1855
1856 hbox = gtk_box_new ( GTK_ORIENTATION_HORIZONTAL, MARGIN_BOX );
1857 gtk_box_pack_start ( GTK_BOX ( dialog_get_content_area( dialog ) ), hbox, TRUE, FALSE, 0 );
1858
1859 label = gtk_label_new ( _("Select the currency of the partial balance: ") );
1860 utils_labels_set_alignment ( GTK_LABEL ( label ), 0, 1 );
1861 gtk_label_set_justify ( GTK_LABEL ( label ), GTK_JUSTIFY_LEFT );
1862 gtk_box_pack_start ( GTK_BOX ( hbox ), label, TRUE, TRUE, 0 );
1863
1864 combo_devise = gsb_currency_combobox_new ( ¤cy_nb, NULL );
1865 gtk_box_pack_start ( GTK_BOX ( hbox ), combo_devise, FALSE, FALSE, 10 );
1866
1867 gtk_widget_show_all ( GTK_WIDGET ( dialog ) );
1868
1869 gsb_currency_set_combobox_history (combo_devise, currency_nb);
1870 gtk_dialog_run ( GTK_DIALOG ( dialog ) );
1871
1872 gtk_widget_destroy ( GTK_WIDGET ( dialog ) );
1873
1874 return currency_nb;
1875 }
1876
1877 /**
1878 * calcule le solde d'un solde partiel à une date donnée
1879 *
1880 * \param partial_balance_number numéro du solde partiel concerné
1881 * \param date date de calcul du solde
1882 *
1883 * \return GsbReal le solde du solde partiel
1884 * */
gsb_data_partial_balance_get_balance_at_date(gint partial_balance_number,GDate * date)1885 GsbReal gsb_data_partial_balance_get_balance_at_date ( gint partial_balance_number,
1886 GDate *date )
1887 {
1888 struct_partial_balance *partial_balance;
1889 GsbReal solde = null_real;
1890 gchar **tab;
1891 gint i;
1892
1893 partial_balance = gsb_data_partial_balance_get_structure ( partial_balance_number );
1894
1895 if ( !partial_balance )
1896 return null_real;
1897
1898 if ( partial_balance -> liste_cptes == NULL ||
1899 strlen ( partial_balance -> liste_cptes ) == 0 )
1900 return null_real;
1901
1902 tab = g_strsplit ( partial_balance -> liste_cptes, ";", 0 );
1903 for ( i = 0; tab[i]; i++ )
1904 {
1905 GsbReal tmp_real;
1906 gint account_number;
1907 gint account_currency;
1908 gint link_number;
1909
1910 account_number = utils_str_atoi ( tab[i] );
1911 account_currency = gsb_data_account_get_currency ( account_number );
1912 tmp_real = gsb_data_account_get_balance_at_date ( account_number, date );
1913
1914 if ( tmp_real.mantissa != 0 && partial_balance -> currency != account_currency )
1915 {
1916 if ( ( link_number = gsb_data_currency_link_search ( account_currency,
1917 partial_balance -> currency ) ) )
1918 {
1919 if ( gsb_data_currency_link_get_first_currency ( link_number) == account_currency )
1920 tmp_real = gsb_real_mul ( tmp_real,
1921 gsb_data_currency_link_get_change_rate ( link_number ) );
1922 else
1923 tmp_real = gsb_real_div ( tmp_real,
1924 gsb_data_currency_link_get_change_rate ( link_number ) );
1925 }
1926 }
1927 solde = gsb_real_add ( solde, tmp_real );
1928 }
1929 g_strfreev ( tab );
1930
1931 return solde;
1932 }
1933
1934
1935 /**
1936 *
1937 *
1938 * \param
1939 *
1940 * \return
1941 * */
1942 /* Local Variables: */
1943 /* c-basic-offset: 4 */
1944 /* End: */
1945