akonadi
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 Mon Aug 27 2012 22:09:21 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Mon Aug 27 2012 22:09:21 by doxygen 1.7.5 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.