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 00107 if ( leftDate.isValid() && rightDate.isValid() ) { 00108 if ( leftDate.month() < rightDate.month() ) 00109 return true; 00110 else if ( leftDate.month() == rightDate.month() ) 00111 return (leftDate.day() < rightDate.day()); 00112 else 00113 return false; 00114 } 00115 00116 return QSortFilterProxyModel::lessThan( leftIndex, rightIndex ); 00117 } 00118 00119 void ContactsFilterProxyModel::setFilterFlags( ContactsFilterProxyModel::FilterFlags flags ) 00120 { 00121 d->flags = flags; 00122 } 00123 00124 void ContactsFilterProxyModel::setExcludeVirtualCollections( bool exclude ) 00125 { 00126 if ( exclude != d->mExcludeVirtualCollections ) { 00127 d->mExcludeVirtualCollections = exclude; 00128 invalidateFilter(); 00129 } 00130 } 00131 00132 Qt::ItemFlags ContactsFilterProxyModel::flags( const QModelIndex& index ) const 00133 { 00134 if ( !index.isValid() ) { 00135 // Don't crash 00136 return 0; 00137 } 00138 const Akonadi::Collection collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>(); 00139 if ( collection.isValid() ) 00140 { 00141 return QSortFilterProxyModel::flags( index ) & ~( Qt::ItemIsSelectable ); 00142 } 00143 return QSortFilterProxyModel::flags( index ); 00144 } 00145 00146 static bool addressMatchesFilter( const KABC::Address &address, const QString &filterString ) 00147 { 00148 if ( address.street().contains( filterString, Qt::CaseInsensitive ) ) 00149 return true; 00150 00151 if ( address.locality().contains( filterString, Qt::CaseInsensitive ) ) 00152 return true; 00153 00154 if ( address.region().contains( filterString, Qt::CaseInsensitive ) ) 00155 return true; 00156 00157 if ( address.postalCode().contains( filterString, Qt::CaseInsensitive ) ) 00158 return true; 00159 00160 if ( address.country().contains( filterString, Qt::CaseInsensitive ) ) 00161 return true; 00162 00163 if ( address.label().contains( filterString, Qt::CaseInsensitive ) ) 00164 return true; 00165 00166 if ( address.postOfficeBox().contains( filterString, Qt::CaseInsensitive ) ) 00167 return true; 00168 00169 return false; 00170 } 00171 00172 static bool contactMatchesFilter( const KABC::Addressee &contact, const QString &filterString ) 00173 { 00174 if ( contact.assembledName().contains( filterString, Qt::CaseInsensitive ) ) 00175 return true; 00176 00177 if ( contact.formattedName().contains( filterString, Qt::CaseInsensitive ) ) 00178 return true; 00179 00180 if ( contact.nickName().contains( filterString, Qt::CaseInsensitive ) ) 00181 return true; 00182 00183 if ( contact.birthday().toString().contains( filterString, Qt::CaseInsensitive ) ) 00184 return true; 00185 00186 const KABC::Address::List addresses = contact.addresses(); 00187 int count = addresses.count(); 00188 for ( int i = 0; i < count; ++i ) { 00189 if ( addressMatchesFilter( addresses.at( i ), filterString ) ) 00190 return true; 00191 } 00192 00193 const KABC::PhoneNumber::List phoneNumbers = contact.phoneNumbers(); 00194 count = phoneNumbers.count(); 00195 for ( int i = 0; i < count; ++i ) { 00196 if ( phoneNumbers.at( i ).number().contains( filterString, Qt::CaseInsensitive ) ) 00197 return true; 00198 } 00199 00200 const QStringList emails = contact.emails(); 00201 count = emails.count(); 00202 for ( int i = 0; i < count; ++i ) { 00203 if ( emails.at( i ).contains( filterString, Qt::CaseInsensitive ) ) 00204 return true; 00205 } 00206 00207 const QStringList categories = contact.categories(); 00208 count = categories.count(); 00209 for ( int i = 0; i < count; ++i ) { 00210 if ( categories.at( i ).contains( filterString, Qt::CaseInsensitive ) ) 00211 return true; 00212 } 00213 00214 if ( contact.mailer().contains( filterString, Qt::CaseInsensitive ) ) 00215 return true; 00216 00217 if ( contact.title().contains( filterString, Qt::CaseInsensitive ) ) 00218 return true; 00219 00220 if ( contact.role().contains( filterString, Qt::CaseInsensitive ) ) 00221 return true; 00222 00223 if ( contact.organization().contains( filterString, Qt::CaseInsensitive ) ) 00224 return true; 00225 00226 if ( contact.department().contains( filterString, Qt::CaseInsensitive ) ) 00227 return true; 00228 00229 if ( contact.note().contains( filterString, Qt::CaseInsensitive ) ) 00230 return true; 00231 00232 if ( contact.url().url().contains( filterString, Qt::CaseInsensitive ) ) 00233 return true; 00234 00235 const QStringList customs = contact.customs(); 00236 count = customs.count(); 00237 for ( int i = 0; i < count; ++i ) { 00238 if ( customs.at( i ).contains( filterString, Qt::CaseInsensitive ) ) 00239 return true; 00240 } 00241 00242 return false; 00243 } 00244 00245 bool contactGroupMatchesFilter( const KABC::ContactGroup &group, const QString &filterString ) 00246 { 00247 if ( group.name().contains( filterString, Qt::CaseInsensitive ) ) 00248 return true; 00249 00250 const int count = group.dataCount(); 00251 for ( int i = 0; i < count; ++i ) { 00252 if ( group.data( i ).name().contains( filterString, Qt::CaseInsensitive ) ) 00253 return true; 00254 if ( group.data( i ).email().contains( filterString, Qt::CaseInsensitive ) ) 00255 return true; 00256 } 00257 00258 return false; 00259 } 00260 00261 #include "contactsfilterproxymodel.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:19:25 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 22:19:25 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.