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