]> Dogcows Code - chaz/homebank/blob - src/hb-filter.c
Merge branch 'upstream'
[chaz/homebank] / src / hb-filter.c
1 /* HomeBank -- Free, easy, personal accounting for everyone.
2 * Copyright (C) 1995-2019 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 #include "homebank.h"
21 #include "hb-filter.h"
22
23 /****************************************************************************/
24 /* Debug macros */
25 /****************************************************************************/
26 #define MYDEBUG 0
27
28 #if MYDEBUG
29 #define DB(x) (x);
30 #else
31 #define DB(x);
32 #endif
33
34 /* our global datas */
35 extern struct HomeBank *GLOBALS;
36 extern struct Preferences *PREFS;
37
38
39 /* = = = = = = = = = = = = = = = = */
40
41 void da_flt_free(Filter *flt)
42 {
43 DB( g_print("da_flt_free\n") );
44 if(flt != NULL)
45 {
46 g_free(flt->memo);
47 g_free(flt->info);
48 g_free(flt->tag);
49 g_free(flt);
50 }
51 }
52
53
54 Filter *da_flt_malloc(void)
55 {
56 DB( g_print("da_flt_malloc\n") );
57 return g_malloc0(sizeof(Filter));
58 }
59
60
61 /* = = = = = = = = = = = = = = = = = = = = */
62
63
64 void filter_status_acc_clear_except(Filter *flt, guint32 selkey)
65 {
66 GHashTableIter iter;
67 gpointer key, value;
68
69 // set all account
70 g_hash_table_iter_init (&iter, GLOBALS->h_acc);
71 while (g_hash_table_iter_next (&iter, &key, &value))
72 {
73 Account *item = value;
74 item->flt_select = item->key == selkey ? TRUE : FALSE;
75 }
76
77 }
78
79
80 void filter_status_pay_clear_except(Filter *flt, guint32 selkey)
81 {
82 GHashTableIter iter;
83 gpointer key, value;
84
85 // set all payee
86 g_hash_table_iter_init (&iter, GLOBALS->h_pay);
87 while (g_hash_table_iter_next (&iter, &key, &value))
88 {
89 Payee *item = value;
90 item->flt_select = item->key == selkey ? TRUE : FALSE;
91 }
92
93 }
94
95
96 void filter_status_cat_clear_except(Filter *flt, guint32 selkey)
97 {
98 GHashTableIter iter;
99 gpointer key, value;
100
101 // set all category
102 g_hash_table_iter_init (&iter, GLOBALS->h_cat);
103 while (g_hash_table_iter_next (&iter, &key, &value))
104 {
105 Category *item = value;
106
107
108 item->flt_select = FALSE;
109 if( (item->key == selkey)
110 //#1824561 don't forget subcat
111 //#1829076 but not when selkey is 0
112 || ((item->parent == selkey) && selkey > 0)
113 )
114 item->flt_select = TRUE;
115 }
116
117 }
118
119
120 /* = = = = = = = = = = = = = = = = */
121
122
123 void filter_reset(Filter *flt)
124 {
125 gint i;
126
127 DB( g_print("\n[filter] default reset all %p\n", flt) );
128
129 for(i=0;i<FILTER_MAX;i++)
130 {
131 flt->option[i] = 0;
132 }
133
134 flt->option[FILTER_DATE] = 1;
135 flt->range = FLT_RANGE_LAST12MONTHS;
136 filter_preset_daterange_set(flt, flt->range, 0);
137
138 for(i=0;i<NUM_PAYMODE_MAX;i++)
139 flt->paymode[i] = TRUE;
140
141 g_free(flt->info);
142 g_free(flt->memo);
143 g_free(flt->tag);
144 flt->info = NULL;
145 flt->memo = NULL;
146 flt->tag = NULL;
147
148 //unsaved
149 flt->nbdaysfuture = 0;
150 flt->type = FLT_TYPE_ALL;
151 flt->status = FLT_STATUS_ALL;
152 flt->forceremind = PREFS->showremind;
153
154 *flt->last_tab = '\0';
155 }
156
157
158 void filter_set_tag_by_id(Filter *flt, guint32 key)
159 {
160 Tag *tag;
161
162 DB( g_print("\n[filter] set tag by id\n") );
163
164 if(flt->tag)
165 {
166 g_free(flt->tag);
167 flt->tag = NULL;
168 }
169
170 tag = da_tag_get(key);
171 if(tag)
172 {
173 flt->tag = g_strdup(tag->name);
174 }
175 }
176
177
178 static void filter_set_date_bounds(Filter *flt, guint32 kacc)
179 {
180 GList *lst_acc, *lnk_acc;
181 GList *lnk_txn;
182
183 DB( g_print("\n[filter] set date bounds %p\n", flt) );
184
185 flt->mindate = 0;
186 flt->maxdate = 0;
187
188 lst_acc = g_hash_table_get_values(GLOBALS->h_acc);
189 lnk_acc = g_list_first(lst_acc);
190 while (lnk_acc != NULL)
191 {
192 Account *acc = lnk_acc->data;
193
194 //#1674045 only rely on nosummary
195 //if( !(acc->flags & AF_CLOSED) )
196 {
197 Transaction *txn;
198
199 DB( g_print(" - do '%s'\n", acc->name) );
200
201 lnk_txn = g_queue_peek_head_link(acc->txn_queue);
202 if(lnk_txn) {
203 txn = lnk_txn->data;
204 if( (kacc == 0) || (txn->kacc == kacc) )
205 {
206 if( flt->mindate == 0 )
207 flt->mindate = txn->date;
208 else
209 flt->mindate = MIN(flt->mindate, txn->date);
210 }
211 }
212
213 lnk_txn = g_queue_peek_tail_link(acc->txn_queue);
214 if(lnk_txn) {
215 txn = lnk_txn->data;
216 if( (kacc == 0) || (txn->kacc == kacc) )
217 {
218 if( flt->maxdate == 0 )
219 flt->maxdate = txn->date;
220 else
221 flt->maxdate = MAX(flt->maxdate, txn->date);
222 }
223 }
224
225 }
226 lnk_acc = g_list_next(lnk_acc);
227 }
228
229 if( flt->mindate == 0 )
230 //changed 5.3
231 //flt->mindate = HB_MINDATE;
232 flt->mindate = GLOBALS->today - 365;
233
234 if( flt->maxdate == 0 )
235 //changed 5.3
236 //flt->maxdate = HB_MAXDATE;
237 flt->maxdate = GLOBALS->today + flt->nbdaysfuture;
238
239 g_list_free(lst_acc);
240 }
241
242
243 gboolean filter_preset_daterange_future_enable(gint range)
244 {
245 switch( range )
246 {
247 case FLT_RANGE_THISMONTH:
248 case FLT_RANGE_THISQUARTER:
249 case FLT_RANGE_THISYEAR:
250 case FLT_RANGE_LAST30DAYS:
251 case FLT_RANGE_LAST60DAYS:
252 case FLT_RANGE_LAST90DAYS:
253 case FLT_RANGE_LAST12MONTHS:
254 return TRUE;
255 break;
256 }
257
258 return FALSE;
259 }
260
261
262 void filter_preset_daterange_add_futuregap(Filter *filter, gint nbdays)
263 {
264
265 DB( g_print("\n[filter] range add future gap\n") );
266
267 //fixed > 5.1.7
268 /*if( nbdays <= 0 )
269 {
270 filter->nbdaysfuture = 0;
271 return;
272 }*/
273
274 filter->nbdaysfuture = 0;
275 if( filter_preset_daterange_future_enable(filter->range) )
276 filter->nbdaysfuture = nbdays;
277
278 }
279
280
281 void filter_preset_daterange_set(Filter *flt, gint range, guint32 kacc)
282 {
283 GDate *tmpdate;
284 guint32 jtoday, jfiscal;
285 guint16 month, year, yfiscal, qnum;
286
287 DB( g_print("\n[filter] daterange set %p %d\n", flt, range) );
288
289 flt->range = range;
290
291 jtoday = GLOBALS->today;
292
293 tmpdate = g_date_new_julian(jtoday);
294
295 month = g_date_get_month(tmpdate);
296 year = g_date_get_year(tmpdate);
297 DB( hb_print_date(jtoday , "today ") );
298
299 g_date_set_dmy(tmpdate, PREFS->fisc_year_day, PREFS->fisc_year_month, year);
300 jfiscal = g_date_get_julian(tmpdate);
301 DB( hb_print_date(jfiscal, "fiscal") );
302
303 yfiscal = (jtoday >= jfiscal) ? year : year-1;
304 qnum = 0;
305
306 if( range == FLT_RANGE_THISQUARTER || range == FLT_RANGE_LASTQUARTER )
307 {
308 g_date_set_dmy(tmpdate, PREFS->fisc_year_day, PREFS->fisc_year_month, yfiscal);
309 while( (qnum < 5) && (g_date_get_julian(tmpdate) < jtoday) )
310 {
311 qnum++;
312 g_date_add_months (tmpdate, 3);
313 }
314 DB( g_print(" qnum: %d\n", qnum ) );
315 }
316
317 switch( range )
318 {
319 case FLT_RANGE_THISMONTH:
320 case FLT_RANGE_LASTMONTH:
321 g_date_set_dmy(tmpdate, 1, month, year);
322 if( range == FLT_RANGE_LASTMONTH )
323 g_date_subtract_months(tmpdate, 1);
324 flt->mindate = g_date_get_julian(tmpdate);
325 month = g_date_get_month(tmpdate);
326 year = g_date_get_year(tmpdate);
327 g_date_add_days(tmpdate, g_date_get_days_in_month(month, year));
328 flt->maxdate = g_date_get_julian(tmpdate) - 1;
329 break;
330
331 case FLT_RANGE_THISQUARTER:
332 case FLT_RANGE_LASTQUARTER:
333 g_date_set_dmy(tmpdate, PREFS->fisc_year_day, PREFS->fisc_year_month, yfiscal);
334 if( range == FLT_RANGE_LASTQUARTER )
335 g_date_subtract_months(tmpdate, 3);
336 g_date_add_months(tmpdate, 3 * (qnum-1) );
337 flt->mindate = g_date_get_julian(tmpdate);
338 g_date_add_months(tmpdate, 3);
339 flt->maxdate = g_date_get_julian(tmpdate) - 1;
340 break;
341
342 case FLT_RANGE_THISYEAR:
343 case FLT_RANGE_LASTYEAR:
344 g_date_set_dmy(tmpdate, PREFS->fisc_year_day, PREFS->fisc_year_month, yfiscal);
345 if( range == FLT_RANGE_LASTYEAR )
346 g_date_subtract_years(tmpdate, 1);
347 flt->mindate = g_date_get_julian(tmpdate);
348 g_date_add_years (tmpdate, 1);
349 flt->maxdate = g_date_get_julian(tmpdate) - 1;
350 break;
351
352 case FLT_RANGE_LAST30DAYS:
353 flt->mindate = jtoday - 30;
354 flt->maxdate = jtoday;
355 break;
356
357 case FLT_RANGE_LAST60DAYS:
358 flt->mindate = jtoday - 60;
359 flt->maxdate = jtoday;
360 break;
361
362 case FLT_RANGE_LAST90DAYS:
363 flt->mindate = jtoday - 90;
364 flt->maxdate = jtoday;
365 break;
366
367 case FLT_RANGE_LAST12MONTHS:
368 g_date_set_julian (tmpdate, jtoday);
369 g_date_subtract_months(tmpdate, 12);
370 flt->mindate = g_date_get_julian(tmpdate);
371 flt->maxdate = jtoday;
372 break;
373
374 // case FLT_RANGE_OTHER:
375 //nothing to do
376
377 case FLT_RANGE_ALLDATE:
378 filter_set_date_bounds(flt, kacc);
379 break;
380 }
381 g_date_free(tmpdate);
382 }
383
384
385 void filter_preset_type_set(Filter *flt, gint type)
386 {
387
388 DB( g_print("\n[filter] preset type set\n") );
389
390 /* any type */
391 flt->type = type;
392 flt->option[FILTER_AMOUNT] = 0;
393 flt->minamount = G_MINDOUBLE;
394 flt->maxamount = G_MINDOUBLE;
395
396 switch( type )
397 {
398 case FLT_TYPE_EXPENSE:
399 flt->option[FILTER_AMOUNT] = 1;
400 flt->minamount = -G_MAXDOUBLE;
401 flt->maxamount = G_MINDOUBLE;
402 break;
403
404 case FLT_TYPE_INCOME:
405 flt->option[FILTER_AMOUNT] = 1;
406 flt->minamount = G_MINDOUBLE;
407 flt->maxamount = G_MAXDOUBLE;
408 break;
409 }
410
411 }
412
413
414 void filter_preset_status_set(Filter *flt, gint status)
415 {
416
417 DB( g_print("\n[filter] preset status set\n") );
418
419 /* any status */
420 flt->status = status;
421 flt->option[FILTER_STATUS] = 0;
422 flt->option[FILTER_CATEGORY] = 0;
423 flt->option[FILTER_PAYMODE] = 0;
424 flt->reconciled = TRUE;
425 flt->cleared = TRUE;
426 //#1602835 fautly set
427 //flt->forceadd = TRUE;
428 //flt->forcechg = TRUE;
429
430 switch( status )
431 {
432 case FLT_STATUS_UNCATEGORIZED:
433 flt->option[FILTER_CATEGORY] = 1;
434 filter_status_cat_clear_except(flt, 0);
435 flt->option[FILTER_PAYMODE] = 1;
436 flt->paymode[PAYMODE_INTXFER] = FALSE;
437 break;
438
439 case FLT_STATUS_UNRECONCILED:
440 flt->option[FILTER_STATUS] = 2;
441 flt->reconciled = TRUE;
442 flt->cleared = FALSE;
443 break;
444
445 case FLT_STATUS_UNCLEARED:
446 flt->option[FILTER_STATUS] = 2;
447 flt->reconciled = FALSE;
448 flt->cleared = TRUE;
449 break;
450
451 case FLT_STATUS_RECONCILED:
452 flt->option[FILTER_STATUS] = 1;
453 flt->reconciled = TRUE;
454 flt->cleared = FALSE;
455 break;
456
457 case FLT_STATUS_CLEARED:
458 flt->option[FILTER_STATUS] = 1;
459 flt->reconciled = FALSE;
460 flt->cleared = TRUE;
461 break;
462
463 }
464 }
465
466
467 gchar *filter_daterange_text_get(Filter *flt)
468 {
469 gchar buffer1[128];
470 gchar buffer2[128];
471 gchar buffer3[128];
472 GDate *date;
473 gchar *retval = NULL;
474
475 DB( g_print("\n[filter] daterange text get\n") );
476
477 date = g_date_new_julian(flt->mindate);
478 g_date_strftime (buffer1, 128-1, PREFS->date_format, date);
479
480 g_date_set_julian(date, flt->maxdate);
481 g_date_strftime (buffer2, 128-1, PREFS->date_format, date);
482
483 if( flt->nbdaysfuture > 0 )
484 {
485 g_date_set_julian(date, flt->maxdate + flt->nbdaysfuture);
486 g_date_strftime (buffer3, 128-1, PREFS->date_format, date);
487 retval = g_strdup_printf("%s — <s>%s</s> %s", buffer1, buffer2, buffer3);
488 }
489 else
490 retval = g_strdup_printf("%s — %s", buffer1, buffer2);
491
492 g_date_free(date);
493
494 //return g_strdup_printf(_("<i>from</i> %s <i>to</i> %s — "), buffer1, buffer2);
495 return retval;
496 }
497
498
499 /* used for quicksearch text into transaction */
500 gboolean filter_txn_search_match(gchar *needle, Transaction *txn, gint flags)
501 {
502 gboolean retval = FALSE;
503 Payee *payitem;
504 Category *catitem;
505 gchar *tags;
506
507 DB( g_print("\n[filter] tnx search match\n") );
508
509 if(flags & FLT_QSEARCH_MEMO)
510 {
511 //#1668036 always try match on txn memo first
512 if(txn->memo)
513 {
514 retval |= hb_string_utf8_strstr(txn->memo, needle, FALSE);
515 }
516 if(retval) goto end;
517
518 //#1509485
519 if(txn->flags & OF_SPLIT)
520 {
521 guint count, i;
522 Split *split;
523
524 count = da_splits_length(txn->splits);
525 for(i=0;i<count;i++)
526 {
527 gint tmpinsert = 0;
528
529 split = da_splits_get(txn->splits, i);
530 tmpinsert = hb_string_utf8_strstr(split->memo, needle, FALSE);
531 retval |= tmpinsert;
532 if( tmpinsert )
533 break;
534 }
535 }
536 if(retval) goto end;
537 }
538
539 if(flags & FLT_QSEARCH_INFO)
540 {
541 if(txn->info)
542 {
543 retval |= hb_string_utf8_strstr(txn->info, needle, FALSE);
544 }
545 if(retval) goto end;
546 }
547
548 if(flags & FLT_QSEARCH_PAYEE)
549 {
550 payitem = da_pay_get(txn->kpay);
551 if(payitem)
552 {
553 retval |= hb_string_utf8_strstr(payitem->name, needle, FALSE);
554 }
555 if(retval) goto end;
556 }
557
558 if(flags & FLT_QSEARCH_CATEGORY)
559 {
560 //#1509485
561 if(txn->flags & OF_SPLIT)
562 {
563 guint count, i;
564 Split *split;
565
566 count = da_splits_length(txn->splits);
567 for(i=0;i<count;i++)
568 {
569 gint tmpinsert = 0;
570
571 split = da_splits_get(txn->splits, i);
572 catitem = da_cat_get(split->kcat);
573 if(catitem)
574 {
575 tmpinsert = hb_string_utf8_strstr(catitem->fullname, needle, FALSE);
576 retval |= tmpinsert;
577 }
578
579 if( tmpinsert )
580 break;
581 }
582 }
583 else
584 {
585 catitem = da_cat_get(txn->kcat);
586 if(catitem)
587 {
588 retval |= hb_string_utf8_strstr(catitem->fullname, needle, FALSE);
589 }
590 }
591 if(retval) goto end;
592 }
593
594 if(flags & FLT_QSEARCH_TAGS)
595 {
596 tags = tags_tostring(txn->tags);
597 if(tags)
598 {
599 retval |= hb_string_utf8_strstr(tags, needle, FALSE);
600 }
601 g_free(tags);
602 if(retval) goto end;
603 }
604
605 //#1741339 add quicksearch for amount
606 if(flags & FLT_QSEARCH_AMOUNT)
607 {
608 gchar formatd_buf[G_ASCII_DTOSTR_BUF_SIZE];
609
610 hb_strfnum(formatd_buf, G_ASCII_DTOSTR_BUF_SIZE-1, txn->amount, txn->kcur, FALSE);
611 retval |= hb_string_utf8_strstr(formatd_buf, needle, FALSE);
612 }
613
614
615 end:
616 return retval;
617 }
618
619
620 gint filter_txn_match(Filter *flt, Transaction *txn)
621 {
622 Account *accitem;
623 Payee *payitem;
624 Category *catitem;
625 gint insert;
626
627 //DB( g_print("\n[filter] txn match\n") );
628
629 insert = 1;
630
631 /*** start filtering ***/
632
633 /* force display */
634 if(flt->forceadd == TRUE && (txn->flags & OF_ADDED))
635 goto end;
636
637 if(flt->forcechg == TRUE && (txn->flags & OF_CHANGED))
638 goto end;
639
640 /* force remind if not filter on status */
641 if(flt->forceremind == TRUE && (txn->status == TXN_STATUS_REMIND))
642 goto end;
643
644 /* date */
645 if(flt->option[FILTER_DATE]) {
646 insert = ( (txn->date >= flt->mindate) && (txn->date <= (flt->maxdate + flt->nbdaysfuture) ) ) ? 1 : 0;
647 if(flt->option[FILTER_DATE] == 2) insert ^= 1;
648 }
649 if(!insert) goto end;
650
651 /* account */
652 if(flt->option[FILTER_ACCOUNT]) {
653 accitem = da_acc_get(txn->kacc);
654 if(accitem)
655 {
656 insert = ( accitem->flt_select == TRUE ) ? 1 : 0;
657 if(flt->option[FILTER_ACCOUNT] == 2) insert ^= 1;
658 }
659 }
660 if(!insert) goto end;
661
662 /* payee */
663 if(flt->option[FILTER_PAYEE]) {
664 payitem = da_pay_get(txn->kpay);
665 if(payitem)
666 {
667 insert = ( payitem->flt_select == TRUE ) ? 1 : 0;
668 if(flt->option[FILTER_PAYEE] == 2) insert ^= 1;
669 }
670 }
671 if(!insert) goto end;
672
673 /* category */
674 if(flt->option[FILTER_CATEGORY]) {
675 if(txn->flags & OF_SPLIT)
676 {
677 guint count, i;
678 Split *split;
679
680 insert = 0; //fix: 1151259
681 count = da_splits_length(txn->splits);
682 for(i=0;i<count;i++)
683 {
684 gint tmpinsert = 0;
685
686 split = da_splits_get(txn->splits, i);
687 catitem = da_cat_get(split->kcat);
688 if(catitem)
689 {
690 tmpinsert = ( catitem->flt_select == TRUE ) ? 1 : 0;
691 if(flt->option[FILTER_CATEGORY] == 2) tmpinsert ^= 1;
692 }
693 insert |= tmpinsert;
694 }
695 }
696 else
697 {
698 catitem = da_cat_get(txn->kcat);
699 if(catitem)
700 {
701 insert = ( catitem->flt_select == TRUE ) ? 1 : 0;
702 if(flt->option[FILTER_CATEGORY] == 2) insert ^= 1;
703 }
704 }
705 }
706 if(!insert) goto end;
707
708 /* status */
709 if(flt->option[FILTER_STATUS]) {
710 gint insert1 = 0, insert2 = 0;
711
712 if(flt->reconciled)
713 insert1 = ( txn->status == TXN_STATUS_RECONCILED ) ? 1 : 0;
714 if(flt->cleared)
715 insert2 = ( txn->status == TXN_STATUS_CLEARED ) ? 1 : 0;
716
717 insert = insert1 | insert2;
718 if(flt->option[FILTER_STATUS] == 2) insert ^= 1;
719 }
720 if(!insert) goto end;
721
722 /* paymode */
723 if(flt->option[FILTER_PAYMODE]) {
724 insert = ( flt->paymode[txn->paymode] == TRUE) ? 1 : 0;
725 if(flt->option[FILTER_PAYMODE] == 2) insert ^= 1;
726 }
727 if(!insert) goto end;
728
729 /* amount */
730 if(flt->option[FILTER_AMOUNT]) {
731 insert = ( (txn->amount >= flt->minamount) && (txn->amount <= flt->maxamount) ) ? 1 : 0;
732
733 if(flt->option[FILTER_AMOUNT] == 2) insert ^= 1;
734 }
735 if(!insert) goto end;
736
737 /* info/memo/tag */
738 if(flt->option[FILTER_TEXT])
739 {
740 gchar *tags;
741 gint insert1, insert2, insert3;
742
743 insert1 = insert2 = insert3 = 0;
744 if(flt->info)
745 {
746 if(txn->info)
747 {
748 insert1 = hb_string_utf8_strstr(txn->info, flt->info, flt->exact);
749 }
750 }
751 else
752 insert1 = 1;
753
754 if(flt->memo)
755 {
756 //#1668036 always try match on txn memo first
757 if(txn->memo)
758 {
759 insert2 = hb_string_utf8_strstr(txn->memo, flt->memo, flt->exact);
760 }
761
762 if( (insert2 == 0) && (txn->flags & OF_SPLIT) )
763 {
764 guint count, i;
765 Split *split;
766
767 count = da_splits_length(txn->splits);
768 for(i=0;i<count;i++)
769 {
770 gint tmpinsert = 0;
771
772 split = da_splits_get(txn->splits, i);
773 tmpinsert = hb_string_utf8_strstr(split->memo, flt->memo, flt->exact);
774 insert2 |= tmpinsert;
775 if( tmpinsert )
776 break;
777 }
778 }
779 }
780 else
781 insert2 = 1;
782
783 if(flt->tag)
784 {
785 tags = tags_tostring(txn->tags);
786 if(tags)
787 {
788 insert3 = hb_string_utf8_strstr(tags, flt->tag, flt->exact);
789 }
790 g_free(tags);
791 }
792 else
793 insert3 = 1;
794
795 insert = insert1 && insert2 && insert3 ? 1 : 0;
796
797 if(flt->option[FILTER_TEXT] == 2) insert ^= 1;
798
799 }
800 if(!insert) goto end;
801
802 end:
803 // DB( g_print(" %d :: %d :: %d\n", flt->mindate, txn->date, flt->maxdate) );
804 // DB( g_print(" [%d] %s => %d (%d)\n", txn->account, txn->memo, insert, count) );
805 return(insert);
806 }
807
This page took 0.071345 seconds and 4 git commands to generate.