1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "ui-category.h"
32 /* our global datas */
33 extern struct HomeBank
*GLOBALS
;
35 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
38 * ui_cat_comboboxentry_get_name:
40 * get the name of the active category or -1
42 * Return value: a new allocated name tobe freed with g_free
46 ui_cat_comboboxentry_get_name(GtkComboBox
*entry_box
)
51 DB( g_print ("ui_cat_comboboxentry_get_name()\n") );
53 cbname
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
56 name
= g_strdup(cbname
);
65 * ui_cat_comboboxentry_get_key:
67 * get the key of the active category or -1
69 * Return value: the key or -1
73 ui_cat_comboboxentry_get_key_add_new(GtkComboBox
*entry_box
)
78 DB( g_print ("ui_cat_comboboxentry_get_key()\n") );
80 name
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
85 item
= da_cat_get_by_fullname(name
);
89 //todo: check prefs + ask the user here 1st time
90 item
= da_cat_append_ifnew_by_fullname(name
, FALSE
);
92 ui_cat_comboboxentry_add(entry_box
, item
);
100 * ui_cat_comboboxentry_get_key:
102 * get the key of the active category or -1
104 * Return value: the key or -1
108 ui_cat_comboboxentry_get_key(GtkComboBox
*entry_box
)
113 DB( g_print ("ui_cat_comboboxentry_get_key()\n") );
115 name
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
119 item
= da_cat_get_by_fullname(name
);
127 ui_cat_comboboxentry_set_active(GtkComboBox
*entry_box
, guint32 key
)
132 DB( g_print ("ui_cat_comboboxentry_set_active()\n") );
137 item
= da_cat_get(key
);
140 if( item
->parent
== 0)
141 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))), item
->name
);
144 fullname
= da_cat_get_fullname(item
);
145 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))), fullname
);
151 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))), "");
156 * ui_cat_comboboxentry_add:
158 * Add a single element (useful for dynamics add)
164 ui_cat_comboboxentry_add(GtkComboBox
*entry_box
, Category
*item
)
167 DB( g_print ("ui_cat_comboboxentry_add()\n") );
170 DB( g_print (" -> try to add: '%s'\n", item
->name
) );
172 if( item
->name
!= NULL
)
177 gchar
*fullname
, *name
;
179 fullname
= da_cat_get_fullname(item
);
180 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box
));
182 if( item
->parent
== 0 )
183 name
= g_strdup(item
->name
);
185 name
= g_strdup_printf(" - %s", item
->name
);
187 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
188 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
201 ui_cat_comboboxentry_populate_ghfunc(gpointer key
, gpointer value
, struct catPopContext
*ctx
)
204 Category
*item
= value
;
205 gchar
*fullname
, *name
;
208 if( ( item
->key
!= ctx
->except_key
) )
210 type
= (item
->flags
& GF_INCOME
) ? '+' : '-';
212 fullname
= da_cat_get_fullname(item
);
214 //DB( g_print ("cat combo populate [%d:%d] %s\n", item->parent, item->key, fullname) );
217 name
= g_strdup(item
->name
);
220 if( item
->parent
== 0 )
221 name
= g_strdup_printf("%s [%c]", item
->name
, type
);
223 name
= g_strdup_printf(" %c %s", type
, item
->name
);
226 gtk_list_store_append (GTK_LIST_STORE(ctx
->model
), &iter
);
227 gtk_list_store_set (GTK_LIST_STORE(ctx
->model
), &iter
,
230 2, item
->parent
== 0 ? 1 : 0,
240 * ui_cat_comboboxentry_populate:
242 * Populate the list and completion
248 ui_cat_comboboxentry_populate(GtkComboBox
*entry_box
, GHashTable
*hash
)
250 ui_cat_comboboxentry_populate_except(entry_box
, hash
, -1);
254 ui_cat_comboboxentry_populate_except(GtkComboBox
*entry_box
, GHashTable
*hash
, guint except_key
)
257 GtkEntryCompletion
*completion
;
258 struct catPopContext ctx
;
260 DB( g_print ("ui_cat_comboboxentry_populate()\n") );
262 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box
));
263 completion
= gtk_entry_get_completion(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
265 /* keep our model alive and detach from comboboxentry and completion */
267 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box
), NULL
);
268 gtk_entry_completion_set_model (completion
, NULL
);
270 /* clear and populate */
272 ctx
.except_key
= except_key
;
274 gtk_list_store_clear (GTK_LIST_STORE(model
));
275 g_hash_table_foreach(hash
, (GHFunc
)ui_cat_comboboxentry_populate_ghfunc
, &ctx
);
277 /* reatach our model */
278 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box
), model
);
279 gtk_entry_completion_set_model (completion
, model
);
280 g_object_unref(model
);
282 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model
), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID
, GTK_SORT_ASCENDING
);
289 ui_cat_comboboxentry_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
292 gchar
*name1
, *name2
;
294 gtk_tree_model_get(model
, a
, 0, &name1
, -1);
295 gtk_tree_model_get(model
, b
, 0, &name2
, -1);
297 retval
= hb_string_utf8_compare(name1
, name2
);
299 retval = (entry1->flags & GF_INCOME) - (entry2->flags & GF_INCOME);
302 retval = hb_string_utf8_compare(entry1->name, entry2->name);
314 ui_cat_comboboxentry_test (GtkCellLayout
*cell_layout
,
315 GtkCellRenderer
*cell
,
316 GtkTreeModel
*tree_model
,
326 gtk_tree_model_get(tree_model
, iter
,
331 style
= subcat
== 0 ? PANGO_STYLE_ITALIC
: PANGO_STYLE_NORMAL
;
334 name
= _("(no category)"); //todo: not used
345 ui_cat_comboboxentry_completion_func (GtkEntryCompletion
*completion
,
351 gchar
*normalized_string
;
352 gchar
*case_normalized_string
;
354 gboolean ret
= FALSE
;
358 model
= gtk_entry_completion_get_model (completion
);
360 gtk_tree_model_get (model
, iter
,
366 normalized_string
= g_utf8_normalize (item
, -1, G_NORMALIZE_ALL
);
368 if (normalized_string
!= NULL
)
370 case_normalized_string
= g_utf8_casefold (normalized_string
, -1);
372 //g_print("match '%s' for '%s' ?\n", key, case_normalized_string);
373 //if (!strncmp (key, case_normalized_string, strlen (key)))
374 if (g_strstr_len (case_normalized_string
, strlen (case_normalized_string
), key
))
377 // g_print(" ==> yes !\n");
381 g_free (case_normalized_string
);
383 g_free (normalized_string
);
392 * ui_cat_comboboxentry_new:
394 * Create a new category comboboxentry
396 * Return value: the new widget
400 ui_cat_comboboxentry_new(GtkWidget
*label
)
403 GtkWidget
*comboboxentry
;
404 GtkEntryCompletion
*completion
;
405 GtkCellRenderer
*renderer
;
407 DB( g_print ("ui_cat_comboboxentry_new()\n") );
410 store
= gtk_list_store_new (3,
411 G_TYPE_STRING
, //fullname Car:Fuel
412 G_TYPE_STRING
, //name Car or Fuel
413 G_TYPE_BOOLEAN
//subcat = 1
415 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store
), ui_cat_comboboxentry_compare_func
, NULL
, NULL
);
417 completion
= gtk_entry_completion_new ();
418 gtk_entry_completion_set_model (completion
, GTK_TREE_MODEL(store
));
419 g_object_set(completion
, "text-column", 0, NULL
);
420 gtk_entry_completion_set_match_func(completion
, ui_cat_comboboxentry_completion_func
, NULL
, NULL
);
421 gtk_entry_completion_set_minimum_key_length(completion
, 2);
423 renderer
= gtk_cell_renderer_text_new ();
424 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion
), renderer
, TRUE
);
425 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion
), renderer
, "text", 0, NULL
);
427 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion
),
429 ui_cat_comboboxentry_test
,
432 // dothe same for combobox
434 comboboxentry
= gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store
));
435 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboboxentry
), 0);
438 gtk_cell_layout_clear(GTK_CELL_LAYOUT (comboboxentry
));
440 renderer
= gtk_cell_renderer_text_new ();
441 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comboboxentry
), renderer
, TRUE
);
442 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comboboxentry
), renderer
, "text", 0, NULL
);
444 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (comboboxentry
),
446 ui_cat_comboboxentry_test
,
451 gtk_entry_set_completion (GTK_ENTRY (gtk_bin_get_child(GTK_BIN (comboboxentry
))), completion
);
453 g_object_unref(store
);
456 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), comboboxentry
);
458 gtk_widget_set_size_request(comboboxentry
, HB_MINWIDTH_COMBO
, -1);
460 return comboboxentry
;
463 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
466 ui_cat_listview_fixed_toggled (GtkCellRendererToggle
*cell
,
470 GtkTreeModel
*model
= (GtkTreeModel
*)data
;
472 GtkTreePath
*path
= gtk_tree_path_new_from_string (path_str
);
475 /* get toggled iter */
476 gtk_tree_model_get_iter (model
, &iter
, path
);
477 gtk_tree_model_get (model
, &iter
, LST_DEFCAT_TOGGLE
, &fixed
, -1);
479 /* do something with the value */
483 gtk_tree_store_set (GTK_TREE_STORE (model
), &iter
, LST_DEFCAT_TOGGLE
, fixed
, -1);
486 gtk_tree_path_free (path
);
491 ** The function should return:
492 ** a negative integer if the first value comes before the second,
493 ** 0 if they are equal,
494 ** or a positive integer if the first value comes after the second.
497 ui_cat_listview_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
500 Category
*entry1
, *entry2
;
502 gtk_tree_model_get(model
, a
, LST_DEFCAT_DATAS
, &entry1
, -1);
503 gtk_tree_model_get(model
, b
, LST_DEFCAT_DATAS
, &entry2
, -1);
505 retval
= (entry1
->flags
& GF_INCOME
) - (entry2
->flags
& GF_INCOME
);
508 retval
= hb_string_utf8_compare(entry1
->name
, entry2
->name
);
515 ** draw some text from the stored data structure
518 ui_cat_listview_text_cell_data_function (GtkTreeViewColumn
*col
,
519 GtkCellRenderer
*renderer
,
528 gtk_tree_model_get(model
, iter
, LST_DEFCAT_DATAS
, &entry
, -1);
530 name
= _("(no category)");
534 gchar type
= (entry
->flags
& GF_INCOME
) ? '+' : '-';
537 string
= g_markup_printf_escaped ("%d > [%d] %s [%c] %d", entry
->key
, entry
->parent
, name
, type
, entry
->flags
);
540 string
= g_strdup(name
);
543 if( entry
->parent
== 0 )
544 string
= g_markup_printf_escaped("%s [%c]", name
, type
);
546 string
= g_markup_printf_escaped(" %c <i>%s</i>", type
, name
);
547 //string = g_strdup_printf(" - %s", name);
551 //g_object_set(renderer, "text", string, NULL);
552 g_object_set(renderer
, "markup", string
, NULL
);
562 ui_cat_listview_add(GtkTreeView
*treeview
, Category
*item
, GtkTreeIter
*parent
)
568 DB( g_print ("ui_cat_listview_add()\n") );
570 if( item
->name
!= NULL
)
572 model
= gtk_tree_view_get_model(treeview
);
574 gtk_tree_store_append (GTK_TREE_STORE(model
), &iter
, parent
);
575 gtk_tree_store_set (GTK_TREE_STORE(model
), &iter
,
576 LST_DEFCAT_TOGGLE
, FALSE
,
577 LST_DEFCAT_DATAS
, item
,
578 LST_DEFCAT_NAME
, item
->name
,
581 //select the added line
583 path
= gtk_tree_model_get_path(model
, &iter
);
584 gtk_tree_view_expand_to_path (treeview
, path
);
585 gtk_tree_path_free(path
);
586 gtk_tree_selection_select_iter (gtk_tree_view_get_selection(treeview
), &iter
);
592 ui_cat_listview_get_selected(GtkTreeView
*treeview
)
594 GtkTreeSelection
*selection
;
598 DB( g_print ("ui_cat_listview_get_selected()\n") );
600 selection
= gtk_tree_view_get_selection(treeview
);
601 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
605 gtk_tree_model_get(model
, &iter
, LST_DEFCAT_DATAS
, &item
, -1);
613 ui_cat_listview_get_selected_parent(GtkTreeView
*treeview
, GtkTreeIter
*return_iter
)
615 GtkTreeSelection
*selection
;
621 DB( g_print ("ui_cat_listview_get_selected_parent()\n") );
624 selection
= gtk_tree_view_get_selection(treeview
);
625 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
627 path
= gtk_tree_model_get_path(model
, &iter
);
629 DB( g_print ("path depth = %d\n", gtk_tree_path_get_depth(path
)) );
632 if(gtk_tree_path_get_depth(path
) > 1)
634 if( gtk_tree_path_up(path
) )
637 DB( g_print ("up ok\n") );
639 if(gtk_tree_model_get_iter(model
, &iter
, path
))
642 DB( g_print ("iter ok\n") );
645 gtk_tree_model_get(model
, &iter
, LST_DEFCAT_DATAS
, &item
, -1);
657 DB( g_print ("path <=1\n") );
659 gtk_tree_model_get(model
, &iter
, LST_DEFCAT_DATAS
, &item
, -1);
673 gboolean
ui_cat_listview_remove (GtkTreeModel
*model
, guint32 key
)
675 GtkTreeIter iter
, child
;
676 gboolean valid
, cvalid
;
679 DB( g_print("ui_cat_listview_remove() \n") );
681 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
684 gtk_tree_model_get (model
, &iter
, LST_DEFCAT_DATAS
, &item
, -1);
686 DB( g_print(" + item %p, %s\n", item
, item
->name
) );
688 if(item
->key
== key
|| item
->parent
== key
)
690 DB( g_print(" + removing cat %s\n", item
->name
) );
691 gtk_tree_store_remove(GTK_TREE_STORE(model
), &iter
);
695 cvalid
= gtk_tree_model_iter_children (GTK_TREE_MODEL(model
), &child
, &iter
);
698 gtk_tree_model_get(GTK_TREE_MODEL(model
), &child
, LST_DEFCAT_DATAS
, &item
, -1);
699 if(item
->key
== key
|| item
->parent
== key
)
701 DB( g_print(" + removing subcat %s\n", item
->name
) );
702 gtk_tree_store_remove(GTK_TREE_STORE(model
), &child
);
705 cvalid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &child
);
707 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
716 ui_cat_listview_remove_selected(GtkTreeView
*treeview
)
718 GtkTreeSelection
*selection
;
722 DB( g_print("ui_cat_listview_remove_selected() \n") );
724 selection
= gtk_tree_view_get_selection(treeview
);
725 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
727 gtk_tree_store_remove(GTK_TREE_STORE(model
), &iter
);
733 ui_cat_listview_get_top_level (GtkTreeModel
*liststore
, guint32 key
, GtkTreeIter
*return_iter
)
739 DB( g_print("ui_cat_listview_get_top_level() \n") );
741 if( liststore
!= NULL
)
743 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(liststore
), &iter
);
746 gtk_tree_model_get (liststore
, &iter
, LST_DEFCAT_DATAS
, &item
, -1);
754 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(liststore
), &iter
);
762 static void ui_cat_listview_populate_cat_ghfunc(gpointer key
, gpointer value
, GtkTreeModel
*model
)
764 GtkTreeIter toplevel
;
765 Category
*item
= value
;
767 //DB( g_print("cat listview populate: %d %s\n", (guint32 *)key, item->name) );
769 if( item
->parent
== 0 )
771 gtk_tree_store_append (GTK_TREE_STORE(model
), &toplevel
, NULL
);
773 gtk_tree_store_set (GTK_TREE_STORE(model
), &toplevel
,
774 LST_DEFCAT_TOGGLE
, FALSE
,
775 LST_DEFCAT_DATAS
, item
,
776 LST_DEFCAT_NAME
, item
->name
,
782 static void ui_cat_listview_populate_subcat_ghfunc(gpointer key
, gpointer value
, GtkTreeModel
*model
)
784 GtkTreeIter toplevel
, child
;
785 Category
*item
= value
;
789 if( item
->parent
!= 0 )
791 ret
= ui_cat_listview_get_top_level(model
, item
->parent
, &toplevel
);
794 gtk_tree_store_append (GTK_TREE_STORE(model
), &child
, &toplevel
);
796 gtk_tree_store_set (GTK_TREE_STORE(model
), &child
,
797 LST_DEFCAT_TOGGLE
, FALSE
,
798 LST_DEFCAT_DATAS
, item
,
799 LST_DEFCAT_NAME
, item
->name
,
808 static void ui_cat_listview_sort_force(GtkTreeSortable
*sortable
, gpointer user_data
)
813 DB( g_print("ui_cat_listview_sort_force()\n") );
815 gtk_tree_sortable_get_sort_column_id(sortable
, &sort_column_id
, &order
);
816 DB( g_print(" - id %d order %d\n", sort_column_id
, order
) );
818 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sortable
), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID
, order
);
819 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sortable
), sort_column_id
, order
);
825 void ui_cat_listview_populate(GtkWidget
*view
)
829 DB( g_print("ui_cat_listview_populate() \n") );
832 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
834 gtk_tree_store_clear (GTK_TREE_STORE(model
));
836 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
837 gtk_tree_view_set_model(GTK_TREE_VIEW(view
), NULL
); /* Detach model from view */
839 /* we have to do this in 2 times to ensure toplevel (cat) will be added before childs */
840 /* populate cat 1st */
841 g_hash_table_foreach(GLOBALS
->h_cat
, (GHFunc
)ui_cat_listview_populate_cat_ghfunc
, model
);
842 g_hash_table_foreach(GLOBALS
->h_cat
, (GHFunc
)ui_cat_listview_populate_subcat_ghfunc
, model
);
845 gtk_tree_view_set_model(GTK_TREE_VIEW(view
), model
); /* Re-attach model to view */
846 g_object_unref(model
);
848 gtk_tree_view_expand_all (GTK_TREE_VIEW(view
));
854 ui_cat_listview_new(gboolean withtoggle
)
858 GtkCellRenderer
*renderer
;
859 GtkTreeViewColumn
*column
;
861 DB( g_print("ui_cat_listview_new() \n") );
863 /* create tree store */
864 store
= gtk_tree_store_new(
872 treeview
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
873 g_object_unref(store
);
877 if( withtoggle
== TRUE
)
879 renderer
= gtk_cell_renderer_toggle_new ();
880 column
= gtk_tree_view_column_new_with_attributes ("Show", renderer
, "active", LST_DEFCAT_TOGGLE
, NULL
);
881 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
883 g_signal_connect (G_OBJECT(renderer
), "toggled",
884 G_CALLBACK (ui_cat_listview_fixed_toggled
), store
);
889 column
= gtk_tree_view_column_new();
890 renderer
= gtk_cell_renderer_text_new ();
891 gtk_tree_view_column_pack_start(column
, renderer
, TRUE
);
892 gtk_tree_view_column_set_cell_data_func(column
, renderer
, ui_cat_listview_text_cell_data_function
, GINT_TO_POINTER(LST_DEFCAT_NAME
), NULL
);
893 //gtk_tree_view_column_set_sort_column_id (column, LST_DEFACC_NAME);
894 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
898 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview
), FALSE
);
900 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store
), LST_DEFCAT_DATAS
, ui_cat_listview_compare_func
, NULL
, NULL
);
901 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store
), LST_DEFCAT_DATAS
, GTK_SORT_ASCENDING
);
903 //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
904 //gtk_tree_view_set_expander_column(GTK_TREE_VIEW(treeview), column);
909 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
912 //add exist function + check before add
919 * ui_cat_manage_filter_text_handler
921 * filter to entry to avoid seizure of ':' char
924 static void ui_cat_manage_filter_text_handler (GtkEntry
*entry
,
930 GtkEditable
*editable
= GTK_EDITABLE(entry
);
931 gint i
, count
=0, pos
;
932 gchar
*result
= g_new0 (gchar
, length
+1);
934 for (i
=0; i
< length
; i
++)
938 result
[count
++] = text
[i
];
943 g_signal_handlers_block_by_func (G_OBJECT (editable
),
944 G_CALLBACK (ui_cat_manage_filter_text_handler
),
946 gtk_editable_insert_text (editable
, result
, count
, &pos
);
947 g_signal_handlers_unblock_by_func (G_OBJECT (editable
),
948 G_CALLBACK (ui_cat_manage_filter_text_handler
),
951 g_signal_stop_emission_by_name (G_OBJECT (editable
), "insert_text");
960 * ui_cat_manage_dialog_load_csv:
964 ui_cat_manage_dialog_load_csv( GtkWidget
*widget
, gpointer user_data
)
966 struct ui_cat_manage_dialog_data
*data
;
967 gchar
*filename
= NULL
;
970 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget
), GTK_TYPE_WINDOW
)), "inst_data");
972 DB( g_print("(ui_cat_manage_dialog) load csv - data %p\n", data
) );
974 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_OPEN
, &filename
, NULL
) == TRUE
)
976 DB( g_print(" + filename is %s\n", filename
) );
978 if(!category_load_csv(filename
, &error
))
980 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_ERROR
,
981 _("File format error"),
982 _("The csv file must contains the exact numbers of column,\nseparated by a semi-colon, please see the help for more details.")
987 ui_cat_listview_populate(data
->LV_cat
);
993 * ui_cat_manage_dialog_save_csv:
997 ui_cat_manage_dialog_save_csv( GtkWidget
*widget
, gpointer user_data
)
999 struct ui_cat_manage_dialog_data
*data
;
1000 gchar
*filename
= NULL
;
1003 DB( g_print("(defcategory) save csv\n") );
1005 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1007 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, NULL
) == TRUE
)
1009 DB( g_print(" + filename is %s\n", filename
) );
1011 category_save_csv(filename
, &error
);
1017 * ui_cat_manage_dialog_add:
1019 * add an empty new category/subcategory
1023 ui_cat_manage_dialog_add(GtkWidget
*widget
, gpointer user_data
)
1025 struct ui_cat_manage_dialog_data
*data
;
1026 gboolean subcat
= GPOINTER_TO_INT(user_data
);
1028 //GtkTreeModel *model;
1029 GtkTreeIter parent_iter
;
1030 GtkWidget
*tmpwidget
;
1031 Category
*item
, *paritem
;
1034 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1035 DB( g_print("\n(defcategory) add (data=%p) is subcat=%d\n", data
, subcat
) );
1037 tmpwidget
= (subcat
== FALSE
? data
->ST_name1
: data
->ST_name2
);
1038 name
= gtk_entry_get_text(GTK_ENTRY(tmpwidget
));
1039 //model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_cat));
1041 /* ignore if item is empty */
1046 item
= da_cat_malloc();
1047 item
->name
= g_strdup(name
);
1049 g_strstrip(item
->name
);
1051 /* if cat use new id */
1054 type
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_type
));
1056 item
->flags
|= GF_INCOME
;
1058 if( da_cat_append(item
) )
1060 DB( g_print(" => add cat: %p %d, %s type=%d\n", item
, subcat
, item
->name
, type
) );
1061 ui_cat_listview_add(GTK_TREE_VIEW(data
->LV_cat
), item
, NULL
);
1064 /* if subcat use parent id & gf_income */
1067 paritem
= ui_cat_listview_get_selected_parent(GTK_TREE_VIEW(data
->LV_cat
), &parent_iter
);
1070 DB( g_print(" => selitem parent: %d, %s\n", paritem
->key
, paritem
->name
) );
1072 item
->parent
= paritem
->key
;
1073 item
->flags
|= (paritem
->flags
& GF_INCOME
);
1074 item
->flags
|= GF_SUB
;
1076 if(da_cat_append(item
))
1078 DB( g_print(" => add subcat: %p %d, %s\n", item
, subcat
, item
->name
) );
1079 ui_cat_listview_add(GTK_TREE_VIEW(data
->LV_cat
), item
, &parent_iter
);
1084 gtk_entry_set_text(GTK_ENTRY(tmpwidget
),"");
1089 static void ui_cat_manage_dialog_modify_entry_cb(GtkEditable
*editable
, gpointer user_data
)
1091 GtkDialog
*window
= user_data
;
1092 const gchar
*buffer
;
1094 buffer
= gtk_entry_get_text(GTK_ENTRY(editable
));
1095 gtk_dialog_set_response_sensitive(GTK_DIALOG(window
), GTK_RESPONSE_ACCEPT
, strlen(buffer
) > 0 ? TRUE
: FALSE
);
1103 ui_cat_manage_dialog_modify(GtkWidget
*widget
, gpointer user_data
)
1105 struct ui_cat_manage_dialog_data
*data
;
1106 GtkWidget
*window
, *content
, *mainvbox
, *w_name
, *w_type
= NULL
;
1107 GtkTreeSelection
*selection
;
1108 GtkTreeModel
*model
;
1111 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1112 DB( g_print("\n(defcategory) modify\n") );
1114 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_cat
));
1115 //if true there is a selected node
1116 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
1120 gtk_tree_model_get(model
, &iter
, LST_DEFCAT_DATAS
, &item
, -1);
1122 window
= gtk_dialog_new_with_buttons (_("Modify..."),
1123 GTK_WINDOW (data
->window
),
1126 GTK_RESPONSE_REJECT
,
1128 GTK_RESPONSE_ACCEPT
,
1131 content
= gtk_dialog_get_content_area(GTK_DIALOG (window
));
1132 mainvbox
= gtk_vbox_new (FALSE
, 0);
1133 gtk_box_pack_start (GTK_BOX (content
), mainvbox
, TRUE
, TRUE
, 0);
1134 gtk_container_set_border_width (GTK_CONTAINER (mainvbox
), HB_MAINBOX_SPACING
);
1136 w_name
= gtk_entry_new();
1137 gtk_box_pack_start (GTK_BOX (mainvbox
), w_name
, TRUE
, TRUE
, 0);
1139 gtk_entry_set_text(GTK_ENTRY(w_name
), item
->name
);
1140 gtk_widget_grab_focus (w_name
);
1142 gtk_entry_set_activates_default (GTK_ENTRY(w_name
), TRUE
);
1144 if(!(item
->flags
& GF_SUB
))
1146 w_type
= gtk_check_button_new_with_mnemonic(_("_Income"));
1147 gtk_box_pack_start (GTK_BOX (mainvbox
), w_type
, TRUE
, TRUE
, 0);
1148 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w_type
), item
->flags
& GF_INCOME
? TRUE
: FALSE
);
1151 gtk_widget_show_all(mainvbox
);
1153 g_signal_connect (G_OBJECT (w_name
), "changed", G_CALLBACK (ui_cat_manage_dialog_modify_entry_cb
), window
);
1155 gtk_dialog_set_default_response(GTK_DIALOG( window
), GTK_RESPONSE_ACCEPT
);
1158 gint result
= gtk_dialog_run (GTK_DIALOG (window
));
1160 if(result
== GTK_RESPONSE_ACCEPT
)
1164 // 1: manage renaming
1165 name
= gtk_entry_get_text(GTK_ENTRY(w_name
));
1166 // ignore if item is empty
1169 if( category_rename(item
, name
) )
1176 gchar
*fromname
, *toname
= NULL
;
1178 fromname
= da_cat_get_fullname(item
);
1180 if( item
->parent
== 0)
1181 toname
= g_strdup(name
);
1184 parent
= da_cat_get(item
->parent
);
1187 toname
= g_strdup_printf("%s:%s", parent
->name
, name
);
1192 ui_dialog_msg_infoerror(GTK_WINDOW(window
), GTK_MESSAGE_ERROR
,
1194 _("Cannot rename this Category,\n"
1195 "from '%s' to '%s',\n"
1196 "this name already exists."),
1207 // 2: manage flag change
1208 if(!(item
->flags
& GF_SUB
))
1212 isIncome
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w_type
));
1213 data
->change
+= category_change_type(item
, isIncome
);
1216 ui_cat_listview_sort_force(GTK_TREE_SORTABLE(model
), NULL
);
1219 // cleanup and destroy
1220 gtk_widget_destroy (window
);
1226 static void ui_cat_manage_dialog_move_entry_cb(GtkComboBox
*widget
, gpointer user_data
)
1228 GtkDialog
*window
= user_data
;
1231 buffer
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (widget
))));
1232 gtk_dialog_set_response_sensitive(GTK_DIALOG(window
), GTK_RESPONSE_ACCEPT
, strlen(buffer
) > 0 ? TRUE
: FALSE
);
1239 static void ui_cat_manage_dialog_move(GtkWidget
*widget
, gpointer user_data
)
1241 struct ui_cat_manage_dialog_data
*data
;
1242 GtkWidget
*window
, *content
, *mainvbox
, *getwidget
;
1243 GtkTreeSelection
*selection
;
1244 GtkTreeModel
*model
;
1247 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1248 DB( g_print("(defcategory) move\n") );
1250 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_cat
));
1251 //if true there is a selected node
1252 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
1256 gtk_tree_model_get(model
, &iter
, LST_DEFCAT_DATAS
, &item
, -1);
1258 window
= gtk_dialog_new_with_buttons (_("Move to..."),
1259 GTK_WINDOW (data
->window
),
1262 GTK_RESPONSE_REJECT
,
1264 GTK_RESPONSE_ACCEPT
,
1267 content
= gtk_dialog_get_content_area(GTK_DIALOG (window
));
1268 mainvbox
= gtk_vbox_new (FALSE
, 0);
1269 gtk_box_pack_start (GTK_BOX (content
), mainvbox
, TRUE
, TRUE
, 0);
1270 gtk_container_set_border_width (GTK_CONTAINER (mainvbox
), HB_BOX_SPACING
);
1272 getwidget
= ui_cat_comboboxentry_new(NULL
);
1273 gtk_box_pack_start (GTK_BOX (mainvbox
), getwidget
, TRUE
, TRUE
, 0);
1275 gtk_dialog_set_response_sensitive(GTK_DIALOG(window
), GTK_RESPONSE_ACCEPT
, FALSE
);
1277 gtk_widget_show_all(mainvbox
);
1279 g_signal_connect (G_OBJECT (getwidget
), "changed", G_CALLBACK (ui_cat_manage_dialog_move_entry_cb
), window
);
1281 ui_cat_comboboxentry_populate_except(GTK_COMBO_BOX(getwidget
), GLOBALS
->h_cat
, item
->key
);
1282 gtk_widget_grab_focus (getwidget
);
1285 gint result
= gtk_dialog_run (GTK_DIALOG (window
));
1287 if(result
== GTK_RESPONSE_ACCEPT
)
1292 npn
= ui_cat_comboboxentry_get_name(GTK_COMBO_BOX(getwidget
)),
1294 result
= ui_dialog_msg_question(
1296 _("Move this category to another one ?"),
1297 _("This will replace '%s' by '%s',\n"
1298 "and then remove '%s'"),
1305 if( result
== GTK_RESPONSE_YES
)
1307 Category
*newcat
, *parent
;
1310 dstkey
= ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(getwidget
));
1311 newcat
= da_cat_get (dstkey
);
1313 DB( g_print(" moving to %d\n", dstkey
) );
1315 category_move(item
->key
, dstkey
);
1317 //keep the income with us
1318 parent
= da_cat_get(item
->parent
);
1319 if(parent
!= NULL
&& (parent
->flags
& GF_INCOME
))
1320 newcat
->flags
|= GF_INCOME
;
1322 // remove the old category
1323 da_cat_remove(item
->key
);
1324 ui_cat_listview_remove_selected(GTK_TREE_VIEW(data
->LV_cat
));
1326 //add the new category into listview
1328 ui_cat_listview_add(GTK_TREE_VIEW(data
->LV_cat
), newcat
, NULL
);
1334 // cleanup and destroy
1335 gtk_widget_destroy (window
);
1342 ** remove the selected payee to our treeview and temp GList
1344 static void ui_cat_manage_dialog_remove(GtkWidget
*widget
, gpointer user_data
)
1346 struct ui_cat_manage_dialog_data
*data
;
1351 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1352 DB( g_print("\n(defcategory) remove (data=%x)\n", (guint
)data
) );
1355 item
= ui_cat_listview_get_selected(GTK_TREE_VIEW(data
->LV_cat
));
1358 if( category_is_used(item
->key
) == TRUE
)
1360 result
= ui_dialog_msg_question(
1361 GTK_WINDOW(data
->window
),
1362 _("Remove a category ?"),
1363 _("If you remove '%s', archive and transaction referencing this category\n"
1364 "will set place to 'no category'"),
1369 if( result
== GTK_RESPONSE_YES
)
1371 category_move(item
->key
, 0);
1373 else if( result
== GTK_RESPONSE_NO
)
1381 ui_cat_listview_remove(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_cat
)), item
->key
);
1382 da_cat_remove(item
->key
);
1391 * ui_cat_manage_dialog_update:
1395 ui_cat_manage_dialog_update(GtkWidget
*treeview
, gpointer user_data
)
1397 struct ui_cat_manage_dialog_data
*data
;
1399 gboolean selected
, sensitive
;
1400 GtkTreeSelection
*selection
;
1401 GtkTreeModel
*model
;
1405 gboolean haschild
= FALSE
;
1407 DB( g_print("ui_cat_manage_dialog_update()\n") );
1409 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
1410 //window = gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW);
1411 //DB( g_print("(defpayee) widget=%08lx, window=%08lx, inst_data=%08lx\n", treeview, window, data) );
1413 //if true there is a selected node
1414 selected
= gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_cat
)), &model
, &iter
);
1416 DB( g_print(" selected = %d\n", selected
) );
1421 gtk_tree_model_get_iter_first(model
, &iter
);
1422 if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_cat
)), &iter
))
1424 DB( g_print(" 0 active = %d\n", 1) );
1429 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
));
1431 //count = gtk_tree_selection_count_selected_rows(selection);
1432 //DB( g_print(" => select count=%d\n", count) );
1435 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
1437 gchar
*tree_path_str
;
1440 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
,
1441 LST_DEFCAT_DATAS
, &item
,
1444 haschild
= gtk_tree_model_iter_has_child(GTK_TREE_MODEL(model
), &iter
);
1445 DB( g_print(" => has child=%d\n", haschild
) );
1448 path
= gtk_tree_model_get_path(gtk_tree_view_get_model(GTK_TREE_VIEW(treeview
)), &iter
);
1449 tree_path_str
= gtk_tree_path_to_string(path
);
1450 DB( g_print(" => select is=%s, depth=%d (id=%d, %s) flags=%d\n",
1452 gtk_tree_path_get_depth(path
),
1457 g_free(tree_path_str
);
1459 //get parent if subcategory selectd
1460 DB( g_print(" => get parent for title\n") );
1461 if(gtk_tree_path_get_depth(path
) != 1)
1462 gtk_tree_path_up(path
);
1464 if(gtk_tree_model_get_iter(model
, &iter
, path
))
1468 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
,
1469 LST_DEFCAT_DATAS
, &tmpitem
,
1472 category
= tmpitem
->name
;
1475 DB( g_print(" => parent is %s\n", category
) );
1479 gtk_tree_path_free(path
);
1483 gtk_label_set_text(GTK_LABEL(data
->LA_category
), category
);
1485 sensitive
= (selected
== TRUE
) ? TRUE
: FALSE
;
1486 gtk_widget_set_sensitive(data
->ST_name2
, sensitive
);
1487 gtk_widget_set_sensitive(data
->BT_add2
, sensitive
);
1488 gtk_widget_set_sensitive(data
->BT_mov
, sensitive
);
1489 gtk_widget_set_sensitive(data
->BT_mod
, sensitive
);
1491 //avoid removing top categories
1492 sensitive
= (haschild
== TRUE
) ? FALSE
: sensitive
;
1494 gtk_widget_set_sensitive(data
->BT_rem
, sensitive
);
1501 static void ui_cat_manage_dialog_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1503 ui_cat_manage_dialog_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
1506 static void ui_cat_manage_dialog_onRowActivated (GtkTreeView
*treeview
,
1508 GtkTreeViewColumn
*col
,
1511 GtkTreeModel
*model
;
1514 DB( g_print("ui_cat_manage_dialog_onRowActivated()\n") );
1517 model
= gtk_tree_view_get_model(treeview
);
1518 gtk_tree_model_get_iter_first(model
, &iter
);
1519 if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
)), &iter
) == FALSE
)
1521 ui_cat_manage_dialog_modify(GTK_WIDGET(treeview
), NULL
);
1531 static gboolean
ui_cat_manage_dialog_cleanup(struct ui_cat_manage_dialog_data
*data
, gint result
)
1533 gboolean doupdate
= FALSE
;
1535 DB( g_print("(defcategory) cleanup\n") );
1537 if(result
== GTK_RESPONSE_ACCEPT
)
1540 //do_application_specific_something ();
1541 DB( g_print(" accept\n") );
1544 GLOBALS
->changes_count
+= data
->change
;
1547 DB( g_print(" free tmp_list\n") );
1549 //da_category_destroy(data->tmp_list);
1557 static void ui_cat_manage_dialog_setup(struct ui_cat_manage_dialog_data
*data
)
1559 DB( g_print("(defcategory) setup\n") );
1562 data
->tmp_list
= NULL
; //data->tmp_list = hb-glist_clone_list(GLOBALS->cat_list, sizeof(struct _Group));
1566 //da_cat_debug_list();
1569 ui_cat_listview_populate(data
->LV_cat
);
1570 gtk_tree_view_expand_all (GTK_TREE_VIEW(data
->LV_cat
));
1574 // the window creation
1575 GtkWidget
*ui_cat_manage_dialog (void)
1577 struct ui_cat_manage_dialog_data data
;
1578 GtkWidget
*window
, *content
, *mainvbox
, *table
, *hbox
, *label
, *scrollwin
, *vbox
, *separator
, *treeview
;
1581 window
= gtk_dialog_new_with_buttons (_("Manage Categories"),
1582 GTK_WINDOW(GLOBALS
->mainwindow
),
1585 GTK_RESPONSE_ACCEPT
,
1588 data
.window
= window
;
1590 //set the window icon
1591 //homebank_window_set_icon_from_file(GTK_WINDOW (window), "category.svg");
1592 gtk_window_set_icon_name(GTK_WINDOW (window
), HB_STOCK_CATEGORY
);
1594 //store our window private data
1595 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)&data
);
1596 DB( g_print("(defcategory) window=%x, inst_data=%x\n", (guint
)window
, (guint
)&data
) );
1598 g_signal_connect (window
, "destroy",
1599 G_CALLBACK (gtk_widget_destroyed
), &window
);
1602 content
= gtk_dialog_get_content_area(GTK_DIALOG (window
));
1603 mainvbox
= gtk_vbox_new (FALSE
, 0);
1604 gtk_box_pack_start (GTK_BOX (content
), mainvbox
, TRUE
, TRUE
, 0);
1605 gtk_container_set_border_width (GTK_CONTAINER(mainvbox
), HB_MAINBOX_SPACING
);
1608 table
= gtk_table_new (3, 2, FALSE
);
1609 gtk_table_set_row_spacings (GTK_TABLE (table
), HB_TABROW_SPACING
);
1610 gtk_table_set_col_spacings (GTK_TABLE (table
), HB_TABCOL_SPACING
);
1611 gtk_box_pack_start (GTK_BOX (mainvbox
), table
, TRUE
, TRUE
, 0);
1613 // category item + add button
1615 hbox
= gtk_hbox_new (FALSE
, HB_BOX_SPACING
);
1616 gtk_table_attach (GTK_TABLE (table
), hbox
, 0, 1, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
|GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1617 data
.ST_name1
= gtk_entry_new ();
1618 gtk_box_pack_start (GTK_BOX (hbox
), data
.ST_name1
, TRUE
, TRUE
, 0);
1619 data
.CM_type
= gtk_check_button_new_with_mnemonic(_("I_ncome"));
1620 gtk_box_pack_start (GTK_BOX (hbox
), data
.CM_type
, FALSE
, FALSE
, 0);
1622 data
.BT_add1
= gtk_button_new_from_stock(GTK_STOCK_ADD
);
1623 gtk_table_attach (GTK_TABLE (table
), data
.BT_add1
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1625 // subcategory + add button
1627 hbox
= gtk_hbox_new (FALSE
, HB_BOX_SPACING
);
1628 gtk_table_attach (GTK_TABLE (table
), hbox
, 0, 1, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
|GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1629 data
.LA_category
= gtk_label_new(NULL
);
1630 gtk_box_pack_start (GTK_BOX (hbox
), data
.LA_category
, FALSE
, FALSE
, 0);
1631 label
= gtk_label_new(":");
1632 gtk_box_pack_start (GTK_BOX (hbox
), label
, FALSE
, FALSE
, 0);
1633 data
.ST_name2
= gtk_entry_new ();
1634 gtk_box_pack_start (GTK_BOX (hbox
), data
.ST_name2
, TRUE
, TRUE
, 0);
1635 data
.BT_add2
= gtk_button_new_from_stock(GTK_STOCK_ADD
);
1636 gtk_table_attach (GTK_TABLE (table
), data
.BT_add2
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1643 scrollwin
= gtk_scrolled_window_new(NULL
,NULL
);
1644 gtk_table_attach (GTK_TABLE (table
), scrollwin
, 0, 1, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
|GTK_FILL
), (GtkAttachOptions
) (GTK_EXPAND
|GTK_FILL
), 0, 0);
1646 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin
), GTK_SHADOW_ETCHED_IN
);
1647 //gtk_container_set_border_width (GTK_CONTAINER(scrollwin), 5);
1648 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
), GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
1649 treeview
= (GtkWidget
*)ui_cat_listview_new(FALSE
);
1650 gtk_widget_set_size_request(treeview
, HB_MINWIDTH_LIST
, -1);
1651 data
.LV_cat
= treeview
;
1652 gtk_container_add(GTK_CONTAINER(scrollwin
), treeview
);
1654 vbox
= gtk_vbox_new (FALSE
, HB_BOX_SPACING
);
1655 gtk_table_attach (GTK_TABLE (table
), vbox
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (GTK_EXPAND
|GTK_FILL
), 0, 0);
1658 widget = gtk_check_button_new_with_mnemonic("Income type");
1659 data.CM_type = widget;
1660 gtk_box_pack_start (GTK_BOX (vbox), data.CM_type, FALSE, FALSE, 0);
1663 data
.BT_rem
= gtk_button_new_from_stock(GTK_STOCK_REMOVE
);
1664 gtk_box_pack_start (GTK_BOX (vbox
), data
.BT_rem
, FALSE
, FALSE
, 0);
1666 data
.BT_mod
= gtk_button_new_from_stock(GTK_STOCK_EDIT
);
1667 //data.BT_mod = gtk_button_new_with_mnemonic(_("_Modify"));
1668 gtk_box_pack_start (GTK_BOX (vbox
), data
.BT_mod
, FALSE
, FALSE
, 0);
1670 data
.BT_mov
= gtk_button_new_with_mnemonic(_("_Move"));
1671 gtk_box_pack_start (GTK_BOX (vbox
), data
.BT_mov
, FALSE
, FALSE
, 0);
1673 separator
= gtk_hseparator_new();
1674 gtk_box_pack_start (GTK_BOX (vbox
), separator
, FALSE
, FALSE
, HB_BOX_SPACING
);
1677 data
.BT_import
= gtk_button_new_with_mnemonic(_("_Import"));
1678 //data.BT_import = gtk_button_new_from_stock(GTK_STOCK_OPEN);
1679 gtk_box_pack_start (GTK_BOX (vbox
), data
.BT_import
, FALSE
, FALSE
, 0);
1681 data
.BT_export
= gtk_button_new_with_mnemonic(_("E_xport"));
1682 //data.BT_export = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1683 gtk_box_pack_start (GTK_BOX (vbox
), data
.BT_export
, FALSE
, FALSE
, 0);
1685 //connect all our signals
1686 g_signal_connect (G_OBJECT (data
.ST_name1
), "activate", G_CALLBACK (ui_cat_manage_dialog_add
), GINT_TO_POINTER(FALSE
));
1687 g_signal_connect (G_OBJECT (data
.ST_name2
), "activate", G_CALLBACK (ui_cat_manage_dialog_add
), GINT_TO_POINTER(TRUE
));
1689 g_signal_connect(G_OBJECT(data
.ST_name1
), "insert_text", G_CALLBACK(ui_cat_manage_filter_text_handler
), NULL
);
1690 g_signal_connect(G_OBJECT(data
.ST_name2
), "insert_text", G_CALLBACK(ui_cat_manage_filter_text_handler
), NULL
);
1693 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
.LV_cat
)), "changed", G_CALLBACK (ui_cat_manage_dialog_selection
), NULL
);
1694 g_signal_connect (GTK_TREE_VIEW(data
.LV_cat
), "row-activated", G_CALLBACK (ui_cat_manage_dialog_onRowActivated
), NULL
);
1696 g_signal_connect (G_OBJECT (data
.BT_add1
), "clicked", G_CALLBACK (ui_cat_manage_dialog_add
), GINT_TO_POINTER(FALSE
));
1697 g_signal_connect (G_OBJECT (data
.BT_add2
), "clicked", G_CALLBACK (ui_cat_manage_dialog_add
), GINT_TO_POINTER(TRUE
));
1698 g_signal_connect (G_OBJECT (data
.BT_mod
), "clicked", G_CALLBACK (ui_cat_manage_dialog_modify
), NULL
);
1699 g_signal_connect (G_OBJECT (data
.BT_mov
), "clicked", G_CALLBACK (ui_cat_manage_dialog_move
), NULL
);
1700 g_signal_connect (G_OBJECT (data
.BT_rem
), "clicked", G_CALLBACK (ui_cat_manage_dialog_remove
), NULL
);
1702 g_signal_connect (G_OBJECT (data
.BT_import
), "clicked", G_CALLBACK (ui_cat_manage_dialog_load_csv
), NULL
);
1703 g_signal_connect (G_OBJECT (data
.BT_export
), "clicked", G_CALLBACK (ui_cat_manage_dialog_save_csv
), NULL
);
1705 //setup, init and show window
1706 ui_cat_manage_dialog_setup(&data
);
1707 ui_cat_manage_dialog_update(data
.LV_cat
, NULL
);
1709 gtk_window_resize(GTK_WINDOW(window
), 200, 320);
1712 gtk_widget_show_all (window
);
1715 gint result
= gtk_dialog_run (GTK_DIALOG (window
));
1719 case GTK_RESPONSE_ACCEPT
:
1720 //do_application_specific_something ();
1723 //do_nothing_since_dialog_was_cancelled ();
1727 // cleanup and destroy
1728 ui_cat_manage_dialog_cleanup(&data
, result
);
1729 gtk_widget_destroy (window
);