1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "ui-txn-multi.h"
24 #include "ui-account.h"
26 #include "ui-category.h"
27 #include "gtk-dateentry.h"
28 #include "list-operation.h"
31 /****************************************************************************/
33 /****************************************************************************/
42 /* our global datas */
43 extern struct HomeBank
*GLOBALS
;
44 extern struct Preferences
*PREFS
;
47 void ui_multipleedit_dialog_prefill( GtkWidget
*widget
, Transaction
*ope
, gint column_id
)
49 struct ui_multipleedit_dialog_data
*data
;
52 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
54 DB( g_print ("\n[ui-multipleedit] prefill\n") );
57 //if(col_id >= LST_DSPOPE_DATE && col_id != LST_DSPOPE_BALANCE)
62 gtk_date_entry_set_date(GTK_DATE_ENTRY(data
->PO_date
), (guint
)ope
->date
);
63 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data
->CM_date
), TRUE
);
66 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->NU_mode
), ope
->paymode
);
67 gtk_entry_set_text(GTK_ENTRY(data
->ST_info
), (ope
->info
!= NULL
) ? ope
->info
: "");
68 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data
->CM_mode
), TRUE
);
69 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data
->CM_info
), TRUE
);
71 case LST_DSPOPE_PAYEE
:
72 ui_pay_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_pay
), ope
->kpay
);
73 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data
->CM_pay
), TRUE
);
76 gtk_entry_set_text(GTK_ENTRY(data
->ST_memo
), (ope
->memo
!= NULL
) ? ope
->memo
: "");
77 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data
->CM_memo
), TRUE
);
79 case LST_DSPOPE_CATEGORY
:
80 ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_cat
), ope
->kcat
);
81 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data
->CM_cat
), TRUE
);
84 tagstr
= tags_tostring(ope
->tags
);
85 gtk_entry_set_text(GTK_ENTRY(data
->ST_tags
), (tagstr
!= NULL
) ? tagstr
: "");
87 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data
->CM_tags
), TRUE
);
94 static void ui_multipleedit_dialog_update( GtkWidget
*widget
, gpointer user_data
)
96 struct ui_multipleedit_dialog_data
*data
;
98 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
100 DB( g_print ("\n[ui-multipleedit] update\n") );
103 gtk_widget_set_sensitive (data
->PO_date
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_date
)) );
105 if(data
->NU_mode
&& data
->ST_info
)
107 gtk_widget_set_sensitive (data
->NU_mode
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_mode
)) );
108 gtk_widget_set_sensitive (data
->ST_info
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_info
)) );
112 gtk_widget_set_sensitive (data
->PO_acc
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_acc
)) );
115 gtk_widget_set_sensitive (data
->PO_pay
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_pay
)) );
118 gtk_widget_set_sensitive (data
->PO_cat
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_cat
)) );
121 gtk_widget_set_sensitive (data
->ST_tags
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_tags
)) );
124 gtk_widget_set_sensitive (data
->ST_memo
, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_memo
)) );
128 static void ui_multipleedit_dialog_init( GtkWidget
*widget
, gpointer user_data
)
130 struct ui_multipleedit_dialog_data
*data
;
132 GList
*selection
, *list
;
134 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
136 DB( g_print ("\n[ui-multipleedit] init\n") );
138 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->treeview
));
139 selection
= gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->treeview
)), &model
);
141 data
->has_xfer
= FALSE
;
143 list
= g_list_last(selection
);
149 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
150 gtk_tree_model_get(model
, &iter
, LST_DSPOPE_DATAS
, &entry
, -1);
152 if(entry
->paymode
== PAYMODE_INTXFER
)
153 data
->has_xfer
= TRUE
;
155 list
= g_list_previous(list
);
158 g_list_foreach(selection
, (GFunc
)gtk_tree_path_free
, NULL
);
159 g_list_free(selection
);
164 gint
ui_multipleedit_dialog_apply( GtkWidget
*widget
, gboolean
*do_sort
)
166 struct ui_multipleedit_dialog_data
*data
;
168 GList
*selection
, *list
;
169 gboolean tmp_sort
= FALSE
;
172 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
174 DB( g_print ("\n[ui-multipleedit] apply\n") );
176 changes
= GLOBALS
->changes_count
;
178 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->treeview
));
179 selection
= gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->treeview
)), &model
);
181 list
= g_list_last(selection
);
187 gboolean change
= FALSE
;
189 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
190 gtk_tree_model_get(model
, &iter
, LST_DSPOPE_DATAS
, &txn
, -1);
192 DB( g_print(" modifying %s %.2f\n", txn
->memo
, txn
->amount
) );
194 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_DATE
) == TRUE
)
196 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_date
)) )
198 guint32 olddate
= txn
->date
;
200 txn
->date
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_date
));
201 DB( g_print(" -> date: '%d'\n", txn
->date
) );
203 //#1270687/1792808: sort if date changed
204 if(olddate
!= txn
->date
)
211 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_INFO
) == TRUE
)
213 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_mode
)) )
215 txn
->paymode
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->NU_mode
));
219 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_info
)) )
228 txt
= gtk_entry_get_text(GTK_ENTRY(data
->ST_info
));
231 txn
->info
= g_strdup(txt
);
237 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_acc
)) )
239 guint32 nkacc
= ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_acc
));
241 if( transaction_acc_move(txn
, txn
->kacc
, nkacc
) )
245 DB( g_print(" -> acc: '%d'\n", nkacc
) );
246 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
247 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
252 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_PAYEE
) == TRUE
)
254 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_pay
)) )
256 txn
->kpay
= ui_pay_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data
->PO_pay
));
257 DB( g_print(" -> payee: '%d'\n", txn
->kpay
) );
262 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_CATEGORY
) == TRUE
)
264 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_cat
)) )
266 if(!(txn
->flags
& OF_SPLIT
))
268 txn
->kcat
= ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data
->PO_cat
));
269 DB( g_print(" -> category: '%d'\n", txn
->kcat
) );
275 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_TAGS
) == TRUE
)
277 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_tags
)) )
279 txt
= (gchar
*)gtk_entry_get_text(GTK_ENTRY(data
->ST_tags
));
283 txn
->tags
= tags_parse(txt
);
284 DB( g_print(" -> tags: '%s'\n", txt
) );
290 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_MEMO
) == TRUE
)
292 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_memo
)) )
301 txt
= gtk_entry_get_text(GTK_ENTRY(data
->ST_memo
));
304 txn
->memo
= g_strdup(txt
);
310 /* since 5.1 date and amount are no more editable
311 case LST_DSPOPE_DATE:
312 txn->date = gtk_date_entry_get_date(GTK_DATE_ENTRY(widget1));
313 data->do_sort = TRUE;
314 refreshbalance = TRUE;
316 case LST_DSPOPE_EXPENSE:
317 case LST_DSPOPE_INCOME:
318 case LST_DSPOPE_AMOUNT:
319 txn->flags &= ~(OF_INCOME); //delete flag
320 txn->amount = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget1));
321 if(txn->amount > 0) txn->flags |= OF_INCOME;
322 refreshbalance = TRUE;
328 txn
->flags
|= OF_CHANGED
;
329 GLOBALS
->changes_count
++;
332 if( data
->has_xfer
&& txn
->paymode
== PAYMODE_INTXFER
)
335 child
= transaction_xfer_child_strong_get(txn
);
336 transaction_xfer_child_sync(txn
, child
);
339 list
= g_list_previous(list
);
342 g_list_foreach(selection
, (GFunc
)gtk_tree_path_free
, NULL
);
343 g_list_free(selection
);
345 if( do_sort
!= NULL
)
348 return GLOBALS
->changes_count
- changes
;
352 static gboolean
ui_multipleedit_dialog_destroy( GtkWidget
*widget
, gpointer user_data
)
354 struct ui_multipleedit_dialog_data
*data
;
356 data
= g_object_get_data(G_OBJECT(widget
), "inst_data");
358 DB( g_print ("\n[ui-multipleedit] destroy event occurred\n") );
365 GtkWidget
*ui_multipleedit_dialog_new(GtkWindow
*parent
, GtkTreeView
*treeview
)
367 struct ui_multipleedit_dialog_data
*data
;
368 GtkWidget
*dialog
, *content_area
;
369 GtkWidget
*group_grid
, *label
, *widget
, *toggle
;
372 DB( g_print ("\n[ui-multipleedit] new\n") );
374 data
= g_malloc0(sizeof(struct ui_multipleedit_dialog_data
));
376 dialog
= gtk_dialog_new_with_buttons (NULL
,
385 //g_signal_connect (dialog, "delete_event", G_CALLBACK (register_panel_dispose), (gpointer)data);
386 g_signal_connect (dialog
, "destroy", G_CALLBACK (ui_multipleedit_dialog_destroy
), (gpointer
)data
);
388 //store our window private data
389 g_object_set_data(G_OBJECT(dialog
), "inst_data", (gpointer
)data
);
390 DB( g_print(" - new window=%p, inst_data=%p\n", dialog
, data
) );
392 data
->window
= dialog
;
393 data
->treeview
= treeview
;
395 ui_multipleedit_dialog_init(dialog
, NULL
);
398 gtk_window_set_title (GTK_WINDOW (data
->window
), _("Multiple edit transactions"));
400 content_area
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
402 group_grid
= gtk_grid_new ();
403 gtk_grid_set_row_spacing (GTK_GRID (group_grid
), SPACING_SMALL
);
404 gtk_grid_set_column_spacing (GTK_GRID (group_grid
), SPACING_MEDIUM
);
405 gtk_container_set_border_width (GTK_CONTAINER(group_grid
), SPACING_MEDIUM
);
406 gtk_container_add (GTK_CONTAINER (content_area
), group_grid
);
410 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_DATE
) == TRUE
)
413 label
= make_label_widget(_("_Date:"));
414 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
415 widget
= gtk_check_button_new();
416 data
->CM_date
= widget
;
417 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
418 widget
= gtk_date_entry_new();
419 data
->PO_date
= widget
;
420 gtk_widget_set_hexpand (widget
, TRUE
);
421 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
423 g_signal_connect (data
->CM_date
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
426 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_INFO
) == TRUE
)
429 label
= make_label_widget(_("Pa_yment:"));
430 data
->LB_mode
= label
;
431 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
432 toggle
= gtk_check_button_new();
433 data
->CM_mode
= toggle
;
434 gtk_grid_attach (GTK_GRID (group_grid
), toggle
, 1, row
, 1, 1);
435 widget
= make_paymode_nointxfer (label
);
436 data
->NU_mode
= widget
;
437 gtk_widget_set_hexpand (widget
, TRUE
);
438 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
440 g_signal_connect (data
->CM_mode
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
443 label
= make_label_widget(_("_Info:"));
444 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
445 widget
= gtk_check_button_new();
446 data
->CM_info
= widget
;
447 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
448 widget
= make_string(label
);
449 data
->ST_info
= widget
;
450 gtk_widget_set_hexpand (widget
, TRUE
);
451 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
453 g_signal_connect (data
->CM_info
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
457 label
= make_label_widget(_("A_ccount:"));
458 data
->LB_acc
= label
;
459 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
460 widget
= gtk_check_button_new();
461 data
->CM_acc
= widget
;
462 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
463 widget
= ui_acc_comboboxentry_new(label
);
464 data
->PO_acc
= widget
;
465 gtk_widget_set_hexpand (widget
, TRUE
);
466 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
468 g_signal_connect (data
->CM_acc
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
470 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_PAYEE
) == TRUE
)
473 label
= make_label_widget(_("_Payee:"));
474 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
475 widget
= gtk_check_button_new();
476 data
->CM_pay
= widget
;
477 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
478 widget
= ui_pay_comboboxentry_new(label
);
479 data
->PO_pay
= widget
;
480 gtk_widget_set_hexpand (widget
, TRUE
);
481 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
483 g_signal_connect (data
->CM_pay
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
486 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_CATEGORY
) == TRUE
)
489 label
= make_label_widget(_("_Category:"));
490 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
491 widget
= gtk_check_button_new();
492 data
->CM_cat
= widget
;
493 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
494 widget
= ui_cat_comboboxentry_new(label
);
495 data
->PO_cat
= widget
;
496 gtk_widget_set_hexpand (widget
, TRUE
);
497 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
499 g_signal_connect (data
->CM_cat
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
502 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_TAGS
) == TRUE
)
505 label
= make_label_widget(_("Ta_gs:"));
506 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
507 widget
= gtk_check_button_new();
508 data
->CM_tags
= widget
;
509 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
510 widget
= make_string(label
);
511 data
->ST_tags
= widget
;
512 gtk_widget_set_hexpand (widget
, TRUE
);
513 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
515 g_signal_connect (data
->CM_tags
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
518 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_MEMO
) == TRUE
)
521 label
= make_label_widget(_("M_emo:"));
522 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
523 widget
= gtk_check_button_new();
524 data
->CM_memo
= widget
;
525 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
526 widget
= make_memo_entry(label
);
527 data
->ST_memo
= widget
;
528 gtk_widget_set_hexpand (widget
, TRUE
);
529 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
531 g_signal_connect (data
->CM_memo
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
535 ui_multipleedit_dialog_update(dialog
, NULL
);
537 ui_acc_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_acc
), GLOBALS
->h_acc
, ACC_LST_INSERT_NORMAL
);
538 ui_pay_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_pay
), GLOBALS
->h_pay
);
539 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->h_cat
);
541 gtk_widget_show_all (dialog
);
543 if(data
->has_xfer
== TRUE
)
545 hb_widget_visible (data
->LB_acc
, FALSE
);
546 hb_widget_visible (data
->CM_acc
, FALSE
);
547 hb_widget_visible (data
->PO_acc
, FALSE
);
550 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_INFO
) == TRUE
)
552 if(data
->has_xfer
== TRUE
)
554 hb_widget_visible (data
->LB_mode
, FALSE
);
555 hb_widget_visible (data
->CM_mode
, FALSE
);
556 hb_widget_visible (data
->NU_mode
, FALSE
);