]> Dogcows Code - chaz/homebank/blob - src/ui-payee.c
import homebank-5.2.6
[chaz/homebank] / src / ui-payee.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "homebank.h"
22
23 #include "ui-payee.h"
24 #include "ui-category.h"
25
26 #define MYDEBUG 0
27
28 #if MYDEBUG
29 #define DB(x) (x);
30 #else
31 #define DB(x);
32 #endif
33
34 /* our global datas */
35 extern struct HomeBank *GLOBALS;
36 extern struct Preferences *PREFS;
37
38
39 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
40
41
42 /**
43 * ui_pay_comboboxentry_get_key_add_new:
44 *
45 * get the key of the active payee
46 * and create the payee if it do not exists
47 *
48 * Return value: the key or 0
49 *
50 */
51 guint32
52 ui_pay_comboboxentry_get_key_add_new(GtkComboBox *entry_box)
53 {
54 gchar *name;
55 Payee *item;
56
57 name = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
58 item = da_pay_get_by_name(name);
59 if( item == NULL )
60 {
61 /* automatic add */
62 //todo: check prefs + ask the user here 1st time
63 item = da_pay_malloc();
64 item->name = g_strdup(name);
65 da_pay_append(item);
66 ui_pay_comboboxentry_add(entry_box, item);
67 }
68
69 return item->key;
70 }
71
72 /**
73 * ui_pay_comboboxentry_get_key:
74 *
75 * get the key of the active payee
76 *
77 * Return value: the key or 0
78 *
79 */
80 guint32
81 ui_pay_comboboxentry_get_key(GtkComboBox *entry_box)
82 {
83 gchar *name;
84 Payee *item;
85
86 name = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
87 item = da_pay_get_by_name(name);
88
89 if( item != NULL )
90 return item->key;
91
92 return 0;
93 }
94
95
96 Payee
97 *ui_pay_comboboxentry_get(GtkComboBox *entry_box)
98 {
99 gchar *name;
100 Payee *item = NULL;
101
102 DB( g_print ("ui_pay_comboboxentry_get()\n") );
103
104 name = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
105 item = da_pay_get_by_name(name);
106
107 return item;
108 }
109
110
111 gboolean
112 ui_pay_comboboxentry_set_active(GtkComboBox *entry_box, guint32 key)
113 {
114 Payee *item;
115
116 DB( g_print ("ui_pay_comboboxentry_set_active()\n") );
117
118 DB( g_print("- key:%d\n", key) );
119
120 if( key > 0 )
121 {
122 item = da_pay_get(key);
123 if( item != NULL )
124 {
125 DB( g_print("- set combo to '%s'\n", item->name) );
126
127 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))), item->name);
128 return TRUE;
129 }
130 }
131
132 DB( g_print("- set combo to ''\n") );
133
134 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))), "");
135 return FALSE;
136 }
137
138 /**
139 * ui_pay_comboboxentry_add:
140 *
141 * Add a single element (useful for dynamics add)
142 *
143 * Return value: --
144 *
145 */
146 void
147 ui_pay_comboboxentry_add(GtkComboBox *entry_box, Payee *pay)
148 {
149 if( pay->name != NULL )
150 {
151 GtkTreeModel *model;
152 GtkTreeIter iter;
153
154 model = gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box));
155
156 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
157 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, pay->name, -1);
158 }
159 }
160
161 static void
162 ui_pay_comboboxentry_populate_ghfunc(gpointer key, gpointer value, struct payPopContext *ctx)
163 {
164 GtkTreeIter iter;
165 Payee *pay = value;
166
167 if( ( pay->key != ctx->except_key ) )
168 {
169 //gtk_list_store_append (GTK_LIST_STORE(ctx->model), &iter);
170 //gtk_list_store_set (GTK_LIST_STORE(ctx->model), &iter, 0, pay->name, -1);
171 gtk_list_store_insert_with_values(GTK_LIST_STORE(ctx->model), &iter, -1,
172 0, pay->name, -1);
173 }
174 }
175
176 /**
177 * ui_pay_comboboxentry_populate:
178 *
179 * Populate the list and completion
180 *
181 * Return value: --
182 *
183 */
184 void
185 ui_pay_comboboxentry_populate(GtkComboBox *entry_box, GHashTable *hash)
186 {
187 ui_pay_comboboxentry_populate_except(entry_box, hash, -1);
188 }
189
190 void
191 ui_pay_comboboxentry_populate_except(GtkComboBox *entry_box, GHashTable *hash, guint except_key)
192 {
193 GtkTreeModel *model;
194 //GtkEntryCompletion *completion;
195 struct payPopContext ctx;
196
197 DB( g_print ("ui_pay_comboboxentry_populate\n") );
198
199 model = gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box));
200 //completion = gtk_entry_get_completion(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
201
202 /* keep our model alive and detach from comboboxentry and completion */
203 //g_object_ref(model);
204 //gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), NULL);
205 //gtk_entry_completion_set_model (completion, NULL);
206
207 /* clear and populate */
208 ctx.model = model;
209 ctx.except_key = except_key;
210 gtk_list_store_clear (GTK_LIST_STORE(model));
211
212 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GTK_LIST_STORE(model)), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
213
214 g_hash_table_foreach(hash, (GHFunc)ui_pay_comboboxentry_populate_ghfunc, &ctx);
215
216 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
217
218 /* reatach our model */
219 //g_print("reattach\n");
220 //gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), model);
221 //gtk_entry_completion_set_model (completion, model);
222 //g_object_unref(model);
223
224 }
225
226
227 static gint
228 ui_pay_comboboxentry_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
229 {
230 gint retval = 0;
231 gchar *name1, *name2;
232
233 gtk_tree_model_get(model, a, 0, &name1, -1);
234 gtk_tree_model_get(model, b, 0, &name2, -1);
235
236 retval = hb_string_utf8_compare(name1, name2);
237
238 g_free(name2);
239 g_free(name1);
240
241 return retval;
242 }
243
244
245 static void
246 ui_pay_comboboxentry_test (GtkCellLayout *cell_layout,
247 GtkCellRenderer *cell,
248 GtkTreeModel *tree_model,
249 GtkTreeIter *iter,
250 gpointer data)
251 {
252 gchar *name;
253
254 gtk_tree_model_get(tree_model, iter,
255 0, &name,
256 -1);
257
258 if( !name )
259 g_object_set(cell, "text", _("(no payee)"), NULL);
260 else
261 g_object_set(cell, "text", name, NULL);
262
263 //leak
264 g_free(name);
265
266 }
267
268 /**
269 * ui_pay_comboboxentry_new:
270 *
271 * Create a new payee comboboxentry
272 *
273 * Return value: the new widget
274 *
275 */
276 GtkWidget *
277 ui_pay_comboboxentry_new(GtkWidget *label)
278 {
279 GtkListStore *store;
280 GtkWidget *comboboxentry;
281 GtkEntryCompletion *completion;
282 GtkCellRenderer *renderer;
283
284 DB( g_print ("ui_pay_comboboxentry_new()\n") );
285
286 store = gtk_list_store_new (1,
287 G_TYPE_STRING
288 );
289 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_pay_comboboxentry_compare_func, NULL, NULL);
290
291 completion = gtk_entry_completion_new ();
292 gtk_entry_completion_set_model (completion, GTK_TREE_MODEL(store));
293 g_object_set(completion, "text-column", 0, NULL);
294
295 renderer = gtk_cell_renderer_text_new ();
296 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
297 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), renderer, "text", 0, NULL);
298
299 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion),
300 renderer,
301 ui_pay_comboboxentry_test,
302 NULL, NULL);
303
304 // dothe same for combobox
305
306 comboboxentry = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store));
307 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboboxentry), 0);
308
309 gtk_cell_layout_clear(GTK_CELL_LAYOUT (comboboxentry));
310
311 renderer = gtk_cell_renderer_text_new ();
312 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comboboxentry), renderer, TRUE);
313 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comboboxentry), renderer, "text", 0, NULL);
314
315 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (comboboxentry),
316 renderer,
317 ui_pay_comboboxentry_test,
318 NULL, NULL);
319
320
321
322 gtk_entry_set_completion (GTK_ENTRY (gtk_bin_get_child(GTK_BIN (comboboxentry))), completion);
323
324 g_object_unref(store);
325
326 if(label)
327 gtk_label_set_mnemonic_widget (GTK_LABEL(label), comboboxentry);
328
329 gtk_widget_set_size_request(comboboxentry, HB_MINWIDTH_LIST, -1);
330
331 return comboboxentry;
332 }
333
334
335 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
336
337 static void
338 ui_pay_listview_toggled_cb (GtkCellRendererToggle *cell,
339 gchar *path_str,
340 gpointer data)
341 {
342 GtkTreeModel *model = (GtkTreeModel *)data;
343 GtkTreeIter iter;
344 GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
345 gboolean fixed;
346
347 /* get toggled iter */
348 gtk_tree_model_get_iter (model, &iter, path);
349 gtk_tree_model_get (model, &iter, LST_DEFPAY_TOGGLE, &fixed, -1);
350
351 /* do something with the value */
352 fixed ^= 1;
353
354 /* set new value */
355 gtk_list_store_set (GTK_LIST_STORE (model), &iter, LST_DEFPAY_TOGGLE, fixed, -1);
356
357 /* clean up */
358 gtk_tree_path_free (path);
359 }
360
361
362 static gint
363 ui_pay_listview_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
364 {
365 gint sortcol = GPOINTER_TO_INT(userdata);
366 Payee *entry1, *entry2;
367 gint retval = 0;
368
369 gtk_tree_model_get(model, a, LST_DEFPAY_DATAS, &entry1, -1);
370 gtk_tree_model_get(model, b, LST_DEFPAY_DATAS, &entry2, -1);
371
372 switch (sortcol)
373 {
374 case LST_DEFPAY_SORT_NAME:
375 retval = hb_string_utf8_compare(entry1->name, entry2->name);
376 break;
377 case LST_DEFPAY_SORT_USED:
378 retval = entry1->usage_count - entry2->usage_count;
379 break;
380 case LST_DEFPAY_SORT_DEFCAT:
381 {
382 Category *c1, *c2;
383
384 c1 = da_cat_get(entry1->kcat);
385 c2 = da_cat_get(entry2->kcat);
386 if( c1 != NULL && c2 != NULL )
387 {
388 retval = hb_string_utf8_compare(c1->fullname, c2->fullname);
389 }
390 }
391 break;
392 default:
393 g_return_val_if_reached(0);
394 }
395
396 return retval;
397 }
398
399
400 static void
401 ui_pay_listview_count_cell_data_function (GtkTreeViewColumn *col,
402 GtkCellRenderer *renderer,
403 GtkTreeModel *model,
404 GtkTreeIter *iter,
405 gpointer user_data)
406 {
407 Payee *entry;
408 gchar buffer[256];
409
410 gtk_tree_model_get(model, iter, LST_DEFPAY_DATAS, &entry, -1);
411 if(entry->usage_count > 0)
412 {
413 g_snprintf(buffer, 256-1, "%d", entry->usage_count);
414 g_object_set(renderer, "text", buffer, NULL);
415 }
416 else
417 g_object_set(renderer, "text", "", NULL);
418 }
419
420
421 static void
422 ui_pay_listview_defcat_cell_data_function (GtkTreeViewColumn *col,
423 GtkCellRenderer *renderer,
424 GtkTreeModel *model,
425 GtkTreeIter *iter,
426 gpointer user_data)
427 {
428 Payee *entry;
429 Category *cat;
430
431 gtk_tree_model_get(model, iter, LST_DEFPAY_DATAS, &entry, -1);
432
433 cat = da_cat_get(entry->kcat);
434 if( cat != NULL )
435 {
436 g_object_set(renderer, "text", cat->fullname, NULL);
437 }
438 else
439 g_object_set(renderer, "text", "", NULL);
440 }
441
442
443 static void
444 ui_pay_listview_name_cell_data_function (GtkTreeViewColumn *col,
445 GtkCellRenderer *renderer,
446 GtkTreeModel *model,
447 GtkTreeIter *iter,
448 gpointer user_data)
449 {
450 Payee *entry;
451 gchar *name;
452 #if MYDEBUG
453 gchar *string;
454 #endif
455
456 gtk_tree_model_get(model, iter, LST_DEFPAY_DATAS, &entry, -1);
457
458 if(entry->key == 0)
459 name = _("(no payee)");
460 else
461 name = entry->name;
462
463 #if MYDEBUG
464 string = g_strdup_printf ("%d > %s [ft=%d]", entry->key, name, entry->flt_select);
465 g_object_set(renderer, "text", string, NULL);
466 g_free(string);
467 #else
468 g_object_set(renderer, "text", name, NULL);
469 #endif
470
471 }
472
473
474 /* = = = = = = = = = = = = = = = = */
475
476
477 void
478 ui_pay_listview_add(GtkTreeView *treeview, Payee *item)
479 {
480 GtkTreeModel *model;
481 GtkTreeIter iter;
482
483 if( item->name != NULL )
484 {
485 model = gtk_tree_view_get_model(treeview);
486
487 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
488 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
489 LST_DEFPAY_TOGGLE, FALSE,
490 LST_DEFPAY_DATAS, item,
491 -1);
492 }
493 }
494
495 guint32
496 ui_pay_listview_get_selected_key(GtkTreeView *treeview)
497 {
498 GtkTreeSelection *selection;
499 GtkTreeModel *model;
500 GtkTreeIter iter;
501
502 selection = gtk_tree_view_get_selection(treeview);
503 if (gtk_tree_selection_get_selected(selection, &model, &iter))
504 {
505 Payee *item;
506
507 gtk_tree_model_get(model, &iter, LST_DEFPAY_DATAS, &item, -1);
508
509 if( item!= NULL )
510 return item->key;
511 }
512 return 0;
513 }
514
515 void
516 ui_pay_listview_remove_selected(GtkTreeView *treeview)
517 {
518 GtkTreeSelection *selection;
519 GtkTreeModel *model;
520 GtkTreeIter iter;
521
522 DB( g_print("ui_pay_listview_remove_selected() \n") );
523
524 selection = gtk_tree_view_get_selection(treeview);
525 if (gtk_tree_selection_get_selected(selection, &model, &iter))
526 {
527 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
528 }
529 }
530
531
532 struct PayListContext {
533 GtkTreeModel *model;
534 gchar *needle;
535 };
536
537
538 static void ui_pay_listview_populate_ghfunc(gpointer key, gpointer value, struct PayListContext *context)
539 {
540 GtkTreeIter iter;
541 Payee *item = value;
542 gboolean hastext = FALSE;
543 gboolean insert = TRUE;
544
545 //DB( g_print(" populate: %p\n", key) );
546 if( context->needle != NULL )
547 hastext = (strlen(context->needle) >= 2) ? TRUE : FALSE;
548
549 if(hastext)
550 {
551 insert = hb_string_utf8_strstr(item->name, context->needle, FALSE);
552 }
553
554 if( insert == TRUE)
555 {
556 gtk_list_store_insert_with_values(GTK_LIST_STORE(context->model), &iter, -1,
557 LST_DEFPAY_TOGGLE , FALSE,
558 LST_DEFPAY_DATAS, item,
559 -1);
560 }
561
562 }
563
564
565 void ui_pay_listview_populate(GtkWidget *treeview, gchar *needle)
566 {
567 struct PayListContext context;
568
569 DB( g_print("ui_pay_listview_populate \n") );
570
571 context.model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
572 context.needle = needle;
573
574 gtk_list_store_clear (GTK_LIST_STORE(context.model));
575
576 //g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
577 //gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); /* Detach model from view */
578
579 /* populate */
580 g_hash_table_foreach(GLOBALS->h_pay, (GHFunc)ui_pay_listview_populate_ghfunc, &context);
581
582 //gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); /* Re-attach model to view */
583 //g_object_unref(model);
584 }
585
586
587 static gboolean ui_pay_listview_search_equal_func (GtkTreeModel *model,
588 gint column,
589 const gchar *key,
590 GtkTreeIter *iter,
591 gpointer search_data)
592 {
593 gboolean retval = TRUE;
594 gchar *normalized_string;
595 gchar *normalized_key;
596 gchar *case_normalized_string = NULL;
597 gchar *case_normalized_key = NULL;
598 Payee *item;
599
600 //gtk_tree_model_get_value (model, iter, column, &value);
601 gtk_tree_model_get(model, iter, LST_DEFPAY_DATAS, &item, -1);
602
603 if(item != NULL)
604 {
605 normalized_string = g_utf8_normalize (item->name, -1, G_NORMALIZE_ALL);
606 normalized_key = g_utf8_normalize (key, -1, G_NORMALIZE_ALL);
607
608 if (normalized_string && normalized_key)
609 {
610 case_normalized_string = g_utf8_casefold (normalized_string, -1);
611 case_normalized_key = g_utf8_casefold (normalized_key, -1);
612
613 if (strncmp (case_normalized_key, case_normalized_string, strlen (case_normalized_key)) == 0)
614 retval = FALSE;
615 }
616
617 g_free (normalized_key);
618 g_free (normalized_string);
619 g_free (case_normalized_key);
620 g_free (case_normalized_string);
621 }
622 return retval;
623 }
624
625
626 GtkWidget *
627 ui_pay_listview_new(gboolean withtoggle, gboolean withcount)
628 {
629 GtkListStore *store;
630 GtkWidget *treeview;
631 GtkCellRenderer *renderer;
632 GtkTreeViewColumn *column;
633
634 DB( g_print("ui_pay_listview_new() \n") );
635
636 store = gtk_list_store_new(
637 NUM_LST_DEFPAY,
638 G_TYPE_BOOLEAN,
639 G_TYPE_POINTER
640 );
641
642 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
643 g_object_unref(store);
644
645 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines);
646
647 // column: toggle
648 if( withtoggle == TRUE )
649 {
650 renderer = gtk_cell_renderer_toggle_new ();
651 column = gtk_tree_view_column_new_with_attributes (_("Visible"),
652 renderer, "active", LST_DEFPAY_TOGGLE, NULL);
653 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
654
655 g_signal_connect (G_OBJECT(renderer), "toggled",
656 G_CALLBACK (ui_pay_listview_toggled_cb), store);
657
658 }
659
660 // column: name
661 renderer = gtk_cell_renderer_text_new ();
662 g_object_set(renderer,
663 "ellipsize", PANGO_ELLIPSIZE_END,
664 "ellipsize-set", TRUE,
665 NULL);
666
667 column = gtk_tree_view_column_new();
668 gtk_tree_view_column_set_title(column, _("Name"));
669 gtk_tree_view_column_pack_start(column, renderer, TRUE);
670 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_pay_listview_name_cell_data_function, GINT_TO_POINTER(LST_DEFPAY_DATAS), NULL);
671 gtk_tree_view_column_set_alignment (column, 0.5);
672 gtk_tree_view_column_set_min_width(column, HB_MINWIDTH_LIST);
673 gtk_tree_view_column_set_sort_column_id (column, LST_DEFPAY_SORT_NAME);
674 gtk_tree_view_column_set_resizable(column, TRUE);
675 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
676
677 // column: usage
678 if( withcount == TRUE )
679 {
680 renderer = gtk_cell_renderer_text_new ();
681 g_object_set(renderer, "xalign", 0.5, NULL);
682
683 column = gtk_tree_view_column_new();
684 gtk_tree_view_column_set_title(column, _("Usage"));
685 gtk_tree_view_column_pack_start(column, renderer, TRUE);
686 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_pay_listview_count_cell_data_function, GINT_TO_POINTER(LST_DEFPAY_DATAS), NULL);
687 gtk_tree_view_column_set_alignment (column, 0.5);
688 gtk_tree_view_column_set_sort_column_id (column, LST_DEFPAY_SORT_USED);
689 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
690 }
691
692 // column: category
693 if( withtoggle == FALSE )
694 {
695 renderer = gtk_cell_renderer_text_new ();
696 g_object_set(renderer,
697 "ellipsize", PANGO_ELLIPSIZE_END,
698 "ellipsize-set", TRUE,
699 NULL);
700
701 column = gtk_tree_view_column_new();
702 gtk_tree_view_column_set_title(column, _("Default category"));
703 gtk_tree_view_column_pack_start(column, renderer, TRUE);
704 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_pay_listview_defcat_cell_data_function, GINT_TO_POINTER(LST_DEFPAY_DATAS), NULL);
705 gtk_tree_view_column_set_alignment (column, 0.5);
706 gtk_tree_view_column_set_sort_column_id (column, LST_DEFPAY_SORT_DEFCAT);
707 gtk_tree_view_column_set_resizable(column, TRUE);
708 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
709 }
710
711 gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(treeview), ui_pay_listview_search_equal_func, NULL, NULL);
712
713 // treeview attribute
714 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), withcount);
715
716 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFPAY_SORT_NAME, ui_pay_listview_compare_func, GINT_TO_POINTER(LST_DEFPAY_SORT_NAME), NULL);
717 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFPAY_SORT_USED, ui_pay_listview_compare_func, GINT_TO_POINTER(LST_DEFPAY_SORT_USED), NULL);
718 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFPAY_SORT_DEFCAT, ui_pay_listview_compare_func, GINT_TO_POINTER(LST_DEFPAY_SORT_DEFCAT), NULL);
719
720 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), LST_DEFPAY_SORT_NAME, GTK_SORT_ASCENDING);
721
722 return treeview;
723 }
724
725
726 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
727
728 static void
729 ui_pay_manage_dialog_delete_unused( GtkWidget *widget, gpointer user_data)
730 {
731 struct ui_pay_manage_dialog_data *data = user_data;
732 gboolean result;
733
734 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
735
736 DB( g_print("(ui_pay_manage_dialog) delete unused - data %p\n", data) );
737
738 result = ui_dialog_msg_confirm_alert(
739 GTK_WINDOW(data->window),
740 _("Delete unused payee"),
741 _("Are you sure you want to\npermanently delete unused payee?"),
742 _("_Delete")
743 );
744
745 if( result == GTK_RESPONSE_OK )
746 {
747 GtkTreeModel *model;
748
749 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_pay));
750 gtk_list_store_clear (GTK_LIST_STORE(model));
751
752 payee_delete_unused();
753
754 ui_pay_listview_populate (data->LV_pay, NULL);
755 }
756 }
757
758
759 /**
760 * ui_pay_manage_dialog_load_csv:
761 *
762 */
763 static void
764 ui_pay_manage_dialog_load_csv( GtkWidget *widget, gpointer user_data)
765 {
766 struct ui_pay_manage_dialog_data *data = user_data;
767 gchar *filename = NULL;
768 gchar *error;
769
770 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
771
772 DB( g_print("(ui_pay_manage_dialog) load csv - data %p\n", data) );
773
774 if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_OPEN, &filename, NULL) == TRUE )
775 {
776 DB( g_print(" + filename is %s\n", filename) );
777
778 if( !payee_load_csv(filename, &error) )
779 {
780 ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_ERROR,
781 _("File format error"),
782 _("The CSV file must contains the exact numbers of column,\nseparated by a semi-colon, please see the help for more details.")
783 );
784 }
785
786 g_free( filename );
787 ui_pay_listview_populate(data->LV_pay, NULL);
788 }
789 }
790
791 /**
792 * ui_pay_manage_dialog_save_csv:
793 *
794 */
795 static void
796 ui_pay_manage_dialog_save_csv( GtkWidget *widget, gpointer user_data)
797 {
798 struct ui_pay_manage_dialog_data *data = user_data;
799 gchar *filename = NULL;
800
801 DB( g_print("(ui_pay_manage_dialog) save csv\n") );
802
803 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
804
805 if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, NULL) == TRUE )
806 {
807 DB( g_print(" + filename is %s\n", filename) );
808
809 payee_save_csv(filename);
810 g_free( filename );
811 }
812 }
813
814
815 /**
816 * ui_pay_manage_dialog_add:
817 *
818 */
819 static void
820 ui_pay_manage_dialog_add(GtkWidget *widget, gpointer user_data)
821 {
822 struct ui_pay_manage_dialog_data *data;
823 Payee *item;
824 gchar *name;
825
826 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
827 DB( g_print("(defayee) add (data=%p)\n", data) );
828
829 name = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_name));
830
831 item = da_pay_malloc ();
832 item->name = g_strdup(name);
833
834 g_strstrip(item->name);
835
836 if( strlen(item->name) > 0 )
837 {
838 if( da_pay_append(item) )
839 {
840 ui_pay_listview_add(GTK_TREE_VIEW(data->LV_pay), item);
841 data->change++;
842 }
843 }
844 else
845 da_pay_free (item);
846
847 gtk_entry_set_text(GTK_ENTRY(data->ST_name), "");
848 }
849
850
851 static void ui_pay_manage_dialog_edit_entry_cb(GtkEditable *editable, gpointer user_data)
852 {
853 GtkDialog *window = user_data;
854 const gchar *buffer;
855
856 buffer = gtk_entry_get_text(GTK_ENTRY(editable));
857 gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT, strlen(buffer) > 0 ? TRUE : FALSE);
858 }
859
860
861 static void ui_pay_manage_dialog_edit(GtkWidget *dowidget, gpointer user_data)
862 {
863 struct ui_pay_manage_dialog_data *data;
864 GtkWidget *dialog, *content_area, *content_grid, *group_grid;
865 GtkWidget *label, *widget;
866 GtkWidget *ST_name, *PO_cat, *NU_mode;
867 gint crow, row;
868 guint32 key;
869
870 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(dowidget, GTK_TYPE_WINDOW)), "inst_data");
871 DB( g_print("(defayee) modify %p\n", data) );
872
873 key = ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data->LV_pay));
874 if( key > 0 )
875 {
876 Payee *item;
877
878 item = da_pay_get( key );
879
880 dialog = gtk_dialog_new_with_buttons (_("Edit..."),
881 GTK_WINDOW (data->window),
882 0,
883 _("_Cancel"),
884 GTK_RESPONSE_REJECT,
885 _("_OK"),
886 GTK_RESPONSE_ACCEPT,
887 NULL);
888
889 content_area = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
890
891 content_grid = gtk_grid_new();
892 gtk_grid_set_row_spacing (GTK_GRID (content_grid), SPACING_LARGE);
893 gtk_orientable_set_orientation(GTK_ORIENTABLE(content_grid), GTK_ORIENTATION_VERTICAL);
894 gtk_container_set_border_width (GTK_CONTAINER(content_grid), SPACING_MEDIUM);
895 gtk_box_pack_start (GTK_BOX (content_area), content_grid, TRUE, TRUE, 0);
896
897 crow = 0;
898 // group :: General
899 group_grid = gtk_grid_new ();
900 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
901 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
902 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
903
904 //label = make_label_group(_("General"));
905 //gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 3, 1);
906
907 row = 1;
908 label = make_label_widget(_("_Name:"));
909 gtk_grid_attach (GTK_GRID (group_grid), label, 1, row, 1, 1);
910 widget = gtk_entry_new();
911 ST_name = widget;
912 gtk_widget_set_hexpand(widget, TRUE);
913 gtk_grid_attach (GTK_GRID (group_grid), widget, 2, row, 1, 1);
914
915 // group :: Default
916 group_grid = gtk_grid_new ();
917 gtk_grid_set_row_spacing (GTK_GRID (group_grid), SPACING_SMALL);
918 gtk_grid_set_column_spacing (GTK_GRID (group_grid), SPACING_MEDIUM);
919 gtk_grid_attach (GTK_GRID (content_grid), group_grid, 0, crow++, 1, 1);
920
921 label = make_label_group(_("Default"));
922 gtk_grid_attach (GTK_GRID (group_grid), label, 0, 0, 4, 1);
923
924 row = 1;
925 label = make_label_widget(_("_Category:"));
926 gtk_grid_attach (GTK_GRID (group_grid), label, 0, row, 1, 1);
927 widget = ui_cat_comboboxentry_new(label);
928 PO_cat = widget;
929 gtk_widget_set_hexpand (widget, TRUE);
930 gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 1, 1);
931
932 row++;
933 label = make_label_widget(_("Pa_yment:"));
934 gtk_grid_attach (GTK_GRID (group_grid), label, 0, row, 1, 1);
935 //5.2.4 we drop internal xfer here as it will disapear
936 //widget = make_paymode_nointxfer(label);
937 widget = make_paymode_nointxfer(label);
938 NU_mode = widget;
939 gtk_grid_attach (GTK_GRID (group_grid), widget, 1, row, 1, 1);
940
941 //setup
942 gtk_entry_set_text(GTK_ENTRY(ST_name), item->name);
943 gtk_widget_grab_focus (ST_name);
944 gtk_entry_set_activates_default (GTK_ENTRY(ST_name), TRUE);
945
946 ui_cat_comboboxentry_populate(GTK_COMBO_BOX(PO_cat), GLOBALS->h_cat);
947 ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(PO_cat), item->kcat);
948
949 gtk_combo_box_set_active(GTK_COMBO_BOX(NU_mode), item->paymode);
950
951 g_signal_connect (G_OBJECT (ST_name), "changed", G_CALLBACK (ui_pay_manage_dialog_edit_entry_cb), dialog);
952
953 gtk_widget_show_all(content_grid);
954
955
956 gtk_dialog_set_default_response(GTK_DIALOG( dialog ), GTK_RESPONSE_ACCEPT);
957
958 //wait for the user
959 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
960
961 if(result == GTK_RESPONSE_ACCEPT)
962 {
963 const gchar *name;
964
965 // 1: manage renaming
966 name = gtk_entry_get_text(GTK_ENTRY(ST_name));
967 // ignore if item is empty
968 if (name && *name)
969 {
970 if( payee_rename(item, name) )
971 {
972 //to redraw the active entry
973 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_pay));
974 data->change++;
975 }
976 else
977 {
978 ui_dialog_msg_infoerror(GTK_WINDOW(dialog), GTK_MESSAGE_ERROR,
979 _("Error"),
980 _("Cannot rename this Payee,\n"
981 "from '%s' to '%s',\n"
982 "this name already exists."),
983 item->name,
984 name
985 );
986
987 }
988 }
989
990 item->kcat = ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(PO_cat));
991 item->paymode = gtk_combo_box_get_active(GTK_COMBO_BOX(NU_mode));
992
993 }
994
995 // cleanup and destroy
996 gtk_widget_destroy (dialog);
997 }
998
999 }
1000
1001
1002 static void ui_pay_manage_dialog_merge_entry_cb(GtkComboBox *widget, gpointer user_data)
1003 {
1004 GtkDialog *window = user_data;
1005 gchar *buffer;
1006
1007 buffer = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (widget))));
1008 gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_OK, strlen(buffer) > 0 ? TRUE : FALSE);
1009 }
1010
1011
1012 static void ui_pay_manage_dialog_merge(GtkWidget *widget, gpointer user_data)
1013 {
1014 struct ui_pay_manage_dialog_data *data;
1015 GtkWidget *dialog, *content, *mainvbox;
1016 GtkWidget *getwidget, *togglebutton;
1017 GtkTreeSelection *selection;
1018 GtkTreeModel *model;
1019 GtkTreeIter iter;
1020
1021 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1022 DB( g_print("(defayee) merge %p\n", data) );
1023
1024 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_pay));
1025 //if true there is a selected node
1026 if (gtk_tree_selection_get_selected(selection, &model, &iter))
1027 {
1028 Payee *srcpay;
1029 gchar *title;
1030 gchar *secondtext;
1031
1032 gtk_tree_model_get(model, &iter, LST_DEFPAY_DATAS, &srcpay, -1);
1033
1034 title = g_strdup_printf (
1035 _("Merge payee '%s'"), srcpay->name);
1036
1037 dialog = gtk_message_dialog_new (GTK_WINDOW (data->window),
1038 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1039 GTK_MESSAGE_WARNING,
1040 GTK_BUTTONS_NONE,
1041 title,
1042 NULL
1043 );
1044
1045 gtk_dialog_add_buttons (GTK_DIALOG(dialog),
1046 _("_Cancel"), GTK_RESPONSE_CANCEL,
1047 _("Merge"), GTK_RESPONSE_OK,
1048 NULL);
1049
1050 gtk_dialog_set_default_response(GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
1051
1052 content = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG (dialog));
1053 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
1054 gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
1055
1056 secondtext = _("Transactions assigned to this payee,\n"
1057 "will be moved to the payee selected below.");
1058
1059 g_object_set(GTK_MESSAGE_DIALOG (dialog), "secondary-text", secondtext, NULL);
1060 g_free(title);
1061
1062 getwidget = ui_pay_comboboxentry_new(NULL);
1063 gtk_box_pack_start (GTK_BOX (mainvbox), getwidget, FALSE, FALSE, 0);
1064
1065 secondtext = g_strdup_printf (
1066 _("_Delete the payee '%s'"), srcpay->name);
1067 togglebutton = gtk_check_button_new_with_mnemonic(secondtext);
1068 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(togglebutton), TRUE);
1069 g_free(secondtext);
1070 gtk_box_pack_start (GTK_BOX (mainvbox), togglebutton, FALSE, FALSE, 0);
1071
1072 //setup
1073 //gtk_combo_box_set_active(GTK_COMBO_BOX(getwidget), oldpos);
1074 g_signal_connect (G_OBJECT (getwidget), "changed", G_CALLBACK (ui_pay_manage_dialog_merge_entry_cb), dialog);
1075 gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK, FALSE);
1076
1077 ui_pay_comboboxentry_populate_except(GTK_COMBO_BOX(getwidget), GLOBALS->h_pay, srcpay->key);
1078 gtk_widget_grab_focus (getwidget);
1079
1080 gtk_widget_show_all(mainvbox);
1081
1082 //wait for the user
1083 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1084
1085 if(result == GTK_RESPONSE_OK)
1086 {
1087 GtkTreeModel *model;
1088 Payee *newpay;
1089 guint dstpaykey;
1090
1091 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_pay));
1092 gtk_list_store_clear (GTK_LIST_STORE(model));
1093
1094 dstpaykey = ui_pay_comboboxentry_get_key_add_new(GTK_COMBO_BOX(getwidget));
1095
1096 payee_move(srcpay->key, dstpaykey);
1097
1098 newpay = da_pay_get(dstpaykey);
1099
1100 //#1771720: update count
1101 newpay->usage_count += srcpay->usage_count;
1102 srcpay->usage_count = 0;
1103
1104 // add the new payee to listview
1105 if(newpay)
1106 ui_pay_listview_add(GTK_TREE_VIEW(data->LV_pay), newpay);
1107
1108 // delete the old payee
1109 if( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)) )
1110 {
1111 DB( g_print(" -> delete %d '%s'\n", srcpay->key, srcpay->name ) );
1112
1113 da_pay_remove(srcpay->key);
1114 ui_pay_listview_remove_selected(GTK_TREE_VIEW(data->LV_pay));
1115 }
1116
1117
1118 data->change++;
1119
1120 ui_pay_listview_populate(data->LV_pay, NULL);
1121 }
1122
1123 // cleanup and destroy
1124 gtk_widget_destroy (dialog);
1125 }
1126
1127 }
1128
1129
1130 /*
1131 ** delete the selected payee to our treeview and temp GList
1132 */
1133 static void ui_pay_manage_dialog_delete(GtkWidget *widget, gpointer user_data)
1134 {
1135 struct ui_pay_manage_dialog_data *data;
1136 Payee *item;
1137 guint32 key;
1138 gint result;
1139
1140
1141 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1142 DB( g_print("(ui_pay_manage_dialog) delete (data=%p)\n", data) );
1143
1144 key = ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data->LV_pay));
1145 if( key > 0 )
1146 {
1147 gchar *title;
1148 gchar *secondtext = NULL;
1149
1150 item = da_pay_get(key);
1151
1152 title = g_strdup_printf (
1153 _("Are you sure you want to permanently delete '%s'?"), item->name);
1154
1155 if( item->usage_count > 0 )
1156 {
1157 secondtext = _("This payee is used.\n"
1158 "Any transaction using that payee will be set to (no payee)");
1159 }
1160
1161 result = ui_dialog_msg_confirm_alert(
1162 GTK_WINDOW(data->window),
1163 title,
1164 secondtext,
1165 _("_Delete")
1166 );
1167
1168 g_free(title);
1169
1170 if( result == GTK_RESPONSE_OK )
1171 {
1172 payee_move(key, 0);
1173 ui_pay_listview_remove_selected(GTK_TREE_VIEW(data->LV_pay));
1174 da_pay_remove(key);
1175 data->change++;
1176 }
1177
1178 }
1179 }
1180
1181
1182 static void ui_pay_manage_dialog_update(GtkWidget *treeview, gpointer user_data)
1183 {
1184 struct ui_pay_manage_dialog_data *data;
1185 gboolean sensitive;
1186 guint32 key;
1187
1188 DB( g_print("\n(ui_pay_manage_dialog) cursor changed\n") );
1189
1190 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW)), "inst_data");
1191
1192 key = ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data->LV_pay));
1193
1194 sensitive = (key > 0) ? TRUE : FALSE;
1195 gtk_widget_set_sensitive(data->BT_edit, sensitive);
1196 gtk_widget_set_sensitive(data->BT_merge, sensitive);
1197 gtk_widget_set_sensitive(data->BT_delete, sensitive);
1198
1199 }
1200
1201
1202 /*
1203 **
1204 */
1205 static void ui_pay_manage_dialog_selection(GtkTreeSelection *treeselection, gpointer user_data)
1206 {
1207 ui_pay_manage_dialog_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), NULL);
1208 }
1209
1210 static void ui_pay_manage_dialog_onRowActivated (GtkTreeView *treeview,
1211 GtkTreePath *path,
1212 GtkTreeViewColumn *col,
1213 gpointer user_data)
1214 {
1215 GtkTreeModel *model;
1216 GtkTreeIter iter;
1217
1218 DB( g_print("ui_pay_manage_dialog_onRowActivated()\n") );
1219
1220
1221 model = gtk_tree_view_get_model(treeview);
1222 gtk_tree_model_get_iter_first(model, &iter);
1223 if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter) == FALSE)
1224 {
1225 ui_pay_manage_dialog_edit(GTK_WIDGET(treeview), NULL);
1226 }
1227 }
1228
1229
1230 static void
1231 ui_pay_manage_search_changed_cb (GtkWidget *widget, gpointer user_data)
1232 {
1233 struct ui_pay_manage_dialog_data *data = user_data;
1234 gchar *needle;
1235
1236 DB( g_printf("\n[ui_pay_manage_dialog] search_changed_cb\n") );
1237
1238 needle = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_search));
1239 ui_pay_listview_populate(data->LV_pay, needle);
1240 }
1241
1242
1243 GtkWidget *ui_pay_manage_dialog (void)
1244 {
1245 struct ui_pay_manage_dialog_data data;
1246 GtkWidget *dialog, *content, *mainvbox, *box, *bbox, *treeview, *scrollwin, *table;
1247 GtkWidget *menu, *menuitem, *widget, *image, *searchbar, *addreveal;
1248 gint w, h, row;
1249
1250 dialog = gtk_dialog_new_with_buttons (_("Manage Payees"),
1251 GTK_WINDOW(GLOBALS->mainwindow),
1252 0,
1253 _("_Close"), GTK_RESPONSE_ACCEPT,
1254 NULL);
1255
1256 /*dialog = g_object_new (GTK_TYPE_DIALOG, "use-header-bar", TRUE, NULL);
1257 gtk_window_set_title (GTK_WINDOW (dialog), _("Manage Payees"));
1258 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW(GLOBALS->mainwindow));
1259 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
1260 */
1261 //gtk_window_set_destroy_with_parent (GTK_WINDOW (dialog), TRUE);
1262
1263 data.window = dialog;
1264 data.change = 0;
1265
1266 gtk_window_set_icon_name(GTK_WINDOW (dialog), ICONNAME_HB_PAYEE);
1267
1268 //set a nice dialog size
1269 gtk_window_get_size(GTK_WINDOW(GLOBALS->mainwindow), &w, &h);
1270 gtk_window_set_default_size (GTK_WINDOW(dialog), -1, h/PHI);
1271
1272
1273 //store our dialog private data
1274 g_object_set_data(G_OBJECT(dialog), "inst_data", (gpointer)&data);
1275 DB( g_print("(ui_pay_manage_dialog) dialog=%p, inst_data=%p\n", dialog, &data) );
1276
1277 g_signal_connect (dialog, "destroy",
1278 G_CALLBACK (gtk_widget_destroyed), &dialog);
1279
1280 //dialog contents
1281 content = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
1282 mainvbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_SMALL);
1283 gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
1284 gtk_container_set_border_width (GTK_CONTAINER(mainvbox), SPACING_MEDIUM);
1285
1286 //our table
1287 table = gtk_grid_new ();
1288 gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_SMALL);
1289 gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_MEDIUM);
1290 gtk_box_pack_start (GTK_BOX (mainvbox), table, TRUE, TRUE, 0);
1291
1292 row = 0;
1293 bbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_MEDIUM);
1294 gtk_grid_attach (GTK_GRID (table), bbox, 0, row, 2, 1);
1295 //test headerbar
1296 //content = gtk_dialog_get_header_bar(GTK_DIALOG (dialog));
1297
1298 menu = gtk_menu_new ();
1299 gtk_widget_set_halign (menu, GTK_ALIGN_END);
1300
1301 menuitem = gtk_menu_item_new_with_mnemonic (_("_Import CSV"));
1302 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1303 g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_pay_manage_dialog_load_csv), &data);
1304
1305 menuitem = gtk_menu_item_new_with_mnemonic (_("E_xport CSV"));
1306 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1307 g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_pay_manage_dialog_save_csv), &data);
1308
1309 menuitem = gtk_separator_menu_item_new();
1310 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1311
1312 menuitem = gtk_menu_item_new_with_mnemonic (_("_Delete unused"));
1313 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
1314 g_signal_connect (G_OBJECT (menuitem), "activate", G_CALLBACK (ui_pay_manage_dialog_delete_unused), &data);
1315
1316 gtk_widget_show_all (menu);
1317
1318
1319 widget = gtk_menu_button_new();
1320 image = gtk_image_new_from_icon_name (ICONNAME_HB_BUTTON_MENU, GTK_ICON_SIZE_MENU);
1321 g_object_set (widget, "image", image, "popup", GTK_MENU(menu), NULL);
1322 gtk_widget_set_halign (widget, GTK_ALIGN_END);
1323 gtk_box_pack_end(GTK_BOX (bbox), widget, FALSE, FALSE, 0);
1324 //gtk_header_bar_pack_end(GTK_HEADER_BAR (content), widget);
1325
1326 data.BT_search = gtk_toggle_button_new ();
1327 image = gtk_image_new_from_icon_name (ICONNAME_SYSTEM_SEARCH, GTK_ICON_SIZE_BUTTON);
1328 gtk_button_set_image (GTK_BUTTON(data.BT_search), image);
1329 gtk_box_pack_end(GTK_BOX (bbox), data.BT_search, FALSE, FALSE, 0);
1330 //gtk_header_bar_pack_end(GTK_HEADER_BAR (content), data.BT_search);
1331
1332 //search + list
1333 row++;
1334 box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1335 gtk_grid_attach (GTK_GRID (table), box, 0, row, 2, 1);
1336
1337 searchbar = gtk_search_bar_new();
1338 gtk_container_add(GTK_CONTAINER(box), searchbar);
1339 widget = make_search();
1340 data.ST_search = widget;
1341 gtk_container_add (GTK_CONTAINER (searchbar), widget);
1342 gtk_search_bar_connect_entry(GTK_SEARCH_BAR(searchbar), GTK_ENTRY(data.ST_search));
1343 gtk_search_bar_set_show_close_button(GTK_SEARCH_BAR(searchbar), TRUE);
1344
1345 scrollwin = gtk_scrolled_window_new(NULL,NULL);
1346 gtk_container_add(GTK_CONTAINER(box), scrollwin);
1347 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
1348 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1349 gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrollwin), HB_MINHEIGHT_LIST);
1350 gtk_widget_set_hexpand (scrollwin, TRUE);
1351 gtk_widget_set_vexpand (scrollwin, TRUE);
1352 treeview = ui_pay_listview_new(FALSE, TRUE);
1353 data.LV_pay = treeview;
1354 gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
1355
1356 row++;
1357 addreveal = gtk_revealer_new ();
1358 gtk_grid_attach (GTK_GRID (table), addreveal, 0, row, 2, 1);
1359 data.ST_name = gtk_entry_new ();
1360 gtk_entry_set_placeholder_text(GTK_ENTRY(data.ST_name), _("new payee") );
1361 gtk_widget_set_hexpand (data.ST_name, TRUE);
1362 gtk_container_add(GTK_CONTAINER(addreveal), data.ST_name);
1363
1364 row++;
1365 bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
1366 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
1367 gtk_box_set_spacing (GTK_BOX (bbox), SPACING_SMALL);
1368 gtk_grid_attach (GTK_GRID (table), bbox, 0, row, 2, 1);
1369
1370 data.BT_add = gtk_toggle_button_new_with_mnemonic(_("_Add"));
1371 gtk_container_add (GTK_CONTAINER (bbox), data.BT_add);
1372
1373 //todo: useless ?
1374 data.BT_edit = gtk_button_new_with_mnemonic(_("_Edit"));
1375 gtk_container_add (GTK_CONTAINER (bbox), data.BT_edit);
1376
1377 data.BT_merge = gtk_button_new_with_mnemonic(_("_Merge"));
1378 gtk_container_add (GTK_CONTAINER (bbox), data.BT_merge);
1379
1380 data.BT_delete = gtk_button_new_with_mnemonic(_("_Delete"));
1381 gtk_container_add (GTK_CONTAINER (bbox), data.BT_delete);
1382
1383
1384 //connect all our signals
1385 g_object_bind_property (data.BT_add, "active", addreveal, "reveal-child", G_BINDING_BIDIRECTIONAL);
1386 g_object_bind_property (data.BT_search, "active", searchbar, "search-mode-enabled", G_BINDING_BIDIRECTIONAL);
1387
1388 g_signal_connect (G_OBJECT (data.ST_search), "search-changed", G_CALLBACK (ui_pay_manage_search_changed_cb), &data);
1389 g_signal_connect (G_OBJECT (data.ST_name), "activate", G_CALLBACK (ui_pay_manage_dialog_add), NULL);
1390
1391 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data.LV_pay)), "changed", G_CALLBACK (ui_pay_manage_dialog_selection), NULL);
1392 g_signal_connect (GTK_TREE_VIEW(data.LV_pay), "row-activated", G_CALLBACK (ui_pay_manage_dialog_onRowActivated), NULL);
1393
1394 g_signal_connect (G_OBJECT (data.BT_edit), "clicked", G_CALLBACK (ui_pay_manage_dialog_edit), NULL);
1395 g_signal_connect (G_OBJECT (data.BT_merge), "clicked", G_CALLBACK (ui_pay_manage_dialog_merge), NULL);
1396 g_signal_connect (G_OBJECT (data.BT_delete), "clicked", G_CALLBACK (ui_pay_manage_dialog_delete), NULL);
1397
1398 //setup, init and show dialog
1399 payee_fill_usage();
1400 ui_pay_listview_populate(data.LV_pay, NULL);
1401 ui_pay_manage_dialog_update(data.LV_pay, NULL);
1402
1403 gtk_widget_show_all (dialog);
1404
1405 //wait for the user
1406 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
1407
1408 switch (result)
1409 {
1410 case GTK_RESPONSE_ACCEPT:
1411 //do_application_specific_something ();
1412 break;
1413 default:
1414 //do_nothing_since_dialog_was_cancelled ();
1415 break;
1416 }
1417
1418 // cleanup and destroy
1419
1420 gtk_widget_destroy (dialog);
1421
1422 GLOBALS->changes_count += data.change;
1423
1424 return NULL;
1425 }
1426
This page took 0.092492 seconds and 4 git commands to generate.