1 /* ************************************************************************** */
2 /* */
3 /* Copyright (C) 2000-2008 Cédric Auger (cedric@grisbi.org) */
4 /* 2004-2008 Benjamin Drieu (bdrieu@april.org) */
5 /* 2009 Thomas Peel (thomas.peel@live.fr) */
6 /* 2008-2021 Pierre Biava (grisbi@pierre.biava.name) */
7 /* https://www.grisbi.org/ */
8 /* */
9 /* This program is free software; you can redistribute it and/or modify */
10 /* it under the terms of the GNU General Public License as published by */
11 /* the Free Software Foundation; either version 2 of the License, or */
12 /* (at your option) any later version. */
13 /* */
14 /* This program is distributed in the hope that it will be useful, */
15 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
16 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
17 /* GNU General Public License for more details. */
18 /* */
19 /* You should have received a copy of the GNU General Public License */
20 /* along with this program; if not, write to the Free Software */
21 /* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
22 /* */
23 /* ************************************************************************** */
24
25 /* \file gsb_scheduler_list.c : functions for the scheduled list */
26
27
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "include.h"
34 #include <gdk/gdkkeysyms.h>
35 #include <glib/gi18n.h>
36
37 /*START_INCLUDE*/
38 #include "gsb_scheduler_list.h"
39 #include "bet_data_finance.h"
40 #include "bet_finance_ui.h"
41 #include "dialog.h"
42 #include "grisbi_app.h"
43 #include "gsb_automem.h"
44 #include "gsb_calendar.h"
45 #include "gsb_data_account.h"
46 #include "gsb_data_category.h"
47 #include "gsb_data_currency.h"
48 #include "gsb_data_payee.h"
49 #include "gsb_data_scheduled.h"
50 #include "gsb_dirs.h"
51 #include "gsb_file.h"
52 #include "gsb_form.h"
53 #include "gsb_form_scheduler.h"
54 #include "gsb_real.h"
55 #include "gsb_rgba.h"
56 #include "gsb_scheduler.h"
57 #include "gsb_transactions_list.h"
58 #include "menu.h"
59 #include "mouse.h"
60 #include "navigation.h"
61 #include "structures.h"
62 #include "traitement_variables.h"
63 #include "utils.h"
64 #include "utils_dates.h"
65 #include "utils_real.h"
66 #include "utils_str.h"
67 #include "erreur.h"
68 /*END_INCLUDE*/
69
70 /*START_GLOBAL*/
71 /* lists of number of scheduled transactions taken or to be taken */
72 GSList * scheduled_transactions_to_take;
73 GSList * scheduled_transactions_taken;
74 /*END_GLOBAL*/
75
76 /*START_EXTERN*/
77 /*END_EXTERN*/
78
79 /*START_STATIC*/
80 /* the total of % of scheduled columns can be > 100 because all the columns are not showed at the same time */
81 static gint scheduler_col_width_init[SCHEDULER_COL_VISIBLE_COLUMNS] = {10, 12, 36, 12, 12, 24, 12};
82
83 /* used to save and restore the width of the scheduled list */
84 static gint scheduler_col_width[SCHEDULER_COL_VISIBLE_COLUMNS];
85 static gint scheduler_current_tree_view_width = 0;
86
87 /* set the tree view and models as static, we can access to them
88 * by the functions gsb_scheduler_list_get_tree_view...
89 * don't call them directly */
90 static GtkWidget * tree_view_scheduler_list;
91 static GtkTreeModel * tree_model_scheduler_list;
92 static GtkTreeModelSort * tree_model_sort_scheduler_list;
93 static GtkSortType sort_type;
94 static GtkTreeViewColumn * scheduler_list_column[SCHEDULER_COL_VISIBLE_COLUMNS];
95 static gint last_scheduled_number;
96
97 /* première ope planifiee de la liste */
98 static gint first_scheduler_list_number = -1;
99
100 /* toolbar */
101 static GtkWidget * scheduler_toolbar;
102
103 /* Used to display/hide comments in scheduler list */
104 static GtkWidget * scheduler_display_hide_notes = NULL;
105
106 /* here are the 3 buttons on the scheduler toolbar
107 * which can been unsensitive or sensitive */
108 static GtkWidget * scheduler_button_execute = NULL;
109 static GtkWidget * scheduler_button_delete = NULL;
110 static GtkWidget * scheduler_button_edit = NULL;
111
112 /* popup view menu */
113 static const gchar * periodicity_names[] = {N_("Unique view"), N_("Week view"), N_("Month view"),
114 N_("Two months view"), N_("Quarter view"),
115 N_("Year view"), N_("Custom view"), NULL,};
116
117 static gboolean view_menu_block_cb = FALSE;
118
119 static const gchar * j_m_a_names[] = {N_("days"), N_("weeks"), N_("months"), N_("years"), NULL};
120 /*END_STATIC*/
121
122 /******************************************************************************/
123 /* Private functions */
124 /******************************************************************************/
125 /**
126 * called when the user choose a custom periodicity on the toolbar
127 *
128 * \param
129 *
130 * \return TRUE : did his choice, FALSE : cancel the choice
131 **/
gsb_scheduler_list_popup_custom_periodicity_dialog(void)132 static gboolean gsb_scheduler_list_popup_custom_periodicity_dialog (void)
133 {
134 GtkWidget *combobox;
135 GtkWidget *dialog;
136 GtkWidget *entry;
137 GtkWidget *hbox;
138 GtkWidget *hbox2;
139 GtkWidget *label;
140 GtkWidget *paddingbox;
141 int i;
142
143 dialog = gtk_dialog_new_with_buttons (_("Show scheduled transactions"),
144 GTK_WINDOW (grisbi_app_get_active_window (NULL)),
145 GTK_DIALOG_MODAL,
146 "gtk-cancel", GTK_RESPONSE_CANCEL,
147 "gtk-apply", GTK_RESPONSE_OK,
148 NULL);
149
150 gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER_ON_PARENT);
151 gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
152
153 /* Ugly dance to avoid side effects on dialog's vbox. */
154 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
155 gtk_box_pack_start (GTK_BOX (dialog_get_content_area (dialog)), hbox, FALSE, FALSE, 0);
156 paddingbox = new_paddingbox_with_title (hbox, TRUE, _("Scheduler frequency"));
157 gtk_container_set_border_width (GTK_CONTAINER (hbox), MARGIN_BOX);
158 gtk_container_set_border_width (GTK_CONTAINER (paddingbox), MARGIN_BOX);
159
160 hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
161 gtk_box_pack_start (GTK_BOX (paddingbox), hbox2, FALSE, FALSE, 0);
162
163 label = gtk_label_new (_("Show transactions for the next: "));
164 gtk_box_pack_start (GTK_BOX (hbox2), label, FALSE, FALSE, 0);
165 entry = gsb_automem_spin_button_new (&etat.affichage_echeances_perso_nb_libre, NULL, NULL);
166 gtk_box_pack_start (GTK_BOX (hbox2), entry, FALSE, FALSE, MARGIN_BOX);
167
168 /* combobox for userdefined frequency */
169 combobox = gtk_combo_box_text_new ();
170 gtk_box_pack_start (GTK_BOX (hbox2), combobox, FALSE, FALSE, 0);
171
172 for (i = 0; j_m_a_names[i]; i++)
173 {
174 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combobox), g_dgettext (NULL, j_m_a_names[i]));
175 }
176 gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), etat.affichage_echeances_perso_j_m_a);
177
178 gtk_widget_show_all (dialog);
179
180 switch (gtk_dialog_run (GTK_DIALOG (dialog)))
181 {
182 case GTK_RESPONSE_OK:
183 etat.affichage_echeances_perso_j_m_a = gtk_combo_box_get_active (GTK_COMBO_BOX (combobox));
184 etat.affichage_echeances_perso_nb_libre = utils_str_atoi (gtk_entry_get_text (GTK_ENTRY(entry)));
185 gtk_widget_destroy (dialog);
186 return TRUE;
187 }
188
189 gtk_widget_destroy (dialog);
190 return FALSE;
191 }
192
193 /**
194 * called from the toolbar to change the scheduler view
195 *
196 * \param periodicity the new view wanted
197 * \param item not used
198 *
199 * \return FALSE
200 **/
gsb_scheduler_list_change_scheduler_view(GtkWidget * item,gpointer pointer_periodicity)201 static void gsb_scheduler_list_change_scheduler_view (GtkWidget *item,
202 gpointer pointer_periodicity)
203 {
204 gchar *tmp_str;
205 gint periodicity;
206
207 periodicity = GPOINTER_TO_INT (pointer_periodicity);
208 if (view_menu_block_cb || periodicity == etat.affichage_echeances)
209 return;
210
211 if (periodicity == SCHEDULER_PERIODICITY_CUSTOM_VIEW)
212 {
213 if (!gsb_scheduler_list_popup_custom_periodicity_dialog ())
214 return;
215 }
216
217 tmp_str = g_strconcat (_("Scheduled transactions"), " : ",
218 g_dgettext (NULL, periodicity_names[periodicity]),
219 NULL);
220 grisbi_win_headings_update_title (tmp_str);
221 grisbi_win_headings_update_suffix ("");
222 g_free (tmp_str);
223
224 etat.affichage_echeances = periodicity;
225 gsb_scheduler_list_fill_list (gsb_scheduler_list_get_tree_view ());
226 gsb_scheduler_list_set_background_color (gsb_scheduler_list_get_tree_view ());
227 gsb_scheduler_list_select (-1);
228
229 gsb_file_set_modified (TRUE);
230
231 return;
232 }
233
234 /**
235 * Called to edit a specific transaction but the number of transaction
236 * is passed via a pointer (by g_signal_connect)
237 *
238 * \param scheduled_number a pointer which is the number of the transaction
239 *
240 * \return FALSE
241 **/
gsb_scheduler_list_edit_transaction_by_pointer(gint * scheduled_number)242 static gboolean gsb_scheduler_list_edit_transaction_by_pointer (gint *scheduled_number)
243 {
244 gint number;
245
246 number = GPOINTER_TO_INT (scheduled_number);
247 devel_debug_int (number);
248
249 if (number == -1)
250 gsb_scheduler_list_select (-1);
251 gsb_scheduler_list_edit_transaction (number);
252
253 return FALSE;
254 }
255
256 /**
257 * change the showed information on the list :
258 * either show the frequency and mode of the scheduled
259 * either show the notes
260 *
261 * \param
262 *
263 * \return FALSE
264 */
gsb_scheduler_list_show_notes(GtkWidget * item)265 static gboolean gsb_scheduler_list_show_notes (GtkWidget *item)
266 {
267 if (scheduler_display_hide_notes)
268 {
269 GrisbiAppConf *a_conf;
270
271 a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
272 if (a_conf->display_toolbar != GSB_BUTTON_ICON)
273 {
274 if (etat.affichage_commentaire_echeancier)
275 gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), _("Frequency/Mode"));
276 else
277 gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), _("Notes"));
278 }
279
280 if (etat.affichage_commentaire_echeancier)
281 gtk_widget_set_tooltip_text (GTK_WIDGET (item),
282 _("Display the frequency and mode of scheduled transactions"));
283 else
284 gtk_widget_set_tooltip_text (GTK_WIDGET (item),
285 _("Display the notes of scheduled transactions"));
286 }
287
288 gtk_tree_view_column_set_visible (GTK_TREE_VIEW_COLUMN (scheduler_list_column[COL_NB_FREQUENCY]),
289 !etat.affichage_commentaire_echeancier);
290 gtk_tree_view_column_set_visible (GTK_TREE_VIEW_COLUMN (scheduler_list_column[COL_NB_MODE]),
291 !etat.affichage_commentaire_echeancier);
292 gtk_tree_view_column_set_visible (GTK_TREE_VIEW_COLUMN (scheduler_list_column[COL_NB_NOTES]),
293 etat.affichage_commentaire_echeancier);
294
295 etat.affichage_commentaire_echeancier = !etat.affichage_commentaire_echeancier;
296
297 return FALSE;
298 }
299
300 /**
301 * Pop up a menu with several actions to apply to current scheduled.
302 *
303 * \param
304 *
305 * \return
306 **/
gsb_scheduler_list_popup_scheduled_context_menu(GtkWidget * tree_view,GtkTreePath * path)307 static void gsb_scheduler_list_popup_scheduled_context_menu (GtkWidget *tree_view,
308 GtkTreePath *path)
309 {
310 GtkWidget *menu;
311 GtkWidget *menu_item;
312 GtkTreeModel *model;
313 GtkTreeIter iter;
314 gint scheduled_number;
315 gint virtual_transaction;
316
317 menu = gtk_menu_new ();
318
319 /* Récupération des données de la ligne sélectionnée */
320 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
321 gtk_tree_model_get_iter (model, &iter, path);
322 gtk_tree_model_get (model,
323 &iter,
324 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_transaction,
325 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &scheduled_number,
326 -1);
327
328 if (virtual_transaction)
329 scheduled_number = 0;
330
331 /* Edit transaction */
332 menu_item = GTK_WIDGET (utils_menu_item_new_from_image_label ("gtk-edit-16.png", _("Edit transaction")));
333 g_signal_connect_swapped (G_OBJECT (menu_item),
334 "activate",
335 G_CALLBACK (gsb_scheduler_list_edit_transaction_by_pointer),
336 GINT_TO_POINTER (scheduled_number));
337 if (scheduled_number <= 0)
338 gtk_widget_set_sensitive (menu_item, FALSE);
339
340 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
341
342 /* Clone transaction */
343 menu_item = GTK_WIDGET (utils_menu_item_new_from_image_label ("gtk-copy-16.png", _("Clone transaction")));
344 g_signal_connect (G_OBJECT (menu_item),
345 "activate",
346 G_CALLBACK (gsb_scheduler_list_clone_selected_scheduled),
347 GINT_TO_POINTER (scheduled_number));
348 if (scheduled_number <= 0)
349 gtk_widget_set_sensitive (menu_item, FALSE);
350
351 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
352
353 /* Separator */
354 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ());
355
356 /* New transaction */
357 menu_item = GTK_WIDGET (utils_menu_item_new_from_image_label ("gsb-new-transaction-16.png",
358 _("New transaction")));
359 g_signal_connect_swapped (G_OBJECT (menu_item),
360 "activate",
361 G_CALLBACK (gsb_scheduler_list_edit_transaction_by_pointer),
362 GINT_TO_POINTER (-1));
363 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
364
365 /* Delete transaction */
366 menu_item = GTK_WIDGET (utils_menu_item_new_from_image_label ("gtk-delete-16.png", _("Delete transaction")));
367 g_signal_connect (G_OBJECT (menu_item),
368 "activate",
369 G_CALLBACK (gsb_scheduler_list_delete_scheduled_transaction_by_menu),
370 NULL);
371
372 if (scheduled_number <= 0)
373 gtk_widget_set_sensitive (menu_item, FALSE);
374
375 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
376
377 /* Separator */
378 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ());
379
380 /* Display/hide notes */
381 if (etat.affichage_commentaire_echeancier)
382 menu_item = GTK_WIDGET (utils_menu_item_new_from_image_label ("gsb-comments-16.png", _("Displays notes")));
383 else
384 menu_item = GTK_WIDGET (utils_menu_item_new_from_image_label ("gsb-comments-16.png",
385 _("Displays Frequency/Mode")));
386
387 g_signal_connect_swapped (G_OBJECT (menu_item),
388 "activate",
389 G_CALLBACK (gsb_scheduler_list_show_notes),
390 scheduler_display_hide_notes);
391 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
392
393 /* Separator */
394 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ());
395
396 /* Execute transaction */
397 menu_item = utils_menu_item_new_from_image_label ("gtk-execute-16.png",_("Execute transaction"));
398 g_signal_connect_swapped (G_OBJECT (menu_item),
399 "activate",
400 G_CALLBACK (gsb_scheduler_list_execute_transaction),
401 NULL);
402 if (scheduled_number <= 0)
403 gtk_widget_set_sensitive (menu_item, FALSE);
404
405 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
406
407 /* Finish all. */
408 gtk_widget_show_all (menu);
409
410 #if GTK_CHECK_VERSION (3,22,0)
411 gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
412 #else
413 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, 3, gtk_get_current_event_time());
414 #endif
415 }
416
417 /**
418 * called when the selection of the list change
419 *
420 * \param selection
421 * \param null not used
422 *
423 * \return FALSE
424 **/
gsb_scheduler_list_select_line(GtkWidget * tree_view,GtkTreePath * path)425 static void gsb_scheduler_list_select_line (GtkWidget *tree_view,
426 GtkTreePath *path)
427 {
428 GtkTreeModel *model;
429 GtkTreeIter iter;
430 gint virtual_transaction;
431 gint tmp_number = 0;
432 gint account_number;
433 GrisbiAppConf *a_conf;
434
435 devel_debug (NULL);
436 a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
437
438 /* Récupération des données de la ligne sélectionnée */
439 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
440 gtk_tree_model_get_iter (model, &iter, path);
441 gtk_tree_model_get (model,
442 &iter,
443 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_transaction,
444 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &tmp_number,
445 -1);
446
447 if (virtual_transaction)
448 tmp_number = 0;
449
450 /* protect last_scheduled_number because when refill the list, set selection to 0 and so last_scheduled_number... */
451 last_scheduled_number = tmp_number;
452
453 /* if a_conf->show_transaction_selected_in_form => edit the scheduled transaction */
454 if (tmp_number != 0 && a_conf->show_transaction_selected_in_form)
455 gsb_scheduler_list_edit_transaction (tmp_number);
456 else if (tmp_number == 0)
457 {
458 gsb_form_scheduler_clean ();
459 account_number = gsb_data_scheduled_get_account_number (tmp_number);
460 gsb_form_clean (account_number);
461 }
462
463 /* sensitive/unsensitive the button execute */
464 gtk_widget_set_sensitive (scheduler_button_execute,
465 (tmp_number > 0)
466 && !gsb_data_scheduled_get_mother_scheduled_number (tmp_number));
467
468 /* sensitive/unsensitive the button edit */
469 gtk_widget_set_sensitive (scheduler_button_edit, (tmp_number > 0));
470
471 /* sensitive/unsensitive the button delete */
472 gtk_widget_set_sensitive (scheduler_button_delete, (tmp_number > 0));
473
474 gsb_menu_set_menus_select_scheduled_sensitive (tmp_number > 0);
475 }
476
477 /**
478 * called when we press a button on the list
479 *
480 * \param tree_view
481 * \param ev
482 *
483 * \return FALSE
484 **/
gsb_scheduler_list_button_press(GtkWidget * tree_view,GdkEventButton * ev)485 static gboolean gsb_scheduler_list_button_press (GtkWidget *tree_view,
486 GdkEventButton *ev)
487 {
488 if (ev->button == RIGHT_BUTTON)
489 {
490 GtkTreePath *path = NULL;
491
492 /* show the popup */
493 if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree_view ), ev->x, ev->y, &path, NULL, NULL, NULL))
494 {
495 gsb_scheduler_list_popup_scheduled_context_menu (tree_view, path);
496 gtk_tree_path_free (path);
497 }
498 }
499
500 else if (ev->type == GDK_2BUTTON_PRESS)
501 {
502 /* if double-click => edit the scheduled transaction */
503 gint current_scheduled_number;
504
505 current_scheduled_number = gsb_scheduler_list_get_current_scheduled_number ();
506
507 if (current_scheduled_number)
508 gsb_scheduler_list_edit_transaction (current_scheduled_number);
509 }
510 else if (ev->button == LEFT_BUTTON)
511 {
512 GtkTreePath *path = NULL;
513
514 /* select line */
515 if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (tree_view ), ev->x, ev->y, &path, NULL, NULL, NULL))
516 {
517 gsb_scheduler_list_select_line (tree_view, path);
518 gtk_tree_path_free (path);
519 }
520 }
521
522 return FALSE;
523 }
524
525 /**
526 * affichage du popup view menu
527 *
528 * \param button
529 * \param event
530 * \param user data
531 *
532 * \return
533 */
gsb_scheduler_list_popup_scheduler_view(GtkWidget * button,GdkEvent * event,gpointer user_data)534 static gboolean gsb_scheduler_list_popup_scheduler_view (GtkWidget *button,
535 GdkEvent *event,
536 gpointer user_data)
537 {
538 GtkWidget *menu, *item;
539 GSList *group = NULL;
540 gint nbre_echeances;
541 gint i;
542
543 view_menu_block_cb = TRUE;
544 menu = gtk_menu_new ();
545
546 /* on enlève la ligne blanche */
547 nbre_echeances = gtk_tree_model_iter_n_children (tree_model_scheduler_list, NULL) - 1;
548
549 for (i = 0 ; periodicity_names[i] ; i++)
550 {
551 gchar *tmp_str;
552
553 if (i == etat.affichage_echeances)
554 {
555 if (i == SCHEDULER_PERIODICITY_CUSTOM_VIEW)
556 {
557 tmp_str = g_strdup_printf ("%s (%d - %d %s)",
558 g_dgettext (NULL, periodicity_names[i]),
559 nbre_echeances,
560 etat.affichage_echeances_perso_nb_libre,
561 g_dgettext (NULL,
562 j_m_a_names[etat.affichage_echeances_perso_j_m_a]));
563 }
564 else
565 {
566 tmp_str = g_strdup_printf ("%s (%d)",
567 g_dgettext (NULL, periodicity_names[i]),
568 nbre_echeances);
569 }
570 item = gtk_radio_menu_item_new_with_label (group, tmp_str);
571
572 g_free (tmp_str);
573 }
574 else
575 item = gtk_radio_menu_item_new_with_label (group, g_dgettext (NULL, periodicity_names[i]));
576
577 group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (item));
578 if (i == etat.affichage_echeances)
579 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE);
580
581 g_signal_connect (G_OBJECT (item),
582 "toggled",
583 G_CALLBACK (gsb_scheduler_list_change_scheduler_view),
584 GINT_TO_POINTER (i));
585
586 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
587 }
588
589 gtk_widget_show_all (menu);
590 #if GTK_CHECK_VERSION (3,22,0)
591 gtk_menu_popup_at_pointer (GTK_MENU (menu), NULL);
592 #else
593 gtk_menu_popup (GTK_MENU (menu), NULL, button, set_popup_position, button, 1, gtk_get_current_event_time ());
594 #endif
595 view_menu_block_cb = FALSE;
596
597 return TRUE;
598 }
599
600 /**
601 * default sorting function for scheduler list :
602 * sort by date, the column number 0
603 * perhaps later sort by different columns ??
604 *
605 * \param
606 * \param
607 * \param
608 * \param
609 *
610 * \return the result of comparison
611 **/
gsb_scheduler_list_default_sort_function(GtkTreeModel * model,GtkTreeIter * iter_1,GtkTreeIter * iter_2,gpointer null)612 static gint gsb_scheduler_list_default_sort_function (GtkTreeModel *model,
613 GtkTreeIter *iter_1,
614 GtkTreeIter *iter_2,
615 gpointer null)
616 {
617 GDate *date_1;
618 GDate *date_2;
619 gchar *date_str;
620 gint number_1;
621 gint number_2;
622 gint return_value = 0;
623
624 /* first, we sort by date (col 0) */
625 gtk_tree_model_get (model,
626 iter_1,
627 COL_NB_DATE, &date_str,
628 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &number_1,
629 -1);
630 date_1 = gsb_parse_date_string (date_str);
631 g_free (date_str);
632
633 gtk_tree_model_get (model,
634 iter_2,
635 COL_NB_DATE, &date_str,
636 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &number_2,
637 -1);
638 date_2 = gsb_parse_date_string (date_str);
639 g_free (date_str);
640
641 if (number_1 == -1)
642 {
643 if (date_1) g_date_free (date_1);
644 if (date_2) g_date_free (date_2);
645 if (sort_type == GTK_SORT_ASCENDING)
646 return 1;
647 else
648 return -1;
649 }
650 else if (number_2 == -1)
651 {
652 if (date_1) g_date_free (date_1);
653 if (date_2) g_date_free (date_2);
654 if (sort_type == GTK_SORT_ASCENDING)
655 return -1;
656 else
657 return 1;
658 }
659
660 if (date_1 && date_2)
661 return_value = g_date_compare (date_1, date_2);
662
663 if (return_value)
664 {
665 if (date_1) g_date_free (date_1);
666 if (date_2) g_date_free (date_2);
667
668 return return_value;
669 }
670 /* if we are here it's because we are in a child of split */
671 if (number_1 < 0)
672 {
673 if (sort_type == GTK_SORT_ASCENDING)
674 return 1;
675 else
676 return -1;
677 }
678 if (number_2 < 0)
679 {
680 if (sort_type == GTK_SORT_ASCENDING)
681 return -1;
682 else
683 return 1;
684 }
685
686 if (!return_value)
687 return_value = number_1 - number_2;
688
689 if (date_1) g_date_free (date_1);
690 if (date_2) g_date_free (date_2);
691
692 return return_value;
693 }
694
695 /**
696 *
697 *
698 * \param
699 * \param
700 *
701 * \return
702 **/
gsb_scheduler_list_sort_column_clicked(GtkTreeViewColumn * tree_view_column,gint * column_ptr)703 static gboolean gsb_scheduler_list_sort_column_clicked (GtkTreeViewColumn *tree_view_column,
704 gint *column_ptr)
705 {
706 gint current_column;
707 gint new_column;
708
709 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (tree_model_sort_scheduler_list),
710 ¤t_column,
711 &sort_type);
712
713 new_column = GPOINTER_TO_INT (column_ptr);
714
715 /* if the new column is the same as the old one, we change the sort type */
716 if (new_column == current_column)
717 {
718 if (sort_type == GTK_SORT_ASCENDING)
719 sort_type = GTK_SORT_DESCENDING;
720 else
721 sort_type = GTK_SORT_ASCENDING;
722 }
723 else
724 /* we sort by another column, so sort type by default is descending */
725 sort_type = GTK_SORT_ASCENDING;
726
727 gtk_tree_view_column_set_sort_indicator (scheduler_list_column[current_column], FALSE);
728 gtk_tree_view_column_set_sort_indicator (scheduler_list_column[new_column], TRUE);
729
730 gtk_tree_view_column_set_sort_order (scheduler_list_column[new_column], sort_type);
731 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (tree_model_sort_scheduler_list),
732 new_column,
733 sort_type);
734
735 gsb_scheduler_list_set_background_color (gsb_scheduler_list_get_tree_view ());
736
737 if (last_scheduled_number > 0)
738 gsb_scheduler_list_select (last_scheduled_number);
739 else
740 gsb_scheduler_list_select (-1);
741
742 return FALSE;
743 }
744
745 /**
746 *
747 *
748 * \param
749 * \param
750 * \param
751 * \param
752 *
753 * \return
754 **/
gsb_scheduler_list_sort_function_by_account(GtkTreeModel * model,GtkTreeIter * iter_1,GtkTreeIter * iter_2,gint * column_ptr)755 static gint gsb_scheduler_list_sort_function_by_account (GtkTreeModel *model,
756 GtkTreeIter *iter_1,
757 GtkTreeIter *iter_2,
758 gint *column_ptr)
759 {
760 gchar *str_1;
761 gchar *str_2;
762 gint number_1;
763 gint number_2;
764 gint virtual_op_1 = 0;
765 gint virtual_op_2 = 0;
766 gint return_value = 0;
767
768 /* first, we sort by account (col 0) */
769 gtk_tree_model_get (model,
770 iter_1,
771 COL_NB_ACCOUNT, &str_1,
772 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &number_1,
773 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_op_1,
774 -1);
775
776 gtk_tree_model_get (model,
777 iter_2,
778 COL_NB_ACCOUNT, &str_2,
779 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &number_2,
780 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_op_2,
781 -1);
782
783 if (number_1 == -1)
784 {
785 if (sort_type == GTK_SORT_ASCENDING)
786 return 1;
787 else
788 return -1;
789 }
790 else if (number_2 == -1)
791 {
792 if (sort_type == GTK_SORT_ASCENDING)
793 return -1;
794 else
795 return 1;
796 }
797
798 if (sort_type == GTK_SORT_ASCENDING)
799 return_value = virtual_op_1 - virtual_op_2;
800 else
801 return_value = virtual_op_2 - virtual_op_1;
802
803 if (return_value)
804 return return_value;
805
806 if (str_1)
807 {
808 if (str_2)
809 return_value = g_utf8_collate (str_1, str_2);
810 else
811 {
812 g_free (str_1);
813 return -1;
814 }
815 }
816 else if (str_2)
817 {
818 g_free (str_2);
819 if (sort_type == GTK_SORT_ASCENDING)
820 return 1;
821 else
822 return -1;
823 }
824
825 if (return_value == 0)
826 return_value = number_1 - number_2;
827
828 g_free (str_1);
829 g_free (str_2);
830
831 return return_value;
832 }
833
834 /**
835 *
836 *
837 * \param
838 * \param
839 * \param
840 * \param
841 *
842 * \return
843 **/
gsb_scheduler_list_sort_function_by_payee(GtkTreeModel * model,GtkTreeIter * iter_1,GtkTreeIter * iter_2,gint * column_ptr)844 static gint gsb_scheduler_list_sort_function_by_payee (GtkTreeModel *model,
845 GtkTreeIter *iter_1,
846 GtkTreeIter *iter_2,
847 gint *column_ptr)
848 {
849 gchar *str_1;
850 gchar *str_2;
851 gint number_1;
852 gint number_2;
853 gint virtual_op_1 = 0;
854 gint virtual_op_2 = 0;
855 gint return_value = 0;
856
857 /* first, we sort by payee (col 0) */
858 gtk_tree_model_get (model,
859 iter_1,
860 COL_NB_PARTY, &str_1,
861 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &number_1,
862 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_op_1,
863 -1);
864
865 gtk_tree_model_get (model,
866 iter_2,
867 COL_NB_PARTY, &str_2,
868 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &number_2,
869 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_op_2,
870 -1);
871
872 if (number_1 == -1)
873 {
874 if (sort_type == GTK_SORT_ASCENDING)
875 return 1;
876 else
877 return -1;
878 }
879 else if (number_2 == -1)
880 {
881 if (sort_type == GTK_SORT_ASCENDING)
882 return -1;
883 else
884 return 1;
885 }
886
887 if (sort_type == GTK_SORT_ASCENDING)
888 return_value = virtual_op_1 - virtual_op_2;
889 else
890 return_value = virtual_op_2 - virtual_op_1;
891
892 if (return_value)
893 return return_value;
894
895 if (str_1)
896 {
897 if (str_2)
898 return_value = g_utf8_collate (str_1, str_2);
899 else
900 {
901 g_free (str_1);
902 return -1;
903 }
904 }
905 else if (str_2)
906 {
907 g_free (str_2);
908 if (sort_type == GTK_SORT_ASCENDING)
909 return 1;
910 else
911 return -1;
912 }
913
914 if (return_value == 0)
915 return_value = number_1 - number_2;
916
917 g_free (str_1);
918 g_free (str_2);
919
920 return return_value;
921 }
922
923 /**
924 * create and append the columns of the tree_view
925 *
926 * \param tree_view the tree_view
927 *
928 * \return
929 **/
gsb_scheduler_list_create_list_columns(GtkWidget * tree_view)930 static void gsb_scheduler_list_create_list_columns (GtkWidget *tree_view)
931 {
932 gint i;
933 const gchar *scheduler_titles[] = {N_("Date"), N_("Account"), N_("Payee"),
934 N_("Frequency"), N_("Mode"), N_("Notes"), N_("Amount")};
935 gfloat col_justs[] =
936 {
937 COLUMN_CENTER, COLUMN_LEFT, COLUMN_LEFT, COLUMN_CENTER,
938 COLUMN_CENTER, COLUMN_LEFT, COLUMN_RIGHT, COLUMN_RIGHT
939 };
940
941 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS ; i++)
942 {
943 GtkCellRenderer *cell_renderer;
944
945 cell_renderer = gtk_cell_renderer_text_new ();
946
947 gtk_cell_renderer_set_alignment (GTK_CELL_RENDERER (cell_renderer), col_justs[i], 0);
948 switch (i)
949 {
950 case 0:
951 scheduler_list_column[i] = gtk_tree_view_column_new_with_attributes (gettext (scheduler_titles[i]),
952 cell_renderer,
953 "text", i,
954 "cell-background-rgba",
955 SCHEDULER_COL_NB_BACKGROUND,
956 "font-desc",
957 SCHEDULER_COL_NB_FONT,
958 "foreground",
959 SCHEDULER_COL_NB_TEXT_COLOR,
960 NULL);
961 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (tree_model_sort_scheduler_list),
962 i,
963 (GtkTreeIterCompareFunc) gsb_scheduler_list_default_sort_function,
964 NULL,
965 NULL);
966 gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (scheduler_list_column[i]), TRUE);
967
968 /* use the click to sort the list */
969 g_signal_connect (G_OBJECT (scheduler_list_column[i]),
970 "clicked",
971 G_CALLBACK (gsb_scheduler_list_sort_column_clicked),
972 GINT_TO_POINTER (i));
973 break;
974 case 1:
975 scheduler_list_column[i] = gtk_tree_view_column_new_with_attributes (gettext (scheduler_titles[i]),
976 cell_renderer,
977 "text", i,
978 "cell-background-rgba",
979 SCHEDULER_COL_NB_BACKGROUND,
980 "font-desc",
981 SCHEDULER_COL_NB_FONT,
982 "foreground",
983 SCHEDULER_COL_NB_TEXT_COLOR,
984 NULL);
985 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (tree_model_sort_scheduler_list),
986 i,
987 (GtkTreeIterCompareFunc) gsb_scheduler_list_sort_function_by_account,
988 NULL,
989 NULL);
990 gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (scheduler_list_column[i]), TRUE);
991
992 /* use the click to sort the list */
993 g_signal_connect (G_OBJECT (scheduler_list_column[i]),
994 "clicked",
995 G_CALLBACK (gsb_scheduler_list_sort_column_clicked),
996 GINT_TO_POINTER (i));
997 break;
998 case 2:
999 scheduler_list_column[i] = gtk_tree_view_column_new_with_attributes (gettext (scheduler_titles[i]),
1000 cell_renderer,
1001 "text", i,
1002 "cell-background-rgba",
1003 SCHEDULER_COL_NB_BACKGROUND,
1004 "font-desc",
1005 SCHEDULER_COL_NB_FONT,
1006 "foreground",
1007 SCHEDULER_COL_NB_TEXT_COLOR,
1008 NULL);
1009 gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (tree_model_sort_scheduler_list),
1010 i,
1011 (GtkTreeIterCompareFunc) gsb_scheduler_list_sort_function_by_payee,
1012 NULL,
1013 NULL);
1014 gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (scheduler_list_column[i]), TRUE);
1015
1016 /* use the click to sort the list */
1017 g_signal_connect (G_OBJECT (scheduler_list_column[i]),
1018 "clicked",
1019 G_CALLBACK (gsb_scheduler_list_sort_column_clicked),
1020 GINT_TO_POINTER (i));
1021 break;
1022 case 3:
1023 scheduler_list_column[i] = gtk_tree_view_column_new_with_attributes (gettext (scheduler_titles[i]),
1024 cell_renderer,
1025 "text", i,
1026 "cell-background-rgba",
1027 SCHEDULER_COL_NB_BACKGROUND,
1028 "font-desc",
1029 SCHEDULER_COL_NB_FONT,
1030 "foreground",
1031 SCHEDULER_COL_NB_TEXT_COLOR,
1032 NULL);
1033 break;
1034 case 4:
1035 scheduler_list_column[i] = gtk_tree_view_column_new_with_attributes (gettext (scheduler_titles[i]),
1036 cell_renderer,
1037 "text", i,
1038 "cell-background-rgba",
1039 SCHEDULER_COL_NB_BACKGROUND,
1040 "font-desc",
1041 SCHEDULER_COL_NB_FONT,
1042 "foreground",
1043 SCHEDULER_COL_NB_TEXT_COLOR,
1044 NULL);
1045 break;
1046 case 5:
1047 scheduler_list_column[i] = gtk_tree_view_column_new_with_attributes (gettext (scheduler_titles[i]),
1048 cell_renderer,
1049 "text", i,
1050 "cell-background-rgba",
1051 SCHEDULER_COL_NB_BACKGROUND,
1052 "font-desc",
1053 SCHEDULER_COL_NB_FONT,
1054 "foreground",
1055 SCHEDULER_COL_NB_TEXT_COLOR,
1056 NULL);
1057 break;
1058 case 6:
1059 scheduler_list_column[i] = gtk_tree_view_column_new_with_attributes (gettext (scheduler_titles[i]),
1060 cell_renderer,
1061 "text", i,
1062 "cell-background-rgba",
1063 SCHEDULER_COL_NB_BACKGROUND,
1064 "foreground",
1065 SCHEDULER_COL_NB_AMOUNT_COLOR,
1066 "font-desc",
1067 SCHEDULER_COL_NB_FONT,
1068 NULL);
1069 gtk_cell_renderer_set_padding (GTK_CELL_RENDERER (cell_renderer), MARGIN_BOX, 0);
1070 break;
1071 }
1072
1073 gtk_tree_view_column_set_alignment (GTK_TREE_VIEW_COLUMN (scheduler_list_column[i]), col_justs[i]);
1074
1075 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
1076 GTK_TREE_VIEW_COLUMN (scheduler_list_column[i]));
1077
1078 /* automatic and resizeable sizing */
1079 gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (scheduler_list_column[i]),
1080 GTK_TREE_VIEW_COLUMN_FIXED);
1081 gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN (scheduler_list_column[i]), TRUE);
1082 }
1083 }
1084
1085 /**
1086 * set the scheduler tree_model
1087 *
1088 * \param model
1089 *
1090 * \return
1091 **/
gsb_scheduler_list_set_model(GtkTreeModel * model)1092 static void gsb_scheduler_list_set_model (GtkTreeModel *model)
1093 {
1094 tree_model_scheduler_list = model;
1095 }
1096
1097 /**
1098 * set the scheduler tree model sort
1099 *
1100 * \param tree_model_sort
1101 *
1102 * \return
1103 **/
gsb_scheduler_list_set_sorted_model(GtkTreeModelSort * tree_model_sort)1104 static void gsb_scheduler_list_set_sorted_model (GtkTreeModelSort *tree_model_sort)
1105 {
1106 tree_model_sort_scheduler_list = tree_model_sort;
1107 }
1108
1109 /**
1110 * create and return the tree store of the scheduler list
1111 *
1112 * \param
1113 *
1114 * \return a gtk_tree_store
1115 **/
gsb_scheduler_list_create_model(void)1116 static GtkTreeModel *gsb_scheduler_list_create_model (void)
1117 {
1118 GtkTreeStore *store;
1119 GtkTreeModel *sortable;
1120
1121 store = gtk_tree_store_new (SCHEDULER_COL_NB_TOTAL,
1122 G_TYPE_STRING, /* COL_NB_DATE */
1123 G_TYPE_STRING, /* COL_NB_ACCOUNT */
1124 G_TYPE_STRING, /* COL_NB_PARTY */
1125 G_TYPE_STRING, /* COL_NB_FREQUENCY */
1126 G_TYPE_STRING, /* COL_NB_MODE */
1127 G_TYPE_STRING, /* COL_NB_NOTES */
1128 G_TYPE_STRING, /* COL_NB_AMOUNT */
1129 GDK_TYPE_RGBA, /* SCHEDULER_COL_NB_BACKGROUND */
1130 GDK_TYPE_RGBA, /* SCHEDULER_COL_NB_SAVE_BACKGROUND */
1131 G_TYPE_STRING, /* SCHEDULER_COL_NB_AMOUNT_COLOR */
1132 G_TYPE_INT, /* SCHEDULER_COL_NB_TRANSACTION_NUMBER */
1133 PANGO_TYPE_FONT_DESCRIPTION, /* SCHEDULER_COL_NB_FONT */
1134 G_TYPE_INT, /* SCHEDULER_COL_NB_VIRTUAL_TRANSACTION */
1135 G_TYPE_STRING); /* SCHEDULER_COL_NB_TEXT_COLOR */
1136
1137 gsb_scheduler_list_set_model (GTK_TREE_MODEL (store));
1138 sortable = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1139 gsb_scheduler_list_set_sorted_model (GTK_TREE_MODEL_SORT (sortable));
1140 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (tree_model_sort_scheduler_list), 0, GTK_SORT_ASCENDING);
1141 gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sortable),
1142 (GtkTreeIterCompareFunc) gsb_scheduler_list_default_sort_function,
1143 NULL,
1144 NULL);
1145
1146 return sortable;
1147 }
1148
1149 /**
1150 * Create the toolbar that contains all elements needed to manipulate
1151 * the scheduler.
1152 *
1153 * \param
1154 *
1155 * \return A newly created hbox.
1156 **/
gsb_scheduler_list_create_toolbar(void)1157 static GtkWidget *gsb_scheduler_list_create_toolbar (void)
1158 {
1159 GtkWidget *toolbar;
1160 GtkToolItem *item;
1161
1162 toolbar = gtk_toolbar_new ();
1163
1164 /* new scheduled button */
1165 item = utils_buttons_tool_button_new_from_image_label ("gsb-new-scheduled-24.png", _("New scheduled"));
1166 gtk_widget_set_tooltip_text (GTK_WIDGET (item),
1167 _("Prepare form to create a new scheduled transaction"));
1168 g_signal_connect_swapped (G_OBJECT (item),
1169 "clicked",
1170 G_CALLBACK (gsb_scheduler_list_edit_transaction),
1171 GINT_TO_POINTER (-1));
1172 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
1173
1174 /* delete button */
1175 scheduler_button_delete = GTK_WIDGET (utils_buttons_tool_button_new_from_image_label ("gtk-delete-24.png",
1176 _("Delete")));
1177 gtk_widget_set_sensitive (scheduler_button_delete, FALSE);
1178 gtk_widget_set_tooltip_text (GTK_WIDGET (scheduler_button_delete),
1179 _("Delete selected scheduled transaction"));
1180 g_signal_connect (G_OBJECT (scheduler_button_delete),
1181 "clicked",
1182 G_CALLBACK (gsb_scheduler_list_delete_scheduled_transaction_by_menu),
1183 NULL);
1184 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (scheduler_button_delete), -1);
1185
1186 /* edit button */
1187 scheduler_button_edit = GTK_WIDGET (utils_buttons_tool_button_new_from_image_label ("gtk-edit-24.png", _("Edit")));
1188 gtk_widget_set_sensitive (scheduler_button_edit, FALSE);
1189 gtk_widget_set_tooltip_text (GTK_WIDGET (scheduler_button_edit), _("Edit selected transaction"));
1190 g_signal_connect_swapped (G_OBJECT (scheduler_button_edit),
1191 "clicked",
1192 G_CALLBACK (gsb_scheduler_list_edit_transaction),
1193 0);
1194 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (scheduler_button_edit), -1);
1195
1196 /* Display/hide comments */
1197 scheduler_display_hide_notes = GTK_WIDGET (utils_buttons_tool_button_new_from_image_label ("gsb-comments-24.png",
1198 _("Notes")));
1199 gtk_widget_set_tooltip_text (GTK_WIDGET (scheduler_display_hide_notes),
1200 _("Display the notes of scheduled transactions"));
1201 g_signal_connect (G_OBJECT (scheduler_display_hide_notes),
1202 "clicked",
1203 G_CALLBACK (gsb_scheduler_list_show_notes),
1204 NULL);
1205 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (scheduler_display_hide_notes), -1);
1206
1207 /* Execute transaction */
1208 scheduler_button_execute = GTK_WIDGET (utils_buttons_tool_button_new_from_image_label ("gtk-execute-24.png",
1209 _("Execute")));
1210 gtk_widget_set_sensitive (scheduler_button_execute, FALSE);
1211 gtk_widget_set_tooltip_text (GTK_WIDGET (scheduler_button_execute), _("Execute current scheduled transaction"));
1212 g_signal_connect_swapped (G_OBJECT (scheduler_button_execute),
1213 "clicked",
1214 G_CALLBACK (gsb_scheduler_list_execute_transaction),
1215 NULL);
1216 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), GTK_TOOL_ITEM (scheduler_button_execute), -1);
1217
1218 /* View button */
1219 item = utils_buttons_tool_button_new_from_image_label ("gtk-select-color-24.png", _("View"));
1220 gtk_widget_set_tooltip_text (GTK_WIDGET (item),
1221 _("Change display mode of scheduled transaction list"));
1222 g_signal_connect (G_OBJECT (item),
1223 "clicked",
1224 G_CALLBACK (gsb_scheduler_list_popup_scheduler_view),
1225 NULL);
1226 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
1227
1228 return toolbar;
1229 }
1230
1231 /**
1232 * return the scheduler tree_model
1233 *
1234 * \param
1235 *
1236 * \return the scheduler tree_model
1237 **/
gsb_scheduler_list_get_model(void)1238 static GtkTreeModel *gsb_scheduler_list_get_model (void)
1239 {
1240 return tree_model_scheduler_list;
1241 }
1242
1243 /**
1244 * get the iter of the scheduled transaction given in param
1245 *
1246 * \param scheduled_number
1247 *
1248 * \return a newly allocated GtkTreeIter or NULL if not found
1249 **/
gsb_scheduler_list_get_iter_from_scheduled_number(gint scheduled_number)1250 static GtkTreeIter *gsb_scheduler_list_get_iter_from_scheduled_number (gint scheduled_number)
1251 {
1252 GtkTreeIter iter;
1253 GtkTreeModel *model;
1254
1255 model = GTK_TREE_MODEL (gsb_scheduler_list_get_model ());
1256
1257 if (!scheduled_number || !model)
1258 return NULL;
1259
1260 /* we go through the list in the model untill we find the transaction */
1261 if (gtk_tree_model_get_iter_first (model, &iter))
1262 {
1263 do
1264 {
1265 GtkTreeIter iter_child;
1266 gint scheduled_number_tmp;
1267
1268 gtk_tree_model_get (GTK_TREE_MODEL (model),
1269 &iter,
1270 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &scheduled_number_tmp,
1271 -1);
1272 if (scheduled_number == scheduled_number_tmp)
1273 return (gtk_tree_iter_copy (&iter));
1274
1275 /* gtk_tree_iter_next doesn't go in the children, so if the current transaction
1276 * has children, we have to look for the transaction here, and go down into the children */
1277 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (model), &iter_child, &iter))
1278 {
1279 /* ok so iter_child is on a split child, we go to see all the splits */
1280 do
1281 {
1282 gtk_tree_model_get (GTK_TREE_MODEL (model),
1283 &iter_child,
1284 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &scheduled_number_tmp,
1285 -1);
1286 if (scheduled_number == scheduled_number_tmp)
1287 return (gtk_tree_iter_copy (&iter_child));
1288 }
1289 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model),&iter_child));
1290 }
1291 }
1292 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (model),&iter));
1293
1294 }
1295 return NULL;
1296 }
1297
1298 /**
1299 * switch the expander of the split given in param
1300 *
1301 * \param scheduled_number the scheduled split we want to switch
1302 *
1303 * \return FALSE
1304 **/
gsb_scheduler_list_switch_expander(gint scheduled_number)1305 static gboolean gsb_scheduler_list_switch_expander (gint scheduled_number)
1306 {
1307 GtkTreeIter *iter;
1308 GtkTreePath *path;
1309 GtkTreePath *path_sorted;
1310
1311 if (!gsb_data_scheduled_get_split_of_scheduled (scheduled_number)
1312 || !tree_view_scheduler_list)
1313 return FALSE;
1314
1315 iter = gsb_scheduler_list_get_iter_from_scheduled_number (scheduled_number);
1316
1317 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_scheduler_list), iter);
1318 path_sorted = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort_scheduler_list, path);
1319 if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (tree_view_scheduler_list), path_sorted))
1320 gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view_scheduler_list), path_sorted);
1321 else
1322 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view_scheduler_list), path_sorted, FALSE);
1323 gtk_tree_path_free (path);
1324 gtk_tree_path_free (path_sorted);
1325 gtk_tree_iter_free (iter);
1326
1327 return FALSE;
1328 }
1329
1330 /**
1331 * called when a key is pressed on the scheduled transactions list
1332 *
1333 * \param tree_view
1334 * \param ev
1335 *
1336 * \return FALSE
1337 **/
gsb_scheduler_list_key_press(GtkWidget * tree_view,GdkEventKey * ev)1338 static gboolean gsb_scheduler_list_key_press (GtkWidget *tree_view,
1339 GdkEventKey *ev)
1340 {
1341 gint scheduled_number;
1342
1343 scheduled_number = gsb_scheduler_list_get_current_scheduled_number ();
1344
1345 switch (ev->keyval)
1346 {
1347 case GDK_KEY_Return : /* touches entrée */
1348 case GDK_KEY_KP_Enter :
1349
1350 if (scheduled_number)
1351 gsb_scheduler_list_edit_transaction (scheduled_number);
1352 break;
1353
1354
1355 case GDK_KEY_Delete : /* del */
1356
1357 if (scheduled_number > 0)
1358 gsb_scheduler_list_delete_scheduled_transaction (scheduled_number, TRUE);
1359 break;
1360
1361 case GDK_KEY_Left:
1362 /* if we press left, give back the focus to the tree at left */
1363 gtk_widget_grab_focus (gsb_gui_navigation_get_tree_view ());
1364 break;
1365
1366 case GDK_KEY_space:
1367 /* space open/close a split */
1368 gsb_scheduler_list_switch_expander (scheduled_number);
1369 break;
1370 }
1371 return (FALSE);
1372 }
1373
1374 /**
1375 * called when the size of the tree view changed, to keep the same ration
1376 * between the columns
1377 *
1378 * \param tree_view the tree view of the scheduled transactions list
1379 * \param allocation the new size
1380 * \param null
1381 *
1382 * \return FALSE
1383 **/
gsb_scheduler_list_size_allocate(GtkWidget * tree_view,GtkAllocation * allocation,gpointer null)1384 static void gsb_scheduler_list_size_allocate (GtkWidget *tree_view,
1385 GtkAllocation *allocation,
1386 gpointer null)
1387 {
1388 gint i;
1389 //~ devel_debug_int (allocation->width);
1390
1391 if (gsb_gui_navigation_get_current_page () != GSB_SCHEDULER_PAGE)
1392 return;
1393
1394 if (allocation->width == scheduler_current_tree_view_width)
1395 {
1396 gint somme = 0;
1397
1398 /* size of the tree view didn't change, but we received an allocated signal
1399 * it happens several times, and especially when we change the columns,
1400 * so we update the colums */
1401
1402 /* sometimes, when the list is not visible, he will set all the columns to 1%...
1403 * we block that here */
1404 if (gtk_tree_view_column_get_width (scheduler_list_column[0]) == 1)
1405 return;
1406
1407 for (i=0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS -1; i++)
1408 {
1409 if (gtk_tree_view_column_get_visible (scheduler_list_column[i]))
1410 {
1411 scheduler_col_width[i] = (gtk_tree_view_column_get_width (
1412 scheduler_list_column[i]) * 100) / allocation->width + 1;
1413 somme+= scheduler_col_width[i];
1414 }
1415 }
1416 scheduler_col_width[i] = 100 - somme;
1417 gsb_file_set_modified (TRUE);
1418
1419 return;
1420 }
1421
1422 /* the size of the tree view changed, we keep the ration between the columns,
1423 * we don't set the size of the last column to avoid the calculate problems,
1424 * it will take the end of the width alone */
1425 scheduler_current_tree_view_width = allocation->width;
1426
1427 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS -1 ; i++)
1428 {
1429 gint width;
1430
1431 width = (scheduler_col_width[i] * (allocation->width))/ 100;
1432 if (width > 0 && gtk_tree_view_column_get_visible (scheduler_list_column[i]))
1433 gtk_tree_view_column_set_fixed_width (scheduler_list_column[i], width);
1434 }
1435
1436 /* update tree_view */
1437 gsb_scheduler_list_update_tree_view (tree_view);
1438 }
1439
1440 /**
1441 * create and configure the tree view of the scheduled transactions
1442 *
1443 * \param
1444 *
1445 * \return the tree_view
1446 **/
gsb_scheduler_list_create_tree_view(void)1447 static GtkWidget *gsb_scheduler_list_create_tree_view (void)
1448 {
1449 GtkWidget * tree_view;
1450
1451 tree_view = gtk_tree_view_new ();
1452 gtk_widget_set_name (tree_view, "tree_view");
1453
1454 /* can select only one line */
1455 gtk_tree_selection_set_mode (GTK_TREE_SELECTION (gtk_tree_view_get_selection (GTK_TREE_VIEW(tree_view))),
1456 GTK_SELECTION_SINGLE);
1457
1458 g_signal_connect (G_OBJECT (tree_view),
1459 "size-allocate",
1460 G_CALLBACK (gsb_scheduler_list_size_allocate),
1461 NULL);
1462 g_signal_connect (G_OBJECT (tree_view),
1463 "button-press-event",
1464 G_CALLBACK (gsb_scheduler_list_button_press),
1465 NULL);
1466
1467 g_signal_connect (G_OBJECT (tree_view),
1468 "key-press-event",
1469 G_CALLBACK (gsb_scheduler_list_key_press),
1470 NULL);
1471
1472 gtk_widget_show (tree_view);
1473
1474 last_scheduled_number = -1;
1475
1476 return tree_view;
1477 }
1478
1479 /**
1480 * fill the row pointed by the iter with the content of
1481 * the char tab given in param
1482 *
1483 * \param store
1484 * \param iter
1485 * \param line a tab of gchar with SCHEDULER_COL_VISIBLE_COLUMNS of size, which is the text content of the line
1486 *
1487 * \return FALSE
1488 **/
gsb_scheduler_list_fill_transaction_row(GtkTreeStore * store,GtkTreeIter * iter,gchar * line[SCHEDULER_COL_VISIBLE_COLUMNS])1489 static gboolean gsb_scheduler_list_fill_transaction_row (GtkTreeStore *store,
1490 GtkTreeIter *iter,
1491 gchar *line[SCHEDULER_COL_VISIBLE_COLUMNS])
1492 {
1493 gchar *color_str = NULL;
1494 gint i;
1495
1496 if (line[COL_NB_AMOUNT] && g_utf8_strchr (line[COL_NB_AMOUNT], -1, '-'))
1497 color_str = (gchar*)"red";
1498
1499 for (i=0 ; i<SCHEDULER_COL_VISIBLE_COLUMNS ; i++)
1500 {
1501 if (!line[i])
1502 continue;
1503
1504 if (i == 6)
1505 gtk_tree_store_set (store, iter, i, line[i], SCHEDULER_COL_NB_AMOUNT_COLOR, color_str, -1);
1506 else
1507 gtk_tree_store_set (store, iter, i, line[i], -1);
1508 }
1509
1510 return FALSE;
1511 }
1512
1513 /**
1514 * fill the char tab in the param with the transaction given in param
1515 *
1516 * \param scheduled_number
1517 * \param line a tab of gchar with SCHEDULER_COL_VISIBLE_COLUMNS of size, which will contain the text of the line
1518 *
1519 * \return FALSE
1520 **/
gsb_scheduler_list_fill_transaction_text(gint scheduled_number,gchar * line[SCHEDULER_COL_VISIBLE_COLUMNS])1521 static gboolean gsb_scheduler_list_fill_transaction_text (gint scheduled_number,
1522 gchar *line[SCHEDULER_COL_VISIBLE_COLUMNS])
1523 {
1524 if (gsb_data_scheduled_get_mother_scheduled_number (scheduled_number))
1525 {
1526 /* for child split we set all to NULL except the party, we show the category instead */
1527 line[COL_NB_DATE] = NULL;
1528 line[COL_NB_FREQUENCY] = NULL;
1529 line[COL_NB_ACCOUNT] = NULL;
1530 line[COL_NB_MODE] = NULL;
1531
1532 if (gsb_data_scheduled_get_category_number (scheduled_number))
1533 line[COL_NB_PARTY] = gsb_data_category_get_name (gsb_data_scheduled_get_category_number
1534 (scheduled_number),
1535 gsb_data_scheduled_get_sub_category_number
1536 (scheduled_number),
1537 NULL);
1538 else
1539 {
1540 /* there is no category, it can be a transfer */
1541 if (gsb_data_scheduled_get_account_number_transfer (scheduled_number) >= 0 && scheduled_number > 0)
1542 {
1543 /* it's a transfer */
1544 if (gsb_data_scheduled_get_amount (scheduled_number).mantissa < 0)
1545 line[COL_NB_PARTY] = g_strdup_printf (_("Transfer to %s"),
1546 gsb_data_account_get_name
1547 (gsb_data_scheduled_get_account_number_transfer
1548 (scheduled_number)));
1549 else
1550 line[COL_NB_PARTY] = g_strdup_printf (_("Transfer from %s"),
1551 gsb_data_account_get_name
1552 (gsb_data_scheduled_get_account_number_transfer
1553 (scheduled_number)));
1554 }
1555 else
1556 /* it's not a transfer, so no category */
1557 line[COL_NB_PARTY] = NULL;
1558 }
1559 }
1560 else
1561 {
1562 /* fill her for normal scheduled transaction (not children) */
1563 gint frequency;
1564
1565 line[COL_NB_DATE] = gsb_format_gdate (gsb_data_scheduled_get_date (scheduled_number));
1566 frequency = gsb_data_scheduled_get_frequency (scheduled_number);
1567
1568 if (frequency == SCHEDULER_PERIODICITY_CUSTOM_VIEW)
1569 {
1570 switch (gsb_data_scheduled_get_user_interval (scheduled_number))
1571 {
1572 case PERIODICITY_DAYS:
1573 line[COL_NB_FREQUENCY] = g_strdup_printf (_("%d days"),
1574 gsb_data_scheduled_get_user_entry (scheduled_number));
1575 break;
1576
1577 case PERIODICITY_WEEKS:
1578 line[COL_NB_FREQUENCY] = g_strdup_printf (_("%d weeks"),
1579 gsb_data_scheduled_get_user_entry (scheduled_number));
1580 break;
1581
1582 case PERIODICITY_MONTHS:
1583 line[COL_NB_FREQUENCY] = g_strdup_printf (_("%d months"),
1584 gsb_data_scheduled_get_user_entry (scheduled_number));
1585 break;
1586
1587 case PERIODICITY_YEARS:
1588 line[COL_NB_FREQUENCY] = g_strdup_printf (_("%d years"),
1589 gsb_data_scheduled_get_user_entry (scheduled_number));
1590 }
1591 }
1592 else
1593 {
1594 if (frequency < SCHEDULER_PERIODICITY_NB_CHOICES && frequency >= 0)
1595 {
1596 gchar * names[] = {_("Once"), _("Weekly"), _("Monthly"),
1597 _("Bimonthly"), _("Quarterly"), _("Yearly") };
1598
1599 line[COL_NB_FREQUENCY] = g_strdup (names [frequency]);
1600 }
1601 }
1602 line[COL_NB_ACCOUNT] = g_strdup (gsb_data_account_get_name (gsb_data_scheduled_get_account_number
1603 (scheduled_number)));
1604 line[COL_NB_PARTY] = g_strdup (gsb_data_payee_get_name (gsb_data_scheduled_get_party_number
1605 (scheduled_number), TRUE));
1606
1607 if (gsb_data_scheduled_get_automatic_scheduled (scheduled_number))
1608 line[COL_NB_MODE]= g_strdup (_("Automatic"));
1609 else
1610 line[COL_NB_MODE] = g_strdup (_("Manual"));
1611 }
1612
1613 /* that can be filled for mother and children of split */
1614 line[COL_NB_NOTES] = g_strdup (gsb_data_scheduled_get_notes (scheduled_number));
1615
1616 /* if it's a white line don't fill the amount
1617 * (in fact fill nothing, but normally all before was set to NULL,
1618 * there is only the amount, we want NULL and not 0) */
1619 if (scheduled_number < 0)
1620 line[COL_NB_AMOUNT] = NULL;
1621 else
1622 line[COL_NB_AMOUNT] = utils_real_get_string_with_currency (
1623 gsb_data_scheduled_get_amount (scheduled_number),
1624 gsb_data_scheduled_get_currency_number (scheduled_number),
1625 TRUE);
1626
1627 return FALSE;
1628 }
1629
1630 /**
1631 * the same as gsb_scheduler_list_get_iter_from_scheduled_number but
1632 * return a gslist of iter corresponding to that scheduled number,
1633 * so there is only 1 iter for the once view, but more than 1 for the other views
1634 * use when changin the scheduled, to change also the virtuals ones on the screen
1635 *
1636 * \param scheduled_number
1637 *
1638 * \return a gslist of pointer to the iters, need to be free, or NULL if not found
1639 **/
gsb_scheduler_list_get_iter_list_from_scheduled_number(gint scheduled_number)1640 static GSList *gsb_scheduler_list_get_iter_list_from_scheduled_number (gint scheduled_number)
1641 {
1642 GtkTreeIter iter;
1643 GtkTreeModel *model;
1644 gint mother_number;
1645 gboolean return_iter = TRUE;
1646 GSList *iter_list = NULL;
1647
1648 if (!scheduled_number)
1649 return NULL;
1650
1651 /* that function is called too for deleting a scheduled transaction,
1652 * and it can be already deleted, so we cannot call gsb_data_scheduled_... here
1653 * but... we need to know if it's a child split, so we call it, in all
1654 * the cases, if the transactions doesn't exist we will have no mother, so very good !*/
1655
1656 mother_number = gsb_data_scheduled_get_mother_scheduled_number (scheduled_number);
1657
1658 model = gsb_scheduler_list_get_model ();
1659
1660 /* go throw the list to find the transaction */
1661 if (!gtk_tree_model_get_iter_first (model, &iter))
1662 return NULL;
1663
1664 while (return_iter)
1665 {
1666 gint scheduled_transaction_buf;
1667
1668 gtk_tree_model_get (model,
1669 &iter,
1670 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &scheduled_transaction_buf,
1671 -1);
1672
1673 if (scheduled_transaction_buf == scheduled_number)
1674 {
1675 iter_list = g_slist_append (iter_list, gtk_tree_iter_copy (&iter));
1676
1677 /* we have found the correct iter, but we want to continue to search,
1678 * so we have to go back to the mother if necessary
1679 * after that scheduled_transaction_buf is on the child, not on the
1680 * mother so we will continue to the next scheduled transasction */
1681
1682 if (mother_number)
1683 {
1684 GtkTreeIter *child_iter;
1685
1686 child_iter = gtk_tree_iter_copy (&iter);
1687 gtk_tree_model_iter_parent (model, &iter, child_iter);
1688 gtk_tree_iter_free (child_iter);
1689 }
1690
1691 }
1692
1693 if (scheduled_transaction_buf == mother_number)
1694 {
1695 GtkTreeIter *mother_iter;
1696
1697 mother_iter = gtk_tree_iter_copy (&iter);
1698 return_iter = gtk_tree_model_iter_children (model, &iter, mother_iter);
1699 gtk_tree_iter_free (mother_iter);
1700 }
1701 else
1702 return_iter = gtk_tree_model_iter_next (model, &iter);
1703 }
1704 return iter_list;
1705 }
1706
1707 /**
1708 * remove the orphan transactions
1709 *
1710 * \param orphan list
1711 *
1712 * \return void
1713 */
gsb_scheduler_list_remove_orphan_list(GSList * orphan_scheduled,GDate * end_date)1714 static void gsb_scheduler_list_remove_orphan_list (GSList *orphan_scheduled,
1715 GDate *end_date)
1716 {
1717 GSList *tmp_list;
1718 gchar *string = NULL;
1719 GArray *garray;
1720
1721 garray = g_array_new (FALSE, FALSE, sizeof (gint));
1722 tmp_list = orphan_scheduled;
1723 while (tmp_list)
1724 {
1725 gint scheduled_number;
1726
1727 scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list->data);
1728
1729 if (!gsb_scheduler_list_append_new_scheduled (scheduled_number, end_date))
1730 {
1731 /* on sauvegarde le numéro de l'opération */
1732 g_array_append_val (garray, scheduled_number);
1733 if (string == NULL)
1734 string = utils_str_itoa (scheduled_number);
1735 else
1736 string = g_strconcat (string, " - ",
1737 utils_str_itoa (scheduled_number), NULL);
1738 }
1739
1740 tmp_list = tmp_list->next;
1741 }
1742
1743 /* if string is not null, there is still some children
1744 * which didn't find their mother. show them now */
1745 if (string)
1746 {
1747 gchar *message;
1748 gint result;
1749
1750 message = g_strdup_printf (_("Some scheduled children didn't find their mother in the list, "
1751 "this shouldn't happen and there is probably a bug behind that.\n\n"
1752 "The concerned children number are:\n %s\n\n"
1753 "Do you want to delete it?"),
1754 string);
1755
1756 result = dialogue_yes_no (message, _("Remove orphan children"), GTK_RESPONSE_CANCEL);
1757
1758 if (result == TRUE)
1759 {
1760 gint i;
1761
1762 for (i = 0; i < (gint) garray->len; i++)
1763 gsb_data_scheduled_remove_scheduled (g_array_index (garray, gint, i));
1764
1765 }
1766
1767 g_free (message);
1768 g_free (string);
1769 g_array_free (garray, TRUE);
1770 }
1771 }
1772
1773 /**
1774 * set the text red if the variance is non zero
1775 *
1776 * \param
1777 * \param
1778 *
1779 * \return
1780 **/
gsb_scheduler_list_set_color_of_mother(gint mother_scheduled_number,gboolean is_red)1781 static gboolean gsb_scheduler_list_set_color_of_mother (gint mother_scheduled_number,
1782 gboolean is_red)
1783 {
1784 GtkTreeIter *iter = NULL;
1785 gchar *color_str = NULL;
1786 gint i;
1787
1788 iter = gsb_scheduler_list_get_iter_from_scheduled_number (mother_scheduled_number);
1789 if (!iter)
1790 return FALSE;
1791
1792 if (is_red)
1793 color_str = (gchar*)"red";
1794
1795 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS -1 ; i++)
1796 {
1797 gtk_tree_store_set (GTK_TREE_STORE (tree_model_scheduler_list),
1798 iter,
1799 SCHEDULER_COL_NB_TEXT_COLOR, color_str,
1800 -1);
1801 }
1802
1803 return TRUE;
1804 }
1805
1806 /**
1807 * set the scheduler tree view
1808 *
1809 * \param tree_view
1810 *
1811 * \return
1812 **/
gsb_scheduler_list_set_tree_view(GtkWidget * tree_view)1813 static void gsb_scheduler_list_set_tree_view (GtkWidget *tree_view)
1814 {
1815 tree_view_scheduler_list = tree_view;
1816 }
1817
1818 /**
1819 *
1820 *
1821 * \param
1822 * \param
1823 * \param
1824 *
1825 * \return
1826 **/
gsb_scheduler_list_set_virtual_amount_with_loan(gint scheduled_number,gchar * line[SCHEDULER_COL_VISIBLE_COLUMNS],gint account_number)1827 static void gsb_scheduler_list_set_virtual_amount_with_loan (gint scheduled_number,
1828 gchar *line[SCHEDULER_COL_VISIBLE_COLUMNS],
1829 gint account_number)
1830 {
1831 gdouble amount;
1832
1833 amount = bet_data_loan_get_other_echeance_amount (account_number);
1834 line[COL_NB_AMOUNT] = utils_real_get_string_with_currency (gsb_real_opposite (gsb_real_double_to_real (amount)),
1835 gsb_data_scheduled_get_currency_number (scheduled_number),
1836 TRUE);
1837 }
1838
1839 /**
1840 *
1841 *
1842 * \param
1843 * \param
1844 *
1845 * \return
1846 **/
gsb_scheduler_list_update_white_child(gint white_line_number,gint mother_scheduled_number)1847 static gboolean gsb_scheduler_list_update_white_child (gint white_line_number,
1848 gint mother_scheduled_number)
1849 {
1850 GtkTreeIter *iter = NULL;
1851 GSList *tmp_list;
1852 GsbReal total_split = null_real;
1853 GsbReal variance;
1854 gchar *tmp_str;
1855
1856 if (!tree_model_scheduler_list)
1857 return FALSE;
1858
1859 iter = gsb_scheduler_list_get_iter_from_scheduled_number (white_line_number);
1860 if (!iter)
1861 return FALSE;
1862
1863 tmp_list = gsb_data_scheduled_get_scheduled_list ();
1864 while (tmp_list)
1865 {
1866 gint split_scheduled_number;
1867
1868 split_scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list->data);
1869
1870 if (gsb_data_scheduled_get_mother_scheduled_number (split_scheduled_number) == mother_scheduled_number)
1871 {
1872 total_split = gsb_real_add (total_split, gsb_data_scheduled_get_amount (split_scheduled_number));
1873 }
1874 tmp_list = tmp_list->next;
1875 }
1876
1877 variance = gsb_real_sub (gsb_data_scheduled_get_amount (mother_scheduled_number), total_split);
1878
1879 /* show the variance and sub-total only if different of the scheduled */
1880 if (variance.mantissa)
1881 {
1882 gchar *amount_string;
1883 gchar *variance_string;
1884 gint currency_number;
1885
1886 currency_number = gsb_data_scheduled_get_currency_number (mother_scheduled_number);
1887 amount_string = utils_real_get_string_with_currency (total_split, currency_number, TRUE);
1888 variance_string = utils_real_get_string_with_currency (variance, currency_number, TRUE);
1889
1890 tmp_str = g_strdup_printf (_("Total: %s (variance : %s)"), amount_string, variance_string);
1891
1892 g_free (amount_string);
1893 g_free (variance_string);
1894
1895 gsb_scheduler_list_set_color_of_mother (mother_scheduled_number, TRUE);
1896 }
1897 else
1898 {
1899 tmp_str = (gchar*)"";
1900 gsb_scheduler_list_set_color_of_mother (mother_scheduled_number, FALSE);
1901 }
1902
1903 gtk_tree_store_set (GTK_TREE_STORE (tree_model_scheduler_list), iter, 2, tmp_str, -1);
1904
1905 if (tmp_str && strlen (tmp_str))
1906 g_free (tmp_str);
1907
1908 return TRUE;
1909 }
1910
1911 /******************************************************************************/
1912 /* Public functions */
1913 /******************************************************************************/
1914 /**
1915 * libère la mémoire utilisée par GSLists de création des opérations
1916 * arrivées à éhéance
1917 *
1918 * \param
1919 *
1920 * \return
1921 **/
gsb_scheduler_list_free_variables(void)1922 void gsb_scheduler_list_free_variables (void)
1923 {
1924 if (scheduled_transactions_to_take)
1925 {
1926 g_slist_free (scheduled_transactions_to_take);
1927 }
1928 if (scheduled_transactions_taken)
1929 {
1930 g_slist_free (scheduled_transactions_taken);
1931 }
1932 }
1933
1934 /**
1935 *
1936 *
1937 * \param
1938 *
1939 * \return
1940 **/
gsb_scheduler_list_init_variables(void)1941 void gsb_scheduler_list_init_variables (void)
1942 {
1943 if (scheduled_transactions_to_take)
1944 {
1945 g_slist_free (scheduled_transactions_to_take);
1946 scheduled_transactions_to_take = NULL;
1947 }
1948 if (scheduled_transactions_taken)
1949 {
1950 g_slist_free (scheduled_transactions_taken);
1951 scheduled_transactions_taken = NULL;
1952 }
1953
1954 /* on réinitialise tous les widgets */
1955 scheduler_display_hide_notes = NULL;
1956 scheduler_button_execute = NULL;
1957 scheduler_button_delete = NULL;
1958 scheduler_button_edit = NULL;
1959 }
1960
1961 /**
1962 * create the scheduler list
1963 *
1964 * \param
1965 *
1966 * \return a vbox widget containing the list
1967 **/
gsb_scheduler_list_create_list(void)1968 GtkWidget *gsb_scheduler_list_create_list (void)
1969 {
1970 GtkWidget *vbox, *scrolled_window;
1971 GtkWidget *tree_view;
1972 GtkWidget *frame;
1973 GtkTreeModel *tree_model;
1974
1975 devel_debug (NULL);
1976
1977 /* first, a vbox */
1978 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, MARGIN_BOX);
1979
1980 /* frame pour la barre d'outils */
1981 frame = gtk_frame_new (NULL);
1982 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1983
1984 /* création de la barre d'outils */
1985 scheduler_toolbar = gsb_scheduler_list_create_toolbar ();
1986 gtk_container_add (GTK_CONTAINER (frame), scheduler_toolbar);
1987
1988 /* create the scrolled window */
1989 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
1990 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1991 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1992 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
1993 GTK_SHADOW_IN);
1994 gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 0);
1995 gtk_widget_show (scrolled_window);
1996
1997 /* we create and set the tree_view in the page */
1998 tree_view = gsb_scheduler_list_create_tree_view ();
1999 gtk_widget_set_margin_end (tree_view, MARGIN_END);
2000 gsb_scheduler_list_set_tree_view (tree_view);
2001 gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
2002
2003 /* set the color of selected row */
2004 gtk_widget_set_name (tree_view, "tree_view");
2005
2006 /* create the store and set it in the tree_view */
2007 tree_model = gsb_scheduler_list_create_model ();
2008 gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view), tree_model);
2009 g_object_unref (G_OBJECT(tree_model));
2010
2011 /* create the columns */
2012 gsb_scheduler_list_create_list_columns (tree_view);
2013
2014 /* begin by hiding the notes */
2015 gsb_scheduler_list_show_notes (scheduler_display_hide_notes);
2016
2017 gtk_widget_show_all (vbox);
2018
2019 return vbox;
2020 }
2021
2022
2023 /**
2024 *
2025 *
2026 *
2027 */
gsb_gui_scheduler_toolbar_set_style(gint toolbar_style)2028 void gsb_gui_scheduler_toolbar_set_style (gint toolbar_style)
2029 {
2030 gtk_toolbar_set_style (GTK_TOOLBAR (scheduler_toolbar), toolbar_style);
2031 }
2032
2033
2034 /**
2035 * return the scheduler tree view
2036 *
2037 * \param
2038 *
2039 * \return the scheduler tree_view
2040 **/
gsb_scheduler_list_get_tree_view(void)2041 GtkWidget *gsb_scheduler_list_get_tree_view (void)
2042 {
2043 return tree_view_scheduler_list;
2044 }
2045
2046 /**
2047 * called to execute a sheduled transaction, either by the button on the toolbar,
2048 * either by click on the first page
2049 * if scheduled_number is 0, get the selected transaction
2050 *
2051 * \param scheduled_number
2052 *
2053 * \return FALSE
2054 **/
gsb_scheduler_list_execute_transaction(gint scheduled_number)2055 gboolean gsb_scheduler_list_execute_transaction (gint scheduled_number)
2056 {
2057 devel_debug_int (scheduled_number);
2058
2059 if (!scheduled_number)
2060 scheduled_number = gsb_scheduler_list_get_current_scheduled_number ();
2061
2062 gsb_scheduler_list_edit_transaction (scheduled_number);
2063
2064 /* the only difference for now between an execution and a edition of scheduled is here :
2065 * set the flag to say that we execute the scheduled transaction
2066 * and hide the scheduler part of the form */
2067 g_object_set_data (G_OBJECT (gsb_form_get_form_widget ()), "execute_scheduled", GINT_TO_POINTER (TRUE));
2068 gtk_widget_hide (gsb_form_get_scheduler_part ());
2069
2070 return FALSE;
2071 }
2072
2073 /**
2074 * fill the scheduled transactions list
2075 *
2076 * \para tree_view
2077 *
2078 * \return FALSE
2079 **/
gsb_scheduler_list_fill_list(GtkWidget * tree_view)2080 gboolean gsb_scheduler_list_fill_list (GtkWidget *tree_view)
2081 {
2082 GSList *tmp_list;
2083 GDate *end_date;
2084 GtkTreeIter iter;
2085 GSList *orphan_scheduled = NULL;
2086 GrisbiAppConf *a_conf;
2087
2088 devel_debug (NULL);
2089
2090 /* get the last date we want to see the transactions */
2091 end_date = gsb_scheduler_list_get_end_date_scheduled_showed ();
2092
2093 if (!tree_model_scheduler_list || !GTK_IS_TREE_STORE (tree_model_scheduler_list))
2094 return FALSE;
2095 else
2096 gtk_tree_store_clear (GTK_TREE_STORE (tree_model_scheduler_list));
2097
2098 /* fill the list */
2099 tmp_list = gsb_data_scheduled_get_scheduled_list ();
2100
2101 while (tmp_list)
2102 {
2103 gint scheduled_number;
2104
2105 scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list->data);
2106
2107 if (!end_date || g_date_compare (gsb_data_scheduled_get_date (scheduled_number), end_date) <= 0)
2108 {
2109 if (!gsb_scheduler_list_append_new_scheduled (scheduled_number, end_date))
2110 /* the scheduled transaction was not added, add to orphan scheduledlist */
2111 orphan_scheduled = g_slist_append (orphan_scheduled, tmp_list->data);
2112 }
2113 tmp_list = tmp_list->next;
2114 }
2115
2116 /* if there are some orphan sheduler (children of breakdonw which didn't find their mother */
2117 if (orphan_scheduled)
2118 {
2119 gsb_scheduler_list_remove_orphan_list (orphan_scheduled, end_date);
2120 g_slist_free (orphan_scheduled);
2121 }
2122
2123 /* create and append the white line */
2124 gtk_tree_store_append (GTK_TREE_STORE (tree_model_scheduler_list), &iter, NULL);
2125 gtk_tree_store_set (GTK_TREE_STORE (tree_model_scheduler_list),
2126 &iter,
2127 SCHEDULER_COL_NB_TRANSACTION_NUMBER, gsb_data_scheduled_new_white_line (0),
2128 -1);
2129
2130 /* get first scheduled of the list */
2131 a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
2132 if (!a_conf->select_scheduled_in_list)
2133 {
2134 GtkWidget *tree_view;
2135 GtkTreeModel *model;
2136
2137 tree_view = gsb_scheduler_list_get_tree_view ();
2138
2139 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
2140 gtk_tree_model_get_iter_first (model, &iter);
2141 gtk_tree_model_get (model,
2142 &iter,
2143 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &first_scheduler_list_number,
2144 -1);
2145 }
2146 return TRUE;
2147 }
2148
2149 /**
2150 * send a "row-changed" to all the row of the showed transactions,
2151 * so in fact re-draw the list and colors
2152 *
2153 * \param
2154 *
2155 * \return
2156 **/
gsb_scheduler_list_redraw(void)2157 gboolean gsb_scheduler_list_redraw (void)
2158 {
2159 GtkTreeIter iter;
2160 GtkTreeModel *tree_model;
2161
2162 tree_model = gsb_scheduler_list_get_model ();
2163
2164 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (tree_model), &iter))
2165 {
2166 do
2167 {
2168 GtkTreePath *path;
2169 GtkTreeIter child_iter;
2170
2171 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model), &iter);
2172 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_model), path, &iter);
2173 gtk_tree_path_free(path);
2174
2175 /* update the children if necessary */
2176 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (tree_model), &child_iter, &iter))
2177 {
2178 do
2179 {
2180 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model), &child_iter);
2181 gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_model), path, &child_iter);
2182 gtk_tree_path_free(path);
2183 }
2184 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tree_model), &child_iter));
2185 }
2186 }
2187 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (tree_model), &iter));
2188 }
2189 return FALSE;
2190 }
2191
2192 /**
2193 * append the scheduled transaction to the tree_view given in param
2194 * if that transaction need to be appended several times (untill end_date),
2195 * it's done here
2196 *
2197 * \param scheduled_number
2198 * \param end_date
2199 *
2200 * \return TRUE : scheduled added, FALSE : not added (usually for children who didn't find their mother)
2201 **/
gsb_scheduler_list_append_new_scheduled(gint scheduled_number,GDate * end_date)2202 gboolean gsb_scheduler_list_append_new_scheduled (gint scheduled_number,
2203 GDate *end_date)
2204 {
2205 GDate *tmp_date;
2206 GDate *pGDateCurrent;
2207 GtkTreeIter *mother_iter = NULL;
2208 gchar *line[SCHEDULER_COL_VISIBLE_COLUMNS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
2209 gint mother_scheduled_number;
2210 gint fixed_date = 0;
2211 gint split_transaction;
2212 gint transfer_account = 0;
2213 gint virtual_transaction = 0;
2214 gboolean first_is_different = FALSE;
2215
2216 /* devel_debug_int (scheduled_number); */
2217 if (!tree_model_scheduler_list)
2218 return FALSE;
2219
2220 /* get the mother iter if needed */
2221 mother_scheduled_number = gsb_data_scheduled_get_mother_scheduled_number (scheduled_number);
2222 if (mother_scheduled_number)
2223 {
2224 gint white_line_number;
2225
2226 mother_iter = gsb_scheduler_list_get_iter_from_scheduled_number (mother_scheduled_number);
2227 if (!mother_iter)
2228 /* it's a child but didn't find the mother, it can happen in old files previous to 0.6
2229 * where the children wer saved before the mother, return FALSE here will add that
2230 * child to a list to append it again later */
2231 return FALSE;
2232
2233 white_line_number = gsb_data_scheduled_get_white_line (mother_scheduled_number);
2234 gsb_scheduler_list_update_white_child (white_line_number, mother_scheduled_number);
2235 }
2236
2237 /* set the good date */
2238 tmp_date = gsb_data_scheduled_get_date (scheduled_number);
2239 pGDateCurrent = gsb_date_copy (tmp_date);
2240 fixed_date = gsb_data_scheduled_get_fixed_date (scheduled_number);
2241 if (fixed_date)
2242 {
2243 g_date_set_day (pGDateCurrent, fixed_date);
2244 if (!g_date_valid (pGDateCurrent))
2245 {
2246 g_date_free (pGDateCurrent);
2247 pGDateCurrent = gsb_date_get_last_day_of_month (tmp_date);
2248 }
2249 }
2250
2251 /* fill the text line */
2252 split_transaction = gsb_data_scheduled_get_split_of_scheduled (scheduled_number);
2253 if (split_transaction)
2254 {
2255 gint init_sch_with_loan;
2256
2257 transfer_account = gsb_data_scheduled_get_account_number_transfer (scheduled_number+1);
2258 init_sch_with_loan = gsb_data_account_get_bet_init_sch_with_loan (transfer_account);
2259 if (init_sch_with_loan) /* cette transaction concerne un prêt */
2260 {
2261 first_is_different = bet_data_loan_get_loan_first_is_different (transfer_account);
2262 if (first_is_different) /* les autres échéances sont différentes */
2263 {
2264 GSList *children_numbers_list;
2265 GsbReal amount;
2266
2267 amount = bet_finance_get_loan_amount_at_date (scheduled_number,
2268 transfer_account,
2269 pGDateCurrent,
2270 FALSE);
2271 gsb_data_scheduled_set_amount (scheduled_number, amount);
2272
2273 /* on traite les opérations filles */
2274 children_numbers_list = gsb_data_scheduled_get_children (scheduled_number, TRUE);
2275 while (children_numbers_list)
2276 {
2277 gint child_number;
2278
2279 child_number = GPOINTER_TO_INT (children_numbers_list->data);
2280 if (child_number)
2281 {
2282 amount = bet_finance_get_loan_amount_at_date (child_number,
2283 transfer_account,
2284 pGDateCurrent,
2285 FALSE);
2286 gsb_data_scheduled_set_amount (child_number, amount);
2287 }
2288
2289 children_numbers_list = children_numbers_list->next;
2290 }
2291 g_slist_free (children_numbers_list);
2292 }
2293 }
2294 }
2295 gsb_scheduler_list_fill_transaction_text (scheduled_number, line);
2296
2297 do
2298 {
2299 GtkTreeIter iter;
2300
2301 gtk_tree_store_append (GTK_TREE_STORE (tree_model_scheduler_list), &iter, mother_iter);
2302
2303 if (scheduled_number > 0)
2304 gsb_scheduler_list_fill_transaction_row (GTK_TREE_STORE (tree_model_scheduler_list), &iter, line);
2305
2306 /* set the number of scheduled transaction to 0 if it's not the first one
2307 * (when more than one showed) */
2308 gtk_tree_store_set (GTK_TREE_STORE (tree_model_scheduler_list),
2309 &iter,
2310 SCHEDULER_COL_NB_TRANSACTION_NUMBER, scheduled_number,
2311 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, virtual_transaction,
2312 -1);
2313
2314 /* if it's a split, we append a white line now */
2315 if (split_transaction && !virtual_transaction)
2316 {
2317 gint white_line_number;
2318
2319 white_line_number = gsb_data_scheduled_get_white_line (scheduled_number);
2320 if (white_line_number == -1)
2321 white_line_number = gsb_data_scheduled_new_white_line (scheduled_number);
2322
2323 gsb_scheduler_list_append_new_scheduled (white_line_number, end_date);
2324 gsb_scheduler_list_update_white_child (white_line_number, scheduled_number);
2325 }
2326
2327 /* if it's a split, we show only one time and color the background */
2328 if (mother_iter)
2329 {
2330 gtk_tree_store_set (GTK_TREE_STORE (tree_model_scheduler_list),
2331 &iter,
2332 SCHEDULER_COL_NB_BACKGROUND, gsb_rgba_get_couleur ("background_split"),
2333 -1);
2334 }
2335 else
2336 {
2337 pGDateCurrent = gsb_scheduler_get_next_date (scheduled_number, pGDateCurrent);
2338
2339 line[COL_NB_DATE] = gsb_format_gdate (pGDateCurrent);
2340
2341 /* now, it's not real transactions */
2342 if (first_is_different && virtual_transaction == 0)
2343 gsb_scheduler_list_set_virtual_amount_with_loan (scheduled_number, line, transfer_account);
2344
2345 virtual_transaction ++;
2346 }
2347 }
2348 while (pGDateCurrent && end_date && g_date_compare (end_date, pGDateCurrent) >= 0 && !mother_iter);
2349
2350 if (mother_iter)
2351 gtk_tree_iter_free (mother_iter);
2352
2353 return TRUE;
2354 }
2355
2356 /**
2357 * remove the given scheduled transaction from the list
2358 * and too all the corresponding virtual transactions
2359 *
2360 * \param transaction_number
2361 *
2362 * \return FALSE
2363 **/
gsb_scheduler_list_remove_transaction_from_list(gint scheduled_number)2364 gboolean gsb_scheduler_list_remove_transaction_from_list (gint scheduled_number)
2365 {
2366 GSList *iter_list;
2367
2368 devel_debug_int (scheduled_number);
2369
2370 if (!scheduled_number || !gsb_scheduler_list_get_model ())
2371 return FALSE;
2372
2373 /* at this level, normally the transaction is already deleted,
2374 * so we cannot call gsb_data_scheduled_... we have only the number
2375 * to remove it from the list */
2376
2377 iter_list = gsb_scheduler_list_get_iter_list_from_scheduled_number (scheduled_number);
2378
2379 if (iter_list)
2380 {
2381 GtkTreeStore *store;
2382 GSList *tmp_list;
2383
2384 store = GTK_TREE_STORE (gsb_scheduler_list_get_model ());
2385 tmp_list = iter_list;
2386
2387 while (tmp_list)
2388 {
2389 GtkTreeIter *iter;
2390
2391 iter = tmp_list->data;
2392
2393 gtk_tree_store_remove (store, iter);
2394 gtk_tree_iter_free (iter);
2395 tmp_list = tmp_list->next;
2396 }
2397 }
2398 else
2399 {
2400 gchar *tmp_str;
2401
2402 tmp_str = g_strdup_printf (_("in gsb_scheduler_list_remove_transaction_from_list, "
2403 "ask to remove the transaction no %d,\nbut didn't find the iter in the list...\n"
2404 "It's normal if appending a new scheduled transaction, but abnormal else..."),
2405 scheduled_number);
2406 warning_debug (tmp_str);
2407 g_free (tmp_str);
2408 }
2409 return FALSE;
2410 }
2411
2412 /**
2413 * update the scheduled transaction in the list (and all the virtuals too)
2414 *
2415 * \param scheduled_number
2416 *
2417 * \return FALSE
2418 **/
gsb_scheduler_list_update_transaction_in_list(gint scheduled_number)2419 gboolean gsb_scheduler_list_update_transaction_in_list (gint scheduled_number)
2420 {
2421 GtkTreeStore *store;
2422 GtkTreeIter iter;
2423 GDate *pGDateCurrent;
2424 gchar *line[SCHEDULER_COL_VISIBLE_COLUMNS] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};;
2425
2426 devel_debug_int (scheduled_number);
2427
2428 if (!scheduled_number || !gsb_scheduler_list_get_model ())
2429 return FALSE;
2430
2431 /* the same transaction can be showed more than one time because of the different views,
2432 * not so difficult, go throw the list and for each iter corresponding to the scheduled
2433 * transaction, re-fill the line */
2434 store = GTK_TREE_STORE (gsb_scheduler_list_get_model ());
2435
2436 pGDateCurrent = gsb_date_copy (gsb_data_scheduled_get_date (scheduled_number));
2437
2438 /* fill the text line */
2439 gsb_scheduler_list_fill_transaction_text (scheduled_number, line);
2440
2441 if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter))
2442 {
2443 do
2444 {
2445 GtkTreeIter child_iter;
2446 gint scheduled_number_tmp;
2447
2448 gtk_tree_model_get (GTK_TREE_MODEL (store),
2449 &iter,
2450 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &scheduled_number_tmp,
2451 -1);
2452 if (scheduled_number_tmp == scheduled_number)
2453 {
2454 gsb_scheduler_list_fill_transaction_row (GTK_TREE_STORE (store), &iter, line);
2455
2456 /* go to the next date if ever there is several lines of that scheduled */
2457 pGDateCurrent = gsb_scheduler_get_next_date (scheduled_number, pGDateCurrent);
2458
2459 line[COL_NB_DATE] = gsb_format_gdate (pGDateCurrent);
2460 }
2461
2462 /* i still haven't found a function to go line by line, including the children,
2463 * so do another do/while into the first one */
2464 if (gtk_tree_model_iter_children (GTK_TREE_MODEL (store), &child_iter, &iter))
2465 {
2466 gint white_line_number = 0;
2467 gint mother_number = 0;
2468
2469 /* we are on the child */
2470 do
2471 {
2472 gtk_tree_model_get (GTK_TREE_MODEL (store),
2473 &child_iter,
2474 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &scheduled_number_tmp,
2475 -1);
2476
2477 if (scheduled_number_tmp < -1)
2478 {
2479 white_line_number = scheduled_number_tmp;
2480 mother_number = gsb_data_scheduled_get_mother_scheduled_number (white_line_number);
2481 }
2482
2483 if (scheduled_number_tmp > 0)
2484 {
2485 GsbReal amount;
2486 gchar *tmp_str;
2487 gchar *color_str = NULL;
2488
2489 amount = gsb_data_scheduled_get_amount (scheduled_number_tmp);
2490 tmp_str = utils_real_get_string_with_currency (amount,
2491 gsb_data_scheduled_get_currency_number
2492 (scheduled_number_tmp),
2493 TRUE);
2494 if (line[COL_NB_AMOUNT] && g_utf8_strchr (line[COL_NB_AMOUNT], -1, '-'))
2495 color_str = (gchar*)"red";
2496 else
2497 {
2498 g_free (color_str);
2499 color_str = NULL;
2500 }
2501 gtk_tree_store_set (store,
2502 &child_iter,
2503 COL_NB_AMOUNT, tmp_str,
2504 SCHEDULER_COL_NB_AMOUNT_COLOR, color_str,
2505 -1);
2506 }
2507 }
2508 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &child_iter));
2509
2510 gsb_scheduler_list_update_white_child (white_line_number, mother_number);
2511 }
2512 }
2513 while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
2514 }
2515
2516 return FALSE;
2517 }
2518
2519 /**
2520 * set the background colors of the list
2521 * just for normal scheduled transactions, not for children of split
2522 *
2523 * \param tree_view
2524 *
2525 * \return FALSE
2526 **/
gsb_scheduler_list_set_background_color(GtkWidget * tree_view)2527 gboolean gsb_scheduler_list_set_background_color (GtkWidget *tree_view)
2528 {
2529 GtkTreeStore *store;
2530 GtkTreeModel *sort_model;
2531 GtkTreePath *sorted_path;
2532 GtkTreePath *path;
2533 gint current_color;
2534
2535 if (!tree_view)
2536 return FALSE;
2537
2538 sort_model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
2539 store = GTK_TREE_STORE (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model)));
2540
2541 current_color = 0;
2542 sorted_path = gtk_tree_path_new_first ();
2543
2544 while ((path = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT (sort_model), sorted_path)))
2545 {
2546 GtkTreeIter iter;
2547 gint virtual_transaction;
2548
2549 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
2550
2551 gtk_tree_model_get (GTK_TREE_MODEL (store),
2552 &iter,
2553 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_transaction,
2554 -1);
2555
2556 if (virtual_transaction)
2557 gtk_tree_store_set (store,
2558 &iter,
2559 SCHEDULER_COL_NB_BACKGROUND, gsb_rgba_get_couleur ("background_scheduled"),
2560 -1);
2561 else
2562 {
2563 gtk_tree_store_set (store,
2564 &iter,
2565 SCHEDULER_COL_NB_BACKGROUND,
2566 gsb_rgba_get_couleur_with_indice ("couleur_fond", current_color),
2567 -1);
2568 current_color = !current_color;
2569 }
2570
2571 gtk_tree_path_free (path);
2572
2573 /* needn't to go in a child because the color is always the same, so
2574 * gtk_tree_path_next is enough */
2575 gtk_tree_path_next (sorted_path);
2576 }
2577
2578 return FALSE;
2579 }
2580
2581 /**
2582 * select the given scheduled transaction
2583 *
2584 * \param scheduled_number
2585 *
2586 * \return FALSE
2587 **/
gsb_scheduler_list_select(gint scheduled_number)2588 gboolean gsb_scheduler_list_select (gint scheduled_number)
2589 {
2590 GtkTreeIter *iter;
2591 GtkTreeIter iter_sort;
2592 GtkTreePath *path = NULL;
2593 gint mother_number;
2594
2595 devel_debug_int (scheduled_number);
2596
2597 /* if it's a split child, we must open the mother to select it */
2598 mother_number = gsb_data_scheduled_get_mother_scheduled_number (scheduled_number);
2599 if (mother_number)
2600 {
2601 GtkTreeIter *iter_mother;
2602 GtkTreeIter iter_mother_sort;
2603
2604 iter_mother = gsb_scheduler_list_get_iter_from_scheduled_number (mother_number);
2605 if (iter_mother)
2606 {
2607
2608 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (tree_model_sort_scheduler_list),
2609 &iter_mother_sort,
2610 iter_mother);
2611 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort_scheduler_list), &iter_mother_sort);
2612 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view_scheduler_list), path, TRUE);
2613 gtk_tree_iter_free (iter_mother);
2614 }
2615 }
2616
2617 /* now can work with the transaction we want to select */
2618 iter = gsb_scheduler_list_get_iter_from_scheduled_number (scheduled_number);
2619
2620 if (!iter)
2621 return FALSE;
2622
2623 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (tree_model_sort_scheduler_list),
2624 &iter_sort,
2625 iter);
2626
2627 gtk_tree_selection_select_iter (GTK_TREE_SELECTION (gtk_tree_view_get_selection
2628 (GTK_TREE_VIEW (tree_view_scheduler_list))),
2629 &iter_sort);
2630
2631 /* move the tree view to the selection */
2632 if (path == NULL)
2633 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort_scheduler_list), &iter_sort);
2634
2635 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (tree_view_scheduler_list), path, NULL, FALSE, 0.0, 0.0);
2636
2637 gtk_tree_iter_free (iter);
2638 gtk_tree_path_free (path);
2639
2640 return FALSE;
2641 }
2642
2643 /**
2644 * find the date untill we want to show the scheduled transactions
2645 * on the scheduled list, with the user configuration
2646 *
2647 * \param
2648 *
2649 * \return a newly allocated final date or NULL for unique view
2650 **/
gsb_scheduler_list_get_end_date_scheduled_showed(void)2651 GDate *gsb_scheduler_list_get_end_date_scheduled_showed (void)
2652 {
2653 GDate *end_date;
2654 GrisbiAppConf *a_conf;
2655
2656 a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
2657
2658 /* on récupère la date du jour et la met dans end_date pour les
2659 * vérifications ultérieures */
2660 end_date = gdate_today ();
2661
2662 /* on calcule la date de fin de l'affichage */
2663 switch (etat.affichage_echeances)
2664 {
2665 case SCHEDULER_PERIODICITY_ONCE_VIEW:
2666 return NULL;
2667 break;
2668
2669 case SCHEDULER_PERIODICITY_WEEK_VIEW:
2670 g_date_add_days (end_date, 7);
2671 g_date_add_months (end_date, 0);
2672 break;
2673
2674 case SCHEDULER_PERIODICITY_MONTH_VIEW:
2675 g_date_add_months (end_date, 1);
2676 end_date->day = 1;
2677 g_date_subtract_days (end_date, 1);
2678 break;
2679
2680 case SCHEDULER_PERIODICITY_TWO_MONTHS_VIEW:
2681 g_date_add_months (end_date, 2);
2682 end_date->day = 1;
2683 g_date_subtract_days (end_date, 1);
2684 break;
2685
2686 case SCHEDULER_PERIODICITY_TRIMESTER_VIEW:
2687 g_date_add_months (end_date, 3);
2688 end_date->day = 1;
2689 g_date_subtract_days (end_date, 1);
2690 break;
2691
2692 case SCHEDULER_PERIODICITY_YEAR_VIEW:
2693 g_date_add_years (end_date, 1);
2694 end_date->day = 1;
2695 end_date->month = 1;
2696 g_date_subtract_days (end_date, 1);
2697 break;
2698
2699 case SCHEDULER_PERIODICITY_CUSTOM_VIEW:
2700 switch (etat.affichage_echeances_perso_j_m_a)
2701 {
2702 case PERIODICITY_DAYS:
2703 g_date_add_days (end_date, etat.affichage_echeances_perso_nb_libre);
2704 break;
2705
2706 case PERIODICITY_WEEKS:
2707 g_date_add_days (end_date, etat.affichage_echeances_perso_nb_libre * 7);
2708 break;
2709
2710 case PERIODICITY_MONTHS:
2711 g_date_add_months (end_date, etat.affichage_echeances_perso_nb_libre);
2712 if (a_conf->execute_scheduled_of_month) /* dans ce cas on affiche toutes les transactions du mois */
2713 {
2714 GDate *tmp_date;
2715
2716 tmp_date = end_date;
2717 end_date = gsb_date_get_last_day_of_month (tmp_date);
2718 g_date_free (tmp_date);
2719 }
2720 break;
2721
2722 case PERIODICITY_YEARS:
2723 g_date_add_years (end_date, etat.affichage_echeances_perso_nb_libre);
2724 break;
2725 }
2726 }
2727 return end_date;
2728 }
2729
2730 /**
2731 * get the current selected transaction and return it
2732 * if it's a virtual transaction, return 0
2733 *
2734 * \param
2735 *
2736 * \return the current scheduled transaction number
2737 **/
gsb_scheduler_list_get_current_scheduled_number(void)2738 gint gsb_scheduler_list_get_current_scheduled_number (void)
2739 {
2740 GList *list_tmp;
2741 GtkTreeModel *model;
2742 GtkTreeIter iter;
2743 GtkWidget *tree_view;
2744 gint scheduled_number;
2745 gint virtual_transaction;
2746
2747 tree_view = gsb_scheduler_list_get_tree_view ();
2748 list_tmp = gtk_tree_selection_get_selected_rows (gtk_tree_view_get_selection
2749 (GTK_TREE_VIEW (tree_view)),
2750 &model);
2751
2752 if (!list_tmp)
2753 return 0;
2754
2755 gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, list_tmp->data);
2756 gtk_tree_model_get (GTK_TREE_MODEL (model),
2757 &iter,
2758 SCHEDULER_COL_NB_TRANSACTION_NUMBER, &scheduled_number,
2759 SCHEDULER_COL_NB_VIRTUAL_TRANSACTION, &virtual_transaction,
2760 -1);
2761
2762 g_list_free_full (list_tmp, (GDestroyNotify) gtk_tree_path_free);
2763
2764 if (virtual_transaction)
2765 return 0;
2766 else
2767 return scheduled_number;
2768 }
2769
2770 /**
2771 * edit the scheduling transaction given in param
2772 *
2773 * \param scheduled_number the number, -1 if new scheduled transaction or < -1 if new child of split
2774 *
2775 * \return FALSE
2776 **/
gsb_scheduler_list_edit_transaction(gint scheduled_number)2777 gboolean gsb_scheduler_list_edit_transaction (gint scheduled_number)
2778 {
2779 devel_debug_int (scheduled_number);
2780 if (scheduled_number == 0)
2781 {
2782 gint tmp_number;
2783
2784 tmp_number = gsb_scheduler_list_get_current_scheduled_number ();
2785 gsb_form_fill_by_transaction (tmp_number, FALSE, TRUE);
2786 last_scheduled_number = tmp_number;
2787 }
2788 else
2789 {
2790 gsb_form_fill_by_transaction (scheduled_number, FALSE, TRUE);
2791 last_scheduled_number = scheduled_number;
2792 }
2793
2794 return FALSE;
2795 }
2796
2797 /**
2798 * delete the current selected transaction, but called by menu
2799 * just call gsb_scheduler_list_delete_scheduled_transaction with show_warning = TRUE
2800 * because cannot do that by the signal
2801 *
2802 * \param button
2803 * \param
2804 *
2805 * \return FALSE
2806 **/
gsb_scheduler_list_delete_scheduled_transaction_by_menu(GtkWidget * button,gpointer null)2807 gboolean gsb_scheduler_list_delete_scheduled_transaction_by_menu (GtkWidget *button,
2808 gpointer null)
2809 {
2810 gsb_scheduler_list_delete_scheduled_transaction (0, TRUE);
2811 return FALSE;
2812 }
2813
2814 /**
2815 * delete the scheduled transaction
2816 *
2817 * \param scheduled_number the transaction to delete
2818 * \param show_warning TRUE to warn, FALSE to delete directly
2819 * !!this don't affect the question to delete only the occurence or the whole scheduled transaction
2820 * it affects only for children of split, and especially deleting the white line child
2821 *
2822 * \return FALSE
2823 **/
gsb_scheduler_list_delete_scheduled_transaction(gint scheduled_number,gboolean show_warning)2824 gboolean gsb_scheduler_list_delete_scheduled_transaction (gint scheduled_number,
2825 gboolean show_warning)
2826 {
2827 gchar *tmp_str;
2828 gint mother_number = 0;
2829 gint result;
2830 gint msg_no = 0;
2831
2832 devel_debug_int (scheduled_number);
2833
2834 if (!scheduled_number)
2835 scheduled_number = gsb_scheduler_list_get_current_scheduled_number ();
2836
2837 /* return for white line only if show_warning is set
2838 * (means the action is not automatic) */
2839 if (scheduled_number <= 0 && show_warning)
2840 return FALSE;
2841
2842 mother_number = gsb_data_scheduled_get_mother_scheduled_number (scheduled_number);
2843
2844 /* show a warning */
2845 if (show_warning)
2846 {
2847 if (mother_number)
2848 {
2849 /* ask all the time for a child */
2850 tmp_str = g_strdup_printf (_("Do you really want to delete the child of the "
2851 "scheduled transaction with party '%s' ?"),
2852 gsb_data_payee_get_name (gsb_data_scheduled_get_party_number
2853 (scheduled_number),
2854 FALSE));
2855 if (!dialogue_conditional_yes_no_with_items ("tab_delete_msg", "delete-child-scheduled", tmp_str))
2856 {
2857 g_free (tmp_str);
2858
2859 return FALSE;
2860 }
2861 g_free (tmp_str);
2862 }
2863 else
2864 {
2865 /* for a normal scheduled, ask only if no frequency, else, it will
2866 * have another dialog to delete the occurence or the transaction */
2867 tmp_str = g_strdup_printf (_("Do you really want to delete the scheduled "
2868 "transaction with party '%s' ?"),
2869 gsb_data_payee_get_name (gsb_data_scheduled_get_party_number
2870 (scheduled_number),
2871 FALSE));
2872 if (!gsb_data_scheduled_get_frequency (scheduled_number)
2873 && !dialogue_conditional_yes_no_with_items ("tab_delete_msg", "delete-scheduled", tmp_str))
2874 {
2875 g_free (tmp_str);
2876
2877 return FALSE;
2878 }
2879 g_free (tmp_str);
2880 }
2881 }
2882
2883 /* split with child of split or normal scheduled,
2884 * for a child, we directly delete it, for mother, ask
2885 * for just that occurrence or the complete transaction */
2886 if (mother_number)
2887 {
2888 gint white_line_number;
2889
2890 /* !!important to remove first from the list... */
2891 gsb_scheduler_list_remove_transaction_from_list (scheduled_number);
2892 gsb_data_scheduled_remove_scheduled (scheduled_number);
2893
2894 white_line_number = gsb_data_scheduled_get_white_line (mother_number);
2895 gsb_scheduler_list_update_white_child (white_line_number, mother_number);
2896 }
2897 else
2898 {
2899 /* ask if we want to remove only the current one (so only change the date
2900 * for the next) or all (so remove the transaction */
2901 if (gsb_data_scheduled_get_frequency (scheduled_number))
2902 {
2903 GtkWidget *checkbox;
2904 GtkWidget *dialog = NULL;
2905 GtkWidget *vbox;
2906 gchar *occurrences;
2907 ConditionalMsg *warning;
2908
2909 warning = (ConditionalMsg*) dialogue_get_tab_delete_msg ();
2910 msg_no = dialogue_conditional_yes_no_get_no_struct (warning,
2911 "delete-scheduled-occurrences");
2912
2913 if (msg_no < 0)
2914 return FALSE;
2915
2916 if ((warning+msg_no)->hidden)
2917 result = (warning+msg_no)->default_answer;
2918 else
2919 {
2920 tmp_str = utils_real_get_string (gsb_data_scheduled_get_amount (scheduled_number));
2921 occurrences = g_strdup_printf (_("Do you want to delete just this occurrence or "
2922 "the whole scheduled transaction?\n\n%s : %s [%s %s]"),
2923 gsb_format_gdate (gsb_data_scheduled_get_date (scheduled_number)),
2924 gsb_data_payee_get_name (gsb_data_scheduled_get_party_number
2925 (scheduled_number),
2926 FALSE),
2927 tmp_str,
2928 gsb_data_currency_get_name (gsb_data_scheduled_get_currency_number
2929 (scheduled_number)));
2930 g_free (tmp_str);
2931
2932 dialog = dialogue_special_no_run (GTK_MESSAGE_QUESTION,
2933 GTK_BUTTONS_NONE,
2934 occurrences,
2935 _("Delete this scheduled transaction?"));
2936
2937 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
2938 "gtk-cancel", 2,
2939 _("All the occurrences"), 1,
2940 _("Only this one"), 0,
2941 NULL);
2942
2943 vbox = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
2944
2945 checkbox = gtk_check_button_new_with_label (_("Keep this choice and no longer see this message?"));
2946 g_signal_connect (G_OBJECT (checkbox),
2947 "toggled",
2948 G_CALLBACK (dialogue_update_struct_message),
2949 (warning+msg_no));
2950 gtk_box_pack_start (GTK_BOX (vbox), checkbox, TRUE, TRUE, MARGIN_BOX);
2951 gtk_widget_show_all (checkbox);
2952
2953 result = gtk_dialog_run (GTK_DIALOG (dialog));
2954
2955 (warning+msg_no)->default_answer = result;
2956 g_free (occurrences);
2957 gtk_widget_destroy (dialog);
2958 }
2959 }
2960 else
2961 result = 1;
2962
2963 switch (result)
2964 {
2965 case 0:
2966 if (gsb_scheduler_increase_scheduled (scheduled_number))
2967 gsb_scheduler_list_update_transaction_in_list (scheduled_number);
2968 break;
2969
2970 case 1:
2971 /* !!important to remove first from the list... */
2972 gsb_scheduler_list_remove_transaction_from_list (scheduled_number);
2973 gsb_data_scheduled_remove_scheduled (scheduled_number);
2974 break;
2975 }
2976 }
2977
2978 gsb_scheduler_list_set_background_color (gsb_scheduler_list_get_tree_view ());
2979
2980 gsb_calendar_update ();
2981 run.mise_a_jour_liste_echeances_manuelles_accueil = TRUE;
2982
2983 gsb_file_set_modified (TRUE);
2984
2985 return FALSE;
2986 }
2987
2988 /**
2989 * Clone selected transaction if any. Update user interface as well.
2990 *
2991 * \param menu_item
2992 * \param scheduled_number
2993 *
2994 * \return FALSE
2995 */
gsb_scheduler_list_clone_selected_scheduled(GtkWidget * menu_item,gint * scheduled_number)2996 gboolean gsb_scheduler_list_clone_selected_scheduled (GtkWidget *menu_item,
2997 gint *scheduled_number)
2998 {
2999 gint new_scheduled_number;
3000 gint tmp_scheduled_number;
3001
3002 if (scheduled_number == NULL)
3003 tmp_scheduled_number = gsb_scheduler_list_get_current_scheduled_number ();
3004 else
3005 tmp_scheduled_number = GPOINTER_TO_INT (scheduled_number);
3006
3007 new_scheduled_number = gsb_data_scheduled_new_scheduled ();
3008
3009 gsb_data_scheduled_copy_scheduled (tmp_scheduled_number, new_scheduled_number);
3010
3011 if (gsb_data_scheduled_get_split_of_scheduled (tmp_scheduled_number))
3012 {
3013 GSList *tmp_list;
3014
3015 tmp_list = g_slist_copy (gsb_data_scheduled_get_scheduled_list ());
3016
3017 while (tmp_list)
3018 {
3019 gint split_scheduled_number;
3020
3021 split_scheduled_number = gsb_data_scheduled_get_scheduled_number (tmp_list->data);
3022
3023 if (gsb_data_scheduled_get_mother_scheduled_number (split_scheduled_number) == tmp_scheduled_number)
3024 {
3025 gint new_number;
3026
3027 new_number = gsb_data_scheduled_new_scheduled ();
3028 gsb_data_scheduled_copy_scheduled (split_scheduled_number, new_number);
3029 gsb_data_scheduled_set_mother_scheduled_number (new_number, new_scheduled_number);
3030 }
3031
3032 tmp_list = tmp_list->next;
3033 }
3034 }
3035
3036 gsb_scheduler_list_fill_list (gsb_scheduler_list_get_tree_view ());
3037 gsb_scheduler_list_set_background_color (gsb_scheduler_list_get_tree_view ());
3038 gsb_scheduler_list_select (new_scheduled_number);
3039
3040 gsb_file_set_modified (TRUE);
3041
3042 return FALSE;
3043 }
3044
3045 /**
3046 *
3047 *
3048 * \param
3049 *
3050 * \return
3051 **/
gsb_scheduler_list_set_largeur_col(void)3052 gboolean gsb_scheduler_list_set_largeur_col (void)
3053 {
3054 gint i;
3055 gint width;
3056
3057 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS ; i++)
3058 {
3059 width = (scheduler_col_width[i] * (scheduler_current_tree_view_width)) / 100;
3060 if (width > 0)
3061 gtk_tree_view_column_set_fixed_width (scheduler_list_column[i], width);
3062 }
3063
3064 return FALSE;
3065 }
3066
3067 /**
3068 *
3069 *
3070 * \param
3071 *
3072 * \return
3073 **/
gsb_scheduler_list_get_toolbar(void)3074 GtkWidget *gsb_scheduler_list_get_toolbar (void)
3075 {
3076 return scheduler_toolbar;
3077 }
3078
3079 /**
3080 *
3081 *
3082 * \param
3083 *
3084 * \return
3085 **/
gsb_scheduler_list_get_scheduled_transactions_taken(void)3086 GSList *gsb_scheduler_list_get_scheduled_transactions_taken (void)
3087 {
3088 return scheduled_transactions_taken;
3089 }
3090
3091 /**
3092 *
3093 *
3094 * \param
3095 *
3096 * \return
3097 **/
gsb_scheduler_list_get_scheduled_transactions_to_take(void)3098 GSList *gsb_scheduler_list_get_scheduled_transactions_to_take (void)
3099 {
3100 return scheduled_transactions_to_take;
3101 }
3102
3103 /**
3104 * Initialise le tableau des largeurs de colonnes du treeview des opérations
3105 *
3106 * \param description Chaine contenant la largeurs des colonnes
3107 * Si NULL utilise les donnes par défaut.
3108 *
3109 * \return
3110 **/
gsb_scheduler_list_init_tab_width_col_treeview(const gchar * description)3111 void gsb_scheduler_list_init_tab_width_col_treeview (const gchar *description)
3112 {
3113 gint i;
3114
3115 if (description && strlen (description))
3116 {
3117 gchar **pointeur_char;
3118 gint somme = 0; /* calcul du % de la dernière colonne */
3119
3120 /* the transactions columns are xx-xx-xx-xx and we want to set in scheduler_col_width[1-2-3...] */
3121 pointeur_char = g_strsplit (description, "-", 0);
3122 if (g_strv_length (pointeur_char) != SCHEDULER_COL_VISIBLE_COLUMNS)
3123 {
3124 /* defaut value for width of columns */
3125 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS ; i++)
3126 scheduler_col_width[i] = scheduler_col_width_init[i];
3127 g_strfreev (pointeur_char);
3128
3129 return;
3130 }
3131
3132 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS -1 ; i++)
3133 {
3134 if (strlen ((const gchar *) pointeur_char[i]) == 0)
3135 scheduler_col_width[i] = scheduler_col_width_init[i];
3136 else
3137 scheduler_col_width[i] = utils_str_atoi (pointeur_char[i]);
3138
3139 if (i != 5)
3140 somme+= scheduler_col_width[i];
3141 }
3142 scheduler_col_width[i] = 100 - somme;
3143 g_strfreev (pointeur_char);
3144
3145 /* si scheduler_col_width[i] est < scheduler_col_width_init[i] on reinitialise la largeur des colonnes */
3146 if (scheduler_col_width[i] < scheduler_col_width_init[i])
3147 {
3148 /* defaut value for width of columns */
3149 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS; i++)
3150 {
3151 scheduler_col_width[i] = scheduler_col_width_init[i];
3152 }
3153 }
3154 }
3155 else
3156 {
3157 for (i = 0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS; i++)
3158 {
3159 scheduler_col_width[i] = scheduler_col_width_init[i];
3160 }
3161 }
3162 }
3163
3164 /**
3165 * retourne une chaine formatée des largeurs de colonnes du treeview prévisions
3166 *
3167 * \param
3168 *
3169 * \return a newly allocated chain to be released
3170 **/
gsb_scheduler_list_get_largeur_col_treeview_to_string(void)3171 gchar *gsb_scheduler_list_get_largeur_col_treeview_to_string (void)
3172 {
3173 gchar *first_string_to_free;
3174 gchar *second_string_to_free;
3175 gchar *tmp_str = NULL;
3176 gint i = 0;
3177
3178 for (i=0 ; i < SCHEDULER_COL_VISIBLE_COLUMNS ; i++)
3179 {
3180 if (tmp_str)
3181 {
3182 first_string_to_free = tmp_str;
3183 second_string_to_free = utils_str_itoa (scheduler_col_width[i]);
3184 tmp_str = g_strconcat (first_string_to_free, "-", second_string_to_free, NULL);
3185 g_free (first_string_to_free);
3186 g_free (second_string_to_free);
3187 }
3188 else
3189 tmp_str = utils_str_itoa (scheduler_col_width[i]);
3190 }
3191
3192 return tmp_str;
3193 }
3194
3195 /**
3196 *
3197 *
3198 * \param
3199 *
3200 * \return
3201 **/
gsb_scheduler_list_update_tree_view(GtkWidget * tree_view)3202 void gsb_scheduler_list_update_tree_view (GtkWidget *tree_view)
3203 {
3204 GrisbiAppConf *a_conf;
3205
3206 devel_debug (NULL);
3207 a_conf = (GrisbiAppConf *) grisbi_app_get_a_conf ();
3208
3209 gsb_scheduler_list_fill_list (tree_view);
3210 gsb_scheduler_list_set_background_color (tree_view);
3211
3212 if (!a_conf->select_scheduled_in_list && last_scheduled_number == -1)
3213 last_scheduled_number = first_scheduler_list_number;
3214
3215 gsb_scheduler_list_select (last_scheduled_number);
3216
3217 }
3218
3219 /**
3220 *
3221 *
3222 * \param
3223 *
3224 * \return
3225 **/
gsb_scheduler_list_set_current_tree_view_width(gint new_tree_view_width)3226 void gsb_scheduler_list_set_current_tree_view_width (gint new_tree_view_width)
3227 {
3228 scheduler_current_tree_view_width = new_tree_view_width;
3229 }
3230
3231 /**
3232 *
3233 *
3234 * \param
3235 *
3236 * \return
3237 **/
3238 /* Local Variables: */
3239 /* c-basic-offset: 4 */
3240 /* End: */
3241