22 #include "contactsfilterproxymodel.h"
24 #include "contactstreemodel.h"
26 #include <akonadi/entitytreemodel.h>
27 #include <kabc/addressee.h>
28 #include <kabc/contactgroup.h>
30 static bool contactMatchesFilter(
const KABC::Addressee &contact,
const QString &filterString );
31 static bool contactGroupMatchesFilter(
const KABC::ContactGroup &group,
const QString &filterString );
33 using namespace Akonadi;
35 class ContactsFilterProxyModel::Private
40 mExcludeVirtualCollections( false )
44 ContactsFilterProxyModel::FilterFlags flags;
45 bool mExcludeVirtualCollections;
48 ContactsFilterProxyModel::ContactsFilterProxyModel( QObject *parent )
49 : QSortFilterProxyModel( parent ), d( new Private )
52 setSortLocaleAware(
true );
53 setDynamicSortFilter(
true );
56 ContactsFilterProxyModel::~ContactsFilterProxyModel()
61 void ContactsFilterProxyModel::setFilterString(
const QString &filter )
67 bool ContactsFilterProxyModel::filterAcceptsRow(
int row,
const QModelIndex &parent )
const
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())
76 if ( ( d->mFilter.isEmpty() ) && ( !( d->flags & ContactsFilterProxyModel::HasEmail ) ))
79 const Akonadi::Item item = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
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() )
87 if ( !d->mFilter.isEmpty() ) {
88 return contactMatchesFilter( contact, d->mFilter );
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 );
102 bool ContactsFilterProxyModel::lessThan(
const QModelIndex &leftIndex,
const QModelIndex &rightIndex )
const
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() )
109 else if(leftDate.year() == rightDate.year()) {
110 if ( leftDate.month() < rightDate.month() )
112 else if ( leftDate.month() == rightDate.month() )
113 return (leftDate.day() < rightDate.day());
119 return QSortFilterProxyModel::lessThan( leftIndex, rightIndex );
122 void ContactsFilterProxyModel::setFilterFlags( ContactsFilterProxyModel::FilterFlags flags )
127 void ContactsFilterProxyModel::setExcludeVirtualCollections(
bool exclude )
129 if ( exclude != d->mExcludeVirtualCollections ) {
130 d->mExcludeVirtualCollections = exclude;
135 Qt::ItemFlags ContactsFilterProxyModel::flags(
const QModelIndex& index )
const
137 if ( !index.isValid() ) {
141 const Akonadi::Collection collection = index.data(Akonadi::EntityTreeModel::CollectionRole).value<Akonadi::Collection>();
142 if ( collection.isValid() )
144 return QSortFilterProxyModel::flags( index ) & ~( Qt::ItemIsSelectable );
146 return QSortFilterProxyModel::flags( index );
149 static bool addressMatchesFilter(
const KABC::Address &address,
const QString &filterString )
151 if ( address.street().contains( filterString, Qt::CaseInsensitive ) )
154 if ( address.locality().contains( filterString, Qt::CaseInsensitive ) )
157 if ( address.region().contains( filterString, Qt::CaseInsensitive ) )
160 if ( address.postalCode().contains( filterString, Qt::CaseInsensitive ) )
163 if ( address.country().contains( filterString, Qt::CaseInsensitive ) )
166 if ( address.label().contains( filterString, Qt::CaseInsensitive ) )
169 if ( address.postOfficeBox().contains( filterString, Qt::CaseInsensitive ) )
175 static bool contactMatchesFilter(
const KABC::Addressee &contact,
const QString &filterString )
177 if ( contact.assembledName().contains( filterString, Qt::CaseInsensitive ) )
180 if ( contact.formattedName().contains( filterString, Qt::CaseInsensitive ) )
183 if ( contact.nickName().contains( filterString, Qt::CaseInsensitive ) )
186 if ( contact.birthday().toString().contains( filterString, Qt::CaseInsensitive ) )
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 ) )
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 ) )
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 ) )
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 ) )
217 if ( contact.mailer().contains( filterString, Qt::CaseInsensitive ) )
220 if ( contact.title().contains( filterString, Qt::CaseInsensitive ) )
223 if ( contact.role().contains( filterString, Qt::CaseInsensitive ) )
226 if ( contact.organization().contains( filterString, Qt::CaseInsensitive ) )
229 if ( contact.department().contains( filterString, Qt::CaseInsensitive ) )
232 if ( contact.note().contains( filterString, Qt::CaseInsensitive ) )
235 if ( contact.url().url().contains( filterString, Qt::CaseInsensitive ) )
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 ) )
248 bool contactGroupMatchesFilter(
const KABC::ContactGroup &group,
const QString &filterString )
250 if ( group.name().contains( filterString, Qt::CaseInsensitive ) )
253 const int count = group.dataCount();
254 for (
int i = 0; i < count; ++i ) {
255 if ( group.data( i ).name().contains( filterString, Qt::CaseInsensitive ) )
257 if ( group.data( i ).email().contains( filterString, Qt::CaseInsensitive ) )
264 #include "contactsfilterproxymodel.moc"