1 /* ************************************************************************** */
2 /*                                                                            */
3 /*     Copyright (C)    2000-2008 Cédric Auger (cedric@grisbi.org)            */
4 /*          2003-2008 Benjamin Drieu (bdrieu@april.org)                       */
5 /*                 2009-2016 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_scheduler.c
26  * work with the form of the scheduler
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_scheduler.h"
39 #include "gsb_account.h"
40 #include "gsb_calendar_entry.h"
41 #include "gsb_combo_box.h"
42 #include "gsb_currency.h"
43 #include "dialog.h"
44 #include "gsb_data_payment.h"
45 #include "gsb_data_scheduled.h"
46 #include "utils_dates.h"
47 #include "gsb_form.h"
48 #include "gsb_form_widget.h"
49 #include "gsb_fyear.h"
50 #include "gsb_payment_method.h"
51 #include "gsb_scheduler_list.h"
52 #include "gsb_transactions_list.h"
53 #include "gtk_combofix.h"
54 #include "utils_str.h"
55 #include "structures.h"
56 #include "gsb_data_form.h"
57 #include "erreur.h"
58 /*END_INCLUDE*/
59 
60 /*START_STATIC*/
61 static void gsb_form_scheduler_free_content_list ( GSList *content_list );
62 static gboolean gsb_form_scheduler_frequency_button_changed ( GtkWidget *combo_box,
63 						       gpointer null );
64 static gint gsb_form_scheduler_get_auto ( void );
65 static GSList *gsb_form_scheduler_get_content_list ( void );
66 static gint gsb_form_scheduler_get_frequency ( void );
67 static gint gsb_form_scheduler_get_frequency_user ( void );
68 static gint gsb_form_scheduler_get_frequency_user_button ( void );
69 static GDate *gsb_form_scheduler_get_limit_date ( void );
70 static gboolean gsb_form_scheduler_set_account ( gint account_number );
71 static gboolean gsb_form_scheduler_set_auto ( gboolean automatic );
72 static void gsb_form_scheduler_set_content_list ( GSList *content_list );
73 static gboolean gsb_form_scheduler_set_frequency_user ( gint user_freq );
74 static gboolean gsb_form_scheduler_set_frequency_user_button ( gboolean automatic );
75 static gboolean gsb_form_scheduler_set_limit_date ( GDate *date );
76 /*END_STATIC*/
77 
78 /*START_EXTERN*/
79 /*END_EXTERN*/
80 
81 /**
82  * \struct
83  * associate an element number and a string value
84  * used to keed the content of the form when changing the account
85  * because the form is redrawed */
86 typedef struct {
87     gint element_number;
88     gchar *element_string;
89     gint element_int;
90 } content_element;
91 
92 /** contains the list of the scheduled elements, ie list of link
93  * between an element number and the pointer of its widget
94  * for now, this list if filled at the opening of grisbi and never erased */
95 static GSList *scheduled_element_list = NULL;
96 
97 /**
98  * used when change the account with the button, have only the new account,
99  * so can use that variable which will be set to the new account at the end
100  * of the callback when change the button (gsb_form_scheduler_change_account)
101  * */
102 static gint last_account_number = 0;
103 
104 /******************************************************************************/
105 /* Private Methods                                                            */
106 /******************************************************************************/
107 /******************************************************************************/
108 /* Public Methods                                                             */
109 /******************************************************************************/
110 /**
111  * create the scheduled part : that widgets are created at the beginning
112  * and normally never destroyed, they are showed only for
113  * scheduled transactions
114  * Cela ne fonctionne pas : tous les widgets sont détruits par la
115  * fonction gsb_form_create_widgets ( )
116  *
117  * \param table a GtkTable with the dimension SCHEDULED_HEIGHT*SCHEDULED_WIDTH to be filled
118  *
119  * \return FALSE
120  * */
gsb_form_scheduler_create(GtkWidget * table)121 gboolean gsb_form_scheduler_create ( GtkWidget *table )
122 {
123     gint row, column;
124     struct_element *element;
125 
126     devel_debug (NULL);
127     if (!table)
128         return FALSE;
129 
130     /* just in case... be sure that not created */
131     if (scheduled_element_list)
132         gsb_form_scheduler_free_list ( );
133 
134     /* ok, now fill the form
135      * we play with height and width, but for now it's fix : 6 columns and 1 line */
136     for ( row=0 ; row < SCHEDULED_HEIGHT ; row++ )
137 	for ( column=0 ; column < SCHEDULED_WIDTH ; column++ )
138 	{
139 	    gint element_number;
140 	    GtkWidget *widget = NULL;
141 	    const gchar *tooltip_text = NULL;
142 	    const gchar *text_auto [] = { N_("Manual"), N_("Automatic"), NULL };
143 	    const gchar *text_frequency [] = { N_("Once"), N_("Weekly"), N_("Monthly"), N_("Bimonthly"),
144                         N_("Quarterly"), N_("Yearly"), N_("Custom"), NULL };
145 		const gchar *text_frequency_user [] = { N_("Days"), N_("Weeks"), N_("Months"), N_("Years"), NULL };
146 
147 	    element_number = row*SCHEDULED_WIDTH + column;
148 
149 	    switch ( element_number )
150 	    {
151 		case SCHEDULED_FORM_ACCOUNT:
152 			widget = gsb_account_create_combo_list (G_CALLBACK (gsb_form_scheduler_change_account), NULL, FALSE);
153 			gtk_widget_set_hexpand (widget, TRUE);
154 			if (etat.scheduler_set_default_account)
155 			{
156 				g_signal_handlers_block_by_func (widget, gsb_form_scheduler_change_account, NULL);
157 				gsb_account_set_combo_account_number (widget, etat.scheduler_default_account_number);
158 				g_signal_handlers_unblock_by_func (widget, gsb_form_scheduler_change_account, NULL);
159 			}
160 			else
161 				gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
162 
163 			tooltip_text = _("Choose the account");
164 		    break;
165 
166 		case SCHEDULED_FORM_AUTO:
167 		    widget = gsb_combo_box_new_with_index ( text_auto, NULL, NULL );
168 			gtk_widget_set_hexpand (widget, TRUE);
169 		    tooltip_text = _("Automatic/manual scheduled transaction");
170 		    break;
171 
172 		case SCHEDULED_FORM_FREQUENCY_BUTTON:
173 		    widget = gsb_combo_box_new_with_index ( text_frequency,
174                         G_CALLBACK (gsb_form_scheduler_frequency_button_changed), NULL );
175 			gtk_widget_set_hexpand (widget, TRUE);
176 		    tooltip_text = _("Frequency");
177 		    break;
178 
179         case SCHEDULED_FORM_LIMIT_DATE:
180             widget = gsb_calendar_entry_new (FALSE);
181 			gtk_widget_set_hexpand (widget, TRUE);
182             g_signal_connect ( G_OBJECT (widget),
183                         "button-press-event",
184                         G_CALLBACK (gsb_form_scheduler_button_press_event),
185                         GINT_TO_POINTER (element_number));
186             g_signal_connect ( G_OBJECT (widget),
187                         "focus-in-event",
188                         G_CALLBACK (gsb_form_entry_get_focus),
189                         GINT_TO_POINTER (element_number));
190             g_signal_connect_after ( G_OBJECT (widget),
191                         "focus-out-event",
192                         G_CALLBACK (gsb_form_scheduler_entry_lose_focus),
193                         GINT_TO_POINTER (element_number));
194             tooltip_text = _("Limit date");
195             break;
196 
197 		case SCHEDULED_FORM_FREQUENCY_USER_ENTRY:
198 		    widget = gtk_entry_new ();
199             g_signal_connect ( G_OBJECT (widget),
200                         "focus-in-event",
201                         G_CALLBACK (gsb_form_entry_get_focus),
202                         GINT_TO_POINTER (element_number));
203             g_signal_connect_after ( G_OBJECT (widget),
204                         "focus-out-event",
205                         G_CALLBACK (gsb_form_scheduler_entry_lose_focus),
206                         GINT_TO_POINTER (element_number));
207 		    tooltip_text = _("Own frequency");
208 		    break;
209 
210 		case SCHEDULED_FORM_FREQUENCY_USER_BUTTON:
211 		    widget = gsb_combo_box_new_with_index ( text_frequency_user,
212 							    NULL, NULL );
213 		    tooltip_text = _("Custom frequency");
214 		    break;
215 	    }
216 
217 	    if (!widget)
218             continue;
219 
220 	    if (tooltip_text)
221             gtk_widget_set_tooltip_text ( GTK_WIDGET (widget),
222                         tooltip_text);
223 
224 	    /* save the element */
225 	    element = g_malloc0 (sizeof (struct_element));
226 	    element -> element_number = element_number;
227 	    element -> element_widget = widget;
228 	    scheduled_element_list = g_slist_append ( scheduled_element_list,
229                         element );
230 
231 	    /* set in the form */
232 	    gtk_grid_attach ( GTK_GRID (table), widget, column, row, 1, 1 );
233 	}
234     gsb_form_scheduler_clean ( );
235 
236     return FALSE;
237 }
238 
239 
240 /**
241  * destroy all the elements in scheduled_element_list
242  * and free the list
243  *
244  * \param
245  *
246  * \return FALSE
247  * */
gsb_form_scheduler_free_list(void)248 gboolean gsb_form_scheduler_free_list ( void )
249 {
250     GSList *list_tmp;
251 
252     devel_debug (NULL);
253 
254     if (!scheduled_element_list)
255 	return FALSE;
256 
257     list_tmp = scheduled_element_list;
258 
259     while (list_tmp)
260     {
261 	struct_element *element;
262 
263 	element = list_tmp -> data;
264 	g_free (element);
265 
266 	list_tmp = list_tmp -> next;
267     }
268     g_slist_free (scheduled_element_list);
269     scheduled_element_list =NULL;
270 
271     return FALSE;
272 }
273 
274 
275 /**
276  * callback called when changing the account from the form's button
277  * re-fill the form but keep the values
278  *
279  * \param button
280  * \param null
281  *
282  * \return FALSE
283  * */
gsb_form_scheduler_change_account(GtkWidget * button,gpointer null)284 gboolean gsb_form_scheduler_change_account ( GtkWidget *button,
285                         gpointer null )
286 {
287     gint save_transaction;
288     gint save_execute;
289     GSList *content_list;
290     gboolean is_split = FALSE;
291     GtkWidget *category_entry;
292     const gchar *tmp_str;
293     gint new_account_number;
294 
295     devel_debug (NULL);
296 
297     new_account_number = gsb_form_get_account_number ();
298 
299     /* need to check first if split (see later) */
300     category_entry = gsb_form_widget_get_widget (TRANSACTION_FORM_CATEGORY);
301     if ( category_entry )
302     {
303         tmp_str = gtk_combofix_get_text ( GTK_COMBOFIX ( category_entry) );
304         if ( gsb_form_widget_check_empty (category_entry)
305          &&
306          tmp_str
307          && strlen ( tmp_str ) > 0
308          &&
309          !strcmp ( tmp_str, _("Split of transaction") ) )
310             /* ok it's a split */
311             is_split = TRUE;
312     }
313 
314     /* problem here : when change account, the form can be changed, with new or less widgets
315      * so we fill again de form
316      * but il the user fill the form and want to change after the account, it's annoying because
317      * filling again the form will lose all the data
318      * so first save the data and after filling the form, set back the data
319      * may still a problem : if for example we set a note, go to an account without notes, and
320      * go back to an account with a note, the first content of the note will be lost but it should
321      * be very rare to do that and i think very difficult to code something to keep that... */
322     save_transaction = GPOINTER_TO_INT (g_object_get_data ( G_OBJECT ( gsb_form_get_form_widget () ),
323 							    "transaction_number_in_form" ));
324     save_execute = GPOINTER_TO_INT (g_object_get_data ( G_OBJECT (gsb_form_get_form_widget ()),
325 							"execute_scheduled"));
326     content_list = gsb_form_scheduler_get_content_list ();
327 	gsb_form_clean (new_account_number);
328 
329     /* a problem now, fill_from_account will clean the form,
330      * and make unsensitive some part of the form (method of payment...)
331      * and make sensitive some other part which could be unsensitive (for split for example)
332      * so we call gsb_form_set_sensitive, but 2 args, split or child.
333      * cannot be a child because child cannot access to the account button, so just to check
334      * if it's a split (done before)
335      */
336     gsb_form_change_sensitive_buttons (TRUE);
337     gsb_form_set_sensitive (is_split, FALSE);
338 
339     gsb_form_scheduler_set_content_list (content_list);
340     gsb_form_scheduler_free_content_list (content_list);
341 
342     g_object_set_data ( G_OBJECT ( gsb_form_get_form_widget () ),
343 			"transaction_number_in_form",
344 			GINT_TO_POINTER (save_transaction));
345     g_object_set_data ( G_OBJECT ( gsb_form_get_form_widget () ),
346 			"execute_scheduled",
347 			GINT_TO_POINTER (save_execute));
348 
349     last_account_number = new_account_number;
350     return FALSE;
351 }
352 
353 
354 /**
355  * get the content in the form, and set it in a list composed
356  * of each element with their content (list of struct content_element
357  *
358  * \param
359  *
360  * \return a newly allocated list
361  * */
gsb_form_scheduler_get_content_list(void)362 GSList *gsb_form_scheduler_get_content_list ( void )
363 {
364     GSList *content_list = NULL;
365     GSList *tmp_list;
366 
367     tmp_list = gsb_form_widget_get_list ();
368 
369     while (tmp_list)
370     {
371 	struct_element *element;
372 
373 	element = tmp_list -> data;
374 
375 	if (gtk_widget_get_visible (element -> element_widget))
376 	{
377 	    content_element *element_save;
378 
379 	    switch (element -> element_number)
380 	    {
381 		/* first, check the entries */
382 		case TRANSACTION_FORM_DATE:
383 		case TRANSACTION_FORM_VALUE_DATE:
384 		case TRANSACTION_FORM_DEBIT:
385 		case TRANSACTION_FORM_CREDIT:
386 		case TRANSACTION_FORM_NOTES:
387 		case TRANSACTION_FORM_BANK:
388 		case TRANSACTION_FORM_VOUCHER:
389 		    if (!gsb_form_widget_check_empty (element -> element_widget))
390 		    {
391 			element_save = g_malloc0 (sizeof (content_element));
392 			element_save -> element_number = element -> element_number;
393 			element_save -> element_string = my_strdup (gtk_entry_get_text (GTK_ENTRY (element -> element_widget)));
394 			content_list = g_slist_append ( content_list,
395 							element_save );
396 		    }
397 		    break;
398 
399 		case TRANSACTION_FORM_TYPE:
400 			element_save = g_malloc0 (sizeof (content_element));
401 			element_save -> element_number = element -> element_number;
402 			element_save -> element_int = gsb_payment_method_get_selected_number (element -> element_widget);
403 			content_list = g_slist_append ( content_list,
404 							element_save );
405 		    break;
406 
407 		case TRANSACTION_FORM_CONTRA:
408 			element_save = g_malloc0 (sizeof (content_element));
409 			element_save -> element_number = element -> element_number;
410 			element_save -> element_int = gsb_payment_method_get_selected_number (element -> element_widget);
411 			content_list = g_slist_append ( content_list,
412 							element_save );
413 		    break;
414 
415 		case TRANSACTION_FORM_EXERCICE:
416 			element_save = g_malloc0 (sizeof (content_element));
417 			element_save -> element_number = element -> element_number;
418 			element_save -> element_int = gsb_fyear_get_fyear_from_combobox ( element -> element_widget, NULL );
419 			content_list = g_slist_append ( content_list,
420 							element_save );
421 		    break;
422 
423 		case TRANSACTION_FORM_DEVISE:
424 			element_save = g_malloc0 (sizeof (content_element));
425 			element_save -> element_number = element -> element_number;
426 			element_save -> element_int = gsb_currency_get_currency_from_combobox (element -> element_widget);
427 			content_list = g_slist_append ( content_list,
428 							element_save );
429 		    break;
430 
431 		    /* check the combofix */
432 		case TRANSACTION_FORM_PARTY:
433 		case TRANSACTION_FORM_CATEGORY:
434 		case TRANSACTION_FORM_BUDGET:
435 		    if (!gsb_form_widget_check_empty (element -> element_widget))
436 		    {
437 				const gchar *tmp_str;
438 
439 				tmp_str = gtk_combofix_get_text (GTK_COMBOFIX (element->element_widget));
440 				element_save = g_malloc0 (sizeof (content_element));
441 				element_save->element_number = element->element_number;
442 				element_save->element_string = my_strdup (tmp_str);
443 				content_list = g_slist_append ( content_list, element_save );
444 		    }
445 		    break;
446 	    }
447 	}
448 	tmp_list = tmp_list -> next;
449     }
450     return content_list;
451 }
452 
453 
454 /**
455  * set the content in the form according to the content of the list
456  * of struct content_element given in param
457  *
458  * \param content_list the list of struct content_element
459  *
460  * \return
461  * */
gsb_form_scheduler_set_content_list(GSList * content_list)462 void gsb_form_scheduler_set_content_list ( GSList *content_list )
463 {
464     GSList *list_tmp;
465     gint account_number;
466 
467     account_number = gsb_form_scheduler_get_account ();
468 
469     list_tmp = content_list;
470 
471     /* see each saved element */
472     while (list_tmp)
473     {
474 	content_element *element;
475 	GSList *form_list;
476 
477 	element = list_tmp -> data;
478 
479 	/* normally, cannot happen */
480 	if (!element)
481 	    continue;
482 
483 	/* we look for that element in the form */
484 	form_list = gsb_form_widget_get_list ();
485 
486 	while (form_list)
487 	{
488 	    struct_element *form_element;
489 
490 	    form_element = form_list -> data;
491 
492 	    if (!gtk_widget_get_visible (form_element -> element_widget)
493 		||
494 		form_element -> element_number != element -> element_number)
495 	    {
496 		form_list = form_list -> next;
497 		continue;
498 	    }
499 
500 	    switch (form_element -> element_number)
501 	    {
502 		/* first, the entries */
503 		case TRANSACTION_FORM_DATE:
504 		case TRANSACTION_FORM_VALUE_DATE:
505 		case TRANSACTION_FORM_DEBIT:
506 		case TRANSACTION_FORM_CREDIT:
507 		case TRANSACTION_FORM_NOTES:
508 		case TRANSACTION_FORM_BANK:
509 		case TRANSACTION_FORM_VOUCHER:
510 		    gsb_form_entry_get_focus (form_element -> element_widget);
511             if ( element -> element_string )
512                 gtk_entry_set_text ( GTK_ENTRY (form_element -> element_widget),
513                                 element -> element_string );
514 		    break;
515 
516 		case TRANSACTION_FORM_TYPE:
517 		    gsb_payment_method_create_combo_list ( form_element -> element_widget,
518 							   gsb_data_payment_get_sign (element -> element_int),
519 							   account_number, 0, FALSE );
520 		    gsb_payment_method_set_combobox_history ( form_element -> element_widget,
521 							   gsb_data_payment_get_similar (element -> element_int, account_number), TRUE );
522 		    break;
523 
524 		case TRANSACTION_FORM_CONTRA:
525 		    gsb_payment_method_create_combo_list ( form_element -> element_widget,
526 							   gsb_data_payment_get_sign (element -> element_int),
527 							   account_number, 0, TRUE );
528 		    gsb_payment_method_set_combobox_history ( form_element -> element_widget,
529 							   gsb_data_payment_get_similar (element -> element_int, account_number), TRUE );
530 			break;
531 
532 		case TRANSACTION_FORM_EXERCICE:
533 		    gsb_fyear_set_combobox_history ( form_element -> element_widget,
534 						     element -> element_int );
535 		    break;
536 
537 		case TRANSACTION_FORM_DEVISE:
538 		    gsb_currency_set_combobox_history ( form_element -> element_widget,
539 							element -> element_int );
540 		    break;
541 
542 		    /* check the combofix */
543 		case TRANSACTION_FORM_PARTY:
544 		case TRANSACTION_FORM_CATEGORY:
545 		case TRANSACTION_FORM_BUDGET:
546 		    gsb_form_entry_get_focus (form_element -> element_widget);
547             if ( element -> element_string )
548                 gtk_combofix_set_text (GTK_COMBOFIX (form_element->element_widget), element->element_string);
549 		    break;
550 	    }
551 	    form_list = form_list -> next;
552 	}
553 	list_tmp = list_tmp -> next;
554     }
555 }
556 
557 
558 /**
559  * free a content list created by gsb_form_scheduler_get_content_list
560  *
561  * \param content_list
562  *
563  * \return
564  * */
gsb_form_scheduler_free_content_list(GSList * content_list)565 void gsb_form_scheduler_free_content_list ( GSList *content_list )
566 {
567     GSList *list_tmp;
568 
569     list_tmp = content_list;
570 
571     while (list_tmp)
572     {
573 	content_element *element;
574 
575 	element = list_tmp -> data;
576 
577 	/* normally, cannot happen */
578 	if (!element)
579 	    continue;
580 
581 	if (element -> element_string)
582 	    g_free (element -> element_string);
583 	g_free (element);
584 
585 	list_tmp = list_tmp -> next;
586     }
587     g_slist_free (content_list);
588 }
589 
590 /**
591  * clean the scheduled form part
592  * and set the default values
593  *
594  * \param account number
595  *
596  * \return FALSE
597  * */
gsb_form_scheduler_clean(void)598 gboolean gsb_form_scheduler_clean ( void )
599 {
600     gint column;
601     GtkWidget *widget;
602 
603     devel_debug (NULL);
604 
605     /* set to NULL the execute flag */
606     g_object_set_data ( G_OBJECT (gsb_form_get_form_widget ()),
607 			"execute_scheduled", NULL );
608 
609     /* first we show it, becaus hidden when execute a scheduled transaction */
610     if (gsb_form_get_origin () == ORIGIN_VALUE_SCHEDULED)
611 	gtk_widget_show (gsb_form_get_scheduler_part ());
612 
613     /* clean the scheduled widget */
614     for ( column = 0 ; column < SCHEDULED_FORM_MAX_WIDGETS ; column++ )
615     {
616 	widget = gsb_form_scheduler_get_element_widget (column);
617 
618 	/* some widgets can be set unsensitive because of the children of splits,
619 	 * so resensitive all to be sure */
620 	if (widget)
621 	{
622 	    switch (column)
623 	    {
624 		case SCHEDULED_FORM_ACCOUNT:
625 			if (etat.scheduler_set_default_account)
626 			{
627 				g_signal_handlers_block_by_func (widget, gsb_form_scheduler_change_account, NULL);
628 				gsb_account_set_combo_account_number (widget, etat.scheduler_default_account_number);
629 				g_signal_handlers_unblock_by_func (widget, gsb_form_scheduler_change_account, NULL);
630 			}
631 			else
632 				gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
633 			gtk_widget_set_sensitive ( widget, FALSE );
634 			break;
635 
636 		case SCHEDULED_FORM_AUTO:
637 		case SCHEDULED_FORM_FREQUENCY_USER_BUTTON:
638 		    gtk_combo_box_set_active ( GTK_COMBO_BOX (widget), 0 );
639 		    gtk_widget_set_sensitive ( widget, FALSE );
640 		    break;
641 
642 		case SCHEDULED_FORM_FREQUENCY_BUTTON:
643 			g_signal_handlers_block_by_func (widget, gsb_form_scheduler_frequency_button_changed, NULL);
644 			gtk_combo_box_set_active ( GTK_COMBO_BOX (widget), 0 );
645 			gtk_widget_set_sensitive ( widget, FALSE );
646 			g_signal_handlers_unblock_by_func (widget, gsb_form_scheduler_frequency_button_changed, NULL);
647 		    break;
648 
649 		case SCHEDULED_FORM_LIMIT_DATE:
650 		    gsb_form_widget_set_empty ( widget, TRUE );
651 		    gtk_entry_set_text ( GTK_ENTRY ( widget ),
652 					 _("Limit date") );
653 		    gtk_widget_set_sensitive ( widget, TRUE );
654 		    break;
655 
656 		case SCHEDULED_FORM_FREQUENCY_USER_ENTRY:
657 		    gsb_form_widget_set_empty ( widget, TRUE );
658 		    gtk_entry_set_text ( GTK_ENTRY ( widget ),
659 					 _("Own frequency") );
660 		    gtk_widget_set_sensitive ( widget, TRUE );
661 		    break;
662 	    }
663 	}
664     }
665     return FALSE;
666 }
667 
668 /**
669  * sensitive the buttons of the scheduler part of the form
670  *
671  * \param sensitive TRUE or FALSE
672  *
673  * \return FALSE
674  * */
gsb_form_scheduler_sensitive_buttons(gboolean sensitive)675 gboolean gsb_form_scheduler_sensitive_buttons ( gboolean sensitive )
676 {
677     gint column;
678 
679     devel_debug_int (sensitive);
680 
681     /* clean the scheduled widget */
682     for ( column = 0 ; column < SCHEDULED_FORM_MAX_WIDGETS ; column++ )
683     {
684 	GtkWidget *widget;
685 
686 	widget = gsb_form_scheduler_get_element_widget (column);
687 
688 	if (widget)
689 	{
690 	    switch (column)
691 	    {
692 		case SCHEDULED_FORM_ACCOUNT:
693 		case SCHEDULED_FORM_AUTO:
694 		case SCHEDULED_FORM_FREQUENCY_BUTTON:
695 		case SCHEDULED_FORM_FREQUENCY_USER_BUTTON:
696 		    gtk_widget_set_sensitive ( widget,
697 					       sensitive );
698 		    break;
699 	    }
700 	}
701     }
702     return FALSE;
703 }
704 
705 
706 
707 /**
708  * set the scheduler part of the form from the scheduled transaction given in param
709  *
710  * \param scheduled_number
711  *
712  * \return FALSE
713  * */
gsb_form_scheduler_set(gint scheduled_number)714 gboolean gsb_form_scheduler_set ( gint scheduled_number )
715 {
716     devel_debug_int (scheduled_number);
717 
718     gsb_form_scheduler_sensitive_buttons (TRUE);
719 
720     /* if we are on a white split line, set all as the mother */
721     if (scheduled_number < -1)
722 	scheduled_number = gsb_data_scheduled_get_mother_scheduled_number (scheduled_number);
723 
724     gsb_form_scheduler_set_account ( gsb_data_scheduled_get_account_number (scheduled_number));
725     gsb_form_scheduler_set_auto ( gsb_data_scheduled_get_automatic_scheduled (scheduled_number));
726     gsb_form_scheduler_set_frequency ( gsb_data_scheduled_get_frequency (scheduled_number));
727     gsb_form_scheduler_set_limit_date ( gsb_data_scheduled_get_limit_date (scheduled_number));
728     gsb_form_scheduler_set_frequency_user ( gsb_data_scheduled_get_user_entry (scheduled_number));
729     gsb_form_scheduler_set_frequency_user_button ( gsb_data_scheduled_get_user_interval (scheduled_number));
730     return FALSE;
731 }
732 
733 
734 /**
735  * fill the scheduled transaction given in param with the content of
736  * the scheduled part of the form (ie frequency...)
737  *
738  * \param scheduled_number
739  *
740  * \return FALSE
741  * */
gsb_form_scheduler_get_scheduler_part(gint scheduled_number)742 gboolean gsb_form_scheduler_get_scheduler_part ( gint scheduled_number )
743 {
744     if (!scheduled_number)
745 	return FALSE;
746 
747     /* needn't to fill the account number because set while creating the scheduled transaction */
748     gsb_data_scheduled_set_account_number (scheduled_number,
749 					   gsb_form_scheduler_get_account ());
750     gsb_data_scheduled_set_automatic_scheduled ( scheduled_number,
751 						 gsb_form_scheduler_get_auto ());
752     gsb_data_scheduled_set_frequency ( scheduled_number,
753 				       gsb_form_scheduler_get_frequency ());
754     gsb_data_scheduled_set_limit_date ( scheduled_number,
755 					gsb_form_scheduler_get_limit_date ());
756     gsb_data_scheduled_set_user_interval ( scheduled_number,
757 					   gsb_form_scheduler_get_frequency_user_button ());
758     gsb_data_scheduled_set_user_entry ( scheduled_number,
759 					gsb_form_scheduler_get_frequency_user ());
760     return FALSE;
761 }
762 
763 
764 /**
765  * return the widget of the element_number given in param,
766  * for the scheduler part of the form
767  *
768  * \param element_number
769  *
770  * \return a GtkWidget * or NULL
771  * */
gsb_form_scheduler_get_element_widget(gint element_number)772 GtkWidget *gsb_form_scheduler_get_element_widget ( gint element_number )
773 {
774     return gsb_form_get_element_widget_from_list ( element_number,
775                         scheduled_element_list );
776 }
777 
778 
779 /**
780  * called when we press the button in an entry field in
781  * the form for the scheduled part
782  *
783  * \param entry which receive the signal
784  * \param ev can be NULL
785  * \param ptr_origin a pointer to int on the element_number
786  *
787  * \return FALSE
788  * */
gsb_form_scheduler_button_press_event(GtkWidget * entry,GdkEventButton * ev,gint * ptr_origin)789 gboolean gsb_form_scheduler_button_press_event ( GtkWidget *entry,
790                         GdkEventButton *ev,
791                         gint *ptr_origin )
792 {
793     GtkWidget *date_entry;
794 
795     /* set the form sensitive */
796     gsb_form_change_sensitive_buttons (TRUE);
797 
798     /* set the current date into the date entry except if there is already something into the value date */
799     date_entry = gsb_form_widget_get_widget (TRANSACTION_FORM_DATE);
800     if ( gsb_form_widget_check_empty (date_entry))
801     {
802         gtk_entry_set_text ( GTK_ENTRY (date_entry),
803                      gsb_date_today ( ) );
804         gsb_form_widget_set_empty ( date_entry, FALSE );
805     }
806     return FALSE;
807 }
808 
809 
810 /**
811  * called when an entry lose the focus in the scheduled part
812  *
813  * \param entry
814  * \param ev
815  * \param ptr_origin a pointer gint which is the number of the element
816  *
817  * \return FALSE
818  * */
gsb_form_scheduler_entry_lose_focus(GtkWidget * entry,GdkEventFocus * ev,gint * ptr_origin)819 gboolean gsb_form_scheduler_entry_lose_focus ( GtkWidget *entry,
820                         GdkEventFocus *ev,
821                         gint *ptr_origin )
822 {
823     gchar *string;
824     gint element_number;
825 
826     /* remove the selection */
827     gtk_editable_select_region ( GTK_EDITABLE ( entry ), 0, 0 );
828     element_number = GPOINTER_TO_INT ( ptr_origin );
829 
830     /* string will be filled only if the field is empty */
831     string = NULL;
832 
833     switch ( element_number )
834     {
835 	case  SCHEDULED_FORM_LIMIT_DATE:
836 	    if ( !strlen ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ) )
837         {
838             gsb_form_widget_set_empty ( entry, TRUE );
839             string = _("Limit date");
840         }
841 	    break;
842 
843 	case  SCHEDULED_FORM_FREQUENCY_USER_ENTRY:
844 	    if ( !strlen ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ) )
845             string = _("Own frequency");
846 	    break;
847 
848 	default :
849 	    break;
850     }
851 
852     /* if string is not NULL, the entry is empty so set the empty field to TRUE */
853 
854     if ( string )
855     {
856         gtk_entry_set_text ( GTK_ENTRY ( entry ), string );
857         gsb_form_widget_set_empty ( entry, TRUE );
858     }
859     return FALSE;
860 }
861 
862 
863 
864 /**
865  * called when the frequency button is changed
866  * show/hide the necessary widget according to its state
867  *
868  * \param combo_box
869  *
870  * \return FALSE
871  * */
gsb_form_scheduler_frequency_button_changed(GtkWidget * combo_box,gpointer null)872 gboolean gsb_form_scheduler_frequency_button_changed ( GtkWidget *combo_box,
873 						       gpointer null )
874 {
875     gchar *selected_item;
876 
877     selected_item = gsb_combo_box_get_active_text ( GTK_COMBO_BOX ( combo_box ) );
878 
879     if ( !strcmp ( selected_item,
880 		   _("Once")))
881     {
882 	gtk_widget_hide (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_LIMIT_DATE));
883 	gtk_widget_hide (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_ENTRY));
884 	gtk_widget_hide (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_BUTTON));
885     }
886     else
887     {
888 	gtk_widget_show (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_LIMIT_DATE));
889 	if ( !strcmp ( selected_item,
890 		       _("Custom")))
891 	{
892 	    gtk_widget_show (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_ENTRY));
893 	    gtk_widget_show (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_BUTTON));
894 	}
895 	else
896 	{
897 	    gtk_widget_hide (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_ENTRY));
898 	    gtk_widget_hide (gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_BUTTON));
899 	}
900     }
901     g_free (selected_item);
902     return FALSE;
903 }
904 
905 
906 /**
907  * get the account number from the scheduled button and return it
908  *
909  * \param
910  *
911  * \return the account number or -2 if problem
912  * */
gsb_form_scheduler_get_account(void)913 gint gsb_form_scheduler_get_account ( void )
914 {
915     gint account_number;
916     GtkWidget *button;
917 
918     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_ACCOUNT);
919     /* if no account button, go away... */
920     if (!button)
921 	return -2;
922 
923     account_number = gsb_account_get_combo_account_number (button);
924 
925     if (account_number == -1)
926 	return -2;
927     return account_number;
928 }
929 
930 /**
931  * set the account in the account button
932  * this will automatickly change the content of the form
933  *
934  * \param account_number
935  *
936  * \return FALSE if not done, TRUE if ok
937  * */
gsb_form_scheduler_set_account(gint account_number)938 gboolean gsb_form_scheduler_set_account ( gint account_number )
939 {
940     GtkTreeIter iter;
941     GtkWidget *button;
942     GtkTreeModel *model;
943 
944     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_ACCOUNT);
945     /* if no account button, go away... */
946     if (!button)
947 	return FALSE;
948 
949     model = gtk_combo_box_get_model ( GTK_COMBO_BOX (button));
950 
951     if ( gtk_tree_model_get_iter_first (model, &iter))
952     {
953 	do
954 	{
955 	    gint number;
956 
957 	    gtk_tree_model_get ( model, &iter,
958 				 1, &number,
959 				 -1 );
960 	    if (number == account_number)
961 	    {
962 		gtk_combo_box_set_active_iter ( GTK_COMBO_BOX (button),
963 						&iter );
964 		return TRUE;
965 	    }
966 	}
967 	while (gtk_tree_model_iter_next (model, &iter));
968     }
969     return FALSE;
970 }
971 
972 
973 /**
974  * get the automatic/manual mode from the form's button
975  *
976  * \param
977  *
978  * \return TRUE if automatic, FALSE if manual, -1 if nothing selected (normaly should not append)
979  * */
gsb_form_scheduler_get_auto(void)980 gint gsb_form_scheduler_get_auto ( void )
981 {
982     GtkWidget *button;
983 
984     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_AUTO);
985     /* if no automatic button, go away... */
986     if (!button)
987 	return FALSE;
988 
989     return gsb_combo_box_get_index (button);
990 }
991 
992 
993 /**
994  * set the automatic/manual mode on the form's button
995  *
996  * \param automatic TRUE to set automatic, FALSE to set manual
997  *
998  * \return TRUE if ok, FALSE else
999  * */
gsb_form_scheduler_set_auto(gboolean automatic)1000 gboolean gsb_form_scheduler_set_auto ( gboolean automatic )
1001 {
1002     GtkWidget *button;
1003 
1004     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_AUTO);
1005     /* if no automatic button, go away... */
1006     if (!button)
1007 	return FALSE;
1008 
1009     return gsb_combo_box_set_index ( button,
1010 				     automatic );
1011 }
1012 
1013 
1014 /**
1015  * get the frequency from the form's button
1016  *
1017  * \param
1018  *
1019  * \return SCHEDULER_PERIODICITY_x_VIEW (see gsb_scheduler_list.h), -1 if nothing selected (normaly should not append)
1020  * */
gsb_form_scheduler_get_frequency(void)1021 gint gsb_form_scheduler_get_frequency ( void )
1022 {
1023     GtkWidget *button;
1024 
1025     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_BUTTON);
1026     /* if no automatic button, go away... */
1027     if (!button)
1028 	return FALSE;
1029 
1030     return gsb_combo_box_get_index (button);
1031 }
1032 
1033 
1034 /**
1035  * set the frequency on the form's button
1036  *
1037  * \param frequency SCHEDULER_PERIODICITY_x_VIEW (see gsb_scheduler_list.h)
1038  *
1039  * \return TRUE if ok, FALSE else
1040  * */
gsb_form_scheduler_set_frequency(gint frequency)1041 gboolean gsb_form_scheduler_set_frequency ( gint frequency )
1042 {
1043     GtkWidget *button;
1044 
1045     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_BUTTON);
1046     /* if no automatic button, go away... */
1047     if (!button)
1048 	return FALSE;
1049 
1050     return gsb_combo_box_set_index ( button,
1051 				     frequency );
1052 }
1053 
1054 
1055 /**
1056  * get the limit date from the form's scheduled part
1057  *
1058  * \param
1059  *
1060  * \return a GDate or NULL if nothing into the entry or problem
1061  * */
gsb_form_scheduler_get_limit_date(void)1062 GDate *gsb_form_scheduler_get_limit_date ( void )
1063 {
1064     GtkWidget *entry;
1065     GDate *date;
1066 
1067     entry = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_LIMIT_DATE);
1068     /* if no entry, go away... */
1069     if (!entry
1070 	||
1071 	gsb_form_widget_check_empty (entry)
1072 	||
1073 	!gtk_widget_get_visible (entry))
1074 	return NULL;
1075 
1076     date = gsb_calendar_entry_get_date (entry);
1077     return date;
1078 }
1079 
1080 
1081 /**
1082  * set the limit date in the form's scheduled part
1083  *
1084  * \param date a GDate or NULL if we want to free the entry
1085  *
1086  * \return TRUE if ok, FALSE else
1087  * */
gsb_form_scheduler_set_limit_date(GDate * date)1088 gboolean gsb_form_scheduler_set_limit_date ( GDate *date )
1089 {
1090     GtkWidget *entry;
1091 
1092     entry = gsb_form_scheduler_get_element_widget ( SCHEDULED_FORM_LIMIT_DATE );
1093 
1094     /* if no entry, go away... */
1095     if (!entry || !gtk_widget_get_visible ( entry ) )
1096         return FALSE;
1097 
1098     if ( !date )
1099     {
1100         gsb_form_widget_set_empty ( entry, TRUE );
1101         gtk_entry_set_text ( GTK_ENTRY ( entry ), _("Limit date") );
1102     }
1103     else
1104     {
1105         gsb_calendar_entry_set_date ( entry, date );
1106         gsb_form_widget_set_empty (entry, FALSE);
1107     }
1108 
1109     return TRUE;
1110 }
1111 
1112 
1113 /**
1114  * get the user frequency from the form's scheduled part
1115  *
1116  * \param
1117  *
1118  * \return a gint contains the user frequency
1119  * */
gsb_form_scheduler_get_frequency_user(void)1120 gint gsb_form_scheduler_get_frequency_user ( void )
1121 {
1122     GtkWidget *entry;
1123 
1124     entry = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_ENTRY);
1125     /* if no entry, go away... */
1126     if (!entry
1127 	||
1128 	gsb_form_widget_check_empty (entry))
1129 	return 0;
1130 
1131     return utils_str_atoi (gtk_entry_get_text (GTK_ENTRY (entry)));
1132 }
1133 
1134 
1135 /**
1136  * set the user frequency in the form's scheduled part
1137  *
1138  * \param user_freq the user frequency number
1139  *
1140  * \return TRUE if ok, FALSE else
1141  * */
gsb_form_scheduler_set_frequency_user(gint user_freq)1142 gboolean gsb_form_scheduler_set_frequency_user ( gint user_freq )
1143 {
1144     GtkWidget *entry;
1145     gchar *string;
1146 
1147     entry = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_ENTRY);
1148     /* if no entry, go away... */
1149     if (!entry
1150 	||
1151 	!gtk_widget_get_visible (entry))
1152 	return FALSE;
1153 
1154     string = utils_str_itoa (user_freq);
1155     if (!string)
1156 	return FALSE;
1157 
1158     gsb_form_widget_set_empty (entry, FALSE);
1159     gtk_entry_set_text ( GTK_ENTRY (entry), string);
1160     g_free ( string ) ;
1161 
1162     return TRUE;
1163 }
1164 
1165 
1166 /**
1167  * get the user frequency from the form's button
1168  *
1169  * \param
1170  *
1171  * \return 0 : Days, 1 : Months, 2 : Years, -1 if nothing selected (normaly should not append)
1172  * */
gsb_form_scheduler_get_frequency_user_button(void)1173 gint gsb_form_scheduler_get_frequency_user_button ( void )
1174 {
1175     GtkWidget *button;
1176 
1177     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_BUTTON);
1178     /* if no automatic button, go away... */
1179     if (!button)
1180 	return FALSE;
1181 
1182     return gsb_combo_box_get_index (button);
1183 }
1184 
1185 
1186 /**
1187  * set the user frequency on the form's button
1188  *
1189  * \param frequency 0 : Days, 1 : Months, 2 : Years
1190  *
1191  * \return TRUE if ok, FALSE else
1192  * */
gsb_form_scheduler_set_frequency_user_button(gboolean automatic)1193 gboolean gsb_form_scheduler_set_frequency_user_button ( gboolean automatic )
1194 {
1195     GtkWidget *button;
1196 
1197     button = gsb_form_scheduler_get_element_widget(SCHEDULED_FORM_FREQUENCY_USER_BUTTON);
1198     /* if no automatic button, go away... */
1199     if (!button
1200 	||
1201 	!gtk_widget_get_visible (button))
1202 	return FALSE;
1203 
1204     return gsb_combo_box_set_index ( button,
1205 				     automatic );
1206 }
1207 
1208 
1209 /**
1210  * Clone the children of a splitted transaction to add the to the new splitted scheduled
1211  *
1212  * \param scheduled_transaction		the splitted scheduled transaction we want to add the children
1213  * \param transaction_number		the splitted transaction we want to clone the children
1214  *
1215  * \return FALSE
1216  * */
gsb_form_scheduler_recover_splits_of_transaction(gint scheduled_transaction,gint transaction_number)1217 gboolean gsb_form_scheduler_recover_splits_of_transaction ( gint scheduled_transaction,
1218 							    gint transaction_number )
1219 {
1220     GSList *tmp_list;
1221 
1222     /* first clone the transactions */
1223     gsb_transactions_list_splitted_to_scheduled (transaction_number, scheduled_transaction);
1224 
1225     /* add the children to the list */
1226     tmp_list = gsb_data_scheduled_get_scheduled_list ();
1227     while (tmp_list)
1228     {
1229 	gint scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list -> data);
1230 
1231 	if (gsb_data_scheduled_get_mother_scheduled_number (scheduled_number) == scheduled_transaction)
1232 	    gsb_scheduler_list_append_new_scheduled (scheduled_number, NULL);
1233 	tmp_list = tmp_list -> next;
1234     }
1235     return FALSE;
1236 }
1237 
1238 /**
1239  * set fixed date if available for the scheduled transaction
1240  *
1241  * \param	sheduled number
1242  * \param	date
1243  *
1244  * \return
1245  **/
gsb_form_scheduler_get_last_day_of_month_dialog(gint scheduled_number,GDate * date)1246 gint gsb_form_scheduler_get_last_day_of_month_dialog (gint scheduled_number,
1247 													  GDate *date)
1248 {
1249 	GtkWidget *dialog = NULL;
1250 	gchar *msg;
1251 	gchar *tmp_str;
1252 	GDateDay day;
1253 	gint fixed_date = 0;
1254 	gint result;
1255 
1256 	day = g_date_get_day (date);
1257 	tmp_str = g_strdup_printf (_("Keep the %d"), day);
1258 	msg = g_strdup_printf (_("Do you want to keep the \"%d\" as the date or to force the last day of the month?\n\n"), day);
1259 
1260 	dialog = dialogue_special_no_run (GTK_MESSAGE_QUESTION,
1261 									  GTK_BUTTONS_NONE,
1262 									  msg,
1263 									  _("This is the last day of the month"));
1264 
1265 	gtk_dialog_add_buttons (GTK_DIALOG(dialog),
1266 							tmp_str, GTK_RESPONSE_NO,
1267 							_("Force the last day of the month"), GTK_RESPONSE_YES,
1268 							NULL);
1269 
1270 	result = gtk_dialog_run (GTK_DIALOG (dialog));
1271 
1272 	if (result == GTK_RESPONSE_YES)
1273 	{
1274 		fixed_date = 31;
1275 	}
1276 	else
1277 	{
1278 		fixed_date = day;
1279 	}
1280 
1281 	g_free (tmp_str);
1282 	g_free (msg);
1283 	gtk_widget_destroy (dialog);
1284 
1285 	return fixed_date;
1286 }
1287 
1288 /**
1289  *
1290  *
1291  * \param
1292  *
1293  * \return
1294  **/
1295 /* Local Variables: */
1296 /* c-basic-offset: 4 */
1297 /* End: */
1298 
1299