1 /* ************************************************************************** */
2 /* */
3 /* Copyright (C) 2000-2008 Cédric Auger (cedric@grisbi.org) */
4 /* 2003-2008 Benjamin Drieu (bdrieu@april.org) */
5 /* 2009-2018 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_form_widget.c
26 * convenient functions to work with the elements in the form
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_form_widget.h"
39 #include "grisbi_app.h"
40 #include "gsb_calendar_entry.h"
41 #include "gsb_combo_box.h"
42 #include "gsb_currency.h"
43 #include "gsb_data_account.h"
44 #include "gsb_data_budget.h"
45 #include "gsb_data_category.h"
46 #include "gsb_data_form.h"
47 #include "gsb_data_payee.h"
48 #include "gsb_data_report.h"
49 #include "gsb_form.h"
50 #include "gsb_form_transaction.h"
51 #include "gsb_fyear.h"
52 #include "gsb_locale.h"
53 #include "gsb_payment_method.h"
54 #include "gtk_combofix.h"
55 #include "gsb_data_payment.h"
56 #include "structures.h"
57 #include "erreur.h"
58 /*END_INCLUDE*/
59
60 /*START_STATIC*/
61 static GSList * form_list_widgets = NULL; /* contains a list of struct_element according to the current form */
62 static gchar * old_debit = NULL;
63 static gchar * old_credit = NULL;
64 static gint old_credit_payment_number = 0;
65 static gint old_debit_payment_number = 0;
66 static gchar * old_credit_payment_content = NULL;
67 static gchar * old_debit_payment_content = NULL;
68 /*END_STATIC*/
69
70 /*START_EXTERN*/
71 /*END_EXTERN*/
72
73
74 /******************************************************************************/
75 /* Private functions */
76 /******************************************************************************/
77 /**
78 *
79 *
80 * \param
81 * \param
82 *
83 * \return
84 **/
gsb_form_combo_selection_changed(GtkTreeSelection * tree_selection,gint * ptr_origin)85 static gboolean gsb_form_combo_selection_changed (GtkTreeSelection *tree_selection,
86 gint *ptr_origin)
87 {
88 GtkWidget *widget;
89 GtkTreeModel *model;
90 GtkTreeIter iter;
91 gchar *tmp_str;
92 gint element_number;
93 gint account_nb;
94
95 element_number = GPOINTER_TO_INT (ptr_origin);
96
97 if (!gtk_tree_selection_get_selected (GTK_TREE_SELECTION (tree_selection), &model, &iter))
98 return FALSE;
99
100 gtk_tree_model_get (model, &iter, 1, &tmp_str, -1);
101
102 if (tmp_str && strlen (tmp_str))
103 {
104 if (element_number == TRANSACTION_FORM_CATEGORY)
105 {
106 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_DEVISE);
107 if (widget != NULL && gtk_widget_get_visible (widget))
108 {
109 if (g_str_has_prefix (tmp_str, _("Transfer : ")))
110 {
111 account_nb = gsb_form_get_account_number ();
112 if (g_str_has_suffix (tmp_str, gsb_data_account_get_name (account_nb)))
113 gtk_widget_hide (gsb_form_widget_get_widget (TRANSACTION_FORM_CHANGE));
114 else
115 gtk_widget_show (gsb_form_widget_get_widget (TRANSACTION_FORM_CHANGE));
116 }
117 else
118 gtk_widget_hide (gsb_form_widget_get_widget (TRANSACTION_FORM_CHANGE));
119 }
120 else
121 {
122 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_CHANGE);
123 if (widget != NULL)
124 gtk_widget_hide (widget);
125 }
126 }
127 }
128 return FALSE;
129 }
130
131 /**
132 * check if the given element can receive focus
133 *
134 * \param element_number
135 *
136 * \return TRUE : can receive focus, or FALSE
137 **/
gsb_form_widget_can_focus(gint element_number)138 static gboolean gsb_form_widget_can_focus (gint element_number)
139 {
140 GtkWidget *widget;
141
142 /* if element_number is -1 or -2, the iteration while must
143 * stop, so return TRUE */
144 if (element_number == -1 || element_number == -2)
145 return TRUE;
146
147 widget = gsb_form_widget_get_widget (element_number);
148 if (!widget)
149 return FALSE;
150
151 if (!gtk_widget_get_visible (widget))
152 return FALSE;
153
154 if (!gtk_widget_get_sensitive (widget))
155 return FALSE;
156
157 if (!(GTK_IS_COMBOFIX (widget)
158 || GTK_IS_ENTRY (widget)
159 || GTK_IS_BUTTON (widget)
160 || GTK_IS_COMBO_BOX (widget)))
161 {
162 return FALSE;
163 }
164
165 return TRUE;
166 }
167
168 /******************************************************************************/
169 /* Public Methods */
170 /******************************************************************************/
171 /**
172 * return the list which contains the widgets of the form
173 *
174 * \param
175 *
176 * \return a GSList with the pointers to the widgets of the form
177 **/
gsb_form_widget_get_list(void)178 GSList *gsb_form_widget_get_list (void)
179 {
180 return form_list_widgets;
181 }
182
183 /**
184 * free the content of the list of the widget's form
185 * so free the content of the form
186 *
187 * \param
188 *
189 * \return FALSE
190 **/
gsb_form_widget_free_list(void)191 gboolean gsb_form_widget_free_list (void)
192 {
193 GtkWidget *entry;
194 GSList *tmp_list;
195 GtkWidget *widget_signals;
196
197 devel_debug (NULL);
198
199 if (!form_list_widgets)
200 return FALSE;
201
202 tmp_list = form_list_widgets;
203 while (tmp_list)
204 {
205 struct_element *element;
206
207 element = tmp_list->data;
208 if (!element)
209 {
210 tmp_list = tmp_list->next;
211 continue;
212 }
213
214 /* just to make sure... */
215 if (element->element_widget)
216 {
217 if (GTK_IS_WIDGET (element->element_widget))
218 {
219 widget_signals = NULL;
220 if (GTK_IS_ENTRY (element->element_widget))
221 {
222 widget_signals = element->element_widget;
223 }
224 else if (GTK_IS_COMBOFIX (element->element_widget))
225 {
226 widget_signals = gtk_combofix_get_entry (GTK_COMBOFIX (element->element_widget));
227 /* if there is something in the combofix we destroy, the popup will
228 * be showed because destroying the gtk_entry will erase it directly,
229 * so the simpliest way to avoid that is to erase now the entry, but with
230 * gtk_combofix_set_text [cedric] (didn't succeed with another thing...) */
231 gtk_combofix_set_text (GTK_COMBOFIX (element->element_widget), "");
232 gsb_form_widget_set_empty (GTK_WIDGET (element->element_widget), TRUE);
233 }
234 else if (GTK_IS_COMBO_BOX (element->element_widget))
235 {
236 /* Ajout du 24/07/2017 : pour une raison encore indéterminée, les éléments de type GtkComboBox */
237 /* provoquent un warning de la part de gtk (version 3.22.11) lorsque le widget est détruit : */
238 /* (grisbi:10426): Gtk-CRITICAL **: gtk_widget_is_drawable: assertion 'GTK_IS_WIDGET (widget)' failed */
239 g_signal_handlers_block_by_func (element->element_widget,
240 gsb_payment_method_changed_callback,
241 NULL);
242 if (element->element_number == TRANSACTION_FORM_TYPE)
243 {
244 element->element_widget = NULL;
245 g_free (element);
246 tmp_list = tmp_list->next;
247 continue;
248 }
249 else if (element->element_number == TRANSACTION_FORM_PARTY)
250 {
251 entry = gtk_combofix_get_entry (GTK_COMBOFIX (element->element_widget));
252 widget_signals = entry;
253 }
254 }
255
256 if (widget_signals)
257 {
258 g_signal_handlers_disconnect_by_func (G_OBJECT (widget_signals),
259 G_CALLBACK (gsb_form_entry_get_focus),
260 GINT_TO_POINTER (element->element_number));
261 g_signal_handlers_disconnect_by_func (G_OBJECT (widget_signals),
262 G_CALLBACK (gsb_form_entry_lose_focus),
263 GINT_TO_POINTER (element->element_number));
264 g_signal_handlers_disconnect_by_func (G_OBJECT (widget_signals),
265 G_CALLBACK (gsb_form_button_press_event),
266 GINT_TO_POINTER (element->element_number));
267 g_signal_handlers_disconnect_by_func (G_OBJECT (widget_signals),
268 G_CALLBACK (gsb_form_key_press_event),
269 GINT_TO_POINTER (element->element_number));
270 if (GTK_IS_COMBOFIX (widget_signals))
271 g_signal_handlers_disconnect_by_func (G_OBJECT (widget_signals),
272 G_CALLBACK (gsb_form_combo_selection_changed),
273 GINT_TO_POINTER (element->element_number));
274 }
275
276 gtk_widget_destroy (element->element_widget);
277 element->element_widget = NULL;
278 }
279 }
280 else
281 {
282 alert_debug ("element_widget is NULL\n");
283 }
284 g_free (element);
285 tmp_list = tmp_list->next;
286 }
287 g_slist_free (form_list_widgets);
288 form_list_widgets = NULL;
289
290 return FALSE;
291 }
292
293 /**
294 * create and return the widget according to its element number
295 *
296 * \param element_number the number corresponding to the widget wanted
297 * \param account_number used for method of payment and currency
298 *
299 * \return the widget or NULL (if the element number is zero)
300 **/
gsb_form_widget_create(gint element_number,gint account_number)301 GtkWidget *gsb_form_widget_create (gint element_number,
302 gint account_number)
303 {
304 GtkWidget *widget;
305 GSList *tmp_list;
306
307 if (!element_number)
308 return NULL;
309
310 widget = NULL;
311 switch (element_number)
312 {
313 case TRANSACTION_FORM_DATE:
314 case TRANSACTION_FORM_VALUE_DATE:
315 widget = gsb_calendar_entry_new (FALSE);
316 break;
317
318 case TRANSACTION_FORM_DEBIT:
319 widget = gtk_entry_new ();
320 g_object_set_data (G_OBJECT (widget), "element_number",
321 GINT_TO_POINTER (TRANSACTION_FORM_DEBIT));
322 g_signal_connect (G_OBJECT (widget),
323 "changed",
324 G_CALLBACK (gsb_form_widget_amount_entry_changed),
325 NULL);
326 break;
327 case TRANSACTION_FORM_CREDIT:
328 widget = gtk_entry_new ();
329 g_object_set_data (G_OBJECT (widget), "element_number",
330 GINT_TO_POINTER (TRANSACTION_FORM_CREDIT));
331 g_signal_connect (G_OBJECT (widget),
332 "changed",
333 G_CALLBACK (gsb_form_widget_amount_entry_changed),
334 NULL);
335 break;
336
337 case TRANSACTION_FORM_NOTES:
338 case TRANSACTION_FORM_CHEQUE:
339 case TRANSACTION_FORM_VOUCHER:
340 case TRANSACTION_FORM_BANK:
341 widget = gtk_entry_new();
342 break;
343
344 case TRANSACTION_FORM_EXERCICE:
345 widget = gsb_fyear_make_combobox (TRUE);
346 gtk_widget_set_tooltip_text (GTK_WIDGET (widget),
347 _("Choose the financial year"));
348 break;
349
350 case TRANSACTION_FORM_PARTY:
351 tmp_list = gsb_data_payee_get_name_and_report_list ();
352 widget = gtk_combofix_new_with_properties (tmp_list,
353 etat.combofix_force_payee,
354 etat.combofix_case_sensitive,
355 FALSE,
356 METATREE_PAYEE);
357 gsb_data_payee_free_name_and_report_list (tmp_list);
358 break;
359
360 case TRANSACTION_FORM_CATEGORY:
361 tmp_list = gsb_data_category_get_name_list (TRUE, TRUE, TRUE, TRUE);
362 widget = gtk_combofix_new_with_properties (tmp_list,
363 etat.combofix_force_category,
364 etat.combofix_case_sensitive,
365 etat.combofix_mixed_sort,
366 METATREE_CATEGORY);
367 gsb_data_categorie_free_name_list (tmp_list);
368 break;
369
370 case TRANSACTION_FORM_FREE:
371 alert_debug ("TRANSACTION_FORM_FREE returns an empty widget");
372 break;
373
374 case TRANSACTION_FORM_BUDGET:
375 tmp_list = gsb_data_budget_get_name_list (TRUE, TRUE);
376 widget = gtk_combofix_new_with_properties (tmp_list,
377 etat.combofix_force_category,
378 etat.combofix_case_sensitive,
379 etat.combofix_mixed_sort,
380 METATREE_BUDGET);
381 gsb_data_categorie_free_name_list (tmp_list);
382 break;
383
384 case TRANSACTION_FORM_TYPE:
385 widget = gtk_combo_box_new ();
386 gsb_payment_method_create_combo_list (widget,
387 GSB_PAYMENT_DEBIT,
388 account_number,
389 0,
390 FALSE);
391 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
392 gtk_widget_set_tooltip_text (GTK_WIDGET (widget),
393 _("Choose the method of payment"));
394 g_signal_connect (G_OBJECT (widget),
395 "changed",
396 G_CALLBACK (gsb_payment_method_changed_callback),
397 NULL);
398 break;
399
400 case TRANSACTION_FORM_DEVISE:
401 widget = gsb_currency_make_combobox (FALSE);
402 gtk_widget_set_tooltip_text (GTK_WIDGET (widget), _("Choose currency"));
403 gsb_currency_set_combobox_history (widget,
404 gsb_data_account_get_currency (account_number));
405 g_signal_connect (G_OBJECT (widget),
406 "changed",
407 G_CALLBACK (gsb_form_transaction_currency_changed),
408 NULL);
409 break;
410
411 case TRANSACTION_FORM_CHANGE:
412 widget = gtk_button_new_with_label (_("Change"));
413 gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE);
414 gtk_widget_set_tooltip_text (GTK_WIDGET (widget),
415 _("Define the change for that transaction"));
416 g_signal_connect (G_OBJECT (widget),
417 "clicked",
418 G_CALLBACK (gsb_form_transaction_change_clicked),
419 NULL);
420 break;
421
422 case TRANSACTION_FORM_CONTRA:
423 /* no menu at beginning, appened when choose the contra-account */
424 widget = gtk_combo_box_new ();
425 gtk_widget_set_tooltip_text (GTK_WIDGET (widget),
426 _("Contra-transaction method of payment"));
427 break;
428
429 case TRANSACTION_FORM_OP_NB:
430 case TRANSACTION_FORM_MODE:
431 widget = gtk_label_new (NULL);
432 break;
433 }
434
435 if (widget)
436 {
437 /* force minimum width */
438 gtk_widget_set_size_request (widget, FORM_COURT_WIDTH, -1);
439
440 /* first, append the widget to the list */
441 struct_element *element;
442
443 element = g_malloc0 (sizeof (struct_element));
444 element->element_number = element_number;
445 element->element_widget = widget;
446 form_list_widgets = g_slist_append (form_list_widgets, element);
447
448 /* set the signals */
449 if (GTK_IS_ENTRY (widget))
450 {
451 g_signal_connect (G_OBJECT (widget),
452 "focus-in-event",
453 G_CALLBACK (gsb_form_widget_entry_get_focus),
454 GINT_TO_POINTER (element_number));
455 g_signal_connect (G_OBJECT (widget),
456 "focus-out-event",
457 G_CALLBACK (gsb_form_entry_lose_focus),
458 GINT_TO_POINTER (element_number));
459 g_signal_connect (G_OBJECT (widget),
460 "button-press-event",
461 G_CALLBACK (gsb_form_button_press_event),
462 GINT_TO_POINTER (element_number));
463 g_signal_connect (G_OBJECT (widget),
464 "key-press-event",
465 G_CALLBACK (gsb_form_key_press_event),
466 GINT_TO_POINTER (element_number));
467 }
468 else
469 {
470 if (GTK_IS_COMBOFIX (widget))
471 {
472 GtkWidget *entry = NULL;
473
474 entry = gtk_combofix_get_entry (GTK_COMBOFIX (widget));
475 if (GTK_IS_ENTRY (entry))
476 {
477 gtk_widget_set_size_request (widget, FORM_LONG_WIDTH, -1);
478
479 g_signal_connect (G_OBJECT (entry),
480 "focus-in-event",
481 G_CALLBACK (gsb_form_entry_get_focus),
482 GINT_TO_POINTER (element_number));
483 g_signal_connect (G_OBJECT (entry),
484 "focus-out-event",
485 G_CALLBACK (gsb_form_entry_lose_focus),
486 GINT_TO_POINTER (element_number));
487 g_signal_connect (G_OBJECT (entry),
488 "button-press-event",
489 G_CALLBACK (gsb_form_button_press_event),
490 GINT_TO_POINTER (element_number));
491 g_signal_connect (G_OBJECT (entry),
492 "key-press-event",
493 G_CALLBACK (gsb_form_key_press_event),
494 GINT_TO_POINTER (element_number));
495 }
496 gtk_combofix_set_selection_callback (GTK_COMBOFIX (widget),
497 G_CALLBACK (gsb_form_combo_selection_changed),
498 GINT_TO_POINTER (element_number));
499 }
500 else
501 /* neither an entry, neither a combofix or combo_box*/
502 g_signal_connect (G_OBJECT (widget),
503 "key-press-event",
504 G_CALLBACK (gsb_form_key_press_event),
505 GINT_TO_POINTER (element_number));
506 }
507 }
508 else
509 {
510 alert_debug ("Widget should not be NULL");
511 }
512
513 return widget;
514 }
515
516 /**
517 * return the pointer to the widget corresponding to the given element
518 *
519 * \param element_number
520 *
521 * \return the widget or NULL
522 **/
gsb_form_widget_get_widget(gint element_number)523 GtkWidget *gsb_form_widget_get_widget (gint element_number)
524 {
525 return gsb_form_get_element_widget_from_list (element_number,
526 form_list_widgets);
527 }
528
529 /**
530 * get an element number and return its name
531 *
532 * \param element_number
533 *
534 * \return the name of the element or NULL if problem
535 **/
gsb_form_widget_get_name(gint element_number)536 const gchar *gsb_form_widget_get_name (gint element_number)
537 {
538 switch (element_number)
539 {
540 case -1:
541 /* that value shouldn't be there, it shows that a gsb_data_form_... returns
542 * an error value */
543 warning_debug ("gsb_form_widget_get_name : a value in the form is -1 "
544 "which should not happen.\nA gsb_data_form_... "
545 "function must have returned an error value...");
546 return NULL;
547 break;
548
549 case TRANSACTION_FORM_DATE:
550 return (N_("Date"));
551 break;
552
553 case TRANSACTION_FORM_DEBIT:
554 return (N_("Debit"));
555 break;
556
557 case TRANSACTION_FORM_CREDIT:
558 return (N_("Credit"));
559 break;
560
561 case TRANSACTION_FORM_VALUE_DATE:
562 return (N_("Value date"));
563 break;
564
565 case TRANSACTION_FORM_EXERCICE:
566 return (N_("Financial year"));
567 break;
568
569 case TRANSACTION_FORM_PARTY:
570 return (N_("Payee"));
571 break;
572
573 case TRANSACTION_FORM_CATEGORY:
574 return (N_("Categories : Sub-categories"));
575 break;
576
577 case TRANSACTION_FORM_FREE:
578 return (N_("Free"));
579 break;
580
581 case TRANSACTION_FORM_BUDGET:
582 return (N_("Budgetary line"));
583 break;
584
585 case TRANSACTION_FORM_NOTES:
586 return (N_("Notes"));
587 break;
588
589 case TRANSACTION_FORM_TYPE:
590 return (N_("Method of payment"));
591 break;
592
593 case TRANSACTION_FORM_CHEQUE:
594 return (N_("Cheque/Transfer number"));
595 break;
596
597 case TRANSACTION_FORM_DEVISE:
598 return (N_("Currency"));
599 break;
600
601 case TRANSACTION_FORM_CHANGE:
602 return (N_("Change"));
603 break;
604
605 case TRANSACTION_FORM_VOUCHER:
606 return (N_("Voucher"));
607 break;
608
609 case TRANSACTION_FORM_BANK:
610 return (N_("Bank references"));
611 break;
612
613 case TRANSACTION_FORM_CONTRA:
614 return (N_("Contra-transaction method of payment"));
615 break;
616
617 case TRANSACTION_FORM_OP_NB:
618 return (N_("Transaction number"));
619 break;
620
621 case TRANSACTION_FORM_MODE:
622 return (N_("Automatic/Manual"));
623 break;
624 }
625 return NULL;
626 }
627
628 /**
629 * return the number of the next valid element in the direction given in param
630 *
631 * \param account_number
632 * \param element_number
633 * \param direction GTK_DIR_LEFT, GTK_DIR_RIGHT, GTK_DIR_UP, GTK_DIR_DOWN
634 *
635 * \return the next element number
636 * -1 if problem or not change
637 * -2 if end of the form and need to finish it
638 **/
gsb_form_widget_next_element(gint account_number,gint element_number,gint direction)639 gint gsb_form_widget_next_element (gint account_number,
640 gint element_number,
641 gint direction)
642 {
643 gint row;
644 gint column;
645 gint return_value_number = 0;
646 gint form_column_number;
647 gint form_row_number;
648
649 if (!gsb_data_form_look_for_value (element_number, &row, &column))
650 return -1;
651
652 form_column_number = gsb_data_form_get_nb_columns ();
653 form_row_number = gsb_data_form_get_nb_rows ();
654
655 while (!gsb_form_widget_can_focus (return_value_number))
656 {
657 switch (direction)
658 {
659 case GTK_DIR_LEFT:
660 if (!column && !row)
661 {
662 /* we are at the upper left, go on the bottom right */
663 column = form_column_number;
664 row = form_row_number -1;
665 }
666
667 if (--column == -1)
668 {
669 column = form_column_number - 1;
670 row--;
671 }
672 return_value_number = gsb_data_form_get_value (column, row);
673 break;
674
675 case GTK_DIR_RIGHT:
676 if (column == (form_column_number - 1)
677 &&
678 row == (form_row_number - 1))
679 {
680 GrisbiAppConf *a_conf;
681
682 a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
683
684 /* we are on the bottom right, we finish the edition or
685 * go to the upper left */
686 if (!a_conf->form_enter_key)
687 {
688 return_value_number = -2;
689 continue;
690 }
691 column = -1;
692 row = 0;
693 }
694
695 if (++column == form_column_number)
696 {
697 column = 0;
698 row++;
699 }
700 return_value_number = gsb_data_form_get_value (column, row);
701 break;
702
703 case GTK_DIR_UP:
704 if (!row)
705 {
706 return_value_number = -1;
707 continue;
708 }
709
710 row--;
711 return_value_number = gsb_data_form_get_value (column, row);
712 break;
713
714 case GTK_DIR_DOWN:
715 if (row == (form_row_number - 1))
716 {
717 return_value_number = -1;
718 continue;
719 }
720 row++;
721 return_value_number = gsb_data_form_get_value (column, row);
722 break;
723
724 default:
725 return_value_number = -1;
726 }
727 }
728 return return_value_number;
729 }
730
731 /**
732 * set the focus on the given element
733 *
734 * \param element_number
735 *
736 * \return
737 **/
gsb_form_widget_set_focus(gint element_number)738 void gsb_form_widget_set_focus (gint element_number)
739 {
740 GtkWidget *widget;
741
742 widget = gsb_form_widget_get_widget (element_number);
743
744 if (!widget)
745 return;
746
747 if (GTK_IS_COMBOFIX (widget))
748 {
749 GtkWidget *entry;
750
751 entry = gtk_combofix_get_entry (GTK_COMBOFIX (widget));
752 if (entry)
753 gtk_widget_grab_focus (entry);
754 else
755 gtk_widget_grab_focus (widget);
756 }
757 else
758 gtk_widget_grab_focus (widget);
759
760 return;
761 }
762
763 /**
764 * check if the entry or combofix given in param is empty (ie grey) or not
765 *
766 * \param entry must be an entry
767 *
768 * \return TRUE : entry is free, FALSE : not free
769 **/
gsb_form_widget_check_empty(GtkWidget * entry)770 gboolean gsb_form_widget_check_empty (GtkWidget *entry)
771 {
772 if (!entry)
773 return FALSE;
774
775 if (GTK_IS_ENTRY (entry))
776 return GPOINTER_TO_INT (g_object_get_data (G_OBJECT(entry), "empty"));
777
778 entry = gtk_combofix_get_entry (GTK_COMBOFIX (entry));
779 if (GTK_IS_ENTRY (entry))
780 return GPOINTER_TO_INT (g_object_get_data (G_OBJECT(entry), "empty"));
781
782 return FALSE;
783 }
784
785 /**
786 * set the style to the entry as empty or not
787 *
788 * \param entry must be an entry
789 * \param empty TRUE or FALSE
790 *
791 * \return
792 **/
gsb_form_widget_set_empty(GtkWidget * entry,gboolean empty)793 void gsb_form_widget_set_empty (GtkWidget *entry,
794 gboolean empty)
795 {
796 GtkStyleContext* context;
797
798 if (!entry)
799 return;
800
801 if (!GTK_IS_ENTRY (entry))
802 entry = gtk_combofix_get_entry (GTK_COMBOFIX (entry));
803
804 if (!entry)
805 return;
806
807 context = gtk_widget_get_style_context (entry);
808
809 if (!empty)
810 {
811 gtk_widget_set_name (entry, "form_entry");
812 gtk_style_context_set_state (context, GTK_STATE_FLAG_NORMAL);
813 }
814 else
815 {
816 gtk_widget_set_name (entry, "form_entry_empty");
817 gtk_style_context_set_state (context, GTK_STATE_FLAG_NORMAL);
818 }
819
820 g_object_set_data (G_OBJECT(entry), "empty", GINT_TO_POINTER (empty));
821 }
822
823 /**
824 * called when an debit or credit entry get the focus,
825 * if the entry is free, set it normal and erase the help content
826 *
827 * \param entry
828 * \param ev
829 *
830 * \return FALSE
831 **/
gsb_form_widget_entry_get_focus(GtkWidget * entry,GdkEventFocus * ev,gint * ptr_origin)832 gboolean gsb_form_widget_entry_get_focus (GtkWidget *entry,
833 GdkEventFocus *ev,
834 gint *ptr_origin)
835 {
836 GtkWidget *widget;
837 GtkWidget *tmp_widget;
838 gint element_number;
839 gint account_number;
840
841 /* still not found, if change the content of the form, something come in entry
842 * which is nothing, so protect here */
843 if (!GTK_IS_WIDGET (entry) || !GTK_IS_ENTRY (entry))
844 return FALSE;
845
846 /* it clears the entry in question */
847 if (gsb_form_widget_check_empty (entry))
848 {
849 gtk_entry_set_text (GTK_ENTRY (entry), "");
850 gsb_form_widget_set_empty (entry, FALSE);
851 }
852 element_number = GPOINTER_TO_INT (ptr_origin);
853 account_number = gsb_form_get_account_number ();
854
855 switch (element_number)
856 {
857 case TRANSACTION_FORM_DEBIT :
858 /* on met old_debit = NULl car avec g_free plantage */
859 if (old_debit && strlen (old_debit) > 0)
860 old_debit = NULL;
861
862 /* save the credit if necessary */
863 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_CREDIT);
864 if (!gsb_form_widget_check_empty (widget))
865 old_credit = g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)));
866
867 /* we change the payment method to adapt it for the debit */
868 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_TYPE);
869
870 /* change the method of payment if necessary
871 * (if grey, it's a child of split so do nothing) */
872 if (widget && gtk_widget_get_sensitive (widget))
873 {
874 /* change the signe of the method of payment and the contra */
875 if (gsb_payment_method_get_combo_sign (widget) == GSB_PAYMENT_CREDIT)
876 {
877 old_credit_payment_number = gsb_payment_method_get_selected_number (widget);
878
879 tmp_widget = gsb_form_widget_get_widget (TRANSACTION_FORM_CHEQUE);
880 if (tmp_widget && gtk_widget_get_visible (tmp_widget))
881 {
882 if (old_credit_payment_content)
883 g_free (old_credit_payment_content);
884 if (gsb_form_widget_check_empty (tmp_widget) == FALSE)
885 old_credit_payment_content = g_strdup (gtk_entry_get_text (GTK_ENTRY (tmp_widget)));
886 else
887 old_credit_payment_content = NULL;
888 }
889
890 gsb_payment_method_create_combo_list (widget,
891 GSB_PAYMENT_DEBIT,
892 account_number,
893 0,
894 FALSE);
895
896 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_CONTRA);
897 if (widget && gtk_widget_get_visible (widget))
898 gsb_payment_method_create_combo_list (gsb_form_widget_get_widget (TRANSACTION_FORM_CONTRA),
899 GSB_PAYMENT_CREDIT,
900 account_number,
901 0,
902 TRUE);
903 }
904 }
905 gsb_form_check_auto_separator (entry);
906 break;
907 case TRANSACTION_FORM_CREDIT :
908 /* on met old_credit = NULl car avec g_free plantage */
909 if (old_credit && strlen (old_credit) > 0)
910 old_credit = NULL;
911
912 /* save the debit if necessary */
913 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_DEBIT);
914 if (!gsb_form_widget_check_empty (widget))
915 old_debit = g_strdup (gtk_entry_get_text (GTK_ENTRY (widget)));
916
917 /* we change the payment method to adapt it for the debit */
918 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_TYPE);
919
920 /* change the method of payment if necessary
921 * (if grey, it's a child of split so do nothing) */
922 if (widget && gtk_widget_get_sensitive (widget))
923 {
924 /* change the signe of the method of payment and the contra */
925 if (gsb_payment_method_get_combo_sign (widget) == GSB_PAYMENT_DEBIT)
926 {
927 old_debit_payment_number = gsb_payment_method_get_selected_number (widget);
928
929 tmp_widget = gsb_form_widget_get_widget (TRANSACTION_FORM_CHEQUE);
930 if (tmp_widget && gtk_widget_get_visible (tmp_widget))
931 {
932 if (old_debit_payment_content)
933 g_free (old_debit_payment_content);
934 if (gsb_form_widget_check_empty (tmp_widget) == FALSE)
935 old_debit_payment_content = g_strdup (gtk_entry_get_text (GTK_ENTRY (tmp_widget)));
936 else
937 old_debit_payment_content = NULL;
938 }
939
940 gsb_payment_method_create_combo_list (widget,
941 GSB_PAYMENT_CREDIT,
942 account_number,
943 0,
944 FALSE);
945
946 widget = gsb_form_widget_get_widget (TRANSACTION_FORM_CONTRA);
947 if (widget && gtk_widget_get_visible (widget))
948 gsb_payment_method_create_combo_list (widget,
949 GSB_PAYMENT_DEBIT,
950 account_number,
951 0,
952 TRUE);
953 }
954 }
955 gsb_form_check_auto_separator (entry);
956 break;
957 }
958
959 /* sensitive the valid and cancel buttons */
960 gsb_form_sensitive_cancel_valid_buttons (TRUE);
961
962 return FALSE;
963 }
964
965 /**
966 *
967 *
968 * \param
969 *
970 * \return
971 **/
gsb_form_widget_get_old_credit(void)972 gchar *gsb_form_widget_get_old_credit (void)
973 {
974 if (old_credit && strlen (old_credit) > 0)
975 return g_strdup (old_credit);
976 else
977 return NULL;
978 }
979
980 /**
981 *
982 *
983 * \param
984 *
985 * \return
986 **/
gsb_form_widget_get_old_debit(void)987 gchar *gsb_form_widget_get_old_debit (void)
988 {
989 if (old_debit && strlen (old_debit) > 0)
990 return g_strdup (old_debit);
991 else
992 return NULL;
993 }
994
995 /**
996 * called when entry changed
997 * check the entry and set the entry red/invalid if not a good number
998 *
999 * \param entry
1000 * \param null
1001 *
1002 * \return FALSE
1003 **/
gsb_form_widget_amount_entry_changed(GtkWidget * entry,gpointer null)1004 gboolean gsb_form_widget_amount_entry_changed (GtkWidget *entry,
1005 gpointer null)
1006 {
1007 GtkStyleContext* context;
1008 gboolean valide;
1009 gint element_number;
1010
1011 /* if we are in the form and the entry is empty, do nothing
1012 * because it's a special style too */
1013 element_number = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (entry), "element_number"));
1014
1015 if (g_strcmp0 (gsb_form_widget_get_name (element_number),
1016 gtk_entry_get_text (GTK_ENTRY (entry))) == 0)
1017 return FALSE;
1018
1019 if (gsb_form_widget_check_empty (entry))
1020 return FALSE;
1021
1022 context = gtk_widget_get_style_context (entry);
1023
1024 /* if nothing in the entry, keep the normal style */
1025 if (!strlen (gtk_entry_get_text (GTK_ENTRY (entry))))
1026 {
1027 gtk_widget_set_name (entry, "form_entry_empty");
1028 gtk_style_context_set_state (context, GTK_STATE_FLAG_NORMAL);
1029
1030 return FALSE;
1031 }
1032
1033 valide = gsb_form_widget_get_valide_amout_entry (gtk_entry_get_text (GTK_ENTRY (entry)));
1034 if (valide)
1035 {
1036 /* the entry is valid, make it normal */
1037 gtk_widget_set_name (entry, "form_entry");
1038 }
1039 else
1040 {
1041 /* the entry is not valid, make it red */
1042 gtk_widget_set_name (entry, "form_entry_error");
1043 }
1044 gtk_style_context_set_state (context, GTK_STATE_FLAG_NORMAL);
1045
1046 return FALSE;
1047 }
1048
1049 /**
1050 *
1051 *
1052 * \param
1053 *
1054 * \return
1055 **/
gsb_form_widget_get_valide_amout_entry(const gchar * string)1056 gboolean gsb_form_widget_get_valide_amout_entry (const gchar *string)
1057 {
1058 const gchar *ptr;
1059 gchar *mon_decimal_point;
1060 gunichar decimal_point;
1061 gchar *mon_thousands_sep;
1062 gunichar thousands_sep = (gunichar) -1;
1063
1064 ptr = string;
1065
1066 if ((g_utf8_strchr (ptr, -1, '*') && g_utf8_strchr (ptr, -1, '+'))
1067 ||
1068 (g_utf8_strchr (ptr, -1, '*') && g_utf8_strchr (ptr, -1, '-')))
1069 return FALSE;
1070
1071 mon_decimal_point = gsb_locale_get_mon_decimal_point ();
1072 decimal_point = g_utf8_get_char_validated (mon_decimal_point, -1);
1073 mon_thousands_sep = gsb_locale_get_mon_thousands_sep ();
1074 if (mon_thousands_sep)
1075 thousands_sep = g_utf8_get_char_validated (mon_thousands_sep, -1);
1076
1077 while (g_utf8_strlen (ptr, -1) > 0)
1078 {
1079 gunichar ch;
1080
1081 ch = g_utf8_get_char_validated (ptr, -1);
1082
1083 if (!g_unichar_isdefined (ch))
1084 {
1085 g_free (mon_decimal_point);
1086 if (mon_thousands_sep)
1087 g_free (mon_thousands_sep);
1088
1089 return FALSE;
1090 }
1091
1092 if (!g_ascii_isdigit (ch))
1093 {
1094 if (ch == 0x00A0 || ch == 0x202F/* NON-BREAK SPACE || ESPACE INSÉCABLE ÉTROITE */)
1095 {
1096 ptr = g_utf8_next_char (ptr);
1097 continue;
1098 }
1099 else if (g_unichar_isdefined (thousands_sep))
1100 {
1101 if (ch != '.' && ch != ',' && ch != '+' && ch != '-'
1102 && ch != '*' && ch != '/' && ch != thousands_sep)
1103 {
1104 g_free (mon_decimal_point);
1105 g_free (mon_thousands_sep);
1106
1107 return FALSE;
1108 }
1109
1110 if (ch == decimal_point
1111 && g_utf8_strlen (ptr, -1) == 1
1112 && g_utf8_strchr (string, -1, thousands_sep))
1113 {
1114 gchar **tab;
1115 guint i = 1; /* le premier champs peut etre < à 3 */
1116 guint nbre_champs;
1117
1118 tab = g_strsplit (string, mon_thousands_sep, 0);
1119 nbre_champs = g_strv_length (tab);
1120
1121 while (i < nbre_champs)
1122 {
1123 if (i < nbre_champs - 1 && g_utf8_strlen (tab[i], -1) != 3)
1124 {
1125 g_strfreev (tab);
1126 g_free (mon_decimal_point);
1127 g_free (mon_thousands_sep);
1128
1129 return FALSE;
1130 }
1131 else if (i == nbre_champs - 1 && g_utf8_strlen (tab[i], -1) != 4)
1132 {
1133 g_strfreev (tab);
1134 g_free (mon_decimal_point);
1135 g_free (mon_thousands_sep);
1136
1137 return FALSE;
1138 }
1139 i++;
1140 }
1141 g_strfreev (tab);
1142 }
1143 }
1144 else if (ch != '.' && ch != ',' && ch != '+' && ch != '-' && ch != '*' && ch != '/')
1145 return FALSE;
1146 }
1147
1148 ptr = g_utf8_next_char (ptr);
1149 }
1150
1151 g_free (mon_decimal_point);
1152 if (mon_thousands_sep)
1153 g_free (mon_thousands_sep);
1154
1155 return TRUE;
1156 }
1157
1158 /**
1159 *
1160 *
1161 * \param
1162 *
1163 * \return
1164 **/
gsb_form_widget_get_old_credit_payment_number(void)1165 gint gsb_form_widget_get_old_credit_payment_number (void)
1166 {
1167 return old_credit_payment_number;
1168 }
1169
1170 /**
1171 *
1172 *
1173 * \param
1174 *
1175 * \return
1176 **/
gsb_form_widget_get_old_debit_payment_number(void)1177 gint gsb_form_widget_get_old_debit_payment_number (void)
1178 {
1179 return old_debit_payment_number;
1180 }
1181
1182 /**
1183 *
1184 *
1185 * \param
1186 *
1187 * \return
1188 **/
gsb_form_widget_get_old_credit_payment_content(void)1189 const gchar *gsb_form_widget_get_old_credit_payment_content (void)
1190 {
1191 return old_credit_payment_content;
1192 }
1193
1194 /**
1195 *
1196 *
1197 * \param
1198 *
1199 * \return
1200 **/
gsb_form_widget_get_old_debit_payment_content(void)1201 const gchar *gsb_form_widget_get_old_debit_payment_content (void)
1202 {
1203 return old_debit_payment_content;
1204 }
1205
1206 /**
1207 * called when entry validated by Enter Tab lose focus
1208 * check the entry and set the entry red/invalid if not a good number
1209 *
1210 * \param entry
1211 *
1212 * \return TRUE if entry is valid
1213 **/
gsb_form_widget_amount_entry_validate(gint element_number)1214 gboolean gsb_form_widget_amount_entry_validate (gint element_number)
1215 {
1216 GtkWidget *entry;
1217 GtkStyleContext* context;
1218 const gchar *text;
1219 gchar *tmp_str;
1220 gchar *mon_decimal_point;
1221 gboolean valide;
1222 gboolean return_value;
1223
1224 entry = gsb_form_widget_get_widget (element_number);
1225 if (gsb_form_widget_check_empty (entry))
1226 return TRUE;
1227
1228 text = gtk_entry_get_text (GTK_ENTRY (entry));
1229 if (g_strcmp0 (gsb_form_widget_get_name (element_number), text) == 0)
1230 return TRUE;
1231
1232 /* if nothing in the entry, set the widget empty */
1233 if (!strlen (text))
1234 {
1235 gsb_form_widget_set_empty (entry, TRUE);
1236 return TRUE;
1237 }
1238
1239 context = gtk_widget_get_style_context (entry);
1240
1241 mon_decimal_point = gsb_locale_get_mon_decimal_point ();
1242 if (g_strrstr (text, gsb_locale_get_mon_decimal_point ()) == NULL)
1243 tmp_str = g_strconcat (text, mon_decimal_point, NULL);
1244 else
1245 tmp_str= g_strdup (text);
1246
1247 valide = gsb_form_widget_get_valide_amout_entry (tmp_str);
1248 if (valide)
1249 {
1250 /* the entry is valid, make it normal */
1251 gtk_widget_set_name (entry, "form_entry");
1252 return_value = TRUE;
1253 }
1254 else
1255 {
1256 /* the entry is not valid, make it red */
1257 gtk_widget_set_name (entry, "form_entry_error");
1258 return_value = FALSE;
1259 }
1260
1261 gtk_style_context_set_state (context, GTK_STATE_FLAG_NORMAL);
1262
1263 g_free (tmp_str);
1264 g_free (mon_decimal_point);
1265
1266 return return_value;
1267 }
1268
1269 /**
1270 * update the payee combofix in the form with the current current report
1271 *
1272 * \param report_number
1273 * \param sens FALSE remove report TRUE add report
1274 *
1275 * \return FALSE
1276 **/
gsb_form_widget_update_payee_combofix(gint report_number,gint sens)1277 gboolean gsb_form_widget_update_payee_combofix (gint report_number,
1278 gint sens)
1279 {
1280 if (sens)
1281 gtk_combofix_append_report (GTK_COMBOFIX (gsb_form_widget_get_widget
1282 (TRANSACTION_FORM_PARTY)),
1283 gsb_data_report_get_report_name (report_number));
1284 else
1285 gtk_combofix_remove_report (GTK_COMBOFIX (gsb_form_widget_get_widget
1286 (TRANSACTION_FORM_PARTY)),
1287 gsb_data_report_get_report_name (report_number));
1288
1289 return FALSE;
1290 }
1291
1292 /**
1293 * free the content of the list of structures of the form
1294 *
1295 * \param
1296 *
1297 * \return FALSE
1298 **/
gsb_form_widget_free_list_without_widgets(void)1299 gboolean gsb_form_widget_free_list_without_widgets (void)
1300 {
1301 GSList *tmp_list;
1302
1303 devel_debug (NULL);
1304
1305 if (!form_list_widgets)
1306 return FALSE;
1307
1308 tmp_list = form_list_widgets;
1309 while (tmp_list)
1310 {
1311 struct_element *element;
1312
1313 element = tmp_list->data;
1314 g_free (element);
1315 tmp_list = tmp_list->next;
1316 }
1317 g_slist_free (form_list_widgets);
1318 form_list_widgets = NULL;
1319
1320 return FALSE;
1321 }
1322
1323 /**
1324 *
1325 *
1326 * \param
1327 *
1328 * \return
1329 **/
1330 /* Local Variables: */
1331 /* c-basic-offset: 4 */
1332 /* End: */
1333
1334