• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
  • contact
contactsfilterproxymodel.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
5 
6  This library is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Library General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or (at your
9  option) any later version.
10 
11  This library is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14  License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to the
18  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  02110-1301, USA.
20 */
21 
22 #include "contactsfilterproxymodel.h"
23 
24 #include "contactstreemodel.h"
25 
26 #include <akonadi/entitytreemodel.h>
27 #include <kabc/addressee.h>
28 #include <kabc/contactgroup.h>
29 
30 static bool contactMatchesFilter( const KABC::Addressee &contact, const QString &filterString );
31 static bool contactGroupMatchesFilter( const KABC::ContactGroup &group, const QString &filterString );
32 
33 using namespace Akonadi;
34 
35 class ContactsFilterProxyModel::Private
36 {
37  public:
38  Private()
39  : flags( 0 ),
40  mExcludeVirtualCollections( false )
41  {
42  }
43  QString mFilter;
44  ContactsFilterProxyModel::FilterFlags flags;
45  bool mExcludeVirtualCollections;
46 };
47 
48 ContactsFilterProxyModel::ContactsFilterProxyModel( QObject *parent )
49  : QSortFilterProxyModel( parent ), d( new Private )
50 {
51  // contact names should be sorted correctly
52  setSortLocaleAware( true );
53  setDynamicSortFilter( true );
54 }
55 
56 ContactsFilterProxyModel::~ContactsFilterProxyModel()
57 {
58  delete d;
59 }
60 
61 void ContactsFilterProxyModel::setFilterString( const QString &filter )
62 {
63  d->mFilter = filter;
64  invalidateFilter();
65 }
66 
67 bool ContactsFilterProxyModel::filterAcceptsRow( int row, const QModelIndex &parent ) const
68 {
69  const QModelIndex index = sourceModel()->index( row, 0, parent );
70  if ( d->mExcludeVirtualCollections ) {
71  const Akonadi::Collection collection = index.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
72  if ( collection.isValid() && collection.isVirtual() ) {
73  return false;
74  }
75  }
76 
77  if ( ( d->mFilter.isEmpty() ) && ( !( d->flags & ContactsFilterProxyModel::HasEmail ) ) ) {
78  return true;
79  }
80 
81  const Akonadi::Item item = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
82 
83  if ( item.hasPayload<KABC::Addressee>() ) {
84  const KABC::Addressee contact = item.payload<KABC::Addressee>();
85  if ( d->flags & ContactsFilterProxyModel::HasEmail ) {
86  if ( contact.emails().isEmpty() ) {
87  return false;
88  }
89  }
90  if ( !d->mFilter.isEmpty() ) {
91  return contactMatchesFilter( contact, d->mFilter );
92  }
93  } else {
94  if ( !d->mFilter.isEmpty() ) {
95  if ( item.hasPayload<KABC::ContactGroup>() ) {
96  const KABC::ContactGroup group = item.payload<KABC::ContactGroup>();
97  return contactGroupMatchesFilter( group, d->mFilter );
98  }
99  }
100  }
101 
102  return true;
103 }
104 
105 bool ContactsFilterProxyModel::lessThan( const QModelIndex &leftIndex, const QModelIndex &rightIndex ) const
106 {
107  const QDate leftDate = leftIndex.data( ContactsTreeModel::DateRole ).toDate();
108  const QDate rightDate = rightIndex.data( ContactsTreeModel::DateRole ).toDate();
109  if ( leftDate.isValid() && rightDate.isValid() ) {
110  if ( leftDate.year() < rightDate.year() ) {
111  return true;
112  } else if ( leftDate.year() == rightDate.year() ) {
113  if ( leftDate.month() < rightDate.month() ) {
114  return true;
115  } else if ( leftDate.month() == rightDate.month() ) {
116  return ( leftDate.day() < rightDate.day() );
117  }
118  } else {
119  return false;
120  }
121  }
122 
123  return QSortFilterProxyModel::lessThan( leftIndex, rightIndex );
124 }
125 
126 void ContactsFilterProxyModel::setFilterFlags( ContactsFilterProxyModel::FilterFlags flags )
127 {
128  d->flags = flags;
129 }
130 
131 void ContactsFilterProxyModel::setExcludeVirtualCollections( bool exclude )
132 {
133  if ( exclude != d->mExcludeVirtualCollections ) {
134  d->mExcludeVirtualCollections = exclude;
135  invalidateFilter();
136  }
137 }
138 
139 Qt::ItemFlags ContactsFilterProxyModel::flags( const QModelIndex& index ) const
140 {
141  if ( !index.isValid() ) {
142  // Don't crash
143  return 0;
144  }
145  const Akonadi::Collection collection = index.data( Akonadi::EntityTreeModel::CollectionRole ).value<Akonadi::Collection>();
146  if ( collection.isValid() ) {
147  return QSortFilterProxyModel::flags( index ) & ~( Qt::ItemIsSelectable );
148  }
149  return QSortFilterProxyModel::flags( index );
150 }
151 
152 static bool addressMatchesFilter( const KABC::Address &address, const QString &filterString )
153 {
154  if ( address.street().contains( filterString, Qt::CaseInsensitive ) ) {
155  return true;
156  }
157 
158  if ( address.locality().contains( filterString, Qt::CaseInsensitive ) ) {
159  return true;
160  }
161 
162  if ( address.region().contains( filterString, Qt::CaseInsensitive ) ) {
163  return true;
164  }
165 
166  if ( address.postalCode().contains( filterString, Qt::CaseInsensitive ) ) {
167  return true;
168  }
169 
170  if ( address.country().contains( filterString, Qt::CaseInsensitive ) ) {
171  return true;
172  }
173 
174  if ( address.label().contains( filterString, Qt::CaseInsensitive ) ) {
175  return true;
176  }
177 
178  if ( address.postOfficeBox().contains( filterString, Qt::CaseInsensitive ) ) {
179  return true;
180  }
181 
182  return false;
183 }
184 
185 static bool contactMatchesFilter( const KABC::Addressee &contact, const QString &filterString )
186 {
187  if ( contact.assembledName().contains( filterString, Qt::CaseInsensitive ) ) {
188  return true;
189  }
190 
191  if ( contact.formattedName().contains( filterString, Qt::CaseInsensitive ) ) {
192  return true;
193  }
194 
195  if ( contact.nickName().contains( filterString, Qt::CaseInsensitive ) ) {
196  return true;
197  }
198 
199  if ( contact.birthday().toString().contains( filterString, Qt::CaseInsensitive ) ) {
200  return true;
201  }
202 
203  const KABC::Address::List addresses = contact.addresses();
204  int count = addresses.count();
205  for ( int i = 0; i < count; ++i ) {
206  if ( addressMatchesFilter( addresses.at( i ), filterString ) ) {
207  return true;
208  }
209  }
210 
211  const KABC::PhoneNumber::List phoneNumbers = contact.phoneNumbers();
212  count = phoneNumbers.count();
213  for ( int i = 0; i < count; ++i ) {
214  if ( phoneNumbers.at( i ).number().contains( filterString, Qt::CaseInsensitive ) ) {
215  return true;
216  }
217  }
218 
219  const QStringList emails = contact.emails();
220  count = emails.count();
221  for ( int i = 0; i < count; ++i ) {
222  if ( emails.at( i ).contains( filterString, Qt::CaseInsensitive ) ) {
223  return true;
224  }
225  }
226 
227  const QStringList categories = contact.categories();
228  count = categories.count();
229  for ( int i = 0; i < count; ++i ) {
230  if ( categories.at( i ).contains( filterString, Qt::CaseInsensitive ) ) {
231  return true;
232  }
233  }
234 
235  if ( contact.mailer().contains( filterString, Qt::CaseInsensitive ) ) {
236  return true;
237  }
238 
239  if ( contact.title().contains( filterString, Qt::CaseInsensitive ) ) {
240  return true;
241  }
242 
243  if ( contact.role().contains( filterString, Qt::CaseInsensitive ) ) {
244  return true;
245  }
246 
247  if ( contact.organization().contains( filterString, Qt::CaseInsensitive ) ) {
248  return true;
249  }
250 
251  if ( contact.department().contains( filterString, Qt::CaseInsensitive ) ) {
252  return true;
253  }
254 
255  if ( contact.note().contains( filterString, Qt::CaseInsensitive ) ) {
256  return true;
257  }
258 
259  if ( contact.url().url().contains( filterString, Qt::CaseInsensitive ) ) {
260  return true;
261  }
262 
263  const QStringList customs = contact.customs();
264  count = customs.count();
265  for ( int i = 0; i < count; ++i ) {
266  if ( customs.at( i ).contains( filterString, Qt::CaseInsensitive ) ) {
267  return true;
268  }
269  }
270 
271  return false;
272 }
273 
274 bool contactGroupMatchesFilter( const KABC::ContactGroup &group, const QString &filterString )
275 {
276  if ( group.name().contains( filterString, Qt::CaseInsensitive ) ) {
277  return true;
278  }
279 
280  const uint count = group.dataCount();
281  for ( uint i = 0; i < count; ++i ) {
282  if ( group.data( i ).name().contains( filterString, Qt::CaseInsensitive ) ) {
283  return true;
284  }
285  if ( group.data( i ).email().contains( filterString, Qt::CaseInsensitive ) ) {
286  return true;
287  }
288  }
289 
290  return false;
291 }
292 
Akonadi::ContactsFilterProxyModel::~ContactsFilterProxyModel
virtual ~ContactsFilterProxyModel()
Destroys the contacts filter proxy model.
Definition: contactsfilterproxymodel.cpp:56
Akonadi::ContactsFilterProxyModel::setFilterString
void setFilterString(const QString &filter)
Sets the filter that is used to filter for matching contacts and contact groups.
Definition: contactsfilterproxymodel.cpp:61
Akonadi::ContactsFilterProxyModel::setFilterFlags
void setFilterFlags(ContactsFilterProxyModel::FilterFlags flags)
Sets the filter flags.
Definition: contactsfilterproxymodel.cpp:126
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::ContactsTreeModel::DateRole
The QDate object for the current index.
Definition: contactstreemodel.h:162
Akonadi::EntityTreeModel::CollectionRole
The collection.
Definition: entitytreemodel.h:335
Akonadi::ContactsFilterProxyModel::setExcludeVirtualCollections
void setExcludeVirtualCollections(bool exclude)
Sets whether we want virtual collections to be filtered or not.
Definition: contactsfilterproxymodel.cpp:131
Akonadi::EntityTreeModel::ItemRole
The Item.
Definition: entitytreemodel.h:331
Akonadi::ContactsFilterProxyModel::ContactsFilterProxyModel
ContactsFilterProxyModel(QObject *parent=0)
Creates a new contacts filter proxy model.
Definition: contactsfilterproxymodel.cpp:48
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::Collection::isVirtual
bool isVirtual() const
Returns whether the collection is virtual, for example a search collection.
Definition: collection.cpp:261
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal