1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2018 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
= transaction_tags_tostring(ope
);
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
, gpointer user_data
)
166 struct ui_multipleedit_dialog_data
*data
;
168 GList
*selection
, *list
;
171 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
173 DB( g_print ("\n[ui-multipleedit] apply\n") );
175 changes
= GLOBALS
->changes_count
;
177 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->treeview
));
178 selection
= gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->treeview
)), &model
);
180 list
= g_list_last(selection
);
186 gboolean change
= FALSE
;
188 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
189 gtk_tree_model_get(model
, &iter
, LST_DSPOPE_DATAS
, &txn
, -1);
191 DB( g_print(" modifying %s %.2f\n", txn
->memo
, txn
->amount
) );
193 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_DATE
) == TRUE
)
195 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_date
)) )
197 txn
->date
= gtk_date_entry_get_date(GTK_DATE_ENTRY(data
->PO_date
));
198 DB( g_print(" -> date: '%d'\n", txn
->date
) );
203 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_INFO
) == TRUE
)
205 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_mode
)) )
207 txn
->paymode
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->NU_mode
));
211 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_info
)) )
220 txt
= gtk_entry_get_text(GTK_ENTRY(data
->ST_info
));
223 txn
->info
= g_strdup(txt
);
229 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_acc
)) )
231 guint32 nkacc
= ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data
->PO_acc
));
233 if( transaction_acc_move(txn
, txn
->kacc
, nkacc
) )
237 DB( g_print(" -> acc: '%d'\n", nkacc
) );
238 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
239 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
244 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_PAYEE
) == TRUE
)
246 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_pay
)) )
248 txn
->kpay
= ui_pay_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data
->PO_pay
));
249 DB( g_print(" -> payee: '%d'\n", txn
->kpay
) );
254 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_CATEGORY
) == TRUE
)
256 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_cat
)) )
258 if(!(txn
->flags
& OF_SPLIT
))
260 txn
->kcat
= ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data
->PO_cat
));
261 DB( g_print(" -> category: '%d'\n", txn
->kcat
) );
267 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_TAGS
) == TRUE
)
269 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_tags
)) )
271 txt
= (gchar
*)gtk_entry_get_text(GTK_ENTRY(data
->ST_tags
));
274 transaction_tags_parse(txn
, txt
);
275 DB( g_print(" -> tags: '%s'\n", txt
) );
281 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_MEMO
) == TRUE
)
283 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data
->CM_memo
)) )
292 txt
= gtk_entry_get_text(GTK_ENTRY(data
->ST_memo
));
295 txn
->memo
= g_strdup(txt
);
301 /* since 5.1 date and amount are no more editable
302 case LST_DSPOPE_DATE:
303 txn->date = gtk_date_entry_get_date(GTK_DATE_ENTRY(widget1));
304 data->do_sort = TRUE;
305 refreshbalance = TRUE;
307 case LST_DSPOPE_EXPENSE:
308 case LST_DSPOPE_INCOME:
309 case LST_DSPOPE_AMOUNT:
310 txn->flags &= ~(OF_INCOME); //delete flag
311 txn->amount = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget1));
312 if(txn->amount > 0) txn->flags |= OF_INCOME;
313 refreshbalance = TRUE;
319 txn
->flags
|= OF_CHANGED
;
320 GLOBALS
->changes_count
++;
323 if( data
->has_xfer
&& txn
->paymode
== PAYMODE_INTXFER
)
326 child
= transaction_xfer_child_strong_get(txn
);
327 transaction_xfer_child_sync(txn
, child
);
330 list
= g_list_previous(list
);
333 g_list_foreach(selection
, (GFunc
)gtk_tree_path_free
, NULL
);
334 g_list_free(selection
);
336 return GLOBALS
->changes_count
- changes
;
340 static gboolean
ui_multipleedit_dialog_destroy( GtkWidget
*widget
, gpointer user_data
)
342 struct ui_multipleedit_dialog_data
*data
;
344 data
= g_object_get_data(G_OBJECT(widget
), "inst_data");
346 DB( g_print ("\n[ui-multipleedit] destroy event occurred\n") );
353 GtkWidget
*ui_multipleedit_dialog_new(GtkWindow
*parent
, GtkTreeView
*treeview
)
355 struct ui_multipleedit_dialog_data
*data
;
356 GtkWidget
*dialog
, *content_area
;
357 GtkWidget
*group_grid
, *label
, *widget
, *toggle
;
360 DB( g_print ("\n[ui-multipleedit] new\n") );
362 data
= g_malloc0(sizeof(struct ui_multipleedit_dialog_data
));
364 dialog
= gtk_dialog_new_with_buttons (NULL
,
373 //g_signal_connect (dialog, "delete_event", G_CALLBACK (register_panel_dispose), (gpointer)data);
374 g_signal_connect (dialog
, "destroy", G_CALLBACK (ui_multipleedit_dialog_destroy
), (gpointer
)data
);
376 //store our window private data
377 g_object_set_data(G_OBJECT(dialog
), "inst_data", (gpointer
)data
);
378 DB( g_print(" - new window=%p, inst_data=%p\n", dialog
, data
) );
380 data
->window
= dialog
;
381 data
->treeview
= treeview
;
383 ui_multipleedit_dialog_init(dialog
, NULL
);
386 gtk_window_set_title (GTK_WINDOW (data
->window
), _("Multiple edit transactions"));
388 content_area
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
390 group_grid
= gtk_grid_new ();
391 gtk_grid_set_row_spacing (GTK_GRID (group_grid
), SPACING_SMALL
);
392 gtk_grid_set_column_spacing (GTK_GRID (group_grid
), SPACING_MEDIUM
);
393 gtk_container_set_border_width (GTK_CONTAINER(group_grid
), SPACING_MEDIUM
);
394 gtk_container_add (GTK_CONTAINER (content_area
), group_grid
);
398 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_DATE
) == TRUE
)
401 label
= make_label_widget(_("_Date:"));
402 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
403 widget
= gtk_check_button_new();
404 data
->CM_date
= widget
;
405 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
406 widget
= gtk_date_entry_new();
407 data
->PO_date
= widget
;
408 gtk_widget_set_hexpand (widget
, TRUE
);
409 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
411 g_signal_connect (data
->CM_date
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
414 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_INFO
) == TRUE
)
417 label
= make_label_widget(_("Pa_yment:"));
418 data
->LB_mode
= label
;
419 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
420 toggle
= gtk_check_button_new();
421 data
->CM_mode
= toggle
;
422 gtk_grid_attach (GTK_GRID (group_grid
), toggle
, 1, row
, 1, 1);
423 widget
= make_paymode_nointxfer (label
);
424 data
->NU_mode
= widget
;
425 gtk_widget_set_hexpand (widget
, TRUE
);
426 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
428 g_signal_connect (data
->CM_mode
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
431 label
= make_label_widget(_("_Info:"));
432 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
433 widget
= gtk_check_button_new();
434 data
->CM_info
= widget
;
435 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
436 widget
= make_string(label
);
437 data
->ST_info
= widget
;
438 gtk_widget_set_hexpand (widget
, TRUE
);
439 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
441 g_signal_connect (data
->CM_info
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
445 label
= make_label_widget(_("A_ccount:"));
446 data
->LB_acc
= label
;
447 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
448 widget
= gtk_check_button_new();
449 data
->CM_acc
= widget
;
450 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
451 widget
= ui_acc_comboboxentry_new(label
);
452 data
->PO_acc
= widget
;
453 gtk_widget_set_hexpand (widget
, TRUE
);
454 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
456 g_signal_connect (data
->CM_acc
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
458 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_PAYEE
) == TRUE
)
461 label
= make_label_widget(_("_Payee:"));
462 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
463 widget
= gtk_check_button_new();
464 data
->CM_pay
= widget
;
465 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
466 widget
= ui_pay_comboboxentry_new(label
);
467 data
->PO_pay
= widget
;
468 gtk_widget_set_hexpand (widget
, TRUE
);
469 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
471 g_signal_connect (data
->CM_pay
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
474 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_CATEGORY
) == TRUE
)
477 label
= make_label_widget(_("_Category:"));
478 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
479 widget
= gtk_check_button_new();
480 data
->CM_cat
= widget
;
481 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
482 widget
= ui_cat_comboboxentry_new(label
);
483 data
->PO_cat
= widget
;
484 gtk_widget_set_hexpand (widget
, TRUE
);
485 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
487 g_signal_connect (data
->CM_cat
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
490 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_TAGS
) == TRUE
)
493 label
= make_label_widget(_("Ta_gs:"));
494 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
495 widget
= gtk_check_button_new();
496 data
->CM_tags
= widget
;
497 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
498 widget
= make_string(label
);
499 data
->ST_tags
= widget
;
500 gtk_widget_set_hexpand (widget
, TRUE
);
501 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
503 g_signal_connect (data
->CM_tags
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
506 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_MEMO
) == TRUE
)
509 label
= make_label_widget(_("M_emo:"));
510 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
511 widget
= gtk_check_button_new();
512 data
->CM_memo
= widget
;
513 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
514 widget
= make_memo_entry(label
);
515 data
->ST_memo
= widget
;
516 gtk_widget_set_hexpand (widget
, TRUE
);
517 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
519 g_signal_connect (data
->CM_memo
, "toggled", G_CALLBACK (ui_multipleedit_dialog_update
), NULL
);
523 ui_multipleedit_dialog_update(dialog
, NULL
);
525 ui_acc_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_acc
), GLOBALS
->h_acc
, ACC_LST_INSERT_NORMAL
);
526 ui_pay_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_pay
), GLOBALS
->h_pay
);
527 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->h_cat
);
529 gtk_widget_show_all (dialog
);
531 if(data
->has_xfer
== TRUE
)
533 hb_widget_visible (data
->LB_acc
, FALSE
);
534 hb_widget_visible (data
->CM_acc
, FALSE
);
535 hb_widget_visible (data
->PO_acc
, FALSE
);
538 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data
->treeview
), LST_DSPOPE_INFO
) == TRUE
)
540 if(data
->has_xfer
== TRUE
)
542 hb_widget_visible (data
->LB_mode
, FALSE
);
543 hb_widget_visible (data
->CM_mode
, FALSE
);
544 hb_widget_visible (data
->NU_mode
, FALSE
);