]> Dogcows Code - chaz/homebank/blob - src/ui-txn-multi.c
import homebank-5.1.7
[chaz/homebank] / src / ui-txn-multi.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2018 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
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.
10 *
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.
15 *
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/>.
18 */
19
20 #include "homebank.h"
21
22 #include "ui-txn-multi.h"
23
24 #include "ui-account.h"
25 #include "ui-payee.h"
26 #include "ui-category.h"
27 #include "gtk-dateentry.h"
28 #include "list_operation.h"
29
30
31 /****************************************************************************/
32 /* Debug macros */
33 /****************************************************************************/
34 #define MYDEBUG 0
35
36 #if MYDEBUG
37 #define DB(x) (x);
38 #else
39 #define DB(x);
40 #endif
41
42 /* our global datas */
43 extern struct HomeBank *GLOBALS;
44 extern struct Preferences *PREFS;
45
46
47 void ui_multipleedit_dialog_prefill( GtkWidget *widget, Transaction *ope, gint column_id )
48 {
49 struct ui_multipleedit_dialog_data *data;
50 gchar *tagstr;
51
52 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
53
54 DB( g_print ("\n[ui-multipleedit] prefill\n") );
55
56 if(ope != NULL)
57 //if(col_id >= LST_DSPOPE_DATE && col_id != LST_DSPOPE_BALANCE)
58 {
59 switch( column_id )
60 {
61 case LST_DSPOPE_DATE:
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);
64 break;
65 case LST_DSPOPE_INFO:
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);
70 break;
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);
74 break;
75 case LST_DSPOPE_MEMO:
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);
78 break;
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);
82 break;
83 case LST_DSPOPE_TAGS:
84 tagstr = transaction_tags_tostring(ope);
85 gtk_entry_set_text(GTK_ENTRY(data->ST_tags), (tagstr != NULL) ? tagstr : "");
86 g_free(tagstr);
87 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(data->CM_tags), TRUE);
88 break;
89 }
90 }
91 }
92
93
94 static void ui_multipleedit_dialog_update( GtkWidget *widget, gpointer user_data )
95 {
96 struct ui_multipleedit_dialog_data *data;
97
98 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
99
100 DB( g_print ("\n[ui-multipleedit] update\n") );
101
102 if(data->PO_date)
103 gtk_widget_set_sensitive (data->PO_date, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_date)) );
104
105 if(data->NU_mode && data->ST_info)
106 {
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)) );
109 }
110
111 if(data->PO_acc)
112 gtk_widget_set_sensitive (data->PO_acc , gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_acc )) );
113
114 if(data->PO_pay)
115 gtk_widget_set_sensitive (data->PO_pay , gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_pay )) );
116
117 if(data->PO_cat)
118 gtk_widget_set_sensitive (data->PO_cat , gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_cat )) );
119
120 if(data->ST_tags)
121 gtk_widget_set_sensitive (data->ST_tags, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_tags)) );
122
123 if(data->ST_memo)
124 gtk_widget_set_sensitive (data->ST_memo, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_memo)) );
125 }
126
127
128 static void ui_multipleedit_dialog_init( GtkWidget *widget, gpointer user_data )
129 {
130 struct ui_multipleedit_dialog_data *data;
131 GtkTreeModel *model;
132 GList *selection, *list;
133
134 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
135
136 DB( g_print ("\n[ui-multipleedit] init\n") );
137
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);
140
141 data->has_xfer = FALSE;
142
143 list = g_list_last(selection);
144 while(list != NULL)
145 {
146 Transaction *entry;
147 GtkTreeIter iter;
148
149 gtk_tree_model_get_iter(model, &iter, list->data);
150 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &entry, -1);
151
152 if(entry->paymode == PAYMODE_INTXFER)
153 data->has_xfer = TRUE;
154
155 list = g_list_previous(list);
156 }
157
158 g_list_foreach(selection, (GFunc)gtk_tree_path_free, NULL);
159 g_list_free(selection);
160
161 }
162
163
164 gint ui_multipleedit_dialog_apply( GtkWidget *widget, gpointer user_data )
165 {
166 struct ui_multipleedit_dialog_data *data;
167 GtkTreeModel *model;
168 GList *selection, *list;
169 guint changes;
170
171 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
172
173 DB( g_print ("\n[ui-multipleedit] apply\n") );
174
175 changes = GLOBALS->changes_count;
176
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);
179
180 list = g_list_last(selection);
181 while(list != NULL)
182 {
183 Transaction *txn;
184 GtkTreeIter iter;
185 const gchar *txt;
186 gboolean change = FALSE;
187
188 gtk_tree_model_get_iter(model, &iter, list->data);
189 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &txn, -1);
190
191 DB( g_print(" modifying %s %.2f\n", txn->memo, txn->amount) );
192
193 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_DATE) == TRUE )
194 {
195 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_date)) )
196 {
197 txn->date = gtk_date_entry_get_date(GTK_DATE_ENTRY(data->PO_date));
198 DB( g_print(" -> date: '%d'\n", txn->date) );
199 change = TRUE;
200 }
201 }
202
203 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_INFO) == TRUE )
204 {
205 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_mode)) )
206 {
207 txn->paymode = gtk_combo_box_get_active(GTK_COMBO_BOX(data->NU_mode));
208 change = TRUE;
209 }
210
211 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_info)) )
212 {
213 if(txn->info)
214 {
215 g_free(txn->info);
216 txn->info = NULL;
217 change = TRUE;
218 }
219
220 txt = gtk_entry_get_text(GTK_ENTRY(data->ST_info));
221 if (txt && *txt)
222 {
223 txn->info = g_strdup(txt);
224 change = TRUE;
225 }
226 }
227 }
228
229 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_acc)) )
230 {
231 guint32 nkacc = ui_acc_comboboxentry_get_key(GTK_COMBO_BOX(data->PO_acc));
232
233 if( transaction_acc_move(txn, txn->kacc, nkacc) )
234 {
235 GtkTreeIter iter;
236
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);
240 change = TRUE;
241 }
242 }
243
244 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_PAYEE) == TRUE )
245 {
246 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_pay)) )
247 {
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) );
250 change = TRUE;
251 }
252 }
253
254 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_CATEGORY) == TRUE )
255 {
256 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_cat)) )
257 {
258 if(!(txn->flags & OF_SPLIT))
259 {
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) );
262 change = TRUE;
263 }
264 }
265 }
266
267 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_TAGS) == TRUE )
268 {
269 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_tags)) )
270 {
271 txt = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_tags));
272 if (txt && *txt)
273 {
274 transaction_tags_parse(txn, txt);
275 DB( g_print(" -> tags: '%s'\n", txt) );
276 change = TRUE;
277 }
278 }
279 }
280
281 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_MEMO) == TRUE )
282 {
283 if( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(data->CM_memo)) )
284 {
285 if(txn->memo)
286 {
287 g_free(txn->memo);
288 txn->memo = NULL;
289 change = TRUE;
290 }
291
292 txt = gtk_entry_get_text(GTK_ENTRY(data->ST_memo));
293 if (txt && *txt)
294 {
295 txn->memo = g_strdup(txt);
296 change = TRUE;
297 }
298 }
299 }
300
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;
306 break;
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;
314 break;
315 */
316
317 if( change == TRUE )
318 {
319 txn->flags |= OF_CHANGED;
320 GLOBALS->changes_count++;
321 }
322
323 if( data->has_xfer && txn->paymode == PAYMODE_INTXFER )
324 {
325 Transaction *child;
326 child = transaction_xfer_child_strong_get(txn);
327 transaction_xfer_child_sync(txn, child);
328 }
329
330 list = g_list_previous(list);
331 }
332
333 g_list_foreach(selection, (GFunc)gtk_tree_path_free, NULL);
334 g_list_free(selection);
335
336 return GLOBALS->changes_count - changes;
337 }
338
339
340 static gboolean ui_multipleedit_dialog_destroy( GtkWidget *widget, gpointer user_data )
341 {
342 struct ui_multipleedit_dialog_data *data;
343
344 data = g_object_get_data(G_OBJECT(widget), "inst_data");
345
346 DB( g_print ("\n[ui-multipleedit] destroy event occurred\n") );
347
348 g_free(data);
349 return FALSE;
350 }
351
352
353 GtkWidget *ui_multipleedit_dialog_new(GtkWindow *parent, GtkTreeView *treeview)
354 {
355 struct ui_multipleedit_dialog_data *data;
356 GtkWidget *dialog, *content_area;
357 GtkWidget *group_grid, *label, *widget, *toggle;
358 gint row;
359
360 DB( g_print ("\n[ui-multipleedit] new\n") );
361
362 data = g_malloc0(sizeof(struct ui_multipleedit_dialog_data));
363
364 dialog = gtk_dialog_new_with_buttons (NULL,
365 GTK_WINDOW (parent),
366 0,
367 _("_Cancel"),
368 GTK_RESPONSE_REJECT,
369 _("_OK"),
370 GTK_RESPONSE_ACCEPT,
371 NULL);
372
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);
375
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) );
379
380 data->window = dialog;
381 data->treeview = treeview;
382
383 ui_multipleedit_dialog_init(dialog, NULL);
384
385
386 gtk_window_set_title (GTK_WINDOW (data->window), _("Multiple edit transactions"));
387
388 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
389
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);
395
396 row = -1;
397
398 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_DATE) == TRUE )
399 {
400 row++;
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);
410
411 g_signal_connect (data->CM_date , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
412 }
413
414 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_INFO) == TRUE )
415 {
416 row++;
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);
427
428 g_signal_connect (data->CM_mode , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
429
430 row++;
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);
440
441 g_signal_connect (data->CM_info , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
442 }
443
444 row++;
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);
455
456 g_signal_connect (data->CM_acc , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
457
458 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_PAYEE) == TRUE )
459 {
460 row++;
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);
470
471 g_signal_connect (data->CM_pay , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
472 }
473
474 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_CATEGORY) == TRUE )
475 {
476 row++;
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);
486
487 g_signal_connect (data->CM_cat , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
488 }
489
490 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_TAGS) == TRUE )
491 {
492 row++;
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);
502
503 g_signal_connect (data->CM_tags , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
504 }
505
506 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_MEMO) == TRUE )
507 {
508 row++;
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);
518
519 g_signal_connect (data->CM_memo , "toggled", G_CALLBACK (ui_multipleedit_dialog_update), NULL);
520 }
521
522
523 ui_multipleedit_dialog_update(dialog, NULL);
524
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);
528
529 gtk_widget_show_all (dialog);
530
531 if(data->has_xfer == TRUE)
532 {
533 hb_widget_visible (data->LB_acc, FALSE);
534 hb_widget_visible (data->CM_acc, FALSE);
535 hb_widget_visible (data->PO_acc, FALSE);
536 }
537
538 if( list_txn_column_id_isvisible(GTK_TREE_VIEW(data->treeview), LST_DSPOPE_INFO) == TRUE )
539 {
540 if(data->has_xfer == TRUE)
541 {
542 hb_widget_visible (data->LB_mode, FALSE);
543 hb_widget_visible (data->CM_mode, FALSE);
544 hb_widget_visible (data->NU_mode, FALSE);
545 }
546 }
547
548 return dialog;
549 }
This page took 0.060299 seconds and 4 git commands to generate.