import homebank-5.1.7
[chaz/homebank] / src / dsp_account.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2018 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "homebank.h"
22
23 #include "dsp_account.h"
24 #include "dsp_mainwindow.h"
25
26 #include "list_operation.h"
27 #include "ui-widgets.h"
28 #include "ui-filter.h"
29 #include "ui-transaction.h"
30 #include "ui-txn-multi.h"
31
32 /****************************************************************************/
33 /* Debug macros */
34 /****************************************************************************/
35 #define MYDEBUG 0
36
37 #if MYDEBUG
38 #define DB(x) (x);
39 #else
40 #define DB(x);
41 #endif
42
43 /* our global datas */
44 extern struct HomeBank *GLOBALS;
45 extern struct Preferences *PREFS;
46
47 //debug
48 #define UI 1
49
50 //extern gchar *CYA_FLT_SELECT[];
51
52 extern gchar *CYA_FLT_TYPE[];
53 extern gchar *CYA_FLT_STATUS[];
54
55
56 static void register_panel_collect_filtered_txn(GtkWidget *view);
57 static void register_panel_listview_populate(GtkWidget *view);
58 static void register_panel_action(GtkWidget *widget, gpointer user_data);
59 static void register_panel_update(GtkWidget *widget, gpointer user_data);
60
61 static void register_panel_export_csv(GtkWidget *widget, gpointer user_data);
62
63 static void register_panel_make_archive(GtkWidget *widget, gpointer user_data);
64
65 static void status_selected_foreach_func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer userdata);
66
67 static void register_panel_edit_multiple(GtkWidget *widget, Transaction *txn, gint column_id, gpointer user_data);
68
69 static void register_panel_selection(GtkTreeSelection *treeselection, gpointer user_data);
70 static void register_panel_onRowActivated (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer userdata);
71
72
73 /* account action functions -------------------- */
74
75 static void register_panel_action_editfilter(GtkAction *action, gpointer user_data)
76 {
77 struct register_panel_data *data = user_data;
78
79 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_FILTER));
80 }
81
82
83 static void register_panel_action_add(GtkAction *action, gpointer user_data)
84 {
85 struct register_panel_data *data = user_data;
86
87 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_ADD));
88 }
89
90 static void register_panel_action_inherit(GtkAction *action, gpointer user_data)
91 {
92 struct register_panel_data *data = user_data;
93
94 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_INHERIT));
95 }
96
97 static void register_panel_action_edit(GtkAction *action, gpointer user_data)
98 {
99 struct register_panel_data *data = user_data;
100
101 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_EDIT));
102 }
103
104 static void register_panel_action_multiedit(GtkAction *action, gpointer user_data)
105 {
106 struct register_panel_data *data = user_data;
107
108 register_panel_edit_multiple(data->window, NULL, 0, user_data);
109 }
110
111 static void register_panel_action_reconcile(GtkAction *action, gpointer user_data)
112 {
113 struct register_panel_data *data = user_data;
114
115 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_RECONCILE));
116 }
117
118 static void register_panel_action_clear(GtkAction *action, gpointer user_data)
119 {
120 struct register_panel_data *data = user_data;
121
122 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_CLEAR));
123 }
124
125 static void register_panel_action_none(GtkAction *action, gpointer user_data)
126 {
127 struct register_panel_data *data = user_data;
128
129 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_NONE));
130 }
131
132 static void register_panel_action_remove(GtkAction *action, gpointer user_data)
133 {
134 struct register_panel_data *data = user_data;
135
136 register_panel_action(data->window, GINT_TO_POINTER(ACTION_ACCOUNT_DELETE));
137 }
138
139
140
141 static void register_panel_action_createtemplate(GtkAction *action, gpointer user_data)
142 {
143 struct register_panel_data *data = user_data;
144
145 register_panel_make_archive(data->window, NULL);
146 }
147
148
149
150 static void register_panel_action_exportcsv(GtkAction *action, gpointer user_data)
151 {
152 struct register_panel_data *data = user_data;
153
154 register_panel_export_csv(data->window, NULL);
155 }
156
157
158 /* = = = = = = = = future version = = = = = = = = */
159
160 static void register_panel_action_exportpdf(GtkAction *action, gpointer user_data)
161 {
162 struct register_panel_data *data = user_data;
163 gchar *name, *filepath;
164
165
166
167 name = g_strdup_printf("%s.pdf", data->acc->name);
168 filepath = g_build_filename(PREFS->path_export, name, NULL);
169 g_free(name);
170
171 if( ui_dialog_export_pdf(GTK_WINDOW(data->window), &filepath) == GTK_RESPONSE_ACCEPT )
172 {
173 DB( g_printf(" filename is'%s'\n", filepath) );
174
175
176 hb_export_pdf_listview(GTK_TREE_VIEW(data->LV_ope), filepath, data->acc->name);
177 }
178
179 g_free(filepath);
180
181
182 }
183
184
185 static void register_panel_action_check_internal_xfer(GtkAction *action, gpointer user_data)
186 {
187 struct register_panel_data *data = user_data;
188 GtkTreeModel *model;
189 GtkTreeIter iter;
190 GList *badxferlist;
191 gboolean valid;
192 gint count;
193
194 DB( g_print("check intenal xfer\n\n") );
195
196 badxferlist = NULL;
197 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_ope));
198 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
199 while (valid)
200 {
201 Transaction *txn;
202
203 gtk_tree_model_get (model, &iter,
204 LST_DSPOPE_DATAS, &txn,
205 -1);
206
207 if( txn->paymode == PAYMODE_INTXFER )
208 {
209 if( transaction_xfer_child_strong_get(txn) == NULL )
210 {
211 DB( g_print(" - invalid xfer: '%s'\n", txn->memo) );
212
213 //test unrecoverable (kxferacc = 0)
214 if( txn->kxferacc <= 0 )
215 {
216 DB( g_print(" - unrecoverable, revert to normal xfer\n") );
217 txn->flags |= OF_CHANGED;
218 txn->paymode = PAYMODE_XFER;
219 txn->kxfer = 0;
220 txn->kxferacc = 0;
221 }
222 else
223 {
224 badxferlist = g_list_append(badxferlist, txn);
225 }
226 }
227 }
228
229 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
230 }
231
232 count = g_list_length (badxferlist);
233 DB( g_print(" - found %d invalid int xfer\n", count) );
234
235 if(count <= 0)
236 {
237 ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_INFO,
238 _("Check internal transfert result"),
239 _("No inconsistency found !")
240 );
241 }
242 else
243 {
244 gboolean do_fix;
245
246 do_fix = ui_dialog_msg_question(
247 GTK_WINDOW(data->window),
248 _("Check internal transfert result"),
249 _("Inconsistency were found: %d\n"
250 "do you want to review and fix ?"),
251 count
252 );
253
254 if(do_fix == GTK_RESPONSE_YES)
255 {
256 GList *tmplist = g_list_first(badxferlist);
257
258 while (tmplist != NULL)
259 {
260 Transaction *stxn = tmplist->data;
261
262 // (open dialog to select date tolerance in days)
263 // ( with info message)
264 // ( with check/fix button and progress bar)
265
266 //adapt this window
267 //-display the src txn
268 //-enable to display 1 of xxx if more than 1
269
270 transaction_xfer_search_or_add_child(GTK_WINDOW(data->window), stxn, TRUE);
271
272 tmplist = g_list_next(tmplist);
273 }
274 }
275 }
276
277 g_list_free (badxferlist);
278
279 }
280
281
282 static void register_panel_action_exportqif(GtkAction *action, gpointer user_data)
283 {
284 struct register_panel_data *data = user_data;
285 gchar *filename;
286
287 DB( g_print("(qif) test qif export\n\n") );
288
289 if( ui_file_chooser_qif(GTK_WINDOW(data->window), &filename) == TRUE )
290 {
291 hb_export_qif_account_single(filename, data->acc);
292 g_free( filename );
293 }
294 }
295
296
297 static void register_panel_action_converttoeuro(GtkAction *action, gpointer user_data)
298 {
299 struct register_panel_data *data = user_data;
300 gchar *msg;
301 gint result;
302
303 DB( g_print("action convert to euro\n") );
304
305 msg = g_strdup_printf(_("Every transaction amount will be divided by %.6f."), PREFS->euro_value);
306
307 result = ui_dialog_msg_confirm_alert(
308 GTK_WINDOW(data->window),
309 _("Are you sure you want to convert this account\nto Euro as Major currency?"),
310 msg,
311 _("_Convert")
312 );
313
314 g_free(msg);
315
316 if(result == GTK_RESPONSE_OK)
317 {
318 account_convert_euro(data->acc);
319 register_panel_update(data->LV_ope, GINT_TO_POINTER(UF_BALANCE));
320 }
321 }
322
323
324 static void register_panel_action_assign(GtkAction *action, gpointer user_data)
325 {
326 struct register_panel_data *data = user_data;
327 gint count;
328 gboolean usermode = TRUE;
329
330 DB( g_print("action assign\n") );
331
332 count = transaction_auto_assign(g_queue_peek_head_link(data->acc->txn_queue), data->accnum);
333 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_ope));
334 GLOBALS->changes_count += count;
335
336 //inform the user
337 if(usermode == TRUE)
338 {
339 gchar *txt;
340
341 if(count == 0)
342 txt = _("No transaction changed");
343 else
344 txt = _("transaction changed: %d");
345
346 ui_dialog_msg_infoerror(GTK_WINDOW(data->window), GTK_MESSAGE_INFO,
347 _("Automatic assignment result"),
348 txt,
349 count);
350 }
351
352 //refresh main
353 if( count > 0 )
354 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
355
356 }
357
358
359 static void register_panel_action_close(GtkAction *action, gpointer user_data)
360 {
361 struct register_panel_data *data = user_data;
362
363 DB( g_print("action close\n") );
364
365 DB( g_print("window %p\n", data->window) );
366
367 gtk_widget_destroy (GTK_WIDGET (data->window));
368
369 //g_signal_emit_by_name(data->window, "delete-event", NULL, &result);
370
371 }
372
373
374 /* these 5 functions are independant from account window */
375
376 /* account functions -------------------- */
377
378 static void register_panel_export_csv(GtkWidget *widget, gpointer user_data)
379 {
380 struct register_panel_data *data;
381 gchar *filename = NULL;
382 GString *node;
383 GIOChannel *io;
384
385 DB( g_print("\n[account] export csv\n") );
386
387 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
388
389 if( ui_file_chooser_csv(GTK_WINDOW(data->window), GTK_FILE_CHOOSER_ACTION_SAVE, &filename, NULL) == TRUE )
390 {
391 DB( g_print(" + filename is %s\n", filename) );
392 io = g_io_channel_new_file(filename, "w", NULL);
393 if(io != NULL)
394 {
395 node = list_txn_to_string(GTK_TREE_VIEW(data->LV_ope), FALSE);
396 g_io_channel_write_chars(io, node->str, -1, NULL, NULL);
397 g_io_channel_unref (io);
398 g_string_free(node, TRUE);
399 }
400 g_free( filename );
401 }
402 }
403
404
405 static void register_panel_edit_multiple(GtkWidget *widget, Transaction *txn, gint column_id, gpointer user_data)
406 {
407 struct register_panel_data *data;
408 GtkWidget *dialog;
409
410 DB( g_print("\n[account] edit multiple\n") );
411
412 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
413
414 DB( g_print(" - txn:%p, column: %d\n", txn, column_id) );
415
416 dialog = ui_multipleedit_dialog_new(GTK_WINDOW(data->window), GTK_TREE_VIEW(data->LV_ope));
417
418 if(txn != NULL && column_id != 0)
419 {
420 ui_multipleedit_dialog_prefill(dialog, txn, column_id);
421 }
422
423 //wait for the user
424 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
425
426 if( result == GTK_RESPONSE_ACCEPT )
427 {
428 gint changes;
429
430 changes = ui_multipleedit_dialog_apply (dialog, NULL);
431 if( changes > 0 )
432 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
433 }
434
435 gtk_widget_destroy (dialog);
436
437 register_panel_update(data->LV_ope, GINT_TO_POINTER(UF_BALANCE));
438 }
439
440
441 /*
442 ** make an archive with the active transaction
443 */
444 static void register_panel_make_archive(GtkWidget *widget, gpointer user_data)
445 {
446 struct register_panel_data *data;
447
448 DB( g_print("\n[account] make archive\n") );
449
450 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
451
452 GtkWidget *p_dialog = NULL;
453 GtkTreeModel *model;
454 GList *selection, *list;
455 gint result, count;
456
457 count = gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope)));
458
459 if( count > 0 )
460 {
461 p_dialog = gtk_message_dialog_new
462 (
463 GTK_WINDOW(data->window),
464 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
465 GTK_MESSAGE_WARNING,
466 GTK_BUTTONS_YES_NO,
467 _("Do you want to create a template with\neach of the selected transaction ?")
468 );
469
470 /*
471 gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
472 _("%d archives will be created"),
473 GLOBALS->changes_count
474 );
475 */
476
477 result = gtk_dialog_run( GTK_DIALOG( p_dialog ) );
478 gtk_widget_destroy( p_dialog );
479
480
481 if(result == GTK_RESPONSE_YES)
482 {
483
484 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_ope));
485 selection = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope)), &model);
486
487 list = g_list_first(selection);
488 while(list != NULL)
489 {
490 Archive *item;
491 Transaction *ope;
492 GtkTreeIter iter;
493
494 gtk_tree_model_get_iter(model, &iter, list->data);
495 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &ope, -1);
496
497 DB( g_print(" create archive %s %.2f\n", ope->memo, ope->amount) );
498
499 item = da_archive_malloc();
500
501 da_archive_init_from_transaction(item, ope);
502
503 GLOBALS->arc_list = g_list_append(GLOBALS->arc_list, item);
504 GLOBALS->changes_count++;
505
506 list = g_list_next(list);
507 }
508
509 g_list_foreach(selection, (GFunc)gtk_tree_path_free, NULL);
510 g_list_free(selection);
511 }
512 }
513 }
514
515
516 static void register_panel_cb_filter_daterange(GtkWidget *widget, gpointer user_data)
517 {
518 struct register_panel_data *data;
519 gint range;
520
521 DB( g_print("\n[account] filter_daterange\n") );
522
523 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
524
525 range = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_range));
526
527 if(range != FLT_RANGE_OTHER)
528 {
529 filter_preset_daterange_set(data->filter, range, data->accnum);
530 // add eventual x days into future display
531 if( PREFS->date_future_nbdays > 0 )
532 filter_preset_daterange_add_futuregap(data->filter, PREFS->date_future_nbdays);
533
534 register_panel_collect_filtered_txn(data->LV_ope);
535 register_panel_listview_populate(data->LV_ope);
536 }
537 else
538 {
539 if(ui_flt_manage_dialog_new(data->window, data->filter, FALSE) != GTK_RESPONSE_REJECT)
540 {
541 register_panel_collect_filtered_txn(data->LV_ope);
542 register_panel_listview_populate(data->LV_ope);
543 register_panel_update(data->LV_ope, GINT_TO_POINTER(UF_SENSITIVE+UF_BALANCE));
544 }
545 }
546
547
548 }
549
550 static void register_panel_cb_filter_type(GtkWidget *widget, gpointer user_data)
551 {
552 struct register_panel_data *data;
553 gint type;
554
555 DB( g_print("\n[account] filter_type\n") );
556 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
557
558 type = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_type));
559
560 filter_preset_type_set(data->filter, type);
561
562 register_panel_collect_filtered_txn(data->LV_ope);
563 register_panel_listview_populate(data->LV_ope);
564 }
565
566
567 static void register_panel_cb_filter_status(GtkWidget *widget, gpointer user_data)
568 {
569 struct register_panel_data *data;
570 gint status;
571
572 DB( g_print("\n[account] filter_status\n") );
573 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
574
575 status = gtk_combo_box_get_active(GTK_COMBO_BOX(data->CY_status));
576
577 filter_preset_status_set(data->filter, status);
578
579 register_panel_collect_filtered_txn(data->LV_ope);
580 register_panel_listview_populate(data->LV_ope);
581 }
582
583
584 static void register_panel_cb_filter_reset(GtkWidget *widget, gpointer user_data)
585 {
586 struct register_panel_data *data;
587
588 DB( g_print("\n[account] filter_reset\n") );
589 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
590
591 filter_default_all_set(data->filter);
592 filter_preset_daterange_set (data->filter, PREFS->date_range_txn, data->accnum);
593 if(PREFS->hidereconciled)
594 filter_preset_status_set (data->filter, 1);
595
596 // add eventual x days into future display
597 if( PREFS->date_future_nbdays > 0 )
598 filter_preset_daterange_add_futuregap(data->filter, PREFS->date_future_nbdays);
599
600 register_panel_collect_filtered_txn(data->LV_ope);
601 register_panel_listview_populate(data->LV_ope);
602
603 g_signal_handler_block(data->CY_range, data->handler_id[HID_RANGE]);
604 g_signal_handler_block(data->CY_type, data->handler_id[HID_TYPE]);
605 g_signal_handler_block(data->CY_status, data->handler_id[HID_STATUS]);
606
607 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_range), data->filter->range);
608 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_type), data->filter->type);
609 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_status), data->filter->status);
610
611 g_signal_handler_unblock(data->CY_status, data->handler_id[HID_STATUS]);
612 g_signal_handler_unblock(data->CY_type, data->handler_id[HID_TYPE]);
613 g_signal_handler_unblock(data->CY_range, data->handler_id[HID_RANGE]);
614
615 }
616
617
618 static void register_panel_balance_refresh(GtkWidget *view)
619 {
620 struct register_panel_data *data;
621 GList *list;
622 gdouble balance;
623 GtkTreeModel *model;
624 guint32 ldate = 0;
625 gushort lpos = 1;
626
627 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(view, GTK_TYPE_WINDOW)), "inst_data");
628
629 DB( g_print("\n[account] balance refresh\n") );
630
631 balance = data->acc->initial;
632
633 //#1270687: sort if date changed
634 if(data->do_sort)
635 {
636 DB( g_print(" - complete txn sort\n") );
637
638 da_transaction_queue_sort(data->acc->txn_queue);
639 data->do_sort = FALSE;
640 }
641
642 list = g_queue_peek_head_link(data->acc->txn_queue);
643 while (list != NULL)
644 {
645 Transaction *ope = list->data;
646 gdouble value;
647
648 //#1267344
649 if(!(ope->status == TXN_STATUS_REMIND))
650 balance += ope->amount;
651
652 ope->balance = balance;
653
654 //#1661806 add show overdraft
655 //#1672209 added round like for #400483
656 ope->overdraft = FALSE;
657 value = hb_amount_round(balance, 2);
658 if( value != 0.0 && value < data->acc->minimum )
659 ope->overdraft = TRUE;
660
661 if(ope->date == ldate)
662 {
663 ope->pos = ++lpos;
664 }
665 else
666 {
667 ope->pos = lpos = 1;
668 }
669 ldate = ope->date;
670
671 list = g_list_next(list);
672 }
673
674 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_ope));
675 list_txn_sort_force(GTK_TREE_SORTABLE(model), NULL);
676
677 }
678
679
680 static void register_panel_collect_filtered_txn(GtkWidget *view)
681 {
682 struct register_panel_data *data;
683 guint i;
684 GList *list;
685
686 DB( g_print("\n[register_panel] collect_filtered_txn\n") );
687
688 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(view, GTK_TYPE_WINDOW)), "inst_data");
689
690 if(data->gpatxn != NULL)
691 g_ptr_array_free (data->gpatxn, TRUE);
692
693 #if MYDEBUG == 1
694 guint nbtxn = g_queue_get_length (data->acc->txn_queue);
695 g_print(" - nb txn %d\n", nbtxn);
696 #endif
697
698 data->gpatxn = g_ptr_array_sized_new(64);
699
700 //data->hidden = 0;
701
702 list = g_queue_peek_head_link(data->acc->txn_queue); i=0;
703 while (list != NULL)
704 {
705 Transaction *ope = list->data;
706
707 if(filter_test(data->filter, ope) == 1)
708 {
709 g_ptr_array_add(data->gpatxn, (gpointer)ope);
710 }
711 /*else
712 {
713 data->hidden++;
714 }*/
715
716 #if MYDEBUG == 1
717
718 if( !(i % 1000) ) { g_print(" - progress %d/%d\n", i, nbtxn); }
719
720 #endif
721 i++;
722 list = g_list_next(list);
723 }
724
725 g_signal_handler_block(data->ST_search, data->handler_id[HID_SEARCH]);
726 gtk_entry_set_text (GTK_ENTRY(data->ST_search), "");
727 g_signal_handler_unblock(data->ST_search, data->handler_id[HID_SEARCH]);
728
729 }
730
731
732 static void register_panel_listview_populate(GtkWidget *widget)
733 {
734 struct register_panel_data *data;
735 GtkTreeModel *model;
736 GtkTreeIter iter;
737 gboolean hastext;
738 gchar *needle;
739 gint sort_column_id;
740 GtkSortType order;
741 guint i, qs_flag;
742
743 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
744
745 DB( g_print("\n[register_panel] listview_populate\n") );
746
747 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_ope));
748
749 // ref model to keep it
750 //g_object_ref(model);
751 //gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_ope), NULL);
752 gtk_list_store_clear (GTK_LIST_STORE(model));
753
754
755 // perf: if you leave the sort, insert is damned slow
756 gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE(GTK_LIST_STORE(model)), &sort_column_id, &order);
757
758 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);
759
760 hastext = gtk_entry_get_text_length (GTK_ENTRY(data->ST_search)) >= 2;
761 needle = (gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_search));
762
763 //build the mask flag for quick search
764 qs_flag = 0;
765 if(hastext)
766 {
767 qs_flag = list_txn_get_quicksearch_column_mask(GTK_TREE_VIEW(data->LV_ope));
768 }
769
770 data->total = 0;
771 data->totalsum = 0.0;
772
773 for(i=0;i<data->gpatxn->len;i++)
774 {
775 Transaction *txn = g_ptr_array_index(data->gpatxn, i);
776 gboolean insert = TRUE;
777
778 if(hastext)
779 {
780 insert = filter_txn_search_match(needle, txn, qs_flag);
781 }
782
783 if(insert)
784 {
785 //gtk_list_store_append (GTK_LIST_STORE(model), &iter);
786 //gtk_list_store_set (GTK_LIST_STORE(model), &iter,
787 gtk_list_store_insert_with_values(GTK_LIST_STORE(model), &iter, -1,
788 LST_DSPOPE_DATAS, txn,
789 -1);
790
791 data->totalsum += txn->amount;
792 data->total++;
793 }
794 }
795
796 //gtk_tree_view_set_model(GTK_TREE_VIEW(data->LV_ope), model); /* Re-attach model to view */
797 //g_object_unref(model);
798
799 // push back the sort id
800 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(GTK_LIST_STORE(model)), sort_column_id, order);
801
802 /* update info range text */
803 {
804 gchar *daterange;
805
806 daterange = filter_daterange_text_get(data->filter);
807 gtk_widget_set_tooltip_markup(GTK_WIDGET(data->CY_range), daterange);
808 g_free(daterange);
809 }
810
811 register_panel_update(data->LV_ope, GINT_TO_POINTER(UF_SENSITIVE+UF_BALANCE));
812
813 }
814
815 static gint txn_list_get_count_reconciled(GtkTreeView *treeview)
816 {
817 GtkTreeModel *model;
818 GList *lselection, *list;
819 gint count = 0;
820
821 model = gtk_tree_view_get_model(treeview);
822 lselection = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(treeview), &model);
823
824 list = g_list_last(lselection);
825 while(list != NULL)
826 {
827 GtkTreeIter iter;
828 Transaction *txn;
829
830
831 gtk_tree_model_get_iter(model, &iter, list->data);
832 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &txn, -1);
833 if(txn->status == TXN_STATUS_RECONCILED)
834 count++;
835
836 list = g_list_previous(list);
837 }
838
839 g_list_foreach(lselection, (GFunc)gtk_tree_path_free, NULL);
840 g_list_free(lselection);
841
842 return count;
843 }
844
845
846 static void txn_list_add_by_value(GtkTreeView *treeview, Transaction *ope)
847 {
848 GtkTreeModel *model;
849 GtkTreeIter iter;
850 //GtkTreePath *path;
851 //GtkTreeSelection *sel;
852
853 DB( g_print("\n[transaction] add_treeview\n") );
854
855 model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
856 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
857 gtk_list_store_set (GTK_LIST_STORE(model), &iter,
858 LST_DSPOPE_DATAS, ope,
859 -1);
860
861 //activate that new line
862 //path = gtk_tree_model_get_path(model, &iter);
863 //gtk_tree_view_expand_to_path(GTK_TREE_VIEW(treeview), path);
864
865 //sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
866 //gtk_tree_selection_select_iter(sel, &iter);
867
868 //gtk_tree_path_free(path);
869
870 }
871
872
873
874
875 /* used to remove a intxfer child from a treeview */
876 static void txn_list_remove_by_value(GtkTreeModel *model, Transaction *txn)
877 {
878 GtkTreeIter iter;
879 gboolean valid;
880
881 if( txn == NULL )
882 return;
883
884 DB( g_print("remove by value %p\n\n", txn) );
885
886 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
887 while (valid)
888 {
889 Transaction *tmp;
890
891 gtk_tree_model_get (model, &iter,
892 LST_DSPOPE_DATAS, &tmp,
893 -1);
894
895 if( txn == tmp)
896 {
897 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
898 break;
899 }
900 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
901 }
902 }
903
904
905 static void status_selected_foreach_func (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer userdata)
906 {
907 gint targetstatus = GPOINTER_TO_INT(userdata);
908 Transaction *txn;
909
910 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &txn, -1);
911
912 account_balances_sub(txn);
913
914 switch(targetstatus)
915 {
916 case TXN_STATUS_NONE:
917 switch(txn->status)
918 {
919 case TXN_STATUS_CLEARED:
920 case TXN_STATUS_RECONCILED:
921 txn->status = TXN_STATUS_NONE;
922 txn->flags |= OF_CHANGED;
923 break;
924 }
925 break;
926
927 case TXN_STATUS_CLEARED:
928 switch(txn->status)
929 {
930 case TXN_STATUS_NONE:
931 txn->status = TXN_STATUS_CLEARED;
932 txn->flags |= OF_CHANGED;
933 break;
934 case TXN_STATUS_CLEARED:
935 txn->status = TXN_STATUS_NONE;
936 txn->flags |= OF_CHANGED;
937 break;
938 }
939 break;
940
941 case TXN_STATUS_RECONCILED:
942 switch(txn->status)
943 {
944 case TXN_STATUS_NONE:
945 case TXN_STATUS_CLEARED:
946 txn->status = TXN_STATUS_RECONCILED;
947 txn->flags |= OF_CHANGED;
948 break;
949 case TXN_STATUS_RECONCILED:
950 txn->status = TXN_STATUS_CLEARED;
951 txn->flags |= OF_CHANGED;
952 break;
953 }
954 break;
955
956 }
957
958
959 account_balances_add(txn);
960
961 /* #492755 let the child transfer unchanged */
962
963 }
964
965
966 static void delete_active_transaction(GtkTreeView *treeview)
967 {
968 GtkTreeModel *model;
969 GList *list;
970
971 model = gtk_tree_view_get_model(treeview);
972 list = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(treeview), &model);
973
974 if(list != NULL)
975 {
976 GtkTreeIter iter;
977
978 gtk_tree_model_get_iter(model, &iter, list->data);
979 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
980 }
981
982 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
983 g_list_free(list);
984
985
986 }
987
988
989
990 static void register_panel_action(GtkWidget *widget, gpointer user_data)
991 {
992 struct register_panel_data *data;
993 gint action = GPOINTER_TO_INT(user_data);
994 guint changes = GLOBALS->changes_count;
995 gboolean result;
996
997 DB( g_print("\n[account] action\n") );
998
999 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1000 //data = INST_DATA(widget);
1001
1002 DB( g_print(" - action=%d\n", action) );
1003
1004 switch(action)
1005 {
1006 //add
1007 case ACTION_ACCOUNT_ADD:
1008 //inherit
1009 case ACTION_ACCOUNT_INHERIT:
1010 {
1011 GtkWidget *dialog;
1012 Transaction *src_txn;
1013 gint type = 0;
1014
1015 homebank_app_date_get_julian();
1016
1017 if(action == ACTION_ACCOUNT_ADD)
1018 {
1019 DB( g_print("(transaction) add multiple\n") );
1020 src_txn = da_transaction_malloc();
1021 src_txn->date = GLOBALS->today;
1022 src_txn->kacc = data->accnum;
1023 type = TRANSACTION_EDIT_ADD;
1024 }
1025 else
1026 {
1027 DB( g_print("(transaction) inherit multiple\n") );
1028 src_txn = da_transaction_clone(list_txn_get_active_transaction(GTK_TREE_VIEW(data->LV_ope)));
1029 //#1432204
1030 src_txn->status = TXN_STATUS_NONE;
1031 type = TRANSACTION_EDIT_INHERIT;
1032 }
1033
1034 dialog = create_deftransaction_window(GTK_WINDOW(data->window), type, FALSE);
1035 result = GTK_RESPONSE_ADD;
1036 while(result == GTK_RESPONSE_ADD || result == GTK_RESPONSE_ADDKEEP)
1037 {
1038 /* clone source transaction */
1039 if( result == GTK_RESPONSE_ADD )
1040 {
1041 data->cur_ope = da_transaction_clone (src_txn);
1042
1043 if( PREFS->heritdate == FALSE ) //fix: 318733 / 1335285
1044 data->cur_ope->date = GLOBALS->today;
1045 }
1046
1047 deftransaction_set_transaction(dialog, data->cur_ope);
1048
1049 result = gtk_dialog_run (GTK_DIALOG (dialog));
1050 if(result == GTK_RESPONSE_ADD || result == GTK_RESPONSE_ADDKEEP || result == GTK_RESPONSE_ACCEPT)
1051 {
1052 Transaction *add_txn;
1053
1054 deftransaction_get(dialog, NULL);
1055 add_txn = transaction_add(data->cur_ope);
1056 if((data->cur_ope->kacc == data->accnum))
1057 {
1058 txn_list_add_by_value(GTK_TREE_VIEW(data->LV_ope), add_txn);
1059 //#1716181 also add to the ptr_array (quickfilter)
1060 g_ptr_array_add(data->gpatxn, (gpointer)add_txn);
1061 }
1062 register_panel_update(widget, GINT_TO_POINTER(UF_BALANCE));
1063 //#1667201 already done into transaction_add
1064 //data->acc->flags |= AF_ADDED;
1065 GLOBALS->changes_count++;
1066 //store last date
1067 src_txn->date = data->cur_ope->date;
1068 }
1069
1070 if( result == GTK_RESPONSE_ADD )
1071 {
1072 da_transaction_free (data->cur_ope);
1073 }
1074
1075 }
1076
1077 deftransaction_dispose(dialog, NULL);
1078 da_transaction_free (src_txn);
1079
1080 gtk_widget_destroy (dialog);
1081 }
1082 break;
1083
1084 case ACTION_ACCOUNT_EDIT:
1085 {
1086 Transaction *active_txn;
1087
1088 active_txn = list_txn_get_active_transaction(GTK_TREE_VIEW(data->LV_ope));
1089
1090 if(active_txn)
1091 {
1092 Transaction *old_txn, *new_txn;
1093
1094 old_txn = da_transaction_clone (active_txn);
1095 new_txn = active_txn;
1096
1097 result = deftransaction_external_edit(GTK_WINDOW(data->window), old_txn, new_txn);
1098
1099 if(result == GTK_RESPONSE_ACCEPT)
1100 {
1101 //manage current window display stuff
1102
1103 //#1270687: sort if date changed
1104 if(old_txn->date != new_txn->date)
1105 data->do_sort = TRUE;
1106
1107 // different account : delete from the display
1108 if( new_txn->kacc != data->accnum )
1109 {
1110 delete_active_transaction(GTK_TREE_VIEW(data->LV_ope));
1111 }
1112
1113 //da_transaction_copy(new_txn, old_txn);
1114
1115 register_panel_update(widget, GINT_TO_POINTER(UF_BALANCE));
1116
1117 data->acc->flags |= AF_CHANGED;
1118 GLOBALS->changes_count++;
1119 }
1120
1121 da_transaction_free (old_txn);
1122 }
1123 }
1124 break;
1125
1126 case ACTION_ACCOUNT_DELETE:
1127 {
1128 GtkWidget *p_dialog = NULL;
1129 GtkTreeModel *model;
1130 GList *selection, *list;
1131 gint result;
1132
1133 DB( g_print(" - delete\n") );
1134
1135 //todo: replace with a call to ui_dialog_msg_question ?
1136 p_dialog = gtk_message_dialog_new
1137 (
1138 GTK_WINDOW(data->window),
1139 GTK_DIALOG_MODAL,
1140 GTK_MESSAGE_WARNING,
1141 GTK_BUTTONS_YES_NO,
1142 _("Do you want to delete\neach of the selected transaction ?")
1143 );
1144
1145 result = gtk_dialog_run( GTK_DIALOG( p_dialog ) );
1146 gtk_widget_destroy( p_dialog );
1147
1148 if(result == GTK_RESPONSE_YES)
1149 {
1150 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_ope));
1151 selection = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope)), &model);
1152
1153 list = g_list_last(selection);
1154 while(list != NULL)
1155 {
1156 Transaction *entry;
1157 GtkTreeIter iter;
1158
1159 gtk_tree_model_get_iter(model, &iter, list->data);
1160 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &entry, -1);
1161
1162 DB( g_print(" delete %s %.2f\n", entry->memo, entry->amount) );
1163
1164 //#1716181 also remove from the ptr_array (quickfilter)
1165 g_ptr_array_remove(data->gpatxn, (gpointer)entry);
1166
1167 // 1) remove visible current and potential xfer
1168 gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
1169 if(entry->paymode == PAYMODE_INTXFER)
1170 {
1171 Transaction *child = transaction_xfer_child_strong_get(entry);
1172 if( child )
1173 {
1174 txn_list_remove_by_value(model, child);
1175 //#1716181 also remove from the ptr_array (quickfilter)
1176 g_ptr_array_remove(data->gpatxn, (gpointer)child);
1177 }
1178 }
1179
1180 // 2) remove datamodel
1181 transaction_remove(entry);
1182 GLOBALS->changes_count++;
1183
1184 list = g_list_previous(list);
1185 }
1186
1187 g_list_foreach(selection, (GFunc)gtk_tree_path_free, NULL);
1188 g_list_free(selection);
1189
1190 register_panel_update(widget, GINT_TO_POINTER(UF_BALANCE));
1191 }
1192 }
1193 break;
1194
1195 //none
1196 case ACTION_ACCOUNT_NONE:
1197 {
1198 GtkTreeSelection *selection;
1199 gint count, result;
1200
1201 count = txn_list_get_count_reconciled(GTK_TREE_VIEW(data->LV_ope));
1202
1203 if(count > 0 )
1204 {
1205
1206 result = ui_dialog_msg_confirm_alert(
1207 GTK_WINDOW(data->window),
1208 _("Are you sure you want to change the status to None?"),
1209 _("Some transaction in your selection are already Reconciled."),
1210 _("_Change")
1211 );
1212 }
1213 else
1214 result = GTK_RESPONSE_OK;
1215
1216 if( result == GTK_RESPONSE_OK )
1217 {
1218 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope));
1219 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc)status_selected_foreach_func,
1220 GINT_TO_POINTER(TXN_STATUS_NONE));
1221
1222 DB( g_print(" - none\n") );
1223
1224 gtk_widget_queue_draw (data->LV_ope);
1225 //gtk_widget_queue_resize (data->LV_acc);
1226
1227 register_panel_update(widget, GINT_TO_POINTER(UF_BALANCE));
1228
1229 data->acc->flags |= AF_CHANGED;
1230 GLOBALS->changes_count++;
1231 }
1232
1233 }
1234 break;
1235 //clear
1236 case ACTION_ACCOUNT_CLEAR:
1237 {
1238 GtkTreeSelection *selection;
1239
1240 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope));
1241 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc)status_selected_foreach_func,
1242 GINT_TO_POINTER(TXN_STATUS_CLEARED));
1243
1244 DB( g_print(" - clear\n") );
1245
1246 gtk_widget_queue_draw (data->LV_ope);
1247 //gtk_widget_queue_resize (data->LV_acc);
1248
1249 register_panel_update(widget, GINT_TO_POINTER(UF_BALANCE));
1250
1251 data->acc->flags |= AF_CHANGED;
1252 GLOBALS->changes_count++;
1253 }
1254 break;
1255
1256
1257 //reconcile
1258 case ACTION_ACCOUNT_RECONCILE:
1259 {
1260 GtkTreeSelection *selection;
1261 gint count, result;
1262
1263 count = txn_list_get_count_reconciled(GTK_TREE_VIEW(data->LV_ope));
1264
1265 if(count > 0 )
1266 {
1267
1268 result = ui_dialog_msg_confirm_alert(
1269 GTK_WINDOW(data->window),
1270 _("Are you sure you want to toggle the status Reconciled?"),
1271 _("Some transaction in your selection are already Reconciled."),
1272 _("_Toggle")
1273 );
1274 }
1275 else
1276 result = GTK_RESPONSE_OK;
1277
1278 if( result == GTK_RESPONSE_OK )
1279 {
1280 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope));
1281 gtk_tree_selection_selected_foreach(selection, (GtkTreeSelectionForeachFunc)status_selected_foreach_func,
1282 GINT_TO_POINTER(TXN_STATUS_RECONCILED));
1283
1284 DB( g_print(" - reconcile\n") );
1285
1286 gtk_widget_queue_draw (data->LV_ope);
1287 //gtk_widget_queue_resize (data->LV_acc);
1288
1289 register_panel_update(widget, GINT_TO_POINTER(UF_BALANCE));
1290
1291 data->acc->flags |= AF_CHANGED;
1292 GLOBALS->changes_count++;
1293 }
1294
1295 }
1296 break;
1297
1298
1299 case ACTION_ACCOUNT_FILTER:
1300 {
1301
1302 if(ui_flt_manage_dialog_new(data->window, data->filter, FALSE) != GTK_RESPONSE_REJECT)
1303 {
1304 register_panel_collect_filtered_txn(data->LV_ope);
1305 register_panel_listview_populate(data->LV_ope);
1306 register_panel_update(data->LV_ope, GINT_TO_POINTER(UF_SENSITIVE+UF_BALANCE));
1307
1308 g_signal_handler_block(data->CY_range, data->handler_id[HID_RANGE]);
1309 gtk_combo_box_set_active(GTK_COMBO_BOX(data->CY_range), FLT_RANGE_OTHER);
1310 g_signal_handler_unblock(data->CY_range, data->handler_id[HID_RANGE]);
1311 }
1312
1313 }
1314 break;
1315
1316 }
1317
1318 //refresh main
1319 if( GLOBALS->changes_count > changes )
1320 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE));
1321
1322 }
1323
1324
1325
1326 static void register_panel_toggle_minor(GtkWidget *widget, gpointer user_data)
1327 {
1328 struct register_panel_data *data;
1329
1330 DB( g_print("\n[account] toggle\n") );
1331
1332 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1333
1334 register_panel_update(data->LV_ope, GINT_TO_POINTER(UF_BALANCE));
1335 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(data->LV_ope));
1336 }
1337
1338
1339 static void register_panel_selection(GtkTreeSelection *treeselection, gpointer user_data)
1340 {
1341
1342 DB( g_print("\n[account] selection changed cb\n") );
1343
1344
1345 register_panel_update(GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), GINT_TO_POINTER(UF_SENSITIVE));
1346
1347 }
1348
1349
1350 static void register_panel_update(GtkWidget *widget, gpointer user_data)
1351 {
1352 struct register_panel_data *data;
1353 GtkTreeSelection *selection;
1354 gint flags = GPOINTER_TO_INT(user_data);
1355 gint count = 0;
1356
1357 DB( g_print("\n[account] update\n") );
1358
1359 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1360 //data = INST_DATA(widget);
1361
1362 GLOBALS->minor = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->CM_minor));
1363
1364 /* set window title */
1365 if(flags & UF_TITLE)
1366 {
1367 DB( g_print(" - UF_TITLE\n") );
1368
1369 }
1370
1371 /* update disabled things */
1372 if(flags & UF_SENSITIVE)
1373 {
1374 gboolean sensitive;
1375
1376 DB( g_print(" - UF_SENSITIVE\n") );
1377
1378 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope));
1379 count = gtk_tree_selection_count_selected_rows(selection);
1380 DB( g_print(" - count = %d\n", count) );
1381
1382
1383 /*
1384 if (active = gtk_tree_selection_get_selected(selection, &model, &iter))
1385 {
1386 gint *indices;
1387
1388 path = gtk_tree_model_get_path(model, &iter);
1389 indices = gtk_tree_path_get_indices(path);
1390
1391 data->accnum = indices[0];
1392
1393 DB( g_print(" active is %d, sel=%d\n", indices[0], active) );
1394 }
1395 */
1396
1397 //5.3.1 if closed account : disable any change
1398 if( data->acc->flags & AF_CLOSED )
1399 {
1400 gtk_widget_set_sensitive (data->TB_bar, FALSE);
1401 //gtk_widget_set_sensitive (data->TB_tools, FALSE);
1402 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/ToolBar/Assign"), FALSE);
1403
1404 gtk_widget_set_sensitive (gtk_ui_manager_get_widget(data->ui, "/MenuBar/TxnMenu"), FALSE);
1405 gtk_widget_set_sensitive (gtk_ui_manager_get_widget(data->ui, "/MenuBar/ToolsMenu"), FALSE);
1406
1407 }
1408 else
1409 {
1410 gtk_widget_set_sensitive (data->TB_bar, TRUE);
1411 //gtk_widget_set_sensitive (data->TB_tools, TRUE);
1412 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/ToolBar/Assign"), TRUE);
1413
1414 gtk_widget_set_sensitive (gtk_ui_manager_get_widget(data->ui, "/MenuBar/TxnMenu"), TRUE);
1415 gtk_widget_set_sensitive (gtk_ui_manager_get_widget(data->ui, "/MenuBar/ToolsMenu"), TRUE);
1416
1417
1418 // multiple: disable inherit, edit
1419 sensitive = (count != 1 ) ? FALSE : TRUE;
1420 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/MenuBar/TxnMenu/Inherit"), sensitive);
1421 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/MenuBar/TxnMenu/Edit"), sensitive);
1422 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/TxnBar/Inherit"), sensitive);
1423 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/TxnBar/Edit"), sensitive);
1424
1425 // single: disable multiedit
1426 sensitive = (count <= 1 ) ? FALSE : TRUE;
1427 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/MenuBar/TxnMenu/MultiEdit"), sensitive);
1428 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/TxnBar/MultiEdit"), sensitive);
1429
1430 // no selection: disable reconcile, delete
1431 sensitive = (count > 0 ) ? TRUE : FALSE;
1432 gtk_widget_set_sensitive (gtk_ui_manager_get_widget(data->ui, "/MenuBar/TxnMenu/TxnStatusMenu"), sensitive);
1433 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/MenuBar/TxnMenu/Delete"), sensitive);
1434 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/MenuBar/TxnMenu/Template"), sensitive);
1435 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/TxnBar/Delete"), sensitive);
1436 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/TxnBar/Cleared"), sensitive);
1437 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/TxnBar/Reconciled"), sensitive);
1438 gtk_action_set_sensitive(gtk_ui_manager_get_action(data->ui, "/TxnBar/Template"), sensitive);
1439
1440 // euro convert
1441 sensitive = PREFS->euro_active;
1442 gtk_action_set_visible(gtk_ui_manager_get_action(data->ui, "/MenuBar/ToolsMenu/ConvToEuro"), sensitive);
1443 }
1444 }
1445
1446 /* update toolbar & list */
1447 if(flags & UF_VISUAL)
1448 {
1449 DB( g_print(" - UF_VISUAL\n") );
1450
1451 if(PREFS->toolbar_style == 0)
1452 gtk_toolbar_unset_style(GTK_TOOLBAR(data->TB_bar));
1453 else
1454 gtk_toolbar_set_style(GTK_TOOLBAR(data->TB_bar), PREFS->toolbar_style-1);
1455
1456 //minor ?
1457 if( PREFS->euro_active )
1458 {
1459 gtk_widget_show(data->CM_minor);
1460 }
1461 else
1462 {
1463 gtk_widget_hide(data->CM_minor);
1464 }
1465 }
1466
1467 /* update balances */
1468 if(flags & UF_BALANCE)
1469 {
1470 DB( g_print(" - UF_BALANCE\n") );
1471
1472 register_panel_balance_refresh(widget);
1473
1474 hb_label_set_colvalue(GTK_LABEL(data->TX_balance[0]), data->acc->bal_bank, data->acc->kcur, GLOBALS->minor);
1475 hb_label_set_colvalue(GTK_LABEL(data->TX_balance[1]), data->acc->bal_today, data->acc->kcur, GLOBALS->minor);
1476 hb_label_set_colvalue(GTK_LABEL(data->TX_balance[2]), data->acc->bal_future, data->acc->kcur, GLOBALS->minor);
1477
1478 ui_mainwindow_populate_accounts(GLOBALS->mainwindow, NULL);
1479 }
1480
1481 /* update fltinfo */
1482 DB( g_print(" - statusbar\n") );
1483
1484 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_ope));
1485 count = gtk_tree_selection_count_selected_rows(selection);
1486 DB( g_print(" - nb selected = %d\n", count) );
1487
1488 /* if more than one ope selected, we make a sum to display to the user */
1489 gdouble opeexp = 0.0;
1490 gdouble opeinc = 0.0;
1491 gchar buf1[64];
1492 gchar buf2[64];
1493 gchar buf3[64];
1494
1495 if( count >= 1 )
1496 {
1497 GList *list, *tmplist;
1498 GtkTreeModel *model;
1499 GtkTreeIter iter;
1500
1501 model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_ope));
1502
1503 list = gtk_tree_selection_get_selected_rows(selection, &model);
1504
1505 tmplist = g_list_first(list);
1506 while (tmplist != NULL)
1507 {
1508 Transaction *item;
1509
1510 gtk_tree_model_get_iter(model, &iter, tmplist->data);
1511 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &item, -1);
1512
1513 if( item->flags & OF_INCOME )
1514 opeinc += item->amount;
1515 else
1516 opeexp += item->amount;
1517
1518 DB( g_print(" - %s, %.2f\n", item->memo, item->amount ) );
1519
1520 tmplist = g_list_next(tmplist);
1521 }
1522 g_list_free(list);
1523
1524 DB( g_print(" %f - %f = %f\n", opeinc, opeexp, opeinc + opeexp) );
1525
1526 hb_strfmon(buf1, 64-1, opeinc, data->acc->kcur, GLOBALS->minor);
1527 hb_strfmon(buf2, 64-1, -opeexp, data->acc->kcur, GLOBALS->minor);
1528 hb_strfmon(buf3, 64-1, opeinc + opeexp, data->acc->kcur, GLOBALS->minor);
1529 }
1530
1531 gchar *msg;
1532
1533 if( count <= 0 )
1534 {
1535 //msg = g_strdup_printf (_("transaction selected: %d, hidden: %d"), count, data->hidden);
1536 hb_strfmon(buf3, 64-1, data->totalsum, data->acc->kcur, GLOBALS->minor);
1537 msg = g_strdup_printf(_("%d items (%s)"), data->total, buf3);
1538 }
1539 else
1540 //TRANSLATORS: detail of the 3 %s which are some amount of selected transaction, 1=total 2=income, 3=expense
1541 //msg = g_strdup_printf (_("transaction selected: %d, hidden: %d / %s ( %s - %s)"), count, data->hidden, buf3, buf1, buf2);
1542 msg = g_strdup_printf(_("%d items (%d selected %s)"), data->total, count, buf3);
1543
1544 gtk_label_set_markup(GTK_LABEL(data->TX_selection), msg);
1545 g_free (msg);
1546
1547 }
1548
1549
1550 void register_panel_onRowActivated (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer userdata)
1551 {
1552 struct register_panel_data *data;
1553 GtkTreeModel *model;
1554 GtkTreeIter iter;
1555 gint col_id, count;
1556 Transaction *ope;
1557
1558 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(treeview), GTK_TYPE_WINDOW)), "inst_data");
1559
1560 //5.3.1 if closed account : disable any change
1561 if( data->acc->flags & AF_CLOSED )
1562 return;
1563
1564
1565 col_id = gtk_tree_view_column_get_sort_column_id (col);
1566
1567 count = gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(treeview));
1568
1569 model = gtk_tree_view_get_model(treeview);
1570
1571 //get transaction double clicked to initiate the widget
1572 gtk_tree_model_get_iter(model, &iter, path);
1573 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &ope, -1);
1574
1575
1576 DB( g_print ("%d rows been double-clicked on column=%d! ope=%s\n", count, col_id, ope->memo) );
1577
1578 if( count == 1)
1579 {
1580 register_panel_action(GTK_WIDGET(treeview), GINT_TO_POINTER(ACTION_ACCOUNT_EDIT));
1581 }
1582 else
1583 {
1584 if(col_id >= LST_DSPOPE_DATE && col_id != LST_DSPOPE_BALANCE)
1585 {
1586 register_panel_edit_multiple (data->window, ope, col_id, data);
1587 }
1588 }
1589 }
1590
1591
1592 /*
1593 static gint listview_context_cb (GtkWidget *widget, GdkEventButton *event, GtkWidget *menu)
1594 {
1595
1596 if (event->button == 3)
1597 {
1598
1599
1600 if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
1601 (gint) event->x, (gint) event->y, &path, NULL, NULL, NULL))
1602 {
1603 gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview), path, NULL, FALSE);
1604 gtk_tree_path_free (path);
1605 }
1606
1607
1608
1609
1610 gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL,
1611 event->button, event->time);
1612
1613 // On indique à l'appelant que l'on a géré cet événement.
1614
1615 return TRUE;
1616 }
1617
1618 // On indique à l'appelant que l'on n'a pas géré cet événement.
1619
1620 return FALSE;
1621 }
1622 */
1623
1624
1625 /*
1626 ** populate the account window
1627 */
1628 void register_panel_window_init(GtkWidget *widget, gpointer user_data)
1629 {
1630 struct register_panel_data *data;
1631 gchar *name;
1632
1633 data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(widget, GTK_TYPE_WINDOW)), "inst_data");
1634
1635 DB( g_print("\n[account] init window\n") );
1636
1637 if( data->acc->flags & AF_CLOSED )
1638 {
1639 name = g_strdup_printf(_("[closed account] %s"), data->acc->name);
1640 gtk_label_set_text (GTK_LABEL(data->LB_name), name);
1641 g_free(name);
1642 }
1643 else
1644 {
1645 gtk_label_set_text (GTK_LABEL(data->LB_name), data->acc->name);
1646 hb_widget_visible (data->IM_closed, (data->acc->flags & AF_CLOSED) ? TRUE : FALSE);
1647 }
1648
1649 DB( g_print(" - sort transactions\n") );
1650 da_transaction_queue_sort(data->acc->txn_queue);
1651
1652 //DB( g_print(" mindate=%d, maxdate=%d %x\n", data->filter->mindate,data->filter->maxdate) );
1653
1654 DB( g_print(" - call update visual\n") );
1655 register_panel_update(widget, GINT_TO_POINTER(UF_VISUAL|UF_SENSITIVE));
1656
1657 DB( g_print(" - set range or populate+update sensitive+balance\n") );
1658
1659 register_panel_cb_filter_reset(widget, user_data);
1660
1661 }
1662
1663 /*
1664 **
1665 */
1666 static gboolean
1667 register_panel_getgeometry(GtkWidget *widget, GdkEventConfigure *event, gpointer user_data)
1668 {
1669 //struct register_panel_data *data = user_data;
1670 struct WinGeometry *wg;
1671
1672 DB( g_print("\n[account] get geometry\n") );
1673
1674 //store position and size
1675 wg = &PREFS->acc_wg;
1676 gtk_window_get_position(GTK_WINDOW(widget), &wg->l, &wg->t);
1677 gtk_window_get_size(GTK_WINDOW(widget), &wg->w, &wg->h);
1678 GdkWindow *gdk_window = gtk_widget_get_window(GTK_WIDGET(widget));
1679 GdkWindowState state = gdk_window_get_state(gdk_window);
1680 wg->s = (state & GDK_WINDOW_STATE_MAXIMIZED) ? 1 : 0;
1681
1682 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) );
1683
1684 return FALSE;
1685 }
1686
1687 /*
1688 **
1689 */
1690 static gboolean register_panel_dispose(GtkWidget *widget, GdkEvent *event, gpointer user_data)
1691 {
1692 //struct register_panel_data *data = user_data;
1693
1694 //data = g_object_get_data(G_OBJECT(widget), "inst_data");
1695
1696 DB( g_print("\n[account] delete-event\n") );
1697
1698 return FALSE;
1699 }
1700
1701 /* Another callback */
1702 static gboolean register_panel_destroy( GtkWidget *widget,
1703 gpointer user_data )
1704 {
1705 struct register_panel_data *data;
1706
1707 data = g_object_get_data(G_OBJECT(widget), "inst_data");
1708
1709
1710 DB( g_print ("\n[account] destroy event occurred\n") );
1711
1712
1713
1714 //enable define windows
1715 GLOBALS->define_off--;
1716
1717 /* unset transaction edit mutex */
1718 if(data->acc)
1719 data->acc->window = NULL;
1720
1721 /* free title and filter */
1722 DB( g_print(" user_data=%p to be free\n", user_data) );
1723 g_free(data->wintitle);
1724
1725 if(data->gpatxn != NULL)
1726 g_ptr_array_free (data->gpatxn, TRUE);
1727
1728 da_filter_free(data->filter);
1729
1730 g_free(data);
1731
1732
1733 //our global list has changed, so update the treeview
1734 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_TITLE+UF_SENSITIVE+UF_BALANCE+UF_REFRESHALL));
1735
1736 return FALSE;
1737 }
1738
1739
1740 static void quick_search_text_changed_cb (GtkWidget *widget, gpointer user_data)
1741 {
1742 struct register_panel_data *data = user_data;
1743
1744 register_panel_listview_populate (data->window);
1745 }
1746
1747
1748 static GtkActionEntry entries[] = {
1749
1750 /* name, icon-name, label */
1751 { "AccountMenu" , NULL, N_("A_ccount"), NULL, NULL, NULL },
1752 { "TxnMenu" , NULL, N_("Transacti_on"), NULL, NULL, NULL },
1753 { "TxnStatusMenu", NULL, N_("_Status"), NULL, NULL, NULL },
1754 { "ToolsMenu" , NULL, N_("_Tools"), NULL, NULL, NULL },
1755 /* = = = = = = = = future version = = = = = = = = */
1756 { "TestingMenu" , NULL, "Testing", NULL, NULL, NULL },
1757
1758 { "Close" , ICONNAME_CLOSE , N_("_Close") , "<control>W", N_("Close the current account"), G_CALLBACK (register_panel_action_close) },
1759
1760 /* name, icon-name, label, accelerator, tooltip */
1761 { "Filter" , ICONNAME_HB_FILTER , N_("_Filter..."), NULL, N_("Open the list filter"), G_CALLBACK (register_panel_action_editfilter) },
1762 { "ConvToEuro" , NULL , N_("Convert to Euro..."), NULL, N_("Convert this account to Euro currency"), G_CALLBACK (register_panel_action_converttoeuro) },
1763
1764 { "Add" , ICONNAME_HB_OPE_ADD , N_("_Add..."), NULL, N_("Add a new transaction"), G_CALLBACK (register_panel_action_add) },
1765 { "Inherit" , ICONNAME_HB_OPE_HERIT , N_("_Inherit..."), NULL, N_("Inherit from the active transaction"), G_CALLBACK (register_panel_action_inherit) },
1766 { "Edit" , ICONNAME_HB_OPE_EDIT , N_("_Edit..."), NULL, N_("Edit the active transaction"), G_CALLBACK (register_panel_action_edit) },
1767
1768 { "None" , NULL , N_("_None"), "<control>N", N_("Toggle none for selected transaction(s)"), G_CALLBACK (register_panel_action_none) },
1769 { "Cleared" , ICONNAME_HB_OPE_CLEARED , N_("_Cleared"), "<control>C", N_("Toggle cleared for selected transaction(s)"), G_CALLBACK (register_panel_action_clear) },
1770 { "Reconciled" , ICONNAME_HB_OPE_RECONCILED, N_("_Reconciled"), "<control>R", N_("Toggle reconciled for selected transaction(s)"), G_CALLBACK (register_panel_action_reconcile) },
1771
1772 { "MultiEdit" , ICONNAME_HB_OPE_MULTIEDIT , N_("_Multiple Edit..."), NULL, N_("Edit multiple transaction"), G_CALLBACK (register_panel_action_multiedit) },
1773 { "Template" , ICONNAME_CONVERT , N_("Create template..."), NULL, N_("Create template"), G_CALLBACK (register_panel_action_createtemplate) },
1774 { "Delete" , ICONNAME_HB_OPE_DELETE , N_("_Delete..."), NULL, N_("Delete selected transaction(s)"), G_CALLBACK (register_panel_action_remove) },
1775
1776 { "Assign" , ICONNAME_HB_ASSIGN_RUN , N_("Auto. assignments"), NULL, N_("Run automatic assignments"), G_CALLBACK (register_panel_action_assign) },
1777 { "ExportQIF" , NULL , N_("Export QIF..."), NULL, N_("Export as QIF"), G_CALLBACK (register_panel_action_exportqif) },
1778 { "ExportCSV" , NULL , N_("Export CSV..."), NULL, N_("Export as CSV"), G_CALLBACK (register_panel_action_exportcsv) },
1779
1780 { "ChkIntXfer" , NULL , N_("Check internal xfer..."), NULL, NULL, G_CALLBACK (register_panel_action_check_internal_xfer) },
1781
1782 /* = = = = = = = = future version = = = = = = = = */
1783 { "ExportPDF" , ICONNAME_PRINT , N_("Export PDF..."), NULL, N_("Export as PDF"), G_CALLBACK (register_panel_action_exportpdf) },
1784
1785 };
1786 static guint n_entries = G_N_ELEMENTS (entries);
1787
1788 static const gchar *ui_info =
1789 "<ui>"
1790 "<menubar name='MenuBar'>"
1791
1792 " <menu action='AccountMenu'>"
1793 " <menuitem action='ExportQIF'/>"
1794 " <menuitem action='ExportCSV'/>"
1795 " <separator/>"
1796 " <menuitem action='Close'/>"
1797 " </menu>"
1798
1799 " <menu action='TxnMenu'>"
1800 " <menuitem action='Add'/>"
1801 " <menuitem action='Inherit'/>"
1802 " <menuitem action='Edit'/>"
1803 " <separator/>"
1804 " <menu action='TxnStatusMenu'>"
1805 " <menuitem action='None'/>"
1806 " <menuitem action='Cleared'/>"
1807 " <menuitem action='Reconciled'/>"
1808 " </menu>"
1809 " <menuitem action='MultiEdit'/>"
1810 " <menuitem action='Template'/>"
1811 " <menuitem action='Delete'/>"
1812 " </menu>"
1813
1814 " <menu action='ToolsMenu'>"
1815 " <menuitem action='Filter'/>"
1816 " <menuitem action='Assign'/>"
1817 " <separator/>"
1818 " <menuitem action='ChkIntXfer'/>"
1819
1820 " <separator/>"
1821 " <menuitem action='ConvToEuro'/>"
1822 " </menu>"
1823
1824 " <menu action='TestingMenu'>"
1825 " <menuitem action='ExportPDF'/>"
1826 " </menu>"
1827
1828 "</menubar>"
1829
1830 "<toolbar name='TxnBar'>"
1831 " <toolitem action='Add'/>"
1832 " <toolitem action='Inherit'/>"
1833 " <toolitem action='Edit'/>"
1834 " <separator/>"
1835 " <toolitem action='Cleared'/>"
1836 " <toolitem action='Reconciled'/>"
1837 " <separator/>"
1838 " <toolitem action='MultiEdit'/>"
1839 " <toolitem action='Template'/>"
1840 " <toolitem action='Delete'/>"
1841 "</toolbar>"
1842 "<toolbar name='ToolBar'>"
1843 " <toolitem action='Filter'/>"
1844 " <toolitem action='Assign'/>"
1845 "</toolbar>"
1846 "</ui>";
1847
1848
1849 GtkWidget *register_panel_window_new(guint32 accnum, Account *acc)
1850 {
1851 struct register_panel_data *data;
1852 struct WinGeometry *wg;
1853 GtkWidget *window, *mainbox, *table, *sw;
1854 GtkWidget *treeview, *label, *widget;
1855 //GtkWidget *menu, *menu_items;
1856 GtkUIManager *ui;
1857 GtkActionGroup *actions;
1858 GtkAction *action;
1859 GError *error = NULL;
1860
1861 DB( g_print("\n[account] create_register_panel_window\n") );
1862
1863 data = g_malloc0(sizeof(struct register_panel_data));
1864 if(!data) return NULL;
1865
1866 //disable define windows
1867 GLOBALS->define_off++;
1868 ui_mainwindow_update(GLOBALS->mainwindow, GINT_TO_POINTER(UF_SENSITIVE));
1869
1870 /* create window, etc */
1871 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1872 data->window = window;
1873
1874 //debug
1875 data->wintitle = NULL;
1876 data->accnum = accnum;
1877 data->acc = acc;
1878
1879 /* set transaction edit mutex */
1880 if(data->acc)
1881 data->acc->window = GTK_WINDOW(window);
1882
1883 //g_free(data->wintitle);
1884 data->wintitle = g_strdup_printf("%s - HomeBank", data->acc->name);
1885 gtk_window_set_title (GTK_WINDOW (window), data->wintitle);
1886
1887 // connect our dispose function
1888 g_signal_connect (window, "delete-event",
1889 G_CALLBACK (register_panel_dispose), (gpointer)data);
1890
1891 // connect our dispose function
1892 g_signal_connect (window, "destroy",
1893 G_CALLBACK (register_panel_destroy), (gpointer)data);
1894
1895 // connect our dispose function
1896 g_signal_connect (window, "configure-event",
1897 G_CALLBACK (register_panel_getgeometry), (gpointer)data);
1898
1899 //store our window private data
1900 g_object_set_data(G_OBJECT(window), "inst_data", (gpointer)data);
1901 DB( g_print(" - new window=%p, inst_data=%p\n", window, data) );
1902
1903 //set the window icon
1904 gtk_window_set_icon_name(GTK_WINDOW (window), ICONNAME_HB_OPE_SHOW );
1905
1906
1907 #if UI == 1
1908 //start test uimanager
1909
1910 actions = gtk_action_group_new ("Account");
1911
1912 //as we use gettext
1913 gtk_action_group_set_translation_domain(actions, GETTEXT_PACKAGE);
1914
1915
1916 DB( g_print(" - add actions: %p user_data: %p\n", actions, data) );
1917 gtk_action_group_add_actions (actions, entries, n_entries, data);
1918
1919 /* set which action should have priority in the toolbar */
1920 action = gtk_action_group_get_action(actions, "Add");
1921 g_object_set(action, "is_important", TRUE, "short_label", _("Add"), NULL);
1922
1923 action = gtk_action_group_get_action(actions, "Inherit");
1924 g_object_set(action, "is_important", TRUE, "short_label", _("Inherit"), NULL);
1925
1926 action = gtk_action_group_get_action(actions, "Edit");
1927 g_object_set(action, "is_important", TRUE, "short_label", _("Edit"), NULL);
1928
1929 action = gtk_action_group_get_action(actions, "Filter");
1930 g_object_set(action, "is_important", TRUE, "short_label", _("Filter"), NULL);
1931
1932 //action = gtk_action_group_get_action(actions, "Reconciled");
1933 //g_object_set(action, "is_important", TRUE, "short_label", _("Reconciled"), NULL);
1934
1935
1936 ui = gtk_ui_manager_new ();
1937
1938 DB( g_print(" - insert action group:\n") );
1939 gtk_ui_manager_insert_action_group (ui, actions, 0);
1940
1941 GtkAccelGroup *ag = gtk_ui_manager_get_accel_group (ui);
1942
1943 DB( g_print(" - add_accel_group actions=%p, ui=%p, ag=%p\n", actions, ui, ag) );
1944
1945 gtk_window_add_accel_group (GTK_WINDOW (window), ag);
1946
1947 DB( g_print(" - add ui from string:\n") );
1948 if (!gtk_ui_manager_add_ui_from_string (ui, ui_info, -1, &error))
1949 {
1950 g_message ("building menus failed: %s", error->message);
1951 g_error_free (error);
1952 }
1953
1954 data->ui = ui;
1955 data->actions = actions;
1956 #endif
1957
1958 mainbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1959 gtk_container_add (GTK_CONTAINER (window), mainbox);
1960
1961 widget = gtk_ui_manager_get_widget (ui, "/MenuBar");
1962 //data->menu = widget;
1963 gtk_box_pack_start (GTK_BOX (mainbox), widget, FALSE, FALSE, 0);
1964
1965 table = gtk_grid_new();
1966 gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_SMALL);
1967 gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_MEDIUM);
1968 gtk_container_set_border_width (GTK_CONTAINER(table), SPACING_SMALL);
1969 gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0);
1970
1971 // account name (+ balance)
1972 widget = gtk_image_new_from_icon_name (ICONNAME_CHANGES_PREVENT, GTK_ICON_SIZE_BUTTON);
1973 data->IM_closed = widget;
1974 gtk_grid_attach (GTK_GRID(table), widget, 0, 0, 1, 1);
1975
1976 label = gtk_label_new(NULL);
1977 data->LB_name = label;
1978 gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_LARGE, -1);
1979 gtk_widget_set_halign (label, GTK_ALIGN_START);
1980 gtk_widget_set_hexpand (label, TRUE);
1981 gtk_grid_attach (GTK_GRID(table), label, 1, 0, 1, 1);
1982
1983 /* balances area */
1984 label = gtk_label_new(_("Bank:"));
1985 gtk_grid_attach (GTK_GRID(table), label, 3, 0, 1, 1);
1986 widget = gtk_label_new(NULL);
1987 data->TX_balance[0] = widget;
1988 gtk_grid_attach (GTK_GRID(table), widget, 4, 0, 1, 1);
1989
1990 label = gtk_label_new(_("Today:"));
1991 gtk_grid_attach (GTK_GRID(table), label, 5, 0, 1, 1);
1992 widget = gtk_label_new(NULL);
1993 data->TX_balance[1] = widget;
1994 gtk_grid_attach (GTK_GRID(table), widget, 6, 0, 1, 1);
1995
1996 label = gtk_label_new(_("Future:"));
1997 gtk_grid_attach (GTK_GRID(table), label, 7, 0, 1, 1);
1998
1999 widget = gtk_label_new(NULL);
2000 data->TX_balance[2] = widget;
2001 gtk_grid_attach (GTK_GRID(table), widget, 8, 0, 1, 1);
2002
2003 //quick search
2004 widget = make_search (NULL);
2005 data->ST_search = widget;
2006 gtk_widget_set_size_request(widget, HB_MINWIDTH_SEARCH, -1);
2007 gtk_grid_attach (GTK_GRID(table), widget, 9, 0, 1, 1);
2008
2009 data->handler_id[HID_SEARCH] = g_signal_connect (data->ST_search, "search-changed", G_CALLBACK (quick_search_text_changed_cb), data);
2010
2011
2012 // windows interior
2013 table = gtk_grid_new();
2014 gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_SMALL);
2015 gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_MEDIUM);
2016 gtk_container_set_border_width (GTK_CONTAINER(table), SPACING_SMALL);
2017 gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0);
2018
2019
2020 label = make_label_widget(_("_Range:"));
2021 gtk_grid_attach (GTK_GRID(table), label, 0, 0, 1, 1);
2022 data->CY_range = make_daterange(label, TRUE);
2023 gtk_grid_attach (GTK_GRID(table), data->CY_range, 1, 0, 1, 1);
2024
2025 label = make_label_widget(_("_Type:"));
2026 gtk_grid_attach (GTK_GRID(table), label, 2, 0, 1, 1);
2027 data->CY_type = make_cycle(label, CYA_FLT_TYPE);
2028 gtk_grid_attach (GTK_GRID(table), data->CY_type, 3, 0, 1, 1);
2029
2030 label = make_label_widget(_("_Status:"));
2031 gtk_grid_attach (GTK_GRID(table), label, 4, 0, 1, 1);
2032 data->CY_status = make_cycle(label, CYA_FLT_STATUS);
2033 gtk_grid_attach (GTK_GRID(table), data->CY_status, 5, 0, 1, 1);
2034
2035 widget = gtk_button_new_with_mnemonic (_("Reset _filters"));
2036 data->BT_reset = widget;
2037 gtk_grid_attach (GTK_GRID(table), widget, 6, 0, 1, 1);
2038
2039 //TRANSLATORS: this is for Euro specific users, a toggle to display in 'Minor' currency
2040 widget = gtk_check_button_new_with_mnemonic (_("Euro _minor"));
2041 data->CM_minor = widget;
2042 gtk_grid_attach (GTK_GRID(table), widget, 8, 0, 1, 1);
2043
2044 label = make_label(NULL, 0.0, 0.5);
2045 data->TX_selection = label;
2046 gtk_widget_set_halign (label, GTK_ALIGN_END);
2047 gtk_widget_set_hexpand (label, TRUE);
2048 gtk_grid_attach (GTK_GRID(table), label, 10, 0, 1, 1);
2049
2050 /*
2051 label = make_label_widget(_("_Month:"));
2052 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2053 data->CY_month = make_cycle(label, CYA_SELECT);
2054 gtk_box_pack_start (GTK_BOX (hbox), data->CY_month, FALSE, FALSE, 0);
2055
2056 label = make_label_widget(_("_Year:"),);
2057 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
2058 data->NB_year = make_year(label);
2059 gtk_box_pack_start (GTK_BOX (hbox), data->NB_year, FALSE, FALSE, 0);
2060 */
2061
2062 //list
2063 sw = gtk_scrolled_window_new (NULL, NULL);
2064 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_ETCHED_IN);
2065 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
2066 treeview = (GtkWidget *)create_list_transaction(LIST_TXN_TYPE_BOOK, PREFS->lst_ope_columns);
2067 data->LV_ope = treeview;
2068 gtk_container_add (GTK_CONTAINER (sw), treeview);
2069 gtk_box_pack_start (GTK_BOX (mainbox), sw, TRUE, TRUE, 0);
2070
2071 list_txn_set_save_column_width(GTK_TREE_VIEW(treeview), TRUE);
2072
2073 /* toolbars */
2074 table = gtk_grid_new();
2075 gtk_box_pack_start (GTK_BOX (mainbox), table, FALSE, FALSE, 0);
2076
2077 widget = gtk_ui_manager_get_widget (ui, "/TxnBar");
2078 data->TB_bar = widget;
2079 //gtk_widget_set_halign (widget, GTK_ALIGN_START);
2080 //gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_INLINE_TOOLBAR);
2081 gtk_widget_set_hexpand (widget, TRUE);
2082 gtk_grid_attach (GTK_GRID(table), widget, 0, 0, 1, 1);
2083
2084 widget = gtk_ui_manager_get_widget (ui, "/ToolBar");
2085 data->TB_tools = widget;
2086 //gtk_widget_set_halign (widget, GTK_ALIGN_END);
2087 //gtk_style_context_add_class (gtk_widget_get_style_context (widget), GTK_STYLE_CLASS_INLINE_TOOLBAR);
2088 gtk_widget_set_hexpand (widget, TRUE);
2089 gtk_grid_attach (GTK_GRID(table), widget, 2, 0, 1, 1);
2090
2091 #ifdef G_OS_WIN32
2092 if(PREFS->toolbar_style == 0)
2093 {
2094 gtk_toolbar_unset_style(GTK_TOOLBAR(data->TB_bar));
2095 gtk_toolbar_unset_style(GTK_TOOLBAR(data->TB_tools));
2096 }
2097 else
2098 {
2099 gtk_toolbar_set_style(GTK_TOOLBAR(data->TB_bar), PREFS->toolbar_style-1);
2100 gtk_toolbar_set_style(GTK_TOOLBAR(data->TB_tools), PREFS->toolbar_style-1);
2101 }
2102 #endif
2103
2104 //todo: should move this
2105 gtk_widget_grab_focus(GTK_WIDGET(data->LV_ope));
2106 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->CM_minor),GLOBALS->minor);
2107 g_object_set_data(G_OBJECT(gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_ope))), "minor", data->CM_minor);
2108
2109 // connect signals
2110 data->handler_id[HID_RANGE] = g_signal_connect (data->CY_range , "changed", G_CALLBACK (register_panel_cb_filter_daterange), NULL);
2111 data->handler_id[HID_TYPE] = g_signal_connect (data->CY_type , "changed", G_CALLBACK (register_panel_cb_filter_type), NULL);
2112 data->handler_id[HID_STATUS] = g_signal_connect (data->CY_status, "changed", G_CALLBACK (register_panel_cb_filter_status), NULL);
2113
2114 g_signal_connect (data->BT_reset , "clicked", G_CALLBACK (register_panel_cb_filter_reset), NULL);
2115
2116 g_signal_connect (data->CM_minor , "toggled", G_CALLBACK (register_panel_toggle_minor), NULL);
2117
2118 //g_signal_connect (GTK_TREE_VIEW(treeview), "cursor-changed", G_CALLBACK (register_panel_update), (gpointer)2);
2119 g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), "changed", G_CALLBACK (register_panel_selection), NULL);
2120 g_signal_connect (GTK_TREE_VIEW(treeview), "row-activated", G_CALLBACK (register_panel_onRowActivated), GINT_TO_POINTER(2));
2121
2122
2123 //todo: test context menu
2124 /*
2125 menu = gtk_menu_new();
2126 menu_items = gtk_ui_manager_get_widget (ui, "/MenuBar/TxnMenu/Add");
2127
2128 menu_items = gtk_menu_item_new_with_label ("test");
2129 gtk_widget_show(menu_items);
2130 gtk_menu_shell_append (GTK_MENU (menu), menu_items);
2131
2132 //todo: debug test
2133 g_signal_connect (treeview, "button-press-event", G_CALLBACK (listview_context_cb),
2134 // todo: here is not a GtkMenu but GtkImageMenuItem...
2135 menu
2136 //gtk_ui_manager_get_widget (ui, "/MenuBar")
2137 );
2138 */
2139
2140 //setup, init and show window
2141 wg = &PREFS->acc_wg;
2142 if(wg->s == 0)
2143 {
2144 gtk_window_move(GTK_WINDOW(window), wg->l, wg->t);
2145 gtk_window_resize(GTK_WINDOW(window), wg->w, wg->h);
2146 }
2147 else
2148 gtk_window_maximize(GTK_WINDOW(window));
2149
2150 gtk_widget_show_all (window);
2151
2152 /* make sure splash is up */
2153 while (gtk_events_pending ())
2154 gtk_main_iteration ();
2155
2156 /* setup to moove later */
2157 data->filter = da_filter_malloc();
2158 DB( g_print(" - filter ok %p\n", data->filter) );
2159
2160
2161 return window;
2162 }
This page took 0.183204 seconds and 4 git commands to generate.