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

akonadi

  • 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  if ( ( d->mFilter.isEmpty() ) && ( !( d->flags & ContactsFilterProxyModel::HasEmail ) ))
77  return true;
78 
79  const Akonadi::Item item = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
80 
81  if ( item.hasPayload<KABC::Addressee>() ) {
82  const KABC::Addressee contact = item.payload<KABC::Addressee>();
83  if ( d->flags & ContactsFilterProxyModel::HasEmail ){
84  if ( contact.emails().isEmpty() )
85  return false;
86  }
87  if ( !d->mFilter.isEmpty() ) {
88  return contactMatchesFilter( contact, d->mFilter );
89  }
90  } else {
91  if ( !d->mFilter.isEmpty() ) {
92  if ( item.hasPayload<KABC::ContactGroup>() ) {
93  const KABC::ContactGroup group = item.payload<KABC::ContactGroup>();
94  return contactGroupMatchesFilter( group, d->mFilter );
95  }
96  }
97  }
98 
99  return true;
100 }
101 
102 bool ContactsFilterProxyModel::lessThan( const QModelIndex &leftIndex, const QModelIndex &rightIndex ) const
103 {
104  const QDate leftDate = leftIndex.data( ContactsTreeModel::DateRole ).toDate();
105  const QDate rightDate = rightIndex.data( ContactsTreeModel::DateRole ).toDate();
106  if ( leftDate.isValid() && rightDate.isValid() ) {
107  if(leftDate.year() < rightDate.year() )
108  return true;
109  else if(leftDate.year() == rightDate.year()) {
110  if ( leftDate.month() < rightDate.month() )
111  return true;
112  else if ( leftDate.month() == rightDate.month() )
113  return (leftDate.day() < rightDate.day());
114  }
115  else
116  return false;
117  }
118 
119  return QSortFilterProxyModel::lessThan( leftIndex, rightIndex );
120 }
121 
122 void ContactsFilterProxyModel::setFilterFlags( ContactsFilterProxyModel::FilterFlags flags )
123 {
124  d->flags = flags;
125 }
126 
127 void ContactsFilterProxyModel::setExcludeVirtualCollections( bool exclude )
128 {
129  if ( exclude != d->mExcludeVirtualCollections ) {
130  d->mExcludeVirtualCollections = exclude;
131  invalidateFilter();
132  }
133 }
134 
135 Qt::ItemFlags ContactsFilterProxyModel::flags( const QModelIndex& index ) const
136 {
137  if ( !index.isValid() ) {
138  // Don't crash
139  return 0;
140  }
141  const Akonadi::Collection collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
142  if ( collection.isValid() )
143  {
144  return QSortFilterProxyModel::flags( index ) & ~( Qt::ItemIsSelectable );
145  }
146  return QSortFilterProxyModel::flags( index );
147 }
148 
149 static bool addressMatchesFilter( const KABC::Address &address, const QString &filterString )
150 {
151  if ( address.street().contains( filterString, Qt::CaseInsensitive ) )
152  return true;
153 
154  if ( address.locality().contains( filterString, Qt::CaseInsensitive ) )
155  return true;
156 
157  if ( address.region().contains( filterString, Qt::CaseInsensitive ) )
158  return true;
159 
160  if ( address.postalCode().contains( filterString, Qt::CaseInsensitive ) )
161  return true;
162 
163  if ( address.country().contains( filterString, Qt::CaseInsensitive ) )
164  return true;
165 
166  if ( address.label().contains( filterString, Qt::CaseInsensitive ) )
167  return true;
168 
169  if ( address.postOfficeBox().contains( filterString, Qt::CaseInsensitive ) )
170  return true;
171 
172  return false;
173 }
174 
175 static bool contactMatchesFilter( const KABC::Addressee &contact, const QString &filterString )
176 {
177  if ( contact.assembledName().contains( filterString, Qt::CaseInsensitive ) )
178  return true;
179 
180  if ( contact.formattedName().contains( filterString, Qt::CaseInsensitive ) )
181  return true;
182 
183  if ( contact.nickName().contains( filterString, Qt::CaseInsensitive ) )
184  return true;
185 
186  if ( contact.birthday().toString().contains( filterString, Qt::CaseInsensitive ) )
187  return true;
188 
189  const KABC::Address::List addresses = contact.addresses();
190  int count = addresses.count();
191  for ( int i = 0; i < count; ++i ) {
192  if ( addressMatchesFilter( addresses.at( i ), filterString ) )
193  return true;
194  }
195 
196  const KABC::PhoneNumber::List phoneNumbers = contact.phoneNumbers();
197  count = phoneNumbers.count();
198  for ( int i = 0; i < count; ++i ) {
199  if ( phoneNumbers.at( i ).number().contains( filterString, Qt::CaseInsensitive ) )
200  return true;
201  }
202 
203  const QStringList emails = contact.emails();
204  count = emails.count();
205  for ( int i = 0; i < count; ++i ) {
206  if ( emails.at( i ).contains( filterString, Qt::CaseInsensitive ) )
207  return true;
208  }
209 
210  const QStringList categories = contact.categories();
211  count = categories.count();
212  for ( int i = 0; i < count; ++i ) {
213  if ( categories.at( i ).contains( filterString, Qt::CaseInsensitive ) )
214  return true;
215  }
216 
217  if ( contact.mailer().contains( filterString, Qt::CaseInsensitive ) )
218  return true;
219 
220  if ( contact.title().contains( filterString, Qt::CaseInsensitive ) )
221  return true;
222 
223  if ( contact.role().contains( filterString, Qt::CaseInsensitive ) )
224  return true;
225 
226  if ( contact.organization().contains( filterString, Qt::CaseInsensitive ) )
227  return true;
228 
229  if ( contact.department().contains( filterString, Qt::CaseInsensitive ) )
230  return true;
231 
232  if ( contact.note().contains( filterString, Qt::CaseInsensitive ) )
233  return true;
234 
235  if ( contact.url().url().contains( filterString, Qt::CaseInsensitive ) )
236  return true;
237 
238  const QStringList customs = contact.customs();
239  count = customs.count();
240  for ( int i = 0; i < count; ++i ) {
241  if ( customs.at( i ).contains( filterString, Qt::CaseInsensitive ) )
242  return true;
243  }
244 
245  return false;
246 }
247 
248 bool contactGroupMatchesFilter( const KABC::ContactGroup &group, const QString &filterString )
249 {
250  if ( group.name().contains( filterString, Qt::CaseInsensitive ) )
251  return true;
252 
253  const int count = group.dataCount();
254  for ( int i = 0; i < count; ++i ) {
255  if ( group.data( i ).name().contains( filterString, Qt::CaseInsensitive ) )
256  return true;
257  if ( group.data( i ).email().contains( filterString, Qt::CaseInsensitive ) )
258  return true;
259  }
260 
261  return false;
262 }
263 
264 #include "contactsfilterproxymodel.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Dec 10 2012 13:48:08 by doxygen 1.8.1.2 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-4.9.4 API Reference

Skip menu "kdepimlibs-4.9.4 API Reference"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
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