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

akonadi/contact

contactsfilterproxymodel.cpp
00001 /*
00002     This file is part of Akonadi Contact.
00003 
00004     Copyright (c) 2009 Tobias Koenig <tokoe@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or modify it
00007     under the terms of the GNU Library General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or (at your
00009     option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful, but WITHOUT
00012     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014     License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to the
00018     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00019     02110-1301, USA.
00020 */
00021 
00022 #include "contactsfilterproxymodel.h"
00023 
00024 #include "contactstreemodel.h"
00025 
00026 #include <akonadi/entitytreemodel.h>
00027 #include <kabc/addressee.h>
00028 #include <kabc/contactgroup.h>
00029 
00030 static bool contactMatchesFilter( const KABC::Addressee &contact, const QString &filterString );
00031 static bool contactGroupMatchesFilter( const KABC::ContactGroup &group, const QString &filterString );
00032 
00033 using namespace Akonadi;
00034 
00035 class ContactsFilterProxyModel::Private
00036 {
00037   public:
00038     Private()
00039       : flags( 0 ),
00040         mExcludeVirtualCollections( false )
00041     {
00042     }
00043     QString mFilter;
00044     ContactsFilterProxyModel::FilterFlags flags;
00045     bool mExcludeVirtualCollections;
00046 };
00047 
00048 ContactsFilterProxyModel::ContactsFilterProxyModel( QObject *parent )
00049   : QSortFilterProxyModel( parent ), d( new Private )
00050 {
00051   // contact names should be sorted correctly
00052   setSortLocaleAware( true );
00053   setDynamicSortFilter( true );
00054 }
00055 
00056 ContactsFilterProxyModel::~ContactsFilterProxyModel()
00057 {
00058   delete d;
00059 }
00060 
00061 void ContactsFilterProxyModel::setFilterString( const QString &filter )
00062 {
00063   d->mFilter = filter;
00064   invalidateFilter();
00065 }
00066 
00067 bool ContactsFilterProxyModel::filterAcceptsRow( int row, const QModelIndex &parent ) const
00068 {
00069   const QModelIndex index = sourceModel()->index( row, 0, parent );
00070   if ( d->mExcludeVirtualCollections ) {
00071     const Akonadi::Collection collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
00072     if ( collection.isValid() && collection.isVirtual())
00073       return false;
00074   }
00075     
00076   if ( ( d->mFilter.isEmpty() ) && ( !( d->flags & ContactsFilterProxyModel::HasEmail ) ))
00077     return true;
00078 
00079   const Akonadi::Item item = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
00080 
00081   if ( item.hasPayload<KABC::Addressee>() ) {
00082     const KABC::Addressee contact = item.payload<KABC::Addressee>();
00083     if ( d->flags & ContactsFilterProxyModel::HasEmail ){
00084       if ( contact.emails().isEmpty() )
00085         return false;
00086     }
00087     if ( !d->mFilter.isEmpty() ) {
00088         return contactMatchesFilter( contact, d->mFilter );
00089     }
00090   } else {
00091     if ( !d->mFilter.isEmpty() ) {
00092       if ( item.hasPayload<KABC::ContactGroup>() ) {
00093       const KABC::ContactGroup group = item.payload<KABC::ContactGroup>();
00094       return contactGroupMatchesFilter( group, d->mFilter );
00095       }
00096     }
00097   }
00098 
00099   return true;
00100 }
00101 
00102 bool ContactsFilterProxyModel::lessThan( const QModelIndex &leftIndex, const QModelIndex &rightIndex ) const
00103 {
00104   const QDate leftDate = leftIndex.data( ContactsTreeModel::DateRole ).toDate();
00105   const QDate rightDate = rightIndex.data( ContactsTreeModel::DateRole ).toDate();
00106   if ( leftDate.isValid() && rightDate.isValid() ) {
00107     if(leftDate.year() < rightDate.year() )
00108       return true;
00109     else if(leftDate.year() == rightDate.year()) {
00110        if ( leftDate.month() < rightDate.month() )
00111          return true;
00112        else if ( leftDate.month() == rightDate.month() )
00113          return (leftDate.day() < rightDate.day());
00114     }
00115     else
00116      return false;
00117   }
00118 
00119   return QSortFilterProxyModel::lessThan( leftIndex, rightIndex );
00120 }
00121 
00122 void ContactsFilterProxyModel::setFilterFlags( ContactsFilterProxyModel::FilterFlags flags )
00123 {
00124   d->flags = flags;
00125 }
00126 
00127 void ContactsFilterProxyModel::setExcludeVirtualCollections( bool exclude )
00128 {
00129   if ( exclude != d->mExcludeVirtualCollections ) {
00130     d->mExcludeVirtualCollections = exclude;
00131     invalidateFilter();
00132   }
00133 }
00134 
00135 Qt::ItemFlags ContactsFilterProxyModel::flags( const QModelIndex& index ) const
00136 {
00137   if ( !index.isValid() ) {
00138     // Don't crash
00139     return 0;
00140   }
00141   const Akonadi::Collection collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
00142   if ( collection.isValid() )
00143   {
00144     return QSortFilterProxyModel::flags( index ) & ~( Qt::ItemIsSelectable );
00145   }
00146   return QSortFilterProxyModel::flags( index );
00147 }
00148 
00149 static bool addressMatchesFilter( const KABC::Address &address, const QString &filterString )
00150 {
00151   if ( address.street().contains( filterString, Qt::CaseInsensitive ) )
00152     return true;
00153 
00154   if ( address.locality().contains( filterString, Qt::CaseInsensitive ) )
00155     return true;
00156 
00157   if ( address.region().contains( filterString, Qt::CaseInsensitive ) )
00158     return true;
00159 
00160   if ( address.postalCode().contains( filterString, Qt::CaseInsensitive ) )
00161     return true;
00162 
00163   if ( address.country().contains( filterString, Qt::CaseInsensitive ) )
00164     return true;
00165 
00166   if ( address.label().contains( filterString, Qt::CaseInsensitive ) )
00167     return true;
00168 
00169   if ( address.postOfficeBox().contains( filterString, Qt::CaseInsensitive ) )
00170     return true;
00171 
00172   return false;
00173 }
00174 
00175 static bool contactMatchesFilter( const KABC::Addressee &contact, const QString &filterString )
00176 {
00177   if ( contact.assembledName().contains( filterString, Qt::CaseInsensitive ) )
00178     return true;
00179 
00180   if ( contact.formattedName().contains( filterString, Qt::CaseInsensitive ) )
00181     return true;
00182 
00183   if ( contact.nickName().contains( filterString, Qt::CaseInsensitive ) )
00184     return true;
00185 
00186   if ( contact.birthday().toString().contains( filterString, Qt::CaseInsensitive ) )
00187     return true;
00188 
00189   const KABC::Address::List addresses = contact.addresses();
00190   int count = addresses.count();
00191   for ( int i = 0; i < count; ++i ) {
00192     if ( addressMatchesFilter( addresses.at( i ), filterString ) )
00193       return true;
00194   }
00195 
00196   const KABC::PhoneNumber::List phoneNumbers = contact.phoneNumbers();
00197   count = phoneNumbers.count();
00198   for ( int i = 0; i < count; ++i ) {
00199     if ( phoneNumbers.at( i ).number().contains( filterString, Qt::CaseInsensitive ) )
00200       return true;
00201   }
00202 
00203   const QStringList emails = contact.emails();
00204   count = emails.count();
00205   for ( int i = 0; i < count; ++i ) {
00206     if ( emails.at( i ).contains( filterString, Qt::CaseInsensitive ) )
00207       return true;
00208   }
00209 
00210   const QStringList categories = contact.categories();
00211   count = categories.count();
00212   for ( int i = 0; i < count; ++i ) {
00213     if ( categories.at( i ).contains( filterString, Qt::CaseInsensitive ) )
00214       return true;
00215   }
00216 
00217   if ( contact.mailer().contains( filterString, Qt::CaseInsensitive ) )
00218     return true;
00219 
00220   if ( contact.title().contains( filterString, Qt::CaseInsensitive ) )
00221     return true;
00222 
00223   if ( contact.role().contains( filterString, Qt::CaseInsensitive ) )
00224     return true;
00225 
00226   if ( contact.organization().contains( filterString, Qt::CaseInsensitive ) )
00227     return true;
00228 
00229   if ( contact.department().contains( filterString, Qt::CaseInsensitive ) )
00230     return true;
00231 
00232   if ( contact.note().contains( filterString, Qt::CaseInsensitive ) )
00233     return true;
00234 
00235   if ( contact.url().url().contains( filterString, Qt::CaseInsensitive ) )
00236     return true;
00237 
00238   const QStringList customs = contact.customs();
00239   count = customs.count();
00240   for ( int i = 0; i < count; ++i ) {
00241     if ( customs.at( i ).contains( filterString, Qt::CaseInsensitive ) )
00242       return true;
00243   }
00244 
00245   return false;
00246 }
00247 
00248 bool contactGroupMatchesFilter( const KABC::ContactGroup &group, const QString &filterString )
00249 {
00250   if ( group.name().contains( filterString, Qt::CaseInsensitive ) )
00251     return true;
00252 
00253   const int count = group.dataCount();
00254   for ( int i = 0; i < count; ++i ) {
00255     if ( group.data( i ).name().contains( filterString, Qt::CaseInsensitive ) )
00256       return true;
00257     if ( group.data( i ).email().contains( filterString, Qt::CaseInsensitive ) )
00258       return true;
00259   }
00260 
00261   return false;
00262 }
00263 
00264 #include "contactsfilterproxymodel.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu Aug 2 2012 15:25:43 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi/contact

Skip menu "akonadi/contact"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.8.5 API Reference

Skip menu "kdepimlibs-4.8.5 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