add gitignore
[chaz/homebank] / src / ui-payee.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 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 #include "homebank.h"
21
22 #include "ui-payee.h"
23
24 #define MYDEBUG 0
25
26 #if MYDEBUG
27 #define DB(x) (x);
28 #else
29 #define DB(x);
30 #endif
31
32 /* our global datas */
33 extern struct HomeBank *GLOBALS;
34
35
36 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
37
38 /**
39 * ui_pay_comboboxentry_get_name:
40 *
41 * get the name of the active payee or -1
42 *
43 * Return value: a new allocated name tobe freed with g_free
44 *
45 */
46 gchar *
47 ui_pay_comboboxentry_get_name(GtkComboBox *entry_box)
48 {
49 gchar *cbname;
50 gchar *name = NULL;
51
52 cbname = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
53
54 if( cbname != NULL)
55 {
56 name = g_strdup(cbname);
57 g_strstrip(name);
58 }
59
60 return name;
61 }
62
63
64 /**
65 * ui_pay_comboboxentry_get_key_add_new:
66 *
67 * get the key of the active payee
68 * and create the payee if it do not exists
69 *
70 * Return value: the key or 0
71 *
72 */
73 guint32
74 ui_pay_comboboxentry_get_key_add_new(GtkComboBox *entry_box)
75 {
76 gchar *name;
77 Payee *item;
78
79 name = ui_pay_comboboxentry_get_name(entry_box);
80
81 item = da_pay_get_by_name(name);
82 if( item == NULL )
83 {
84 /* automatic add */
85 //todo: check prefs + ask the user here 1st time
86 item = da_pay_malloc();
87 item->name = g_strdup(name);
88 da_pay_append(item);
89 ui_pay_comboboxentry_add(entry_box, item);
90 }
91
92 g_free(name);
93
94 return item->key;
95 }
96
97 /**
98 * ui_pay_comboboxentry_get_key:
99 *
100 * get the key of the active payee
101 *
102 * Return value: the key or 0
103 *
104 */
105 guint32
106 ui_pay_comboboxentry_get_key(GtkComboBox *entry_box)
107 {
108 gchar *name;
109 Payee *item;
110
111 name = ui_pay_comboboxentry_get_name(entry_box);
112 item = da_pay_get_by_name(name);
113 g_free(name);
114
115 if( item != NULL )
116 return item->key;
117
118 return 0;
119 }
120
121 gboolean
122 ui_pay_comboboxentry_set_active(GtkComboBox *entry_box, guint32 key)
123 {
124 Payee *item;
125
126 if( key > 0 )
127 {
128 item = da_pay_get(key);
129 if( item != NULL)
130 {
131 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))), item->name);
132 return TRUE;
133 }
134 }
135 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))), "");
136 return FALSE;
137 }
138
139
140
141
142 /**
143 * ui_pay_comboboxentry_add:
144 *
145 * Add a single element (useful for dynamics add)
146 *
147 * Return value: --
148 *
149 */
150 void
151 ui_pay_comboboxentry_add(GtkComboBox *entry_box, Payee *pay)
152 {
153 if( pay->name != NULL )
154 {
155 GtkTreeModel *model;
156 GtkTreeIter iter;
157
158 model = gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box));
159
160 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
161 gtk_list_store_set (GTK_LIST_STORE(model), &iter, 0, pay->name, -1);
162 }
163 }
164
165 static void
166 ui_pay_comboboxentry_populate_ghfunc(gpointer key, gpointer value, struct payPopContext *ctx)
167 {
168 GtkTreeIter iter;
169 Payee *pay = value;
170
171 if( ( pay->key != ctx->except_key ) )
172 {
173 gtk_list_store_append (GTK_LIST_STORE(ctx->model), &iter);
174 gtk_list_store_set (GTK_LIST_STORE(ctx->model), &iter, 0, pay->name, -1);
175 }
176 }
177
178 /**
179 * ui_pay_comboboxentry_populate:
180 *
181 * Populate the list and completion
182 *
183 * Return value: --
184 *
185 */
186 void
187 ui_pay_comboboxentry_populate(GtkComboBox *entry_box, GHashTable *hash)
188 {
189 ui_pay_comboboxentry_populate_except(entry_box, hash, -1);
190 }
191
192 void
193 ui_pay_comboboxentry_populate_except(GtkComboBox *entry_box, GHashTable *hash, guint except_key)
194 {
195 GtkTreeModel *model;
196 GtkEntryCompletion *completion;
197 struct payPopContext ctx;
198
199 DB( g_print ("ui_pay_comboboxentry_populate\n") );
200
201 model = gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box));
202 completion = gtk_entry_get_completion(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box))));
203
204 /* keep our model alive and detach from comboboxentry and completion */
205 g_object_ref(model);
206 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), NULL);
207 gtk_entry_completion_set_model (completion, NULL);
208
209 /* clear and populate */
210 ctx.model = model;
211 ctx.except_key = except_key;
212 gtk_list_store_clear (GTK_LIST_STORE(model));
213 g_hash_table_foreach(hash, (GHFunc)ui_pay_comboboxentry_populate_ghfunc, &ctx);
214
215 /* reatach our model */
216 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box), model);
217 gtk_entry_completion_set_model (completion, model);
218 g_object_unref(model);
219
220 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
221
222 }
223
224
225
226 static gint
227 ui_pay_comboboxentry_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
228 {
229 gint retval = 0;
230 gchar *name1, *name2;
231
232 gtk_tree_model_get(model, a, 0, &name1, -1);
233 gtk_tree_model_get(model, b, 0, &name2, -1);
234
235 retval = hb_string_utf8_compare(name1, name2);
236
237 g_free(name2);
238 g_free(name1);
239
240 return retval;
241 }
242
243
244 static void
245 ui_pay_comboboxentry_test (GtkCellLayout *cell_layout,
246 GtkCellRenderer *cell,
247 GtkTreeModel *tree_model,
248 GtkTreeIter *iter,
249 gpointer data)
250 {
251 gchar *name;
252
253 gtk_tree_model_get(tree_model, iter,
254 0, &name,
255 -1);
256
257 if( !name )
258 g_object_set(cell, "text", _("(no payee)"), NULL);
259 else
260 g_object_set(cell, "text", name, NULL);
261
262 }
263
264 /**
265 * ui_pay_comboboxentry_new:
266 *
267 * Create a new payee comboboxentry
268 *
269 * Return value: the new widget
270 *
271 */
272 GtkWidget *
273 ui_pay_comboboxentry_new(GtkWidget *label)
274 {
275 GtkListStore *store;
276 GtkWidget *comboboxentry;
277 GtkEntryCompletion *completion;
278 GtkCellRenderer *renderer;
279
280 store = gtk_list_store_new (1,
281 G_TYPE_STRING
282 );
283 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_pay_comboboxentry_compare_func, NULL, NULL);
284
285 completion = gtk_entry_completion_new ();
286 gtk_entry_completion_set_model (completion, GTK_TREE_MODEL(store));
287 g_object_set(completion, "text-column", 0, NULL);
288
289 renderer = gtk_cell_renderer_text_new ();
290 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
291 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), renderer, "text", 0, NULL);
292
293 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion),
294 renderer,
295 ui_pay_comboboxentry_test,
296 NULL, NULL);
297
298 // dothe same for combobox
299
300 comboboxentry = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store));
301 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboboxentry), 0);
302
303 gtk_cell_layout_clear(GTK_CELL_LAYOUT (comboboxentry));
304
305 renderer = gtk_cell_renderer_text_new ();
306 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comboboxentry), renderer, TRUE);
307 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comboboxentry), renderer, "text", 0, NULL);
308
309 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (comboboxentry),
310 renderer,
311 ui_pay_comboboxentry_test,
312 NULL, NULL);
313
314
315
316 gtk_entry_set_completion (GTK_ENTRY (gtk_bin_get_child(GTK_BIN (comboboxentry))), completion);
317
318 g_object_unref(store);
319
320 if(label)
321 gtk_label_set_mnemonic_widget (GTK_LABEL(label), comboboxentry);
322
323 gtk_widget_set_size_request(comboboxentry, HB_MINWIDTH_COMBO, -1);
324
325 return comboboxentry;
326 }
327
328 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
329
330
331 static void
332 ui_pay_listview_toggled_cb (GtkCellRendererToggle *cell,
333 gchar *path_str,
334 gpointer data)
335 {
336 GtkTreeModel *model = (GtkTreeModel *)data;
337 GtkTreeIter iter;
338 GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
339 gboolean fixed;
340
341 /* get toggled iter */
342 gtk_tree_model_get_iter (model, &iter, path);
343 gtk_tree_model_get (model, &iter, LST_DEFPAY_TOGGLE, &fixed, -1);
344
345 /* do something with the value */
346 fixed ^= 1;
347
348 /* set new value */
349 gtk_list_store_set (GTK_LIST_STORE (model), &iter, LST_DEFPAY_TOGGLE, fixed, -1);
350
351 /* clean up */
352 gtk_tree_path_free (path);
353 }
354
355 static gint
356 ui_pay_listview_compare_func (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer userdata)
357 {
358 Payee *entry1, *entry2;
359
360 gtk_tree_model_get(model, a, LST_DEFPAY_DATAS, &entry1, -1);
361 gtk_tree_model_get(model, b, LST_DEFPAY_DATAS, &entry2, -1);
362
363 return hb_string_utf8_compare(entry1->name, entry2->name);
364 }
365
366 static void
367 ui_pay_listview_name_cell_data_function (GtkTreeViewColumn *col,
368 GtkCellRenderer *renderer,
369 GtkTreeModel *model,
370 GtkTreeIter *iter,
371 gpointer user_data)
372 {
373 Payee *entry;
374 gchar *name;
375 #if MYDEBUG
376 gchar *string;
377 #endif
378
379 gtk_tree_model_get(model, iter, LST_DEFPAY_DATAS, &entry, -1);
380
381 if(entry->key == 0)
382 name = _("(no payee)");
383 else
384 name = entry->name;
385
386 #if MYDEBUG
387 string = g_strdup_printf ("%d > %s [ft=%d im=%d]", entry->key, name, entry->filter, entry->imported);
388 g_object_set(renderer, "text", string, NULL);
389 g_free(string);
390 #else
391 g_object_set(renderer, "text", name, NULL);
392 #endif
393
394 }
395
396
397
398 /* = = = = = = = = = = = = = = = = */
399
400
401 void
402 ui_pay_listview_add(GtkTreeView *treeview, Payee *item)
403 {
404 if( item->name != NULL )
405 {
406 GtkTreeModel *model;
407 GtkTreeIter iter;
408
409 model = gtk_tree_view_get_model(treeview);
410
411 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
412 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
413 LST_DEFPAY_TOGGLE, FALSE,
414 LST_DEFPAY_DATAS, item,
415 -1);
416 }
417 }
418
419 guint32
420 ui_pay_listview_get_selected_key(GtkTreeView *treeview)
421 {
422 GtkTreeSelection *selection;
423 GtkTreeModel *model;
424 GtkTreeIter iter;
425
426 selection = gtk_tree_view_get_selection(treeview);
427 if (gtk_tree_selection_get_selected(selection, &model, &iter))
428 {
429 Payee *item;
430
431 gtk_tree_model_get(model, &iter, LST_DEFPAY_DATAS, &item, -1);
432
433 if( item!= NULL )
434 return item->key;
435 }
436 return 0;
437 }
438
439 void
440 ui_pay_listview_remove_selected(GtkTreeView *treeview)
441 {
442 GtkTreeSelection *selection;
443 GtkTreeModel *model;
444 GtkTreeIter iter;
445
446 selection = gtk_tree_view_get_selection(treeview);
447 if (gtk_tree_selection_get_selected(selection, &model, &iter))
448 {
449 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
450 }
451 }
452
453
454 static void ui_pay_listview_populate_ghfunc(gpointer key, gpointer value, GtkTreeModel *model)
455 {
456 GtkTreeIter iter;
457 Payee *item = value;
458
459 DB( g_print(" populate: %p\n", key) );
460
461 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
462 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
463 LST_DEFPAY_TOGGLE , FALSE,
464 LST_DEFPAY_DATAS, item,
465 -1);
466 }
467
468 void ui_pay_listview_populate(GtkWidget *view)
469 {
470 GtkTreeModel *model;
471
472 model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
473
474 gtk_list_store_clear (GTK_LIST_STORE(model));
475
476 g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
477 gtk_tree_view_set_model(GTK_TREE_VIEW(view), NULL); /* Detach model from view */
478
479 /* populate */
480 g_hash_table_foreach(GLOBALS->h_pay, (GHFunc)ui_pay_listview_populate_ghfunc, model);
481
482 gtk_tree_view_set_model(GTK_TREE_VIEW(view), model); /* Re-attach model to view */
483 g_object_unref(model);
484 }
485
486
487 GtkWidget *
488 ui_pay_listview_new(gboolean withtoggle)
489 {
490 GtkListStore *store;
491 GtkWidget *treeview;
492 GtkCellRenderer *renderer;
493 GtkTreeViewColumn *column;
494
495 // create list store
496 store = gtk_list_store_new(
497 NUM_LST_DEFPAY,
498 G_TYPE_BOOLEAN,
499 G_TYPE_POINTER
500 );
501
502 // treeview
503 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
504 g_object_unref(store);
505
506 //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
507
508 // column 1: toggle
509 if( withtoggle == TRUE )
510 {
511 renderer = gtk_cell_renderer_toggle_new ();
512 column = gtk_tree_view_column_new_with_attributes (_("Visible"),
513 renderer,
514 "active", LST_DEFPAY_TOGGLE,
515 NULL);
516 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
517
518 g_signal_connect (renderer, "toggled",
519 G_CALLBACK (ui_pay_listview_toggled_cb), store);
520
521 }
522
523 // column 2: name
524 renderer = gtk_cell_renderer_text_new ();
525 column = gtk_tree_view_column_new();
526 gtk_tree_view_column_pack_start(column, renderer, TRUE);
527 gtk_tree_view_column_set_cell_data_func(column, renderer, ui_pay_listview_name_cell_data_function, GINT_TO_POINTER(LST_DEFPAY_DATAS), NULL);
528 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
529
530 // treeview attribute
531 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), FALSE);
532 //gtk_tree_view_set_reorderable (GTK_TREE_VIEW(view), TRUE);
533 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DEFPAY_DATAS, ui_pay_listview_compare_func, NULL, NULL);
534 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), LST_DEFPAY_DATAS, GTK_SORT_ASCENDING);
535
536 return treeview;
537 }
538
539
540
541
542 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
543
544 /**
545 * ui_pay_manage_dialog_load_csv:
546 *
547 */
548 static void
549 ui_pay_manage_dialog_load_csv( GtkWidget *widget, gpointer user_data)
550 {
551 struct ui_pay_manage_dialog_data *data;
552 gchar *filename = NULL;
553
554 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");
555
556 DB( g_print("(ui_pay_manage_dialog) load csv - data %p\n", data) );
557
558 if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_OPEN, &filename, NULL) == TRUE )
559 {
560 DB( g_print(" + filename is %s\n", filename) );
561
562 payee_load_csv(filename);
563 //todo: add error message
564
565 g_free( filename );
566 ui_pay_listview_populate(data->LV_pay);
567 }
568 }
569
570 /**
571 * ui_pay_manage_dialog_save_csv:
572 *
573 */
574 static void
575 ui_pay_manage_dialog_save_csv( GtkWidget *widget, gpointer user_data)
576 {
577 struct ui_pay_manage_dialog_data *data;
578 gchar *filename = NULL;
579
580 DB( g_print("(ui_pay_manage_dialog) save csv\n") );
581
582 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
583
584 if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, NULL) == TRUE )
585 {
586 DB( g_print(" + filename is %s\n", filename) );
587
588 payee_save_csv(filename);
589 g_free( filename );
590 }
591 }
592
593
594 /**
595 * ui_pay_manage_dialog_add:
596 *
597 */
598 static void
599 ui_pay_manage_dialog_add(GtkWidget *widget, gpointer user_data)
600 {
601 struct ui_pay_manage_dialog_data *data;
602 Payee *item;
603 gchar *name;
604
605 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
606 DB( g_print("(defayee) add (data=%p)\n", data) );
607
608 name = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_name));
609
610 item = payee_append_if_new(name);
611 if( item )
612 {
613 ui_pay_listview_add(GTK_TREE_VIEW(data->LV_pay), item);
614 data->change++;
615 }
616
617 gtk_entry_set_text(GTK_ENTRY(data->ST_name), "");
618 }
619
620
621 static void ui_pay_manage_dialog_modify_entry_cb(GtkEditable *editable, gpointer user_data)
622 {
623 GtkDialog *window = user_data;
624 const gchar *buffer;
625
626 buffer = gtk_entry_get_text(GTK_ENTRY(editable));
627 gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT, strlen(buffer) > 0 ? TRUE : FALSE);
628 }
629
630
631 /*
632 ** modify
633 */
634 static void ui_pay_manage_dialog_modify(GtkWidget *widget, gpointer user_data)
635 {
636 struct ui_pay_manage_dialog_data *data;
637 GtkWidget *window, *content, *mainvbox, *getwidget;
638 guint32 key;
639
640 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
641 DB( g_print("(defayee) modify %p\n", data) );
642
643 key = ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data->LV_pay));
644 if( key > 0 )
645 {
646 Payee *item;
647
648 item = da_pay_get( key );
649
650 window = gtk_dialog_new_with_buttons (_("Modify..."),
651 GTK_WINDOW (data->window),
652 0,
653 GTK_STOCK_CANCEL,
654 GTK_RESPONSE_REJECT,
655 GTK_STOCK_OK,
656 GTK_RESPONSE_ACCEPT,
657 NULL);
658
659 content = gtk_dialog_get_content_area(GTK_DIALOG (window));
660 mainvbox = gtk_vbox_new (FALSE, 0);
661 gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
662 gtk_container_set_border_width (GTK_CONTAINER (mainvbox), HB_BOX_SPACING);
663
664 getwidget = gtk_entry_new();
665 gtk_box_pack_start (GTK_BOX (mainvbox), getwidget, TRUE, TRUE, 0);
666 gtk_widget_show_all(mainvbox);
667
668 g_signal_connect (G_OBJECT (getwidget), "changed", G_CALLBACK (ui_pay_manage_dialog_modify_entry_cb), window);
669
670 gtk_entry_set_text(GTK_ENTRY(getwidget), item->name);
671 gtk_widget_grab_focus (getwidget);
672
673 gtk_entry_set_activates_default (GTK_ENTRY(getwidget), TRUE);
674
675 gtk_dialog_set_default_response(GTK_DIALOG( window ), GTK_RESPONSE_ACCEPT);
676
677 //wait for the user
678 gint result = gtk_dialog_run (GTK_DIALOG (window));
679
680 if(result == GTK_RESPONSE_ACCEPT)
681 {
682 const gchar *name;
683
684 name = gtk_entry_get_text(GTK_ENTRY(getwidget));
685
686 /* ignore if entry is empty */
687 if (name && *name)
688 {
689 if( payee_rename(item, name) )
690 {
691 //to redraw the active entry
692 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_pay));
693 data->change++;
694 }
695 else
696 {
697 ui_dialog_msg_infoerror(GTK_WINDOW(window), GTK_MESSAGE_ERROR,
698 _("Error"),
699 _("Cannot rename this Payee,\n"
700 "from '%s' to '%s',\n"
701 "this name already exists."),
702 item->name,
703 name
704 );
705
706 }
707 }
708 }
709
710 // cleanup and destroy
711 gtk_widget_destroy (window);
712 }
713
714 }
715
716
717 static void ui_pay_manage_dialog_move_entry_cb(GtkComboBox *widget, gpointer user_data)
718 {
719 GtkDialog *window = user_data;
720 gchar *buffer;
721
722 buffer = (gchar *)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (widget))));
723 gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT, strlen(buffer) > 0 ? TRUE : FALSE);
724 }
725
726
727 /*
728 ** move
729 */
730 static void ui_pay_manage_dialog_move(GtkWidget *widget, gpointer user_data)
731 {
732 struct ui_pay_manage_dialog_data *data;
733 GtkWidget *window, *content, *mainvbox;
734 GtkWidget *getwidget;
735 GtkTreeSelection *selection;
736 GtkTreeModel *model;
737 GtkTreeIter iter;
738
739 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
740 DB( g_print("(defayee) move %p\n", data) );
741
742 // get selection ...
743 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_pay));
744 //if true there is a selected node
745 if (gtk_tree_selection_get_selected(selection, &model, &iter))
746 {
747 Payee *entry;
748
749 gtk_tree_model_get(model, &iter, LST_DEFPAY_DATAS, &entry, -1);
750
751 window = gtk_dialog_new_with_buttons (_("Move to..."),
752 GTK_WINDOW (data->window),
753 0,
754 GTK_STOCK_CANCEL,
755 GTK_RESPONSE_REJECT,
756 GTK_STOCK_OK,
757 GTK_RESPONSE_ACCEPT,
758 NULL);
759
760 content = gtk_dialog_get_content_area(GTK_DIALOG (window));
761 mainvbox = gtk_vbox_new (FALSE, 0);
762 gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
763 gtk_container_set_border_width (GTK_CONTAINER (mainvbox), HB_BOX_SPACING);
764
765 getwidget = ui_pay_comboboxentry_new(NULL);
766 gtk_box_pack_start (GTK_BOX (mainvbox), getwidget, TRUE, TRUE, 0);
767
768 //gtk_combo_box_set_active(GTK_COMBO_BOX(getwidget), oldpos);
769 gtk_dialog_set_response_sensitive(GTK_DIALOG(window), GTK_RESPONSE_ACCEPT, FALSE);
770
771 gtk_widget_show_all(mainvbox);
772
773 g_signal_connect (G_OBJECT (getwidget), "changed", G_CALLBACK (ui_pay_manage_dialog_move_entry_cb), window);
774
775 //data->tmp_list = g_list_sort(data->tmp_list, (GCompareFunc)ui_pay_manage_dialog_list_sort);
776 ui_pay_comboboxentry_populate_except(GTK_COMBO_BOX(getwidget), GLOBALS->h_pay, entry->key);
777 gtk_widget_grab_focus (getwidget);
778
779 //wait for the user
780 gint result = gtk_dialog_run (GTK_DIALOG (window));
781
782 if(result == GTK_RESPONSE_ACCEPT)
783 {
784 gint result;
785 gchar *npn;
786
787 npn = ui_pay_comboboxentry_get_name(GTK_COMBO_BOX(getwidget)),
788
789 result = ui_dialog_msg_question(
790 GTK_WINDOW(window),
791 _("Move this payee to another one ?"),
792 _("This will replace '%s' by '%s',\n"
793 "and then remove '%s'"),
794 entry->name,
795 npn,
796 entry->name,
797 NULL
798 );
799
800 if( result == GTK_RESPONSE_YES )
801 {
802 Payee *payee;
803 guint newpayee;
804
805 newpayee = ui_pay_comboboxentry_get_key_add_new(GTK_COMBO_BOX(getwidget));
806
807 gtk_combo_box_get_active(GTK_COMBO_BOX(getwidget));
808
809 DB( g_print(" -> should move %d - %s to %d - %s\n", entry->key, entry->name, newpayee, npn ) );
810
811 payee_move(entry->key, newpayee);
812
813 // remove the old payee
814 da_pay_remove(entry->key);
815 ui_pay_listview_remove_selected(GTK_TREE_VIEW(data->LV_pay));
816
817 // add the new payee to listview
818 payee = da_pay_get(newpayee);
819 if(payee)
820 ui_pay_listview_add(GTK_TREE_VIEW(data->LV_pay), payee);
821 data->change++;
822
823 }
824
825 }
826
827 // cleanup and destroy
828 gtk_widget_destroy (window);
829
830 }
831
832 }
833
834
835 /*
836 ** remove the selected payee to our treeview and temp GList
837 */
838 static void ui_pay_manage_dialog_remove(GtkWidget *widget, gpointer user_data)
839 {
840 struct ui_pay_manage_dialog_data *data;
841 guint32 key;
842 Payee *item;
843 gint result;
844 gboolean do_remove;
845
846 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
847 DB( g_print("(ui_pay_manage_dialog) remove (data=%p)\n", data) );
848
849 do_remove = TRUE;
850 key = ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data->LV_pay));
851 if( key > 0 )
852 {
853 if( payee_is_used(key) == TRUE )
854 {
855 item = da_pay_get(key);
856
857 result = ui_dialog_msg_question(
858 GTK_WINDOW(data->window),
859 _("Remove a payee ?"),
860 _("If you remove '%s', archive and transaction referencing this payee\n"
861 "will set place to 'no payee'"),
862 item->name,
863 NULL
864 );
865
866 if( result == GTK_RESPONSE_YES )
867 {
868 payee_move(key, 0);
869 }
870 else if( result == GTK_RESPONSE_NO )
871 {
872 do_remove = FALSE;
873 }
874 }
875
876 if( do_remove )
877 {
878 da_pay_remove(key);
879 ui_pay_listview_remove_selected(GTK_TREE_VIEW(data->LV_pay));
880 data->change++;
881 }
882
883 }
884 }
885
886
887 /*
888 **
889 */
890 static void ui_pay_manage_dialog_update(GtkWidget *treeview, gpointer user_data)
891 {
892 struct ui_pay_manage_dialog_data *data;
893 gboolean sensitive;
894 guint32 key;
895
896 DB( g_print("\n(ui_pay_manage_dialog) cursor changed\n") );
897
898 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW)), "inst_data");
899
900 key = ui_pay_listview_get_selected_key(GTK_TREE_VIEW(data->LV_pay));
901
902 sensitive = (key > 0) ? TRUE : FALSE;
903 gtk_widget_set_sensitive(data->BT_mov, sensitive);
904 gtk_widget_set_sensitive(data->BT_mod, sensitive);
905 gtk_widget_set_sensitive(data->BT_rem, sensitive);
906
907 }
908
909
910 /*
911 **
912 */
913 static void ui_pay_manage_dialog_selection(GtkTreeSelection *treeselection, gpointer user_data)
914 {
915 ui_pay_manage_dialog_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), NULL);
916 }
917
918 static void ui_pay_manage_dialog_onRowActivated (GtkTreeView *treeview,
919 GtkTreePath *path,
920 GtkTreeViewColumn *col,
921 gpointer userdata)
922 {
923 GtkTreeModel *model;
924 GtkTreeIter iter;
925
926 model = gtk_tree_view_get_model(treeview);
927 gtk_tree_model_get_iter_first(model, &iter);
928 if(gtk_tree_selection_iter_is_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), &iter) == FALSE)
929 {
930 ui_pay_manage_dialog_modify(GTK_WIDGET(treeview), NULL);
931 }
932 }
933
934 /*
935 **
936 */
937 GtkWidget *ui_pay_manage_dialog (void)
938 {
939 struct ui_pay_manage_dialog_data data;
940 GtkWidget *window, *content, *mainvbox, *treeview, *scrollwin, *vbox, *table;
941 GtkWidget *separator;
942 gint row;
943
944 window = gtk_dialog_new_with_buttons (_("Manage Payees"),
945 GTK_WINDOW(GLOBALS->mainwindow),
946 0,
947 GTK_STOCK_CLOSE,
948 GTK_RESPONSE_ACCEPT,
949 NULL);
950
951 data.window = window;
952 data.change = 0;
953
954
955 //homebank_window_set_icon_from_file(GTK_WINDOW (window), "payee.svg");
956 gtk_window_set_icon_name(GTK_WINDOW (window), HB_STOCK_PAYEE);
957
958 //store our window private data
959 g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)&data);
960 DB( g_print("(ui_pay_manage_dialog) window=%p, inst_data=%p\n", window, &data) );
961
962 g_signal_connect (window, "destroy",
963 G_CALLBACK (gtk_widget_destroyed), &window);
964
965 //window contents
966 content = gtk_dialog_get_content_area(GTK_DIALOG (window));
967 mainvbox = gtk_vbox_new (FALSE, HB_BOX_SPACING);
968 gtk_box_pack_start (GTK_BOX (content), mainvbox, TRUE, TRUE, 0);
969 gtk_container_set_border_width (GTK_CONTAINER(mainvbox), HB_MAINBOX_SPACING);
970
971 //our table
972 table = gtk_table_new (2, 2, FALSE);
973 gtk_table_set_row_spacings (GTK_TABLE (table), HB_TABROW_SPACING);
974 gtk_table_set_col_spacings (GTK_TABLE (table), HB_TABCOL_SPACING);
975 gtk_box_pack_start (GTK_BOX (mainvbox), table, TRUE, TRUE, 0);
976
977 row = 0;
978 data.ST_name = gtk_entry_new ();
979 gtk_table_attach (GTK_TABLE (table), data.ST_name, 0, 1, row, row+1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), (GtkAttachOptions) (0), 0, 0);
980 data.BT_add = gtk_button_new_from_stock(GTK_STOCK_ADD);
981 gtk_table_attach (GTK_TABLE (table), data.BT_add, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
982
983 //list
984 row++;
985 scrollwin = gtk_scrolled_window_new(NULL,NULL);
986 gtk_table_attach (GTK_TABLE (table), scrollwin, 0, 1, row, row+1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), 0, 0);
987
988 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin), GTK_SHADOW_ETCHED_IN);
989 //gtk_container_set_border_width (GTK_CONTAINER(scrollwin), 5);
990 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
991 //treeview = (GtkWidget *)ui_pay_manage_dialog_list_new(FALSE);
992 treeview = ui_pay_listview_new(FALSE);
993 gtk_widget_set_size_request(treeview, HB_MINWIDTH_LIST, -1);
994 data.LV_pay = treeview;
995 gtk_container_add(GTK_CONTAINER(scrollwin), treeview);
996
997 vbox = gtk_vbox_new (FALSE, HB_BOX_SPACING);
998 gtk_table_attach (GTK_TABLE (table), vbox, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), 0, 0);
999
1000 data.BT_rem = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
1001 gtk_box_pack_start (GTK_BOX (vbox), data.BT_rem, FALSE, FALSE, 0);
1002
1003 data.BT_mod = gtk_button_new_from_stock(GTK_STOCK_EDIT);
1004 //data.BT_mod = gtk_button_new_with_mnemonic(_("_Modify"));
1005 gtk_box_pack_start (GTK_BOX (vbox), data.BT_mod, FALSE, FALSE, 0);
1006
1007 data.BT_mov = gtk_button_new_with_mnemonic(_("_Move"));
1008 gtk_box_pack_start (GTK_BOX (vbox), data.BT_mov, FALSE, FALSE, 0);
1009
1010 separator = gtk_hseparator_new();
1011 gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, HB_BOX_SPACING);
1012
1013
1014 data.BT_import = gtk_button_new_with_mnemonic(_("_Import"));
1015 //data.BT_import = gtk_button_new_from_stock(GTK_STOCK_OPEN);
1016 gtk_box_pack_start (GTK_BOX (vbox), data.BT_import, FALSE, FALSE, 0);
1017
1018 data.BT_export = gtk_button_new_with_mnemonic(_("E_xport"));
1019 //data.BT_export = gtk_button_new_from_stock(GTK_STOCK_SAVE);
1020 gtk_box_pack_start (GTK_BOX (vbox), data.BT_export, FALSE, FALSE, 0);
1021
1022
1023
1024 //connect all our signals
1025 g_signal_connect (G_OBJECT (data.ST_name), "activate", G_CALLBACK (ui_pay_manage_dialog_add), NULL);
1026
1027 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data.LV_pay)), "changed", G_CALLBACK (ui_pay_manage_dialog_selection), NULL);
1028 g_signal_connect (GTK_TREE_VIEW(data.LV_pay), "row-activated", G_CALLBACK (ui_pay_manage_dialog_onRowActivated), NULL);
1029
1030 g_signal_connect (G_OBJECT (data.BT_add), "clicked", G_CALLBACK (ui_pay_manage_dialog_add), NULL);
1031 g_signal_connect (G_OBJECT (data.BT_mod), "clicked", G_CALLBACK (ui_pay_manage_dialog_modify), NULL);
1032 g_signal_connect (G_OBJECT (data.BT_mov), "clicked", G_CALLBACK (ui_pay_manage_dialog_move), NULL);
1033 g_signal_connect (G_OBJECT (data.BT_rem), "clicked", G_CALLBACK (ui_pay_manage_dialog_remove), NULL);
1034
1035 g_signal_connect (G_OBJECT (data.BT_import), "clicked", G_CALLBACK (ui_pay_manage_dialog_load_csv), NULL);
1036 g_signal_connect (G_OBJECT (data.BT_export), "clicked", G_CALLBACK (ui_pay_manage_dialog_save_csv), NULL);
1037
1038 //setup, init and show window
1039 ui_pay_listview_populate(data.LV_pay);
1040 ui_pay_manage_dialog_update(data.LV_pay, NULL);
1041
1042 //gtk_window_resize(GTK_WINDOW(window), 200, 320);
1043
1044 gtk_widget_show_all (window);
1045
1046 //wait for the user
1047 gint result = gtk_dialog_run (GTK_DIALOG (window));
1048
1049 switch (result)
1050 {
1051 case GTK_RESPONSE_ACCEPT:
1052 //do_application_specific_something ();
1053 break;
1054 default:
1055 //do_nothing_since_dialog_was_cancelled ();
1056 break;
1057 }
1058
1059
1060 // cleanup and destroy
1061 GLOBALS->changes_count += data.change;
1062 gtk_widget_destroy (window);
1063
1064 return NULL;
1065 }
1066
1067
1068
This page took 0.099078 seconds and 4 git commands to generate.