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 ofdeftransaction_amountchanged
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/>.
23 #include "ui-transaction.h"
24 #include "ui-archive.h"
25 #include "gtk-dateentry.h"
27 #include "ui-category.h"
28 #include "ui-account.h"
34 /****************************************************************************/
36 /****************************************************************************/
45 /* our global datas */
46 extern struct HomeBank
*GLOBALS
;
47 extern struct Preferences
*PREFS
;
50 #define GTK_RESPONSE_SPLIT_REM 10888
53 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
54 static void list_split_number_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
60 path
= gtk_tree_model_get_path(model
, iter
);
61 indices
= gtk_tree_path_get_indices(path
);
62 //num = gtk_tree_path_to_string(path);
63 g_snprintf(num
, 15, "%d", 1 + *indices
);
64 gtk_tree_path_free(path
);
66 g_object_set(renderer
, "text", num
, NULL
);
71 static void list_split_amount_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
74 gchar buf
[G_ASCII_DTOSTR_BUF_SIZE
];
78 gtk_tree_model_get(model
, iter
, 0, &split
, -1);
80 //hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, amount, ope->kcur, GLOBALS->minor);
81 amount
= split
->amount
;
82 g_snprintf(buf
, G_ASCII_DTOSTR_BUF_SIZE
-1, "%.2f", amount
);
84 color
= get_normal_color_amount(amount
);
85 g_object_set(renderer
,
93 static void list_split_memo_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
97 gtk_tree_model_get(model
, iter
, 0, &split
, -1);
99 g_object_set(renderer
, "text", split
->memo
, NULL
);
103 static void list_split_category_cell_data_function (GtkTreeViewColumn
*col
, GtkCellRenderer
*renderer
, GtkTreeModel
*model
, GtkTreeIter
*iter
, gpointer user_data
)
108 gtk_tree_model_get(model
, iter
, 0, &split
, -1);
110 cat
= da_cat_get(split
->kcat
);
113 g_object_set(renderer
, "text", cat
->fullname
, NULL
);
116 g_object_set(renderer
, "text", "", NULL
);
120 static void list_split_populate(struct ui_split_dialog_data
*data
)
127 DB( g_print("\n[list_split] populate\n") );
129 count
= da_splits_length (data
->tmp_splits
);
134 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_split
));
136 gtk_list_store_clear (GTK_LIST_STORE(model
));
138 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
139 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_split
), NULL
); /* Detach model from view */
142 for(i
=0 ; i
< count
; i
++)
144 split
= da_splits_get(data
->tmp_splits
, i
);
146 DB( g_print("- set split %d : %d, %.2f, %s\n", i
, split
->kcat
, split
->amount
, split
->memo
) );
148 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
149 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
155 gtk_tree_view_set_model(GTK_TREE_VIEW(data
->LV_split
), model
); /* Re-attach model to view */
156 g_object_unref(model
);
168 GtkCellRenderer
*renderer
;
169 GtkTreeViewColumn
*column
;
171 DB( g_print("\n[ui_split_listview] new\n") );
175 store
= gtk_list_store_new(1,
180 treeview
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
181 g_object_unref(store
);
183 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview
), PREFS
->grid_lines
);
185 //column 0: line number
186 renderer
= gtk_cell_renderer_text_new ();
187 g_object_set(renderer
, "xalign", 1.0, NULL
);
188 column
= gtk_tree_view_column_new_with_attributes("#", renderer
, NULL
);
189 gtk_tree_view_column_set_alignment (column
, 1.0);
190 gtk_tree_view_column_set_cell_data_func(column
, renderer
, list_split_number_cell_data_function
, NULL
, NULL
);
191 gtk_tree_view_column_set_sizing (column
, GTK_TREE_VIEW_COLUMN_AUTOSIZE
);
192 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
195 // column 1: category
196 renderer
= gtk_cell_renderer_text_new ();
197 g_object_set(renderer
,
198 "ellipsize", PANGO_ELLIPSIZE_END
,
199 "ellipsize-set", TRUE
,
202 column
= gtk_tree_view_column_new_with_attributes(_("Category"), renderer
, NULL
);
204 //gtk_tree_view_column_set_alignment (column, 0.5);
205 gtk_tree_view_column_set_resizable(column
, TRUE
);
207 //gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
208 //gtk_tree_view_column_set_fixed_width( column, HB_MINWIDTH_LIST);
209 gtk_tree_view_column_set_expand (column
, TRUE
);
210 gtk_tree_view_column_set_cell_data_func(column
, renderer
, list_split_category_cell_data_function
, NULL
, NULL
);
211 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
214 renderer
= gtk_cell_renderer_text_new ();
215 g_object_set(renderer
,
216 "ellipsize", PANGO_ELLIPSIZE_END
,
217 "ellipsize-set", TRUE
,
220 column
= gtk_tree_view_column_new_with_attributes(_("Memo"), renderer
, NULL
);
222 //gtk_tree_view_column_set_alignment (column, 0.5);
223 gtk_tree_view_column_set_resizable(column
, TRUE
);
225 //gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
226 //gtk_tree_view_column_set_fixed_width( column, HB_MINWIDTH_LIST);
227 gtk_tree_view_column_set_expand (column
, TRUE
);
228 gtk_tree_view_column_set_cell_data_func(column
, renderer
, list_split_memo_cell_data_function
, NULL
, NULL
);
229 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
233 renderer
= gtk_cell_renderer_text_new ();
234 g_object_set(renderer
, "xalign", 1.0, NULL
);
236 column
= gtk_tree_view_column_new_with_attributes(_("Amount"), renderer
, NULL
);
238 gtk_tree_view_column_set_alignment (column
, 1.0);
239 gtk_tree_view_column_set_resizable(column
, TRUE
);
240 //gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
241 gtk_tree_view_column_set_fixed_width( column
, HB_MINWIDTH_LIST
);
242 gtk_tree_view_column_set_cell_data_func(column
, renderer
, list_split_amount_cell_data_function
, NULL
, NULL
);
243 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
247 //column = gtk_tree_view_column_new();
248 //gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
252 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview
), TRUE
);
253 gtk_tree_view_set_reorderable (GTK_TREE_VIEW(treeview
), TRUE
);
255 //gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_acc_listview_compare_func, NULL, NULL);
256 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
264 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
266 static void ui_split_dialog_filter_text_handler (GtkEntry
*entry
,
272 GtkEditable
*editable
= GTK_EDITABLE(entry
);
274 gchar
*result
= g_new0 (gchar
, length
+1);
276 for (i
=0; i
< length
; i
++)
280 result
[count
++] = text
[i
];
285 g_signal_handlers_block_by_func (G_OBJECT (editable
),
286 G_CALLBACK (ui_split_dialog_filter_text_handler
),
288 gtk_editable_insert_text (editable
, result
, count
, position
);
289 g_signal_handlers_unblock_by_func (G_OBJECT (editable
),
290 G_CALLBACK (ui_split_dialog_filter_text_handler
),
293 g_signal_stop_emission_by_name (G_OBJECT (editable
), "insert-text");
299 static void ui_split_dialog_cb_eval_order(struct ui_split_dialog_data
*data
)
306 DB( g_print("\n[ui_split_dialog] eval order\n") );
308 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_split
));
309 i
=1; valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
314 gtk_tree_model_get (model
, &iter
, 0, &split
, -1);
317 DB( g_print("split pos: %d '%s' %.2f\n", i
, split
->memo
, split
->amount
) );
319 i
++; valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
322 da_splits_sort(data
->tmp_splits
);
326 static void ui_split_dialog_cb_eval_split(GtkWidget
*widget
, gpointer user_data
)
328 struct ui_split_dialog_data
*data
;
329 gboolean tmpval
= FALSE
;
333 DB( g_print("\n[ui_split_dialog] eval split\n") );
335 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
337 amount
= g_strtod(gtk_entry_get_text(GTK_ENTRY(data
->ST_amount
)), NULL
);
339 tmpval
= hb_amount_round(amount
, 2) != 0.0 ? TRUE
: FALSE
;
340 gtk_widget_set_sensitive (data
->BT_apply
, tmpval
);
342 count
= gtk_tree_model_iter_n_children(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_split
)), NULL
);
343 if( count
>= TXN_MAX_SPLIT
)
345 gtk_widget_set_sensitive (data
->BT_add
, tmpval
);
347 DB( g_print(" - txt='%s' amt=%.2f, nbsplit=%d, valid=%d\n", gtk_entry_get_text(GTK_ENTRY(data
->ST_amount
)), amount
, count
, tmpval
) );
352 static void ui_split_dialog_update(GtkWidget
*widget
, gpointer user_data
)
354 struct ui_split_dialog_data
*data
;
358 DB( g_print("\n[ui_split_dialog] update\n") );
360 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
362 count
= da_splits_length (data
->tmp_splits
);
365 tmpval
= gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_split
)), NULL
, NULL
);
366 gtk_widget_set_sensitive (data
->BT_edit
, (data
->isedited
) ? FALSE
: tmpval
);
367 gtk_widget_set_sensitive (data
->BT_rem
, (data
->isedited
) ? FALSE
: tmpval
);
370 tmpval
= (count
> 1) ? TRUE
: FALSE
;
371 gtk_widget_set_sensitive (data
->BT_remall
, (data
->isedited
) ? FALSE
: tmpval
);
373 ui_split_dialog_cb_eval_split(widget
, NULL
);
376 /*amount = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->ST_amount));
377 tmpval = hb_amount_round(amount, 2) != 0.0 ? TRUE : FALSE;
378 gtk_widget_set_sensitive (data->BT_apply, tmpval);
380 if( count >= TXN_MAX_SPLIT )
382 gtk_widget_set_sensitive (data->BT_add, tmpval);
386 gtk_widget_set_sensitive (data
->LV_split
, !data
->isedited
);
388 hb_widget_visible (data
->BT_add
, !data
->isedited
);
390 hb_widget_visible (data
->IM_edit
, data
->isedited
);
391 hb_widget_visible (data
->BT_apply
, data
->isedited
);
392 hb_widget_visible (data
->BT_cancel
, data
->isedited
);
396 static void ui_split_dialog_edit_end(GtkWidget
*widget
, gpointer user_data
)
398 struct ui_split_dialog_data
*data
;
400 DB( g_print("\n[ui_split_dialog] edit_end\n") );
402 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
404 g_signal_handler_block(data
->PO_cat
, data
->hid_cat
);
405 g_signal_handler_block(data
->ST_amount
, data
->hid_amt
);
407 ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_cat
), 0);
408 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->ST_amount
), 0.0);
409 gtk_entry_set_text(GTK_ENTRY(data
->ST_memo
), "");
411 g_signal_handler_unblock(data
->ST_amount
, data
->hid_amt
);
412 g_signal_handler_unblock(data
->PO_cat
, data
->hid_cat
);
414 data
->isedited
= FALSE
;
418 static void ui_split_dialog_edit_start(GtkWidget
*widget
, gpointer user_data
)
420 struct ui_split_dialog_data
*data
;
421 GtkTreeSelection
*selection
;
425 DB( g_print("\n[ui_split_dialog] edit_start\n") );
427 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
429 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_split
));
430 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_split
));
431 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
436 gtk_tree_model_get(model
, &iter
, 0, &split
, -1);
438 ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(data
->PO_cat
), split
->kcat
);
439 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->ST_amount
), split
->amount
);
440 txt
= (split
->memo
!= NULL
) ? split
->memo
: "";
441 gtk_entry_set_text(GTK_ENTRY(data
->ST_memo
), txt
);
443 data
->isedited
= TRUE
;
445 ui_split_dialog_update (data
->dialog
, user_data
);
451 static void ui_split_dialog_cancel_cb(GtkWidget
*widget
, gpointer user_data
)
453 //struct ui_split_dialog_data *data;
455 DB( g_print("\n[ui_split_dialog] cancel\n") );
457 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
459 ui_split_dialog_edit_end(widget
, user_data
);
460 ui_split_dialog_update (widget
, user_data
);
464 static void ui_split_dialog_apply_cb(GtkWidget
*widget
, gpointer user_data
)
466 struct ui_split_dialog_data
*data
;
467 GtkTreeSelection
*selection
;
471 DB( g_print("\n[ui_split_dialog] apply\n") );
473 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
475 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_split
));
476 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
481 gtk_tree_model_get(model
, &iter
, 0, &split
, -1);
482 gtk_spin_button_update (GTK_SPIN_BUTTON(data
->ST_amount
));
483 amount
= gtk_spin_button_get_value(GTK_SPIN_BUTTON(data
->ST_amount
));
486 split
->kcat
= ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data
->PO_cat
));
488 split
->memo
= g_strdup((gchar
*)gtk_entry_get_text(GTK_ENTRY(data
->ST_memo
)));
489 split
->amount
= amount
;
493 ui_split_dialog_edit_end(widget
, user_data
);
494 ui_split_dialog_compute (widget
, data
);
495 ui_split_dialog_update (widget
, user_data
);
499 static void ui_split_dialog_removeall_cb(GtkWidget
*widget
, gpointer user_data
)
501 struct ui_split_dialog_data
*data
;
503 DB( g_print("\n[ui_split_dialog] removeall_cb\n") );
505 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
507 gtk_list_store_clear (GTK_LIST_STORE(gtk_tree_view_get_model (GTK_TREE_VIEW(data
->LV_split
))));
508 da_split_destroy(data
->tmp_splits
);
509 data
->tmp_splits
= da_split_new ();
511 ui_split_dialog_compute (widget
, data
);
512 ui_split_dialog_update (widget
, user_data
);
516 static void ui_split_dialog_remove_cb(GtkWidget
*widget
, gpointer user_data
)
518 struct ui_split_dialog_data
*data
;
519 GtkTreeSelection
*selection
;
523 DB( g_print("\n[ui_split_dialog] remove_cb\n") );
525 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
527 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_split
));
528 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
532 gtk_tree_model_get(model
, &iter
, 0, &split
, -1);
533 //todo: not implemented yet
534 da_splits_remove(data
->tmp_splits
, split
);
535 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
538 ui_split_dialog_compute (widget
, data
);
539 ui_split_dialog_update (widget
, user_data
);
543 static void ui_split_dialog_add_cb(GtkWidget
*widget
, gpointer user_data
)
545 struct ui_split_dialog_data
*data
;
552 DB( g_print("\n[ui_split_dialog] add\n") );
554 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
556 count
= da_splits_length (data
->tmp_splits
);
557 if( count
<= TXN_MAX_SPLIT
)
559 split
= da_split_malloc ();
560 gtk_spin_button_update (GTK_SPIN_BUTTON(data
->ST_amount
));
561 amount
= gtk_spin_button_get_value(GTK_SPIN_BUTTON(data
->ST_amount
));
564 split
->amount
= amount
;
565 split
->kcat
= ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data
->PO_cat
));
566 split
->memo
= g_strdup((gchar
*)gtk_entry_get_text(GTK_ENTRY(data
->ST_memo
)));
568 DB( g_print("- get split : %d, %.2f, %s\n", split
->kcat
, split
->amount
, split
->memo
) );
570 da_splits_append (data
->tmp_splits
, split
);
572 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_split
));
573 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
574 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
578 ui_split_dialog_compute (widget
, data
);
583 //todo: msg max number reached
584 da_split_free(split
);
588 ui_split_dialog_edit_end(widget
, user_data
);
589 ui_split_dialog_update (widget
, user_data
);
593 static void ui_split_dialog_cb_activate_split(GtkWidget
*widget
, gpointer user_data
)
595 struct ui_split_dialog_data
*data
;
597 DB( g_print("\n[ui_split_dialog] cb activate split\n") );
599 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
601 if( data
->isedited
== TRUE
)
602 ui_split_dialog_apply_cb(widget
, NULL
);
604 ui_split_dialog_add_cb(widget
, NULL
);
608 static void ui_split_rowactivated (GtkTreeView
*treeview
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer user_data
)
610 DB( g_print("\n[ui_split_dialog] rowactivated\n") );
612 ui_split_dialog_edit_start(GTK_WIDGET(treeview
), NULL
);
616 static void ui_split_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
618 DB( g_print("\n[ui_split_dialog] selection\n") );
620 ui_split_dialog_update (GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), user_data
);
624 void ui_split_dialog_compute(GtkWidget
*widget
, gpointer user_data
)
626 struct ui_split_dialog_data
*data
;
627 gint i
, count
, nbvalid
;
634 DB( g_print("\n[ui_split_dialog] compute\n") );
636 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
639 data
->sumsplit
= 0.0;
640 data
->remsplit
= 0.0;
642 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_split
));
643 i
=0; valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
648 gtk_tree_model_get (model
, &iter
,
652 data
->sumsplit
+= split
->amount
;
653 if( hb_amount_round(split
->amount
, 2) != 0.0 )
656 /* Make iter point to the next row in the list store */
657 i
++; valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
661 DB( g_print("- count=%d, nbvalid=%d\n", count
, nbvalid
) );
663 data
->remsplit
= data
->amount
- data
->sumsplit
;
666 //validation: 2 split min
668 if( (count
== 0) || nbvalid
>= 2 )
670 gtk_dialog_set_response_sensitive(GTK_DIALOG(data
->dialog
), GTK_RESPONSE_ACCEPT
, sensitive
);
672 if( hb_amount_round(data
->amount
, 2) != 0.0 )
675 g_sprintf(buf
, "----");
677 g_snprintf(buf
, 48, "%.2f", data
->remsplit
);
679 gtk_label_set_label(GTK_LABEL(data
->LB_remain
), buf
);
681 g_snprintf(buf
, 48, "%.2f", data
->amount
);
682 gtk_label_set_label(GTK_LABEL(data
->LB_txnamount
), buf
);
685 g_snprintf(buf
, 48, "%.2f", data
->sumsplit
);
686 gtk_label_set_text(GTK_LABEL(data
->LB_sumsplit
), buf
);
691 static void ui_split_dialog_setup(struct ui_split_dialog_data
*data
)
695 DB( g_print("\n[ui_split_dialog] set\n") );
697 count
= da_splits_length(data
->tmp_splits
);
698 data
->nbsplit
= count
> 1 ? count
-1 : 0;
700 DB( g_print("- count = %d\n", count
) );
701 list_split_populate (data
);
703 data
->isedited
= FALSE
;
705 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data
->PO_cat
), GLOBALS
->h_cat
);
707 ui_split_dialog_compute(data
->dialog
, data
);
708 ui_split_dialog_update (data
->dialog
, data
);
712 GtkWidget
*ui_split_dialog (GtkWidget
*parent
, GPtrArray
**src_splits
, gdouble amount
, void (update_callbackFunction(GtkWidget
*, gdouble
)))
714 struct ui_split_dialog_data
*data
;
715 GtkWidget
*dialog
, *content
, *table
, *box
, *scrollwin
;
716 GtkWidget
*label
, *widget
;
719 DB( g_print("\n[ui_split_dialog] new\n") );
721 data
= g_malloc0(sizeof(struct ui_split_dialog_data
));
723 dialog
= gtk_dialog_new_with_buttons (_("Transaction splits"),
730 //store our dialog private data
731 g_object_set_data(G_OBJECT(dialog
), "inst_data", (gpointer
)data
);
732 DB( g_print(" - window=%p, inst_data=%p\n", dialog
, data
) );
734 g_signal_connect (dialog
, "destroy",
735 G_CALLBACK (gtk_widget_destroyed
), &dialog
);
737 data
->dialog
= dialog
;
739 //gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Remove"), GTK_RESPONSE_SPLIT_REM);
740 gtk_dialog_add_button(GTK_DIALOG(dialog
), _("_OK"), GTK_RESPONSE_ACCEPT
);
742 //todo: init should move
743 //clone splits or create new
744 data
->src_splits
= *src_splits
;
745 data
->amount
= amount
;
746 data
->sumsplit
= amount
;
748 if( *src_splits
!= NULL
)
749 data
->tmp_splits
= da_splits_clone(*src_splits
);
751 data
->tmp_splits
= da_split_new();
754 content
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
756 table
= gtk_grid_new ();
757 gtk_container_set_border_width (GTK_CONTAINER (table
), SPACING_SMALL
);
758 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_TINY
);
759 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_TINY
);
760 gtk_box_pack_start (GTK_BOX (content
), table
, TRUE
, TRUE
, 0);
764 scrollwin
= gtk_scrolled_window_new(NULL
,NULL
);
765 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_AUTOMATIC
);
766 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin
), GTK_SHADOW_ETCHED_IN
);
767 gtk_widget_set_size_request(scrollwin
, HB_MINWIDTH_LIST
, HB_MINHEIGHT_LIST
);
768 gtk_widget_set_hexpand (scrollwin
, TRUE
);
769 gtk_widget_set_vexpand (scrollwin
, TRUE
);
770 data
->LV_split
= list_split_new();
771 gtk_container_add(GTK_CONTAINER(scrollwin
), data
->LV_split
);
772 gtk_grid_attach (GTK_GRID (table
), scrollwin
, 0, row
, 4, 1);
774 box
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, SPACING_TINY
);
775 gtk_widget_set_valign (box
, GTK_ALIGN_CENTER
);
776 gtk_grid_attach (GTK_GRID (table
), box
, 4, row
, 1, 1);
778 widget
= make_image_button(ICONNAME_LIST_REMOVE_ALL
, _("Remove all"));
779 data
->BT_remall
= widget
;
780 gtk_box_pack_end (GTK_BOX (box
), widget
, FALSE
, FALSE
, 0);
782 widget
= make_image_button(ICONNAME_LIST_REMOVE
, _("Remove"));
783 data
->BT_rem
= widget
;
784 gtk_box_pack_end (GTK_BOX(box
), widget
, FALSE
, FALSE
, 0);
786 widget
= make_image_button(ICONNAME_HB_OPE_EDIT
, _("Edit"));
787 data
->BT_edit
= widget
;
788 gtk_box_pack_end (GTK_BOX(box
), widget
, FALSE
, FALSE
, 0);
791 label
= gtk_label_new(_("Category"));
792 gimp_label_set_attributes (GTK_LABEL (label
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
793 gtk_grid_attach (GTK_GRID (table
), label
, 0, row
, 1, 1);
795 label
= gtk_label_new(_("Memo"));
796 gimp_label_set_attributes (GTK_LABEL (label
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
797 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
799 label
= gtk_label_new(_("Amount"));
800 gimp_label_set_attributes (GTK_LABEL (label
), PANGO_ATTR_SCALE
, PANGO_SCALE_SMALL
, -1);
801 gtk_grid_attach (GTK_GRID (table
), label
, 2, row
, 1, 1);
805 widget
= ui_cat_comboboxentry_new(NULL
);
806 data
->PO_cat
= widget
;
807 gtk_grid_attach (GTK_GRID (table
), widget
, 0, row
, 1, 1);
809 widget
= make_string(NULL
);
810 data
->ST_memo
= widget
;
811 gtk_grid_attach (GTK_GRID (table
), widget
, 1, row
, 1, 1);
813 widget
= make_amount(NULL
);
814 data
->ST_amount
= widget
;
815 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
817 box
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, SPACING_TINY
);
818 gtk_grid_attach (GTK_GRID (table
), box
, 3, row
, 1, 1);
820 widget
= gtk_image_new_from_icon_name (ICONNAME_HB_OPE_EDIT
, GTK_ICON_SIZE_BUTTON
);
821 data
->IM_edit
= widget
;
822 gtk_box_pack_start (GTK_BOX(box
), widget
, TRUE
, TRUE
, 0);
824 widget
= make_image_button(ICONNAME_LIST_ADD
, _("Add"));
825 data
->BT_add
= widget
;
826 gtk_box_pack_start (GTK_BOX(box
), widget
, FALSE
, FALSE
, 0);
828 widget
= make_image_button(ICONNAME_EMBLEM_OK
, _("Apply"));
829 data
->BT_apply
= widget
;
830 gtk_box_pack_start (GTK_BOX(box
), widget
, FALSE
, FALSE
, 0);
832 widget
= make_image_button(ICONNAME_WINDOW_CLOSE
, _("Cancel"));
833 data
->BT_cancel
= widget
;
834 gtk_box_pack_start (GTK_BOX(box
), widget
, FALSE
, FALSE
, 0);
837 if( hb_amount_round(data
->amount
, 2) != 0.0 )
840 label
= gtk_label_new(_("Transaction amount:"));
841 gtk_widget_set_halign (label
, GTK_ALIGN_END
);
842 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
843 widget
= gtk_label_new(NULL
);
844 gtk_widget_set_halign (widget
, GTK_ALIGN_CENTER
);
845 data
->LB_txnamount
= widget
;
846 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
849 label
= gtk_label_new(_("Unassigned:"));
850 gtk_widget_set_halign (label
, GTK_ALIGN_END
);
851 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
852 widget
= gtk_label_new(NULL
);
853 gtk_widget_set_halign (widget
, GTK_ALIGN_CENTER
);
854 data
->LB_remain
= widget
;
855 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
858 widget
= gtk_separator_new (GTK_ORIENTATION_HORIZONTAL
);
859 gtk_grid_attach (GTK_GRID (table
), widget
, 1, row
, 2, 1);
864 label
= gtk_label_new(_("Sum of splits:"));
865 gtk_widget_set_halign (label
, GTK_ALIGN_END
);
866 gtk_grid_attach (GTK_GRID (table
), label
, 1, row
, 1, 1);
867 widget
= gtk_label_new(NULL
);
868 gtk_widget_set_halign (widget
, GTK_ALIGN_CENTER
);
869 data
->LB_sumsplit
= widget
;
870 gtk_grid_attach (GTK_GRID (table
), widget
, 2, row
, 1, 1);
873 //connect all our signals
874 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_split
)), "changed", G_CALLBACK (ui_split_selection
), data
);
875 g_signal_connect (GTK_TREE_VIEW(data
->LV_split
), "row-activated", G_CALLBACK (ui_split_rowactivated
), data
);
877 g_signal_connect (data
->ST_memo
, "insert-text", G_CALLBACK(ui_split_dialog_filter_text_handler
), data
);
879 data
->hid_cat
= g_signal_connect (data
->PO_cat
, "changed" , G_CALLBACK (ui_split_dialog_cb_eval_split
), data
);
880 data
->hid_amt
= g_signal_connect (data
->ST_amount
, "changed", G_CALLBACK (ui_split_dialog_cb_eval_split
), data
);
881 //data->hid_amt = g_signal_connect (data->ST_amount, "value-changed", G_CALLBACK (ui_split_dialog_cb_eval_split), data);
883 //todo: add enter validate
884 g_signal_connect (data
->ST_amount
, "activate", G_CALLBACK (ui_split_dialog_cb_activate_split
), NULL
);
887 g_signal_connect (data
->BT_edit
, "clicked", G_CALLBACK (ui_split_dialog_edit_start
), NULL
);
888 g_signal_connect (data
->BT_rem
, "clicked", G_CALLBACK (ui_split_dialog_remove_cb
), NULL
);
889 g_signal_connect (data
->BT_remall
, "clicked", G_CALLBACK (ui_split_dialog_removeall_cb
), NULL
);
891 g_signal_connect (data
->BT_add
, "clicked", G_CALLBACK (ui_split_dialog_add_cb
), NULL
);
892 g_signal_connect (data
->BT_apply
, "clicked", G_CALLBACK (ui_split_dialog_apply_cb
), NULL
);
893 g_signal_connect (data
->BT_cancel
, "clicked", G_CALLBACK (ui_split_dialog_cancel_cb
), NULL
);
895 //gtk_window_set_default_size(GTK_WINDOW(dialog), 480, -1);
896 gtk_widget_show_all (dialog
);
898 //setup, init and show dialog
899 ui_split_dialog_setup(data
);
902 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
906 // sum split and alter txn amount
907 case GTK_RESPONSE_ACCEPT
:
908 if( da_splits_length(data
->tmp_splits
) )
910 ui_split_dialog_cb_eval_order(data
);
911 // here we swap src_splits <> tmp_splits
912 *src_splits
= data
->tmp_splits
;
913 data
->tmp_splits
= data
->src_splits
;
914 update_callbackFunction(parent
, data
->sumsplit
);
918 //remove split and revert back original amount
919 da_split_destroy(*src_splits
);
921 update_callbackFunction(parent
, data
->amount
);
924 /*case GTK_RESPONSE_SPLIT_REM:
925 da_split_destroy(*src_splits);
927 update_callbackFunction(parent, data->sumsplit);
931 //do_nothing_since_dialog_was_cancelled ();
940 for(i=0;i<TXN_MAX_SPLIT;i++)
942 Split *split = data->ope_splits[i];
943 if(data->ope_splits[i] == NULL)
945 g_print(" split %d : %d, %.2f, %s\n", i, split->kcat, split->amount, split->memo);
950 // cleanup and destroy
951 //GLOBALS->changes_count += data->change;
952 gtk_widget_destroy (dialog
);
954 da_split_destroy (data
->tmp_splits
);