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