9#include "contactgroupmodel_p.h"
11#include <Akonadi/ItemFetchJob>
12#include <Akonadi/ItemFetchScope>
13#include <KContacts/Addressee>
16#include <KLocalizedString>
22 KContacts::ContactGroup::ContactReference reference;
23 KContacts::ContactGroup::Data data;
24 KContacts::Addressee referencedContact;
25 bool isReference =
false;
26 bool loadingError =
false;
29class Akonadi::ContactGroupModelPrivate
32 ContactGroupModelPrivate(ContactGroupModel *parent)
37 void resolveContactReference(
const KContacts::ContactGroup::ContactReference &reference,
int row)
41 item.setGid(reference.
gid());
45 auto job =
new ItemFetchJob(item, mParent);
46 job->setProperty(
"row", row);
47 job->fetchScope().fetchFullPayload();
54 void itemFetched(KJob *job)
59 mMembers[row].loadingError =
true;
60 Q_EMIT mParent->dataChanged(mParent->index(row, 0, QModelIndex()), mParent->index(row, 1, QModelIndex()));
64 auto fetchJob = qobject_cast<ItemFetchJob *>(job);
66 if (fetchJob->items().count() != 1) {
67 mMembers[row].loadingError =
true;
68 Q_EMIT mParent->dataChanged(mParent->index(row, 0, QModelIndex()), mParent->index(row, 1, QModelIndex()));
72 const Item item = fetchJob->items().at(0);
73 const auto contact = item.payload<KContacts::Addressee>();
75 GroupMember &member = mMembers[row];
76 member.referencedContact = contact;
77 Q_EMIT mParent->dataChanged(mParent->index(row, 0, QModelIndex()), mParent->index(row, 1, QModelIndex()));
80 void normalizeMemberList()
83 bool needsNormalization =
false;
84 if (mMembers.isEmpty()) {
85 needsNormalization =
true;
87 for (
int i = 0; i < mMembers.count(); ++i) {
88 const GroupMember &member = mMembers[i];
89 if (!member.isReference && !(i == mMembers.count() - 1)) {
91 needsNormalization =
true;
97 const GroupMember &member = mMembers.last();
99 needsNormalization =
true;
104 if (!needsNormalization) {
108 bool foundEmpty =
false;
111 mParent->beginInsertRows(QModelIndex(), mMembers.count(), mMembers.count());
113 member.isReference =
false;
114 mMembers.append(member);
115 mParent->endInsertRows();
120 for (
int i = 0, total = mMembers.count(); i < total; ++i) {
121 const GroupMember &member = mMembers[i];
122 if (!member.isReference && !(i == mMembers.count() - 1)) {
124 mParent->beginRemoveRows(QModelIndex(), i, i);
126 mParent->endRemoveRows();
132 }
while (foundEmpty);
135 ContactGroupModel *
const mParent;
136 QList<GroupMember> mMembers;
137 KContacts::ContactGroup mGroup;
138 QString mLastErrorMessage;
141ContactGroupModel::ContactGroupModel(
QObject *parent)
143 , d(new ContactGroupModelPrivate(this))
147ContactGroupModel::~ContactGroupModel() =
default;
151 Q_EMIT layoutAboutToBeChanged();
154 d->mGroup = contactGroup;
156 for (
int i = 0; i < d->mGroup.dataCount(); ++i) {
159 member.isReference =
false;
162 d->mMembers.append(member);
165 for (
int i = 0; i < d->mGroup.contactReferenceCount(); ++i) {
168 member.isReference =
true;
169 member.reference = reference;
171 d->mMembers.append(member);
173 d->resolveContactReference(reference, d->mMembers.count() - 1);
176 d->normalizeMemberList();
178 Q_EMIT layoutChanged();
186 for (
int i = 0; i < d->mMembers.count(); ++i) {
187 const GroupMember &member = d->mMembers[i];
188 if (member.isReference) {
189 group.
append(member.reference);
191 if (i != (d->mMembers.count() - 1)) {
193 d->mLastErrorMessage =
i18n(
"The member with name <b>%1</b> is missing an email address", member.data.
name());
196 group.
append(member.data);
204QString ContactGroupModel::lastErrorMessage()
const
206 return d->mLastErrorMessage;
212 return createIndex(row, col);
227 if (index.
row() < 0 || index.
row() >= d->mMembers.count()) {
235 const GroupMember &member = d->mMembers[index.
row()];
238 if (member.loadingError) {
239 if (index.
column() == 0) {
240 return i18n(
"Contact does not exist any more");
246 if (member.isReference) {
247 if (index.
column() == 0) {
248 return member.referencedContact.
realName();
257 if (index.
column() == 0) {
258 return member.data.
name();
260 return member.data.
email();
266 if (index.
column() == 1) {
270 if (member.loadingError) {
274 if (index.
row() == (d->mMembers.count() - 1)) {
278 if (member.isReference) {
286 if (member.isReference) {
287 if (index.
column() == 0) {
288 return member.referencedContact.
realName();
297 if (index.
column() == 0) {
298 return member.data.
name();
300 return member.data.
email();
305 if (role == IsReferenceRole) {
306 return member.isReference;
309 if (role == AllEmailsRole) {
310 if (member.isReference) {
311 return member.referencedContact.
emails();
326 if (index.
row() < 0 || index.
row() >= d->mMembers.count()) {
334 GroupMember &member = d->mMembers[index.
row()];
337 if (member.isReference) {
338 if (index.
column() == 0) {
340 d->resolveContactReference(member.reference, index.
row());
342 if (index.
column() == 1) {
351 if (index.
column() == 0) {
358 d->normalizeMemberList();
363 if (role == IsReferenceRole) {
364 if ((value.
toBool() ==
true) && !member.isReference) {
365 member.isReference =
true;
367 if ((value.
toBool() ==
false) && member.isReference) {
368 member.isReference =
false;
381 if (section < 0 || section > 1) {
394 return i18nc(
"contact's name",
"Name");
396 return i18nc(
"contact's email address",
"EMail");
402 if (!index.
isValid() || index.
row() < 0 || index.
row() >= d->mMembers.count()) {
406 if (d->mMembers[index.
row()].loadingError) {
414int ContactGroupModel::columnCount(
const QModelIndex &parent)
const
423int ContactGroupModel::rowCount(
const QModelIndex &parent)
const
426 return d->mMembers.count();
432bool ContactGroupModel::removeRows(
int row,
int count,
const QModelIndex &parent)
438 beginRemoveRows(
QModelIndex(), row, row + count - 1);
439 for (
int i = 0; i < count; ++i) {
440 d->mMembers.remove(row);
447GroupFilterModel::GroupFilterModel(
QObject *parent)
451 setFilterKeyColumn(-1);
454bool GroupFilterModel::filterAcceptsRow(
int sourceRow,
const QModelIndex &sourceParent)
const
456 if (sourceRow == sourceModel()->rowCount() - 1) {
465 if (
left.row() == sourceModel()->rowCount() - 1) {
469 if (
right.row() == sourceModel()->rowCount() - 1) {
476#include "moc_contactgroupmodel_p.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
A widget for editing the display name of a contact.
QIcon addOverlays(const QIcon &icon, const QHash< Qt::Corner, QIcon > &overlays)
virtual Qt::ItemFlags flags(const QModelIndex &index) const const
QIcon fromTheme(const QString &name)
bool isValid() const const
QVariant property(const char *name) const const
virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const const
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
qlonglong toLongLong(bool *ok, int base) const const
QTextStream & left(QTextStream &stream)
QTextStream & right(QTextStream &stream)
bool toBool() const const
int toInt(bool *ok) const const
qlonglong toLongLong(bool *ok) const const
QString toString() const const