~chris.gagnon/+junk/qtpim-coverage

« back to all changes in this revision

Viewing changes to src/imports/contacts/qdeclarativecontactrelationshipmodel.cpp

  • Committer: chris.gagnon
  • Date: 2013-12-10 23:09:37 UTC
  • Revision ID: chris.gagnon@canonical.com-20131210230937-2akf1ft1edcttk87
first post

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
 
4
** Contact: http://www.qt-project.org/legal
 
5
**
 
6
** This file is part of the QtQml module of the Qt Toolkit.
 
7
**
 
8
** $QT_BEGIN_LICENSE:LGPL$
 
9
** Commercial License Usage
 
10
** Licensees holding valid commercial Qt licenses may use this file in
 
11
** accordance with the commercial license agreement provided with the
 
12
** Software or, alternatively, in accordance with the terms contained in
 
13
** a written agreement between you and Digia.  For licensing terms and
 
14
** conditions see http://qt.digia.com/licensing.  For further information
 
15
** use the contact form at http://qt.digia.com/contact-us.
 
16
**
 
17
** GNU Lesser General Public License Usage
 
18
** Alternatively, this file may be used under the terms of the GNU Lesser
 
19
** General Public License version 2.1 as published by the Free Software
 
20
** Foundation and appearing in the file LICENSE.LGPL included in the
 
21
** packaging of this file.  Please review the following information to
 
22
** ensure the GNU Lesser General Public License version 2.1 requirements
 
23
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 
24
**
 
25
** In addition, as a special exception, Digia gives you certain additional
 
26
** rights.  These rights are described in the Digia Qt LGPL Exception
 
27
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
 
28
**
 
29
** GNU General Public License Usage
 
30
** Alternatively, this file may be used under the terms of the GNU
 
31
** General Public License version 3.0 as published by the Free Software
 
32
** Foundation and appearing in the file LICENSE.GPL included in the
 
33
** packaging of this file.  Please review the following information to
 
34
** ensure the GNU General Public License version 3.0 requirements will be
 
35
** met: http://www.gnu.org/copyleft/gpl.html.
 
36
**
 
37
**
 
38
** $QT_END_LICENSE$
 
39
**
 
40
****************************************************************************/
 
41
#include <QtQml/qqmlinfo.h>
 
42
#include "qdeclarativecontactrelationshipmodel_p.h"
 
43
#include "qcontactmanager.h"
 
44
#include "qcontactrequests.h"
 
45
 
 
46
#include <QPixmap>
 
47
 
 
48
QT_BEGIN_NAMESPACE_CONTACTS
 
49
 
 
50
/*!
 
51
   \qmltype RelationshipModel
 
52
    \instantiates QDeclarativeContactRelationshipModel
 
53
   \brief The RelationshipModel provides a model of contact relationships from the contacts store.
 
54
 
 
55
   \ingroup qml-contacts-main
 
56
   \inqmlmodule QtContacts 5.0
 
57
 
 
58
   This element is part of the \b{QtContacts} module.
 
59
 
 
60
    The contents of the model can be specified with \l participantId, \l role and \l relationshipType properties.
 
61
    Whether the model is automatically updated when the store or filter changes, can be controlled
 
62
    with \l RelationshipModel::autoUpdate property.
 
63
 
 
64
    There are two ways of accessing the relationship data: through model by using views and delegates,
 
65
    or alternatively via \l relationships list property.
 
66
 
 
67
    At the moment only data role provided by the model is \c relationship (\l Relationship).
 
68
    Through that one can access any data provided by the Relationship element.
 
69
 
 
70
   \sa Relationship, {QContactRelationship}
 
71
 */
 
72
 
 
73
class QDeclarativeContactRelationshipModelPrivate
 
74
{
 
75
public:
 
76
    QDeclarativeContactRelationshipModelPrivate()
 
77
        : m_manager(0)
 
78
        , m_participant(0)
 
79
        , m_role(QDeclarativeContactRelationship::Either)
 
80
    {
 
81
    }
 
82
 
 
83
    ~QDeclarativeContactRelationshipModelPrivate()
 
84
    {
 
85
        delete m_manager;
 
86
    }
 
87
 
 
88
    QContactManager *m_manager;
 
89
    QDeclarativeContactRelationship m_relationshipTypeHolder;
 
90
    QDeclarativeContact* m_participant;
 
91
    QDeclarativeContactRelationship::RelationshipRole m_role;
 
92
    QList<QContactRelationship> m_relationships;
 
93
    QList<QDeclarativeContactRelationship *> m_declarativeRelationships;
 
94
};
 
95
 
 
96
QDeclarativeContactRelationshipModel::QDeclarativeContactRelationshipModel(QObject *parent)
 
97
    : QAbstractListModel(parent)
 
98
    , d(new QDeclarativeContactRelationshipModelPrivate)
 
99
{
 
100
    QHash<int, QByteArray> roleNames;
 
101
    roleNames = QAbstractItemModel::roleNames();
 
102
    roleNames.insert(RelationshipRole, "relationship");
 
103
    setRoleNames(roleNames);
 
104
    connect(this, SIGNAL(managerChanged()), SLOT(fetchAgain()));
 
105
    connect(this, SIGNAL(participantChanged()), SLOT(fetchAgain()));
 
106
    connect(this, SIGNAL(relationshipTypeChanged()), SLOT(fetchAgain()));
 
107
    connect(this, SIGNAL(roleChanged()), SLOT(fetchAgain()));
 
108
}
 
109
 
 
110
QDeclarativeContactRelationshipModel::~QDeclarativeContactRelationshipModel()
 
111
{
 
112
    delete d;
 
113
}
 
114
 
 
115
/*!
 
116
  \qmlproperty string RelationshipModel::manager
 
117
 
 
118
  This property holds the manager uri of the contact backend engine.
 
119
  */
 
120
QString QDeclarativeContactRelationshipModel::manager() const
 
121
{
 
122
    if (d->m_manager)
 
123
        return d->m_manager->managerName();
 
124
    return QString();
 
125
}
 
126
 
 
127
 
 
128
/*!
 
129
  \qmlproperty string RelationshipModel::error
 
130
 
 
131
  This property holds the latest error code returned by the contact manager.
 
132
 
 
133
  This property is read only.
 
134
  */
 
135
QString QDeclarativeContactRelationshipModel::error() const
 
136
{
 
137
    switch (d->m_manager->error()) {
 
138
    case QContactManager::DoesNotExistError:
 
139
        return QStringLiteral("DoesNotExist");
 
140
    case QContactManager::AlreadyExistsError:
 
141
        return QStringLiteral("AlreadyExists");
 
142
    case QContactManager::InvalidDetailError:
 
143
        return QStringLiteral("InvalidDetail");
 
144
    case QContactManager::InvalidRelationshipError:
 
145
        return QStringLiteral("InvalidRelationship");
 
146
    case QContactManager::LockedError:
 
147
        return QStringLiteral("LockedError");
 
148
    case QContactManager::DetailAccessError:
 
149
        return QStringLiteral("DetailAccessError");
 
150
    case QContactManager::PermissionsError:
 
151
        return QStringLiteral("PermissionsError");
 
152
    case QContactManager::OutOfMemoryError:
 
153
        return QStringLiteral("OutOfMemory");
 
154
    case QContactManager::NotSupportedError:
 
155
        return QStringLiteral("NotSupported");
 
156
    case QContactManager::BadArgumentError:
 
157
        return QStringLiteral("BadArgument");
 
158
    case QContactManager::UnspecifiedError:
 
159
        return QStringLiteral("UnspecifiedError");
 
160
    case QContactManager::VersionMismatchError:
 
161
        return QStringLiteral("VersionMismatch");
 
162
    case QContactManager::LimitReachedError:
 
163
        return QStringLiteral("LimitReached");
 
164
    case QContactManager::InvalidContactTypeError:
 
165
        return QStringLiteral("InvalidContactType");
 
166
    default:
 
167
        break;
 
168
    }
 
169
    return QStringLiteral("NoError");
 
170
}
 
171
void QDeclarativeContactRelationshipModel::setManager(const QString& manager)
 
172
{
 
173
    if (d->m_manager == 0 || manager != d->m_manager->managerName() ) {
 
174
        d->m_manager = new QContactManager(manager,QMap<QString,QString>(), this);
 
175
        connect(d->m_manager,SIGNAL(relationshipsAdded(const QList<QContactId>&)), this, SLOT(fetchAgain()));
 
176
        connect(d->m_manager,SIGNAL(relationshipsRemoved(const QList<QContactId>&)), this, SLOT(fetchAgain()));
 
177
        emit managerChanged();
 
178
    }
 
179
}
 
180
 
 
181
 
 
182
/*!
 
183
  \qmlproperty int RelationshipModel::participantId
 
184
 
 
185
  This property holds the participant which the list of relationships returned by RelationshipModel should contain.
 
186
 
 
187
  \sa RelationshipFilter::relatedContactId
 
188
  \sa RelationshipModel::role
 
189
  */
 
190
QDeclarativeContact* QDeclarativeContactRelationshipModel::participant() const
 
191
{
 
192
    return d->m_participant;
 
193
}
 
194
void QDeclarativeContactRelationshipModel::setParticipant(QDeclarativeContact* participant)
 
195
{
 
196
    if (d->m_participant != participant) {
 
197
        d->m_participant = participant;
 
198
        emit participantChanged();
 
199
    }
 
200
}
 
201
 
 
202
/*!
 
203
  \qmlproperty variant RelationshipModel::relationshipType
 
204
 
 
205
  This property holds the relationship type which the list of relationships returned by RelationshipModel should contain.
 
206
 
 
207
  \sa Relationship::type
 
208
  */
 
209
QVariant QDeclarativeContactRelationshipModel::relationshipType() const
 
210
{
 
211
    return d->m_relationshipTypeHolder.relationshipType();
 
212
}
 
213
void QDeclarativeContactRelationshipModel::setRelationshipType(const QVariant& type)
 
214
{
 
215
    if (type != relationshipType()) {
 
216
        d->m_relationshipTypeHolder.setRelationshipType(type);
 
217
        emit relationshipTypeChanged();
 
218
    }
 
219
}
 
220
 
 
221
/*!
 
222
  \qmlproperty enumeration RelationshipModel::role
 
223
 
 
224
  This property holds the relationship role which the list of relationships returned by RelationshipModel should contain.
 
225
 
 
226
  \sa RelationshipFilter::relatedContactRole
 
227
  */
 
228
QDeclarativeContactRelationship::RelationshipRole QDeclarativeContactRelationshipModel::role() const
 
229
{
 
230
    return d->m_role;
 
231
}
 
232
void QDeclarativeContactRelationshipModel::setRole(QDeclarativeContactRelationship::RelationshipRole role)
 
233
{
 
234
    if (d->m_role != role) {
 
235
        d->m_role = role;
 
236
        emit roleChanged();
 
237
    }
 
238
}
 
239
 
 
240
/*!
 
241
  \qmlproperty bool RelationshipModel::autoUpdate
 
242
 
 
243
  This property indicates whether or not the relationship model should be updated automatically, default value is true.
 
244
  */
 
245
bool QDeclarativeContactRelationshipModel::autoUpdate() const
 
246
{
 
247
    //TODO
 
248
    return true;
 
249
}
 
250
void QDeclarativeContactRelationshipModel::setAutoUpdate(bool autoUpdate)
 
251
{
 
252
    Q_UNUSED(autoUpdate);
 
253
    //TODO
 
254
}
 
255
 
 
256
/*!
 
257
  \qmlproperty list<Relationship> RelationshipModel::relationships
 
258
 
 
259
  This property holds a list of relationships.
 
260
 
 
261
  \sa Relationship
 
262
  */
 
263
QQmlListProperty<QDeclarativeContactRelationship> QDeclarativeContactRelationshipModel::relationships()
 
264
{
 
265
    return QQmlListProperty<QDeclarativeContactRelationship>(this, d->m_declarativeRelationships);
 
266
}
 
267
 
 
268
int QDeclarativeContactRelationshipModel::rowCount(const QModelIndex &parent) const
 
269
{
 
270
    Q_UNUSED(parent);
 
271
    return d->m_declarativeRelationships.count();
 
272
}
 
273
 
 
274
QVariant QDeclarativeContactRelationshipModel::data(const QModelIndex &index, int role) const
 
275
{
 
276
    QDeclarativeContactRelationship* dcr = d->m_declarativeRelationships.value(index.row());
 
277
    if (role == RelationshipRole) {
 
278
        return QVariant::fromValue(dcr);
 
279
    } else if (role == Qt::DisplayRole) {
 
280
        return QString(QStringLiteral("%1 %2 %3")).arg(dcr->relationship().first().id().toString()).arg(dcr->relationship().relationshipType()).arg(dcr->relationship().second().id().toString());
 
281
    }
 
282
    return QVariant();
 
283
}
 
284
 
 
285
void QDeclarativeContactRelationshipModel::fetchAgain()
 
286
{
 
287
    if (d->m_manager) {
 
288
        QContactRelationshipFetchRequest* req = new QContactRelationshipFetchRequest(this);
 
289
        req->setManager(d->m_manager);
 
290
        if (d->m_participant) {
 
291
            QContact contact (d->m_participant->contact());
 
292
            if (d->m_role == QDeclarativeContactRelationship::First || d->m_role == QDeclarativeContactRelationship::Either)
 
293
                req->setFirst(contact);
 
294
            if (d->m_role == QDeclarativeContactRelationship::Second || d->m_role == QDeclarativeContactRelationship::Either)
 
295
                req->setSecond(contact);
 
296
            req->setRelationshipType(d->m_relationshipTypeHolder.relationship().relationshipType());
 
297
            connect(req,SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(requestUpdated()));
 
298
            req->start();
 
299
        }
 
300
    }
 
301
}
 
302
 
 
303
/*!
 
304
  \qmlmethod RelationshipModel::addRelationship(relationship)
 
305
  Addes the given \a relationship to the backend store.
 
306
  */
 
307
void QDeclarativeContactRelationshipModel::addRelationship(QDeclarativeContactRelationship* dcr)
 
308
{
 
309
    if (dcr) {
 
310
        QContactRelationship cr = dcr->relationship();
 
311
        QContactRelationshipSaveRequest* req = new QContactRelationshipSaveRequest(this);
 
312
        req->setManager(d->m_manager);
 
313
        req->setRelationship(cr);
 
314
        connect(req, SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(relationshipsSaved()));
 
315
        req->start();
 
316
    }
 
317
}
 
318
 
 
319
/*!
 
320
  \qmlmethod RelationshipModel::removeRelationship(relationship)
 
321
  Removes the given \a relationship from the backend store.
 
322
  */
 
323
void QDeclarativeContactRelationshipModel::removeRelationship(QDeclarativeContactRelationship* dcr)
 
324
{
 
325
    if (dcr) {
 
326
        QContactRelationship cr = dcr->relationship();
 
327
        QContactRelationshipRemoveRequest* req = new QContactRelationshipRemoveRequest(this);
 
328
        req->setManager(d->m_manager);
 
329
        req->setRelationship(cr);
 
330
        connect(req,SIGNAL(stateChanged(QContactAbstractRequest::State)), this, SLOT(relationshipsRemoved()));
 
331
        req->start();
 
332
    }
 
333
}
 
334
 
 
335
void QDeclarativeContactRelationshipModel::requestUpdated()
 
336
{
 
337
    QContactRelationshipFetchRequest* req = qobject_cast<QContactRelationshipFetchRequest*>(sender());
 
338
    if (req->isFinished() && req->error() == QContactManager::NoError) {
 
339
 
 
340
        QList<QContactRelationship> relationships = req->relationships();
 
341
 
 
342
        reset();
 
343
        beginInsertRows(QModelIndex(), 0, relationships.count());
 
344
 
 
345
        foreach(QDeclarativeContactRelationship* dcr, d->m_declarativeRelationships) {
 
346
            dcr->deleteLater();
 
347
        }
 
348
        d->m_declarativeRelationships.clear();
 
349
        d->m_relationships.clear();
 
350
 
 
351
        foreach (const QContactRelationship& cr, relationships) {
 
352
            QDeclarativeContactRelationship* dcr = new QDeclarativeContactRelationship(this);
 
353
            dcr->setRelationship(cr);
 
354
            d->m_declarativeRelationships.append(dcr);
 
355
            d->m_relationships.append(cr);
 
356
        }
 
357
        endInsertRows();
 
358
        req->deleteLater();
 
359
        emit relationshipsChanged();
 
360
    }
 
361
}
 
362
 
 
363
void QDeclarativeContactRelationshipModel::relationshipsSaved()
 
364
{
 
365
    QContactRelationshipSaveRequest* req = qobject_cast<QContactRelationshipSaveRequest*>(sender());
 
366
 
 
367
    if (req->isFinished()) {
 
368
        QList<QContactRelationship> rs = req->relationships();
 
369
        QList<int> errorIds = req->errorMap().keys();
 
370
 
 
371
        for( int i = 0; i < rs.count(); i++) {
 
372
            if (!errorIds.contains(i)) {
 
373
                //saved
 
374
                QContactRelationship r = rs.at(i);
 
375
 
 
376
                if (!d->m_relationships.contains(r)) {
 
377
                    //new relationship saved
 
378
                    QDeclarativeContactRelationship* dcr = new QDeclarativeContactRelationship(this);
 
379
                    dcr->setRelationship(r);
 
380
                    beginInsertRows(QModelIndex(), d->m_declarativeRelationships.count(), d->m_declarativeRelationships.count());
 
381
                    d->m_declarativeRelationships.append(dcr);
 
382
                    d->m_relationships.append(r);
 
383
                    endInsertRows();
 
384
                }
 
385
            }
 
386
        }
 
387
        req->deleteLater();
 
388
    }
 
389
}
 
390
 
 
391
void QDeclarativeContactRelationshipModel::relationshipsRemoved()
 
392
{
 
393
    QContactRelationshipRemoveRequest* req = qobject_cast<QContactRelationshipRemoveRequest*>(sender());
 
394
 
 
395
    if (req->isFinished()) {
 
396
        QList<QContactRelationship> rs = req->relationships();
 
397
        QList<int> errorIds = req->errorMap().keys();
 
398
 
 
399
 
 
400
        for( int i = 0; i < rs.count(); i++) {
 
401
            if (!errorIds.contains(i)) {
 
402
                int row = 0;
 
403
                QContactRelationship r = rs.at(i);
 
404
                for (; row < d->m_relationships.count(); row++) {
 
405
                    if (d->m_relationships.at(row) == r)
 
406
                        break;
 
407
                }
 
408
                if (row < d->m_relationships.count()) {
 
409
                    beginRemoveRows(QModelIndex(), row, row);
 
410
                    d->m_declarativeRelationships.removeAt(row);
 
411
                    d->m_relationships.removeAt(row);
 
412
                    endRemoveRows();
 
413
                } else {
 
414
                    //impossible?
 
415
                    qmlInfo(this) << tr("this relationship '") << row << tr("' was already removed!");
 
416
                }
 
417
            }
 
418
        }
 
419
        req->deleteLater();
 
420
    }
 
421
}
 
422
 
 
423
#include "moc_qdeclarativecontactrelationshipmodel_p.cpp"
 
424
 
 
425
QT_END_NAMESPACE_CONTACTS