22 #include "contactgroupmodel_p.h"
24 #include <akonadi/itemfetchjob.h>
25 #include <akonadi/itemfetchscope.h>
26 #include <kabc/addressee.h>
28 #include <kiconloader.h>
31 using namespace Akonadi;
36 : loadingError( false )
41 KABC::ContactGroup::ContactReference reference;
42 KABC::ContactGroup::Data data;
43 KABC::Addressee referencedContact;
47 class ContactGroupModel::Private
50 Private( ContactGroupModel *parent )
55 void resolveContactReference(
const KABC::ContactGroup::ContactReference &reference,
int row )
57 const Item item( reference.uid().toLongLong() );
60 job->setProperty(
"row", row );
61 job->fetchScope().fetchFullPayload();
63 mParent->connect( job, SIGNAL(result(KJob*)), SLOT(itemFetched(KJob*)) );
66 void itemFetched( KJob *job )
68 const int row = job->property(
"row" ).toInt();
71 mMembers[ row ].loadingError =
true;
72 emit mParent->dataChanged( mParent->index( row, 0, QModelIndex() ), mParent->index( row, 1, QModelIndex() ) );
78 if ( fetchJob->
items().count() != 1 ) {
79 mMembers[ row ].loadingError =
true;
80 emit mParent->dataChanged( mParent->index( row, 0, QModelIndex() ), mParent->index( row, 1, QModelIndex() ) );
84 const Item item = fetchJob->
items().first();
85 const KABC::Addressee contact = item.
payload<KABC::Addressee>();
87 GroupMember &member = mMembers[ row ];
88 member.referencedContact = contact;
89 emit mParent->dataChanged( mParent->index( row, 0, QModelIndex() ), mParent->index( row, 1, QModelIndex() ) );
92 void normalizeMemberList()
95 bool needsNormalization =
false;
96 if ( mMembers.isEmpty() ) {
97 needsNormalization =
true;
99 for (
int i = 0; i < mMembers.count(); ++i ) {
100 const GroupMember &member = mMembers[ i ];
101 if ( !member.isReference && !(i == mMembers.count() - 1) ) {
102 if ( member.data.name().isEmpty() && member.data.email().isEmpty() ) {
103 needsNormalization =
true;
109 const GroupMember &member = mMembers.last();
110 if ( member.isReference || !(member.data.name().isEmpty() && member.data.email().isEmpty()) )
111 needsNormalization =
true;
115 if ( !needsNormalization )
118 bool foundEmpty =
false;
121 mParent->beginInsertRows( QModelIndex(), mMembers.count(), mMembers.count() );
123 member.isReference =
false;
124 mMembers.append( member );
125 mParent->endInsertRows();
130 for (
int i = 0; i < mMembers.count(); ++i ) {
131 const GroupMember &member = mMembers[ i ];
132 if ( !member.isReference && !(i == mMembers.count() - 1) ) {
133 if ( member.data.name().isEmpty() && member.data.email().isEmpty() ) {
134 mParent->beginRemoveRows( QModelIndex(), i, i );
135 mMembers.remove( i );
136 mParent->endRemoveRows();
142 }
while ( foundEmpty );
145 ContactGroupModel *mParent;
146 QVector<GroupMember> mMembers;
147 KABC::ContactGroup mGroup;
148 QString mLastErrorMessage;
151 ContactGroupModel::ContactGroupModel( QObject *parent )
152 : QAbstractItemModel( parent ), d( new Private( this ) )
156 ContactGroupModel::~ContactGroupModel()
161 void ContactGroupModel::loadContactGroup(
const KABC::ContactGroup &contactGroup )
163 emit layoutAboutToBeChanged();
166 d->mGroup = contactGroup;
168 for ( uint i = 0; i < d->mGroup.dataCount(); ++i ) {
169 const KABC::ContactGroup::Data data = d->mGroup.data( i );
171 member.isReference =
false;
174 d->mMembers.append( member );
177 for ( uint i = 0; i < d->mGroup.contactReferenceCount(); ++i ) {
178 const KABC::ContactGroup::ContactReference reference = d->mGroup.contactReference( i );
180 member.isReference =
true;
181 member.reference = reference;
183 d->mMembers.append( member );
185 d->resolveContactReference( reference, d->mMembers.count() - 1 );
188 d->normalizeMemberList();
190 emit layoutChanged();
193 bool ContactGroupModel::storeContactGroup( KABC::ContactGroup &group )
const
195 group.removeAllContactReferences();
196 group.removeAllContactData();
198 for (
int i = 0; i < d->mMembers.count(); ++i ) {
199 const GroupMember &member = d->mMembers[ i ];
200 if ( member.isReference )
201 group.append( member.reference );
203 if ( i != (d->mMembers.count() - 1) ) {
204 if ( member.data.email().isEmpty() ) {
205 d->mLastErrorMessage =
206 i18n(
"The member with name <b>%1</b> is missing an email address",
207 member.data.name() );
210 group.append( member.data );
218 QString ContactGroupModel::lastErrorMessage()
const
220 return d->mLastErrorMessage;
223 QModelIndex ContactGroupModel::index(
int row,
int col,
const QModelIndex& )
const
225 return createIndex( row, col, 0 );
228 QModelIndex ContactGroupModel::parent(
const QModelIndex& )
const
230 return QModelIndex();
233 QVariant ContactGroupModel::data(
const QModelIndex &index,
int role )
const
235 if ( !index.isValid() )
238 if ( index.row() < 0 || index.row() >= d->mMembers.count() )
241 if ( index.column() < 0 || index.column() > 1 )
244 const GroupMember &member = d->mMembers[ index.row() ];
246 if ( role == Qt::DisplayRole ) {
247 if ( member.loadingError ) {
248 if ( index.column() == 0 )
249 return i18n(
"Contact does not exist any more" );
254 if ( member.isReference ) {
255 if ( index.column() == 0 )
256 return member.referencedContact.realName();
258 if ( !member.reference.preferredEmail().isEmpty() )
259 return member.reference.preferredEmail();
261 return member.referencedContact.preferredEmail();
264 if ( index.column() == 0 )
265 return member.data.name();
267 return member.data.email();
271 if ( role == Qt::DecorationRole ) {
272 if ( index.column() == 1 )
275 if ( member.loadingError )
276 return KIcon( QLatin1String(
"emblem-important" ) );
278 if ( index.row() == (d->mMembers.count() - 1) )
279 return KIcon( QLatin1String(
"contact-new" ) );
281 if ( member.isReference ) {
282 return KIcon( QLatin1String(
"x-office-contact" ), KIconLoader::global(),
283 QStringList() << QLatin1String(
"emblem-symbolic-link" ) );
285 return KIcon( QLatin1String(
"x-office-contact" ) );
289 if ( role == Qt::EditRole ) {
290 if ( member.isReference ) {
291 if ( index.column() == 0 )
292 return member.referencedContact.realName();
294 if ( !member.reference.preferredEmail().isEmpty() )
295 return member.reference.preferredEmail();
297 return member.referencedContact.preferredEmail();
300 if ( index.column() == 0 )
301 return member.data.name();
303 return member.data.email();
307 if ( role == IsReferenceRole )
308 return member.isReference;
310 if ( role == AllEmailsRole ) {
311 if ( member.isReference )
312 return member.referencedContact.emails();
314 return QStringList();
320 bool ContactGroupModel::setData(
const QModelIndex &index,
const QVariant &value,
int role )
322 if ( !index.isValid() )
325 if ( index.row() < 0 || index.row() >= d->mMembers.count() )
328 if ( index.column() < 0 || index.column() > 1 )
331 GroupMember &member = d->mMembers[ index.row() ];
333 if ( role == Qt::EditRole ) {
334 if ( member.isReference ) {
335 if ( index.column() == 0 ) {
336 member.reference.setUid( QString::number( value.toLongLong() ) );
337 d->resolveContactReference( member.reference, index.row() );
339 if ( index.column() == 1 ) {
340 const QString email = value.toString();
341 if ( email != member.referencedContact.preferredEmail() ) {
342 member.reference.setPreferredEmail( email );
344 member.reference.setPreferredEmail( QString() );
348 if ( index.column() == 0 )
349 member.data.setName( value.toString() );
351 member.data.setEmail( value.toString() );
354 d->normalizeMemberList();
359 if ( role == IsReferenceRole ) {
360 if ( (value.toBool() ==
true) && !member.isReference ) {
361 member.isReference =
true;
363 if ( (value.toBool() ==
false) && member.isReference ) {
364 member.isReference =
false;
365 member.data.setName( member.referencedContact.realName() );
366 member.data.setEmail( member.referencedContact.preferredEmail() );
375 QVariant ContactGroupModel::headerData(
int section, Qt::Orientation orientation,
int role )
const
377 if ( section < 0 || section > 1 )
380 if ( orientation != Qt::Horizontal )
383 if ( role != Qt::DisplayRole )
387 return i18nc(
"contact's name",
"Name" );
389 return i18nc(
"contact's email address",
"EMail" );
392 Qt::ItemFlags ContactGroupModel::flags(
const QModelIndex &index )
const
394 if ( !index.isValid() || index.row() < 0 || index.row() >= d->mMembers.count() )
395 return Qt::ItemIsEnabled;
397 if ( d->mMembers[ index.row() ].loadingError )
398 return Qt::ItemFlags( Qt::ItemIsEnabled );
400 Qt::ItemFlags parentFlags = QAbstractItemModel::flags( index );
401 return (parentFlags | Qt::ItemIsEnabled | Qt::ItemIsEditable);
404 int ContactGroupModel::columnCount(
const QModelIndex &parent )
const
406 if ( !parent.isValid() )
412 int ContactGroupModel::rowCount(
const QModelIndex &parent )
const
414 if ( !parent.isValid() )
415 return d->mMembers.count();
420 bool ContactGroupModel::removeRows(
int row,
int count,
const QModelIndex &parent )
422 if ( parent.isValid() )
425 beginRemoveRows( QModelIndex(), row, row + count - 1 );
426 for (
int i = 0; i < count; ++i )
427 d->mMembers.remove( row );
433 #include "contactgroupmodel_p.moc"