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/>.
24 #include "ui-category.h"
34 /* our global datas */
35 extern struct HomeBank
*GLOBALS
;
36 extern struct Preferences
*PREFS
;
39 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
43 container_get_nth(GtkBox
*container
, gint nth
)
48 if(!GTK_IS_CONTAINER(container
))
51 lchild
= list
= gtk_container_get_children (GTK_CONTAINER(container
));
52 child
= g_list_nth_data (list
, nth
);
60 ui_pay_entry_popover_get_entry(GtkBox
*box
)
62 return container_get_nth(box
, 0);
67 *ui_pay_entry_popover_get(GtkBox
*box
)
73 DB( g_print ("ui_pay_entry_popover_get()\n") );
75 entry
= container_get_nth(box
, 0);
76 if( entry
!= NULL
&& GTK_IS_ENTRY(entry
) )
78 name
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (entry
));
79 item
= da_pay_get_by_name(name
);
86 ui_pay_entry_popover_get_key_add_new(GtkBox
*box
)
88 Payee
*item
= ui_pay_entry_popover_get(box
);
95 //todo: check prefs + ask the user here 1st time
96 entry
= container_get_nth(box
, 0);
97 if( entry
!= NULL
&& GTK_IS_ENTRY(entry
) )
99 item
= da_pay_malloc();
100 item
->name
= g_strdup(gtk_entry_get_text(GTK_ENTRY (entry
)));
103 store
= gtk_entry_completion_get_model(gtk_entry_get_completion(GTK_ENTRY(entry
)));
105 gtk_list_store_insert_with_values(GTK_LIST_STORE(store
), NULL
, -1,
114 ui_pay_entry_popover_get_key(GtkBox
*box
)
116 Payee
*item
= ui_pay_entry_popover_get(box
);
118 return ((item
!= NULL
) ? item
->key
: 0);
123 ui_pay_entry_popover_set_active(GtkBox
*box
, guint32 key
)
127 DB( g_print ("ui_pay_comboboxentry_set_active()\n") );
129 entry
= container_get_nth(box
, 0);
130 if( entry
!= NULL
&& GTK_IS_ENTRY(entry
) )
132 Payee
*item
= da_pay_get(key
);
134 ui_gtk_entry_set_text(GTK_WIDGET(entry
), item
!= NULL
? item
->name
: "");
140 ui_pay_entry_popover_cb_row_activated(GtkTreeView
*tree_view
, GtkTreePath
*path
, GtkTreeViewColumn
*column
, gpointer user_data
)
142 GtkTreeSelection
*treeselection
;
145 GtkEntry
*entry
= user_data
;
147 if( GTK_IS_ENTRY(entry
) )
149 treeselection
= gtk_tree_view_get_selection(tree_view
);
150 if( gtk_tree_selection_get_selected(treeselection
, &model
, &iter
) )
154 gtk_tree_model_get(model
, &iter
, 0, &item
, -1);
155 gtk_entry_set_text(GTK_ENTRY(user_data
), item
);
163 ui_pay_entry_popover_populate(GtkListStore
*store
)
165 GHashTableIter hiter
;
168 g_hash_table_iter_init (&hiter
, GLOBALS
->h_pay
);
169 while (g_hash_table_iter_next (&hiter
, &key
, &value
))
173 gtk_list_store_insert_with_values(GTK_LIST_STORE(store
), NULL
, -1,
177 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store
), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID
, GTK_SORT_ASCENDING
);
183 ui_pay_entry_popover_function (GtkEditable
*editable
, gpointer user_data
)
186 g_print("text changed to %s\n", gtk_entry_get_text(GTK_ENTRY(editable
)) );
194 ui_pay_entry_popover_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
197 gchar
*name1
, *name2
;
199 gtk_tree_model_get(model
, a
, 0, &name1
, -1);
200 gtk_tree_model_get(model
, b
, 0, &name2
, -1);
202 retval
= hb_string_utf8_compare(name1
, name2
);
212 ui_pay_entry_popover_destroy( GtkWidget
*widget
, gpointer user_data
)
215 g_print ("[pay entry popover] destroy\n");
221 ui_pay_entry_popover_new(GtkWidget
*label
)
223 GtkWidget
*mainbox
, *box
, *entry
, *menubutton
, *image
, *popover
, *scrollwin
, *treeview
;
225 GtkEntryCompletion
*completion
;
227 g_print ("[pay entry popover] new\n");
229 mainbox
= gtk_box_new(GTK_ORIENTATION_HORIZONTAL
, 0);
230 gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(mainbox
)), GTK_STYLE_CLASS_LINKED
);
232 entry
= gtk_entry_new();
233 gtk_box_pack_start(GTK_BOX(mainbox
), entry
, TRUE
, TRUE
, 0);
235 menubutton
= gtk_menu_button_new ();
236 //data->MB_template = menubutton;
237 image
= gtk_image_new_from_icon_name ("pan-down-symbolic", GTK_ICON_SIZE_BUTTON
);
238 gtk_container_add(GTK_CONTAINER(menubutton
), image
);
239 //gtk_menu_button_set_direction (GTK_MENU_BUTTON(menubutton), GTK_ARROW_DOWN );
240 //gtk_widget_set_halign (menubutton, GTK_ALIGN_END);
241 gtk_box_pack_start(GTK_BOX(mainbox
), menubutton
, FALSE
, FALSE
, 0);
243 completion
= gtk_entry_completion_new ();
245 gtk_entry_set_completion (GTK_ENTRY (entry
), completion
);
246 g_object_unref(completion
);
248 store
= gtk_list_store_new (1,
252 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store
), ui_pay_entry_popover_compare_func
, NULL
, NULL
);
254 ui_pay_entry_popover_populate(store
);
257 gtk_entry_completion_set_model (completion
, GTK_TREE_MODEL(store
));
258 g_object_unref(store
);
260 gtk_entry_completion_set_text_column (completion
, 0);
262 gtk_widget_show_all(mainbox
);
265 box
= gtk_box_new(GTK_ORIENTATION_VERTICAL
, SPACING_MEDIUM
);
266 scrollwin
= gtk_scrolled_window_new(NULL
,NULL
);
267 gtk_box_pack_start(GTK_BOX(box
), scrollwin
, TRUE
, TRUE
, 0);
268 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin
), GTK_SHADOW_ETCHED_IN
);
269 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
), GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
270 //gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrollwin), HB_MINHEIGHT_LIST);
271 treeview
= gtk_tree_view_new_with_model (GTK_TREE_MODEL(store
));
272 gtk_container_add(GTK_CONTAINER(scrollwin
), GTK_WIDGET(treeview
));
273 gtk_widget_show_all(box
);
275 //gtk_widget_set_can_focus(GTK_WIDGET(treeview), FALSE);
277 GtkCellRenderer
*renderer
;
278 GtkTreeViewColumn
*column
;
280 renderer
= gtk_cell_renderer_text_new ();
281 column
= gtk_tree_view_column_new_with_attributes (NULL
,
286 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
289 gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(treeview
), TRUE
);
290 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview
), FALSE
);
291 gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(treeview
), TRUE
);
294 //gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_BROWSE);
297 popover
= create_popover (menubutton
, box
, GTK_POS_BOTTOM
);
298 gtk_widget_set_size_request (popover
, HB_MINWIDTH_LIST
, HB_MINHEIGHT_LIST
);
300 gtk_menu_button_set_popover(GTK_MENU_BUTTON(menubutton
), popover
);
302 // connect our dispose function
303 g_signal_connect (entry
, "destroy", G_CALLBACK (ui_pay_entry_popover_destroy
), NULL
);
305 g_signal_connect_after (entry
, "changed", G_CALLBACK (ui_pay_entry_popover_function
), NULL
);
307 g_signal_connect (treeview
, "row-activated", G_CALLBACK (ui_pay_entry_popover_cb_row_activated
), entry
);
308 g_signal_connect_swapped(treeview
, "row-activated", G_CALLBACK(gtk_popover_popdown
), popover
);
309 //g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), "changed", G_CALLBACK (ui_pay_entry_popover_cb_selection), entry);
310 //g_signal_connect_swapped(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), "changed", G_CALLBACK(gtk_popover_popdown), popover);
314 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), entry
);
316 //gtk_widget_set_size_request(comboboxentry, HB_MINWIDTH_LIST, -1);
322 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
326 * ui_pay_comboboxentry_add:
328 * Add a single element (useful for dynamics add)
334 ui_pay_comboboxentry_add(GtkComboBox
*entry_box
, Payee
*pay
)
336 if( pay
->name
!= NULL
)
341 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box
));
343 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
344 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
, 0, pay
->name
, -1);
351 * ui_pay_comboboxentry_get_key_add_new:
353 * get the key of the active payee
354 * and create the payee if it do not exists
356 * Return value: the key or 0
360 ui_pay_comboboxentry_get_key_add_new(GtkComboBox
*entry_box
)
365 name
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
366 item
= da_pay_get_by_name(name
);
370 //todo: check prefs + ask the user here 1st time
371 item
= da_pay_malloc();
372 item
->name
= g_strdup(name
);
374 ui_pay_comboboxentry_add(entry_box
, item
);
381 * ui_pay_comboboxentry_get_key:
383 * get the key of the active payee
385 * Return value: the key or 0
389 ui_pay_comboboxentry_get_key(GtkComboBox
*entry_box
)
394 name
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
395 item
= da_pay_get_by_name(name
);
405 *ui_pay_comboboxentry_get(GtkComboBox
*entry_box
)
410 DB( g_print ("ui_pay_comboboxentry_get()\n") );
412 name
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
413 item
= da_pay_get_by_name(name
);
420 ui_pay_comboboxentry_set_active(GtkComboBox
*entry_box
, guint32 key
)
424 DB( g_print ("ui_pay_comboboxentry_set_active()\n") );
426 DB( g_print("- key:%d\n", key
) );
430 item
= da_pay_get(key
);
433 DB( g_print("- set combo to '%s'\n", item
->name
) );
435 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))), item
->name
);
440 DB( g_print("- set combo to ''\n") );
442 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))), "");
448 ui_pay_comboboxentry_populate_ghfunc(gpointer key
, gpointer value
, struct payPopContext
*ctx
)
453 if( ( pay
->key
!= ctx
->except_key
) )
455 //gtk_list_store_append (GTK_LIST_STORE(ctx->model), &iter);
456 //gtk_list_store_set (GTK_LIST_STORE(ctx->model), &iter, 0, pay->name, -1);
457 gtk_list_store_insert_with_values(GTK_LIST_STORE(ctx
->model
), &iter
, -1,
463 //not used except here
465 ui_pay_comboboxentry_populate_except(GtkComboBox
*entry_box
, GHashTable
*hash
, guint except_key
)
468 //GtkEntryCompletion *completion;
469 struct payPopContext ctx
;
471 DB( g_print ("ui_pay_comboboxentry_populate\n") );
473 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box
));
474 //completion = gtk_entry_get_completion(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
476 /* keep our model alive and detach from comboboxentry and completion */
477 //g_object_ref(model);
478 //gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), NULL);
479 //gtk_entry_completion_set_model (completion, NULL);
481 /* clear and populate */
483 ctx
.except_key
= except_key
;
484 gtk_list_store_clear (GTK_LIST_STORE(model
));
486 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GTK_LIST_STORE(model)), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
488 g_hash_table_foreach(hash
, (GHFunc
)ui_pay_comboboxentry_populate_ghfunc
, &ctx
);
490 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model
), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID
, GTK_SORT_ASCENDING
);
492 /* reatach our model */
493 //g_print("reattach\n");
494 //gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), model);
495 //gtk_entry_completion_set_model (completion, model);
496 //g_object_unref(model);
501 * ui_pay_comboboxentry_populate:
503 * Populate the list and completion
509 ui_pay_comboboxentry_populate(GtkComboBox
*entry_box
, GHashTable
*hash
)
511 ui_pay_comboboxentry_populate_except(entry_box
, hash
, -1);
516 ui_pay_comboboxentry_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
519 gchar
*name1
, *name2
;
521 gtk_tree_model_get(model
, a
, 0, &name1
, -1);
522 gtk_tree_model_get(model
, b
, 0, &name2
, -1);
524 retval
= hb_string_utf8_compare(name1
, name2
);
534 ui_pay_comboboxentry_test (GtkCellLayout
*cell_layout
,
535 GtkCellRenderer
*cell
,
536 GtkTreeModel
*tree_model
,
542 gtk_tree_model_get(tree_model
, iter
,
547 g_object_set(cell
, "text", _("(no payee)"), NULL
);
549 g_object_set(cell
, "text", name
, NULL
);
557 * ui_pay_comboboxentry_new:
559 * Create a new payee comboboxentry
561 * Return value: the new widget
565 ui_pay_comboboxentry_new(GtkWidget
*label
)
568 GtkWidget
*comboboxentry
;
569 GtkEntryCompletion
*completion
;
570 GtkCellRenderer
*renderer
;
572 DB( g_print ("ui_pay_comboboxentry_new()\n") );
574 store
= gtk_list_store_new (1,
577 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store
), ui_pay_comboboxentry_compare_func
, NULL
, NULL
);
579 completion
= gtk_entry_completion_new ();
580 gtk_entry_completion_set_model (completion
, GTK_TREE_MODEL(store
));
581 g_object_set(completion
, "text-column", 0, NULL
);
583 renderer
= gtk_cell_renderer_text_new ();
584 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion
), renderer
, TRUE
);
585 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion
), renderer
, "text", 0, NULL
);
587 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion
),
589 ui_pay_comboboxentry_test
,
592 // dothe same for combobox
594 comboboxentry
= gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store
));
595 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboboxentry
), 0);
597 gtk_cell_layout_clear(GTK_CELL_LAYOUT (comboboxentry
));
599 renderer
= gtk_cell_renderer_text_new ();
600 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comboboxentry
), renderer
, TRUE
);
601 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comboboxentry
), renderer
, "text", 0, NULL
);
603 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (comboboxentry
),
605 ui_pay_comboboxentry_test
,
608 gtk_entry_set_completion (GTK_ENTRY (gtk_bin_get_child(GTK_BIN (comboboxentry
))), completion
);
610 g_object_unref(store
);
613 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), comboboxentry
);
615 gtk_widget_set_size_request(comboboxentry
, HB_MINWIDTH_LIST
, -1);
617 return comboboxentry
;
621 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
624 ui_pay_listview_toggled_cb (GtkCellRendererToggle
*cell
,
628 GtkTreeModel
*model
= (GtkTreeModel
*)data
;
630 GtkTreePath
*path
= gtk_tree_path_new_from_string (path_str
);
633 /* get toggled iter */
634 gtk_tree_model_get_iter (model
, &iter
, path
);
635 gtk_tree_model_get (model
, &iter
, LST_DEFPAY_TOGGLE
, &fixed
, -1);
637 /* do something with the value */
641 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, LST_DEFPAY_TOGGLE
, fixed
, -1);
644 gtk_tree_path_free (path
);
649 ui_pay_listview_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
651 gint sortcol
= GPOINTER_TO_INT(userdata
);
652 Payee
*entry1
, *entry2
;
655 gtk_tree_model_get(model
, a
, LST_DEFPAY_DATAS
, &entry1
, -1);
656 gtk_tree_model_get(model
, b
, LST_DEFPAY_DATAS
, &entry2
, -1);
660 case LST_DEFPAY_SORT_NAME
:
661 retval
= hb_string_utf8_compare(entry1
->name
, entry2
->name
);
663 case LST_DEFPAY_SORT_USED
:
664 retval
= entry1
->usage_count
- entry2
->usage_count
;
666 case LST_DEFPAY_SORT_DEFCAT
:
670 c1
= da_cat_get(entry1
->kcat
);
671 c2
= da_cat_get(entry2
->kcat
);
672 if( c1
!= NULL
&& c2
!= NULL
)
674 retval
= hb_string_utf8_compare(c1
->fullname
, c2
->fullname
);
679 g_return_val_if_reached(0);
687 ui_pay_listview_count_cell_data_function (GtkTreeViewColumn
*col
,
688 GtkCellRenderer
*renderer
,
696 gtk_tree_model_get(model
, iter
, LST_DEFPAY_DATAS
, &entry
, -1);
697 if(entry
->usage_count
> 0)
699 g_snprintf(buffer
, 256-1, "%d", entry
->usage_count
);
700 g_object_set(renderer
, "text", buffer
, NULL
);
703 g_object_set(renderer
, "text", "", NULL
);
708 ui_pay_listview_defcat_cell_data_function (GtkTreeViewColumn
*col
,
709 GtkCellRenderer
*renderer
,
717 gtk_tree_model_get(model
, iter
, LST_DEFPAY_DATAS
, &entry
, -1);
719 cat
= da_cat_get(entry
->kcat
);
722 g_object_set(renderer
, "text", cat
->fullname
, NULL
);
725 g_object_set(renderer
, "text", "", NULL
);
730 ui_pay_listview_name_cell_data_function (GtkTreeViewColumn
*col
,
731 GtkCellRenderer
*renderer
,
742 gtk_tree_model_get(model
, iter
, LST_DEFPAY_DATAS
, &entry
, -1);
745 name
= _("(no payee)");
750 string
= g_strdup_printf ("%d > %s [ft=%d]", entry
->key
, name
, entry
->flt_select
);
751 g_object_set(renderer
, "text", string
, NULL
);
754 g_object_set(renderer
, "text", name
, NULL
);
760 /* = = = = = = = = = = = = = = = = */
764 ui_pay_listview_add(GtkTreeView
*treeview
, Payee
*item
)
769 if( item
->name
!= NULL
)
771 model
= gtk_tree_view_get_model(treeview
);
773 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
774 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
775 LST_DEFPAY_TOGGLE
, FALSE
,
776 LST_DEFPAY_DATAS
, item
,
782 ui_pay_listview_get_selected_key(GtkTreeView
*treeview
)
784 GtkTreeSelection
*selection
;
788 selection
= gtk_tree_view_get_selection(treeview
);
789 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
793 gtk_tree_model_get(model
, &iter
, LST_DEFPAY_DATAS
, &item
, -1);
802 ui_pay_listview_remove_selected(GtkTreeView
*treeview
)
804 GtkTreeSelection
*selection
;
808 DB( g_print("ui_pay_listview_remove_selected() \n") );
810 selection
= gtk_tree_view_get_selection(treeview
);
811 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
813 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
818 struct PayListContext
{
824 static void ui_pay_listview_populate_ghfunc(gpointer key
, gpointer value
, struct PayListContext
*context
)
828 gboolean hastext
= FALSE
;
829 gboolean insert
= TRUE
;
831 //DB( g_print(" populate: %p\n", key) );
832 if( context
->needle
!= NULL
)
833 hastext
= (strlen(context
->needle
) >= 2) ? TRUE
: FALSE
;
837 insert
= hb_string_utf8_strstr(item
->name
, context
->needle
, FALSE
);
842 gtk_list_store_insert_with_values(GTK_LIST_STORE(context
->model
), &iter
, -1,
843 LST_DEFPAY_TOGGLE
, FALSE
,
844 LST_DEFPAY_DATAS
, item
,
851 void ui_pay_listview_populate(GtkWidget
*treeview
, gchar
*needle
)
853 struct PayListContext context
;
855 DB( g_print("ui_pay_listview_populate \n") );
857 context
.model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeview
));
858 context
.needle
= needle
;
860 gtk_list_store_clear (GTK_LIST_STORE(context
.model
));
862 //g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
863 //gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); /* Detach model from view */
866 g_hash_table_foreach(GLOBALS
->h_pay
, (GHFunc
)ui_pay_listview_populate_ghfunc
, &context
);
868 //gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); /* Re-attach model to view */
869 //g_object_unref(model);
873 static gboolean
ui_pay_listview_search_equal_func (GtkTreeModel
*model
,
877 gpointer search_data
)
879 gboolean retval
= TRUE
;
880 gchar
*normalized_string
;
881 gchar
*normalized_key
;
882 gchar
*case_normalized_string
= NULL
;
883 gchar
*case_normalized_key
= NULL
;
886 //gtk_tree_model_get_value (model, iter, column, &value);
887 gtk_tree_model_get(model
, iter
, LST_DEFPAY_DATAS
, &item
, -1);
891 normalized_string
= g_utf8_normalize (item
->name
, -1, G_NORMALIZE_ALL
);
892 normalized_key
= g_utf8_normalize (key
, -1, G_NORMALIZE_ALL
);
894 if (normalized_string
&& normalized_key
)
896 case_normalized_string
= g_utf8_casefold (normalized_string
, -1);
897 case_normalized_key
= g_utf8_casefold (normalized_key
, -1);
899 if (strncmp (case_normalized_key
, case_normalized_string
, strlen (case_normalized_key
)) == 0)
903 g_free (normalized_key
);
904 g_free (normalized_string
);
905 g_free (case_normalized_key
);
906 g_free (case_normalized_string
);
913 ui_pay_listview_new(gboolean withtoggle
, gboolean withcount
)
917 GtkCellRenderer
*renderer
;
918 GtkTreeViewColumn
*column
;
920 DB( g_print("ui_pay_listview_new() \n") );
922 store
= gtk_list_store_new(
928 treeview
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
929 g_object_unref(store
);
931 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview
), PREFS
->grid_lines
);
934 if( withtoggle
== TRUE
)
936 renderer
= gtk_cell_renderer_toggle_new ();
937 column
= gtk_tree_view_column_new_with_attributes (_("Visible"),
938 renderer
, "active", LST_DEFPAY_TOGGLE
, NULL
);
939 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
941 g_signal_connect (G_OBJECT(renderer
), "toggled",
942 G_CALLBACK (ui_pay_listview_toggled_cb
), store
);
947 renderer
= gtk_cell_renderer_text_new ();
949 g_object_set(renderer
,
950 "ellipsize", PANGO_ELLIPSIZE_END
,
951 "ellipsize-set", TRUE
,
952 //taken from nemo, not exactly a resize to content, but good compromise
956 column
= gtk_tree_view_column_new();
957 gtk_tree_view_column_set_title(column
, _("Payee"));
958 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
959 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_pay_listview_name_cell_data_function
, GINT_TO_POINTER(LST_DEFPAY_DATAS
), NULL
);
960 gtk_tree_view_column_set_alignment (column
, 0.5);
961 gtk_tree_view_column_set_resizable(column
, TRUE
);
962 gtk_tree_view_column_set_min_width(column
, HB_MINWIDTH_LIST
);
963 gtk_tree_view_column_set_sort_column_id (column
, LST_DEFPAY_SORT_NAME
);
964 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
967 if( withcount
== TRUE
)
969 renderer
= gtk_cell_renderer_text_new ();
970 g_object_set(renderer
, "xalign", 0.5, NULL
);
972 column
= gtk_tree_view_column_new();
973 gtk_tree_view_column_set_title(column
, _("Usage"));
974 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
975 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_pay_listview_count_cell_data_function
, GINT_TO_POINTER(LST_DEFPAY_DATAS
), NULL
);
976 gtk_tree_view_column_set_alignment (column
, 0.5);
977 gtk_tree_view_column_set_sort_column_id (column
, LST_DEFPAY_SORT_USED
);
978 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
982 if( withtoggle
== FALSE
)
984 renderer
= gtk_cell_renderer_text_new ();
985 g_object_set(renderer
,
986 "ellipsize", PANGO_ELLIPSIZE_END
,
987 "ellipsize-set", TRUE
,
988 //taken from nemo, not exactly a resize to content, but good compromise
992 column
= gtk_tree_view_column_new();
993 gtk_tree_view_column_set_title(column
, _("Category"));
994 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
995 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_pay_listview_defcat_cell_data_function
, GINT_TO_POINTER(LST_DEFPAY_DATAS
), NULL
);
996 gtk_tree_view_column_set_alignment (column
, 0.5);
997 gtk_tree_view_column_set_resizable(column
, TRUE
);
998 gtk_tree_view_column_set_sort_column_id (column
, LST_DEFPAY_SORT_DEFCAT
);
999 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
1004 column
= gtk_tree_view_column_new();
1005 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
1008 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview
), ui_pay_listview_search_equal_func
, NULL
, NULL
);
1010 // treeview attribute
1011 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview
), withcount
);
1013 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_DEFPAY_SORT_NAME
, ui_pay_listview_compare_func
, GINT_TO_POINTER(LST_DEFPAY_SORT_NAME
), NULL
);
1014 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_DEFPAY_SORT_USED
, ui_pay_listview_compare_func
, GINT_TO_POINTER(LST_DEFPAY_SORT_USED
), NULL
);
1015 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_DEFPAY_SORT_DEFCAT
, ui_pay_listview_compare_func
, GINT_TO_POINTER(LST_DEFPAY_SORT_DEFCAT
), NULL
);
1017 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store
), LST_DEFPAY_SORT_NAME
, GTK_SORT_ASCENDING
);
1023 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
1026 ui_pay_manage_dialog_delete_unused( GtkWidget
*widget
, gpointer user_data
)
1028 struct ui_pay_manage_dialog_data
*data
= user_data
;
1031 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
1033 DB( g_print("(ui_pay_manage_dialog) delete unused - data %p\n", data
) );
1035 result
= ui_dialog_msg_confirm_alert(
1036 GTK_WINDOW(data
->window
),
1037 _("Delete unused payee"),
1038 _("Are you sure you want to\npermanently delete unused payee?"),
1042 if( result
== GTK_RESPONSE_OK
)
1044 GtkTreeModel
*model
;
1046 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_pay
));
1047 gtk_list_store_clear (GTK_LIST_STORE(model
));
1049 payee_delete_unused();
1051 ui_pay_listview_populate (data
->LV_pay
, NULL
);
1057 * ui_pay_manage_dialog_load_csv:
1061 ui_pay_manage_dialog_load_csv( GtkWidget
*widget
, gpointer user_data
)
1063 struct ui_pay_manage_dialog_data
*data
= user_data
;
1064 gchar
*filename
= NULL
;
1067 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
1069 DB( g_print("(ui_pay_manage_dialog) load csv - data %p\n", data
) );
1071 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_OPEN
, &filename
, NULL
) == TRUE
)
1073 DB( g_print(" + filename is %s\n", filename
) );
1075 if( !payee_load_csv(filename
, &error
) )
1077 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_ERROR
,
1078 _("File format error"),
1079 _("The CSV file must contains the exact numbers of column,\nseparated by a semi-colon, please see the help for more details.")
1084 ui_pay_listview_populate(data
->LV_pay
, NULL
);
1089 * ui_pay_manage_dialog_save_csv:
1093 ui_pay_manage_dialog_save_csv( GtkWidget
*widget
, gpointer user_data
)
1095 struct ui_pay_manage_dialog_data
*data
= user_data
;
1096 gchar
*filename
= NULL
;
1098 DB( g_print("(ui_pay_manage_dialog) save csv\n") );
1100 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1102 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, NULL
) == TRUE
)
1104 DB( g_print(" + filename is %s\n", filename
) );
1106 payee_save_csv(filename
);
1113 * ui_pay_manage_dialog_add:
1117 ui_pay_manage_dialog_add(GtkWidget
*widget
, gpointer user_data
)
1119 struct ui_pay_manage_dialog_data
*data
;
1123 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1124 DB( g_print("(defayee) add (data=%p)\n", data
) );
1126 name
= (gchar
*)gtk_entry_get_text(GTK_ENTRY(data
->ST_name
));
1128 item
= da_pay_malloc ();
1129 item
->name
= g_strdup(name
);
1131 g_strstrip(item
->name
);
1133 if( strlen(item
->name
) > 0 )
1135 if( da_pay_append(item
) )
1137 ui_pay_listview_add(GTK_TREE_VIEW(data
->LV_pay
), item
);
1144 gtk_entry_set_text(GTK_ENTRY(data
->ST_name
), "");
1148 static void ui_pay_manage_dialog_edit_entry_cb(GtkEditable
*editable
, gpointer user_data
)
1150 GtkDialog
*window
= user_data
;
1151 const gchar
*buffer
;
1153 buffer
= gtk_entry_get_text(GTK_ENTRY(editable
));
1154 gtk_dialog_set_response_sensitive(GTK_DIALOG(window
), GTK_RESPONSE_ACCEPT
, strlen(buffer
) > 0 ? TRUE
: FALSE
);
1158 static void ui_pay_manage_dialog_edit(GtkWidget
*dowidget
, gpointer user_data
)
1160 struct ui_pay_manage_dialog_data
*data
;
1161 GtkWidget
*dialog
, *content_area
, *content_grid
, *group_grid
;
1162 GtkWidget
*label
, *widget
;
1163 GtkWidget
*ST_name
, *PO_cat
, *NU_mode
;
1167 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(dowidget
, GTK_TYPE_WINDOW
)), "inst_data");
1168 DB( g_print("(defayee) modify %p\n", data
) );
1170 key
= ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data
->LV_pay
));
1175 item
= da_pay_get( key
);
1177 dialog
= gtk_dialog_new_with_buttons (_("Edit..."),
1178 GTK_WINDOW (data
->window
),
1181 GTK_RESPONSE_REJECT
,
1183 GTK_RESPONSE_ACCEPT
,
1186 content_area
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
1188 content_grid
= gtk_grid_new();
1189 gtk_grid_set_row_spacing (GTK_GRID (content_grid
), SPACING_LARGE
);
1190 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid
), GTK_ORIENTATION_VERTICAL
);
1191 gtk_container_set_border_width (GTK_CONTAINER(content_grid
), SPACING_MEDIUM
);
1192 gtk_box_pack_start (GTK_BOX (content_area
), content_grid
, TRUE
, TRUE
, 0);
1196 group_grid
= gtk_grid_new ();
1197 gtk_grid_set_row_spacing (GTK_GRID (group_grid
), SPACING_SMALL
);
1198 gtk_grid_set_column_spacing (GTK_GRID (group_grid
), SPACING_MEDIUM
);
1199 gtk_grid_attach (GTK_GRID (content_grid
), group_grid
, 0, crow
++, 1, 1);
1201 //label = make_label_group(_("General"));
1202 //gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
1205 label
= make_label_widget(_("_Name:"));
1206 gtk_grid_attach (GTK_GRID (group_grid
), label
, 1, row
, 1, 1);
1207 widget
= gtk_entry_new();
1209 gtk_widget_set_hexpand(widget
, TRUE
);
1210 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 2, row
, 1, 1);
1213 group_grid
= gtk_grid_new ();
1214 gtk_grid_set_row_spacing (GTK_GRID (group_grid
), SPACING_SMALL
);
1215 gtk_grid_set_column_spacing (GTK_GRID (group_grid
), SPACING_MEDIUM
);
1216 gtk_grid_attach (GTK_GRID (content_grid
), group_grid
, 0, crow
++, 1, 1);
1218 label
= make_label_group(_("Default"));
1219 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, 0, 4, 1);
1222 label
= make_label_widget(_("_Category:"));
1223 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
1224 widget
= ui_cat_comboboxentry_new(label
);
1226 gtk_widget_set_hexpand (widget
, TRUE
);
1227 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
1230 label
= make_label_widget(_("Pa_yment:"));
1231 gtk_grid_attach (GTK_GRID (group_grid
), label
, 0, row
, 1, 1);
1232 //5.2.4 we drop internal xfer here as it will disapear
1233 //widget = make_paymode_nointxfer(label);
1234 widget
= make_paymode_nointxfer(label
);
1236 gtk_grid_attach (GTK_GRID (group_grid
), widget
, 1, row
, 1, 1);
1239 gtk_entry_set_text(GTK_ENTRY(ST_name
), item
->name
);
1240 gtk_widget_grab_focus (ST_name
);
1241 gtk_entry_set_activates_default (GTK_ENTRY(ST_name
), TRUE
);
1243 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(PO_cat
), GLOBALS
->h_cat
);
1244 ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(PO_cat
), item
->kcat
);
1246 gtk_combo_box_set_active(GTK_COMBO_BOX(NU_mode
), item
->paymode
);
1248 g_signal_connect (G_OBJECT (ST_name
), "changed", G_CALLBACK (ui_pay_manage_dialog_edit_entry_cb
), dialog
);
1250 gtk_widget_show_all(content_grid
);
1253 gtk_dialog_set_default_response(GTK_DIALOG( dialog
), GTK_RESPONSE_ACCEPT
);
1256 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
1258 if(result
== GTK_RESPONSE_ACCEPT
)
1262 // 1: manage renaming
1263 name
= gtk_entry_get_text(GTK_ENTRY(ST_name
));
1264 // ignore if item is empty
1267 if( payee_rename(item
, name
) )
1269 //to redraw the active entry
1270 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_pay
));
1275 ui_dialog_msg_infoerror(GTK_WINDOW(dialog
), GTK_MESSAGE_ERROR
,
1277 _("Cannot rename this Payee,\n"
1278 "from '%s' to '%s',\n"
1279 "this name already exists."),
1287 item
->kcat
= ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(PO_cat
));
1288 item
->paymode
= gtk_combo_box_get_active(GTK_COMBO_BOX(NU_mode
));
1292 // cleanup and destroy
1293 gtk_widget_destroy (dialog
);
1299 static void ui_pay_manage_dialog_merge_entry_cb(GtkComboBox
*widget
, gpointer user_data
)
1301 GtkDialog
*window
= user_data
;
1304 buffer
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (widget
))));
1305 gtk_dialog_set_response_sensitive(GTK_DIALOG(window
), GTK_RESPONSE_OK
, strlen(buffer
) > 0 ? TRUE
: FALSE
);
1309 static void ui_pay_manage_dialog_merge(GtkWidget
*widget
, gpointer user_data
)
1311 struct ui_pay_manage_dialog_data
*data
;
1312 GtkWidget
*dialog
, *content
, *mainvbox
;
1313 GtkWidget
*getwidget
, *togglebutton
;
1314 GtkTreeSelection
*selection
;
1315 GtkTreeModel
*model
;
1318 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1319 DB( g_print("(defayee) merge %p\n", data
) );
1321 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_pay
));
1322 //if true there is a selected node
1323 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
1329 gtk_tree_model_get(model
, &iter
, LST_DEFPAY_DATAS
, &srcpay
, -1);
1331 title
= g_strdup_printf (
1332 _("Merge payee '%s'"), srcpay
->name
);
1334 dialog
= gtk_message_dialog_new (GTK_WINDOW (data
->window
),
1335 GTK_DIALOG_MODAL
| GTK_DIALOG_DESTROY_WITH_PARENT
,
1336 GTK_MESSAGE_WARNING
,
1342 gtk_dialog_add_buttons (GTK_DIALOG(dialog
),
1343 _("_Cancel"), GTK_RESPONSE_CANCEL
,
1344 _("Merge"), GTK_RESPONSE_OK
,
1347 gtk_dialog_set_default_response(GTK_DIALOG (dialog
), GTK_RESPONSE_CANCEL
);
1349 content
= gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG (dialog
));
1350 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, SPACING_SMALL
);
1351 gtk_box_pack_start (GTK_BOX (content
), mainvbox
, TRUE
, TRUE
, 0);
1353 secondtext
= _("Transactions assigned to this payee,\n"
1354 "will be moved to the payee selected below.");
1356 g_object_set(GTK_MESSAGE_DIALOG (dialog
), "secondary-text", secondtext
, NULL
);
1359 getwidget
= ui_pay_comboboxentry_new(NULL
);
1360 gtk_box_pack_start (GTK_BOX (mainvbox
), getwidget
, FALSE
, FALSE
, 0);
1362 secondtext
= g_strdup_printf (
1363 _("_Delete the payee '%s'"), srcpay
->name
);
1364 togglebutton
= gtk_check_button_new_with_mnemonic(secondtext
);
1365 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton
), TRUE
);
1367 gtk_box_pack_start (GTK_BOX (mainvbox
), togglebutton
, FALSE
, FALSE
, 0);
1370 //gtk_combo_box_set_active(GTK_COMBO_BOX(getwidget), oldpos);
1371 g_signal_connect (G_OBJECT (getwidget
), "changed", G_CALLBACK (ui_pay_manage_dialog_merge_entry_cb
), dialog
);
1372 gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog
), GTK_RESPONSE_OK
, FALSE
);
1374 ui_pay_comboboxentry_populate_except(GTK_COMBO_BOX(getwidget
), GLOBALS
->h_pay
, srcpay
->key
);
1375 gtk_widget_grab_focus (getwidget
);
1377 gtk_widget_show_all(mainvbox
);
1380 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
1382 if(result
== GTK_RESPONSE_OK
)
1384 GtkTreeModel
*model
;
1388 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_pay
));
1389 gtk_list_store_clear (GTK_LIST_STORE(model
));
1391 dstpaykey
= ui_pay_comboboxentry_get_key_add_new(GTK_COMBO_BOX(getwidget
));
1393 payee_move(srcpay
->key
, dstpaykey
);
1395 newpay
= da_pay_get(dstpaykey
);
1397 //#1771720: update count
1398 newpay
->usage_count
+= srcpay
->usage_count
;
1399 srcpay
->usage_count
= 0;
1401 // add the new payee to listview
1403 ui_pay_listview_add(GTK_TREE_VIEW(data
->LV_pay
), newpay
);
1405 // delete the old payee
1406 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton
)) )
1408 DB( g_print(" -> delete %d '%s'\n", srcpay
->key
, srcpay
->name
) );
1410 da_pay_remove(srcpay
->key
);
1411 ui_pay_listview_remove_selected(GTK_TREE_VIEW(data
->LV_pay
));
1417 ui_pay_listview_populate(data
->LV_pay
, NULL
);
1420 // cleanup and destroy
1421 gtk_widget_destroy (dialog
);
1428 ** delete the selected payee to our treeview and temp GList
1430 static void ui_pay_manage_dialog_delete(GtkWidget
*widget
, gpointer user_data
)
1432 struct ui_pay_manage_dialog_data
*data
;
1438 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1439 DB( g_print("(ui_pay_manage_dialog) delete (data=%p)\n", data
) );
1441 key
= ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data
->LV_pay
));
1445 gchar
*secondtext
= NULL
;
1447 item
= da_pay_get(key
);
1449 title
= g_strdup_printf (
1450 _("Are you sure you want to permanently delete '%s'?"), item
->name
);
1452 if( item
->usage_count
> 0 )
1454 secondtext
= _("This payee is used.\n"
1455 "Any transaction using that payee will be set to (no payee)");
1458 result
= ui_dialog_msg_confirm_alert(
1459 GTK_WINDOW(data
->window
),
1467 if( result
== GTK_RESPONSE_OK
)
1470 ui_pay_listview_remove_selected(GTK_TREE_VIEW(data
->LV_pay
));
1479 static void ui_pay_manage_dialog_update(GtkWidget
*treeview
, gpointer user_data
)
1481 struct ui_pay_manage_dialog_data
*data
;
1485 DB( g_print("\n(ui_pay_manage_dialog) cursor changed\n") );
1487 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
1489 key
= ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data
->LV_pay
));
1491 sensitive
= (key
> 0) ? TRUE
: FALSE
;
1492 gtk_widget_set_sensitive(data
->BT_edit
, sensitive
);
1493 gtk_widget_set_sensitive(data
->BT_merge
, sensitive
);
1494 gtk_widget_set_sensitive(data
->BT_delete
, sensitive
);
1502 static void ui_pay_manage_dialog_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1504 ui_pay_manage_dialog_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
1507 static void ui_pay_manage_dialog_onRowActivated (GtkTreeView
*treeview
,
1509 GtkTreeViewColumn
*col
,
1512 GtkTreeModel
*model
;
1515 DB( g_print("ui_pay_manage_dialog_onRowActivated()\n") );
1518 model
= gtk_tree_view_get_model(treeview
);
1519 gtk_tree_model_get_iter_first(model
, &iter
);
1520 if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
)), &iter
) == FALSE
)
1522 ui_pay_manage_dialog_edit(GTK_WIDGET(treeview
), NULL
);
1528 ui_pay_manage_search_changed_cb (GtkWidget
*widget
, gpointer user_data
)
1530 struct ui_pay_manage_dialog_data
*data
= user_data
;
1533 DB( g_printf("\n[ui_pay_manage_dialog] search_changed_cb\n") );
1535 needle
= (gchar
*)gtk_entry_get_text(GTK_ENTRY(data
->ST_search
));
1536 ui_pay_listview_populate(data
->LV_pay
, needle
);
1540 GtkWidget
*ui_pay_manage_dialog (void)
1542 struct ui_pay_manage_dialog_data data
;
1543 GtkWidget
*dialog
, *content
, *mainvbox
, *box
, *bbox
, *treeview
, *scrollwin
, *table
;
1544 GtkWidget
*menu
, *menuitem
, *widget
, *image
, *searchbar
, *addreveal
;
1547 dialog
= gtk_dialog_new_with_buttons (_("Manage Payees"),
1548 GTK_WINDOW(GLOBALS
->mainwindow
),
1550 _("_Close"), GTK_RESPONSE_ACCEPT
,
1553 /*dialog = g_object_new (GTK_TYPE_DIALOG, "use-header-bar", TRUE, NULL);
1554 gtk_window_set_title (GTK_WINDOW (dialog), _("Manage Payees"));
1555 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW(GLOBALS->mainwindow));
1556 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1558 //gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
1560 data
.window
= dialog
;
1563 gtk_window_set_icon_name(GTK_WINDOW (dialog
), ICONNAME_HB_PAYEE
);
1565 //set a nice dialog size
1566 gtk_window_get_size(GTK_WINDOW(GLOBALS
->mainwindow
), &w
, &h
);
1567 gtk_window_set_default_size (GTK_WINDOW(dialog
), -1, h
/PHI
);
1570 //store our dialog private data
1571 g_object_set_data(G_OBJECT(dialog
), "inst_data", (gpointer
)&data
);
1572 DB( g_print("(ui_pay_manage_dialog) dialog=%p, inst_data=%p\n", dialog
, &data
) );
1574 g_signal_connect (dialog
, "destroy",
1575 G_CALLBACK (gtk_widget_destroyed
), &dialog
);
1578 content
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
1579 mainvbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, SPACING_SMALL
);
1580 gtk_box_pack_start (GTK_BOX (content
), mainvbox
, TRUE
, TRUE
, 0);
1581 gtk_container_set_border_width (GTK_CONTAINER(mainvbox
), SPACING_MEDIUM
);
1584 table
= gtk_grid_new ();
1585 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
1586 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
1587 gtk_box_pack_start (GTK_BOX (mainvbox
), table
, TRUE
, TRUE
, 0);
1590 bbox
= gtk_box_new (GTK_ORIENTATION_HORIZONTAL
, SPACING_MEDIUM
);
1591 gtk_grid_attach (GTK_GRID (table
), bbox
, 0, row
, 2, 1);
1593 //content = gtk_dialog_get_header_bar(GTK_DIALOG (dialog));
1595 menu
= gtk_menu_new ();
1596 gtk_widget_set_halign (menu
, GTK_ALIGN_END
);
1598 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Import CSV"));
1599 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1600 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_pay_manage_dialog_load_csv
), &data
);
1602 menuitem
= gtk_menu_item_new_with_mnemonic (_("E_xport CSV"));
1603 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1604 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_pay_manage_dialog_save_csv
), &data
);
1606 menuitem
= gtk_separator_menu_item_new();
1607 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1609 menuitem
= gtk_menu_item_new_with_mnemonic (_("_Delete unused"));
1610 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
1611 g_signal_connect (G_OBJECT (menuitem
), "activate", G_CALLBACK (ui_pay_manage_dialog_delete_unused
), &data
);
1613 gtk_widget_show_all (menu
);
1616 widget
= gtk_menu_button_new();
1617 image
= gtk_image_new_from_icon_name (ICONNAME_HB_BUTTON_MENU
, GTK_ICON_SIZE_MENU
);
1618 g_object_set (widget
, "image", image
, "popup", GTK_MENU(menu
), NULL
);
1619 gtk_widget_set_halign (widget
, GTK_ALIGN_END
);
1620 gtk_box_pack_end(GTK_BOX (bbox
), widget
, FALSE
, FALSE
, 0);
1621 //gtk_header_bar_pack_end(GTK_HEADER_BAR (content), widget);
1623 data
.BT_search
= gtk_toggle_button_new ();
1624 image
= gtk_image_new_from_icon_name (ICONNAME_SYSTEM_SEARCH
, GTK_ICON_SIZE_BUTTON
);
1625 gtk_button_set_image (GTK_BUTTON(data
.BT_search
), image
);
1626 gtk_box_pack_end(GTK_BOX (bbox
), data
.BT_search
, FALSE
, FALSE
, 0);
1627 //gtk_header_bar_pack_end(GTK_HEADER_BAR (content), data.BT_search);
1631 box
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
1632 gtk_grid_attach (GTK_GRID (table
), box
, 0, row
, 2, 1);
1634 searchbar
= gtk_search_bar_new();
1635 gtk_container_add(GTK_CONTAINER(box
), searchbar
);
1636 widget
= make_search();
1637 data
.ST_search
= widget
;
1638 gtk_container_add (GTK_CONTAINER (searchbar
), widget
);
1639 gtk_search_bar_connect_entry(GTK_SEARCH_BAR(searchbar
), GTK_ENTRY(data
.ST_search
));
1640 gtk_search_bar_set_show_close_button(GTK_SEARCH_BAR(searchbar
), TRUE
);
1642 scrollwin
= gtk_scrolled_window_new(NULL
,NULL
);
1643 gtk_container_add(GTK_CONTAINER(box
), scrollwin
);
1644 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin
), GTK_SHADOW_ETCHED_IN
);
1645 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
), GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
1646 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrollwin
), HB_MINHEIGHT_LIST
);
1647 gtk_widget_set_hexpand (scrollwin
, TRUE
);
1648 gtk_widget_set_vexpand (scrollwin
, TRUE
);
1649 treeview
= ui_pay_listview_new(FALSE
, TRUE
);
1650 data
.LV_pay
= treeview
;
1651 gtk_container_add(GTK_CONTAINER(scrollwin
), treeview
);
1654 addreveal
= gtk_revealer_new ();
1655 gtk_grid_attach (GTK_GRID (table
), addreveal
, 0, row
, 2, 1);
1656 data
.ST_name
= gtk_entry_new ();
1657 gtk_entry_set_placeholder_text(GTK_ENTRY(data
.ST_name
), _("new payee") );
1658 gtk_widget_set_hexpand (data
.ST_name
, TRUE
);
1659 gtk_container_add(GTK_CONTAINER(addreveal
), data
.ST_name
);
1662 bbox
= gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL
);
1663 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox
), GTK_BUTTONBOX_START
);
1664 gtk_box_set_spacing (GTK_BOX (bbox
), SPACING_SMALL
);
1665 gtk_grid_attach (GTK_GRID (table
), bbox
, 0, row
, 2, 1);
1667 data
.BT_add
= gtk_toggle_button_new_with_mnemonic(_("_Add"));
1668 gtk_container_add (GTK_CONTAINER (bbox
), data
.BT_add
);
1671 data
.BT_edit
= gtk_button_new_with_mnemonic(_("_Edit"));
1672 gtk_container_add (GTK_CONTAINER (bbox
), data
.BT_edit
);
1674 data
.BT_merge
= gtk_button_new_with_mnemonic(_("_Merge"));
1675 gtk_container_add (GTK_CONTAINER (bbox
), data
.BT_merge
);
1677 data
.BT_delete
= gtk_button_new_with_mnemonic(_("_Delete"));
1678 gtk_container_add (GTK_CONTAINER (bbox
), data
.BT_delete
);
1681 //connect all our signals
1682 g_object_bind_property (data
.BT_add
, "active", addreveal
, "reveal-child", G_BINDING_BIDIRECTIONAL
);
1683 g_object_bind_property (data
.BT_search
, "active", searchbar
, "search-mode-enabled", G_BINDING_BIDIRECTIONAL
);
1685 g_signal_connect (G_OBJECT (data
.ST_search
), "search-changed", G_CALLBACK (ui_pay_manage_search_changed_cb
), &data
);
1686 g_signal_connect (G_OBJECT (data
.ST_name
), "activate", G_CALLBACK (ui_pay_manage_dialog_add
), NULL
);
1688 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
.LV_pay
)), "changed", G_CALLBACK (ui_pay_manage_dialog_selection
), NULL
);
1689 g_signal_connect (GTK_TREE_VIEW(data
.LV_pay
), "row-activated", G_CALLBACK (ui_pay_manage_dialog_onRowActivated
), NULL
);
1691 g_signal_connect (G_OBJECT (data
.BT_edit
), "clicked", G_CALLBACK (ui_pay_manage_dialog_edit
), NULL
);
1692 g_signal_connect (G_OBJECT (data
.BT_merge
), "clicked", G_CALLBACK (ui_pay_manage_dialog_merge
), NULL
);
1693 g_signal_connect (G_OBJECT (data
.BT_delete
), "clicked", G_CALLBACK (ui_pay_manage_dialog_delete
), NULL
);
1695 //setup, init and show dialog
1697 ui_pay_listview_populate(data
.LV_pay
, NULL
);
1698 ui_pay_manage_dialog_update(data
.LV_pay
, NULL
);
1700 gtk_widget_show_all (dialog
);
1703 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
1707 case GTK_RESPONSE_ACCEPT
:
1708 //do_application_specific_something ();
1711 //do_nothing_since_dialog_was_cancelled ();
1715 // cleanup and destroy
1717 gtk_widget_destroy (dialog
);
1719 GLOBALS
->changes_count
+= data
.change
;