Skip to content

Commit

Permalink
[qtcontacts-sqlite] Load installed display label generator plugins. C…
Browse files Browse the repository at this point in the history
…ontributes to JB#44742
  • Loading branch information
Chris Adams committed Apr 15, 2019
1 parent 1db5b4a commit d1af84a
Show file tree
Hide file tree
Showing 22 changed files with 1,054 additions and 80 deletions.
3 changes: 2 additions & 1 deletion rpm/qtcontacts-sqlite-qt5.spec
Expand Up @@ -31,6 +31,7 @@ This package contains unit tests for the qtcontacts-sqlite-qt5 library.
%files tests
%defattr(-,root,root,-)
/opt/tests/qtcontacts-sqlite-qt5/*
%{_libdir}/qtcontacts-sqlite-qt5/libtestdlgg.so

%package extensions
Summary: QtContacts extension headers for qtcontacts-sqlite-qt5
Expand All @@ -50,7 +51,7 @@ This package contains extension headers for the qtcontacts-sqlite-qt5 library.
%setup -q -n %{name}-%{version}

%build
%qmake5
%qmake5 "VERSION=%{version}"
make %{?_smp_mflags}

%install
Expand Down
341 changes: 271 additions & 70 deletions src/engine/contactsdatabase.cpp

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions src/engine/contactsdatabase.h
Expand Up @@ -34,6 +34,7 @@

#include "semaphore_p.h"
#include "contactstransientstore.h"
#include "../extensions/displaylabelgroupgenerator.h"

#include <QHash>
#include <QMutex>
Expand All @@ -42,6 +43,9 @@
#include <QSqlError>
#include <QSqlQuery>
#include <QVariantList>
#include <QVector>

#include <QContact>

class ContactsDatabase
{
Expand Down Expand Up @@ -148,6 +152,9 @@ class ContactsDatabase
bool removeTransientDetails(quint32 contactId);
bool removeTransientDetails(const QList<quint32> &contactIds);

QString determineDisplayLabelGroup(const QContact &c) const;
QStringList displayLabelGroups() const;

static bool execute(QSqlQuery &query);
static bool executeBatch(QSqlQuery &query, QSqlQuery::BatchExecutionMode mode = QSqlQuery::ValuesAsRows);

Expand All @@ -162,8 +169,6 @@ class ContactsDatabase
// Output is UTC
static QDateTime fromDateTimeString(const QString &s);

static QString determineDisplayLabelGroup(const QString &firstName, const QString &lastName, const QString &displayLabel);

private:
QSqlDatabase m_database;
ContactsTransientStore m_transientStore;
Expand All @@ -172,6 +177,8 @@ class ContactsDatabase
bool m_nonprivileged;
QString m_localeName;
QHash<QString, QSqlQuery> m_preparedQueries;
QVector<QtContactsSqliteExtensions::DisplayLabelGroupGenerator*> m_dlgGenerators;
QScopedPointer<QtContactsSqliteExtensions::DisplayLabelGroupGenerator> m_defaultGenerator;
};

#endif
17 changes: 14 additions & 3 deletions src/engine/contactsengine.cpp
Expand Up @@ -39,6 +39,7 @@

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

#include <QCoreApplication>
#include <QMutex>
Expand Down Expand Up @@ -1182,9 +1183,9 @@ void ContactsEngine::regenerateDisplayLabel(QContact &contact) const
return;
}

const QString group = ContactsDatabase::determineDisplayLabelGroup(contact.detail<QContactName>().firstName(),
contact.detail<QContactName>().lastName(),
label);
QContact tempContact(contact);
setContactDisplayLabel(&tempContact, label, QString());
const QString group = m_database ? m_database->determineDisplayLabelGroup(tempContact) : QString();
setContactDisplayLabel(&contact, label, group);
}

Expand Down Expand Up @@ -1285,6 +1286,11 @@ bool ContactsEngine::removeOOB(const QString &scope)
return writer()->removeOOB(scope, QStringList());
}

QStringList ContactsEngine::displayLabelGroups()
{
return database().displayLabelGroups();
}

bool ContactsEngine::setContactDisplayLabel(QContact *contact, const QString &label, const QString &group)
{
QContactDisplayLabel detail(contact->detail<QContactDisplayLabel>());
Expand Down Expand Up @@ -1406,6 +1412,11 @@ void ContactsEngine::_q_syncContactsChanged(const QStringList &syncTargets)
emit syncContactsChanged(syncTargets);
}

void ContactsEngine::_q_displayLabelGroupsChanged(const QStringList &groups)
{
emit displayLabelGroupsChanged(groups);
}

void ContactsEngine::_q_contactsRemoved(const QVector<quint32> &contactIds)
{
emit contactsRemoved(idList(contactIds));
Expand Down
3 changes: 3 additions & 0 deletions src/engine/contactsengine.h
Expand Up @@ -165,6 +165,8 @@ class ContactsEngine : public QtContactsSqliteExtensions::ContactManagerEngine

QString synthesizedDisplayLabel(const QContact &contact, QContactManager::Error *error) const;

QStringList displayLabelGroups() override;

private slots:
void _q_contactsChanged(const QVector<quint32> &contactIds);
void _q_contactsPresenceChanged(const QVector<quint32> &contactIds);
Expand All @@ -174,6 +176,7 @@ private slots:
void _q_selfContactIdChanged(quint32,quint32);
void _q_relationshipsAdded(const QVector<quint32> &contactIds);
void _q_relationshipsRemoved(const QVector<quint32> &contactIds);
void _q_displayLabelGroupsChanged(const QStringList &groups);

private:
QString databaseUuid();
Expand Down
2 changes: 1 addition & 1 deletion src/engine/contactwriter.cpp
Expand Up @@ -5620,7 +5620,7 @@ ContactsDatabase::Query ContactWriter::bindContactDetails(const QContact &contac
QContactDisplayLabel label = contact.detail<QContactDisplayLabel>();
const QString displayLabel = label.label().trimmed();
query.bindValue(0, displayLabel);
query.bindValue(1, ContactsDatabase::determineDisplayLabelGroup(firstName, lastName, displayLabel));
query.bindValue(1, m_database.determineDisplayLabelGroup(contact));

query.bindValue(2, firstName);
query.bindValue(3, firstName.toLower());
Expand Down
138 changes: 138 additions & 0 deletions src/engine/defaultdlggenerator.cpp
@@ -0,0 +1,138 @@
/*
* Copyright (C) 2019 Jolla Ltd. <chris.adams@jollamobile.com>
*
* 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."
*/

#include "defaultdlggenerator.h"

/*
This display label group generator provides the
default (fallback) group generation semantics, and should
be the last generator used (i.e. if no other generator
is valid in the current locale).
The semantics it implements are as follows:
1) if the preferred name field data is empty,
it falls back to display label data to generate the
group.
2) if the first character of the preferred data
is a digit (0..9) then the group is '#'.
3) if the first character of the preferred data
is within 'A'..'Z' it returns that character.
(TODO: perform a unidecode transliteration first.)
4) otherwise, the group is '!'
For example, if the preferred detail is
QContactName::Type and the preferred field is
QContactName::FieldLastName, and the client passes
in a contact with name "John Smith", then the first
letter of the last name (in this case, 'S') will be
returned as the group.
*/

DefaultDlgGenerator::DefaultDlgGenerator(QObject *parent)
: QObject(parent)
{
}

QString DefaultDlgGenerator::name() const
{
return QStringLiteral("default");
}

int DefaultDlgGenerator::priority() const
{
return 0;
}

bool DefaultDlgGenerator::validForLocale(const QLocale &) const
{
return true; // this default plugin is the fallback, and always valid.
}

QStringList DefaultDlgGenerator::displayLabelGroups() const
{
static QStringList groups {
QStringLiteral("A"),
QStringLiteral("B"),
QStringLiteral("C"),
QStringLiteral("D"),
QStringLiteral("E"),
QStringLiteral("F"),
QStringLiteral("G"),
QStringLiteral("H"),
QStringLiteral("I"),
QStringLiteral("J"),
QStringLiteral("K"),
QStringLiteral("L"),
QStringLiteral("M"),
QStringLiteral("N"),
QStringLiteral("O"),
QStringLiteral("P"),
QStringLiteral("Q"),
QStringLiteral("R"),
QStringLiteral("S"),
QStringLiteral("T"),
QStringLiteral("U"),
QStringLiteral("V"),
QStringLiteral("W"),
QStringLiteral("X"),
QStringLiteral("Y"),
QStringLiteral("Z"),
QStringLiteral("#"),
QStringLiteral("!")
};
return groups;
}

QString DefaultDlgGenerator::displayLabelGroup(const QString &data) const
{
QString group;

if (!data.isEmpty()) {
QChar upperChar = data.at(0).toUpper();
ushort val = upperChar.unicode();
if (val >= 'A' && val <= 'Z') {
group = QString(upperChar);
} else if (data.at(0).isDigit()) {
group = QStringLiteral("#");
}
}

if (group.isEmpty()) {
// unknown group. put in "other" group '!'
group = QStringLiteral("!");
}

return group;
}
52 changes: 52 additions & 0 deletions src/engine/defaultdlggenerator.h
@@ -0,0 +1,52 @@
/*
* Copyright (C) 2019 Jolla Ltd. <chris.adams@jollamobile.com>
*
* 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 DEFAULTDLGGENERATOR_H
#define DEFAULTDLGGENERATOR_H

#include <QObject>
#include <displaylabelgroupgenerator.h>

class DefaultDlgGenerator : public QObject, public QtContactsSqliteExtensions::DisplayLabelGroupGenerator
{
Q_OBJECT
Q_INTERFACES(QtContactsSqliteExtensions::DisplayLabelGroupGenerator)

public:
DefaultDlgGenerator(QObject *parent = Q_NULLPTR);
QString name() const Q_DECL_OVERRIDE;
int priority() const Q_DECL_OVERRIDE;
bool validForLocale(const QLocale &locale) const Q_DECL_OVERRIDE;
QString displayLabelGroup(const QString &data) const Q_DECL_OVERRIDE;
QStringList displayLabelGroups() const Q_DECL_OVERRIDE;
};

#endif // DEFAULTDLGGENERATOR_H
5 changes: 5 additions & 0 deletions src/engine/engine.pro
Expand Up @@ -9,6 +9,9 @@ CONFIG += plugin hide_symbols
PLUGIN_TYPE=contacts
DESTDIR=$${PLUGIN_TYPE}

CONFIG += link_pkgconfig
PKGCONFIG += mlocale5

# we hardcode this for Qt4 as there's no GenericDataLocation offered by QDesktopServices
DEFINES += 'QTCONTACTS_SQLITE_PRIVILEGED_DIR=\'\"privileged\"\''
DEFINES += 'QTCONTACTS_SQLITE_DATABASE_DIR=\'\"Contacts/qtcontacts-sqlite\"\''
Expand All @@ -22,6 +25,7 @@ INCLUDEPATH += \
../extensions

HEADERS += \
defaultdlggenerator.h \
memorytable_p.h \
semaphore_p.h \
trace_p.h \
Expand All @@ -36,6 +40,7 @@ HEADERS += \
../extensions/contactmanagerengine.h

SOURCES += \
defaultdlggenerator.cpp \
memorytable.cpp \
semaphore_p.cpp \
conversion.cpp \
Expand Down
3 changes: 3 additions & 0 deletions src/extensions/contactmanagerengine.h
Expand Up @@ -93,9 +93,12 @@ class Q_DECL_EXPORT ContactManagerEngine
virtual bool removeOOB(const QString &scope, const QStringList &keys) = 0;
virtual bool removeOOB(const QString &scope) = 0;

virtual QStringList displayLabelGroups() = 0;

Q_SIGNALS:
void contactsPresenceChanged(const QList<QContactId> &contactsIds);
void syncContactsChanged(const QStringList &syncTargets);
void displayLabelGroupsChanged(const QStringList &groups);

protected:
bool m_nonprivileged;
Expand Down

0 comments on commit d1af84a

Please sign in to comment.