1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 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/>.
23 #include "dsp-account.h"
24 #include "dsp-mainwindow.h"
26 #include "list-operation.h"
27 #include "hub-account.h"
29 #include "ui-widgets.h"
30 #include "ui-filter.h"
31 #include "ui-transaction.h"
32 #include "ui-txn-multi.h"
34 /****************************************************************************/
36 /****************************************************************************/
45 /* our global datas */
46 extern struct HomeBank
*GLOBALS
;
47 extern struct Preferences
*PREFS
;
53 extern gchar
*CYA_FLT_TYPE
[];
54 extern gchar
*CYA_FLT_STATUS
[];
57 static void register_panel_collect_filtered_txn(GtkWidget
*view
, gboolean emptysearch
);
58 static void register_panel_listview_populate(GtkWidget
*view
);
59 static void register_panel_action(GtkWidget
*widget
, gpointer user_data
);
60 static void register_panel_update(GtkWidget
*widget
, gpointer user_data
);
62 static void register_panel_export_csv(GtkWidget
*widget
, gpointer user_data
);
64 static void register_panel_make_archive(GtkWidget
*widget
, gpointer user_data
);
66 static void status_selected_foreach_func (GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
, gpointer userdata
);
68 static void register_panel_edit_multiple(GtkWidget
*widget
, Transaction
*txn
, gint column_id
, gpointer user_data
);
70 static void register_panel_selection(GtkTreeSelection
*treeselection
, gpointer user_data
);
71 static void register_panel_onRowActivated (GtkTreeView
*treeview
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer userdata
);
74 /* account action functions -------------------- */
76 static void register_panel_action_editfilter(GtkAction
*action
, gpointer user_data
)
78 struct register_panel_data
*data
= user_data
;
80 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_FILTER
));
84 static void register_panel_action_add(GtkAction
*action
, gpointer user_data
)
86 struct register_panel_data
*data
= user_data
;
88 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_ADD
));
91 static void register_panel_action_inherit(GtkAction
*action
, gpointer user_data
)
93 struct register_panel_data
*data
= user_data
;
95 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_INHERIT
));
98 static void register_panel_action_edit(GtkAction
*action
, gpointer user_data
)
100 struct register_panel_data
*data
= user_data
;
102 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_EDIT
));
105 static void register_panel_action_multiedit(GtkAction
*action
, gpointer user_data
)
107 struct register_panel_data
*data
= user_data
;
109 register_panel_edit_multiple(data
->window
, NULL
, 0, user_data
);
112 static void register_panel_action_reconcile(GtkAction
*action
, gpointer user_data
)
114 struct register_panel_data
*data
= user_data
;
116 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_RECONCILE
));
119 static void register_panel_action_clear(GtkAction
*action
, gpointer user_data
)
121 struct register_panel_data
*data
= user_data
;
123 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_CLEAR
));
126 static void register_panel_action_none(GtkAction
*action
, gpointer user_data
)
128 struct register_panel_data
*data
= user_data
;
130 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_NONE
));
133 static void register_panel_action_remove(GtkAction
*action
, gpointer user_data
)
135 struct register_panel_data
*data
= user_data
;
137 register_panel_action(data
->window
, GINT_TO_POINTER(ACTION_ACCOUNT_DELETE
));
142 static void register_panel_action_createtemplate(GtkAction
*action
, gpointer user_data
)
144 struct register_panel_data
*data
= user_data
;
146 register_panel_make_archive(data
->window
, NULL
);
151 static void register_panel_action_exportcsv(GtkAction
*action
, gpointer user_data
)
153 struct register_panel_data
*data
= user_data
;
155 register_panel_export_csv(data
->window
, NULL
);
159 /* = = = = = = = = future version = = = = = = = = */
161 static void register_panel_action_exportpdf(GtkAction
*action
, gpointer user_data
)
163 struct register_panel_data
*data
= user_data
;
164 gchar
*name
, *filepath
;
166 if(data
->showall
== FALSE
)
168 name
= g_strdup_printf("%s.pdf", data
->acc
->name
);
169 filepath
= g_build_filename(PREFS
->path_export
, name
, NULL
);
172 if( ui_dialog_export_pdf(GTK_WINDOW(data
->window
), &filepath
) == GTK_RESPONSE_ACCEPT
)
174 DB( g_printf(" filename is'%s'\n", filepath
) );
177 hb_export_pdf_listview(GTK_TREE_VIEW(data
->LV_ope
), filepath
, data
->acc
->name
);
186 static void register_panel_action_duplicate_mark(GtkAction
*action
, gpointer user_data
)
188 struct register_panel_data
*data
= user_data
;
190 DB( g_print("check duplicate\n\n") );
192 // open dialog to select date tolerance in days
194 // with check/fix button and progress bar
195 // parse listview txn, clear/mark duplicate
198 if(data
->showall
== FALSE
)
202 daygap
= gtk_spin_button_get_value(GTK_SPIN_BUTTON(data
->NB_txn_daygap
));
203 data
->similar
= transaction_similar_mark (data
->acc
, daygap
);
204 if( data
->similar
> 0 )
206 gchar
*text
= g_strdup_printf(_("There is %d group of similar transactions"), data
->similar
);
207 gtk_label_set_text(GTK_LABEL(data
->LB_duplicate
), text
);
211 gtk_label_set_text(GTK_LABEL(data
->LB_duplicate
), _("No similar transaction were found !"));
213 gtk_widget_show(data
->IB_duplicate
);
214 //#GTK+710888: hack waiting a fix
215 gtk_widget_queue_resize (data
->IB_duplicate
);
217 gtk_widget_queue_draw (data
->LV_ope
);
224 static void register_panel_action_duplicate_unmark(GtkAction
*action
, gpointer user_data
)
226 struct register_panel_data
*data
= user_data
;
228 DB( g_print("uncheck duplicate\n\n") );
230 if(data
->showall
== FALSE
)
233 gtk_widget_hide(data
->IB_duplicate
);
234 transaction_similar_unmark(data
->acc
);
235 gtk_widget_queue_draw (data
->LV_ope
);
240 static void register_panel_action_check_internal_xfer(GtkAction
*action
, gpointer user_data
)
242 struct register_panel_data
*data
= user_data
;
249 DB( g_print("check intenal xfer\n\n") );
252 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_ope
));
253 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
258 gtk_tree_model_get (model
, &iter
,
259 MODEL_TXN_POINTER
, &txn
,
262 if( txn
->paymode
== PAYMODE_INTXFER
)
264 if( transaction_xfer_child_strong_get(txn
) == NULL
)
266 DB( g_print(" - invalid xfer: '%s'\n", txn
->memo
) );
268 //test unrecoverable (kxferacc = 0)
269 if( txn
->kxferacc
<= 0 )
271 DB( g_print(" - unrecoverable, revert to normal xfer\n") );
272 txn
->flags
|= OF_CHANGED
;
273 txn
->paymode
= PAYMODE_XFER
;
279 badxferlist
= g_list_append(badxferlist
, txn
);
284 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
287 count
= g_list_length (badxferlist
);
288 DB( g_print(" - found %d invalid int xfer\n", count
) );
292 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_INFO
,
293 _("Check internal transfer result"),
294 _("No inconsistency found !")
301 do_fix
= ui_dialog_msg_question(
302 GTK_WINDOW(data
->window
),
303 _("Check internal transfer result"),
304 _("Inconsistency were found: %d\n"
305 "do you want to review and fix ?"),
309 if(do_fix
== GTK_RESPONSE_YES
)
311 GList
*tmplist
= g_list_first(badxferlist
);
313 while (tmplist
!= NULL
)
315 Transaction
*stxn
= tmplist
->data
;
317 //future (open dialog to select date tolerance in days)
318 transaction_xfer_search_or_add_child(GTK_WINDOW(data
->window
), stxn
, 0);
320 tmplist
= g_list_next(tmplist
);
325 g_list_free (badxferlist
);
330 static void register_panel_action_exportqif(GtkAction
*action
, gpointer user_data
)
332 struct register_panel_data
*data
= user_data
;
335 // noaction if show all account
339 DB( g_print("(qif) test qif export\n\n") );
341 if( ui_file_chooser_qif(GTK_WINDOW(data
->window
), &filename
) == TRUE
)
343 hb_export_qif_account_single(filename
, data
->acc
);
349 static void register_panel_action_converttoeuro(GtkAction
*action
, gpointer user_data
)
351 struct register_panel_data
*data
= user_data
;
355 // noaction if show all account
359 DB( g_print("action convert to euro\n") );
361 msg
= g_strdup_printf(_("Every transaction amount will be divided by %.6f."), PREFS
->euro_value
);
363 result
= ui_dialog_msg_confirm_alert(
364 GTK_WINDOW(data
->window
),
365 _("Are you sure you want to convert this account\nto Euro as Major currency?"),
372 if(result
== GTK_RESPONSE_OK
)
374 account_convert_euro(data
->acc
);
375 register_panel_update(data
->LV_ope
, GINT_TO_POINTER(UF_BALANCE
));
380 static void register_panel_action_assign(GtkAction
*action
, gpointer user_data
)
382 struct register_panel_data
*data
= user_data
;
384 gboolean usermode
= TRUE
;
386 // noaction if show all account
390 DB( g_print("action assign\n") );
392 count
= transaction_auto_assign(g_queue_peek_head_link(data
->acc
->txn_queue
), data
->acc
->key
);
393 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_ope
));
394 GLOBALS
->changes_count
+= count
;
402 txt
= _("No transaction changed");
404 txt
= _("transaction changed: %d");
406 ui_dialog_msg_infoerror(GTK_WINDOW(data
->window
), GTK_MESSAGE_INFO
,
407 _("Automatic assignment result"),
414 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
419 static void register_panel_action_close(GtkAction
*action
, gpointer user_data
)
421 struct register_panel_data
*data
= user_data
;
423 DB( g_print("action close\n") );
425 DB( g_print("window %p\n", data
->window
) );
427 gtk_widget_destroy (GTK_WIDGET (data
->window
));
429 //g_signal_emit_by_name(data->window, "delete-event", NULL, &result);
434 /* these 5 functions are independant from account window */
436 /* account functions -------------------- */
438 static void register_panel_export_csv(GtkWidget
*widget
, gpointer user_data
)
440 struct register_panel_data
*data
;
441 gchar
*filename
= NULL
;
445 DB( g_print("\n[account] export csv\n") );
447 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
449 if( ui_file_chooser_csv(GTK_WINDOW(data
->window
), GTK_FILE_CHOOSER_ACTION_SAVE
, &filename
, NULL
) == TRUE
)
451 DB( g_print(" + filename is %s\n", filename
) );
452 io
= g_io_channel_new_file(filename
, "w", NULL
);
455 node
= list_txn_to_string(GTK_TREE_VIEW(data
->LV_ope
), FALSE
);
456 g_io_channel_write_chars(io
, node
->str
, -1, NULL
, NULL
);
457 g_io_channel_unref (io
);
458 g_string_free(node
, TRUE
);
465 static void register_panel_edit_multiple(GtkWidget
*widget
, Transaction
*txn
, gint column_id
, gpointer user_data
)
467 struct register_panel_data
*data
;
470 DB( g_print("\n[account] edit multiple\n") );
472 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
474 DB( g_print(" - txn:%p, column: %d\n", txn
, column_id
) );
476 dialog
= ui_multipleedit_dialog_new(GTK_WINDOW(data
->window
), GTK_TREE_VIEW(data
->LV_ope
));
478 if(txn
!= NULL
&& column_id
!= 0)
480 ui_multipleedit_dialog_prefill(dialog
, txn
, column_id
);
484 gint result
= gtk_dialog_run (GTK_DIALOG (dialog
));
486 if( result
== GTK_RESPONSE_ACCEPT
)
491 //#1792808: sort if date changed
492 changes
= ui_multipleedit_dialog_apply (dialog
, &do_sort
);
493 data
->do_sort
= do_sort
;
496 //#1782749 update account status
497 if( data
->acc
!= NULL
)
498 data
->acc
->flags
|= AF_CHANGED
;
500 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
504 gtk_widget_destroy (dialog
);
506 register_panel_update(data
->LV_ope
, GINT_TO_POINTER(UF_BALANCE
));
511 ** make an archive with the active transaction
513 static void register_panel_make_archive(GtkWidget
*widget
, gpointer user_data
)
515 struct register_panel_data
*data
;
517 GList
*selection
, *list
;
520 DB( g_print("\n[account] make archive\n") );
522 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
525 count
= gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
)));
530 result
= ui_dialog_msg_confirm_alert(
531 GTK_WINDOW(data
->window
),
533 _("Do you want to create a template with\neach of the selected transaction ?"),
538 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
539 _("%d archives will be created"),
540 GLOBALS->changes_count
544 if(result
== GTK_RESPONSE_OK
)
546 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_ope
));
547 selection
= gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
)), &model
);
549 list
= g_list_first(selection
);
556 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
557 gtk_tree_model_get(model
, &iter
, MODEL_TXN_POINTER
, &ope
, -1);
559 DB( g_print(" create archive %s %.2f\n", ope
->memo
, ope
->amount
) );
561 item
= da_archive_malloc();
563 da_archive_init_from_transaction(item
, ope
);
565 //GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, item);
566 da_archive_append_new(item
);
567 GLOBALS
->changes_count
++;
569 list
= g_list_next(list
);
572 g_list_foreach(selection
, (GFunc
)gtk_tree_path_free
, NULL
);
573 g_list_free(selection
);
579 static void register_panel_cb_bar_duplicate_response(GtkWidget
*info_bar
, gint response_id
, gpointer user_data
)
581 struct register_panel_data
*data
;
583 DB( g_print("\n[account] bar_duplicate_response\n") );
585 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(info_bar
, GTK_TYPE_WINDOW
)), "inst_data");
587 switch( response_id
)
589 case HB_RESPONSE_REFRESH
:
590 register_panel_action_duplicate_mark(NULL
, data
);
592 case GTK_RESPONSE_CLOSE
:
593 register_panel_action_duplicate_unmark(NULL
, data
);
594 gtk_widget_hide (GTK_WIDGET (info_bar
));
600 static void register_panel_cb_filter_daterange(GtkWidget
*widget
, gpointer user_data
)
602 struct register_panel_data
*data
;
606 DB( g_print("\n[account] filter_daterange\n") );
608 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
610 range
= hbtk_combo_box_get_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
));
611 future
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_future
));
613 data
->filter
->nbdaysfuture
= 0;
615 if(range
!= FLT_RANGE_OTHER
)
617 filter_preset_daterange_set(data
->filter
, range
, (data
->showall
== FALSE
) ? data
->acc
->key
: 0);
618 // add eventual x days into future display
619 if( future
&& (PREFS
->date_future_nbdays
> 0) )
620 filter_preset_daterange_add_futuregap(data
->filter
, PREFS
->date_future_nbdays
);
622 register_panel_collect_filtered_txn(data
->LV_ope
, FALSE
);
623 register_panel_listview_populate(data
->LV_ope
);
627 if(ui_flt_manage_dialog_new(GTK_WINDOW(data
->window
), data
->filter
, data
->showall
, TRUE
) != GTK_RESPONSE_REJECT
)
629 register_panel_collect_filtered_txn(data
->LV_ope
, FALSE
);
630 register_panel_listview_populate(data
->LV_ope
);
631 register_panel_update(data
->LV_ope
, GINT_TO_POINTER(UF_SENSITIVE
+UF_BALANCE
));
637 static void register_panel_cb_filter_type(GtkWidget
*widget
, gpointer user_data
)
639 struct register_panel_data
*data
;
642 DB( g_print("\n[account] filter_type\n") );
643 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
645 type
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_type
));
647 filter_preset_type_set(data
->filter
, type
);
649 register_panel_collect_filtered_txn(data
->LV_ope
, FALSE
);
650 register_panel_listview_populate(data
->LV_ope
);
654 static void register_panel_cb_filter_status(GtkWidget
*widget
, gpointer user_data
)
656 struct register_panel_data
*data
;
659 DB( g_print("\n[account] filter_status\n") );
660 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
662 status
= gtk_combo_box_get_active(GTK_COMBO_BOX(data
->CY_status
));
664 filter_preset_status_set(data
->filter
, status
);
666 register_panel_collect_filtered_txn(data
->LV_ope
, FALSE
);
667 register_panel_listview_populate(data
->LV_ope
);
671 static void register_panel_cb_filter_reset(GtkWidget
*widget
, gpointer user_data
)
673 struct register_panel_data
*data
;
675 DB( g_print("\n[account] filter_reset\n") );
676 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
678 filter_reset(data
->filter
);
680 filter_preset_daterange_set (data
->filter
, PREFS
->date_range_txn
, (data
->showall
== FALSE
) ? data
->acc
->key
: 0);
682 if(PREFS
->hidereconciled
)
683 filter_preset_status_set (data
->filter
, FLT_STATUS_UNRECONCILED
);
685 // add eventual x days into future display
686 if( PREFS
->date_future_nbdays
> 0 )
687 filter_preset_daterange_add_futuregap(data
->filter
, PREFS
->date_future_nbdays
);
689 register_panel_collect_filtered_txn(data
->LV_ope
, TRUE
);
690 register_panel_listview_populate(data
->LV_ope
);
692 g_signal_handler_block(data
->CY_range
, data
->handler_id
[HID_RANGE
]);
693 g_signal_handler_block(data
->CY_type
, data
->handler_id
[HID_TYPE
]);
694 g_signal_handler_block(data
->CY_status
, data
->handler_id
[HID_STATUS
]);
696 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), data
->filter
->range
);
697 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_type
), data
->filter
->type
);
698 gtk_combo_box_set_active(GTK_COMBO_BOX(data
->CY_status
), data
->filter
->status
);
700 g_signal_handler_unblock(data
->CY_status
, data
->handler_id
[HID_STATUS
]);
701 g_signal_handler_unblock(data
->CY_type
, data
->handler_id
[HID_TYPE
]);
702 g_signal_handler_unblock(data
->CY_range
, data
->handler_id
[HID_RANGE
]);
707 static void register_panel_balance_refresh(GtkWidget
*view
)
709 struct register_panel_data
*data
;
716 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(view
, GTK_TYPE_WINDOW
)), "inst_data");
718 // noaction if show all account
722 DB( g_print("\n[account %d] balance refresh\n", data
->acc
!= NULL
? (gint
)data
->acc
->key
: -1) );
724 balance
= data
->acc
->initial
;
726 //#1270687: sort if date changed
729 DB( g_print(" - complete txn sort\n") );
731 da_transaction_queue_sort(data
->acc
->txn_queue
);
732 data
->do_sort
= FALSE
;
735 list
= g_queue_peek_head_link(data
->acc
->txn_queue
);
738 Transaction
*ope
= list
->data
;
742 if(!(ope
->status
== TXN_STATUS_REMIND
))
743 balance
+= ope
->amount
;
745 ope
->balance
= balance
;
747 //#1661806 add show overdraft
748 //#1672209 added round like for #400483
749 ope
->overdraft
= FALSE
;
750 value
= hb_amount_round(balance
, 2);
751 if( value
!= 0.0 && value
< data
->acc
->minimum
)
752 ope
->overdraft
= TRUE
;
754 if(ope
->date
== ldate
)
764 list
= g_list_next(list
);
767 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_ope
));
768 list_txn_sort_force(GTK_TREE_SORTABLE(model
), NULL
);
773 static void register_panel_collect_filtered_txn(GtkWidget
*view
, gboolean emptysearch
)
775 struct register_panel_data
*data
;
776 GList
*lst_acc
, *lnk_acc
;
779 DB( g_print("\n[register_panel] collect_filtered_txn\n") );
781 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(view
, GTK_TYPE_WINDOW
)), "inst_data");
783 if(data
->gpatxn
!= NULL
)
784 g_ptr_array_free (data
->gpatxn
, TRUE
);
787 data
->gpatxn
= g_ptr_array_sized_new(64);
789 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
790 lnk_acc
= g_list_first(lst_acc
);
791 while (lnk_acc
!= NULL
)
793 Account
*acc
= lnk_acc
->data
;
795 // skip closed in showall mode
796 if( data
->showall
== TRUE
&& (acc
->flags
& AF_CLOSED
) )
799 // skip other than current in normal mode
800 if( (data
->showall
== FALSE
) && (data
->acc
!= NULL
) && (acc
->key
!= data
->acc
->key
) )
803 lnk_txn
= g_queue_peek_head_link(acc
->txn_queue
);
804 while (lnk_txn
!= NULL
)
806 Transaction
*ope
= lnk_txn
->data
;
808 if(filter_txn_match(data
->filter
, ope
) == 1)
811 g_ptr_array_add(data
->gpatxn
, (gpointer
)ope
);
813 lnk_txn
= g_list_next(lnk_txn
);
817 lnk_acc
= g_list_next(lnk_acc
);
819 g_list_free(lst_acc
);
821 //#1789698 not always empty
822 if( emptysearch
== TRUE
)
824 g_signal_handler_block(data
->ST_search
, data
->handler_id
[HID_SEARCH
]);
825 gtk_entry_set_text (GTK_ENTRY(data
->ST_search
), "");
826 g_signal_handler_unblock(data
->ST_search
, data
->handler_id
[HID_SEARCH
]);
831 static void register_panel_listview_populate(GtkWidget
*widget
)
833 struct register_panel_data
*data
;
842 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
844 DB( g_print("\n[register_panel] listview_populate\n") );
846 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_ope
));
848 // ref model to keep it
849 //g_object_ref(model);
850 //gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_ope), NULL);
851 gtk_list_store_clear (GTK_LIST_STORE(model
));
854 // perf: if you leave the sort, insert is damned slow
855 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE(GTK_LIST_STORE(model
)), &sort_column_id
, &order
);
857 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GTK_LIST_STORE(model
)), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID
, PREFS
->lst_ope_sort_order
);
859 hastext
= gtk_entry_get_text_length (GTK_ENTRY(data
->ST_search
)) >= 2;
860 needle
= (gchar
*)gtk_entry_get_text(GTK_ENTRY(data
->ST_search
));
862 //build the mask flag for quick search
866 qs_flag
= list_txn_get_quicksearch_column_mask(GTK_TREE_VIEW(data
->LV_ope
));
870 data
->totalsum
= 0.0;
872 for(i
=0;i
<data
->gpatxn
->len
;i
++)
874 Transaction
*txn
= g_ptr_array_index(data
->gpatxn
, i
);
875 gboolean insert
= TRUE
;
879 insert
= filter_txn_search_match(needle
, txn
, qs_flag
);
884 //gtk_list_store_append (GTK_LIST_STORE(model), &iter);
885 //gtk_list_store_set (GTK_LIST_STORE(model), &iter,
886 gtk_list_store_insert_with_values(GTK_LIST_STORE(model
), &iter
, -1,
887 MODEL_TXN_POINTER
, txn
,
890 if( data
->showall
== FALSE
)
891 data
->totalsum
+= txn
->amount
;
893 data
->totalsum
+= hb_amount_base (txn
->amount
, txn
->kcur
);
899 //gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_ope), model); /* Re-attach model to view */
900 //g_object_unref(model);
902 // push back the sort id
903 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GTK_LIST_STORE(model
)), sort_column_id
, order
);
905 /* update info range text */
909 daterange
= filter_daterange_text_get(data
->filter
);
910 gtk_widget_set_tooltip_markup(GTK_WIDGET(data
->CY_range
), daterange
);
915 register_panel_update(data
->LV_ope
, GINT_TO_POINTER(UF_SENSITIVE
+UF_BALANCE
));
919 static gint
txn_list_get_count_reconciled(GtkTreeView
*treeview
)
922 GList
*lselection
, *list
;
925 model
= gtk_tree_view_get_model(treeview
);
926 lselection
= gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(treeview
), &model
);
928 list
= g_list_last(lselection
);
935 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
936 gtk_tree_model_get(model
, &iter
, MODEL_TXN_POINTER
, &txn
, -1);
937 if(txn
->status
== TXN_STATUS_RECONCILED
)
940 list
= g_list_previous(list
);
943 g_list_foreach(lselection
, (GFunc
)gtk_tree_path_free
, NULL
);
944 g_list_free(lselection
);
950 static void txn_list_add_by_value(GtkTreeView
*treeview
, Transaction
*ope
)
955 //GtkTreeSelection *sel;
957 DB( g_print("\n[transaction] add_treeview\n") );
959 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(treeview
));
960 gtk_list_store_append (GTK_LIST_STORE(model
), &iter
);
961 gtk_list_store_set (GTK_LIST_STORE(model
), &iter
,
962 MODEL_TXN_POINTER
, ope
,
965 //activate that new line
966 //path = gtk_tree_model_get_path(model, &iter);
967 //gtk_tree_view_expand_to_path(GTK_TREE_VIEW(treeview), path);
969 //sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
970 //gtk_tree_selection_select_iter(sel, &iter);
972 //gtk_tree_path_free(path);
979 /* used to remove a intxfer child from a treeview */
980 static void txn_list_remove_by_value(GtkTreeModel
*model
, Transaction
*txn
)
988 DB( g_print("remove by value %p\n\n", txn
) );
990 valid
= gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model
), &iter
);
995 gtk_tree_model_get (model
, &iter
,
996 MODEL_TXN_POINTER
, &tmp
,
1001 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
1004 valid
= gtk_tree_model_iter_next(GTK_TREE_MODEL(model
), &iter
);
1009 static void status_selected_foreach_func (GtkTreeModel
*model
, GtkTreePath
*path
, GtkTreeIter
*iter
, gpointer userdata
)
1011 gint targetstatus
= GPOINTER_TO_INT(userdata
);
1014 gtk_tree_model_get(model
, iter
, MODEL_TXN_POINTER
, &txn
, -1);
1016 account_balances_sub(txn
);
1018 switch(targetstatus
)
1020 case TXN_STATUS_NONE
:
1023 case TXN_STATUS_CLEARED
:
1024 case TXN_STATUS_RECONCILED
:
1025 txn
->status
= TXN_STATUS_NONE
;
1026 txn
->flags
|= OF_CHANGED
;
1031 case TXN_STATUS_CLEARED
:
1034 case TXN_STATUS_NONE
:
1035 txn
->status
= TXN_STATUS_CLEARED
;
1036 txn
->flags
|= OF_CHANGED
;
1038 case TXN_STATUS_CLEARED
:
1039 txn
->status
= TXN_STATUS_NONE
;
1040 txn
->flags
|= OF_CHANGED
;
1045 case TXN_STATUS_RECONCILED
:
1048 case TXN_STATUS_NONE
:
1049 case TXN_STATUS_CLEARED
:
1050 txn
->status
= TXN_STATUS_RECONCILED
;
1051 txn
->flags
|= OF_CHANGED
;
1053 case TXN_STATUS_RECONCILED
:
1054 txn
->status
= TXN_STATUS_CLEARED
;
1055 txn
->flags
|= OF_CHANGED
;
1062 transaction_changed(txn
);
1064 account_balances_add(txn
);
1066 /* #492755 let the child transfer unchanged */
1071 static void delete_active_transaction(GtkTreeView
*treeview
)
1073 GtkTreeModel
*model
;
1076 model
= gtk_tree_view_get_model(treeview
);
1077 list
= gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(treeview
), &model
);
1083 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
1084 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
1087 g_list_foreach(list
, (GFunc
)gtk_tree_path_free
, NULL
);
1094 static void register_panel_add_single_transaction(GtkWindow
*window
, Transaction
*txn
)
1096 struct register_panel_data
*data
;
1098 DB( g_print("\n[account] add single txn\n") );
1100 data
= g_object_get_data(G_OBJECT(window
), "inst_data");
1102 txn_list_add_by_value(GTK_TREE_VIEW(data
->LV_ope
), txn
);
1106 static void register_panel_action(GtkWidget
*widget
, gpointer user_data
)
1108 struct register_panel_data
*data
;
1109 gint action
= GPOINTER_TO_INT(user_data
);
1110 guint changes
= GLOBALS
->changes_count
;
1113 DB( g_print("\n[account] action\n") );
1115 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1116 //data = INST_DATA(widget);
1118 DB( g_print(" - action=%d\n", action
) );
1123 case ACTION_ACCOUNT_ADD
:
1125 case ACTION_ACCOUNT_INHERIT
:
1128 Transaction
*src_txn
;
1131 homebank_app_date_get_julian();
1133 if(action
== ACTION_ACCOUNT_ADD
)
1135 DB( g_print("(transaction) add multiple\n") );
1136 src_txn
= da_transaction_malloc();
1137 src_txn
->date
= GLOBALS
->today
;
1138 if( data
->acc
!= NULL
)
1139 src_txn
->kacc
= data
->acc
->key
;
1140 da_transaction_set_default_template(src_txn
);
1141 type
= TRANSACTION_EDIT_ADD
;
1145 DB( g_print("(transaction) inherit multiple\n") );
1146 src_txn
= da_transaction_clone(list_txn_get_active_transaction(GTK_TREE_VIEW(data
->LV_ope
)));
1148 src_txn
->status
= TXN_STATUS_NONE
;
1149 type
= TRANSACTION_EDIT_INHERIT
;
1152 dialog
= create_deftransaction_window(GTK_WINDOW(data
->window
), type
, FALSE
, (data
->acc
!= NULL
) ? data
->acc
->key
: 0 );
1153 result
= HB_RESPONSE_ADD
;
1154 while(result
== HB_RESPONSE_ADD
|| result
== HB_RESPONSE_ADDKEEP
)
1156 /* clone source transaction */
1157 if( result
== HB_RESPONSE_ADD
)
1159 data
->cur_ope
= da_transaction_clone (src_txn
);
1161 if( PREFS
->heritdate
== FALSE
) //fix: 318733 / 1335285
1162 data
->cur_ope
->date
= GLOBALS
->today
;
1165 deftransaction_set_transaction(dialog
, data
->cur_ope
);
1167 result
= gtk_dialog_run (GTK_DIALOG (dialog
));
1168 if(result
== HB_RESPONSE_ADD
|| result
== HB_RESPONSE_ADDKEEP
|| result
== GTK_RESPONSE_ACCEPT
)
1170 Transaction
*add_txn
;
1172 deftransaction_get(dialog
, NULL
);
1173 add_txn
= transaction_add(GTK_WINDOW(data
->window
), data
->cur_ope
);
1174 if((data
->showall
== TRUE
) || ( (data
->acc
!= NULL
) && (data
->cur_ope
->kacc
== data
->acc
->key
) ) )
1176 txn_list_add_by_value(GTK_TREE_VIEW(data
->LV_ope
), add_txn
);
1177 //#1716181 also add to the ptr_array (quickfilter)
1178 g_ptr_array_add(data
->gpatxn
, (gpointer
)add_txn
);
1180 register_panel_update(widget
, GINT_TO_POINTER(UF_BALANCE
));
1181 //#1667201 already done into transaction_add
1182 //data->acc->flags |= AF_ADDED;
1183 GLOBALS
->changes_count
++;
1185 src_txn
->date
= data
->cur_ope
->date
;
1188 if( result
== HB_RESPONSE_ADD
)
1190 da_transaction_free (data
->cur_ope
);
1195 deftransaction_dispose(dialog
, NULL
);
1196 da_transaction_free (src_txn
);
1198 gtk_widget_destroy (dialog
);
1202 case ACTION_ACCOUNT_EDIT
:
1204 Transaction
*active_txn
;
1206 DB( g_print(" - edit\n") );
1208 active_txn
= list_txn_get_active_transaction(GTK_TREE_VIEW(data
->LV_ope
));
1212 Transaction
*old_txn
, *new_txn
;
1214 old_txn
= da_transaction_clone (active_txn
);
1215 new_txn
= active_txn
;
1217 result
= deftransaction_external_edit(GTK_WINDOW(data
->window
), old_txn
, new_txn
);
1219 if(result
== GTK_RESPONSE_ACCEPT
)
1221 //manage current window display stuff
1223 //#1270687: sort if date changed
1224 if(old_txn
->date
!= new_txn
->date
)
1225 data
->do_sort
= TRUE
;
1227 // txn changed of account
1228 //TODO: maybe this should move to deftransaction_external_edit
1229 if( data
->acc
!= NULL
&& (new_txn
->kacc
!= data
->acc
->key
) )
1233 delete_active_transaction(GTK_TREE_VIEW(data
->LV_ope
));
1234 //#1667501 update target account window is open
1235 nacc
= da_acc_get(new_txn
->kacc
);
1236 if( nacc
!= NULL
&& nacc
->window
!= NULL
)
1238 DB( g_print("- account %d changed and window is open\n", nacc
->key
) );
1239 if( GTK_IS_WINDOW(nacc
->window
) )
1241 register_panel_add_single_transaction(nacc
->window
, new_txn
);
1242 register_panel_update(GTK_WIDGET(nacc
->window
), GINT_TO_POINTER(UF_BALANCE
));
1247 //#1812470 txn is xfer update target account window is open
1248 if( (old_txn
->paymode
== PAYMODE_INTXFER
) && (old_txn
->amount
!= new_txn
->amount
) )
1250 Account
*nacc
= da_acc_get(new_txn
->kxferacc
);
1252 if( nacc
!= NULL
&& nacc
->window
!= NULL
)
1254 if( GTK_IS_WINDOW(nacc
->window
) )
1256 register_panel_update(GTK_WIDGET(nacc
->window
), GINT_TO_POINTER(UF_BALANCE
));
1261 //da_transaction_copy(new_txn, old_txn);
1263 register_panel_update(widget
, GINT_TO_POINTER(UF_BALANCE
));
1265 transaction_changed(new_txn
);
1267 GLOBALS
->changes_count
++;
1270 da_transaction_free (old_txn
);
1275 case ACTION_ACCOUNT_DELETE
:
1277 GtkTreeModel
*model
;
1278 GList
*selection
, *list
;
1281 DB( g_print(" - delete\n") );
1283 result
= ui_dialog_msg_confirm_alert(
1284 GTK_WINDOW(data
->window
),
1286 _("Do you want to delete\neach of the selected transaction ?"),
1290 if(result
== GTK_RESPONSE_OK
)
1292 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_ope
));
1293 selection
= gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
)), &model
);
1295 list
= g_list_last(selection
);
1301 gtk_tree_model_get_iter(model
, &iter
, list
->data
);
1302 gtk_tree_model_get(model
, &iter
, MODEL_TXN_POINTER
, &entry
, -1);
1304 DB( g_print(" delete %s %.2f\n", entry
->memo
, entry
->amount
) );
1306 //#1716181 also remove from the ptr_array (quickfilter)
1307 g_ptr_array_remove(data
->gpatxn
, (gpointer
)entry
);
1309 // 1) remove visible current and potential xfer
1310 gtk_list_store_remove(GTK_LIST_STORE(model
), &iter
);
1311 if(data
->showall
&& entry
->paymode
== PAYMODE_INTXFER
)
1313 Transaction
*child
= transaction_xfer_child_strong_get(entry
);
1316 txn_list_remove_by_value(model
, child
);
1317 //#1716181 also remove from the ptr_array (quickfilter)
1318 g_ptr_array_remove(data
->gpatxn
, (gpointer
)child
);
1322 // 2) remove datamodel
1323 transaction_remove(entry
);
1324 GLOBALS
->changes_count
++;
1326 list
= g_list_previous(list
);
1329 g_list_foreach(selection
, (GFunc
)gtk_tree_path_free
, NULL
);
1330 g_list_free(selection
);
1332 register_panel_update(widget
, GINT_TO_POINTER(UF_BALANCE
));
1338 case ACTION_ACCOUNT_NONE
:
1340 GtkTreeSelection
*selection
;
1343 count
= txn_list_get_count_reconciled(GTK_TREE_VIEW(data
->LV_ope
));
1348 result
= ui_dialog_msg_confirm_alert(
1349 GTK_WINDOW(data
->window
),
1350 _("Are you sure you want to change the status to None?"),
1351 _("Some transaction in your selection are already Reconciled."),
1356 result
= GTK_RESPONSE_OK
;
1358 if( result
== GTK_RESPONSE_OK
)
1360 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
));
1361 gtk_tree_selection_selected_foreach(selection
, (GtkTreeSelectionForeachFunc
)status_selected_foreach_func
,
1362 GINT_TO_POINTER(TXN_STATUS_NONE
));
1364 DB( g_print(" - none\n") );
1366 gtk_widget_queue_draw (data
->LV_ope
);
1367 //gtk_widget_queue_resize (data->LV_acc);
1369 register_panel_update(widget
, GINT_TO_POINTER(UF_BALANCE
));
1371 GLOBALS
->changes_count
++;
1377 case ACTION_ACCOUNT_CLEAR
:
1379 GtkTreeSelection
*selection
;
1381 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
));
1382 gtk_tree_selection_selected_foreach(selection
, (GtkTreeSelectionForeachFunc
)status_selected_foreach_func
,
1383 GINT_TO_POINTER(TXN_STATUS_CLEARED
));
1385 DB( g_print(" - clear\n") );
1387 gtk_widget_queue_draw (data
->LV_ope
);
1388 //gtk_widget_queue_resize (data->LV_acc);
1390 register_panel_update(widget
, GINT_TO_POINTER(UF_BALANCE
));
1392 GLOBALS
->changes_count
++;
1398 case ACTION_ACCOUNT_RECONCILE
:
1400 GtkTreeSelection
*selection
;
1403 count
= txn_list_get_count_reconciled(GTK_TREE_VIEW(data
->LV_ope
));
1408 result
= ui_dialog_msg_confirm_alert(
1409 GTK_WINDOW(data
->window
),
1410 _("Are you sure you want to toggle the status Reconciled?"),
1411 _("Some transaction in your selection are already Reconciled."),
1416 result
= GTK_RESPONSE_OK
;
1418 if( result
== GTK_RESPONSE_OK
)
1420 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
));
1421 gtk_tree_selection_selected_foreach(selection
, (GtkTreeSelectionForeachFunc
)status_selected_foreach_func
,
1422 GINT_TO_POINTER(TXN_STATUS_RECONCILED
));
1424 DB( g_print(" - reconcile\n") );
1426 gtk_widget_queue_draw (data
->LV_ope
);
1427 //gtk_widget_queue_resize (data->LV_acc);
1429 register_panel_update(widget
, GINT_TO_POINTER(UF_BALANCE
));
1431 GLOBALS
->changes_count
++;
1438 case ACTION_ACCOUNT_FILTER
:
1441 if(ui_flt_manage_dialog_new(GTK_WINDOW(data
->window
), data
->filter
, data
->showall
, TRUE
) != GTK_RESPONSE_REJECT
)
1443 register_panel_collect_filtered_txn(data
->LV_ope
, TRUE
);
1444 register_panel_listview_populate(data
->LV_ope
);
1445 register_panel_update(data
->LV_ope
, GINT_TO_POINTER(UF_SENSITIVE
+UF_BALANCE
));
1447 g_signal_handler_block(data
->CY_range
, data
->handler_id
[HID_RANGE
]);
1448 hbtk_combo_box_set_active_id(GTK_COMBO_BOX_TEXT(data
->CY_range
), FLT_RANGE_OTHER
);
1449 g_signal_handler_unblock(data
->CY_range
, data
->handler_id
[HID_RANGE
]);
1458 if( GLOBALS
->changes_count
> changes
)
1459 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
));
1465 static void register_panel_toggle_minor(GtkWidget
*widget
, gpointer user_data
)
1467 struct register_panel_data
*data
;
1469 DB( g_print("\n[account] toggle\n") );
1471 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1473 register_panel_update(data
->LV_ope
, GINT_TO_POINTER(UF_BALANCE
));
1474 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data
->LV_ope
));
1478 static void register_panel_selection(GtkTreeSelection
*treeselection
, gpointer user_data
)
1481 DB( g_print("\n[account] selection changed cb\n") );
1484 register_panel_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection
)), GINT_TO_POINTER(UF_SENSITIVE
));
1489 static void register_panel_update(GtkWidget
*widget
, gpointer user_data
)
1491 struct register_panel_data
*data
;
1492 GtkTreeSelection
*selection
;
1493 gint flags
= GPOINTER_TO_INT(user_data
);
1496 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1497 //data = INST_DATA(widget);
1499 DB( g_print("\n[account %d] update\n", data
->acc
!= NULL
? (gint
)data
->acc
->key
: -1) );
1502 GLOBALS
->minor
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data
->CM_minor
));
1504 /* set window title */
1505 if(flags
& UF_TITLE
)
1507 DB( g_print(" - UF_TITLE\n") );
1511 /* update disabled things */
1512 if(flags
& UF_SENSITIVE
)
1516 DB( g_print(" - UF_SENSITIVE\n") );
1518 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
));
1519 count
= gtk_tree_selection_count_selected_rows(selection
);
1520 DB( g_print(" - count = %d\n", count
) );
1523 sensitive
= !data
->showall
;
1524 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/AccountMenu/ExportPDF"), sensitive
);
1525 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/AccountMenu/ExportQIF"), sensitive
);
1526 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/AccountMenu/ExportCSV"), sensitive
);
1527 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/ToolsMenu/ChkIntXfer"), sensitive
);
1528 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/ToolsMenu/DuplicateMark"), sensitive
);
1529 //gtk_action_set_visible(gtk_ui_manager_get_action(data->ui, "/MenuBar/ToolsMenu/DuplicateClear"), sensitive);
1531 //5.3.1 if closed account : disable any change
1533 if( (data
->showall
== FALSE
) && (data
->acc
->flags
& AF_CLOSED
) )
1536 gtk_widget_set_sensitive (data
->TB_bar
, sensitive
);
1537 //gtk_widget_set_sensitive (data->TB_tools, sensitive);
1538 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/ToolBar/Assign"), data
->showall
? FALSE
: sensitive
);
1540 gtk_widget_set_sensitive(gtk_ui_manager_get_widget(data
->ui
, "/MenuBar/TxnMenu"), sensitive
);
1541 gtk_widget_set_sensitive(gtk_ui_manager_get_widget(data
->ui
, "/MenuBar/ToolsMenu"), sensitive
);
1543 // multiple: disable inherit, edit
1544 sensitive
= (count
!= 1 ) ? FALSE
: TRUE
;
1545 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/TxnMenu/Inherit"), sensitive
);
1546 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/TxnMenu/Edit"), sensitive
);
1547 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/TxnBar/Inherit"), sensitive
);
1548 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/TxnBar/Edit"), sensitive
);
1550 // single: disable multiedit
1551 sensitive
= (count
<= 1 ) ? FALSE
: TRUE
;
1552 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/TxnMenu/MultiEdit"), sensitive
);
1553 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/TxnBar/MultiEdit"), sensitive
);
1555 // no selection: disable reconcile, delete
1556 sensitive
= (count
> 0 ) ? TRUE
: FALSE
;
1557 gtk_widget_set_sensitive(gtk_ui_manager_get_widget(data
->ui
, "/MenuBar/TxnMenu/TxnStatusMenu"), sensitive
);
1558 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/TxnMenu/Delete"), sensitive
);
1559 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/TxnMenu/Template"), sensitive
);
1560 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/TxnBar/Delete"), sensitive
);
1561 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/TxnBar/Cleared"), sensitive
);
1562 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/TxnBar/Reconciled"), sensitive
);
1563 gtk_action_set_sensitive(gtk_ui_manager_get_action(data
->ui
, "/TxnBar/Template"), sensitive
);
1566 sensitive
= (data
->showall
== TRUE
) ? FALSE
: PREFS
->euro_active
;
1567 if( (data
->acc
!= NULL
) && currency_is_euro(data
->acc
->kcur
) )
1569 gtk_action_set_visible(gtk_ui_manager_get_action(data
->ui
, "/MenuBar/ToolsMenu/ConvToEuro"), sensitive
);
1573 /* update toolbar & list */
1574 if(flags
& UF_VISUAL
)
1576 DB( g_print(" - UF_VISUAL\n") );
1578 if(PREFS
->toolbar_style
== 0)
1579 gtk_toolbar_unset_style(GTK_TOOLBAR(data
->TB_bar
));
1581 gtk_toolbar_set_style(GTK_TOOLBAR(data
->TB_bar
), PREFS
->toolbar_style
-1);
1584 if( PREFS
->euro_active
)
1586 gtk_widget_show(data
->CM_minor
);
1590 gtk_widget_hide(data
->CM_minor
);
1594 /* update balances */
1595 if(flags
& UF_BALANCE
)
1597 DB( g_print(" - UF_BALANCE\n") );
1599 if(data
->showall
== FALSE
)
1601 Account
*acc
= data
->acc
;
1603 register_panel_balance_refresh(widget
);
1604 hb_label_set_colvalue(GTK_LABEL(data
->TX_balance
[0]), acc
->bal_bank
, acc
->kcur
, GLOBALS
->minor
);
1605 hb_label_set_colvalue(GTK_LABEL(data
->TX_balance
[1]), acc
->bal_today
, acc
->kcur
, GLOBALS
->minor
);
1606 hb_label_set_colvalue(GTK_LABEL(data
->TX_balance
[2]), acc
->bal_future
, acc
->kcur
, GLOBALS
->minor
);
1610 GList
*lst_acc
, *lnk_acc
;
1611 gdouble bank
, today
, future
;
1613 bank
= today
= future
= 0.0;
1614 lst_acc
= g_hash_table_get_values(GLOBALS
->h_acc
);
1615 lnk_acc
= g_list_first(lst_acc
);
1616 while (lnk_acc
!= NULL
)
1618 Account
*acc
= lnk_acc
->data
;
1620 bank
+= hb_amount_base(acc
->bal_bank
, acc
->kcur
);
1621 today
+= hb_amount_base(acc
->bal_today
, acc
->kcur
);
1622 future
+= hb_amount_base(acc
->bal_future
, acc
->kcur
);
1624 lnk_acc
= g_list_next(lnk_acc
);
1626 g_list_free(lst_acc
);
1628 hb_label_set_colvalue(GTK_LABEL(data
->TX_balance
[0]), bank
, GLOBALS
->kcur
, GLOBALS
->minor
);
1629 hb_label_set_colvalue(GTK_LABEL(data
->TX_balance
[1]), today
, GLOBALS
->kcur
, GLOBALS
->minor
);
1630 hb_label_set_colvalue(GTK_LABEL(data
->TX_balance
[2]), future
, GLOBALS
->kcur
, GLOBALS
->minor
);
1632 ui_hub_account_populate(GLOBALS
->mainwindow
, NULL
);
1635 /* update fltinfo */
1636 DB( g_print(" - statusbar\n") );
1638 selection
= gtk_tree_view_get_selection(GTK_TREE_VIEW(data
->LV_ope
));
1639 count
= gtk_tree_selection_count_selected_rows(selection
);
1640 DB( g_print(" - nb selected = %d\n", count
) );
1642 /* if more than one ope selected, we make a sum to display to the user */
1643 gdouble opeexp
= 0.0;
1644 gdouble opeinc
= 0.0;
1651 kcur
= (data
->showall
== TRUE
) ? GLOBALS
->kcur
: data
->acc
->kcur
;
1656 GList
*list
, *tmplist
;
1657 GtkTreeModel
*model
;
1660 model
= gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_ope
));
1661 list
= gtk_tree_selection_get_selected_rows(selection
, &model
);
1662 tmplist
= g_list_first(list
);
1663 while (tmplist
!= NULL
)
1667 gtk_tree_model_get_iter(model
, &iter
, tmplist
->data
);
1668 gtk_tree_model_get(model
, &iter
, MODEL_TXN_POINTER
, &item
, -1);
1670 if( data
->showall
== FALSE
)
1672 if( item
->flags
& OF_INCOME
)
1673 opeinc
+= item
->amount
;
1675 opeexp
+= item
->amount
;
1679 if( item
->flags
& OF_INCOME
)
1680 opeinc
+= hb_amount_base(item
->amount
, item
->kcur
);
1682 opeexp
+= hb_amount_base(item
->amount
, item
->kcur
);
1685 DB( g_print(" - %s, %.2f\n", item
->memo
, item
->amount
) );
1687 tmplist
= g_list_next(tmplist
);
1691 DB( g_print(" %f - %f = %f\n", opeinc
, opeexp
, opeinc
+ opeexp
) );
1694 hb_strfmon(buf1
, 64-1, opeinc
, kcur
, GLOBALS
->minor
);
1695 hb_strfmon(buf2
, 64-1, -opeexp
, kcur
, GLOBALS
->minor
);
1696 hb_strfmon(buf3
, 64-1, opeinc
+ opeexp
, kcur
, GLOBALS
->minor
);
1697 hb_strfmon(fbufavg
, 64-1, (opeinc
+ opeexp
) / count
, kcur
, GLOBALS
->minor
);
1704 msg
= g_strdup_printf(_("%d transactions"), data
->total
);
1707 msg
= g_strdup_printf(_("%d transactions, %d selected, avg: %s, sum: %s (%s - %s)"), data
->total
, count
, fbufavg
, buf3
, buf1
, buf2
);
1709 gtk_label_set_markup(GTK_LABEL(data
->TX_selection
), msg
);
1715 void register_panel_onRowActivated (GtkTreeView
*treeview
, GtkTreePath
*path
, GtkTreeViewColumn
*col
, gpointer userdata
)
1717 struct register_panel_data
*data
;
1718 GtkTreeModel
*model
;
1723 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview
), GTK_TYPE_WINDOW
)), "inst_data");
1725 //5.3.1 if closed account : disable any change
1726 if( (data
->showall
== FALSE
) && (data
->acc
->flags
& AF_CLOSED
) )
1730 col_id
= gtk_tree_view_column_get_sort_column_id (col
);
1732 count
= gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(treeview
));
1734 model
= gtk_tree_view_get_model(treeview
);
1736 //get transaction double clicked to initiate the widget
1737 gtk_tree_model_get_iter(model
, &iter
, path
);
1738 gtk_tree_model_get(model
, &iter
, MODEL_TXN_POINTER
, &ope
, -1);
1741 DB( g_print ("%d rows been double-clicked on column=%d! ope=%s\n", count
, col_id
, ope
->memo
) );
1745 register_panel_action(GTK_WIDGET(treeview
), GINT_TO_POINTER(ACTION_ACCOUNT_EDIT
));
1749 if( data
->showall
== FALSE
)
1751 if(col_id
>= LST_DSPOPE_DATE
&& col_id
!= LST_DSPOPE_BALANCE
)
1753 register_panel_edit_multiple (data
->window
, ope
, col_id
, data
);
1761 static gint listview_context_cb (GtkWidget *widget, GdkEventButton *event, GtkWidget *menu)
1764 if (event->button == 3)
1768 if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
1769 (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL))
1771 gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, NULL, FALSE);
1772 gtk_tree_path_free (path);
1778 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL,
1779 event->button, event->time);
1781 // On indique à l'appelant que l'on a géré cet événement.
1786 // On indique à l'appelant que l'on n'a pas géré cet événement.
1794 ** populate the account window
1796 void register_panel_window_init(GtkWidget
*widget
, gpointer user_data
)
1798 struct register_panel_data
*data
;
1800 data
= g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget
, GTK_TYPE_WINDOW
)), "inst_data");
1802 DB( g_print("\n[account] init window\n") );
1804 if( data
->showall
== TRUE
)
1806 gtk_label_set_text (GTK_LABEL(data
->LB_name
), _("All transactions"));
1807 hb_widget_visible (data
->IM_closed
, FALSE
);
1811 gtk_label_set_text (GTK_LABEL(data
->LB_name
), data
->acc
->name
);
1812 hb_widget_visible (data
->IM_closed
, (data
->acc
->flags
& AF_CLOSED
) ? TRUE
: FALSE
);
1814 DB( g_print(" - sort transactions\n") );
1815 da_transaction_queue_sort(data
->acc
->txn_queue
);
1818 list_txn_set_column_acc_visible(GTK_TREE_VIEW(data
->LV_ope
), data
->showall
);
1820 //DB( g_print(" mindate=%d, maxdate=%d %x\n", data->filter->mindate,data->filter->maxdate) );
1822 DB( g_print(" - call update visual\n") );
1823 register_panel_update(widget
, GINT_TO_POINTER(UF_VISUAL
|UF_SENSITIVE
));
1825 DB( g_print(" - set range or populate+update sensitive+balance\n") );
1827 register_panel_cb_filter_reset(widget
, user_data
);
1835 register_panel_getgeometry(GtkWidget
*widget
, GdkEventConfigure
*event
, gpointer user_data
)
1837 //struct register_panel_data *data = user_data;
1838 struct WinGeometry
*wg
;
1840 DB( g_print("\n[account] get geometry\n") );
1842 //store position and size
1843 wg
= &PREFS
->acc_wg
;
1844 gtk_window_get_position(GTK_WINDOW(widget
), &wg
->l
, &wg
->t
);
1845 gtk_window_get_size(GTK_WINDOW(widget
), &wg
->w
, &wg
->h
);
1846 GdkWindow
*gdk_window
= gtk_widget_get_window(GTK_WIDGET(widget
));
1847 GdkWindowState state
= gdk_window_get_state(gdk_window
);
1848 wg
->s
= (state
& GDK_WINDOW_STATE_MAXIMIZED
) ? 1 : 0;
1850 DB( g_print(" window: l=%d, t=%d, w=%d, h=%d s=%d, state=%d\n", wg
->l
, wg
->t
, wg
->w
, wg
->h
, wg
->s
, state
& GDK_WINDOW_STATE_MAXIMIZED
) );
1858 static gboolean
register_panel_dispose(GtkWidget
*widget
, GdkEvent
*event
, gpointer user_data
)
1860 struct register_panel_data
*data
= user_data
;
1862 data
= g_object_get_data(G_OBJECT(widget
), "inst_data");
1864 DB( g_print("\n[account] delete-event\n") );
1866 register_panel_getgeometry(data
->window
, NULL
, data
);
1871 /* Another callback */
1872 static gboolean
register_panel_destroy( GtkWidget
*widget
,
1873 gpointer user_data
)
1875 struct register_panel_data
*data
;
1877 data
= g_object_get_data(G_OBJECT(widget
), "inst_data");
1880 DB( g_print ("\n[account] destroy event occurred\n") );
1884 //enable define windows
1885 GLOBALS
->define_off
--;
1887 /* unset transaction edit mutex */
1888 if(data
->showall
== FALSE
)
1889 data
->acc
->window
= NULL
;
1891 GLOBALS
->alltxnwindow
= NULL
;
1893 /* free title and filter */
1894 DB( g_print(" user_data=%p to be free\n", user_data
) );
1895 g_free(data
->wintitle
);
1897 if(data
->gpatxn
!= NULL
)
1898 g_ptr_array_free (data
->gpatxn
, TRUE
);
1900 da_flt_free(data
->filter
);
1905 //our global list has changed, so update the treeview
1906 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_TITLE
+UF_SENSITIVE
+UF_BALANCE
+UF_REFRESHALL
));
1912 static void quick_search_text_changed_cb (GtkWidget
*widget
, gpointer user_data
)
1914 struct register_panel_data
*data
= user_data
;
1916 register_panel_listview_populate (data
->window
);
1920 static GtkActionEntry entries
[] = {
1922 /* name, icon-name, label */
1923 { "AccountMenu" , NULL
, N_("A_ccount"), NULL
, NULL
, NULL
},
1924 { "TxnMenu" , NULL
, N_("Transacti_on"), NULL
, NULL
, NULL
},
1925 { "TxnStatusMenu", NULL
, N_("_Status"), NULL
, NULL
, NULL
},
1926 { "ToolsMenu" , NULL
, N_("_Tools"), NULL
, NULL
, NULL
},
1929 /* name, icon-name, label, accelerator, tooltip */
1930 { "ExportPDF" , NULL
, N_("Export as PDF..."), NULL
, N_("Export to a PDF file"), G_CALLBACK (register_panel_action_exportpdf
) },
1931 { "ExportQIF" , NULL
, N_("Export QIF..."), NULL
, N_("Export as QIF"), G_CALLBACK (register_panel_action_exportqif
) },
1932 { "ExportCSV" , NULL
, N_("Export CSV..."), NULL
, N_("Export as CSV"), G_CALLBACK (register_panel_action_exportcsv
) },
1933 { "Close" , ICONNAME_CLOSE
, N_("_Close") , "<control>W", N_("Close the current account"), G_CALLBACK (register_panel_action_close
) },
1935 { "Add" , ICONNAME_HB_OPE_ADD
, N_("_Add..."), NULL
, N_("Add a new transaction"), G_CALLBACK (register_panel_action_add
) },
1936 { "Inherit" , ICONNAME_HB_OPE_HERIT
, N_("_Inherit..."), NULL
, N_("Inherit from the active transaction"), G_CALLBACK (register_panel_action_inherit
) },
1937 { "Edit" , ICONNAME_HB_OPE_EDIT
, N_("_Edit..."), NULL
, N_("Edit the active transaction"), G_CALLBACK (register_panel_action_edit
) },
1939 { "None" , NULL
, N_("_None"), "<control>N", N_("Toggle none for selected transaction(s)"), G_CALLBACK (register_panel_action_none
) },
1940 { "Cleared" , ICONNAME_HB_OPE_CLEARED
, N_("_Cleared"), "<control>C", N_("Toggle cleared for selected transaction(s)"), G_CALLBACK (register_panel_action_clear
) },
1941 { "Reconciled" , ICONNAME_HB_OPE_RECONCILED
, N_("_Reconciled"), "<control>R", N_("Toggle reconciled for selected transaction(s)"), G_CALLBACK (register_panel_action_reconcile
) },
1943 { "MultiEdit" , ICONNAME_HB_OPE_MULTIEDIT
, N_("_Multiple Edit..."), NULL
, N_("Edit multiple transaction"), G_CALLBACK (register_panel_action_multiedit
) },
1944 { "Template" , ICONNAME_CONVERT
, N_("Create template..."), NULL
, N_("Create template"), G_CALLBACK (register_panel_action_createtemplate
) },
1945 { "Delete" , ICONNAME_HB_OPE_DELETE
, N_("_Delete..."), NULL
, N_("Delete selected transaction(s)"), G_CALLBACK (register_panel_action_remove
) },
1947 { "DuplicateMark", NULL
, N_("Mark duplicate..."), NULL
, NULL
, G_CALLBACK (register_panel_action_duplicate_mark
) },
1948 // { "DuplicateClear", NULL , N_("Unmark duplicate"), NULL, NULL, G_CALLBACK (register_panel_action_duplicate_unmark) },
1950 { "ChkIntXfer" , NULL
, N_("Check internal xfer"), NULL
, NULL
, G_CALLBACK (register_panel_action_check_internal_xfer
) },
1951 { "Assign" , ICONNAME_HB_ASSIGN_RUN
, N_("Auto. assignments"), NULL
, N_("Run automatic assignments"), G_CALLBACK (register_panel_action_assign
) },
1953 { "Filter" , ICONNAME_HB_FILTER
, N_("_Filter..."), NULL
, N_("Open the list filter"), G_CALLBACK (register_panel_action_editfilter
) },
1954 { "ConvToEuro" , NULL
, N_("Convert to Euro..."), NULL
, N_("Convert this account to Euro currency"), G_CALLBACK (register_panel_action_converttoeuro
) },
1957 static guint n_entries
= G_N_ELEMENTS (entries
);
1960 static const gchar
*ui_info
=
1962 "<menubar name='MenuBar'>"
1963 " <menu action='AccountMenu'>"
1964 " <menuitem action='ExportQIF'/>"
1965 " <menuitem action='ExportCSV'/>"
1967 " <menuitem action='ExportPDF'/>"
1969 " <menuitem action='Close'/>"
1971 " <menu action='TxnMenu'>"
1972 " <menuitem action='Add'/>"
1973 " <menuitem action='Inherit'/>"
1974 " <menuitem action='Edit'/>"
1976 " <menu action='TxnStatusMenu'>"
1977 " <menuitem action='None'/>"
1978 " <menuitem action='Cleared'/>"
1979 " <menuitem action='Reconciled'/>"
1982 " <menuitem action='MultiEdit'/>"
1983 " <menuitem action='Template'/>"
1984 " <menuitem action='Delete'/>"
1986 " <menu action='ToolsMenu'>"
1987 " <menuitem action='DuplicateMark'/>"
1988 //" <menuitem action='DuplicateClear'/>"
1990 " <menuitem action='ChkIntXfer'/>"
1992 " <menuitem action='Filter'/>"
1993 " <menuitem action='Assign'/>"
1995 " <menuitem action='ConvToEuro'/>"
1999 "<toolbar name='TxnBar'>"
2000 " <toolitem action='Add'/>"
2001 " <toolitem action='Inherit'/>"
2002 " <toolitem action='Edit'/>"
2004 " <toolitem action='Cleared'/>"
2005 " <toolitem action='Reconciled'/>"
2007 " <toolitem action='MultiEdit'/>"
2008 " <toolitem action='Template'/>"
2009 " <toolitem action='Delete'/>"
2011 "<toolbar name='ToolBar'>"
2012 " <toolitem action='Filter'/>"
2013 " <toolitem action='Assign'/>"
2019 * if accnum = 0 or acc is null : show all account
2021 GtkWidget
*register_panel_window_new(Account
*acc
)
2023 struct register_panel_data
*data
;
2024 struct WinGeometry
*wg
;
2025 GtkWidget
*window
, *mainbox
, *table
, *sw
, *bar
;
2026 GtkWidget
*treeview
, *label
, *widget
, *image
;
2027 //GtkWidget *menu, *menu_items;
2029 GtkActionGroup
*actions
;
2031 GError
*error
= NULL
;
2033 DB( g_print("\n[account] create_register_panel_window\n") );
2035 data
= g_malloc0(sizeof(struct register_panel_data
));
2036 if(!data
) return NULL
;
2038 //disable define windows
2039 GLOBALS
->define_off
++;
2040 ui_mainwindow_update(GLOBALS
->mainwindow
, GINT_TO_POINTER(UF_SENSITIVE
));
2042 /* create window, etc */
2043 window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
2044 data
->window
= window
;
2046 //store our window private data
2047 g_object_set_data(G_OBJECT(window
), "inst_data", (gpointer
)data
);
2048 DB( g_print(" - new window=%p, inst_data=%p\n", window
, data
) );
2051 data
->showall
= (acc
!= NULL
) ? FALSE
: TRUE
;
2053 if(data
->showall
== FALSE
)
2055 data
->acc
->window
= GTK_WINDOW(window
);
2056 if( data
->acc
->flags
& AF_CLOSED
)
2057 data
->wintitle
= g_strdup_printf("%s %s - HomeBank", data
->acc
->name
, _("(closed)"));
2059 data
->wintitle
= g_strdup_printf("%s - HomeBank", data
->acc
->name
);
2063 GLOBALS
->alltxnwindow
= window
;
2064 data
->wintitle
= g_strdup_printf(_("%s - HomeBank"), _("All transactions"));
2067 gtk_window_set_title (GTK_WINDOW (window
), data
->wintitle
);
2068 gtk_window_set_icon_name(GTK_WINDOW (window
), ICONNAME_HB_OPE_SHOW
);
2070 // connect our dispose function
2071 g_signal_connect (window
, "delete-event",
2072 G_CALLBACK (register_panel_dispose
), (gpointer
)data
);
2074 // connect our dispose function
2075 g_signal_connect (window
, "destroy",
2076 G_CALLBACK (register_panel_destroy
), (gpointer
)data
);
2078 // connect our dispose function
2079 //g_signal_connect (window, "configure-event",
2080 // G_CALLBACK (register_panel_getgeometry), (gpointer)data);
2083 //start test uimanager
2085 actions
= gtk_action_group_new ("Account");
2088 gtk_action_group_set_translation_domain(actions
, GETTEXT_PACKAGE
);
2091 DB( g_print(" - add actions: %p user_data: %p\n", actions
, data
) );
2092 gtk_action_group_add_actions (actions
, entries
, n_entries
, data
);
2094 /* set which action should have priority in the toolbar */
2095 action
= gtk_action_group_get_action(actions
, "Add");
2096 g_object_set(action
, "is_important", TRUE
, "short_label", _("Add"), NULL
);
2098 action
= gtk_action_group_get_action(actions
, "Inherit");
2099 g_object_set(action
, "is_important", TRUE
, "short_label", _("Inherit"), NULL
);
2101 action
= gtk_action_group_get_action(actions
, "Edit");
2102 g_object_set(action
, "is_important", TRUE
, "short_label", _("Edit"), NULL
);
2104 action
= gtk_action_group_get_action(actions
, "Filter");
2105 g_object_set(action
, "is_important", TRUE
, "short_label", _("Filter"), NULL
);
2107 //action = gtk_action_group_get_action(actions, "Reconciled");
2108 //g_object_set(action, "is_important", TRUE, "short_label", _("Reconciled"), NULL);
2111 ui
= gtk_ui_manager_new ();
2113 DB( g_print(" - insert action group:\n") );
2114 gtk_ui_manager_insert_action_group (ui
, actions
, 0);
2116 GtkAccelGroup
*ag
= gtk_ui_manager_get_accel_group (ui
);
2118 DB( g_print(" - add_accel_group actions=%p, ui=%p, ag=%p\n", actions
, ui
, ag
) );
2120 gtk_window_add_accel_group (GTK_WINDOW (window
), ag
);
2122 DB( g_print(" - add ui from string:\n") );
2123 if (!gtk_ui_manager_add_ui_from_string (ui
, ui_info
, -1, &error
))
2125 g_message ("building menus failed: %s", error
->message
);
2126 g_error_free (error
);
2130 data
->actions
= actions
;
2133 mainbox
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
2134 //gtk_container_set_border_width(GTK_CONTAINER(mainbox), SPACING_SMALL);
2135 gtk_container_add (GTK_CONTAINER (window
), mainbox
);
2137 widget
= gtk_ui_manager_get_widget (ui
, "/MenuBar");
2138 //data->menu = widget;
2139 gtk_box_pack_start (GTK_BOX (mainbox
), widget
, FALSE
, FALSE
, 0);
2141 // info bar for duplicate
2142 bar
= gtk_info_bar_new_with_buttons (_("_Refresh"), HB_RESPONSE_REFRESH
, NULL
);
2143 data
->IB_duplicate
= bar
;
2144 gtk_box_pack_start (GTK_BOX (mainbox
), bar
, FALSE
, FALSE
, 0);
2146 gtk_info_bar_set_message_type (GTK_INFO_BAR (bar
), GTK_MESSAGE_WARNING
);
2147 gtk_info_bar_set_show_close_button (GTK_INFO_BAR (bar
), TRUE
);
2148 label
= gtk_label_new ("This is an info bar with message type GTK_MESSAGE_WARNING");
2149 data
->LB_duplicate
= label
;
2150 gtk_label_set_line_wrap (GTK_LABEL (label
), TRUE
);
2151 gtk_label_set_xalign (GTK_LABEL (label
), 0);
2152 gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar
))), label
, FALSE
, FALSE
, 0);
2154 widget
= make_numeric(NULL
, 0, HB_DATE_MAX_GAP
);
2155 data
->NB_txn_daygap
= widget
;
2156 gtk_box_pack_start (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar
))), widget
, FALSE
, FALSE
, 0);
2158 table
= gtk_grid_new();
2159 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
2160 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
2161 gtk_container_set_border_width (GTK_CONTAINER(table
), SPACING_SMALL
);
2162 gtk_box_pack_start (GTK_BOX (mainbox
), table
, FALSE
, FALSE
, 0);
2164 // account name (+ balance)
2165 widget
= gtk_image_new_from_icon_name (ICONNAME_CHANGES_PREVENT
, GTK_ICON_SIZE_BUTTON
);
2166 data
->IM_closed
= widget
;
2167 gtk_grid_attach (GTK_GRID(table
), widget
, 0, 0, 1, 1);
2169 label
= gtk_label_new(NULL
);
2170 data
->LB_name
= label
;
2171 gimp_label_set_attributes (GTK_LABEL (label
), PANGO_ATTR_SCALE
, PANGO_SCALE_LARGE
, -1);
2172 gtk_widget_set_halign (label
, GTK_ALIGN_START
);
2173 gtk_widget_set_hexpand (label
, TRUE
);
2174 gtk_grid_attach (GTK_GRID(table
), label
, 1, 0, 1, 1);
2177 label
= gtk_label_new(_("Bank:"));
2178 gtk_grid_attach (GTK_GRID(table
), label
, 3, 0, 1, 1);
2179 widget
= gtk_label_new(NULL
);
2180 data
->TX_balance
[0] = widget
;
2181 gtk_grid_attach (GTK_GRID(table
), widget
, 4, 0, 1, 1);
2183 label
= gtk_label_new(_("Today:"));
2184 gtk_grid_attach (GTK_GRID(table
), label
, 5, 0, 1, 1);
2185 widget
= gtk_label_new(NULL
);
2186 data
->TX_balance
[1] = widget
;
2187 gtk_grid_attach (GTK_GRID(table
), widget
, 6, 0, 1, 1);
2189 label
= gtk_label_new(_("Future:"));
2190 gtk_grid_attach (GTK_GRID(table
), label
, 7, 0, 1, 1);
2192 widget
= gtk_label_new(NULL
);
2193 data
->TX_balance
[2] = widget
;
2194 gtk_grid_attach (GTK_GRID(table
), widget
, 8, 0, 1, 1);
2197 widget
= make_search ();
2198 data
->ST_search
= widget
;
2199 gtk_widget_set_size_request(widget
, HB_MINWIDTH_SEARCH
, -1);
2200 gtk_grid_attach (GTK_GRID(table
), widget
, 9, 0, 1, 1);
2202 data
->handler_id
[HID_SEARCH
] = g_signal_connect (data
->ST_search
, "search-changed", G_CALLBACK (quick_search_text_changed_cb
), data
);
2206 table
= gtk_grid_new();
2207 gtk_grid_set_row_spacing (GTK_GRID (table
), SPACING_SMALL
);
2208 gtk_grid_set_column_spacing (GTK_GRID (table
), SPACING_MEDIUM
);
2209 gtk_container_set_border_width (GTK_CONTAINER(table
), SPACING_SMALL
);
2210 gtk_box_pack_start (GTK_BOX (mainbox
), table
, FALSE
, FALSE
, 0);
2212 label
= make_label_widget(_("_Range:"));
2213 gtk_grid_attach (GTK_GRID(table
), label
, 0, 0, 1, 1);
2214 data
->CY_range
= make_daterange(label
, DATE_RANGE_CUSTOM_SHOW
);
2215 gtk_grid_attach (GTK_GRID(table
), data
->CY_range
, 1, 0, 1, 1);
2217 widget
= gtk_toggle_button_new();
2218 image
= gtk_image_new_from_icon_name (ICONNAME_HB_OPE_FUTURE
, GTK_ICON_SIZE_MENU
);
2219 g_object_set (widget
, "image", image
, NULL
);
2220 gtk_widget_set_tooltip_text (widget
, _("Toggle show future transaction"));
2221 data
->CM_future
= widget
;
2222 gtk_grid_attach (GTK_GRID(table
), widget
, 2, 0, 1, 1);
2224 label
= make_label_widget(_("_Type:"));
2225 gtk_grid_attach (GTK_GRID(table
), label
, 3, 0, 1, 1);
2226 data
->CY_type
= make_cycle(label
, CYA_FLT_TYPE
);
2227 gtk_grid_attach (GTK_GRID(table
), data
->CY_type
, 4, 0, 1, 1);
2229 label
= make_label_widget(_("_Status:"));
2230 gtk_grid_attach (GTK_GRID(table
), label
, 5, 0, 1, 1);
2231 data
->CY_status
= make_cycle(label
, CYA_FLT_STATUS
);
2232 gtk_grid_attach (GTK_GRID(table
), data
->CY_status
, 6, 0, 1, 1);
2234 //widget = gtk_button_new_with_mnemonic (_("Reset _filters"));
2235 widget
= gtk_button_new_with_mnemonic (_("_Reset"));
2236 data
->BT_reset
= widget
;
2237 gtk_grid_attach (GTK_GRID(table
), widget
, 7, 0, 1, 1);
2239 //TRANSLATORS: this is for Euro specific users, a toggle to display in 'Minor' currency
2240 widget
= gtk_check_button_new_with_mnemonic (_("Euro _minor"));
2241 data
->CM_minor
= widget
;
2242 gtk_grid_attach (GTK_GRID(table
), widget
, 8, 0, 1, 1);
2244 label
= make_label(NULL
, 0.0, 0.5);
2245 data
->TX_selection
= label
;
2246 gtk_widget_set_halign (label
, GTK_ALIGN_END
);
2247 gtk_widget_set_hexpand (label
, TRUE
);
2248 gtk_grid_attach (GTK_GRID(table
), label
, 10, 0, 1, 1);
2251 label = make_label_widget(_("_Month:"));
2252 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2253 data->CY_month = make_cycle(label, CYA_SELECT);
2254 gtk_box_pack_start (GTK_BOX (hbox), data->CY_month, FALSE, FALSE, 0);
2256 label = make_label_widget(_("_Year:"),);
2257 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2258 data->NB_year = make_year(label);
2259 gtk_box_pack_start (GTK_BOX (hbox), data->NB_year, FALSE, FALSE, 0);
2263 sw
= gtk_scrolled_window_new (NULL
, NULL
);
2264 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw
), GTK_SHADOW_ETCHED_IN
);
2265 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw
), GTK_POLICY_AUTOMATIC
, GTK_POLICY_ALWAYS
);
2266 treeview
= (GtkWidget
*)create_list_transaction(LIST_TXN_TYPE_BOOK
, PREFS
->lst_ope_columns
);
2267 data
->LV_ope
= treeview
;
2268 gtk_container_add (GTK_CONTAINER (sw
), treeview
);
2269 gtk_box_pack_start (GTK_BOX (mainbox
), sw
, TRUE
, TRUE
, 0);
2271 list_txn_set_save_column_width(GTK_TREE_VIEW(treeview
), TRUE
);
2274 table
= gtk_grid_new();
2275 gtk_box_pack_start (GTK_BOX (mainbox
), table
, FALSE
, FALSE
, 0);
2277 widget
= gtk_ui_manager_get_widget (ui
, "/TxnBar");
2278 data
->TB_bar
= widget
;
2279 //gtk_widget_set_halign (widget, GTK_ALIGN_START);
2280 //gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_INLINE_TOOLBAR);
2281 gtk_widget_set_hexpand (widget
, TRUE
);
2282 gtk_grid_attach (GTK_GRID(table
), widget
, 0, 0, 1, 1);
2284 widget
= gtk_ui_manager_get_widget (ui
, "/ToolBar");
2285 data
->TB_tools
= widget
;
2286 //gtk_widget_set_halign (widget, GTK_ALIGN_END);
2287 //gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_INLINE_TOOLBAR);
2288 gtk_widget_set_hexpand (widget
, TRUE
);
2289 gtk_grid_attach (GTK_GRID(table
), widget
, 2, 0, 1, 1);
2292 if(PREFS
->toolbar_style
== 0)
2294 gtk_toolbar_unset_style(GTK_TOOLBAR(data
->TB_bar
));
2295 gtk_toolbar_unset_style(GTK_TOOLBAR(data
->TB_tools
));
2299 gtk_toolbar_set_style(GTK_TOOLBAR(data
->TB_bar
), PREFS
->toolbar_style
-1);
2300 gtk_toolbar_set_style(GTK_TOOLBAR(data
->TB_tools
), PREFS
->toolbar_style
-1);
2304 //todo: should move this
2306 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data
->LV_ope
))), "minor", data
->CM_minor
);
2307 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_future
), (PREFS
->date_future_nbdays
> 0) ? TRUE
: FALSE
);
2308 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data
->CM_minor
), GLOBALS
->minor
);
2309 gtk_widget_grab_focus(GTK_WIDGET(data
->LV_ope
));
2312 g_signal_connect (data
->IB_duplicate
, "response", G_CALLBACK (register_panel_cb_bar_duplicate_response
), NULL
);
2314 data
->handler_id
[HID_RANGE
] = g_signal_connect (data
->CY_range
, "changed", G_CALLBACK (register_panel_cb_filter_daterange
), NULL
);
2315 data
->handler_id
[HID_TYPE
] = g_signal_connect (data
->CY_type
, "changed", G_CALLBACK (register_panel_cb_filter_type
), NULL
);
2316 data
->handler_id
[HID_STATUS
] = g_signal_connect (data
->CY_status
, "changed", G_CALLBACK (register_panel_cb_filter_status
), NULL
);
2318 g_signal_connect (data
->CM_future
, "toggled", G_CALLBACK (register_panel_cb_filter_daterange
), NULL
);
2320 g_signal_connect (data
->BT_reset
, "clicked", G_CALLBACK (register_panel_cb_filter_reset
), NULL
);
2322 g_signal_connect (data
->CM_minor
, "toggled", G_CALLBACK (register_panel_toggle_minor
), NULL
);
2324 //g_signal_connect (GTK_TREE_VIEW(treeview), "cursor-changed", G_CALLBACK (register_panel_update), (gpointer)2);
2325 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview
)), "changed", G_CALLBACK (register_panel_selection
), NULL
);
2326 g_signal_connect (GTK_TREE_VIEW(treeview
), "row-activated", G_CALLBACK (register_panel_onRowActivated
), GINT_TO_POINTER(2));
2329 //todo: test context menu
2331 menu = gtk_menu_new();
2332 menu_items = gtk_ui_manager_get_widget (ui, "/MenuBar/TxnMenu/Add");
2334 menu_items = gtk_menu_item_new_with_label ("test");
2335 gtk_widget_show(menu_items);
2336 gtk_menu_shell_append (GTK_MENU (menu), menu_items);
2339 g_signal_connect (treeview, "button-press-event", G_CALLBACK (listview_context_cb),
2340 // todo: here is not a GtkMenu but GtkImageMenuItem...
2342 //gtk_ui_manager_get_widget (ui, "/MenuBar")
2346 //setup, init and show window
2347 wg
= &PREFS
->acc_wg
;
2350 gtk_window_move(GTK_WINDOW(window
), wg
->l
, wg
->t
);
2351 gtk_window_resize(GTK_WINDOW(window
), wg
->w
, wg
->h
);
2354 gtk_window_maximize(GTK_WINDOW(window
));
2356 gtk_widget_show_all (window
);
2357 gtk_widget_hide(data
->IB_duplicate
);
2359 /* hide showfuture */
2360 hb_widget_visible (data
->CM_future
, PREFS
->date_future_nbdays
> 0 ? TRUE
: FALSE
);
2363 /* make sure splash is up */
2364 while (gtk_events_pending ())
2365 gtk_main_iteration ();
2367 /* setup to moove later */
2368 data
->filter
= da_flt_malloc();
2369 DB( g_print(" - filter ok %p\n", data
->filter
) );