]> Dogcows Code - chaz/homebank/blob - src/list_operation.c
import homebank-5.1.7
[chaz/homebank] / src / list_operation.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2018 Maxime DOYEN
3 *
4 * This file is part of HomeBank.
5 *
6 * HomeBank is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * HomeBank is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "homebank.h"
22
23 #include "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
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 list_txn_sort_iter_compare_strings(gchar *s1, gchar *s2)
49 {
50 return hb_string_utf8_compare(s1, s2);
51 }
52
53
54 static gint
55 list_txn_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_ADDED) - (ope2->flags & OF_ADDED) ) )
72 {
73 retval = (ope1->flags & OF_CHANGED) - (ope2->flags & OF_CHANGED);
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 retval = list_txn_sort_iter_compare_strings((a1 != NULL) ? a1->name : NULL, (a2 != NULL) ? a2->name : NULL);
95 }
96 break;
97
98 case LST_DSPOPE_INFO:
99 if(!(retval = ope1->paymode - ope2->paymode))
100 {
101 retval = list_txn_sort_iter_compare_strings(ope1->info, ope2->info);
102 }
103 break;
104
105 case LST_DSPOPE_PAYEE:
106 {
107 if( ope1->paymode==PAYMODE_INTXFER && ope2->paymode==PAYMODE_INTXFER )
108 {
109 Account *a1, *a2;
110
111 a1 = da_acc_get(ope1->kxferacc);
112 a2 = da_acc_get(ope2->kxferacc);
113 retval = list_txn_sort_iter_compare_strings((a1 != NULL) ? a1->name : NULL, (a2 != NULL) ? a2->name : NULL);
114 }
115 else
116 {
117 Payee *p1, *p2;
118
119 p1 = da_pay_get(ope1->kpay);
120 p2 = da_pay_get(ope2->kpay);
121 retval = list_txn_sort_iter_compare_strings((p1 != NULL) ? p1->name : NULL, (p2 != NULL) ? p2->name : NULL);
122 }
123 }
124 break;
125
126 case LST_DSPOPE_MEMO:
127 retval = list_txn_sort_iter_compare_strings(ope1->memo, ope2->memo);
128 break;
129
130 case LST_DSPOPE_CLR:
131 retval = ope1->status - ope2->status;
132 break;
133
134 case LST_DSPOPE_AMOUNT:
135 case LST_DSPOPE_EXPENSE:
136 case LST_DSPOPE_INCOME:
137 tmpval = ope1->amount - ope2->amount;
138 retval = tmpval > 0 ? 1 : -1;
139 break;
140
141 case LST_DSPOPE_CATEGORY:
142 {
143 Category *c1, *c2;
144 gchar *name1, *name2;
145
146 c1 = da_cat_get(ope1->kcat);
147 c2 = da_cat_get(ope2->kcat);
148 if( c1 != NULL && c2 != NULL )
149 {
150 name1 = da_cat_get_fullname(c1);
151 name2 = da_cat_get_fullname(c2);
152 retval = list_txn_sort_iter_compare_strings(name1, name2);
153 g_free(name2);
154 g_free(name1);
155 }
156 }
157 break;
158
159 case LST_DSPOPE_TAGS:
160 {
161 gchar *t1, *t2;
162
163 t1 = transaction_tags_tostring(ope1);
164 t2 = transaction_tags_tostring(ope2);
165 retval = list_txn_sort_iter_compare_strings(t1, t2);
166 g_free(t2);
167 g_free(t1);
168 }
169 break;
170
171 default:
172 g_return_val_if_reached(0);
173 }
174
175 return retval;
176 }
177
178
179 static void list_txn_eval_future(GtkCellRenderer *renderer, Transaction *txn)
180 {
181
182 //it seems we are not able to get a valid GdkRGBA
183 //nor to set/use the alpha
184 /*GdkRGBA *rgba;
185 g_object_get(renderer, "foreground-rgba", &rgba, NULL);
186 g_print("forcol: %p %f %f %f %f\n", rgba, rgba->red, rgba->green, rgba->blue, rgba->alpha);
187 rgba->red = 1.0;
188 rgba->alpha = 0.1;
189 g_object_set(renderer, "foreground-set", TRUE,
190 "foreground-rgba", rgba,
191 NULL);
192 gdk_rgba_free(rgba);
193 */
194
195 if(txn->date > GLOBALS->today)
196 {
197 g_object_set(renderer,
198 "scale-set", TRUE,
199 "scale", 0.8,
200 "style-set", TRUE,
201 "style", PANGO_STYLE_OBLIQUE,
202 NULL);
203 }
204 else
205 {
206 g_object_set(renderer, "scale-set", FALSE, "style-set", FALSE,
207 NULL);
208 }
209 }
210
211
212 /*
213 ** date cell function
214 */
215 static void list_txn_status_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
216 {
217 Transaction *entry;
218 gchar *iconname = NULL;
219
220 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &entry, -1);
221
222 /*
223 stat[0] = ( entry->ope_Flags & OF_ADDED ) ? data->istatus[2] : data->istatus[0];
224 stat[1] = ( entry->ope_Flags & OF_CHANGED) ? data->istatus[3] : data->istatus[0];
225 stat[2] = ( entry->ope_Flags & OF_VALID ) ? data->istatus[4] : data->istatus[0];
226 if( entry->ope_Flags & OF_REMIND ) stat[2] = data->istatus[1];
227 */
228
229 switch(GPOINTER_TO_INT(user_data))
230 {
231 case 1:
232 iconname = ( entry->flags & OF_AUTO ) ? ICONNAME_HB_OPE_AUTO : ( entry->flags & OF_ADDED ) ? ICONNAME_NEW : NULL;
233 break;
234 case 2:
235 iconname = ( entry->flags & OF_CHANGED ) ? ICONNAME_HB_OPE_EDIT : NULL;
236 break;
237 /*case 3:
238 if( entry->flags & OF_VALID )
239 iconname = ICONNAME_HB_OPE_VALID;
240 else
241 {
242 if( entry->flags & OF_REMIND )
243 iconname = ICONNAME_HB_OPE_REMIND;
244 }
245 break;*/
246 }
247 g_object_set(renderer, "icon-name", iconname, NULL);
248 }
249
250
251 /*
252 ** account cell function
253 */
254 static void list_txn_account_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
255 {
256 Transaction *ope;
257 Account *acc;
258
259 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
260
261 acc = da_acc_get(ope->kacc);
262 if( acc )
263 {
264 g_object_set(renderer, "text", acc->name, NULL);
265 }
266 else
267 g_object_set(renderer, "text", "", NULL);
268 }
269
270 /*
271 ** date cell function
272 */
273 static void list_txn_date_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
274 {
275 Transaction *ope;
276 gchar buffer[256];
277 GDate date;
278
279 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
280 list_txn_eval_future(renderer, ope);
281
282 if(ope->date > 0)
283 {
284 g_date_set_julian (&date, ope->date);
285 g_date_strftime (buffer, 256-1, PREFS->date_format, &date);
286
287 //g_snprintf(buf, sizeof(buf), "%d", ope->ope_Date);
288
289 g_object_set(renderer, "text", buffer, NULL);
290 }
291 else
292 g_object_set(renderer, "text", "????", NULL);
293 }
294
295 /*
296 ** info cell function
297 */
298 static void list_txn_info_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
299 {
300 Transaction *ope;
301
302 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
303
304 switch(GPOINTER_TO_INT(user_data))
305 {
306 case 1:
307 g_object_set(renderer, "icon-name", get_paymode_icon_name(ope->paymode), NULL);
308 break;
309 case 2:
310 list_txn_eval_future(renderer, ope);
311 g_object_set(renderer, "text", ope->info, NULL);
312 break;
313 }
314 }
315
316 /*
317 ** payee cell function
318 */
319 static void list_txn_payee_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
320 {
321 Transaction *ope;
322
323 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
324 list_txn_eval_future(renderer, ope);
325
326 //#926782
327 if(ope->paymode == PAYMODE_INTXFER)
328 {
329 Account *acc = da_acc_get(ope->kxferacc);
330
331 g_object_set(renderer, "text", (acc != NULL) ? acc->name : "", NULL);
332 }
333 else
334 {
335 Payee *pay = da_pay_get(ope->kpay);
336
337 g_object_set(renderer, "text", pay != NULL ? pay->name : "", NULL);
338 }
339 }
340
341
342 /*
343 ** tags cell function
344 */
345 static void list_txn_tags_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
346 {
347 Transaction *ope;
348 gchar *str;
349
350 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
351 list_txn_eval_future(renderer, ope);
352
353 if(ope->tags != NULL)
354 {
355 str = transaction_tags_tostring(ope);
356 g_object_set(renderer, "text", str, NULL);
357 g_free(str);
358 }
359 else
360 g_object_set(renderer, "text", "", NULL);
361
362
363 }
364
365
366 /*
367 ** memo cell function
368 */
369 static void list_txn_memo_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
370 {
371 Transaction *ope;
372
373 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
374 list_txn_eval_future(renderer, ope);
375
376 g_object_set(renderer, "text", ope->memo, NULL);
377 }
378
379
380 /*
381 ** clr cell function
382 */
383 static void list_txn_clr_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
384 {
385 Transaction *ope;
386 gchar *iconname = NULL;
387 //const gchar *c = "";
388
389 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
390 switch(ope->status)
391 {
392 /*case TXN_STATUS_CLEARED: c = "c"; break;
393 case TXN_STATUS_RECONCILED: c = "R"; break;
394 case TXN_STATUS_REMIND: c = "!"; break;*/
395 case TXN_STATUS_CLEARED: iconname = ICONNAME_HB_OPE_CLEARED; break;
396 case TXN_STATUS_RECONCILED: iconname = ICONNAME_HB_OPE_RECONCILED; break;
397 case TXN_STATUS_REMIND: iconname = ICONNAME_HB_OPE_REMIND; break;
398
399 }
400
401 //g_object_set(renderer, "text", c, NULL);
402 g_object_set(renderer, "icon-name", iconname, NULL);
403
404 }
405
406
407 /*
408 ** amount cell function
409 */
410 static void list_txn_amount_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
411 {
412 Transaction *ope;
413 gint column = GPOINTER_TO_INT(user_data);
414 gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
415 gint type;
416 gdouble amount;
417 gchar *color;
418
419 // get the transaction
420 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
421 list_txn_eval_future(renderer, ope);
422
423 if(column == LST_DSPOPE_BALANCE)
424 amount = ope->balance;
425 else
426 amount = ope->amount;
427
428 if(column == LST_DSPOPE_INCOME || column == LST_DSPOPE_EXPENSE)
429 {
430 type = (ope->flags & OF_INCOME) ? LST_DSPOPE_INCOME : LST_DSPOPE_EXPENSE;
431 if( type != column)
432 {
433 g_object_set(renderer, "markup", NULL, NULL);
434 return;
435 }
436 }
437
438 //if(amount != 0)
439 //{
440 hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, amount, ope->kcur, GLOBALS->minor);
441
442 color = get_normal_color_amount(amount);
443 if( (column == LST_DSPOPE_BALANCE) && (ope->overdraft == TRUE) && (PREFS->custom_colors == TRUE) )
444 {
445 color = PREFS->color_warn;
446 }
447
448 g_object_set(renderer,
449 "foreground", color,
450 "text", buf,
451 NULL);
452 //}
453
454
455 }
456
457
458 /*
459 ** category cell function
460 */
461 static void list_txn_category_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
462 {
463 Transaction *ope;
464 Category *cat;
465 gchar *fullname;
466
467 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
468 list_txn_eval_future(renderer, ope);
469
470 if(ope->flags & OF_SPLIT)
471 {
472 g_object_set(renderer, "text", _("- split -"), NULL);
473 }
474 else
475 {
476 cat = da_cat_get(ope->kcat);
477 if( cat != NULL )
478 {
479 fullname = da_cat_get_fullname(cat);
480 g_object_set(renderer, "text", fullname, NULL);
481 g_free(fullname);
482 }
483 else
484 g_object_set(renderer, "text", "", NULL);
485
486 }
487
488 }
489
490
491 /* = = = = = = = = = = = = = = = = */
492
493 GString *list_txn_to_string(GtkTreeView *treeview, gboolean clipboard)
494 {
495 GtkTreeModel *model;
496 GtkTreeIter iter;
497 gboolean valid;
498 GString *node;
499 const gchar *format;
500 Transaction *ope;
501 gchar datebuf[16];
502 gchar *info, *payeename, *categoryname;
503 Payee *payee;
504 Category *category;
505 gchar *tags;
506 char amountbuf[G_ASCII_DTOSTR_BUF_SIZE];
507
508 node = g_string_new(NULL);
509
510 //title line
511 if(clipboard)
512 g_string_append (node, "date\tpaymode\tinfo\tpayee\tmemo\tamount\tcategory\ttags\n");
513 else
514 g_string_append (node, "date;paymode;info;payee;memo;amount;category;tags\n");
515
516 model = gtk_tree_view_get_model(treeview);
517
518 valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
519 while (valid)
520 {
521 gtk_tree_model_get (model, &iter,
522 LST_DSPOPE_DATAS, &ope,
523 -1);
524
525 hb_sprint_date(datebuf, ope->date);
526
527 info = ope->info;
528 if(info == NULL) info = "";
529 payee = da_pay_get(ope->kpay);
530 payeename = (payee->name == NULL) ? "" : payee->name;
531 category = da_cat_get(ope->kcat);
532 categoryname = (category->name == NULL) ? NULL : da_cat_get_fullname(category);
533 tags = transaction_tags_tostring(ope);
534
535 //#793719
536 //g_ascii_dtostr (amountbuf, sizeof (amountbuf), ope->amount);
537 g_ascii_formatd (amountbuf, sizeof (amountbuf), "%.2f", ope->amount);
538
539 DB( g_print("amount = %f '%s'\n", ope->amount, amountbuf) );
540
541 format = (clipboard == TRUE) ? "%s\t%d\t%s\t%s\t%s\t%s\t%s\t%s\n" : "%s;%d;%s;%s;%s;%s;%s;%s\n";
542 g_string_append_printf(node, format,
543 datebuf,
544 ope->paymode,
545 info,
546 payeename,
547 ope->memo,
548 amountbuf,
549 categoryname != NULL ? categoryname : "",
550 tags != NULL ? tags : ""
551 );
552
553 //leak
554 g_free(categoryname);
555 g_free(tags);
556
557 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
558 }
559
560 //DB( g_print("text is:\n%s", node->str) );
561
562 return node;
563 }
564
565
566 gboolean list_txn_column_id_isvisible(GtkTreeView *treeview, gint sort_id)
567 {
568 GtkTreeViewColumn *column;
569 gint n, id;
570
571 for(n=0; n < NUM_LST_DSPOPE-1 ; n++ ) // -1 cause account not to be processed
572 {
573 column = gtk_tree_view_get_column (treeview, n);
574 if(column == NULL)
575 continue;
576
577 if( gtk_tree_view_column_get_visible(column) )
578 {
579 id = gtk_tree_view_column_get_sort_column_id (column);
580 if( sort_id == id )
581 return TRUE;
582 }
583 }
584
585 return FALSE;
586 }
587
588
589 static GtkTreeViewColumn *list_txn_get_column(GList *list, gint search_id)
590 {
591 GtkTreeViewColumn *column = NULL;
592 GList *tmp;
593 gint id;
594
595 tmp = g_list_first(list);
596 while (tmp != NULL)
597 {
598 id = gtk_tree_view_column_get_sort_column_id(tmp->data);
599 if( search_id == id )
600 {
601 column = tmp->data;
602 break;
603 }
604 tmp = g_list_next(tmp);
605 }
606 return column;
607 }
608
609
610 guint list_txn_get_quicksearch_column_mask(GtkTreeView *treeview)
611 {
612 GtkTreeViewColumn *column;
613 guint n, mask;
614 gint id;
615
616 mask = 0;
617 for(n=0; n < NUM_LST_DSPOPE-1 ; n++ ) // -1 cause account not to be processed
618 {
619 column = gtk_tree_view_get_column (treeview, n);
620 if(column == NULL)
621 continue;
622
623 if( gtk_tree_view_column_get_visible(column) )
624 {
625 id = gtk_tree_view_column_get_sort_column_id (column);
626 switch(id)
627 {
628 case LST_DSPOPE_MEMO: mask |= FLT_QSEARCH_MEMO; break;
629 case LST_DSPOPE_INFO: mask |= FLT_QSEARCH_INFO; break;
630 case LST_DSPOPE_PAYEE: mask |= FLT_QSEARCH_PAYEE; break;
631 case LST_DSPOPE_CATEGORY: mask |= FLT_QSEARCH_CATEGORY; break;
632 case LST_DSPOPE_TAGS: mask |= FLT_QSEARCH_TAGS; break;
633 case LST_DSPOPE_AMOUNT:
634 case LST_DSPOPE_EXPENSE:
635 case LST_DSPOPE_INCOME: mask |= FLT_QSEARCH_AMOUNT; break;
636 }
637 }
638 }
639
640 return mask;
641 }
642
643
644 void list_txn_set_save_column_width(GtkTreeView *treeview, gboolean save_column_width)
645 {
646 struct list_txn_data *data;
647
648 data = g_object_get_data(G_OBJECT(treeview), "inst_data");
649 if( data )
650 {
651 data->save_column_width = save_column_width;
652 }
653 }
654
655
656 void list_txn_sort_force(GtkTreeSortable *sortable, gpointer user_data)
657 {
658 gint sort_column_id;
659 GtkSortType order;
660
661 DB( g_print("list_txn_sort_force\n") );
662
663 gtk_tree_sortable_get_sort_column_id(sortable, &sort_column_id, &order);
664 DB( g_print(" - id %d order %d\n", sort_column_id, order) );
665
666 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sortable), GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, order);
667 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(sortable), sort_column_id, order);
668 }
669
670
671 static void list_txn_get_columns(GtkTreeView *treeview)
672 {
673 struct list_txn_data *data;
674 GtkTreeViewColumn *column;
675 gint i, col_id;
676
677 DB( g_print("\n[list_txn] get columns order/width\n") );
678
679 data = g_object_get_data(G_OBJECT(treeview), "inst_data");
680
681 DB( g_print(" nbcol=%d, nbsortid=%d\n", NUM_LST_DSPOPE, gtk_tree_view_get_n_columns (treeview)) );
682
683 for(i=0 ; i < NUM_LST_DSPOPE-1 ; i++ ) // -1 'caus: account and blank column
684 {
685 column = gtk_tree_view_get_column(treeview, i);
686 if(column != NULL)
687 {
688 col_id = gtk_tree_view_column_get_sort_column_id (column);
689 if( col_id >= 0 )
690 {
691 gboolean visible;
692
693 visible = gtk_tree_view_column_get_visible (column);
694 if( col_id == LST_DSPOPE_BALANCE) //keep initial state of balance
695 visible = data->tvc_is_visible;
696
697 if( visible )
698 PREFS->lst_ope_columns[i] = col_id;
699 else
700 PREFS->lst_ope_columns[i] = -col_id;
701
702 PREFS->lst_ope_col_size[col_id-1] = gtk_tree_view_column_get_width(column);
703
704 DB( g_print(" col-%2d => %2d '%s' w=%d\n", i, col_id, gtk_tree_view_column_get_title(column), PREFS->lst_ope_col_size[col_id-1] ) );
705 }
706 else //should not occurs
707 PREFS->lst_ope_columns[i] = 0;
708 }
709 }
710 }
711
712
713 static void list_txn_set_columns(GtkTreeView *treeview, gint *col_id)
714 {
715 struct list_txn_data *data;
716 GtkTreeViewColumn *column, *base;
717 gboolean visible;
718 GList *list;
719 gint i = 0;
720 gint id;
721
722 DB( g_print("\n[list_txn] set columns order/width\n") );
723
724 data = g_object_get_data(G_OBJECT(treeview), "inst_data");
725
726 #if MYDEBUG == 1
727 DB( g_print("\n debug column sortid\n") );
728
729 for(i=0; i < NUM_LST_DSPOPE-1 ; i++ ) // -1 cause account not to be processed
730 {
731 DB( g_print(" - pos:%2d sortid:%2d\n", i, col_id[i]) );
732 }
733 #endif
734
735
736 DB( g_print("\n apply column prefs\n") );
737
738 list = gtk_tree_view_get_columns( treeview );
739
740 base = NULL;
741
742 for(i=0; i < NUM_LST_DSPOPE-1 ; i++ ) // -1 cause account not to be processed
743 {
744 /* hidden are stored as col_id negative */
745 id = ABS(col_id[i]);
746 column = list_txn_get_column(list, id);
747
748 //DB( g_print(" - get column %d %p\n", id, column) );
749
750 if( column != NULL )
751 {
752 DB( g_print(" - pos:%2d sortid:%2d (%s)\n", i, col_id[i], gtk_tree_view_column_get_title(column)) );
753
754 gtk_tree_view_move_column_after(treeview, column, base);
755 base = column;
756
757 visible = col_id[i] < 0 ? FALSE : TRUE;
758
759 /* display exception for detail/import list */
760 if(data->list_type != LIST_TXN_TYPE_BOOK)
761 {
762 if( id == LST_DSPOPE_AMOUNT )
763 visible = TRUE;
764
765 if( id == LST_DSPOPE_STATUS || id == LST_DSPOPE_EXPENSE || id == LST_DSPOPE_INCOME )
766 visible = FALSE;
767 }
768
769 gtk_tree_view_column_set_visible (column, visible);
770 if( id == LST_DSPOPE_BALANCE )
771 {
772 data->tvc_is_visible = visible;
773 }
774
775 if( id == LST_DSPOPE_INFO
776 || id == LST_DSPOPE_PAYEE
777 || id == LST_DSPOPE_MEMO
778 || id == LST_DSPOPE_CATEGORY
779 || id == LST_DSPOPE_TAGS
780 || id == LST_DSPOPE_ACCOUNT )
781 {
782 gtk_tree_view_column_set_fixed_width( column, PREFS->lst_ope_col_size[id - 1]);
783 }
784 }
785
786 }
787
788 g_list_free(list );
789 }
790
791
792 static void list_txn_sort_column_changed(GtkTreeSortable *sortable, gpointer user_data)
793 {
794 struct list_txn_data *data = user_data;
795 gint id;
796 GtkSortType order;
797 gboolean showBalance;
798
799 gtk_tree_sortable_get_sort_column_id(sortable, &id, &order);
800
801 DB( g_print("list_txn_columns_changed %d %d\n", id, order) );
802
803 //here save the transaction list columnid and sort order
804 PREFS->lst_ope_sort_id = id;
805 PREFS->lst_ope_sort_order = order;
806
807 //manage visibility of balance column
808 //showBalance = (id == LST_DSPOPE_DATE && order == GTK_SORT_ASCENDING) ? data->tvc_is_visible : FALSE;
809 showBalance = (id == LST_DSPOPE_DATE) ? data->tvc_is_visible : FALSE;
810 gtk_tree_view_column_set_visible (data->tvc_balance, showBalance);
811 }
812
813
814 static void
815 list_txn_column_popup_menuitem_on_activate (GtkCheckMenuItem *checkmenuitem,
816 gpointer user_data)
817 {
818 GtkTreeViewColumn *column = user_data;
819
820 DB( g_print("toggled\n") );
821
822 gtk_tree_view_column_set_visible(column, gtk_check_menu_item_get_active(checkmenuitem) );
823 }
824
825
826 static gboolean list_txn_column_popup_callback ( GtkWidget *button,
827 GdkEventButton *ev,
828 gpointer user_data )
829 {
830 struct list_txn_data *data = user_data;
831 GtkWidget *menu, *menuitem;
832 GtkTreeViewColumn *column;
833 gint i, col_id;
834
835
836 if( ev->button == 3 )
837 {
838 DB( g_print("should popup\n") );
839
840 menu = gtk_menu_new ();
841
842 //note: deactive this disable any menuitem action
843 g_signal_connect (menu, "selection-done", G_CALLBACK (gtk_widget_destroy), NULL);
844
845 for(i=0 ; i < NUM_LST_DSPOPE-1 ; i++ ) // -1 'caus: account and blank column
846 {
847 column = gtk_tree_view_get_column(GTK_TREE_VIEW(data->treeview), i);
848 if( column != NULL )
849 {
850 col_id = gtk_tree_view_column_get_sort_column_id (column);
851
852 if( (col_id == -1)
853 || (col_id == LST_DSPOPE_STATUS)
854 || (col_id == LST_DSPOPE_ACCOUNT)
855 || (col_id == LST_DSPOPE_DATE)
856 || (col_id == LST_DSPOPE_BALANCE)
857 )
858 continue;
859 //if( (data->tvc_is_visible == FALSE) && (col_id == LST_DSPOPE_BALANCE) )
860 // continue;
861
862 if( (data->list_type == LIST_TXN_TYPE_DETAIL) &&
863 ( (col_id == LST_DSPOPE_AMOUNT)
864 || (col_id == LST_DSPOPE_EXPENSE)
865 || (col_id == LST_DSPOPE_INCOME)
866 )
867 )
868 continue;
869
870 menuitem = gtk_check_menu_item_new_with_label ( gtk_tree_view_column_get_title (column) );
871 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
872 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), gtk_tree_view_column_get_visible (column) );
873 gtk_widget_show (menuitem);
874
875 g_signal_connect (menuitem, "activate",
876 G_CALLBACK (list_txn_column_popup_menuitem_on_activate), column);
877 }
878
879 }
880
881 gtk_menu_attach_to_widget (GTK_MENU (menu), button, NULL);
882 gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
883 ev->button, ev->time);
884 }
885
886 return FALSE;
887 }
888
889
890 static GtkTreeViewColumn *
891 list_txn_column_amount_create(gint list_type, gchar *title, gint sortcolumnid, GtkTreeCellDataFunc func)
892 {
893 GtkTreeViewColumn *column;
894 GtkCellRenderer *renderer;
895
896 renderer = gtk_cell_renderer_text_new ();
897 g_object_set(renderer, "xalign", 1.0, NULL);
898
899 column = gtk_tree_view_column_new_with_attributes(title, renderer, NULL);
900
901 gtk_tree_view_column_set_alignment (column, 0.5);
902 //gtk_tree_view_column_set_resizable(column, TRUE);
903 gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
904 if(list_type == LIST_TXN_TYPE_BOOK)
905 {
906 gtk_tree_view_column_set_reorderable(column, TRUE);
907 }
908 gtk_tree_view_column_set_cell_data_func(column, renderer, func, GINT_TO_POINTER(sortcolumnid), NULL);
909
910 return column;
911 }
912
913
914 static GtkTreeViewColumn *
915 list_txn_column_text_create(gint list_type, gchar *title, gint sortcolumnid, GtkTreeCellDataFunc func, gpointer user_data)
916 {
917 GtkTreeViewColumn *column;
918 GtkCellRenderer *renderer;
919
920 renderer = gtk_cell_renderer_text_new ();
921 g_object_set(renderer,
922 "ellipsize", PANGO_ELLIPSIZE_END,
923 "ellipsize-set", TRUE,
924 NULL);
925
926 column = gtk_tree_view_column_new_with_attributes(title, renderer, NULL);
927
928 gtk_tree_view_column_set_alignment (column, 0.5);
929 gtk_tree_view_column_set_resizable(column, TRUE);
930
931 gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
932 if(list_type == LIST_TXN_TYPE_BOOK)
933 {
934 gtk_tree_view_column_set_reorderable(column, TRUE);
935 gtk_tree_view_column_set_min_width (column, HB_MINWIDTH_COLUMN);
936 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
937 }
938 gtk_tree_view_column_set_cell_data_func(column, renderer, func, user_data, NULL);
939
940 return column;
941 }
942
943
944 static GtkTreeViewColumn *
945 list_txn_column_info_create(gint list_type)
946 {
947 GtkTreeViewColumn *column;
948 GtkCellRenderer *renderer;
949
950 column = gtk_tree_view_column_new();
951 gtk_tree_view_column_set_title(column, _("Info"));
952
953 renderer = gtk_cell_renderer_pixbuf_new ();
954 gtk_tree_view_column_pack_start(column, renderer, FALSE);
955 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_info_cell_data_function, GINT_TO_POINTER(1), NULL);
956
957 renderer = gtk_cell_renderer_text_new ();
958 /*g_object_set(renderer,
959 "ellipsize", PANGO_ELLIPSIZE_END,
960 "ellipsize-set", TRUE,
961 NULL);*/
962 gtk_tree_view_column_pack_start(column, renderer, TRUE);
963 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_info_cell_data_function, GINT_TO_POINTER(2), NULL);
964
965 gtk_tree_view_column_set_alignment (column, 0.5);
966 gtk_tree_view_column_set_resizable(column, TRUE);
967 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_INFO);
968 if(list_type == LIST_TXN_TYPE_BOOK)
969 {
970 gtk_tree_view_column_set_reorderable(column, TRUE);
971 gtk_tree_view_column_set_min_width (column, HB_MINWIDTH_COLUMN);
972 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
973 }
974
975 return column;
976 }
977
978
979 static void list_txn_destroy( GtkWidget *widget, gpointer user_data )
980 {
981 struct list_txn_data *data;
982
983 data = g_object_get_data(G_OBJECT(widget), "inst_data");
984
985 DB( g_print ("\n[list_transaction] destroy event occurred\n") );
986
987 if( data->save_column_width )
988 {
989 list_txn_get_columns(GTK_TREE_VIEW(data->treeview));
990 }
991
992 DB( g_print(" - view=%p, inst_data=%p\n", widget, data) );
993 g_free(data);
994 }
995
996
997 Transaction *list_txn_get_active_transaction(GtkTreeView *treeview)
998 {
999 GtkTreeModel *model;
1000 GList *list;
1001 Transaction *ope;
1002
1003 ope = NULL;
1004
1005 model = gtk_tree_view_get_model(treeview);
1006 list = gtk_tree_selection_get_selected_rows(gtk_tree_view_get_selection(treeview), &model);
1007
1008 if(list != NULL)
1009 {
1010 GtkTreeIter iter;
1011
1012 gtk_tree_model_get_iter(model, &iter, list->data);
1013 gtk_tree_model_get(model, &iter, LST_DSPOPE_DATAS, &ope, -1);
1014 }
1015
1016 g_list_foreach(list, (GFunc)gtk_tree_path_free, NULL);
1017 g_list_free(list);
1018
1019 return ope;
1020 }
1021
1022
1023 /*
1024 ** create our transaction list
1025 ** Status, Date, Info, Payee, Memo, (Amount), Expense, Income, Category
1026 */
1027 GtkWidget *create_list_transaction(gint list_type, gboolean *pref_columns)
1028 {
1029 struct list_txn_data *data;
1030 GtkListStore *store;
1031 GtkWidget *treeview;
1032 GtkCellRenderer *renderer;
1033 GtkTreeViewColumn *column, *col_acc = NULL, *col_status = NULL;
1034
1035
1036 data = g_malloc0(sizeof(struct list_txn_data));
1037 if(!data) return NULL;
1038
1039 data->list_type = list_type;
1040 data->save_column_width = FALSE;
1041
1042 /* create list store */
1043 store = gtk_list_store_new(
1044 1, G_TYPE_POINTER /*only really used column */
1045 );
1046
1047 //treeview
1048 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1049 data->treeview = treeview;
1050 g_object_unref(store);
1051
1052 //store our window private data
1053 g_object_set_data(G_OBJECT(treeview), "inst_data", (gpointer)data);
1054 DB( g_print(" - treeview=%p, inst_data=%p\n", treeview, data) );
1055
1056 // connect our dispose function
1057 g_signal_connect (treeview, "destroy", G_CALLBACK (list_txn_destroy), (gpointer)data);
1058
1059 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines);
1060 //gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
1061 // COLUMN_DESCRIPTION);
1062
1063 if(list_type == LIST_TXN_TYPE_BOOK)
1064 gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)), GTK_SELECTION_MULTIPLE);
1065
1066 /* column 1: Changes */
1067 column = gtk_tree_view_column_new();
1068 //gtk_tree_view_column_set_title(column, _("Status"));
1069 col_status = column;
1070
1071 renderer = gtk_cell_renderer_pixbuf_new ();
1072 //gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
1073 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1074 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_status_cell_data_function, GINT_TO_POINTER(1), NULL);
1075
1076 renderer = gtk_cell_renderer_pixbuf_new ();
1077 //gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
1078 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1079 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_status_cell_data_function, GINT_TO_POINTER(2), NULL);
1080
1081 renderer = gtk_cell_renderer_pixbuf_new ();
1082 //gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
1083 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1084 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_status_cell_data_function, GINT_TO_POINTER(3), NULL);
1085
1086 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_STATUS);
1087 //gtk_tree_view_column_set_resizable(column, TRUE);
1088 gtk_tree_view_column_set_alignment (column, 0.5);
1089 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1090
1091 if(list_type == LIST_TXN_TYPE_DETAIL)
1092 {
1093 column = list_txn_column_text_create(list_type, _("Account"), LST_DSPOPE_ACCOUNT, list_txn_account_cell_data_function, NULL);
1094 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1095 col_acc = column;
1096 // add column popup
1097 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1098 "button-press-event",
1099 G_CALLBACK ( list_txn_column_popup_callback ),
1100 data );
1101 }
1102
1103 /* column 2: Date */
1104 column = gtk_tree_view_column_new();
1105 gtk_tree_view_column_set_title(column, _("Date"));
1106 renderer = gtk_cell_renderer_text_new ();
1107 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1108 g_object_set(renderer, "xalign", 1.0, NULL);
1109 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_date_cell_data_function, NULL, NULL);
1110 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_DATE);
1111 //gtk_tree_view_column_set_resizable(column, TRUE);
1112 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1113 // add column popup
1114 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1115 "button-press-event",
1116 G_CALLBACK ( list_txn_column_popup_callback ),
1117 data );
1118
1119
1120 column = list_txn_column_info_create(list_type);
1121 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1122 // add column popup
1123 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1124 "button-press-event",
1125 G_CALLBACK ( list_txn_column_popup_callback ),
1126 data );
1127
1128 column = list_txn_column_text_create(list_type, _("Payee"), LST_DSPOPE_PAYEE, list_txn_payee_cell_data_function, NULL);
1129 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1130 // add column popup
1131 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1132 "button-press-event",
1133 G_CALLBACK ( list_txn_column_popup_callback ),
1134 data );
1135
1136 column = list_txn_column_text_create(list_type, _("Memo"), LST_DSPOPE_MEMO, list_txn_memo_cell_data_function, NULL);
1137 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1138 // add column popup
1139 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1140 "button-press-event",
1141 G_CALLBACK ( list_txn_column_popup_callback ),
1142 data );
1143
1144 /* column status CLR */
1145 column = gtk_tree_view_column_new();
1146 gtk_tree_view_column_set_title(column, _("Status"));
1147 //renderer = gtk_cell_renderer_text_new ();
1148 renderer = gtk_cell_renderer_pixbuf_new();
1149 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1150 g_object_set(renderer, "xalign", 1.0, NULL);
1151 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_clr_cell_data_function, NULL, NULL);
1152 gtk_tree_view_column_set_reorderable(column, TRUE);
1153 gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_CLR);
1154 //gtk_tree_view_column_set_sort_indicator (column, FALSE);
1155 //gtk_tree_view_column_set_resizable(column, TRUE);
1156 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1157 // add column popup
1158 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1159 "button-press-event",
1160 G_CALLBACK ( list_txn_column_popup_callback ),
1161 data );
1162
1163
1164 column = list_txn_column_amount_create(list_type, _("Amount"), LST_DSPOPE_AMOUNT, list_txn_amount_cell_data_function);
1165 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1166 // add column popup
1167 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1168 "button-press-event",
1169 G_CALLBACK ( list_txn_column_popup_callback ),
1170 data );
1171
1172 column = list_txn_column_amount_create(list_type, _("Expense"), LST_DSPOPE_EXPENSE, list_txn_amount_cell_data_function);
1173 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1174 // add column popup
1175 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1176 "button-press-event",
1177 G_CALLBACK ( list_txn_column_popup_callback ),
1178 data );
1179
1180 column = list_txn_column_amount_create(list_type, _("Income"), LST_DSPOPE_INCOME, list_txn_amount_cell_data_function);
1181 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1182 // add column popup
1183 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1184 "button-press-event",
1185 G_CALLBACK ( list_txn_column_popup_callback ),
1186 data );
1187
1188 column = list_txn_column_text_create(list_type, _("Category"), LST_DSPOPE_CATEGORY, list_txn_category_cell_data_function, NULL);
1189 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1190 // add column popup
1191 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1192 "button-press-event",
1193 G_CALLBACK ( list_txn_column_popup_callback ),
1194 data );
1195
1196 column = list_txn_column_text_create(list_type, _("Tags"), LST_DSPOPE_TAGS, list_txn_tags_cell_data_function, NULL);
1197 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1198 // add column popup
1199 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1200 "button-press-event",
1201 G_CALLBACK ( list_txn_column_popup_callback ),
1202 data );
1203
1204 if(list_type == LIST_TXN_TYPE_BOOK)
1205 {
1206 column = list_txn_column_amount_create(list_type, _("Balance"), LST_DSPOPE_BALANCE, list_txn_amount_cell_data_function);
1207 data->tvc_balance = column;
1208 gtk_tree_view_column_set_clickable(column, FALSE);
1209 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1210 // add column popup
1211 g_signal_connect ( G_OBJECT (gtk_tree_view_column_get_button (column)),
1212 "button-press-event",
1213 G_CALLBACK ( list_txn_column_popup_callback ),
1214 data );
1215 }
1216
1217 /* column 9: empty */
1218 column = gtk_tree_view_column_new();
1219 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1220
1221 /* sort */
1222 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_STATUS , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_STATUS), NULL);
1223 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_DATE , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_DATE), NULL);
1224 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_INFO , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_INFO), NULL);
1225 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_PAYEE , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_PAYEE), NULL);
1226 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_MEMO , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_MEMO), NULL);
1227 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_AMOUNT , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_AMOUNT), NULL);
1228 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_EXPENSE , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_EXPENSE), NULL);
1229 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_INCOME , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_INCOME), NULL);
1230 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_CATEGORY, list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_CATEGORY), NULL);
1231 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_TAGS , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_TAGS), NULL);
1232 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_CLR , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_CLR), NULL);
1233 gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LST_DSPOPE_ACCOUNT , list_txn_sort_iter_compare_func, GINT_TO_POINTER(LST_DSPOPE_ACCOUNT), NULL);
1234
1235 /* apply user preference for columns */
1236 list_txn_set_columns(GTK_TREE_VIEW(treeview), pref_columns);
1237
1238 /* force account column for detail treeview */
1239 if(list_type == LIST_TXN_TYPE_DETAIL)
1240 {
1241 gtk_tree_view_move_column_after(GTK_TREE_VIEW(treeview), col_acc, col_status);
1242 }
1243
1244 /* set initial sort order */
1245 DB( g_print("set sort to %d %d\n", PREFS->lst_ope_sort_id, PREFS->lst_ope_sort_order) );
1246 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), PREFS->lst_ope_sort_id, PREFS->lst_ope_sort_order);
1247
1248
1249 /* signals */
1250 if(list_type == LIST_TXN_TYPE_BOOK)
1251 g_signal_connect (GTK_TREE_SORTABLE(store), "sort-column-changed", G_CALLBACK (list_txn_sort_column_changed), data);
1252
1253 return(treeview);
1254 }
1255
1256
1257 /* ---------------------------------------------- */
1258 /* import list : soon obsolete */
1259 /* ---------------------------------------------- */
1260
1261 /*
1262 ** account cell function
1263 */
1264 static void ope_importaccount_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
1265 {
1266 Transaction *ope;
1267 Account *acc, *dacc;
1268
1269 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
1270
1271 acc = da_acc_get(ope->kacc);
1272 if( acc )
1273 {
1274 if(acc->imp_key > 0)
1275 {
1276 dacc = da_acc_get(acc->imp_key);
1277 if( dacc )
1278 g_object_set(renderer, "text", dacc->name, NULL);
1279 }
1280 else
1281 g_object_set(renderer, "text", acc->name, NULL);
1282
1283 }
1284 }
1285
1286 /*
1287 ** amount cell function
1288 */
1289 static void ope_importamount_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
1290 {
1291 Transaction *ope;
1292 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
1293 gchar *color;
1294
1295 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
1296
1297 //mystrfnum(buf, G_ASCII_DTOSTR_BUF_SIZE-1, ope->amount, GLOBALS->minor);
1298 //hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, ope->amount, GLOBALS->minor);
1299 g_ascii_formatd(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, "%.2f", ope->amount);
1300
1301 color = get_normal_color_amount(ope->amount);
1302
1303 g_object_set(renderer,
1304 "foreground", color,
1305 "text", formatd_buf,
1306 NULL);
1307
1308 }
1309
1310
1311 static void ope_importstatus_cell_data_function (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
1312 {
1313 Transaction *ope;
1314 gchar *iconname = NULL;
1315
1316 // get the transaction
1317 gtk_tree_model_get(model, iter, LST_DSPOPE_DATAS, &ope, -1);
1318
1319 iconname = ( ope->same != NULL ) ? ICONNAME_WARNING : NULL;
1320
1321 g_object_set(renderer, "icon-name", iconname, NULL);
1322 }
1323
1324
1325 static void
1326 ope_importfixed_toggled (GtkCellRendererToggle *cell,
1327 gchar *path_str,
1328 gpointer data)
1329 {
1330 GtkTreeModel *model = (GtkTreeModel *)data;
1331 GtkTreeIter iter;
1332 GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
1333 gboolean fixed;
1334
1335 /* get toggled iter */
1336 gtk_tree_model_get_iter (model, &iter, path);
1337 gtk_tree_model_get (model, &iter, LST_OPE_IMPTOGGLE, &fixed, -1);
1338
1339 /* do something with the value */
1340 fixed ^= 1;
1341
1342 /* set new value */
1343 gtk_list_store_set (GTK_LIST_STORE (model), &iter, LST_OPE_IMPTOGGLE, fixed, -1);
1344
1345 /* clean up */
1346 gtk_tree_path_free (path);
1347 }
1348
1349 /*
1350 ** create our transaction list
1351 */
1352 GtkWidget *create_list_import_transaction(gboolean enable_choose)
1353 {
1354 GtkListStore *store;
1355 GtkWidget *treeview;
1356 GtkCellRenderer *renderer;
1357 GtkTreeViewColumn *column;
1358
1359 /* create list store */
1360 store = gtk_list_store_new(
1361 10,
1362 G_TYPE_POINTER,
1363 G_TYPE_BOOLEAN,
1364 G_TYPE_BOOLEAN,
1365 G_TYPE_BOOLEAN,
1366 G_TYPE_BOOLEAN,
1367 G_TYPE_BOOLEAN,
1368 G_TYPE_BOOLEAN,
1369 G_TYPE_BOOLEAN,
1370 G_TYPE_BOOLEAN,
1371 G_TYPE_BOOLEAN
1372 );
1373
1374 //treeview
1375 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
1376 g_object_unref(store);
1377
1378 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines);
1379 //gtk_tree_view_set_search_column (GTK_TREE_VIEW (treeview),
1380 // COLUMN_DESCRIPTION);
1381
1382 //gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(view)), GTK_SELECTION_MULTIPLE);
1383
1384 /* column: Selection */
1385 if(enable_choose)
1386 {
1387 renderer = gtk_cell_renderer_toggle_new ();
1388
1389 g_signal_connect (renderer, "toggled", G_CALLBACK (ope_importfixed_toggled), store);
1390
1391
1392 column = gtk_tree_view_column_new_with_attributes (NULL,
1393 renderer,
1394 "active", LST_OPE_IMPTOGGLE,
1395 NULL);
1396
1397 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1398
1399 /* column: Duplicate */
1400 column = gtk_tree_view_column_new();
1401 //gtk_tree_view_column_set_title(column, _("Import ?"));
1402 renderer = gtk_cell_renderer_pixbuf_new ();
1403 //gtk_cell_renderer_set_fixed_size(renderer, GLOBALS->lst_pixbuf_maxwidth, -1);
1404 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1405 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_importstatus_cell_data_function, NULL, NULL);
1406 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1407 }
1408
1409 //#ifndef NOOFX
1410 /* column: Account */
1411 column = gtk_tree_view_column_new();
1412 gtk_tree_view_column_set_title(column, _("Account"));
1413 renderer = gtk_cell_renderer_text_new ();
1414 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1415 gtk_tree_view_column_set_cell_data_func(column, renderer, ope_importaccount_cell_data_function, NULL, NULL);
1416 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_DATE);
1417 gtk_tree_view_column_set_resizable(column, TRUE);
1418 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1419 //#endif
1420
1421 /* column: Date */
1422 column = gtk_tree_view_column_new();
1423 gtk_tree_view_column_set_title(column, _("Date"));
1424 renderer = gtk_cell_renderer_text_new ();
1425 g_object_set(renderer, "xalign", 1.0, NULL);
1426 gtk_tree_view_column_pack_start(column, renderer, TRUE);
1427 gtk_tree_view_column_set_cell_data_func(column, renderer, list_txn_date_cell_data_function, NULL, NULL);
1428 //gtk_tree_view_column_set_sort_column_id (column, LST_DSPOPE_DATE);
1429 gtk_tree_view_column_set_resizable(column, TRUE);
1430 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1431
1432 column = list_txn_column_text_create(LIST_TXN_TYPE_IMPORT, _("Memo"), -1, list_txn_memo_cell_data_function, NULL);
1433 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1434
1435 column = list_txn_column_amount_create(LIST_TXN_TYPE_IMPORT, _("Amount"), -1, ope_importamount_cell_data_function);
1436 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1437
1438 column = list_txn_column_info_create(LIST_TXN_TYPE_IMPORT);
1439 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1440
1441 column = list_txn_column_text_create(LIST_TXN_TYPE_IMPORT, _("Payee"), -1, list_txn_payee_cell_data_function, NULL);
1442 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1443
1444 column = list_txn_column_text_create(LIST_TXN_TYPE_IMPORT, _("Category"), -1, list_txn_category_cell_data_function, NULL);
1445 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1446
1447 column = gtk_tree_view_column_new();
1448 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
1449
1450 return(treeview);
1451 }
This page took 0.094389 seconds and 5 git commands to generate.