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