summaryrefslogtreecommitdiffstats
path: root/src/filter.cpp
blob: 967293798974f22ae3b347764330632bb4aa4a5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/***************************************************************************
    copyright            : (C) 2003-2006 by Robby Stephenson
    email                : robby@periapsis.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of version 2 of the GNU General Public License as  *
 *   published by the Free Software Foundation;                            *
 *                                                                         *
 ***************************************************************************/

#include "filter.h"
#include "entry.h"

#include "tellico_debug.h"

#include <qregexp.h>

using Tellico::Filter;
using Tellico::FilterRule;

FilterRule::FilterRule() : m_function(FuncEquals) {
}

FilterRule::FilterRule(const QString& fieldName_, const QString& pattern_, Function func_)
 : m_fieldName(fieldName_), m_function(func_), m_pattern(pattern_) {
}

bool FilterRule::matches(Data::EntryPtr entry_) const {
  switch (m_function) {
    case FuncEquals:
      return equals(entry_);
    case FuncNotEquals:
      return !equals(entry_);
    case FuncContains:
      return contains(entry_);
    case FuncNotContains:
      return !contains(entry_);
    case FuncRegExp:
      return matchesRegExp(entry_);
    case FuncNotRegExp:
      return !matchesRegExp(entry_);
    default:
      kdWarning() << "FilterRule::matches() - invalid function!" << endl;
      break;
  }
  return true;
}

bool FilterRule::equals(Data::EntryPtr entry_) const {
  // empty field name means search all
  if(m_fieldName.isEmpty()) {
    QStringList list = entry_->fieldValues() + entry_->formattedFieldValues();
    for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
      if(QString::compare((*it).lower(), m_pattern.lower()) == 0) {
        return true;
      }
    }
  } else {
    return QString::compare(entry_->field(m_fieldName).lower(), m_pattern.lower()) == 0
           || QString::compare(entry_->formattedField(m_fieldName).lower(), m_pattern.lower()) == 0;
  }

  return false;
}

bool FilterRule::contains(Data::EntryPtr entry_) const {
  // empty field name means search all
  if(m_fieldName.isEmpty()) {
    QStringList list = entry_->fieldValues() + entry_->formattedFieldValues();
    // match is true if any strings match
    for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
      if((*it).find(m_pattern, 0, false) >= 0) {
        return true;
      }
    }
  } else {
    return entry_->field(m_fieldName).find(m_pattern, 0, false) >= 0
           || entry_->formattedField(m_fieldName).find(m_pattern, 0, false) >= 0;
  }

  return false;
}

bool FilterRule::matchesRegExp(Data::EntryPtr entry_) const {
  QRegExp rx(m_pattern, false);
  // empty field name means search all
  if(m_fieldName.isEmpty()) {
    QStringList list = entry_->fieldValues() + entry_->formattedFieldValues();
    for(QStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
      if((*it).find(rx) >= 0) {
        return true;
        break;
      }
    }
  } else {
    return entry_->field(m_fieldName).find(rx) >= 0
           || entry_->formattedField(m_fieldName).find(rx) >= 0;
  }

  return false;
}


/*******************************************************/

Filter::Filter(const Filter& other_) : QPtrList<FilterRule>(), KShared(), m_op(other_.op()), m_name(other_.name()) {
  for(QPtrListIterator<FilterRule> it(other_); it.current(); ++it) {
    append(new FilterRule(*it.current()));
  }
  setAutoDelete(true);
}

bool Filter::matches(Data::EntryPtr entry_) const {
  if(isEmpty()) {
    return true;
  }

  bool match = false;
  for(QPtrListIterator<FilterRule> it(*this); it.current(); ++it) {
    if(it.current()->matches(entry_)) {
      if(m_op == Filter::MatchAny) {
        return true;
      } else {
        match = true;
      }
    } else {
      if(m_op == Filter::MatchAll) {
        return false;
      }
    }
  }

  return match;
}