Skip to content

Commit

Permalink
[qtcontacts-sqlite] Add an extension for querying unique details inde…
Browse files Browse the repository at this point in the history
…penently of a contact. Contributes to JB#47219

This may be used to provide data-entry suggestions based on existing
contacts.
  • Loading branch information
adenexter committed Oct 25, 2019
1 parent d807043 commit 22f1ce4
Show file tree
Hide file tree
Showing 10 changed files with 747 additions and 54 deletions.
333 changes: 290 additions & 43 deletions src/engine/contactreader.cpp

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion src/engine/contactreader.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Jolla Ltd. <andrew.den.exter@jollamobile.com>
* Copyright (c) 2013 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -83,6 +84,14 @@ class ContactReader
const QContactId &first,
const QContactId &second);

QContactManager::Error readDetails(
QList<QContactDetail> *details,
QContactDetail::DetailType type,
QList<int> fields,
const QContactFilter &filter,
const QList<QContactSortOrder> &order,
const QContactFetchHint &hint);

bool fetchOOB(const QString &scope, const QStringList &keys, QMap<QString, QVariant> *values);

bool fetchOOBKeys(const QString &scope, QStringList *keys);
Expand Down
99 changes: 91 additions & 8 deletions src/engine/contactsengine.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Jolla Ltd. <andrew.den.exter@jollamobile.com>
* Copyright (c) 2013 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -39,6 +40,7 @@

#include "qtcontacts-extensions.h"
#include "qtcontacts-extensions_impl.h"
#include "qcontactdetailfetchrequest_p.h"
#include "displaylabelgroupgenerator.h"

#include <QCoreApplication>
Expand Down Expand Up @@ -97,7 +99,7 @@ class Job
{
}

virtual QContactAbstractRequest *request() = 0;
virtual QObject *request() = 0;
virtual void clear() = 0;

virtual void execute(ContactReader *reader, WriterProxy &writer) = 0;
Expand All @@ -122,7 +124,7 @@ class TemplateJob : public Job
{
}

QContactAbstractRequest *request()
QObject *request()
{
return m_request;
}
Expand Down Expand Up @@ -499,6 +501,62 @@ class RelationshipFetchJob : public TemplateJob<QContactRelationshipFetchRequest
QList<QContactRelationship> m_relationships;
};

class DetailFetchJob : public TemplateJob<QContactDetailFetchRequest>
{
public:
DetailFetchJob(QContactDetailFetchRequest *request, QContactDetailFetchRequestPrivate *d)
: TemplateJob(request)
, m_filter(d->filter)
, m_fetchHint(d->hint)
, m_sorting(d->sorting)
, m_fields(d->fields)
, m_type(d->type)
{
}

void execute(ContactReader *reader, WriterProxy &) override
{
m_error = reader->readDetails(
&m_details,
m_type,
m_fields,
m_filter,
m_sorting,
m_fetchHint);
}

void updateState(QContactAbstractRequest::State state) override
{
if (m_request) {
QContactDetailFetchRequestPrivate * const d = QContactDetailFetchRequestPrivate::get(m_request);

d->details = m_details;
d->error = m_error;
d->state = state;

if (state == QContactAbstractRequest::FinishedState) {
emit (m_request->*(d->resultsAvailable))();
}
emit (m_request->*(d->stateChanged))(state);
}
}

QString description() const override
{
QString s(QLatin1String("Detail Fetch"));
return s;
}

private:
const QContactFilter m_filter;
const QContactFetchHint m_fetchHint;
const QList<QContactSortOrder> m_sorting;
const QList<int> m_fields;
QList<QContactDetail> m_details;
const QContactDetail::DetailType m_type;

};

class JobThread : public QThread
{
struct MutexUnlocker {
Expand Down Expand Up @@ -563,7 +621,7 @@ class JobThread : public QThread
m_wait.wakeOne();
}

bool requestDestroyed(QContactAbstractRequest *request)
bool requestDestroyed(QObject *request)
{
QMutexLocker locker(&m_mutex);
for (QList<Job*>::iterator it = m_pendingJobs.begin(); it != m_pendingJobs.end(); it++) {
Expand Down Expand Up @@ -593,11 +651,10 @@ class JobThread : public QThread
m_cancelledJobs.erase(it);
return false;
}
}
return false;
} return false;
}

bool cancelRequest(QContactAbstractRequest *request)
bool cancelRequest(QObject *request)
{
QMutexLocker locker(&m_mutex);
for (QList<Job*>::iterator it = m_pendingJobs.begin(); it != m_pendingJobs.end(); it++) {
Expand All @@ -610,7 +667,7 @@ class JobThread : public QThread
return false;
}

bool waitForFinished(QContactAbstractRequest *request, const int msecs)
bool waitForFinished(QObject *request, const int msecs)
{
long timeout = msecs <= 0
? INT32_MAX
Expand Down Expand Up @@ -1105,11 +1162,17 @@ bool ContactsEngine::removeRelationships(
}

void ContactsEngine::requestDestroyed(QContactAbstractRequest* req)
{
requestDestroyed(static_cast<QObject *>(req));
}

void ContactsEngine::requestDestroyed(QObject* req)
{
if (m_jobThread)
m_jobThread->requestDestroyed(req);
}


bool ContactsEngine::startRequest(QContactAbstractRequest* request)
{
Job *job = 0;
Expand Down Expand Up @@ -1149,7 +1212,22 @@ bool ContactsEngine::startRequest(QContactAbstractRequest* request)
return true;
}

bool ContactsEngine::startRequest(QContactDetailFetchRequest* request)
{
Job *job = new DetailFetchJob(request, QContactDetailFetchRequestPrivate::get(request));

job->updateState(QContactAbstractRequest::ActiveState);
m_jobThread->enqueue(job);

return true;
}

bool ContactsEngine::cancelRequest(QContactAbstractRequest* req)
{
return cancelRequest(static_cast<QObject *>(req));
}

bool ContactsEngine::cancelRequest(QObject* req)
{
if (m_jobThread)
return m_jobThread->cancelRequest(req);
Expand All @@ -1158,6 +1236,11 @@ bool ContactsEngine::cancelRequest(QContactAbstractRequest* req)
}

bool ContactsEngine::waitForRequestFinished(QContactAbstractRequest* req, int msecs)
{
return waitForRequestFinished(static_cast<QObject *>(req), msecs);
}

bool ContactsEngine::waitForRequestFinished(QObject* req, int msecs)
{
if (m_jobThread)
return m_jobThread->waitForFinished(req, msecs);
Expand Down
7 changes: 6 additions & 1 deletion src/engine/contactsengine.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Jolla Ltd. <andrew.den.exter@jollamobile.com>
* Copyright (c) 2013 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -129,9 +130,13 @@ class ContactsEngine : public QtContactsSqliteExtensions::ContactManagerEngine
QContactManager::Error *error) override;

void requestDestroyed(QContactAbstractRequest* req) override;
void requestDestroyed(QObject* request) override;
bool startRequest(QContactAbstractRequest* req) override;
bool startRequest(QContactDetailFetchRequest* request) override;
bool cancelRequest(QContactAbstractRequest* req) override;
bool cancelRequest(QObject* request) override;
bool waitForRequestFinished(QContactAbstractRequest* req, int msecs) override;
bool waitForRequestFinished(QObject* req, int msecs) override;

bool isRelationshipTypeSupported(const QString &relationshipType, QContactType::TypeValues contactType) const override;
QList<QContactType::TypeValues> supportedContactTypes() const override;
Expand Down
1 change: 1 addition & 0 deletions src/extensions/QContactDetailFetchRequest
@@ -0,0 +1 @@
#include "./qcontactdetailfetchrequest.h"
12 changes: 11 additions & 1 deletion src/extensions/contactmanagerengine.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2013 Jolla Ltd. <mattthew.vogt@jollamobile.com>
* Copyright (c) 2013 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -34,6 +35,10 @@

#include <QContactManagerEngine>

QT_BEGIN_NAMESPACE_CONTACTS
class QContactDetailFetchRequest;
QT_END_NAMESPACE_CONTACTS

QTCONTACTS_USE_NAMESPACE

namespace QtContactsSqliteExtensions {
Expand Down Expand Up @@ -95,6 +100,11 @@ class Q_DECL_EXPORT ContactManagerEngine

virtual QStringList displayLabelGroups() = 0;

virtual void requestDestroyed(QObject* request) = 0;
virtual bool startRequest(QContactDetailFetchRequest* request) = 0;
virtual bool cancelRequest(QObject* request) = 0;
virtual bool waitForRequestFinished(QObject* req, int msecs) = 0;

Q_SIGNALS:
void contactsPresenceChanged(const QList<QContactId> &contactsIds);
void syncContactsChanged(const QStringList &syncTargets);
Expand Down
94 changes: 94 additions & 0 deletions src/extensions/qcontactdetailfetchrequest.h
@@ -0,0 +1,94 @@
/*
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
* "Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Nemo Mobile nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
*/

#ifndef QCONTACTDETAILFETCHREQUEST_H
#define QCONTACTDETAILFETCHREQUEST_H

#include <qcontactabstractrequest.h>
#include <qcontactdetail.h>
#include <qcontactsortorder.h>
#include <qcontactfilter.h>
#include <qcontactfetchhint.h>

QT_BEGIN_NAMESPACE_CONTACTS

class QContactDetailFetchRequestPrivate;
class QContactDetailFetchRequest : public QObject
{
Q_OBJECT
Q_DISABLE_COPY(QContactDetailFetchRequest)
Q_DECLARE_PRIVATE(QContactDetailFetchRequest)
public:
QContactDetailFetchRequest(QObject *parent = nullptr);
~QContactDetailFetchRequest() override;

QContactManager *manager() const;
void setManager(QContactManager *manager);

QContactDetail::DetailType type() const;
void setType(QContactDetail::DetailType type);

QList<int> fields() const;
void setFields(const QList<int> fields);

QContactFilter filter() const;
void setFilter(const QContactFilter &filter);

QList<QContactSortOrder> sorting() const;
void setSorting(const QList<QContactSortOrder> &sorting);

QContactFetchHint fetchHint() const;
void setFetchHint(const QContactFetchHint &hint);

QContactAbstractRequest::State state() const;
QContactManager::Error error() const;

QList<QContactDetail> details() const;

public Q_SLOTS:
bool start();
bool cancel();

bool waitForFinished(int msecs = 0);

Q_SIGNALS:
void stateChanged(QContactAbstractRequest::State state);
void resultsAvailable();

private:
QScopedPointer<QContactDetailFetchRequestPrivate> d_ptr;


};

QT_END_NAMESPACE_CONTACTS

#endif

0 comments on commit 22f1ce4

Please sign in to comment.