1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2014 Maxime DOYEN
4 * This file is part of HomeBank.
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "hb-account.h"
22 #include "ui-account.h"
32 /* our global datas */
33 extern struct HomeBank
*GLOBALS
;
36 gchar
*CYA_ACC_TYPE
[] =
48 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
51 * ui_acc_comboboxentry_get_name:
53 * get the name of the active account or -1
55 * Return value: a new allocated name tobe freed with g_free
59 ui_acc_comboboxentry_get_name(GtkComboBox
*entry_box
)
64 cbname
= (gchar
*)gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
69 name
= g_strdup(cbname
);
78 * ui_acc_comboboxentry_get_key:
80 * get the key of the active account
81 * and create the account if it do not exists
83 * Return value: the key or 0
87 ui_acc_comboboxentry_get_key(GtkComboBox
*entry_box
)
92 name
= ui_acc_comboboxentry_get_name(entry_box
);
94 item
= da_acc_get_by_name(name
);
100 //todo: ask the user here
102 item = da_acc_malloc();
103 item->name = g_strdup(name);
105 ui_acc_comboboxentry_add(entry_box, item);
116 ui_acc_comboboxentry_set_active(GtkComboBox
*entry_box
, guint32 key
)
122 item
= da_acc_get(key
);
125 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))), item
->name
);
129 gtk_entry_set_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))), "");
135 * ui_acc_comboboxentry_add:
137 * Add a single element (useful for dynamics add)
143 ui_acc_comboboxentry_add(GtkComboBox
*entry_box
, Account
*acc
)
145 if( acc
->name
!= NULL
)
150 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box
));
152 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
153 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
162 ui_acc_comboboxentry_populate_ghfunc(gpointer key
, gpointer value
, struct accPopContext
*ctx
)
165 Account
*acc
= value
;
167 if( (acc
->flags
& AF_CLOSED
) ) return;
168 if( (ctx
->insert_type
== ACC_LST_INSERT_REPORT
) && (acc
->flags
& AF_NOREPORT
) ) return;
169 if( (acc
->key
== ctx
->except_key
) ) return;
170 if( (acc
->imported
== TRUE
) ) return;
172 DB( g_print (" -> append %s\n", acc
->name
) );
175 gtk_list_store_append (GTK_LIST_STORE(ctx
->model
), &iter
);
176 gtk_list_store_set (GTK_LIST_STORE(ctx
->model
), &iter
,
183 * ui_acc_comboboxentry_populate:
185 * Populate the list and completion
191 ui_acc_comboboxentry_populate(GtkComboBox
*entry_box
, GHashTable
*hash
, gint insert_type
)
193 ui_acc_comboboxentry_populate_except(entry_box
, hash
, 0, insert_type
);
197 ui_acc_comboboxentry_populate_except(GtkComboBox
*entry_box
, GHashTable
*hash
, guint except_key
, gint insert_type
)
200 GtkEntryCompletion
*completion
;
201 struct accPopContext ctx
;
203 DB( g_print ("ui_acc_comboboxentry_populate\n") );
205 DB( g_print (" -> except is %d\n", except_key
) );
207 model
= gtk_combo_box_get_model(GTK_COMBO_BOX(entry_box
));
208 completion
= gtk_entry_get_completion(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (entry_box
))));
210 /* keep our model alive and detach from comboboxentry and completion */
212 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box
), NULL
);
213 gtk_entry_completion_set_model (completion
, NULL
);
215 /* clear and populate */
217 ctx
.except_key
= except_key
;
219 ctx
.insert_type
= insert_type
;
220 /* Account *acc = da_acc_get(except_key);
222 ctx.kcur = acc->kcur;*/
224 gtk_list_store_clear (GTK_LIST_STORE(model
));
225 g_hash_table_foreach(hash
, (GHFunc
)ui_acc_comboboxentry_populate_ghfunc
, &ctx
);
227 /* reatach our model */
228 gtk_combo_box_set_model(GTK_COMBO_BOX(entry_box
), model
);
229 gtk_entry_completion_set_model (completion
, model
);
230 g_object_unref(model
);
232 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model
), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID
, GTK_SORT_ASCENDING
);
239 ui_acc_comboboxentry_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
243 gtk_tree_model_get(model
, a
, 1, &pos1
, -1);
244 gtk_tree_model_get(model
, b
, 1, &pos2
, -1);
245 return (pos1
- pos2
);
250 * ui_acc_comboboxentry_new:
252 * Create a new account comboboxentry
254 * Return value: the new widget
258 ui_acc_comboboxentry_new(GtkWidget
*label
)
261 GtkWidget
*comboboxentry
;
262 GtkEntryCompletion
*completion
;
264 store
= gtk_list_store_new (2, G_TYPE_STRING
, G_TYPE_INT
);
265 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store
), ui_acc_comboboxentry_compare_func
, NULL
, NULL
);
266 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
268 completion
= gtk_entry_completion_new ();
269 gtk_entry_completion_set_model (completion
, GTK_TREE_MODEL(store
));
270 gtk_entry_completion_set_text_column (completion
, 0);
272 /* renderer = gtk_cell_renderer_text_new ();
273 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
274 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (completion), renderer, "text", 0, NULL);
277 comboboxentry
= gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store
));
278 gtk_entry_set_completion (GTK_ENTRY (gtk_bin_get_child(GTK_BIN (comboboxentry
))), completion
);
279 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(comboboxentry
), 0);
281 /* gtk_cell_layout_clear(GTK_CELL_LAYOUT (comboboxentry));
283 renderer = gtk_cell_renderer_text_new ();
284 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (comboboxentry), renderer, TRUE);
285 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (comboboxentry), renderer, "text", 0, NULL);
287 g_object_unref(store
);
290 gtk_label_set_mnemonic_widget (GTK_LABEL(label
), comboboxentry
);
292 gtk_widget_set_size_request(comboboxentry
, HB_MINWIDTH_COMBO
, -1);
294 return comboboxentry
;
297 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
301 ui_acc_listview_toggled_cb (GtkCellRendererToggle
*cell
,
305 GtkTreeModel
*model
= (GtkTreeModel
*)data
;
307 GtkTreePath
*path
= gtk_tree_path_new_from_string (path_str
);
310 /* get toggled iter */
311 gtk_tree_model_get_iter (model
, &iter
, path
);
312 gtk_tree_model_get (model
, &iter
, LST_DEFACC_TOGGLE
, &fixed
, -1);
314 /* do something with the value */
318 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, LST_DEFACC_TOGGLE
, fixed
, -1);
321 gtk_tree_path_free (path
);
325 ui_acc_listview_compare_func (GtkTreeModel
*model
, GtkTreeIter
*a
, GtkTreeIter
*b
, gpointer userdata
)
328 Account
*entry1
, *entry2
;
329 //gchar *name1, *name2;
331 gtk_tree_model_get(model
, a
, LST_DEFACC_DATAS
, &entry1
, -1);
332 gtk_tree_model_get(model
, b
, LST_DEFACC_DATAS
, &entry2
, -1);
334 retval
= entry1
->pos
- entry2
->pos
;
340 ui_acc_listview_name_cell_data_function (GtkTreeViewColumn
*col
,
341 GtkCellRenderer
*renderer
,
352 gtk_tree_model_get(model
, iter
, LST_DEFACC_DATAS
, &entry
, -1);
353 if(entry
->name
== NULL
)
354 name
= _("(none)"); // can never occurs !
359 string
= g_strdup_printf ("[%d] %s", entry
->key
, name
);
360 g_object_set(renderer
, "text", string
, NULL
);
363 g_object_set(renderer
, "text", name
, NULL
);
370 /* = = = = = = = = = = = = = = = = */
375 * Add a single element (useful for dynamics add)
381 ui_acc_listview_add(GtkTreeView
*treeview
, Account
*item
)
383 if( item
->name
!= NULL
)
388 model
= gtk_tree_view_get_model(treeview
);
390 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
391 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
392 LST_DEFACC_TOGGLE
, FALSE
,
393 LST_DEFACC_DATAS
, item
,
396 gtk_tree_selection_select_iter (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
)), &iter
);
402 ui_acc_listview_get_selected_key(GtkTreeView
*treeview
)
404 GtkTreeSelection
*selection
;
408 selection
= gtk_tree_view_get_selection(treeview
);
409 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
413 gtk_tree_model_get(model
, &iter
, LST_DEFACC_DATAS
, &item
, -1);
422 ui_acc_listview_remove_selected(GtkTreeView
*treeview
)
424 GtkTreeSelection
*selection
;
428 selection
= gtk_tree_view_get_selection(treeview
);
429 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
431 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
436 static gint
ui_acc_glist_compare_func(Account
*a
, Account
*b
)
438 return ((gint
)a
->pos
- b
->pos
);
442 void ui_acc_listview_populate(GtkWidget
*view
, gint insert_type
)
448 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(view
));
450 gtk_list_store_clear (GTK_LIST_STORE(model
));
452 g_object_ref(model
); /* Make sure the model stays with us after the tree view unrefs it */
453 gtk_tree_view_set_model(GTK_TREE_VIEW(view
), NULL
); /* Detach model from view */
456 //g_hash_table_foreach(GLOBALS->h_acc, (GHFunc)ui_acc_listview_populate_ghfunc, model);
457 list
= g_hash_table_get_values(GLOBALS
->h_acc
);
459 lacc
= list
= g_list_sort(list
, (GCompareFunc
)ui_acc_glist_compare_func
);
462 Account
*item
= list
->data
;
464 if( insert_type
== ACC_LST_INSERT_REPORT
)
466 if( (item
->flags
& AF_CLOSED
) ) goto next1
;
467 if( (item
->flags
& AF_NOREPORT
) ) goto next1
;
470 DB( g_print(" populate: %d\n", item
->key
) );
472 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
473 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
474 LST_DEFACC_TOGGLE
, FALSE
,
475 LST_DEFACC_DATAS
, item
,
479 list
= g_list_next(list
);
483 gtk_tree_view_set_model(GTK_TREE_VIEW(view
), model
); /* Re-attach model to view */
484 g_object_unref(model
);
489 ui_acc_listview_new(gboolean withtoggle
)
493 GtkCellRenderer
*renderer
;
494 GtkTreeViewColumn
*column
;
497 store
= gtk_list_store_new(NUM_LST_DEFACC
,
503 treeview
= gtk_tree_view_new_with_model(GTK_TREE_MODEL(store
));
504 g_object_unref(store
);
506 //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE);
509 if( withtoggle
== TRUE
)
511 renderer
= gtk_cell_renderer_toggle_new ();
512 column
= gtk_tree_view_column_new_with_attributes (_("Visible"),
514 "active", LST_DEFACC_TOGGLE
,
516 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
518 g_signal_connect (renderer
, "toggled",
519 G_CALLBACK (ui_acc_listview_toggled_cb
), store
);
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_acc_listview_name_cell_data_function
, GINT_TO_POINTER(LST_DEFACC_DATAS
), NULL
);
528 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview
), column
);
531 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview
), FALSE
);
532 gtk_tree_view_set_reorderable (GTK_TREE_VIEW(treeview
), TRUE
);
534 gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store
), ui_acc_listview_compare_func
, NULL
, NULL
);
535 //gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
540 /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
543 ** get widgets contents to the selected account
546 static void ui_acc_manage_get(GtkWidget *widget, gpointer user_data)
548 struct ui_acc_manage_data *data;
549 GtkTreeSelection *selection;
558 gint field = GPOINTER_TO_INT(user_data);
560 DB( g_print("(ui_acc_manage_) get %d\n", field) );
562 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
564 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_acc));
565 //if true there is a selected node
566 if (gtk_tree_selection_get_selected(selection, &model, &iter))
568 gtk_tree_model_get(model, &iter, LST_DEFACC_DATAS, &item, -1);
575 txt = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_name));
576 // ignore if entry is empty
579 bool = account_rename(item, txt);
582 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_acc));
586 gtk_entry_set_text(GTK_ENTRY(data->ST_name), item->name);
591 //todo: for stock account
594 // item->type = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_type));
598 g_free(item->bankname);
599 item->bankname = g_strdup(gtk_entry_get_text(GTK_ENTRY(data->ST_bank)));
603 g_free(item->number);
604 item->number = g_strdup(gtk_entry_get_text(GTK_ENTRY(data->ST_number)));
608 item->flags &= ~(AF_BUDGET);
609 bool = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_nobudget));
610 if(bool) item->flags |= AF_BUDGET;
614 item->flags &= ~(AF_CLOSED);
615 bool = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_closed));
616 if(bool) item->flags |= AF_CLOSED;
620 value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->ST_initial));
621 item->initial = value;
625 value = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->ST_minimum));
626 item->minimum = value;
630 item->cheque1 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->ST_cheque1));
634 item->cheque2 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data->ST_cheque2));
643 static gchar
*dialog_get_name(gchar
*title
, gchar
*origname
, GtkWindow
*parentwindow
)
645 GtkWidget
*dialog
, *content
, *mainvbox
, *getwidget
;
646 gchar
*retval
= NULL
;
648 dialog
= gtk_dialog_new_with_buttons (title
,
649 GTK_WINDOW (parentwindow
),
657 content
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
659 mainvbox
= gtk_vbox_new (FALSE
, 0);
660 gtk_box_pack_start (GTK_BOX (content
), mainvbox
, TRUE
, TRUE
, 0);
661 gtk_container_set_border_width (GTK_CONTAINER (mainvbox
), HB_BOX_SPACING
);
663 getwidget
= gtk_entry_new();
664 gtk_box_pack_start (GTK_BOX (mainvbox
), getwidget
, TRUE
, TRUE
, 0);
665 gtk_widget_show_all(mainvbox
);
668 gtk_entry_set_text(GTK_ENTRY(getwidget
), origname
);
669 gtk_widget_grab_focus (getwidget
);
671 gtk_entry_set_activates_default (GTK_ENTRY(getwidget
), TRUE
);
673 gtk_dialog_set_default_response(GTK_DIALOG( dialog
), GTK_RESPONSE_ACCEPT
);
676 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
678 if(result
== GTK_RESPONSE_ACCEPT
)
682 name
= gtk_entry_get_text(GTK_ENTRY(getwidget
));
684 /* ignore if entry is empty */
687 retval
= g_strdup(name
);
691 // cleanup and destroy
692 gtk_widget_destroy (dialog
);
702 static void ui_acc_manage_getlast(struct ui_acc_manage_data
*data
)
708 DB( g_print("\n(ui_acc_manage_getlast)\n") );
710 DB( g_print(" -> for account id=%d\n", data
->lastkey
) );
712 item
= da_acc_get(data
->lastkey
);
717 item
->type
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_type
));
719 //account_set_currency(item, ui_cur_combobox_get_key(GTK_COMBO_BOX(data->CY_curr)) );
721 g_free(item
->bankname
);
722 item
->bankname
= g_strdup(gtk_entry_get_text(GTK_ENTRY(data
->ST_bank
)));
724 g_free(item
->number
);
725 item
->number
= g_strdup(gtk_entry_get_text(GTK_ENTRY(data
->ST_number
)));
727 item
->flags
&= ~(AF_CLOSED
);
728 bool = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_closed
));
729 if(bool) item
->flags
|= AF_CLOSED
;
731 item
->flags
&= ~(AF_NOBUDGET
);
732 bool = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_nobudget
));
733 if(bool) item
->flags
|= AF_NOBUDGET
;
735 item
->flags
&= ~(AF_NOSUMMARY
);
736 bool = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_nosummary
));
737 if(bool) item
->flags
|= AF_NOSUMMARY
;
739 item
->flags
&= ~(AF_NOREPORT
);
740 bool = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_noreport
));
741 if(bool) item
->flags
|= AF_NOREPORT
;
743 gtk_spin_button_update(GTK_SPIN_BUTTON(data
->ST_initial
));
744 value
= gtk_spin_button_get_value(GTK_SPIN_BUTTON(data
->ST_initial
));
745 item
->initial
= value
;
747 gtk_spin_button_update(GTK_SPIN_BUTTON(data
->ST_minimum
));
748 value
= gtk_spin_button_get_value(GTK_SPIN_BUTTON(data
->ST_minimum
));
749 item
->minimum
= value
;
751 gtk_spin_button_update(GTK_SPIN_BUTTON(data
->ST_cheque1
));
752 item
->cheque1
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data
->ST_cheque1
));
754 gtk_spin_button_update(GTK_SPIN_BUTTON(data
->ST_cheque2
));
755 item
->cheque2
= gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(data
->ST_cheque2
));
765 ** set widgets contents from the selected account
767 static void ui_acc_manage_set(GtkWidget
*widget
, gpointer user_data
)
769 struct ui_acc_manage_data
*data
;
770 GtkTreeSelection
*selection
;
775 DB( g_print("\n(ui_acc_manage_set)\n") );
777 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
779 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_acc
));
780 //if true there is a selected node
781 if (gtk_tree_selection_get_selected(selection
, &model
, &iter
))
783 gtk_tree_model_get(model
, &iter
, LST_DEFACC_DATAS
, &item
, -1);
785 DB( g_print(" -> set acc id=%d\n", item
->key
) );
787 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_type
), item
->type
);
789 //ui_cur_combobox_set_active(GTK_COMBO_BOX(data->CY_curr), item->kcur);
791 if(item
->bankname
!= NULL
)
792 gtk_entry_set_text(GTK_ENTRY(data
->ST_bank
), item
->bankname
);
794 gtk_entry_set_text(GTK_ENTRY(data
->ST_bank
), "");
796 if(item
->number
!= NULL
)
797 gtk_entry_set_text(GTK_ENTRY(data
->ST_number
), item
->number
);
799 gtk_entry_set_text(GTK_ENTRY(data
->ST_number
), "");
802 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_nobudget
), item
->flags
& AF_NOBUDGET
);
803 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_nosummary
), item
->flags
& AF_NOSUMMARY
);
804 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_noreport
), item
->flags
& AF_NOREPORT
);
805 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_closed
), item
->flags
& AF_CLOSED
);
807 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->ST_initial
), item
->initial
);
808 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->ST_minimum
), item
->minimum
);
810 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->ST_cheque1
), item
->cheque1
);
811 gtk_spin_button_set_value(GTK_SPIN_BUTTON(data
->ST_cheque2
), item
->cheque2
);
818 static gboolean ui_acc_manage_focus_out(GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
820 ui_acc_manage_get(widget, user_data);
826 ** update the widgets status and contents from action/selection value
828 static void ui_acc_manage_update(GtkWidget
*widget
, gpointer user_data
)
830 struct ui_acc_manage_data
*data
;
833 gboolean selected
, sensitive
;
835 //todo: for stock account
838 DB( g_print("\n(ui_acc_manage_update)\n") );
840 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
841 //window = gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW);
842 //DB( g_print("(defpayee) widget=%08lx, window=%08lx, inst_data=%08lx\n", treeview, window, data) );
844 //if true there is a selected node
845 selected
= gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_acc
)), &model
, &iter
);
846 key
= ui_acc_listview_get_selected_key(GTK_TREE_VIEW(data
->LV_acc
));
848 DB( g_print(" -> selected = %d action = %d key = %d\n", selected
, data
->action
, key
) );
854 // check for archives related
859 DoMethod(data->mwd->LV_arc, MUIM_List_GetEntry, i, &arc);
861 if(arc->arc_Account == acc->acc_Id)
865 // check for transaction related
868 struct Transaction *ope;
870 DoMethod(data->mwd->LV_ope, MUIM_List_GetEntry, i, &ope);
872 if(ope->ope_Account == acc->acc_Id)
877 //todo: for stock account
878 //todo: lock type if oldpos!=0
882 gtk_tree_model_get(model, &iter,
883 LST_DEFACC_NEW, &is_new,
885 gtk_widget_set_sensitive(data->CY_type, is_new);
889 sensitive
= (selected
== TRUE
) ? TRUE
: FALSE
;
890 gtk_widget_set_sensitive(data
->CY_type
, sensitive
);
891 //gtk_widget_set_sensitive(data->CY_curr, sensitive);
892 gtk_widget_set_sensitive(data
->ST_number
, sensitive
);
893 gtk_widget_set_sensitive(data
->ST_bank
, sensitive
);
894 gtk_widget_set_sensitive(data
->CM_nobudget
, sensitive
);
895 gtk_widget_set_sensitive(data
->CM_nosummary
, sensitive
);
896 gtk_widget_set_sensitive(data
->CM_noreport
, sensitive
);
897 gtk_widget_set_sensitive(data
->CM_closed
, sensitive
);
899 gtk_widget_set_sensitive(data
->ST_initial
, sensitive
);
900 gtk_widget_set_sensitive(data
->ST_minimum
, sensitive
);
901 gtk_widget_set_sensitive(data
->ST_cheque1
, sensitive
);
902 gtk_widget_set_sensitive(data
->ST_cheque2
, sensitive
);
905 //sensitive = (data->action == 0) ? TRUE : FALSE;
906 //gtk_widget_set_sensitive(data->LV_acc, sensitive);
907 //gtk_widget_set_sensitive(data->BT_new, sensitive);
909 sensitive
= (selected
== TRUE
&& data
->action
== 0) ? TRUE
: FALSE
;
910 //gtk_widget_set_sensitive(data->BT_mod, sensitive);
911 gtk_widget_set_sensitive(data
->BT_rem
, sensitive
);
915 if(key
!= data
->lastkey
)
917 DB( g_print(" -> should first do a get for account %d\n", data
->lastkey
) );
918 ui_acc_manage_getlast(data
);
921 ui_acc_manage_set(widget
, NULL
);
930 ** add an empty new account to our temp GList and treeview
932 static void ui_acc_manage_add(GtkWidget
*widget
, gpointer user_data
)
934 struct ui_acc_manage_data
*data
;
937 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
938 DB( g_print("\n(ui_acc_manage_add) (data=%x)\n", (guint
)data
) );
940 gchar
*name
= dialog_get_name(_("Account name"), NULL
, GTK_WINDOW(data
->window
));
943 if(account_exists(name
))
945 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_ERROR
,
947 _("Cannot add an account '%s',\n"
948 "this name already exists."),
954 item
= da_acc_malloc();
955 item
->name
= name
; //g_strdup_printf( _("(account %d)"), da_acc_length()+1);
956 //item->kcur = GLOBALS->kcur;
959 ui_acc_listview_add(GTK_TREE_VIEW(data
->LV_acc
), item
);
967 ** remove the selected account to our treeview and temp GList
969 static void ui_acc_manage_remove(GtkWidget
*widget
, gpointer user_data
)
971 struct ui_acc_manage_data
*data
;
976 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
977 DB( g_print("\n(ui_acc_manage_remove) (data=%x)\n", (guint
)data
) );
980 key
= ui_acc_listview_get_selected_key(GTK_TREE_VIEW(data
->LV_acc
));
983 if( account_is_used(key
) == TRUE
)
985 //item = da_acc_get(key);
987 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_INFO
,
988 _("Remove not allowed"),
989 _("This account is used and cannot be removed.")
997 ui_acc_listview_remove_selected(GTK_TREE_VIEW(data
->LV_acc
));
1009 ** rename the selected account to our treeview and temp GList
1011 static void ui_acc_manage_rename(GtkWidget
*widget
, gpointer user_data
)
1013 struct ui_acc_manage_data
*data
;
1018 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1019 DB( g_print("\n(ui_acc_manage_rename) (data=%x)\n", (guint
)data
) );
1021 key
= ui_acc_listview_get_selected_key(GTK_TREE_VIEW(data
->LV_acc
));
1024 item
= da_acc_get(key
);
1026 gchar
*name
= dialog_get_name(_("Account name"), item
->name
, GTK_WINDOW(data
->window
));
1029 if(account_exists(name
))
1031 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_ERROR
,
1033 _("Cannot rename this Account,\n"
1034 "from '%s' to '%s',\n"
1035 "this name already exists."),
1042 bool = account_rename(item
, name
);
1045 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_acc
));
1056 static void ui_acc_manage_rowactivated (GtkTreeView
*treeview
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer userdata
)
1058 //struct account_data *data;
1060 //data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW)), "inst_data");
1062 ui_acc_manage_rename(GTK_WIDGET(treeview
), NULL
);
1072 static void ui_acc_manage_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1074 ui_acc_manage_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), NULL
);
1077 //gint ui_acc_manage_list_sort(struct _Account *a, struct _Account *b) { return( a->acc_Id - b->acc_Id); }
1082 static gboolean
ui_acc_manage_cleanup(struct ui_acc_manage_data
*data
, gint result
)
1084 GtkTreeModel
*model
;
1089 gboolean doupdate
= FALSE
;
1091 DB( g_print("\n(ui_acc_manage_cleanup) %x\n", (guint
)data
) );
1093 key
= ui_acc_listview_get_selected_key(GTK_TREE_VIEW(data
->LV_acc
));
1096 data
->lastkey
= key
;
1097 DB( g_print(" -> should first do a get for account %d\n", data
->lastkey
) );
1098 ui_acc_manage_getlast(data
);
1101 // test for change & store new position
1102 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_acc
));
1103 i
=1; valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
1108 gtk_tree_model_get(GTK_TREE_MODEL(model
), &iter
,
1109 LST_DEFACC_DATAS
, &item
,
1112 DB( g_print(" -> check acc %d, pos is %d, %s\n", i
, item
->pos
, item
->name
) );
1119 // Make iter point to the next row in the list store
1120 i
++; valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
1123 GLOBALS
->changes_count
+= data
->change
;
1131 static void ui_acc_manage_setup(struct ui_acc_manage_data
*data
)
1134 DB( g_print("\n(ui_acc_manage_setup)\n") );
1137 data
->tmp_list
= NULL
; //hb-glist_clone_list(GLOBALS->acc_list, sizeof(struct _Account));
1142 ui_acc_listview_populate(data
->LV_acc
, ACC_LST_INSERT_NORMAL
);
1143 //ui_cur_combobox_populate(data->CY_curr, GLOBALS->h_cur);
1144 //populate_view_acc(data->LV_acc, GLOBALS->acc_list, TRUE);
1150 GtkWidget
*ui_acc_manage_dialog (void)
1152 struct ui_acc_manage_data data
;
1153 GtkWidget
*dialog
, *content
, *mainbox
, *scrollwin
, *notebook
, *alignment
;
1154 GtkWidget
*table
, *label
, *widget
, *hpaned
;
1157 dialog
= gtk_dialog_new_with_buttons (_("Manage Accounts"),
1158 GTK_WINDOW(GLOBALS
->mainwindow
),
1161 GTK_RESPONSE_ACCEPT
,
1164 data
.window
= dialog
;
1166 //set the dialog icon
1167 //homebank_window_set_icon_from_file(GTK_WINDOW (dialog), "account.svg");
1168 gtk_window_set_icon_name(GTK_WINDOW (dialog
), HB_STOCK_ACCOUNT
);
1170 //store our dialog private data
1171 g_object_set_data(G_OBJECT(dialog
), "inst_data", (gpointer
)&data
);
1172 DB( g_print("(ui_acc_manage_) dialog=%x, inst_data=%x\n", (guint
)dialog
, (guint
)&data
) );
1175 content
= gtk_dialog_get_content_area(GTK_DIALOG (dialog
));
1176 mainbox
= gtk_hbox_new (FALSE
, HB_BOX_SPACING
);
1177 gtk_box_pack_start (GTK_BOX (content
), mainbox
, TRUE
, TRUE
, 0);
1178 gtk_container_set_border_width (GTK_CONTAINER(mainbox
), HB_MAINBOX_SPACING
);
1180 hpaned
= gtk_hpaned_new();
1181 gtk_box_pack_start (GTK_BOX (mainbox
), hpaned
, TRUE
, TRUE
, 0);
1184 table
= gtk_table_new (2, 2, FALSE
);
1185 gtk_table_set_row_spacings (GTK_TABLE (table
), HB_TABROW_SPACING
);
1186 gtk_table_set_col_spacings (GTK_TABLE (table
), HB_TABCOL_SPACING
);
1187 gtk_paned_pack1 (GTK_PANED(hpaned
), table
, FALSE
, FALSE
);
1190 scrollwin
= gtk_scrolled_window_new(NULL
,NULL
);
1191 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin
), GTK_POLICY_NEVER
, GTK_POLICY_AUTOMATIC
);
1192 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollwin
), GTK_SHADOW_ETCHED_IN
);
1193 data
.LV_acc
= ui_acc_listview_new(FALSE
);
1194 gtk_widget_set_size_request(data
.LV_acc
, HB_MINWIDTH_LIST
, -1);
1195 gtk_container_add(GTK_CONTAINER(scrollwin
), data
.LV_acc
);
1196 gtk_widget_set_tooltip_text(data
.LV_acc
, _("Drag & drop to change the order\nDouble-click to rename"));
1197 gtk_table_attach_defaults (GTK_TABLE (table
), scrollwin
, 0, 2, row
, row
+1);
1201 widget
= gtk_button_new_from_stock(GTK_STOCK_ADD
);
1202 data
.BT_add
= widget
;
1203 gtk_table_attach (GTK_TABLE (table
), widget
, 0, 1, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
|GTK_EXPAND
), (GtkAttachOptions
) (0), 0, 0);
1204 widget
= gtk_button_new_from_stock(GTK_STOCK_REMOVE
);
1205 data
.BT_rem
= widget
;
1206 gtk_table_attach (GTK_TABLE (table
), widget
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
|GTK_EXPAND
), (GtkAttachOptions
) (0), 0, 0);
1210 notebook
= gtk_notebook_new();
1211 //gtk_box_pack_start (GTK_BOX (mainbox), notebook, TRUE, TRUE, 0);
1212 gtk_paned_pack2 (GTK_PANED(hpaned
), notebook
, FALSE
, FALSE
);
1215 table
= gtk_table_new (8, 3, FALSE
);
1216 gtk_table_set_row_spacings (GTK_TABLE (table
), HB_TABROW_SPACING
);
1217 gtk_table_set_col_spacings (GTK_TABLE (table
), HB_TABCOL_SPACING
);
1218 gtk_container_set_border_width (GTK_CONTAINER(table
), HB_MAINBOX_SPACING
);
1219 // gtk_alignment_new(xalign, yalign, xscale, yscale)
1220 alignment
= gtk_alignment_new(0.5, 0, 1.0, 0.0);
1221 gtk_container_add(GTK_CONTAINER(alignment
), table
);
1222 label
= gtk_label_new(_("General"));
1223 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), alignment
, label
);
1226 label
= make_label(_("Account"), 0.0, 0.5);
1227 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
1228 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 3, row
, row
+1);
1231 label
= make_label(_("_Type:"), 0.0, 0.5);
1232 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1233 widget
= make_cycle(label
, CYA_ACC_TYPE
);
1234 data
.CY_type
= widget
;
1235 gtk_table_attach (GTK_TABLE (table
), widget
, 2, 3, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1239 label = make_label(_("_Currency:"), 0.0, 0.5);
1240 gtk_table_attach (GTK_TABLE (table), label, 1, 2, row, row+1, (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1241 widget = ui_cur_combobox_new(label);
1242 data.CY_curr = widget;
1243 gtk_table_attach (GTK_TABLE (table), widget, 2, 3, row, row+1, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), (GtkAttachOptions) (0), 0, 0);
1247 label
= make_label (_("Start _balance:"), 0.0, 0.5);
1248 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), 0, 0);
1249 widget
= make_amount(label
);
1250 data
.ST_initial
= widget
;
1251 gtk_table_attach (GTK_TABLE (table
), widget
, 2, 3, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1256 widget
= gtk_check_button_new_with_mnemonic (_("this account was _closed"));
1257 data
.CM_closed
= widget
;
1258 gtk_table_attach (GTK_TABLE (table
), widget
, 1, 3, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1262 label
= make_label(_("Current check number"), 0.0, 0.5);
1263 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
1264 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 3, row
, row
+1);
1267 label
= make_label(_("Checkbook _1:"), 0.0, 0.5);
1268 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1269 widget
= make_long (label
);
1270 data
.ST_cheque1
= widget
;
1271 gtk_table_attach (GTK_TABLE (table
), widget
, 2, 3, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1274 label
= make_label(_("Checkbook _2:"), 0.0, 0.5);
1275 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1276 widget
= make_long (label
);
1277 data
.ST_cheque2
= widget
;
1278 gtk_table_attach (GTK_TABLE (table
), widget
, 2, 3, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1282 table
= gtk_table_new (9, 3, FALSE
);
1283 gtk_table_set_row_spacings (GTK_TABLE (table
), HB_TABROW_SPACING
);
1284 gtk_table_set_col_spacings (GTK_TABLE (table
), HB_TABCOL_SPACING
);
1285 gtk_container_set_border_width (GTK_CONTAINER(table
), HB_MAINBOX_SPACING
);
1286 // gtk_alignment_new(xalign, yalign, xscale, yscale)
1287 alignment
= gtk_alignment_new(0.5, 0, 1.0, 0.0);
1288 gtk_container_add(GTK_CONTAINER(alignment
), table
);
1289 label
= gtk_label_new(_("Options"));
1290 gtk_notebook_append_page(GTK_NOTEBOOK(notebook
), alignment
, label
);
1294 label
= make_label(_("Institution"), 0.0, 0.5);
1295 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
1296 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 3, row
, row
+1);
1299 label
= make_label(_("_Name:"), 0.0, 0.5);
1300 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1,(GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1301 widget
= make_string(label
);
1302 data
.ST_bank
= widget
;
1303 gtk_table_attach (GTK_TABLE (table
), widget
, 2, 3, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1306 label
= make_label(_("N_umber:"), 0.0, 0.5);
1307 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1308 widget
= make_string(label
);
1309 data
.ST_number
= widget
;
1310 gtk_table_attach (GTK_TABLE (table
), widget
, 2, 3, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1313 label
= make_label(_("Limits"), 0.0, 0.5);
1314 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
1315 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 3, row
, row
+1);
1317 //TODO: warning/absolute minimum balance
1320 label
= make_label (_("_Min. balance:"), 0.0, 0.5);
1321 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1322 widget
= make_amount(label
);
1323 data
.ST_minimum
= widget
;
1324 gtk_table_attach (GTK_TABLE (table
), widget
, 2, 3, row
, row
+1, (GtkAttachOptions
) (GTK_EXPAND
| GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1327 label
= make_label(_("Report exclusion"), 0.0, 0.5);
1328 gimp_label_set_attributes(GTK_LABEL(label
), PANGO_ATTR_WEIGHT
, PANGO_WEIGHT_BOLD
, -1);
1329 gtk_table_attach_defaults (GTK_TABLE (table
), label
, 0, 3, row
, row
+1);
1332 widget
= gtk_check_button_new_with_mnemonic (_("exclude from account _summary"));
1333 data
.CM_nosummary
= widget
;
1334 gtk_table_attach (GTK_TABLE (table
), widget
, 1, 3, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1337 widget
= gtk_check_button_new_with_mnemonic (_("exclude from the _budget"));
1338 data
.CM_nobudget
= widget
;
1339 gtk_table_attach (GTK_TABLE (table
), widget
, 1, 3, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1342 widget
= gtk_check_button_new_with_mnemonic (_("exclude from any _reports"));
1343 data
.CM_noreport
= widget
;
1344 gtk_table_attach (GTK_TABLE (table
), widget
, 1, 3, row
, row
+1, (GtkAttachOptions
) (GTK_FILL
), (GtkAttachOptions
) (0), 0, 0);
1347 //connect all our signals
1348 g_signal_connect (dialog
, "destroy", G_CALLBACK (gtk_widget_destroyed
), &dialog
);
1349 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data
.LV_acc
)), "changed", G_CALLBACK (ui_acc_manage_selection
), NULL
);
1350 g_signal_connect (GTK_TREE_VIEW(data
.LV_acc
), "row-activated", G_CALLBACK (ui_acc_manage_rowactivated
), GINT_TO_POINTER(2));
1352 g_signal_connect (G_OBJECT (data
.BT_add
), "clicked", G_CALLBACK (ui_acc_manage_add
), NULL
);
1353 g_signal_connect (G_OBJECT (data
.BT_rem
), "clicked", G_CALLBACK (ui_acc_manage_remove
), NULL
);
1355 //setup, init and show window
1356 ui_acc_manage_setup(&data
);
1357 ui_acc_manage_update(data
.LV_acc
, NULL
);
1359 // gtk_window_set_default_size (GTK_WINDOW (window), 640, 480);
1361 gtk_widget_show_all (dialog
);
1364 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
1366 // cleanup and destroy
1367 ui_acc_manage_cleanup(&data
, result
);
1368 gtk_widget_destroy (dialog
);