add gitignore
[chaz/homebank] / src / list_operation.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 "list_operation.h"
24
25 /****************************************************************************/
26 /* Debug macros */
27 /****************************************************************************/
28 #define MYDEBUG 0
29
30 #if MYDEBUG
31 #define DB(x) (x);
32 #else
33 #define DB(x);
34 #endif
35
36 /* our global datas */
37 extern struct HomeBank *GLOBALS;
38 extern struct Preferences *PREFS;
39
40
41 //debug
42 //extern gboolean minor_active;
43 extern GdkPixbuf *paymode_icons[];
44
45 /* This is not pretty. Of course you can also use a
46 * separate compare function for each sort ID value */
47
48 static gint ope_sort_iter_compare_strings(gchar *s1, gchar *s2)
49 {
50 return hb_string_utf8_compare(s1, s2);
51 }
52
53
54 static gint
55 ope_sort_iter_compare_func (GtkTreeModel *model,
56 GtkTreeIter *a,
57 GtkTreeIter *b,
58 gpointer userdata)
59 {
60 gint sortcol = GPOINTER_TO_INT(userdata);
61 gint retval = 0;
62 Transaction *ope1, *ope2;
63 gdouble tmpval = 0;
64
65 gtk_tree_model_get(model, a, LST_DSPOPE_DATAS, &ope1, -1);
66 gtk_tree_model_get(model, b, LST_DSPOPE_DATAS, &ope2, -1);
67
68 switch (sortcol)
69 {
70 case LST_DSPOPE_STATUS:
71 if(!(retval = (ope1->flags & OF_VALID) - (ope2->flags & OF_VALID) ) )
72 {
73 retval = (ope1->flags & OF_REMIND) - (ope2->flags & OF_REMIND);
74 }
75 break;
76
77 case LST_DSPOPE_DATE:
78 if(! (retval = ope1->date - ope2->date) )
79 {
80 //g_print("sort on balance d1=%d, d2=%d %f %f\n", ope1->date, ope2->date, ope1->balance , ope2->balance);
81
82 tmpval = ope1->pos - ope2->pos;
83 retval = tmpval > 0 ? 1 : -1;
84 }
85 //g_print("ret=%d\n", ret);
86 break;
87
88 case LST_DSPOPE_ACCOUNT:
89 {
90 Account *a1, *a2;
91
92 a1 = da_acc_get(ope1->kacc);
93 a2 = da_acc_get(ope2->kacc);
94 if( a1 != NULL && a2 != NULL )
95 {
96 retval = ope_sort_iter_compare_strings(a1->name, a2->name);
97 }
98 }
99 break;
100
101 case LST_DSPOPE_INFO:
102 if(!(retval = ope1->paymode - ope2->paymode))
103 {
104 retval = ope_sort_iter_compare_strings(ope1->info, ope2->info);
105 }
106 break;
107
108 case LST_DSPOPE_PAYEE:
109 {
110 Payee *p1, *p2;
111
112 p1 = da_pay_get(ope1->kpay);
113 p2 = da_pay_get(ope2->kpay);
114 if( p1 != NULL && p2 != NULL )
115 {
116 retval = ope_sort_iter_compare_strings(p1->name, p2->name);
117 }
118 }
119 break;
120
121 case LST_DSPOPE_WORDING:
122 retval = ope_sort_iter_compare_strings(ope1->wording, ope2->wording);
123 break;
124
125 case LST_DSPOPE_AMOUNT:
126 case LST_DSPOPE_EXPENSE:
127 case LST_DSPOPE_INCOME:
128 tmpval = ope1->amount - ope2->amount;
129 retval = tmpval > 0 ? 1 : -1;
130 break;
131
132 case LST_DSPOPE_CATEGORY:
133 {
134 Category *c1, *c2;
135 gchar *name1, *name2;
136
137 c1 = da_cat_get(ope1->kcat);
138 c2 = da_cat_get(ope2->kcat);
139 if( c1 != NULL && c2 != NULL )
140 {
141 name1 = da_cat_get_fullname(c1);
142 name2 = da_cat_get_fullname(c2);
143 retval = ope_sort_iter_compare_strings(name1, name2);
144 g_free(name2);
145 g_free(name1);
146 }
147 }
148 break;
149
150 case LST_DSPOPE_TAGS:
151 {
152 gchar *t1, *t2;
153
154 t1 = transaction_tags_tostring(ope1);
155 t2 = transaction_tags_tostring(ope2);
156 retval = ope_sort_iter_compare_strings(t1, t2);
157 g_free(t1);
158 g_free(t2);
159 }
160 break;
161
162 default:
163 g_return_val_if_reached(0);
164 }
165
166 return retval;
167 }
168
169 /*
170 ** date cell function
171 */
172 static void ope_status_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
173 {
174 Transaction *entry;
175 GdkPixbuf *pixbuf = NULL;
176
177 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &entry, -1);
178
179 /*
180 stat[0] = ( entry->ope_Flags & OF_ADDED ) ? data->istatus[2] : data->istatus[0];
181 stat[1] = ( entry->ope_Flags & OF_CHANGED) ? data->istatus[3] : data->istatus[0];
182 stat[2] = ( entry->ope_Flags & OF_VALID ) ? data->istatus[4] : data->istatus[0];
183 if( entry->ope_Flags & OF_REMIND ) stat[2] = data->istatus[1];
184 */
185
186 switch(GPOINTER_TO_INT(user_data))
187 {
188 case 1:
189 pixbuf = ( entry->flags & OF_AUTO ) ? GLOBALS->lst_pixbuf[LST_PIXBUF_AUTO] : ( entry->flags & OF_ADDED ) ? GLOBALS->lst_pixbuf[LST_PIXBUF_ADD] : NULL;
190 break;
191 case 2:
192 pixbuf = ( entry->flags & OF_CHANGED ) ? GLOBALS->lst_pixbuf[LST_PIXBUF_EDIT] : NULL;
193 break;
194 case 3:
195 if( entry->flags & OF_VALID )
196 pixbuf = GLOBALS->lst_pixbuf[LST_PIXBUF_VALID];
197 else
198 {
199 if( entry->flags & OF_REMIND )
200 pixbuf = GLOBALS->lst_pixbuf[LST_PIXBUF_REMIND];
201 }
202 break;
203 }
204 g_object_set(renderer, "pixbuf", pixbuf, NULL);
205 }
206
207
208 /*
209 ** account cell function
210 */
211 static void ope_account_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
212 {
213 Transaction *ope;
214 Account *acc;
215
216 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
217
218 acc = da_acc_get(ope->kacc);
219 if( acc )
220 {
221 g_object_set(renderer, "text", acc->name, NULL);
222 }
223 else
224 g_object_set(renderer, "text", "", NULL);
225 }
226
227 /*
228 ** date cell function
229 */
230 static void ope_date_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
231 {
232 Transaction *ope;
233 gchar buffer[256];
234 GDate *date;
235
236 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
237
238 if(ope->date > 0)
239 {
240 date = g_date_new_julian (ope->date);
241 g_date_strftime (buffer, 256-1, PREFS->date_format, date);
242 g_date_free(date);
243
244 //g_snprintf(buf, sizeof(buf), "%d", ope->ope_Date);
245
246 g_object_set(renderer, "text", buffer, NULL);
247 }
248 else
249 g_object_set(renderer, "text", "????", NULL);
250 }
251
252 /*
253 ** info cell function
254 */
255 static void ope_info_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
256 {
257 Transaction *ope;
258
259 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
260
261 switch(GPOINTER_TO_INT(user_data))
262 {
263 case 1:
264 g_object_set(renderer, "pixbuf", paymode_icons[ope->paymode], NULL);
265 break;
266 case 2:
267 g_object_set(renderer, "text", ope->info, NULL);
268 break;
269 }
270 }
271
272 /*
273 ** payee cell function
274 */
275 static void ope_payee_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
276 {
277 Transaction *ope;
278 Payee *pay;
279
280 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
281
282 pay = da_pay_get(ope->kpay);
283 if(pay != NULL)
284 g_object_set(renderer, "text", pay->name, NULL);
285 else
286 g_object_set(renderer, "text", "", NULL);
287 }
288
289 /*
290 ** tags cell function
291 */
292 static void ope_tags_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
293 {
294 Transaction *ope;
295 gchar *str;
296
297 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
298
299 if(ope->tags != NULL)
300 {
301 str = transaction_tags_tostring(ope);
302 g_object_set(renderer, "text", str, NULL);
303 g_free(str);
304 }
305 else
306 g_object_set(renderer, "text", "", NULL);
307
308
309 }
310
311
312 /*
313 ** wording cell function
314 */
315 static void ope_wording_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
316 {
317 Transaction *ope;
318
319 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
320 g_object_set(renderer, "text", ope->wording, NULL);
321 }
322
323 /*
324 ** amount cell function
325 */
326 static void ope_amount_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
327 {
328 Transaction *ope;
329 gint column = GPOINTER_TO_INT(user_data);
330 gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
331 gint type;
332 gdouble amount;
333 gchar *color;
334
335 // get the transaction
336 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
337 if(column == LST_DSPOPE_BALANCE)
338 amount = ope->balance;
339 else
340 amount = ope->amount;
341
342
343 if(column == LST_DSPOPE_INCOME || column == LST_DSPOPE_EXPENSE)
344 {
345 type = (ope->flags & OF_INCOME) ? LST_DSPOPE_INCOME : LST_DSPOPE_EXPENSE;
346 if( type != column)
347 {
348 g_object_set(renderer, "markup", NULL, NULL);
349 return;
350 }
351 }
352
353 //if(amount != 0)
354 {
355 //mystrfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, ope->amount, GLOBALS->minor);
356
357 //todo: optimize this
358 //store to a data set to the listview
359 //acc = da_acc_get(ope->kacc);
360 //hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, ope->amount, acc->kcur);
361 mystrfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, amount, GLOBALS->minor);
362 color = get_normal_color_amount(amount);
363
364 g_object_set(renderer,
365 "foreground", color,
366 "text", buf,
367 NULL);
368 }
369
370
371 }
372
373
374 /*
375 ** category cell function
376 */
377 static void ope_category_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
378 {
379 Transaction *ope;
380 Category *cat;
381 gchar *fullname;
382
383 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
384
385 if(ope->flags &OF_SPLIT)
386 {
387 g_object_set(renderer, "text", _("- split -"), NULL);
388 }
389 else
390 {
391 cat = da_cat_get(ope->kcat);
392 if( cat != NULL )
393 {
394 fullname = da_cat_get_fullname(cat);
395 g_object_set(renderer, "text", fullname, NULL);
396 g_free(fullname);
397 }
398 else
399 g_object_set(renderer, "text", "", NULL);
400
401 }
402
403 }
404
405
406
407
408 /* column 3: Infos */
409 static GtkTreeViewColumn *info_list_transaction_column()
410 {
411 GtkTreeViewColumn *column;
412 GtkCellRenderer *renderer;
413
414 column = gtk_tree_view_column_new();
415 gtk_tree_view_column_set_title(column, _("Info"));
416
417 renderer = gtk_cell_renderer_pixbuf_new ();
418 gtk_tree_view_column_pack_start(column, renderer, FALSE);
419 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_info_cell_data_function, GINT_TO_POINTER(1), NULL);
420
421 renderer = gtk_cell_renderer_text_new ();
422 gtk_tree_view_column_pack_start(column, renderer, TRUE);
423 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_info_cell_data_function, GINT_TO_POINTER(2), NULL);
424 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_INFO);
425
426 gtk_tree_view_column_set_resizable(column, TRUE);
427 gtk_tree_view_column_set_reorderable(column, TRUE);
428 gtk_tree_view_column_set_alignment (column, 0.5);
429
430 return column;
431 }
432
433
434 /* column 4: Payee */
435 static GtkTreeViewColumn *payee_list_transaction_column()
436 {
437 GtkTreeViewColumn *column;
438 GtkCellRenderer *renderer;
439
440 column = gtk_tree_view_column_new();
441 gtk_tree_view_column_set_title(column, _("Payee"));
442 renderer = gtk_cell_renderer_text_new ();
443 gtk_tree_view_column_pack_start(column, renderer, TRUE);
444 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_payee_cell_data_function, NULL, NULL);
445 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_PAYEE);
446 gtk_tree_view_column_set_resizable(column, TRUE);
447 gtk_tree_view_column_set_reorderable(column, TRUE);
448 gtk_tree_view_column_set_alignment (column, 0.5);
449
450 return column;
451 }
452
453 /* column 5: Wording */
454 static GtkTreeViewColumn *wording_list_transaction_column()
455 {
456 GtkTreeViewColumn *column;
457 GtkCellRenderer *renderer;
458
459 column = gtk_tree_view_column_new();
460 gtk_tree_view_column_set_title(column, _("Memo"));
461 renderer = gtk_cell_renderer_text_new ();
462 gtk_tree_view_column_pack_start(column, renderer, TRUE);
463 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_wording_cell_data_function, NULL, NULL);
464 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_WORDING);
465 gtk_tree_view_column_set_resizable(column, TRUE);
466 gtk_tree_view_column_set_reorderable(column, TRUE);
467 gtk_tree_view_column_set_alignment (column, 0.5);
468
469 return column;
470 }
471
472
473
474
475 /* column 6/7: Amount/Expense/Income */
476
477 static GtkTreeViewColumn *amount_list_transaction_column(gchar *title, gint id)
478 {
479 GtkTreeViewColumn *column;
480 GtkCellRenderer *renderer;
481
482 column = gtk_tree_view_column_new();
483 gtk_tree_view_column_set_title(column, title);
484 renderer = gtk_cell_renderer_text_new ();
485 g_object_set(renderer, "xalign", 1.0, NULL);
486 gtk_tree_view_column_pack_start(column, renderer, TRUE);
487 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_amount_cell_data_function, GINT_TO_POINTER(id), NULL);
488 gtk_tree_view_column_set_sort_column_id (column, id);
489 gtk_tree_view_column_set_resizable(column, TRUE);
490 gtk_tree_view_column_set_reorderable(column, TRUE);
491 gtk_tree_view_column_set_alignment (column, 0.5);
492
493 return column;
494 }
495
496
497
498
499 /* column 8: Category */
500 static GtkTreeViewColumn *category_list_transaction_column()
501 {
502 GtkTreeViewColumn *column;
503 GtkCellRenderer *renderer;
504
505 column = gtk_tree_view_column_new();
506 gtk_tree_view_column_set_title(column, _("Category"));
507 renderer = gtk_cell_renderer_text_new ();
508 gtk_tree_view_column_pack_start(column, renderer, TRUE);
509 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_category_cell_data_function, NULL, NULL);
510 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_CATEGORY);
511 gtk_tree_view_column_set_resizable(column, TRUE);
512 gtk_tree_view_column_set_reorderable(column, TRUE);
513 gtk_tree_view_column_set_alignment (column, 0.5);
514
515 return column;
516 }
517
518 /* column 9: Tags */
519 static GtkTreeViewColumn *tags_list_transaction_column()
520 {
521 GtkTreeViewColumn *column;
522 GtkCellRenderer *renderer;
523
524 column = gtk_tree_view_column_new();
525 gtk_tree_view_column_set_title(column, _("Tags"));
526 renderer = gtk_cell_renderer_text_new ();
527 gtk_tree_view_column_pack_start(column, renderer, TRUE);
528 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_tags_cell_data_function, NULL, NULL);
529 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_TAGS);
530 gtk_tree_view_column_set_resizable(column, TRUE);
531 gtk_tree_view_column_set_reorderable(column, TRUE);
532 gtk_tree_view_column_set_alignment (column, 0.5);
533
534 return column;
535 }
536
537 static GtkTreeViewColumn *list_transaction_get_column(GList *list, gint search_id)
538 {
539 GtkTreeViewColumn *column = NULL;
540 GList *tmp;
541 gint id;
542
543 tmp = g_list_first(list);
544 while (tmp != NULL)
545 {
546 id = gtk_tree_view_column_get_sort_column_id(tmp->data);
547 if( search_id == id)
548 column = tmp->data;
549
550 tmp = g_list_next(tmp);
551 }
552
553 return column;
554 }
555
556
557 guint list_transaction_get_quicksearch_column_mask(GtkTreeView *treeview)
558 {
559 GtkTreeViewColumn *column;
560 guint n, mask;
561 gint id;
562
563 mask = 0;
564 for(n=0; n < NUM_LST_DSPOPE-1 ; n++ ) // -1 cause account not to be processed
565 {
566 column = gtk_tree_view_get_column (treeview, n);
567 if(column == NULL)
568 continue;
569
570 if( gtk_tree_view_column_get_visible(column) )
571 {
572 id = gtk_tree_view_column_get_sort_column_id (column);
573 switch(id)
574 {
575 case LST_DSPOPE_WORDING: mask |= FLT_QSEARCH_MEMO; break;
576 case LST_DSPOPE_INFO: mask |= FLT_QSEARCH_INFO; break;
577 case LST_DSPOPE_PAYEE: mask |= FLT_QSEARCH_PAYEE; break;
578 case LST_DSPOPE_CATEGORY: mask |= FLT_QSEARCH_CATEGORY; break;
579 case LST_DSPOPE_TAGS: mask |= FLT_QSEARCH_TAGS; break;
580 }
581 }
582 }
583
584 return mask;
585 }
586
587
588 /* todo: something simpler to sort ? */
589 void list_transaction_sort_force(GtkTreeSortable *sortable, gpointer user_data)
590 {
591 gint sort_column_id;
592 GtkSortType order;
593
594 DB( g_print("list_transaction_sort_force\n") );
595
596 gtk_tree_sortable_get_sort_column_id(sortable, &sort_column_id, &order);
597 DB( g_print(" - id %d order %d\n", sort_column_id, order) );
598
599 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sortable), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, order);
600 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sortable), sort_column_id, order);
601 }
602
603
604 static void list_transaction_sort_column_changed(GtkTreeSortable *sortable, gpointer user_data)
605 {
606 struct list_transaction_data *data = user_data;
607 gint id;
608 GtkSortType order;
609 gboolean showBalance;
610
611 gtk_tree_sortable_get_sort_column_id(sortable, &id, &order);
612
613 DB( g_print("list_transaction_columns_changed %d %d\n", id, order) );
614
615 //here save the transaction list columnid and sort order
616 PREFS->lst_ope_sort_id = id;
617 PREFS->lst_ope_sort_order = order;
618
619 //manage visibility of balance column
620 //showBalance = (id == LST_DSPOPE_DATE && order == GTK_SORT_ASCENDING) ? data->tvc_is_visible : FALSE;
621 showBalance = (id == LST_DSPOPE_DATE) ? data->tvc_is_visible : FALSE;
622 gtk_tree_view_column_set_visible (data->tvc_balance, showBalance);
623 }
624
625
626 static void list_transaction_set_columns(GtkTreeView *treeview, gint *visibility)
627 {
628 struct list_transaction_data *data;
629 GtkTreeViewColumn *column, *base;
630 gboolean visible;
631 GList *list;
632 gint i = 0;
633
634 DB( g_print("(list_transaction_set_columns)\n") );
635
636 data = g_object_get_data(G_OBJECT(treeview), "inst_data");
637
638 list = gtk_tree_view_get_columns( treeview );
639
640 base = NULL;
641
642 for(i=0; i < NUM_LST_DSPOPE-1 ; i++ ) // -1 cause account not to be processed
643 {
644 column = list_transaction_get_column(list, ABS(visibility[i]));
645 if( column != NULL )
646 {
647 DB( g_print(" - pos:%d col:%d (%s)\n", i, visibility[i], gtk_tree_view_column_get_title(column)) );
648
649 gtk_tree_view_move_column_after(treeview, column, base);
650 base = column;
651
652 visible = visibility[i] < 0 ? FALSE : TRUE;
653 gtk_tree_view_column_set_visible (column, visible);
654 if( ABS(visibility[i]) == LST_DSPOPE_BALANCE)
655 {
656 data->tvc_is_visible = visible;
657 }
658
659 }
660
661 }
662
663 g_list_free(list );
664 }
665
666
667 static void list_transaction_destroy( GtkWidget *widget, gpointer user_data )
668 {
669 struct list_transaction_data *data;
670
671 data = g_object_get_data(G_OBJECT(widget), "inst_data");
672
673 DB( g_print ("\n[list_transaction] destroy event occurred\n") );
674
675
676 DB( g_print(" - view=%p, inst_data=%p\n", widget, data) );
677 g_free(data);
678 }
679
680
681 /*
682 ** create our transaction list
683 ** Status, Date, Info, Payee, Wording, (Amount), Expense, Income, Category
684 */
685 GtkWidget *create_list_transaction(gint type, gboolean *pref_columns)
686 {
687 struct list_transaction_data *data;
688 GtkListStore *store;
689 GtkWidget *view;
690 GtkCellRenderer *renderer;
691 GtkTreeViewColumn *column, *col_acc = NULL;
692
693
694 data = g_malloc0(sizeof(struct list_transaction_data));
695 if(!data) return NULL;
696
697 /* create list store */
698 store = gtk_list_store_new(
699 NUM_LST_DSPOPE,
700 G_TYPE_POINTER, /*only really used columns, other are fake */
701 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
702 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
703 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
704 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
705 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
706 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
707 G_TYPE_BOOLEAN, G_TYPE_BOOLEAN
708 );
709
710 //treeview
711 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
712 g_object_unref(store);
713
714 //store our window private data
715 g_object_set_data(G_OBJECT(view), "inst_data", (gpointer)data);
716 DB( g_print(" - view=%p, inst_data=%p\n", view, data) );
717
718 // connect our dispose function
719 g_signal_connect (view, "destroy",
720 G_CALLBACK (list_transaction_destroy), (gpointer)data);
721
722 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), PREFS->rules_hint);
723 //gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
724 // COLUMN_DESCRIPTION);
725
726 if(type == TRN_LIST_TYPE_BOOK)
727 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), GTK_SELECTION_MULTIPLE);
728
729 /* column 1: Status */
730 column = gtk_tree_view_column_new();
731 gtk_tree_view_column_set_title(column, _("Status"));
732
733 renderer = gtk_cell_renderer_pixbuf_new ();
734 gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
735 gtk_tree_view_column_pack_start(column, renderer, TRUE);
736 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_status_cell_data_function, GINT_TO_POINTER(1), NULL);
737
738 renderer = gtk_cell_renderer_pixbuf_new ();
739 gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
740 gtk_tree_view_column_pack_start(column, renderer, TRUE);
741 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_status_cell_data_function, GINT_TO_POINTER(2), NULL);
742
743 renderer = gtk_cell_renderer_pixbuf_new ();
744 gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
745 gtk_tree_view_column_pack_start(column, renderer, TRUE);
746 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_status_cell_data_function, GINT_TO_POINTER(3), NULL);
747
748 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_STATUS);
749 //gtk_tree_view_column_set_resizable(column, TRUE);
750 gtk_tree_view_column_set_alignment (column, 0.5);
751 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
752
753
754 if(type == TRN_LIST_TYPE_DETAIL)
755 {
756 column = gtk_tree_view_column_new();
757 col_acc = column;
758 gtk_tree_view_column_set_title(column, _("Account"));
759 renderer = gtk_cell_renderer_text_new ();
760 gtk_tree_view_column_pack_start(column, renderer, TRUE);
761 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_account_cell_data_function, NULL, NULL);
762 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_ACCOUNT);
763 gtk_tree_view_column_set_resizable(column, TRUE);
764 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
765 }
766
767
768 /* column 2: Date */
769 column = gtk_tree_view_column_new();
770 gtk_tree_view_column_set_title(column, _("Date"));
771 renderer = gtk_cell_renderer_text_new ();
772 gtk_tree_view_column_pack_start(column, renderer, TRUE);
773 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_date_cell_data_function, NULL, NULL);
774 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_DATE);
775 gtk_tree_view_column_set_resizable(column, TRUE);
776 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
777
778
779 column = info_list_transaction_column();
780 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
781
782 column = payee_list_transaction_column();
783 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
784
785 column = wording_list_transaction_column();
786 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
787
788 column = amount_list_transaction_column(_("Amount"), LST_DSPOPE_AMOUNT);
789 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
790
791 column = amount_list_transaction_column(_("Expense"), LST_DSPOPE_EXPENSE);
792 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
793
794 column = amount_list_transaction_column(_("Income"), LST_DSPOPE_INCOME);
795 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
796
797 column = category_list_transaction_column();
798 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
799
800 column = tags_list_transaction_column();
801 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
802
803 if(type != TRN_LIST_TYPE_DETAIL)
804 {
805 column = amount_list_transaction_column(_("Balance"), LST_DSPOPE_BALANCE);
806 data->tvc_balance = column;
807 gtk_tree_view_column_set_clickable(column, FALSE);
808 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
809 }
810
811 /* column 9: empty */
812 column = gtk_tree_view_column_new();
813 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
814
815 /* sort */
816 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_STATUS , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_STATUS), NULL);
817 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_DATE , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_DATE), NULL);
818 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_INFO , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_INFO), NULL);
819 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_PAYEE , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_PAYEE), NULL);
820 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_WORDING , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_WORDING), NULL);
821 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_AMOUNT , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_AMOUNT), NULL);
822 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_EXPENSE , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_EXPENSE), NULL);
823 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_INCOME , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_INCOME), NULL);
824 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_CATEGORY, ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_CATEGORY), NULL);
825 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_TAGS , ope_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_TAGS), NULL);
826
827
828
829 /* apply user preference for columns */
830 list_transaction_set_columns(GTK_TREE_VIEW(view), pref_columns);
831
832 /* force accoutn column for detail view */
833 if(type == TRN_LIST_TYPE_DETAIL)
834 {
835 gtk_tree_view_move_column_after(GTK_TREE_VIEW(view), col_acc, NULL);
836 }
837
838 /* set initial sort order */
839 DB( g_print("set sort to %d %d\n", PREFS->lst_ope_sort_id, PREFS->lst_ope_sort_order) );
840 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), PREFS->lst_ope_sort_id, PREFS->lst_ope_sort_order);
841
842
843 /* signals */
844 if(type == TRN_LIST_TYPE_BOOK)
845 g_signal_connect (GTK_TREE_SORTABLE(store), "sort-column-changed", G_CALLBACK (list_transaction_sort_column_changed), data);
846
847 return(view);
848 }
849
850
851 /* ---------------------------------------------- */
852
853 /*
854 ** account cell function
855 */
856 static void ope_importaccount_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
857 {
858 Transaction *ope;
859 Account *acc, *dacc;
860
861 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
862
863 acc = da_acc_get(ope->kacc);
864 if( acc )
865 {
866 if(acc->imp_key > 0)
867 {
868 dacc = da_acc_get(acc->imp_key);
869 if( dacc )
870 g_object_set(renderer, "text", dacc->name, NULL);
871 }
872 else
873 g_object_set(renderer, "text", acc->name, NULL);
874
875 }
876 }
877
878 /*
879 ** amount cell function
880 */
881 static void ope_importamount_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
882 {
883 Transaction *ope;
884 gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
885 gchar *color;
886
887 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
888
889 mystrfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, ope->amount, GLOBALS->minor);
890 //hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, ope->amount, GLOBALS->minor);
891
892 color = get_normal_color_amount(ope->amount);
893
894 g_object_set(renderer,
895 "foreground", color,
896 "text", buf,
897 NULL);
898
899 }
900
901 /*
902 **
903 */
904 static void ope_importstatus_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
905 {
906 Transaction *ope;
907 GdkPixbuf *pixbuf = NULL;
908
909 // get the transaction
910 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
911
912 if( ope->same != NULL )
913 pixbuf = GLOBALS->lst_pixbuf[LST_PIXBUF_WARNING];
914
915 g_object_set(renderer, "pixbuf", pixbuf, NULL);
916 }
917
918
919 static void
920 ope_importfixed_toggled (GtkCellRendererToggle *cell,
921 gchar *path_str,
922 gpointer data)
923 {
924 GtkTreeModel *model = (GtkTreeModel *)data;
925 GtkTreeIter iter;
926 GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
927 gboolean fixed;
928
929 /* get toggled iter */
930 gtk_tree_model_get_iter (model, &iter, path);
931 gtk_tree_model_get (model, &iter, LST_OPE_IMPTOGGLE, &fixed, -1);
932
933 /* do something with the value */
934 fixed ^= 1;
935
936 /* set new value */
937 gtk_list_store_set (GTK_LIST_STORE (model), &iter, LST_OPE_IMPTOGGLE, fixed, -1);
938
939 /* clean up */
940 gtk_tree_path_free (path);
941 }
942
943 /*
944 ** create our transaction list
945 */
946 GtkWidget *create_list_import_transaction(void)
947 {
948 GtkListStore *store;
949 GtkWidget *view;
950 GtkCellRenderer *renderer;
951 GtkTreeViewColumn *column;
952
953 /* create list store */
954 store = gtk_list_store_new(
955 10,
956 G_TYPE_POINTER,
957 G_TYPE_BOOLEAN,
958 G_TYPE_BOOLEAN,
959 G_TYPE_BOOLEAN,
960 G_TYPE_BOOLEAN,
961 G_TYPE_BOOLEAN,
962 G_TYPE_BOOLEAN,
963 G_TYPE_BOOLEAN,
964 G_TYPE_BOOLEAN,
965 G_TYPE_BOOLEAN
966 );
967
968 //treeview
969 view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
970 g_object_unref(store);
971
972 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
973 //gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
974 // COLUMN_DESCRIPTION);
975
976 //gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), GTK_SELECTION_MULTIPLE);
977
978 /* column: Selection */
979 renderer = gtk_cell_renderer_toggle_new ();
980
981 g_signal_connect (renderer, "toggled",
982 G_CALLBACK (ope_importfixed_toggled), store);
983
984
985 column = gtk_tree_view_column_new_with_attributes (NULL,
986 renderer,
987 "active", LST_OPE_IMPTOGGLE,
988 NULL);
989
990 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
991
992 /* column: Duplicate */
993 column = gtk_tree_view_column_new();
994 //gtk_tree_view_column_set_title(column, _("Import ?"));
995 renderer = gtk_cell_renderer_pixbuf_new ();
996 gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
997 gtk_tree_view_column_pack_start(column, renderer, TRUE);
998 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_importstatus_cell_data_function, NULL, NULL);
999 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1000
1001 //#ifndef NOOFX
1002 /* column: Account */
1003 column = gtk_tree_view_column_new();
1004 gtk_tree_view_column_set_title(column, _("Account"));
1005 renderer = gtk_cell_renderer_text_new ();
1006 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1007 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_importaccount_cell_data_function, NULL, NULL);
1008 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_DATE);
1009 gtk_tree_view_column_set_resizable(column, TRUE);
1010 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1011 //#endif
1012
1013 /* column: Date */
1014 column = gtk_tree_view_column_new();
1015 gtk_tree_view_column_set_title(column, _("Date"));
1016 renderer = gtk_cell_renderer_text_new ();
1017 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1018 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_date_cell_data_function, NULL, NULL);
1019 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_DATE);
1020 gtk_tree_view_column_set_resizable(column, TRUE);
1021 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1022
1023
1024 /* column: Wording */
1025 column = gtk_tree_view_column_new();
1026 gtk_tree_view_column_set_title(column, _("Memo"));
1027 renderer = gtk_cell_renderer_text_new ();
1028 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1029 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_wording_cell_data_function, NULL, NULL);
1030 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_WORDING);
1031 gtk_tree_view_column_set_resizable(column, TRUE);
1032 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1033
1034 /* column: Amount */
1035 column = gtk_tree_view_column_new();
1036 gtk_tree_view_column_set_title(column, _("Amount"));
1037 renderer = gtk_cell_renderer_text_new ();
1038 g_object_set(renderer, "xalign", 1.0, NULL);
1039 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1040 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_importamount_cell_data_function, NULL, NULL);
1041 gtk_tree_view_column_set_alignment (column, 1.0);
1042 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_EXPENSE);
1043 gtk_tree_view_column_set_resizable(column, TRUE);
1044 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1045
1046 /* column: Infos */
1047 column = gtk_tree_view_column_new();
1048 gtk_tree_view_column_set_title(column, _("Info"));
1049
1050 renderer = gtk_cell_renderer_pixbuf_new ();
1051 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1052 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_info_cell_data_function, GINT_TO_POINTER(1), NULL);
1053
1054 renderer = gtk_cell_renderer_text_new ();
1055 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1056 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_info_cell_data_function, GINT_TO_POINTER(2), NULL);
1057 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_INFO);
1058 gtk_tree_view_column_set_resizable(column, TRUE);
1059 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1060
1061 /* column: Payee */
1062
1063 column = gtk_tree_view_column_new();
1064 gtk_tree_view_column_set_title(column, _("Payee"));
1065 renderer = gtk_cell_renderer_text_new ();
1066 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1067 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_payee_cell_data_function, NULL, NULL);
1068 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_PAYEE);
1069 gtk_tree_view_column_set_resizable(column, TRUE);
1070 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1071
1072 /* column : Category */
1073
1074 column = gtk_tree_view_column_new();
1075 gtk_tree_view_column_set_title(column, _("Category"));
1076 renderer = gtk_cell_renderer_text_new ();
1077 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1078 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_category_cell_data_function, NULL, NULL);
1079 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_CATEGORY);
1080 gtk_tree_view_column_set_resizable(column, TRUE);
1081 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1082
1083
1084
1085 /* column 6: empty */
1086 column = gtk_tree_view_column_new();
1087 gtk_tree_view_append_column (GTK_TREE_VIEW(view), column);
1088
1089 return(view);
1090 }
This page took 0.100146 seconds and 4 git commands to generate.