/* HomeBank -- Free, easy, personal accounting for everyone.
- * Copyright (C) 1995-2014 Maxime DOYEN
+ * Copyright (C) 1995-2016 Maxime DOYEN
*
* This file is part of HomeBank.
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+
#include "homebank.h"
#include "ui-category.h"
/* our global datas */
extern struct HomeBank *GLOBALS;
+extern struct Preferences *PREFS;
+
+
+gchar *CYA_CAT_TYPE[] = {
+ N_("Expense"),
+ N_("Income"),
+ NULL
+};
+
+static void ui_cat_manage_populate_listview(struct ui_cat_manage_dialog_data *data);
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
return -1;
}
+
+Category
+*ui_cat_comboboxentry_get(GtkComboBox *entry_box)
+{
+Category *item = NULL;
+gchar *name;
+
+ DB( g_print ("ui_cat_comboboxentry_get_key()\n") );
+
+ name = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
+ if(name == NULL)
+ return NULL;
+
+ item = da_cat_get_by_fullname(name);
+
+ return item;
+}
+
+
gboolean
ui_cat_comboboxentry_set_active(GtkComboBox *entry_box, guint32 key)
{
gtk_list_store_append (GTK_LIST_STORE(model), &iter);
gtk_list_store_set (GTK_LIST_STORE(model), &iter,
- 0, fullname,
- 1, name,
+ LST_CMBCAT_DATAS, item,
+ LST_CMBCAT_FULLNAME, fullname,
+ LST_CMBCAT_SORTNAME, NULL,
+ LST_CMBCAT_NAME, name,
+ LST_CMBCAT_SUBCAT, item->parent == 0 ? 1 : 0,
-1);
g_free(fullname);
{
GtkTreeIter iter;
Category *item = value;
-gchar *fullname, *name;
+Category *pitem = NULL;
+gchar *fullname, *name, *sortname;
gchar type;
if( ( item->key != ctx->except_key ) )
{
- type = (item->flags & GF_INCOME) ? '+' : '-';
+ pitem = da_cat_get(item->parent);
+ type = (item->flags & GF_INCOME) ? '+' : '-';
fullname = da_cat_get_fullname(item);
-
+ sortname = NULL;
+ name = NULL;
+
//DB( g_print ("cat combo populate [%d:%d] %s\n", item->parent, item->key, fullname) );
if(item->key == 0)
+ {
name = g_strdup(item->name);
+ sortname = g_strdup(item->name);
+ }
else
{
if( item->parent == 0 )
+ {
name = g_strdup_printf("%s [%c]", item->name, type);
+ sortname = g_strdup_printf("%s", item->name);
+ }
else
- name = g_strdup_printf(" %c %s", type, item->name);
+ {
+ if(pitem)
+ {
+ name = g_strdup_printf(" %c %s", type, item->name);
+ sortname = g_strdup_printf("%s_%s", pitem->name, item->name);
+ }
+ }
}
- gtk_list_store_append (GTK_LIST_STORE(ctx->model), &iter);
- gtk_list_store_set (GTK_LIST_STORE(ctx->model), &iter,
- 0, fullname,
- 1, name,
- 2, item->parent == 0 ? 1 : 0,
+ hb_string_replace_char(' ', sortname);
+
+ //gtk_list_store_append (GTK_LIST_STORE(ctx->model), &iter);
+ //gtk_list_store_set (GTK_LIST_STORE(ctx->model), &iter,
+ gtk_list_store_insert_with_values(GTK_LIST_STORE(ctx->model), &iter, -1,
+ LST_CMBCAT_DATAS, item,
+ LST_CMBCAT_FULLNAME, fullname,
+ LST_CMBCAT_SORTNAME, sortname,
+ LST_CMBCAT_NAME, name,
+ LST_CMBCAT_SUBCAT, item->parent == 0 ? 1 : 0,
-1);
+ DB( g_print(" - add [%2d:%2d] '%-12s' '%-12s' '%s' '%s' %d\n", item->parent, item->key, pitem->name, name, fullname, sortname, item->parent == 0 ? 1 : 0) );
+
+ g_free(sortname);
g_free(fullname);
g_free(name);
}
ui_cat_comboboxentry_populate_except(GtkComboBox *entry_box, GHashTable *hash, guint except_key)
{
GtkTreeModel *model;
-GtkEntryCompletion *completion;
+//GtkEntryCompletion *completion;
struct catPopContext ctx;
DB( g_print ("ui_cat_comboboxentry_populate()\n") );
model = gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box));
- completion = gtk_entry_get_completion(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
+ //completion = gtk_entry_get_completion(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
/* keep our model alive and detach from comboboxentry and completion */
- g_object_ref(model);
- gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), NULL);
- gtk_entry_completion_set_model (completion, NULL);
+ //g_object_ref(model);
+ //gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), NULL);
+ //gtk_entry_completion_set_model (completion, NULL);
/* clear and populate */
+
ctx.model = model;
ctx.except_key = except_key;
-
gtk_list_store_clear (GTK_LIST_STORE(model));
+
+ //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GTK_LIST_STORE(model)), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
+
g_hash_table_foreach(hash, (GHFunc)ui_cat_comboboxentry_populate_ghfunc, &ctx);
/* reatach our model */
- gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), model);
- gtk_entry_completion_set_model (completion, model);
- g_object_unref(model);
+ //gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), model);
+ //gtk_entry_completion_set_model (completion, model);
+ //g_object_unref(model);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
gint retval = 0;
gchar *name1, *name2;
- gtk_tree_model_get(model, a, 0, &name1, -1);
- gtk_tree_model_get(model, b, 0, &name2, -1);
+ gtk_tree_model_get(model, a,
+ LST_CMBCAT_SORTNAME, &name1,
+ -1);
+ gtk_tree_model_get(model, b,
+ LST_CMBCAT_SORTNAME, &name2,
+ -1);
+
+ //DB( g_print(" compare '%s' '%s'\n", name1, name2) );
retval = hb_string_utf8_compare(name1, name2);
-/*
- retval = (entry1->flags & GF_INCOME) - (entry2->flags & GF_INCOME);
- if(!retval)
- {
- retval = hb_string_utf8_compare(entry1->name, entry2->name);
- }
-*/
+
g_free(name2);
g_free(name1);
return retval;
- }
-
+}
static void
//PANGO_STYLE_ITALIC
gtk_tree_model_get(tree_model, iter,
- 1, &name,
- 2, &subcat,
+ LST_CMBCAT_NAME, &name,
+ LST_CMBCAT_SUBCAT, &subcat,
-1);
style = subcat == 0 ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL;
model = gtk_entry_completion_get_model (completion);
gtk_tree_model_get (model, iter,
- 0, &item,
+ LST_CMBCAT_FULLNAME, &item,
-1);
if (item != NULL)
DB( g_print ("ui_cat_comboboxentry_new()\n") );
-
- store = gtk_list_store_new (3,
+ store = gtk_list_store_new (NUM_LST_CMBCAT,
+ G_TYPE_POINTER,
G_TYPE_STRING, //fullname Car:Fuel
+ G_TYPE_STRING, //parent name Car
G_TYPE_STRING, //name Car or Fuel
G_TYPE_BOOLEAN //subcat = 1
);
completion = gtk_entry_completion_new ();
gtk_entry_completion_set_model (completion, GTK_TREE_MODEL(store));
- g_object_set(completion, "text-column", 0, NULL);
+ //g_object_set(completion, "text-column", LST_CMBCAT_FULLNAME, NULL);
gtk_entry_completion_set_match_func(completion, ui_cat_comboboxentry_completion_func, NULL, NULL);
- gtk_entry_completion_set_minimum_key_length(completion, 2);
+ //gtk_entry_completion_set_minimum_key_length(completion, 2);
- renderer = gtk_cell_renderer_text_new ();
+ gtk_entry_completion_set_text_column(completion, 1);
+
+ /*renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), renderer, "text", 0, NULL);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), renderer, "text", LST_CMBCAT_FULLNAME, NULL);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion),
renderer,
ui_cat_comboboxentry_test,
NULL, NULL);
+ */
// dothe same for combobox
comboboxentry = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store));
- gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboboxentry), 0);
-
+ gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboboxentry), LST_CMBCAT_FULLNAME);
gtk_cell_layout_clear(GTK_CELL_LAYOUT (comboboxentry));
renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comboboxentry), renderer, TRUE);
- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comboboxentry), renderer, "text", 0, NULL);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comboboxentry), renderer, "text", LST_CMBCAT_FULLNAME, NULL);
gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (comboboxentry),
renderer,
ui_cat_comboboxentry_test,
NULL, NULL);
-
-
gtk_entry_set_completion (GTK_ENTRY (gtk_bin_get_child(GTK_BIN (comboboxentry))), completion);
g_object_unref(store);
if(label)
gtk_label_set_mnemonic_widget (GTK_LABEL(label), comboboxentry);
- gtk_widget_set_size_request(comboboxentry, HB_MINWIDTH_COMBO, -1);
+ gtk_widget_set_size_request(comboboxentry, HB_MINWIDTH_LIST, -1);
return comboboxentry;
}
gtk_tree_path_free (path);
}
-/*
-**
-** The function should return:
-** a negative integer if the first value comes before the second,
-** 0 if they are equal,
-** or a positive integer if the first value comes after the second.
-*/
static gint
ui_cat_listview_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
{
-gint retval = 0;
+gint sortcol = GPOINTER_TO_INT(userdata);
Category *entry1, *entry2;
-
+gint retval = 0;
+
gtk_tree_model_get(model, a, LST_DEFCAT_DATAS, &entry1, -1);
gtk_tree_model_get(model, b, LST_DEFCAT_DATAS, &entry2, -1);
- retval = (entry1->flags & GF_INCOME) - (entry2->flags & GF_INCOME);
- if(!retval)
- {
- retval = hb_string_utf8_compare(entry1->name, entry2->name);
+ switch (sortcol)
+ {
+ case LST_DEFCAT_SORT_NAME:
+ retval = (entry1->flags & GF_INCOME) - (entry2->flags & GF_INCOME);
+ if(!retval)
+ {
+ retval = hb_string_utf8_compare(entry1->name, entry2->name);
+ }
+ break;
+ case LST_DEFCAT_SORT_USED:
+ retval = entry1->usage_count - entry2->usage_count;
+ break;
+ default:
+ g_return_val_if_reached(0);
}
return retval;
}
}
+static void
+ui_cat_listview_count_cell_data_function (GtkTreeViewColumn *col,
+ GtkCellRenderer *renderer,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+Category *entry;
+gchar buffer[256];
+
+ gtk_tree_model_get(model, iter, LST_DEFCAT_DATAS, &entry, -1);
+ if(entry->usage_count > 0)
+ {
+ g_snprintf(buffer, 256-1, "%d", entry->usage_count);
+ g_object_set(renderer, "text", buffer, NULL);
+ }
+ else
+ g_object_set(renderer, "text", "", NULL);
+}
+
+
+/* = = = = = = = = = = = = = = = = */
void
}
-static void ui_cat_listview_populate_cat_ghfunc(gpointer key, gpointer value, GtkTreeModel *model)
+static void ui_cat_listview_populate_cat_ghfunc(gpointer key, gpointer value, struct catPopContext *ctx)
{
GtkTreeIter toplevel;
Category *item = value;
+gint item_type;
- //DB( g_print("cat listview populate: %d %s\n", (guint32 *)key, item->name) );
+ item_type = (item->flags & GF_INCOME) ? CAT_TYPE_INCOME : CAT_TYPE_EXPENSE;
- if( item->parent == 0 )
+ //DB( g_print("cat listview populate: %d %s\n", (guint32 *)key, item->name) );
+ if( (ctx->type == CAT_TYPE_ALL) || ctx->type == item_type || item->key == 0 )
{
- gtk_tree_store_append (GTK_TREE_STORE(model), &toplevel, NULL);
+ if( item->parent == 0 )
+ {
+ gtk_tree_store_append (GTK_TREE_STORE(ctx->model), &toplevel, NULL);
- gtk_tree_store_set (GTK_TREE_STORE(model), &toplevel,
- LST_DEFCAT_TOGGLE , FALSE,
- LST_DEFCAT_DATAS, item,
- LST_DEFCAT_NAME, item->name,
- -1);
+ gtk_tree_store_set (GTK_TREE_STORE(ctx->model), &toplevel,
+ LST_DEFCAT_TOGGLE , FALSE,
+ LST_DEFCAT_DATAS, item,
+ LST_DEFCAT_NAME, item->name,
+ -1);
+ }
}
+
}
-static void ui_cat_listview_populate_subcat_ghfunc(gpointer key, gpointer value, GtkTreeModel *model)
+static void ui_cat_listview_populate_subcat_ghfunc(gpointer key, gpointer value, struct catPopContext *ctx)
{
GtkTreeIter toplevel, child;
Category *item = value;
gboolean ret;
+gint item_type;
+ item_type = (item->flags & GF_INCOME) ? CAT_TYPE_INCOME : CAT_TYPE_EXPENSE;
- if( item->parent != 0 )
+ if( (ctx->type == CAT_TYPE_ALL) || ctx->type == item_type)
{
- ret = ui_cat_listview_get_top_level(model, item->parent, &toplevel);
- if( ret == TRUE )
+ if( item->parent != 0 )
{
- gtk_tree_store_append (GTK_TREE_STORE(model), &child, &toplevel);
-
- gtk_tree_store_set (GTK_TREE_STORE(model), &child,
- LST_DEFCAT_TOGGLE , FALSE,
- LST_DEFCAT_DATAS, item,
- LST_DEFCAT_NAME, item->name,
- -1);
+ ret = ui_cat_listview_get_top_level(ctx->model, item->parent, &toplevel);
+ if( ret == TRUE )
+ {
+ gtk_tree_store_append (GTK_TREE_STORE(ctx->model), &child, &toplevel);
+ gtk_tree_store_set (GTK_TREE_STORE(ctx->model), &child,
+ LST_DEFCAT_TOGGLE , FALSE,
+ LST_DEFCAT_DATAS, item,
+ LST_DEFCAT_NAME, item->name,
+ -1);
+ }
}
}
}
-
-
-void ui_cat_listview_populate(GtkWidget *view)
+void ui_cat_listview_populate(GtkWidget *view, gint type)
{
GtkTreeModel *model;
+struct catPopContext ctx = { 0 };
DB( g_print("ui_cat_listview_populate() \n") );
g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); /* Detach model from view */
+ /* clear and populate */
+ ctx.model = model;
+ ctx.type = type;
+
/* we have to do this in 2 times to ensure toplevel (cat) will be added before childs */
/* populate cat 1st */
- g_hash_table_foreach(GLOBALS->h_cat, (GHFunc)ui_cat_listview_populate_cat_ghfunc, model);
- g_hash_table_foreach(GLOBALS->h_cat, (GHFunc)ui_cat_listview_populate_subcat_ghfunc, model);
+ g_hash_table_foreach(GLOBALS->h_cat, (GHFunc)ui_cat_listview_populate_cat_ghfunc, &ctx);
+ g_hash_table_foreach(GLOBALS->h_cat, (GHFunc)ui_cat_listview_populate_subcat_ghfunc, &ctx);
gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); /* Re-attach model to view */
}
+static gboolean ui_cat_listview_search_equal_func (GtkTreeModel *model,
+ gint column,
+ const gchar *key,
+ GtkTreeIter *iter,
+ gpointer search_data)
+{
+ gboolean retval = TRUE;
+ gchar *normalized_string;
+ gchar *normalized_key;
+ gchar *case_normalized_string = NULL;
+ gchar *case_normalized_key = NULL;
+ Category *item;
+
+ //gtk_tree_model_get_value (model, iter, column, &value);
+ gtk_tree_model_get(model, iter, LST_DEFCAT_DATAS, &item, -1);
+
+ if(item != NULL)
+ {
+ normalized_string = g_utf8_normalize (item->name, -1, G_NORMALIZE_ALL);
+ normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
+
+ if (normalized_string && normalized_key)
+ {
+ case_normalized_string = g_utf8_casefold (normalized_string, -1);
+ case_normalized_key = g_utf8_casefold (normalized_key, -1);
+
+ if (strncmp (case_normalized_key, case_normalized_string, strlen (case_normalized_key)) == 0)
+ retval = FALSE;
+ }
+
+ g_free (normalized_key);
+ g_free (normalized_string);
+ g_free (case_normalized_key);
+ g_free (case_normalized_string);
+ }
+ return retval;
+}
+
+
GtkWidget *
-ui_cat_listview_new(gboolean withtoggle)
+ui_cat_listview_new(gboolean withtoggle, gboolean withcount)
{
GtkTreeStore *store;
GtkWidget *treeview;
DB( g_print("ui_cat_listview_new() \n") );
- /* create tree store */
store = gtk_tree_store_new(
NUM_LST_DEFCAT,
G_TYPE_BOOLEAN,
G_TYPE_STRING
);
- //treeview
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
g_object_unref(store);
+ gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines);
+
// column 1: toggle
if( withtoggle == TRUE )
{
renderer = gtk_cell_renderer_toggle_new ();
- column = gtk_tree_view_column_new_with_attributes ("Show", renderer, "active", LST_DEFCAT_TOGGLE, NULL);
+ column = gtk_tree_view_column_new_with_attributes (_("Visible"),
+ renderer, "active", LST_DEFCAT_TOGGLE, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
g_signal_connect (G_OBJECT(renderer), "toggled",
}
- // column 1
- column = gtk_tree_view_column_new();
+ // column 2: name
renderer = gtk_cell_renderer_text_new ();
+ g_object_set(renderer,
+ "ellipsize", PANGO_ELLIPSIZE_END,
+ "ellipsize-set", TRUE,
+ NULL);
+
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_title(column, _("Name"));
gtk_tree_view_column_pack_start(column, renderer, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cat_listview_text_cell_data_function, GINT_TO_POINTER(LST_DEFCAT_NAME), NULL);
- //gtk_tree_view_column_set_sort_column_id (column, LST_DEFACC_NAME);
+ gtk_tree_view_column_set_alignment (column, 0.5);
+ gtk_tree_view_column_set_min_width(column, HB_MINWIDTH_LIST);
+ gtk_tree_view_column_set_sort_column_id (column, LST_DEFCAT_SORT_NAME);
+ gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
+ if( withcount == TRUE )
+ {
+ column = gtk_tree_view_column_new();
+ gtk_tree_view_column_set_title(column, _("Usage"));
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set(renderer, "xalign", 0.5, NULL);
+ gtk_tree_view_column_pack_start(column, renderer, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cat_listview_count_cell_data_function, GINT_TO_POINTER(LST_DEFCAT_DATAS), NULL);
+ gtk_tree_view_column_set_alignment (column, 0.5);
+ gtk_tree_view_column_set_sort_column_id (column, LST_DEFCAT_SORT_USED);
+ gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
+ }
- // parameters
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), FALSE);
+
+ gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview), ui_cat_listview_search_equal_func, NULL, NULL);
- gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFCAT_DATAS, ui_cat_listview_compare_func, NULL, NULL);
- gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), LST_DEFCAT_DATAS, GTK_SORT_ASCENDING);
+ // treeview attribute
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), withcount);
- //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
- //gtk_tree_view_set_expander_column(GTK_TREE_VIEW(treeview), column);
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFCAT_SORT_NAME, ui_cat_listview_compare_func, GINT_TO_POINTER(LST_DEFCAT_SORT_NAME), NULL);
+ gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFCAT_SORT_USED, ui_cat_listview_compare_func, GINT_TO_POINTER(LST_DEFCAT_SORT_USED), NULL);
+
+ gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), LST_DEFCAT_SORT_NAME, GTK_SORT_ASCENDING);
return treeview;
}
-/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
-
-//todo amiga/linux
-//add exist function + check before add
-//save
-//load
-
+/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/**
* ui_cat_manage_filter_text_handler
gpointer data)
{
GtkEditable *editable = GTK_EDITABLE(entry);
-gint i, count=0, pos;
+gint i, count=0;
gchar *result = g_new0 (gchar, length+1);
for (i=0; i < length; i++)
g_signal_handlers_block_by_func (G_OBJECT (editable),
G_CALLBACK (ui_cat_manage_filter_text_handler),
data);
- gtk_editable_insert_text (editable, result, count, &pos);
+ gtk_editable_insert_text (editable, result, count, position);
g_signal_handlers_unblock_by_func (G_OBJECT (editable),
G_CALLBACK (ui_cat_manage_filter_text_handler),
data);
}
+static void
+ui_cat_manage_dialog_delete_unused( GtkWidget *widget, gpointer user_data)
+{
+struct ui_cat_manage_dialog_data *data = user_data;
+gboolean result;
+
+ //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
+
+ DB( g_print("(ui_cat_manage_dialog) delete unused - data %p\n", data) );
+
+ result = ui_dialog_msg_confirm_alert(
+ GTK_WINDOW(data->window),
+ _("Delete unused categories"),
+ _("Are you sure you want to permanently\ndelete unused categories?"),
+ _("_Delete")
+ );
+
+ if( result == GTK_RESPONSE_OK )
+ {
+ GtkTreeModel *model;
+
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_cat));
+ gtk_tree_store_clear (GTK_TREE_STORE(model));
+
+ category_delete_unused();
+
+ ui_cat_manage_populate_listview (data);
+ }
+}
+
/**
static void
ui_cat_manage_dialog_load_csv( GtkWidget *widget, gpointer user_data)
{
-struct ui_cat_manage_dialog_data *data;
+struct ui_cat_manage_dialog_data *data = user_data;
gchar *filename = NULL;
gchar *error;
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
+ //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
DB( g_print("(ui_cat_manage_dialog) load csv - data %p\n", data) );
{
ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
_("File format error"),
- _("The csv file must contains the exact numbers of column,\nseparated by a semi-colon, please see the help for more details.")
+ _("The CSV file must contains the exact numbers of column,\nseparated by a semi-colon, please see the help for more details.")
);
}
g_free( filename );
- ui_cat_listview_populate(data->LV_cat);
+ ui_cat_manage_populate_listview(data);
}
}
static void
ui_cat_manage_dialog_save_csv( GtkWidget *widget, gpointer user_data)
{
-struct ui_cat_manage_dialog_data *data;
+struct ui_cat_manage_dialog_data *data = user_data;
gchar *filename = NULL;
gchar *error;
DB( g_print("(defcategory) save csv\n") );
- data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+ //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, NULL) == TRUE )
{
GtkTreeIter parent_iter;
GtkWidget *tmpwidget;
Category *item, *paritem;
-gboolean type;
+gint type;
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
DB( g_print("\n(defcategory) add (data=%p) is subcat=%d\n", data, subcat) );
/* if cat use new id */
if(subcat == FALSE)
{
- type = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_type));
- if(type == TRUE)
+ type = radio_get_active(GTK_CONTAINER(data->RA_type));
+ if(type == 1)
item->flags |= GF_INCOME;
if( da_cat_append(item) )
}
-static void ui_cat_manage_dialog_modify_entry_cb(GtkEditable *editable, gpointer user_data)
+static void ui_cat_manage_dialog_edit_entry_cb(GtkEditable *editable, gpointer user_data)
{
GtkDialog *window = user_data;
const gchar *buffer;
}
-/*
-**
-*/
-static void
-ui_cat_manage_dialog_modify(GtkWidget *widget, gpointer user_data)
+static void ui_cat_manage_dialog_edit(GtkWidget *widget, gpointer user_data)
{
struct ui_cat_manage_dialog_data *data;
-GtkWidget *window, *content, *mainvbox, *w_name, *w_type = NULL;
+GtkWidget *dialog, *content, *mainvbox, *w_name, *w_type = NULL;
GtkTreeSelection *selection;
GtkTreeModel *model;
GtkTreeIter iter;
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
- DB( g_print("\n(defcategory) modify\n") );
+ DB( g_print("\n(defcategory) edit\n") );
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_cat));
//if true there is a selected node
gtk_tree_model_get(model, &iter, LST_DEFCAT_DATAS, &item, -1);
- window = gtk_dialog_new_with_buttons (_("Modify..."),
+ dialog = gtk_dialog_new_with_buttons (_("Edit..."),
GTK_WINDOW (data->window),
0,
- GTK_STOCK_CANCEL,
+ _("_Cancel"),
GTK_RESPONSE_REJECT,
- GTK_STOCK_OK,
+ _("_OK"),
GTK_RESPONSE_ACCEPT,
NULL);
- content = gtk_dialog_get_content_area(GTK_DIALOG (window));
- mainvbox = gtk_vbox_new (FALSE, 0);
+ content = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
+ mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (mainvbox), HB_MAINBOX_SPACING);
+ gtk_container_set_border_width (GTK_CONTAINER (mainvbox), SPACING_MEDIUM);
w_name = gtk_entry_new();
gtk_box_pack_start (GTK_BOX (mainvbox), w_name, TRUE, TRUE, 0);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w_type), item->flags & GF_INCOME ? TRUE : FALSE);
}
+ g_signal_connect (G_OBJECT (w_name), "changed", G_CALLBACK (ui_cat_manage_dialog_edit_entry_cb), dialog);
+
+
gtk_widget_show_all(mainvbox);
- g_signal_connect (G_OBJECT (w_name), "changed", G_CALLBACK (ui_cat_manage_dialog_modify_entry_cb), window);
-
- gtk_dialog_set_default_response(GTK_DIALOG( window ), GTK_RESPONSE_ACCEPT);
+ gtk_dialog_set_default_response(GTK_DIALOG( dialog ), GTK_RESPONSE_ACCEPT);
//wait for the user
- gint result = gtk_dialog_run (GTK_DIALOG (window));
+ gint result = gtk_dialog_run (GTK_DIALOG (dialog));
if(result == GTK_RESPONSE_ACCEPT)
{
{
if( category_rename(item, name) )
{
+ //to redraw the active entry
+ gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_cat));
data->change++;
}
else
}
- ui_dialog_msg_infoerror(GTK_WINDOW(window), GTK_MESSAGE_ERROR,
+ ui_dialog_msg_infoerror(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
_("Error"),
_("Cannot rename this Category,\n"
"from '%s' to '%s',\n"
}
// cleanup and destroy
- gtk_widget_destroy (window);
+ gtk_widget_destroy (dialog);
}
}
-static void ui_cat_manage_dialog_move_entry_cb(GtkComboBox *widget, gpointer user_data)
+static void ui_cat_manage_dialog_merge_entry_cb(GtkComboBox *widget, gpointer user_data)
{
GtkDialog *window = user_data;
gchar *buffer;
buffer = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (widget))));
- gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT, strlen(buffer) > 0 ? TRUE : FALSE);
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_OK, strlen(buffer) > 0 ? TRUE : FALSE);
}
-/*
-**
-*/
-static void ui_cat_manage_dialog_move(GtkWidget *widget, gpointer user_data)
+static void ui_cat_manage_dialog_merge(GtkWidget *widget, gpointer user_data)
{
struct ui_cat_manage_dialog_data *data;
-GtkWidget *window, *content, *mainvbox, *getwidget;
+GtkWidget *dialog, *content, *mainvbox;
+GtkWidget *getwidget, *togglebutton;
GtkTreeSelection *selection;
-GtkTreeModel *model;
-GtkTreeIter iter;
+GtkTreeModel *model;
+GtkTreeIter iter;
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
- DB( g_print("(defcategory) move\n") );
+ DB( g_print("(defcategory) merge\n") );
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_cat));
//if true there is a selected node
if (gtk_tree_selection_get_selected(selection, &model, &iter))
{
- Category *item;
+ Category *srccat;
+ gchar *title;
+ gchar *secondtext;
- gtk_tree_model_get(model, &iter, LST_DEFCAT_DATAS, &item, -1);
+ gtk_tree_model_get(model, &iter, LST_DEFCAT_DATAS, &srccat, -1);
- window = gtk_dialog_new_with_buttons (_("Move to..."),
- GTK_WINDOW (data->window),
- 0,
- GTK_STOCK_CANCEL,
- GTK_RESPONSE_REJECT,
- GTK_STOCK_OK,
- GTK_RESPONSE_ACCEPT,
- NULL);
+ title = g_strdup_printf (
+ _("Merge category '%s'"), srccat->name);
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (data->window),
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ title,
+ NULL
+ );
+
+ gtk_dialog_add_buttons (GTK_DIALOG(dialog),
+ _("_Cancel"), GTK_RESPONSE_CANCEL,
+ _("Merge"), GTK_RESPONSE_OK,
+ NULL);
+
+ gtk_dialog_set_default_response(GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
- content = gtk_dialog_get_content_area(GTK_DIALOG (window));
- mainvbox = gtk_vbox_new (FALSE, 0);
+ content = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG (dialog));
+ mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (mainvbox), HB_BOX_SPACING);
+
+ secondtext = _("Transactions assigned to this category,\n"
+ "will be moved to the category selected below.");
+
+ g_object_set(GTK_MESSAGE_DIALOG (dialog), "secondary-text", secondtext, NULL);
+ g_free(title);
getwidget = ui_cat_comboboxentry_new(NULL);
- gtk_box_pack_start (GTK_BOX (mainvbox), getwidget, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (mainvbox), getwidget, FALSE, FALSE, 0);
- gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT, FALSE);
-
- gtk_widget_show_all(mainvbox);
+ secondtext = g_strdup_printf (
+ _("_Delete the category '%s'"), srccat->name);
+ togglebutton = gtk_check_button_new_with_mnemonic(secondtext);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton), TRUE);
+ g_free(secondtext);
+ gtk_box_pack_start (GTK_BOX (mainvbox), togglebutton, FALSE, FALSE, 0);
- g_signal_connect (G_OBJECT (getwidget), "changed", G_CALLBACK (ui_cat_manage_dialog_move_entry_cb), window);
-
- ui_cat_comboboxentry_populate_except(GTK_COMBO_BOX(getwidget), GLOBALS->h_cat, item->key);
+ //setup
+ //gtk_combo_box_set_active(GTK_COMBO_BOX(getwidget), oldpos);
+ g_signal_connect (G_OBJECT (getwidget), "changed", G_CALLBACK (ui_cat_manage_dialog_merge_entry_cb), dialog);
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK, FALSE);
+
+ ui_cat_comboboxentry_populate_except(GTK_COMBO_BOX(getwidget), GLOBALS->h_cat, srccat->key);
gtk_widget_grab_focus (getwidget);
+ gtk_widget_show_all(mainvbox);
+
//wait for the user
- gint result = gtk_dialog_run (GTK_DIALOG (window));
+ gint result = gtk_dialog_run (GTK_DIALOG (dialog));
- if(result == GTK_RESPONSE_ACCEPT)
+ if(result == GTK_RESPONSE_OK)
{
- gboolean result;
- gchar *npn;
-
- npn = ui_cat_comboboxentry_get_name(GTK_COMBO_BOX(getwidget)),
-
- result = ui_dialog_msg_question(
- GTK_WINDOW(window),
- _("Move this category to another one ?"),
- _("This will replace '%s' by '%s',\n"
- "and then remove '%s'"),
- item->name,
- npn,
- item->name,
- NULL
- );
-
- if( result == GTK_RESPONSE_YES )
- {
- Category *newcat, *parent;
- guint dstkey;
+ GtkTreeModel *model;
+ Category *newcat, *parent;
+ guint dstcatkey;
- dstkey = ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(getwidget));
- newcat = da_cat_get (dstkey);
- DB( g_print(" moving to %d\n", dstkey) );
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_cat));
+ gtk_tree_store_clear (GTK_TREE_STORE(model));
- category_move(item->key, dstkey);
+ dstcatkey = ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(getwidget));
- //keep the income with us
- parent = da_cat_get(item->parent);
- if(parent != NULL && (parent->flags & GF_INCOME))
- newcat->flags |= GF_INCOME;
+ DB( g_print(" -> move cat to %d\n", dstcatkey) );
- // remove the old category
- da_cat_remove(item->key);
- ui_cat_listview_remove_selected(GTK_TREE_VIEW(data->LV_cat));
+ category_move(srccat->key, dstcatkey);
+
+ newcat = da_cat_get (dstcatkey);
+
+ //keep the income type with us
+ parent = da_cat_get(srccat->parent);
+ if(parent != NULL && (parent->flags & GF_INCOME))
+ newcat->flags |= GF_INCOME;
- //add the new category into listview
- if(newcat)
- ui_cat_listview_add(GTK_TREE_VIEW(data->LV_cat), newcat, NULL);
+ //add the new category into listview
+ if(newcat)
+ ui_cat_listview_add(GTK_TREE_VIEW(data->LV_cat), newcat, NULL);
- data->change++;
+ // delete the old category
+ if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)) )
+ {
+ DB( g_print(" -> delete %d '%s'\n", srccat->key, srccat->name ) );
+
+ da_cat_remove(srccat->key);
+ ui_cat_listview_remove_selected(GTK_TREE_VIEW(data->LV_cat));
}
- }
+
+
+ data->change++;
+
+ ui_cat_manage_populate_listview(data);
+
+ }
// cleanup and destroy
- gtk_widget_destroy (window);
+ gtk_widget_destroy (dialog);
}
}
/*
-** remove the selected payee to our treeview and temp GList
+** delete the selected payee to our treeview and temp GList
*/
-static void ui_cat_manage_dialog_remove(GtkWidget *widget, gpointer user_data)
+static void ui_cat_manage_dialog_delete(GtkWidget *widget, gpointer user_data)
{
struct ui_cat_manage_dialog_data *data;
Category *item;
gint result;
-gboolean do_remove;
data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
- DB( g_print("\n(defcategory) remove (data=%x)\n", (guint)data) );
+ DB( g_print("\n(defcategory) delete (data=%x)\n", (guint)data) );
- do_remove = TRUE;
item = ui_cat_listview_get_selected(GTK_TREE_VIEW(data->LV_cat));
if( item != NULL )
{
- if( category_is_used(item->key) == TRUE )
+ gchar *title = NULL;
+ gchar *secondtext = NULL;
+
+ title = g_strdup_printf (
+ _("Are you sure you want to permanently delete '%s'?"), item->name);
+
+ if( item->usage_count > 0 )
{
- result = ui_dialog_msg_question(
- GTK_WINDOW(data->window),
- _("Remove a category ?"),
- _("If you remove '%s', archive and transaction referencing this category\n"
- "will set place to 'no category'"),
- item->name,
- NULL
- );
-
- if( result == GTK_RESPONSE_YES )
- {
- category_move(item->key, 0);
- }
- else if( result == GTK_RESPONSE_NO )
- {
- do_remove = FALSE;
- }
+ secondtext = _("This category is used.\n"
+ "Any transaction using that category will be set to (no category)");
}
- if( do_remove )
+ result = ui_dialog_msg_confirm_alert(
+ GTK_WINDOW(data->window),
+ title,
+ secondtext,
+ _("_Delete")
+ );
+
+ g_free(title);
+
+ if( result == GTK_RESPONSE_OK )
{
+ category_move(item->key, 0);
ui_cat_listview_remove(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_cat)), item->key);
da_cat_remove(item->key);
data->change++;
}
+
}
+}
+
+
+
+static void ui_cat_manage_dialog_expand_all(GtkWidget *widget, gpointer user_data)
+{
+struct ui_cat_manage_dialog_data *data;
+
+ data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+ DB( g_print("\n(defcategory) expand all (data=%x)\n", (guint)data) );
+
+ gtk_tree_view_expand_all(GTK_TREE_VIEW(data->LV_cat));
}
-/**
- * ui_cat_manage_dialog_update:
- *
- */
-static void
-ui_cat_manage_dialog_update(GtkWidget *treeview, gpointer user_data)
+static void ui_cat_manage_dialog_collapse_all(GtkWidget *widget, gpointer user_data)
+{
+struct ui_cat_manage_dialog_data *data;
+
+ data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
+ DB( g_print("\n(defcategory) collapse all (data=%x)\n", (guint)data) );
+
+ gtk_tree_view_collapse_all(GTK_TREE_VIEW(data->LV_cat));
+
+}
+
+
+static void ui_cat_manage_dialog_update(GtkWidget *treeview, gpointer user_data)
{
struct ui_cat_manage_dialog_data *data;
//gint count;
LST_DEFCAT_DATAS, &tmpitem,
-1);
- category = tmpitem->name;
-
+ if(tmpitem->key > 0)
+ category = tmpitem->name;
DB( g_print(" => parent is %s\n", category) );
sensitive = (selected == TRUE) ? TRUE : FALSE;
gtk_widget_set_sensitive(data->ST_name2, sensitive);
- gtk_widget_set_sensitive(data->BT_add2, sensitive);
- gtk_widget_set_sensitive(data->BT_mov, sensitive);
- gtk_widget_set_sensitive(data->BT_mod, sensitive);
+ gtk_widget_set_sensitive(data->BT_edit, sensitive);
+ gtk_widget_set_sensitive(data->BT_merge, sensitive);
//avoid removing top categories
sensitive = (haschild == TRUE) ? FALSE : sensitive;
- gtk_widget_set_sensitive(data->BT_rem, sensitive);
+ gtk_widget_set_sensitive(data->BT_delete, sensitive);
}
gtk_tree_model_get_iter_first(model, &iter);
if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter) == FALSE)
{
- ui_cat_manage_dialog_modify(GTK_WIDGET(treeview), NULL);
+ ui_cat_manage_dialog_edit(GTK_WIDGET(treeview), NULL);
}
}
-
-
-/*
-**
-*/
static gboolean ui_cat_manage_dialog_cleanup(struct ui_cat_manage_dialog_data *data, gint result)
{
gboolean doupdate = FALSE;
return doupdate;
}
+
+static void ui_cat_manage_populate_listview(struct ui_cat_manage_dialog_data *data)
+{
+gint type;
+
+ type = radio_get_active(GTK_CONTAINER(data->RA_type)) == 1 ? CAT_TYPE_INCOME : CAT_TYPE_EXPENSE;
+ ui_cat_listview_populate(data->LV_cat, type);
+ gtk_tree_view_expand_all (GTK_TREE_VIEW(data->LV_cat));
+}
+
+
/*
**
*/
static void ui_cat_manage_dialog_setup(struct ui_cat_manage_dialog_data *data)
{
+
DB( g_print("(defcategory) setup\n") );
//init GList
//debug
//da_cat_debug_list();
+ ui_cat_manage_populate_listview(data);
+
+}
- ui_cat_listview_populate(data->LV_cat);
- gtk_tree_view_expand_all (GTK_TREE_VIEW(data->LV_cat));
+static void ui_cat_manage_type_changed_cb (GtkToggleButton *button, gpointer user_data)
+{
+ ui_cat_manage_populate_listview(user_data);
+ //g_print(" toggle type=%d\n", gtk_toggle_button_get_active(button));
}
-// the window creation
+
GtkWidget *ui_cat_manage_dialog (void)
{
struct ui_cat_manage_dialog_data data;
-GtkWidget *window, *content, *mainvbox, *table, *hbox, *label, *scrollwin, *vbox, *separator, *treeview;
-gint row;
+GtkWidget *window, *content, *mainvbox, *bbox, *table, *hbox, *vbox, *label, *scrollwin, *treeview;
+GtkWidget *menu, *menuitem, *widget, *image, *tbar;
+GtkToolItem *toolitem;
+gint w, h, row;
window = gtk_dialog_new_with_buttons (_("Manage Categories"),
GTK_WINDOW(GLOBALS->mainwindow),
0,
- GTK_STOCK_CLOSE,
+ _("_Close"),
GTK_RESPONSE_ACCEPT,
NULL);
data.window = window;
+ data.change = 0;
+
+ gtk_window_set_icon_name(GTK_WINDOW (window), ICONNAME_HB_CATEGORY);
- //set the window icon
- //homebank_window_set_icon_from_file(GTK_WINDOW (window), "category.svg");
- gtk_window_set_icon_name(GTK_WINDOW (window), HB_STOCK_CATEGORY);
+ //set a nice dialog size
+ gtk_window_get_size(GTK_WINDOW(GLOBALS->mainwindow), &w, &h);
+ gtk_window_set_default_size (GTK_WINDOW(window), -1, h/PHI);
+
//store our window private data
g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)&data);
DB( g_print("(defcategory) window=%x, inst_data=%x\n", (guint)window, (guint)&data) );
//window contents
content = gtk_dialog_get_content_area(GTK_DIALOG (window));
- mainvbox = gtk_vbox_new (FALSE, 0);
+ mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER(mainvbox), HB_MAINBOX_SPACING);
+ gtk_container_set_border_width (GTK_CONTAINER(mainvbox), SPACING_MEDIUM);
//our table
- table = gtk_table_new (3, 2, FALSE);
- gtk_table_set_row_spacings (GTK_TABLE (table), HB_TABROW_SPACING);
- gtk_table_set_col_spacings (GTK_TABLE (table), HB_TABCOL_SPACING);
+ table = gtk_grid_new ();
+ gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_SMALL);
+ gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_MEDIUM);
gtk_box_pack_start (GTK_BOX (mainvbox), table, TRUE, TRUE, 0);
- // category item + add button
row = 0;
- hbox = gtk_hbox_new (FALSE, HB_BOX_SPACING);
- gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, row, row+1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), (GtkAttachOptions) (0), 0, 0);
- data.ST_name1 = gtk_entry_new ();
- gtk_box_pack_start (GTK_BOX (hbox), data.ST_name1, TRUE, TRUE, 0);
- data.CM_type = gtk_check_button_new_with_mnemonic(_("I_ncome"));
- gtk_box_pack_start (GTK_BOX (hbox), data.CM_type, FALSE, FALSE, 0);
+ bbox = make_radio(CYA_CAT_TYPE, TRUE, GTK_ORIENTATION_HORIZONTAL);
+ data.RA_type = bbox;
+ gtk_widget_set_halign (bbox, GTK_ALIGN_CENTER);
+ gtk_grid_attach (GTK_GRID (table), bbox, 0, row, 2, 1);
+
+ widget = radio_get_nth_widget(GTK_CONTAINER(bbox), 1);
+ if(widget)
+ g_signal_connect (widget, "toggled", G_CALLBACK (ui_cat_manage_type_changed_cb), &data);
+
+ menu = gtk_menu_new ();
+ gtk_widget_set_halign (menu, GTK_ALIGN_END);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Import CSV"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_load_csv), &data);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("E_xport CSV"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_save_csv), &data);
+
+ menuitem = gtk_separator_menu_item_new();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+
+ menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete unused"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_delete_unused), &data);
- data.BT_add1 = gtk_button_new_from_stock(GTK_STOCK_ADD);
- gtk_table_attach (GTK_TABLE (table), data.BT_add1, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
+ gtk_widget_show_all (menu);
+
+ widget = gtk_menu_button_new();
+ image = gtk_image_new_from_icon_name (ICONNAME_HB_BUTTON_MENU, GTK_ICON_SIZE_MENU);
+
+ //gchar *thename;
+ //gtk_image_get_icon_name(image, &thename, NULL);
+ //g_print("the name is %s\n", thename);
+
+ g_object_set (widget, "image", image, "popup", GTK_MENU(menu), NULL);
+ gtk_widget_set_halign (widget, GTK_ALIGN_END);
+ gtk_grid_attach (GTK_GRID (table), widget, 1, row, 1, 1);
+
+ row++;
+ widget = gtk_entry_new ();
+ data.ST_name1 = widget;
+ gtk_entry_set_placeholder_text(GTK_ENTRY(data.ST_name1), _("new category") );
+ gtk_widget_set_hexpand (widget, TRUE);
+ gtk_grid_attach (GTK_GRID (table), widget, 0, row, 2, 1);
// subcategory + add button
row++;
- hbox = gtk_hbox_new (FALSE, HB_BOX_SPACING);
- gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, row, row+1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), (GtkAttachOptions) (0), 0, 0);
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
+ gtk_grid_attach (GTK_GRID (table), hbox, 0, row, 2, 1);
data.LA_category = gtk_label_new(NULL);
gtk_box_pack_start (GTK_BOX (hbox), data.LA_category, FALSE, FALSE, 0);
label = gtk_label_new(":");
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
data.ST_name2 = gtk_entry_new ();
+ gtk_entry_set_placeholder_text(GTK_ENTRY(data.ST_name2), _("new subcategory") );
gtk_box_pack_start (GTK_BOX (hbox), data.ST_name2, TRUE, TRUE, 0);
- data.BT_add2 = gtk_button_new_from_stock(GTK_STOCK_ADD);
- gtk_table_attach (GTK_TABLE (table), data.BT_add2, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
-
-
-
//list
row++;
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+ gtk_grid_attach (GTK_GRID (table), vbox, 0, row, 2, 1);
+
scrollwin = gtk_scrolled_window_new(NULL,NULL);
- gtk_table_attach (GTK_TABLE (table), scrollwin, 0, 1, row, row+1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), 0, 0);
-
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
- //gtk_container_set_border_width (GTK_CONTAINER(scrollwin), 5);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- treeview = (GtkWidget *)ui_cat_listview_new(FALSE);
- gtk_widget_set_size_request(treeview, HB_MINWIDTH_LIST, -1);
- data.LV_cat = treeview;
+ gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrollwin), HB_MINHEIGHT_LIST);
+ treeview = ui_cat_listview_new(FALSE, TRUE);
+ data.LV_cat = treeview;
gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
-
- vbox = gtk_vbox_new (FALSE, HB_BOX_SPACING);
- gtk_table_attach (GTK_TABLE (table), vbox, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), 0, 0);
-
+ gtk_widget_set_hexpand (scrollwin, TRUE);
+ gtk_widget_set_vexpand (scrollwin, TRUE);
+ gtk_box_pack_start (GTK_BOX(vbox), scrollwin, TRUE, TRUE, 0);
+
+ //list toolbar
+ tbar = gtk_toolbar_new();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR(tbar), GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style(GTK_TOOLBAR(tbar), GTK_TOOLBAR_ICONS);
+ gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
+ gtk_box_pack_start (GTK_BOX (vbox), tbar, FALSE, FALSE, 0);
+
+ /*widget = gtk_tool_item_new ();
+ label = gtk_label_new("test");
+ gtk_container_add(GTK_CONTAINER(widget), label);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(widget), -1);*/
+
+ //hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
/*
- widget = gtk_check_button_new_with_mnemonic("Income type");
- data.CM_type = widget;
- gtk_box_pack_start (GTK_BOX (vbox), data.CM_type, FALSE, FALSE, 0);
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), hbox);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ //widget = make_image_button("text-editor-symbolic", _("Edit"));
+ widget = gtk_button_new_with_mnemonic(_("_Edit"));
+ data.BT_edit = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ //widget = make_image_button("merge-symbolic", _("Merge"));
+ widget = gtk_button_new_with_mnemonic(_("_Merge"));
+ data.BT_merge = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
+
+ //widget = make_image_button(ICONNAME_SYM_EDIT_DELETE, _("Delete"));
+ widget = gtk_button_new_with_mnemonic(_("_Delete"));
+ data.BT_delete = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
*/
+
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, TRUE);
+ gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+ toolitem = gtk_tool_item_new();
+ gtk_container_add (GTK_CONTAINER(toolitem), hbox);
+ gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
+
+ widget = make_image_button(ICONNAME_HB_BUTTON_EXPAND, _("Expand all"));
+ data.BT_expand = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
- data.BT_rem = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
- gtk_box_pack_start (GTK_BOX (vbox), data.BT_rem, FALSE, FALSE, 0);
+ widget = make_image_button(ICONNAME_HB_BUTTON_COLLAPSE, _("Collapse all"));
+ data.BT_collapse = widget;
+ gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
- data.BT_mod = gtk_button_new_from_stock(GTK_STOCK_EDIT);
- //data.BT_mod = gtk_button_new_with_mnemonic(_("_Modify"));
- gtk_box_pack_start (GTK_BOX (vbox), data.BT_mod, FALSE, FALSE, 0);
- data.BT_mov = gtk_button_new_with_mnemonic(_("_Move"));
- gtk_box_pack_start (GTK_BOX (vbox), data.BT_mov, FALSE, FALSE, 0);
+ row++;
+ bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
+ gtk_box_set_spacing (GTK_BOX (bbox), SPACING_SMALL);
+ gtk_grid_attach (GTK_GRID (table), bbox, 0, row, 2, 1);
+
+ data.BT_edit = gtk_button_new_with_mnemonic(_("_Edit"));
+ gtk_container_add (GTK_CONTAINER (bbox), data.BT_edit);
- separator = gtk_hseparator_new();
- gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, HB_BOX_SPACING);
+ data.BT_merge = gtk_button_new_with_mnemonic(_("_Merge"));
+ gtk_container_add (GTK_CONTAINER (bbox), data.BT_merge);
+ data.BT_delete = gtk_button_new_with_mnemonic(_("_Delete"));
+ gtk_container_add (GTK_CONTAINER (bbox), data.BT_delete);
- data.BT_import = gtk_button_new_with_mnemonic(_("_Import"));
- //data.BT_import = gtk_button_new_from_stock(GTK_STOCK_OPEN);
- gtk_box_pack_start (GTK_BOX (vbox), data.BT_import, FALSE, FALSE, 0);
- data.BT_export = gtk_button_new_with_mnemonic(_("E_xport"));
- //data.BT_export = gtk_button_new_from_stock(GTK_STOCK_SAVE);
- gtk_box_pack_start (GTK_BOX (vbox), data.BT_export, FALSE, FALSE, 0);
+ /*row++;
+ widget = gtk_check_button_new_with_mnemonic(_("I_ncome"));
+ data.CM_type = widget;
+ gtk_grid_attach (GTK_GRID (table), widget, 0, row, 3, 1);*/
+
//connect all our signals
g_signal_connect (G_OBJECT (data.ST_name1), "activate", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(FALSE));
g_signal_connect (G_OBJECT (data.ST_name2), "activate", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(TRUE));
- g_signal_connect(G_OBJECT(data.ST_name1), "insert_text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
- g_signal_connect(G_OBJECT(data.ST_name2), "insert_text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
+ g_signal_connect(G_OBJECT(data.ST_name1), "insert-text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
+ g_signal_connect(G_OBJECT(data.ST_name2), "insert-text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data.LV_cat)), "changed", G_CALLBACK (ui_cat_manage_dialog_selection), NULL);
g_signal_connect (GTK_TREE_VIEW(data.LV_cat), "row-activated", G_CALLBACK (ui_cat_manage_dialog_onRowActivated), NULL);
- g_signal_connect (G_OBJECT (data.BT_add1), "clicked", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(FALSE));
- g_signal_connect (G_OBJECT (data.BT_add2), "clicked", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(TRUE));
- g_signal_connect (G_OBJECT (data.BT_mod), "clicked", G_CALLBACK (ui_cat_manage_dialog_modify), NULL);
- g_signal_connect (G_OBJECT (data.BT_mov), "clicked", G_CALLBACK (ui_cat_manage_dialog_move), NULL);
- g_signal_connect (G_OBJECT (data.BT_rem), "clicked", G_CALLBACK (ui_cat_manage_dialog_remove), NULL);
+ g_signal_connect (G_OBJECT (data.BT_edit), "clicked", G_CALLBACK (ui_cat_manage_dialog_edit), NULL);
+ g_signal_connect (G_OBJECT (data.BT_merge), "clicked", G_CALLBACK (ui_cat_manage_dialog_merge), NULL);
+ g_signal_connect (G_OBJECT (data.BT_delete), "clicked", G_CALLBACK (ui_cat_manage_dialog_delete), NULL);
- g_signal_connect (G_OBJECT (data.BT_import), "clicked", G_CALLBACK (ui_cat_manage_dialog_load_csv), NULL);
- g_signal_connect (G_OBJECT (data.BT_export), "clicked", G_CALLBACK (ui_cat_manage_dialog_save_csv), NULL);
+ g_signal_connect (G_OBJECT (data.BT_expand), "clicked", G_CALLBACK (ui_cat_manage_dialog_expand_all), NULL);
+ g_signal_connect (G_OBJECT (data.BT_collapse), "clicked", G_CALLBACK (ui_cat_manage_dialog_collapse_all), NULL);
//setup, init and show window
+ category_fill_usage();
ui_cat_manage_dialog_setup(&data);
ui_cat_manage_dialog_update(data.LV_cat, NULL);
- gtk_window_resize(GTK_WINDOW(window), 200, 320);
-
-
gtk_widget_show_all (window);
//wait for the user
ui_cat_manage_dialog_cleanup(&data, result);
gtk_widget_destroy (window);
- return NULL;
+ GLOBALS->changes_count += data.change;
+
+ return NULL;
}