~veselkovsd/homebank/ignore_week-end

« back to all changes in this revision

Viewing changes to src/ui-category.c

  • Committer: Maxime Doyen
  • Date: 2020-01-09 20:51:22 UTC
  • Revision ID: homebank@free.fr-20200109205122-160pgd4y7hirpins
5.3 release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*  HomeBank -- Free, easy, personal accounting for everyone.
2
 
 *  Copyright (C) 1995-2019 Maxime DOYEN
 
2
 *  Copyright (C) 1995-2020 Maxime DOYEN
3
3
 *
4
4
 *  This file is part of HomeBank.
5
5
 *
40
40
 
41
41
static void ui_cat_manage_populate_listview(struct ui_cat_manage_dialog_data *data);
42
42
 
43
 
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
43
 
 
44
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
45
 
 
46
 
 
47
static GtkWidget *
 
48
container_get_nth(GtkBox *container, gint nth)
 
49
{
 
50
GList *lchild, *list;
 
51
GtkWidget *child;
 
52
 
 
53
        if(!GTK_IS_CONTAINER(container))
 
54
                return NULL;
 
55
 
 
56
        lchild = list = gtk_container_get_children (GTK_CONTAINER(container));
 
57
        child = g_list_nth_data (list, nth);
 
58
        g_list_free(lchild);
 
59
        
 
60
        return child;
 
61
}
 
62
 
 
63
 
 
64
GtkWidget *
 
65
ui_cat_entry_popover_get_entry(GtkBox *box)
 
66
{
 
67
        return container_get_nth(box, 0);
 
68
}
 
69
 
 
70
 
 
71
Category
 
72
*ui_cat_entry_popover_get(GtkBox *box)
 
73
{
 
74
GtkWidget *entry;
 
75
gchar *name;
 
76
Category *item = NULL;
 
77
 
 
78
        DB( g_print ("ui_cat_entry_popover_get()\n") );
 
79
 
 
80
        entry = container_get_nth(box, 0);
 
81
        if( entry != NULL && GTK_IS_ENTRY(entry) )
 
82
        {
 
83
                name = (gchar *)gtk_entry_get_text(GTK_ENTRY (entry));
 
84
                item = da_cat_get_by_fullname(name);
 
85
        }
 
86
        return item;
 
87
}
 
88
 
 
89
 
 
90
guint32
 
91
ui_cat_entry_popover_get_key_add_new(GtkBox *box)
 
92
{
 
93
Category *item;
 
94
GtkWidget *entry;
 
95
GtkTreeModel *store;
 
96
 
 
97
        DB( g_print ("ui_cat_entry_popover_get_key_add_new()\n") );
 
98
 
 
99
        /* automatic add */
 
100
        //todo: check prefs + ask the user here 1st time
 
101
        entry = container_get_nth(box, 0);
 
102
        if( entry != NULL && GTK_IS_ENTRY(entry) )
 
103
        {
 
104
        gchar *name = (gchar *)gtk_entry_get_text(GTK_ENTRY (entry));
 
105
 
 
106
                item = da_cat_get_by_fullname(name);
 
107
                if(item != NULL)
 
108
                        return item->key;
 
109
 
 
110
                item = da_cat_append_ifnew_by_fullname(name);
 
111
                if( item != NULL )
 
112
                {
 
113
                        store = gtk_entry_completion_get_model(gtk_entry_get_completion(GTK_ENTRY(entry)));
 
114
                        if( store )
 
115
                                gtk_list_store_insert_with_values(GTK_LIST_STORE(store), NULL, -1,
 
116
                                        0, item->name,
 
117
                                        1, item,
 
118
                                        -1);
 
119
                        return item->key;
 
120
                }
 
121
        }
 
122
 
 
123
        return 0;
 
124
}
 
125
 
 
126
 
 
127
guint32
 
128
ui_cat_entry_popover_get_key(GtkBox *box)
 
129
{
 
130
Category *item = ui_cat_entry_popover_get(box);
 
131
 
 
132
        return ((item != NULL) ? item->key : 0);
 
133
}
 
134
 
 
135
 
 
136
void
 
137
ui_cat_entry_popover_set_active(GtkBox *box, guint32 key)
 
138
{
 
139
GtkWidget *entry;
 
140
 
 
141
        DB( g_print ("ui_cat_comboboxentry_set_active()\n") );
 
142
 
 
143
        entry = container_get_nth(box, 0);
 
144
        if( entry != NULL && GTK_IS_ENTRY(entry) )
 
145
        {
 
146
        Category *item = da_cat_get(key);
 
147
 
 
148
                hbtk_entry_set_text(GTK_ENTRY(entry), item != NULL ? item->fullname : "");
 
149
        }
 
150
}
 
151
 
 
152
 
 
153
static void 
 
154
ui_cat_entry_popover_cb_row_activated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
 
155
{
 
156
GtkTreeSelection *treeselection;
 
157
GtkTreeModel *model;
 
158
GtkTreeIter iter;
 
159
GtkEntry *entry = user_data;
 
160
 
 
161
        if( GTK_IS_ENTRY(entry) )
 
162
        {
 
163
                treeselection = gtk_tree_view_get_selection(tree_view);
 
164
                if( gtk_tree_selection_get_selected(treeselection, &model, &iter) )
 
165
                {
 
166
                Category *item;
 
167
 
 
168
                        gtk_tree_model_get(model, &iter, 1, &item, -1);
 
169
                        if(item)
 
170
                                gtk_entry_set_text(GTK_ENTRY(user_data), item->fullname);
 
171
                }
 
172
        }
 
173
}
 
174
 
 
175
 
 
176
static void
 
177
ui_cat_entry_popover_text_cell_data_function (GtkTreeViewColumn *col,
 
178
                                GtkCellRenderer *renderer,
 
179
                                GtkTreeModel *model,
 
180
                                GtkTreeIter *iter,
 
181
                                gpointer user_data)
 
182
{
 
183
Category *entry;
 
184
gchar *name;
 
185
gchar *string;
 
186
 
 
187
        gtk_tree_model_get(model, iter, 1, &entry, -1);
 
188
        if(entry->key == 0)
 
189
                name = _("(no category)");
 
190
        else
 
191
                name = entry->name;
 
192
 
 
193
        gchar type = category_get_type_char(entry);
 
194
 
 
195
        #if MYDEBUG
 
196
        string = g_markup_printf_escaped ("%d > [%d] %s [%c] %d %c", entry->key, entry->parent, name, type, entry->flags, (entry->flags & GF_MIXED) ?'m':' ' );
 
197
        #else
 
198
        if(entry->key == 0)
 
199
                string = g_strdup(name);
 
200
        else
 
201
        {
 
202
                if( entry->parent == 0 )
 
203
                        string = g_markup_printf_escaped("%s [%c]", name, type);
 
204
                else
 
205
                        string = g_markup_printf_escaped(" %c <i>%s</i>", type, name);
 
206
                        //string = g_strdup_printf(" - %s", name);
 
207
        }
 
208
        #endif
 
209
 
 
210
        //g_object_set(renderer, "text", string, NULL);
 
211
        g_object_set(renderer, "markup", string, NULL);
 
212
 
 
213
        g_free(string);
 
214
 
 
215
}
 
216
 
 
217
 
 
218
static void
 
219
ui_cat_entry_popover_populate(GtkListStore *store)
 
220
{
 
221
GHashTableIter hiter;
 
222
gpointer key, value;
 
223
        
 
224
        g_hash_table_iter_init (&hiter, GLOBALS->h_cat);
 
225
        while (g_hash_table_iter_next (&hiter, &key, &value))
 
226
        {
 
227
        Category *item = value;
 
228
 
 
229
                gtk_list_store_insert_with_values(GTK_LIST_STORE(store), NULL, -1,
 
230
                        0, item->fullname,
 
231
                    1, item,
 
232
                        -1);
 
233
        }
 
234
 
 
235
        gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
 
236
}
 
237
 
 
238
 
 
239
static void
 
240
ui_cat_entry_popover_function (GtkEditable *editable, gpointer user_data)
 
241
{
 
242
 
 
243
        DB( g_print("text changed to %s\n", gtk_entry_get_text(GTK_ENTRY(editable)) ) );
 
244
        
 
245
 
 
246
 
 
247
}
 
248
 
 
249
 
 
250
static void
 
251
ui_cat_entry_popover_cb_toggled (GtkToggleButton *togglebutton, gpointer user_data)
 
252
{
 
253
GtkWidget *entry = user_data;
 
254
GtkAllocation allocation;
 
255
GtkPopover *popover;
 
256
 
 
257
        if(GTK_IS_ENTRY(entry))
 
258
        {
 
259
                gtk_widget_get_allocation (entry, &allocation);
 
260
                popover = gtk_menu_button_get_popover(GTK_MENU_BUTTON(togglebutton));
 
261
                if(GTK_IS_POPOVER(popover))
 
262
                {
 
263
                        gtk_widget_set_size_request (GTK_WIDGET(popover), allocation.width + (2*SPACING_POPOVER), -1);  
 
264
                        DB( g_print("should set width to %d\n", allocation.width + (2*SPACING_POPOVER)) );      
 
265
                }
 
266
        }
 
267
}
 
268
 
 
269
 
 
270
static gint
 
271
ui_cat_entry_popover_compare_func (GtkTreeModel *model, GtkTreeIter  *a, GtkTreeIter  *b, gpointer      userdata)
 
272
{
 
273
gint retval = 0;
 
274
gchar *name1, *name2;
 
275
 
 
276
    gtk_tree_model_get(model, a, 0, &name1, -1);
 
277
    gtk_tree_model_get(model, b, 0, &name2, -1);
 
278
 
 
279
        retval = hb_string_utf8_compare(name1, name2);
 
280
 
 
281
    g_free(name2);
 
282
    g_free(name1);
 
283
 
 
284
        return retval;
 
285
}
 
286
 
 
287
 
 
288
 
 
289
static gboolean
 
290
ui_cat_entry_popover_completion_func (GtkEntryCompletion *completion,
 
291
                                              const gchar        *key,
 
292
                                              GtkTreeIter        *iter,
 
293
                                              gpointer            user_data)
 
294
{
 
295
  Category *item = NULL;
 
296
  gchar *normalized_string;
 
297
  gchar *case_normalized_string;
 
298
 
 
299
  gboolean ret = FALSE;
 
300
 
 
301
  GtkTreeModel *model;
 
302
 
 
303
  model = gtk_entry_completion_get_model (completion);
 
304
 
 
305
  gtk_tree_model_get (model, iter,
 
306
                      1, &item,
 
307
                      -1);
 
308
 
 
309
  if (item != NULL)
 
310
    {
 
311
      normalized_string = g_utf8_normalize (item->fullname, -1, G_NORMALIZE_ALL);
 
312
 
 
313
      if (normalized_string != NULL)
 
314
        {
 
315
          case_normalized_string = g_utf8_casefold (normalized_string, -1);
 
316
 
 
317
                        //g_print("match '%s' for '%s' ?\n", key, case_normalized_string);
 
318
                //if (!strncmp (key, case_normalized_string, strlen (key)))
 
319
          if (g_strstr_len (case_normalized_string, strlen (case_normalized_string), key ))
 
320
                        {
 
321
                        ret = TRUE;
 
322
                                //      g_print(" ==> yes !\n");
 
323
                                
 
324
                        }
 
325
                                
 
326
          g_free (case_normalized_string);
 
327
        }
 
328
      g_free (normalized_string);
 
329
    }
 
330
 
 
331
  return ret;
 
332
}
 
333
 
 
334
 
 
335
 
 
336
static void 
 
337
ui_cat_entry_popover_destroy( GtkWidget *widget, gpointer user_data )
 
338
{
 
339
 
 
340
    DB( g_print ("[pay entry popover] destroy\n") );
 
341
 
 
342
}
 
343
 
 
344
 
 
345
GtkWidget *
 
346
ui_cat_entry_popover_new(GtkWidget *label)
 
347
{
 
348
GtkWidget *mainbox, *box, *entry, *menubutton, *image, *popover, *scrollwin, *treeview;
 
349
GtkListStore *store;
 
350
GtkEntryCompletion *completion;
 
351
 
 
352
    DB( g_print ("[pay entry popover] new\n") );
 
353
 
 
354
        mainbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
 
355
        gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(mainbox)), GTK_STYLE_CLASS_LINKED);
 
356
        
 
357
        entry = gtk_entry_new();
 
358
        gtk_box_pack_start(GTK_BOX(mainbox), entry, TRUE, TRUE, 0);
 
359
 
 
360
        menubutton = gtk_menu_button_new ();
 
361
        //data->MB_template = menubutton;
 
362
        image = gtk_image_new_from_icon_name ("pan-down-symbolic", GTK_ICON_SIZE_BUTTON);
 
363
        gtk_container_add(GTK_CONTAINER(menubutton), image);
 
364
        gtk_menu_button_set_direction (GTK_MENU_BUTTON(menubutton), GTK_ARROW_LEFT );
 
365
        //gtk_widget_set_halign (menubutton, GTK_ALIGN_END);
 
366
        gtk_box_pack_start(GTK_BOX(mainbox), menubutton, FALSE, FALSE, 0);
 
367
        
 
368
    completion = gtk_entry_completion_new ();
 
369
 
 
370
        gtk_entry_set_completion (GTK_ENTRY (entry), completion);
 
371
        g_object_unref(completion);
 
372
        
 
373
        store = gtk_list_store_new (2,
 
374
                G_TYPE_STRING,
 
375
                G_TYPE_POINTER
 
376
                );
 
377
 
 
378
        gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_cat_entry_popover_compare_func, NULL, NULL);
 
379
 
 
380
        ui_cat_entry_popover_populate(store);
 
381
 
 
382
        
 
383
    gtk_entry_completion_set_model (completion, GTK_TREE_MODEL(store));
 
384
        gtk_entry_completion_set_match_func(completion, ui_cat_entry_popover_completion_func, NULL, NULL);
 
385
        g_object_unref(store);
 
386
 
 
387
        gtk_entry_completion_set_text_column (completion, 0);
 
388
 
 
389
        gtk_widget_show_all(mainbox);
 
390
 
 
391
 
 
392
        box = gtk_box_new(GTK_ORIENTATION_VERTICAL, SPACING_MEDIUM);
 
393
        scrollwin = gtk_scrolled_window_new(NULL,NULL);
 
394
        gtk_box_pack_start(GTK_BOX(box), scrollwin, TRUE, TRUE, 0);
 
395
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
 
396
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
397
        //gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrollwin), HB_MINHEIGHT_LIST);
 
398
        treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL(store));
 
399
        gtk_container_add(GTK_CONTAINER(scrollwin), GTK_WIDGET(treeview));
 
400
        gtk_widget_show_all(box);
 
401
 
 
402
 
 
403
        //gtk_widget_set_can_focus(GTK_WIDGET(treeview), FALSE);
 
404
 
 
405
GtkCellRenderer *renderer;
 
406
  GtkTreeViewColumn *column;
 
407
        
 
408
  renderer = gtk_cell_renderer_text_new ();
 
409
 
 
410
        g_object_set(renderer, 
 
411
                "ellipsize", PANGO_ELLIPSIZE_END,
 
412
            "ellipsize-set", TRUE,
 
413
                //taken from nemo, not exactly a resize to content, but good compromise
 
414
            "width-chars", 40,
 
415
            NULL);
 
416
 
 
417
        column = gtk_tree_view_column_new_with_attributes (NULL,
 
418
                                                     renderer,
 
419
                                                     "text",
 
420
                                                     0,
 
421
                                                     NULL);
 
422
        gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cat_entry_popover_text_cell_data_function, NULL, NULL);
 
423
        gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
 
424
 
 
425
 
 
426
        gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(treeview), TRUE);
 
427
        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
 
428
        gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(treeview), TRUE);
 
429
 
 
430
 
 
431
        //gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_BROWSE);
 
432
        
 
433
        
 
434
        //popover = create_popover (menubutton, box, GTK_POS_BOTTOM);
 
435
        popover = create_popover (menubutton, box, GTK_POS_LEFT);
 
436
        //gtk_widget_set_size_request (popover, HB_MINWIDTH_LIST, HB_MINHEIGHT_LIST);
 
437
        gtk_widget_set_vexpand(popover, TRUE);
 
438
        
 
439
        gtk_menu_button_set_popover(GTK_MENU_BUTTON(menubutton), popover);
 
440
        
 
441
        
 
442
        // connect our dispose function
 
443
        g_signal_connect (entry, "destroy", G_CALLBACK (ui_cat_entry_popover_destroy), NULL);
 
444
 
 
445
        g_signal_connect_after (entry  , "changed", G_CALLBACK (ui_cat_entry_popover_function), NULL);
 
446
 
 
447
        g_signal_connect (menubutton, "toggled", G_CALLBACK (ui_cat_entry_popover_cb_toggled), entry);
 
448
        
 
449
        g_signal_connect (treeview, "row-activated", G_CALLBACK (ui_cat_entry_popover_cb_row_activated), entry);
 
450
 
 
451
        #if( (GTK_MAJOR_VERSION == 3) && (GTK_MINOR_VERSION >= 22) )
 
452
                g_signal_connect_swapped(treeview, "row-activated", G_CALLBACK(gtk_popover_popdown), popover);
 
453
        #else
 
454
                g_signal_connect_swapped(treeview, "row-activated", G_CALLBACK(gtk_widget_hide), popover);
 
455
        #endif
 
456
 
 
457
        //g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), "changed", G_CALLBACK (ui_cat_entry_popover_cb_selection), entry);
 
458
        //g_signal_connect_swapped(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), "changed", G_CALLBACK(gtk_popover_popdown), popover);
 
459
        
 
460
        if(label)
 
461
                gtk_label_set_mnemonic_widget (GTK_LABEL(label), entry);
 
462
 
 
463
        //gtk_widget_set_size_request(comboboxentry, HB_MINWIDTH_LIST, -1);
 
464
 
 
465
        return mainbox;
 
466
}
 
467
 
 
468
 
 
469
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
 
470
 
44
471
 
45
472
/**
46
473
 * ui_cat_comboboxentry_get_key:
732
1159
        return NULL;
733
1160
}
734
1161
 
735
 
gboolean ui_cat_listview_remove (GtkTreeModel *model, guint32 key)
736
 
{
737
 
GtkTreeIter  iter, child;
738
 
gboolean     valid, cvalid;
739
 
Category *item;
740
 
 
741
 
        DB( g_print("ui_cat_listview_remove() \n") );
742
 
 
743
 
    valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
744
 
    while (valid)
745
 
    {
746
 
                gtk_tree_model_get (model, &iter, LST_DEFCAT_DATAS, &item, -1);
747
 
 
748
 
                DB( g_print(" + item %p, %s\n", item, item->name) );
749
 
 
750
 
                if(item->key == key || item->parent == key)
751
 
                {
752
 
                        DB( g_print(" + removing cat %s\n", item->name) );
753
 
                        gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
754
 
                }
755
 
 
756
 
                // iter children
757
 
                cvalid = gtk_tree_model_iter_children (GTK_TREE_MODEL(model), &child, &iter);
758
 
                while(cvalid)
759
 
                {
760
 
                        gtk_tree_model_get(GTK_TREE_MODEL(model), &child, LST_DEFCAT_DATAS, &item, -1);
761
 
                        if(item->key == key || item->parent == key)
762
 
                        {
763
 
                                DB( g_print(" + removing subcat %s\n", item->name) );
764
 
                                gtk_tree_store_remove(GTK_TREE_STORE(model), &child);
765
 
                        }
766
 
 
767
 
                        cvalid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &child);
768
 
                }
769
 
                valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
770
 
    }
771
 
 
772
 
        return TRUE;
773
 
}
774
 
 
775
 
 
776
1162
 
777
1163
void
778
1164
ui_cat_listview_remove_selected(GtkTreeView *treeview)
786
1172
        selection = gtk_tree_view_get_selection(treeview);
787
1173
        if (gtk_tree_selection_get_selected(selection, &model, &iter))
788
1174
        {
789
 
                gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
 
1175
                if( gtk_tree_model_iter_has_child(GTK_TREE_MODEL(model), &iter) == FALSE )
 
1176
                        gtk_tree_store_remove(GTK_TREE_STORE(model), &iter);
790
1177
        }
791
1178
}
792
1179
 
830
1217
        item_type = (item->flags & GF_INCOME) ? CAT_TYPE_INCOME : CAT_TYPE_EXPENSE; 
831
1218
 
832
1219
        //DB( g_print("cat listview populate: %d %s\n", (guint32 *)key, item->name) );
833
 
        if( (ctx->type == CAT_TYPE_ALL) || ctx->type == item_type || item->key == 0 )
 
1220
        //#1740368 add mixed cat as well
 
1221
        if( (ctx->type == CAT_TYPE_ALL) || ctx->type == item_type || item->key == 0 || (item->flags & GF_MIXED) )
834
1222
        {
835
1223
                if( item->parent == 0 )
836
1224
                {
852
1240
GtkTreeIter  toplevel, child;
853
1241
Category *item = value;
854
1242
gboolean ret;
855
 
gint item_type;
856
 
 
857
 
        item_type = (item->flags & GF_INCOME) ? CAT_TYPE_INCOME : CAT_TYPE_EXPENSE; 
858
 
 
859
 
        if( (ctx->type == CAT_TYPE_ALL) || ctx->type == item_type)
860
 
        {
 
1243
//gint item_type;
 
1244
 
 
1245
        //#1740368 no need to filter on type, always insert all childs
 
1246
        //item_type = (item->flags & GF_INCOME) ? CAT_TYPE_INCOME : CAT_TYPE_EXPENSE; 
 
1247
 
 
1248
        //if( (ctx->type == CAT_TYPE_ALL) || ctx->type == item_type)
 
1249
        //{
861
1250
                if( item->parent != 0 )
862
1251
                {
863
1252
                        ret = ui_cat_listview_get_top_level(ctx->model, item->parent, &toplevel);
872
1261
                                        -1);
873
1262
                        }
874
1263
                }
875
 
        }
 
1264
        //}
876
1265
 
877
1266
}
878
1267
 
1003
1392
 
1004
1393
        // column 2: name
1005
1394
        renderer = gtk_cell_renderer_text_new ();
 
1395
 
1006
1396
        g_object_set(renderer, 
1007
1397
                "ellipsize", PANGO_ELLIPSIZE_END,
1008
1398
            "ellipsize-set", TRUE,
 
1399
                //taken from nemo, not exactly a resize to content, but good compromise
 
1400
            "width-chars", 40,
1009
1401
            NULL);
1010
1402
 
1011
1403
        column = gtk_tree_view_column_new();
1012
 
        gtk_tree_view_column_set_title(column, _("Name"));
 
1404
        gtk_tree_view_column_set_title(column, _("Category"));
1013
1405
        gtk_tree_view_column_pack_start(column, renderer, TRUE);
1014
1406
        gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cat_listview_text_cell_data_function, GINT_TO_POINTER(LST_DEFCAT_NAME), NULL);
1015
1407
        gtk_tree_view_column_set_alignment (column, 0.5);
1016
 
        gtk_tree_view_column_set_min_width(column, HB_MINWIDTH_LIST*2);
 
1408
        gtk_tree_view_column_set_resizable(column, TRUE);
 
1409
        gtk_tree_view_column_set_min_width(column, HB_MINWIDTH_LIST);
1017
1410
        gtk_tree_view_column_set_sort_column_id (column, LST_DEFCAT_SORT_NAME);
1018
 
        gtk_tree_view_column_set_resizable(column, TRUE);
1019
1411
        gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1020
1412
 
1021
1413
        if( withcount == TRUE )
1022
1414
        {
1023
1415
                column = gtk_tree_view_column_new();
1024
 
                gtk_tree_view_column_set_title(column, _("Usage"));
 
1416
                gtk_tree_view_column_set_title(column, "#");
1025
1417
                renderer = gtk_cell_renderer_text_new ();
1026
1418
                g_object_set(renderer, "xalign", 0.5, NULL);
1027
1419
                gtk_tree_view_column_pack_start(column, renderer, TRUE);
1028
1420
                gtk_tree_view_column_set_cell_data_func(column, renderer, ui_cat_listview_count_cell_data_function, GINT_TO_POINTER(LST_DEFCAT_DATAS), NULL);
1029
1421
                gtk_tree_view_column_set_alignment (column, 0.5);
1030
 
                //gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
 
1422
                gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
1031
1423
                gtk_tree_view_column_set_sort_column_id (column, LST_DEFCAT_SORT_USED);
1032
1424
                gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1033
1425
        }
1034
1426
 
 
1427
        /* empty */
 
1428
        column = gtk_tree_view_column_new();
 
1429
        gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
 
1430
 
1035
1431
        
1036
1432
        gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview), ui_cat_listview_search_equal_func, NULL, NULL);
1037
1433
 
1099
1495
        DB( g_print("(ui_cat_manage_dialog) delete unused - data %p\n", data) );
1100
1496
 
1101
1497
        result = ui_dialog_msg_confirm_alert(
1102
 
                        GTK_WINDOW(data->window),
 
1498
                        GTK_WINDOW(data->dialog),
1103
1499
                        _("Delete unused categories"),
1104
1500
                        _("Are you sure you want to permanently\ndelete unused categories?"),
1105
1501
                        _("_Delete")
1135
1531
 
1136
1532
        DB( g_print("(ui_cat_manage_dialog) load csv - data %p\n", data) );
1137
1533
 
1138
 
        if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_OPEN, &filename, NULL) == TRUE )
 
1534
        if( ui_file_chooser_csv(GTK_WINDOW(data->dialog), GTK_FILE_CHOOSER_ACTION_OPEN, &filename, NULL) == TRUE )
1139
1535
        {
1140
1536
                DB( g_print(" + filename is %s\n", filename) );
1141
1537
 
1142
1538
                if(!category_load_csv(filename, &error))
1143
1539
                {
1144
 
                        ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
 
1540
                        ui_dialog_msg_infoerror(GTK_WINDOW(data->dialog), GTK_MESSAGE_ERROR,
1145
1541
                                        _("File format error"),
1146
1542
                                        _("The CSV file must contains the exact numbers of column,\nseparated by a semi-colon, please see the help for more details.")
1147
1543
                                        );
1168
1564
 
1169
1565
        //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1170
1566
 
1171
 
        if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, NULL) == TRUE )
 
1567
        if( ui_file_chooser_csv(GTK_WINDOW(data->dialog), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, NULL) == TRUE )
1172
1568
        {
1173
1569
                DB( g_print(" + filename is %s\n", filename) );
1174
1570
 
1268
1664
static void ui_cat_manage_dialog_edit(GtkWidget *widget, gpointer user_data)
1269
1665
{
1270
1666
struct ui_cat_manage_dialog_data *data;
1271
 
GtkWidget *dialog, *content, *mainvbox, *w_name, *w_type = NULL;
 
1667
GtkWidget *dialog, *content, *mainvbox, *w_name, *w_type = NULL, *w_child;
1272
1668
GtkTreeSelection *selection;
1273
1669
GtkTreeModel             *model;
1274
1670
GtkTreeIter                      iter;
1285
1681
                gtk_tree_model_get(model, &iter, LST_DEFCAT_DATAS, &item, -1);
1286
1682
 
1287
1683
                dialog = gtk_dialog_new_with_buttons (_("Edit..."),
1288
 
                                                    GTK_WINDOW (data->window),
 
1684
                                                    GTK_WINDOW (data->dialog),
1289
1685
                                                    0,
1290
1686
                                                    _("_Cancel"),
1291
1687
                                                    GTK_RESPONSE_REJECT,
1294
1690
                                                    NULL);
1295
1691
 
1296
1692
                content = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
1297
 
                mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1298
 
                gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
 
1693
                mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_MEDIUM);
 
1694
                gtk_box_pack_start (GTK_BOX (content), mainvbox, FALSE, FALSE, 0);
1299
1695
                gtk_container_set_border_width (GTK_CONTAINER (mainvbox), SPACING_MEDIUM);
1300
1696
 
1301
1697
                w_name = gtk_entry_new();
1302
 
                gtk_box_pack_start (GTK_BOX (mainvbox), w_name, TRUE, TRUE, 0);
1303
 
 
1304
1698
                gtk_entry_set_text(GTK_ENTRY(w_name), item->name);
1305
1699
                gtk_widget_grab_focus (w_name);
 
1700
                gtk_box_pack_start (GTK_BOX (mainvbox), w_name, FALSE, FALSE, 0);
1306
1701
 
1307
1702
                gtk_entry_set_activates_default (GTK_ENTRY(w_name), TRUE);
1308
1703
 
1309
 
                if(!(item->flags & GF_SUB))
1310
 
                {
 
1704
                //if(!(item->flags & GF_SUB))
 
1705
                //{
1311
1706
                        w_type = gtk_check_button_new_with_mnemonic(_("_Income"));
1312
 
                        gtk_box_pack_start (GTK_BOX (mainvbox), w_type, TRUE, TRUE, 0);
 
1707
                        gtk_box_pack_start (GTK_BOX (mainvbox), w_type, FALSE, FALSE, 0);
1313
1708
                        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w_type), item->flags & GF_INCOME ? TRUE : FALSE);
1314
 
                }
 
1709
                //}
 
1710
 
 
1711
                w_child = gtk_check_button_new_with_mnemonic(_("Change type for _child"));
 
1712
                gtk_box_pack_start (GTK_BOX (mainvbox), w_child, FALSE, FALSE, 0);
1315
1713
 
1316
1714
                g_signal_connect (G_OBJECT (w_name), "changed", G_CALLBACK (ui_cat_manage_dialog_edit_entry_cb), dialog);
1317
1715
 
1318
 
 
1319
1716
                gtk_widget_show_all(mainvbox);
1320
1717
 
 
1718
                if((item->flags & GF_SUB))
 
1719
                {
 
1720
                        gtk_widget_hide(w_child);
 
1721
                }
 
1722
 
 
1723
                
1321
1724
                gtk_dialog_set_default_response(GTK_DIALOG( dialog ), GTK_RESPONSE_ACCEPT);
1322
1725
 
1323
1726
                //wait for the user
1356
1759
                                                }
1357
1760
                                        }
1358
1761
 
1359
 
 
1360
1762
                                        ui_dialog_msg_infoerror(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
1361
1763
                                                _("Error"),
1362
1764
                                                _("Cannot rename this Category,\n"
1367
1769
                                                );
1368
1770
 
1369
1771
                                        g_free(toname);
1370
 
 
1371
1772
                                }
1372
1773
                        }
1373
1774
        
1374
1775
                        // 2: manage flag change
1375
 
                        if(!(item->flags & GF_SUB))
1376
 
                        {
1377
 
                        gboolean isIncome;
1378
 
                        
1379
 
                                isIncome = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w_type));
1380
 
                                data->change += category_change_type(item, isIncome);
1381
 
                        }
 
1776
                        gboolean isIncome = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w_type));
 
1777
                        gboolean doChild  = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w_child));
 
1778
                        data->change += category_change_type(item, isIncome, doChild);
1382
1779
                        
1383
1780
                        ui_cat_listview_sort_force(GTK_TREE_SORTABLE(model), NULL);
1384
1781
            }
1425
1822
                title = g_strdup_printf (
1426
1823
                        _("Merge category '%s'"), srccat->name);
1427
1824
 
1428
 
                dialog = gtk_message_dialog_new (GTK_WINDOW (data->window),
 
1825
                dialog = gtk_message_dialog_new (GTK_WINDOW (data->dialog),
1429
1826
                                                      GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1430
1827
                                                      GTK_MESSAGE_WARNING,
1431
1828
                                                      GTK_BUTTONS_NONE,
1509
1906
                        {
1510
1907
                                DB( g_print(" -> delete %d '%s'\n", srccat->key, srccat->name ) );
1511
1908
 
1512
 
                                da_cat_remove(srccat->key);
1513
1909
                                ui_cat_listview_remove_selected(GTK_TREE_VIEW(data->LV_cat));
 
1910
                                da_cat_delete(srccat->key);
1514
1911
                        }
1515
1912
 
1516
1913
 
1528
1925
 
1529
1926
 
1530
1927
/*
1531
 
** delete the selected payee to our treeview and temp GList
 
1928
** delete the selected category to our treeview and temp GList
1532
1929
*/
1533
1930
static void ui_cat_manage_dialog_delete(GtkWidget *widget, gpointer user_data)
1534
1931
{
1555
1952
                }
1556
1953
 
1557
1954
                result = ui_dialog_msg_confirm_alert(
1558
 
                                GTK_WINDOW(data->window),
 
1955
                                GTK_WINDOW(data->dialog),
1559
1956
                                title,
1560
1957
                                secondtext,
1561
1958
                                _("_Delete")
1565
1962
 
1566
1963
                if( result == GTK_RESPONSE_OK )
1567
1964
                {
1568
 
                        ui_cat_listview_remove(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_cat)), item->key);
 
1965
                        ui_cat_listview_remove_selected(GTK_TREE_VIEW(data->LV_cat));
1569
1966
                        category_move(item->key, 0);
1570
 
                        da_cat_remove(item->key);
 
1967
                        da_cat_delete(item->key);
1571
1968
                        data->change++;
1572
1969
                }
1573
1970
 
1616
2013
 
1617
2014
        data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW)), "inst_data");
1618
2015
        //window = gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW);
1619
 
        //DB( g_print("(defpayee) widget=%08lx, window=%08lx, inst_data=%08lx\n", treeview, window, data) );
 
2016
        //DB( g_print("(defcategory) widget=%08lx, window=%08lx, inst_data=%08lx\n", treeview, window, data) );
1620
2017
 
1621
2018
        //if true there is a selected node
1622
2019
        selected = gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_cat)), &model, &iter);
1695
2092
        gtk_widget_set_sensitive(data->BT_edit, sensitive);
1696
2093
        gtk_widget_set_sensitive(data->BT_merge, sensitive);
1697
2094
 
1698
 
        //avoid removing top categories
 
2095
        //avoid deleting top categories
1699
2096
        sensitive = (haschild == TRUE) ? FALSE : sensitive;
1700
2097
 
1701
2098
        gtk_widget_set_sensitive(data->BT_delete, sensitive);
1793
2190
 
1794
2191
GtkWidget *ui_cat_manage_dialog (void)
1795
2192
{
1796
 
struct ui_cat_manage_dialog_data data;
 
2193
struct ui_cat_manage_dialog_data *data;
1797
2194
GtkWidget *window, *content, *mainvbox, *bbox, *table, *hbox, *vbox, *label, *scrollwin, *treeview;
1798
2195
GtkWidget *menu, *menuitem, *widget, *image, *tbar, *addreveal;
1799
2196
GtkToolItem *toolitem;
1800
2197
gint w, h, row;
1801
2198
 
 
2199
        data = g_malloc0(sizeof(struct ui_cat_manage_dialog_data));
 
2200
        if(!data) return NULL;
 
2201
 
1802
2202
        window = gtk_dialog_new_with_buttons (_("Manage Categories"),
1803
2203
                                            GTK_WINDOW(GLOBALS->mainwindow),
1804
2204
                                            0,
1806
2206
                                            GTK_RESPONSE_ACCEPT,
1807
2207
                                            NULL);
1808
2208
 
1809
 
        data.window = window;
1810
 
        data.change = 0;
 
2209
        data->dialog = window;
 
2210
        data->change = 0;
1811
2211
 
1812
2212
        gtk_window_set_icon_name(GTK_WINDOW (window), ICONNAME_HB_CATEGORY);
1813
2213
 
1817
2217
 
1818
2218
        
1819
2219
        //store our window private data
1820
 
        g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)&data);
1821
 
        DB( g_print("(defcategory) window=%p, inst_data=%p\n", window, &data) );
 
2220
        g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)data);
 
2221
        DB( g_print("(defcategory) window=%p, inst_data=%p\n", window, data) );
1822
2222
 
1823
2223
    g_signal_connect (window, "destroy",
1824
2224
                        G_CALLBACK (gtk_widget_destroyed), &window);
1837
2237
 
1838
2238
        row = 0;
1839
2239
        bbox = hbtk_radio_button_new(CYA_CAT_TYPE, TRUE);
1840
 
        data.RA_type = bbox;
 
2240
        data->RA_type = bbox;
1841
2241
        gtk_widget_set_halign (bbox, GTK_ALIGN_CENTER);
1842
2242
        gtk_grid_attach (GTK_GRID (table), bbox, 0, row, 2, 1);
1843
2243
 
1844
 
        hbtk_radio_button_connect (GTK_CONTAINER(bbox), "toggled", G_CALLBACK (ui_cat_manage_type_changed_cb), &data);
 
2244
        hbtk_radio_button_connect (GTK_CONTAINER(bbox), "toggled", G_CALLBACK (ui_cat_manage_type_changed_cb), data);
1845
2245
 
1846
2246
        menu = gtk_menu_new ();
1847
2247
        gtk_widget_set_halign (menu, GTK_ALIGN_END);
1848
2248
 
1849
2249
        menuitem = gtk_menu_item_new_with_mnemonic (_("_Import CSV"));
1850
2250
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1851
 
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_load_csv), &data);
 
2251
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_load_csv), data);
1852
2252
 
1853
2253
        menuitem = gtk_menu_item_new_with_mnemonic (_("E_xport CSV"));
1854
2254
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1855
 
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_save_csv), &data);
 
2255
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_save_csv), data);
1856
2256
 
1857
2257
        menuitem = gtk_separator_menu_item_new();
1858
2258
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1859
2259
        
1860
2260
        menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete unused"));
1861
2261
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1862
 
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_delete_unused), &data);
 
2262
        g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_cat_manage_dialog_delete_unused), data);
1863
2263
 
1864
2264
        gtk_widget_show_all (menu);
1865
2265
        
1884
2284
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1885
2285
        gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrollwin), HB_MINHEIGHT_LIST);
1886
2286
        treeview = ui_cat_listview_new(FALSE, TRUE);
1887
 
        data.LV_cat = treeview;
 
2287
        data->LV_cat = treeview;
1888
2288
        gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
1889
2289
        gtk_widget_set_hexpand (scrollwin, TRUE);
1890
2290
        gtk_widget_set_vexpand (scrollwin, TRUE);
1897
2297
        gtk_style_context_add_class (gtk_widget_get_style_context (tbar), GTK_STYLE_CLASS_INLINE_TOOLBAR);
1898
2298
        gtk_box_pack_start (GTK_BOX (vbox), tbar, FALSE, FALSE, 0);
1899
2299
 
1900
 
        /*widget = gtk_tool_item_new ();
1901
 
        label = gtk_label_new("test");
1902
 
        gtk_container_add(GTK_CONTAINER(widget), label);
1903
 
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(widget), -1);*/
1904
 
        
1905
 
        //hbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
1906
 
        /*
1907
 
        hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
2300
        bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1908
2301
        toolitem = gtk_tool_item_new();
1909
 
        gtk_container_add (GTK_CONTAINER(toolitem), hbox);
 
2302
        gtk_container_add (GTK_CONTAINER(toolitem), bbox);
1910
2303
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
1911
 
        
1912
 
                //widget = make_image_button("text-editor-symbolic", _("Edit"));
1913
 
                widget = gtk_button_new_with_mnemonic(_("_Edit"));
1914
 
                data.BT_edit = widget;
1915
 
                gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
1916
 
 
1917
 
                //widget = make_image_button("merge-symbolic", _("Merge"));
1918
 
                widget = gtk_button_new_with_mnemonic(_("_Merge"));
1919
 
                data.BT_merge = widget;
1920
 
                gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
1921
 
        
1922
 
                //widget = make_image_button(ICONNAME_SYM_EDIT_DELETE, _("Delete"));
1923
 
                widget = gtk_button_new_with_mnemonic(_("_Delete"));
1924
 
                data.BT_delete = widget;
1925
 
                gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
1926
 
        */
 
2304
 
 
2305
                widget = make_image_toggle_button(ICONNAME_LIST_ADD, _("Add"));
 
2306
                data->BT_add = widget;
 
2307
                gtk_container_add (GTK_CONTAINER (bbox), widget);
 
2308
        
 
2309
                widget = make_image_button(ICONNAME_LIST_EDIT, _("Edit"));
 
2310
                data->BT_edit = widget;
 
2311
                gtk_container_add (GTK_CONTAINER (bbox), widget);
 
2312
 
 
2313
                widget = make_image_button(ICONNAME_HB_LIST_MERGE, _("Move/Merge"));
 
2314
                data->BT_merge = widget;
 
2315
                gtk_container_add (GTK_CONTAINER (bbox), widget);
 
2316
        
 
2317
                widget = make_image_button(ICONNAME_LIST_DELETE, _("Delete"));
 
2318
                data->BT_delete = widget;
 
2319
                gtk_container_add (GTK_CONTAINER (bbox), widget);
 
2320
        
1927
2321
        
1928
2322
        toolitem = gtk_separator_tool_item_new ();
1929
2323
        gtk_tool_item_set_expand (toolitem, TRUE);
1936
2330
        gtk_toolbar_insert(GTK_TOOLBAR(tbar), GTK_TOOL_ITEM(toolitem), -1);
1937
2331
        
1938
2332
                widget = make_image_button(ICONNAME_HB_BUTTON_EXPAND, _("Expand all"));
1939
 
                data.BT_expand = widget;
 
2333
                data->BT_expand = widget;
1940
2334
                gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
1941
2335
 
1942
2336
                widget = make_image_button(ICONNAME_HB_BUTTON_COLLAPSE, _("Collapse all"));
1943
 
                data.BT_collapse = widget;
 
2337
                data->BT_collapse = widget;
1944
2338
                gtk_box_pack_start (GTK_BOX (hbox), widget, FALSE, FALSE, 0);
1945
2339
 
1946
2340
        // subcategory + add button
1951
2345
        gtk_container_add(GTK_CONTAINER(addreveal), vbox);
1952
2346
 
1953
2347
        widget = gtk_entry_new ();
1954
 
        data.ST_name1 = widget;
1955
 
        gtk_entry_set_placeholder_text(GTK_ENTRY(data.ST_name1), _("new category") );
 
2348
        data->ST_name1 = widget;
 
2349
        gtk_entry_set_placeholder_text(GTK_ENTRY(data->ST_name1), _("new category") );
1956
2350
        gtk_widget_set_hexpand (widget, TRUE);
1957
2351
        gtk_container_add (GTK_CONTAINER (vbox), widget);
1958
2352
        
1959
2353
        row++;
1960
2354
        hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
1961
2355
        gtk_container_add (GTK_CONTAINER (vbox), hbox);
1962
 
        data.LA_category = gtk_label_new(NULL);
1963
 
        gtk_box_pack_start (GTK_BOX (hbox), data.LA_category, FALSE, FALSE, 0);
 
2356
        data->LA_category = gtk_label_new(NULL);
 
2357
        gtk_box_pack_start (GTK_BOX (hbox), data->LA_category, FALSE, FALSE, 0);
1964
2358
        label = gtk_label_new(":");
1965
2359
        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1966
 
        data.ST_name2 = gtk_entry_new ();
1967
 
        gtk_entry_set_placeholder_text(GTK_ENTRY(data.ST_name2), _("new subcategory") );
1968
 
        gtk_box_pack_start (GTK_BOX (hbox), data.ST_name2, TRUE, TRUE, 0);
1969
 
 
1970
 
 
1971
 
        row++;
1972
 
        bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
1973
 
        gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
1974
 
        gtk_box_set_spacing (GTK_BOX (bbox), SPACING_SMALL);
1975
 
        gtk_grid_attach (GTK_GRID (table), bbox, 0, row, 2, 1);
1976
 
 
1977
 
        data.BT_add = gtk_toggle_button_new_with_mnemonic(_("_Add"));
1978
 
        gtk_container_add (GTK_CONTAINER (bbox), data.BT_add);
1979
 
 
1980
 
        //todo: useless ?
1981
 
        data.BT_edit = gtk_button_new_with_mnemonic(_("_Edit"));
1982
 
        gtk_container_add (GTK_CONTAINER (bbox), data.BT_edit);
1983
 
 
1984
 
        data.BT_merge = gtk_button_new_with_mnemonic(_("_Merge"));
1985
 
        gtk_container_add (GTK_CONTAINER (bbox), data.BT_merge);
1986
 
 
1987
 
        data.BT_delete = gtk_button_new_with_mnemonic(_("_Delete"));
1988
 
        gtk_container_add (GTK_CONTAINER (bbox), data.BT_delete);
 
2360
        data->ST_name2 = gtk_entry_new ();
 
2361
        gtk_entry_set_placeholder_text(GTK_ENTRY(data->ST_name2), _("new subcategory") );
 
2362
        gtk_box_pack_start (GTK_BOX (hbox), data->ST_name2, TRUE, TRUE, 0);
 
2363
 
1989
2364
 
1990
2365
        //connect all our signals
1991
 
        g_object_bind_property (data.BT_add, "active", addreveal, "reveal-child", G_BINDING_BIDIRECTIONAL);
1992
 
 
1993
 
        g_signal_connect (G_OBJECT (data.ST_name1), "activate", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(FALSE));
1994
 
        g_signal_connect (G_OBJECT (data.ST_name2), "activate", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(TRUE));
1995
 
 
1996
 
        g_signal_connect(G_OBJECT(data.ST_name1), "insert-text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
1997
 
        g_signal_connect(G_OBJECT(data.ST_name2), "insert-text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
1998
 
 
1999
 
 
2000
 
        g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data.LV_cat)), "changed", G_CALLBACK (ui_cat_manage_dialog_selection), NULL);
2001
 
        g_signal_connect (GTK_TREE_VIEW(data.LV_cat), "row-activated", G_CALLBACK (ui_cat_manage_dialog_onRowActivated), NULL);
2002
 
 
2003
 
        g_signal_connect (G_OBJECT (data.BT_edit), "clicked", G_CALLBACK (ui_cat_manage_dialog_edit), NULL);
2004
 
        g_signal_connect (G_OBJECT (data.BT_merge), "clicked", G_CALLBACK (ui_cat_manage_dialog_merge), NULL);
2005
 
        g_signal_connect (G_OBJECT (data.BT_delete), "clicked", G_CALLBACK (ui_cat_manage_dialog_delete), NULL);
2006
 
 
2007
 
        g_signal_connect (G_OBJECT (data.BT_expand), "clicked", G_CALLBACK (ui_cat_manage_dialog_expand_all), NULL);
2008
 
        g_signal_connect (G_OBJECT (data.BT_collapse), "clicked", G_CALLBACK (ui_cat_manage_dialog_collapse_all), NULL);
 
2366
        g_object_bind_property (data->BT_add, "active", addreveal, "reveal-child", G_BINDING_BIDIRECTIONAL);
 
2367
 
 
2368
        g_signal_connect (G_OBJECT (data->ST_name1), "activate", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(FALSE));
 
2369
        g_signal_connect (G_OBJECT (data->ST_name2), "activate", G_CALLBACK (ui_cat_manage_dialog_add), GINT_TO_POINTER(TRUE));
 
2370
 
 
2371
        g_signal_connect(G_OBJECT(data->ST_name1), "insert-text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
 
2372
        g_signal_connect(G_OBJECT(data->ST_name2), "insert-text", G_CALLBACK(ui_cat_manage_filter_text_handler), NULL);
 
2373
 
 
2374
 
 
2375
        g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_cat)), "changed", G_CALLBACK (ui_cat_manage_dialog_selection), NULL);
 
2376
        g_signal_connect (GTK_TREE_VIEW(data->LV_cat), "row-activated", G_CALLBACK (ui_cat_manage_dialog_onRowActivated), NULL);
 
2377
 
 
2378
        g_signal_connect (G_OBJECT (data->BT_edit), "clicked", G_CALLBACK (ui_cat_manage_dialog_edit), NULL);
 
2379
        g_signal_connect (G_OBJECT (data->BT_merge), "clicked", G_CALLBACK (ui_cat_manage_dialog_merge), NULL);
 
2380
        g_signal_connect (G_OBJECT (data->BT_delete), "clicked", G_CALLBACK (ui_cat_manage_dialog_delete), NULL);
 
2381
 
 
2382
        g_signal_connect (G_OBJECT (data->BT_expand), "clicked", G_CALLBACK (ui_cat_manage_dialog_expand_all), NULL);
 
2383
        g_signal_connect (G_OBJECT (data->BT_collapse), "clicked", G_CALLBACK (ui_cat_manage_dialog_collapse_all), NULL);
2009
2384
 
2010
2385
        //setup, init and show window
2011
2386
        category_fill_usage();
2012
 
        ui_cat_manage_dialog_setup(&data);
2013
 
        ui_cat_manage_dialog_update(data.LV_cat, NULL);
 
2387
        ui_cat_manage_dialog_setup(data);
 
2388
        ui_cat_manage_dialog_update(data->LV_cat, NULL);
2014
2389
 
2015
2390
        gtk_widget_show_all (window);
2016
2391
 
2028
2403
    }
2029
2404
 
2030
2405
        // cleanup and destroy
2031
 
        ui_cat_manage_dialog_cleanup(&data, result);
 
2406
 
 
2407
        GLOBALS->changes_count += data->change;
 
2408
 
 
2409
        ui_cat_manage_dialog_cleanup(data, result);
2032
2410
        gtk_widget_destroy (window);
2033
2411
 
2034
 
        GLOBALS->changes_count += data.change;
 
2412
        g_free(data);
2035
2413
 
2036
2414
        return NULL;
2037
2415
}