00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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 QString mFilter;
00039 };
00040
00041 ContactsFilterProxyModel::ContactsFilterProxyModel( QObject *parent )
00042 : QSortFilterProxyModel( parent ), d( new Private )
00043 {
00044
00045 setSortLocaleAware( true );
00046 setDynamicSortFilter( true );
00047 }
00048
00049 ContactsFilterProxyModel::~ContactsFilterProxyModel()
00050 {
00051 delete d;
00052 }
00053
00054 void ContactsFilterProxyModel::setFilterString( const QString &filter )
00055 {
00056 d->mFilter = filter;
00057 invalidateFilter();
00058 }
00059
00060 bool ContactsFilterProxyModel::filterAcceptsRow( int row, const QModelIndex &parent ) const
00061 {
00062 if ( d->mFilter.isEmpty() )
00063 return true;
00064
00065 const QModelIndex index = sourceModel()->index( row, 0, parent );
00066
00067 const Akonadi::Item item = index.data( Akonadi::EntityTreeModel::ItemRole ).value<Akonadi::Item>();
00068
00069 if ( item.hasPayload<KABC::Addressee>() ) {
00070 const KABC::Addressee contact = item.payload<KABC::Addressee>();
00071 return contactMatchesFilter( contact, d->mFilter );
00072 } else if ( item.hasPayload<KABC::ContactGroup>() ) {
00073 const KABC::ContactGroup group = item.payload<KABC::ContactGroup>();
00074 return contactGroupMatchesFilter( group, d->mFilter );
00075 }
00076
00077 return true;
00078 }
00079
00080 bool ContactsFilterProxyModel::lessThan( const QModelIndex &leftIndex, const QModelIndex &rightIndex ) const
00081 {
00082 const QDate leftDate = leftIndex.data( ContactsTreeModel::DateRole ).toDate();
00083 const QDate rightDate = rightIndex.data( ContactsTreeModel::DateRole ).toDate();
00084
00085 if ( leftDate.isValid() && rightDate.isValid() ) {
00086 if ( leftDate.month() < rightDate.month() )
00087 return true;
00088 else if ( leftDate.month() == rightDate.month() )
00089 return (leftDate.day() < rightDate.day());
00090 else
00091 return false;
00092 }
00093
00094 return QSortFilterProxyModel::lessThan( leftIndex, rightIndex );
00095 }
00096
00097 static bool addressMatchesFilter( const KABC::Address &address, const QString &filterString )
00098 {
00099 if ( address.street().contains( filterString, Qt::CaseInsensitive ) )
00100 return true;
00101
00102 if ( address.locality().contains( filterString, Qt::CaseInsensitive ) )
00103 return true;
00104
00105 if ( address.region().contains( filterString, Qt::CaseInsensitive ) )
00106 return true;
00107
00108 if ( address.postalCode().contains( filterString, Qt::CaseInsensitive ) )
00109 return true;
00110
00111 if ( address.country().contains( filterString, Qt::CaseInsensitive ) )
00112 return true;
00113
00114 if ( address.label().contains( filterString, Qt::CaseInsensitive ) )
00115 return true;
00116
00117 if ( address.postOfficeBox().contains( filterString, Qt::CaseInsensitive ) )
00118 return true;
00119
00120 return false;
00121 }
00122
00123 static bool contactMatchesFilter( const KABC::Addressee &contact, const QString &filterString )
00124 {
00125 if ( contact.assembledName().contains( filterString, Qt::CaseInsensitive ) )
00126 return true;
00127
00128 if ( contact.formattedName().contains( filterString, Qt::CaseInsensitive ) )
00129 return true;
00130
00131 if ( contact.nickName().contains( filterString, Qt::CaseInsensitive ) )
00132 return true;
00133
00134 if ( contact.birthday().toString().contains( filterString, Qt::CaseInsensitive ) )
00135 return true;
00136
00137 const KABC::Address::List addresses = contact.addresses();
00138 int count = addresses.count();
00139 for ( int i = 0; i < count; ++i ) {
00140 if ( addressMatchesFilter( addresses.at( i ), filterString ) )
00141 return true;
00142 }
00143
00144 const KABC::PhoneNumber::List phoneNumbers = contact.phoneNumbers();
00145 count = phoneNumbers.count();
00146 for ( int i = 0; i < count; ++i ) {
00147 if ( phoneNumbers.at( i ).number().contains( filterString, Qt::CaseInsensitive ) )
00148 return true;
00149 }
00150
00151 const QStringList emails = contact.emails();
00152 count = emails.count();
00153 for ( int i = 0; i < count; ++i ) {
00154 if ( emails.at( i ).contains( filterString, Qt::CaseInsensitive ) )
00155 return true;
00156 }
00157
00158 if ( contact.mailer().contains( filterString, Qt::CaseInsensitive ) )
00159 return true;
00160
00161 if ( contact.title().contains( filterString, Qt::CaseInsensitive ) )
00162 return true;
00163
00164 if ( contact.role().contains( filterString, Qt::CaseInsensitive ) )
00165 return true;
00166
00167 if ( contact.organization().contains( filterString, Qt::CaseInsensitive ) )
00168 return true;
00169
00170 if ( contact.department().contains( filterString, Qt::CaseInsensitive ) )
00171 return true;
00172
00173 if ( contact.note().contains( filterString, Qt::CaseInsensitive ) )
00174 return true;
00175
00176 if ( contact.url().url().contains( filterString, Qt::CaseInsensitive ) )
00177 return true;
00178
00179 const QStringList customs = contact.customs();
00180 count = customs.count();
00181 for ( int i = 0; i < count; ++i ) {
00182 if ( customs.at( i ).contains( filterString, Qt::CaseInsensitive ) )
00183 return true;
00184 }
00185
00186 return false;
00187 }
00188
00189 bool contactGroupMatchesFilter( const KABC::ContactGroup &group, const QString &filterString )
00190 {
00191 if ( group.name().contains( filterString, Qt::CaseInsensitive ) )
00192 return true;
00193
00194 const int count = group.dataCount();
00195 for ( int i = 0; i < count; ++i ) {
00196 if ( group.data( i ).name().contains( filterString, Qt::CaseInsensitive ) )
00197 return true;
00198 if ( group.data( i ).email().contains( filterString, Qt::CaseInsensitive ) )
00199 return true;
00200 }
00201
00202 return false;
00203 }
00204
00205 #include "contactsfilterproxymodel.moc"