Commit 9ded8af8 authored by chriadam's avatar chriadam

[libcontacts] Provide decomposeDisplayLabel() function. Contributes to MER#1379

Some data sources provide a display label (or formatted name) but not
structured name data.  The qtcontacts-sqlite backend uses structured
name data to perform aggregation, and thus it is useful to have the
decomposition function provided for clients (e.g., sync plugins).

Contributes to MER#1379
parent 8af9c023
TEMPLATE = subdirs
SUBDIRS = src tests
SUBDIRS = src tests translations
OTHER_FILES += rpm/libcontacts-qt5.spec
tests.depends = src
......@@ -15,6 +15,8 @@ BuildRequires: pkgconfig(mlite5)
BuildRequires: pkgconfig(mlocale5)
BuildRequires: pkgconfig(mce)
BuildRequires: pkgconfig(qtcontacts-sqlite-qt5-extensions) >= 0.2.1
BuildRequires: qt5-qttools
BuildRequires: qt5-qttools-linguist
%description
%{summary}.
......@@ -36,6 +38,20 @@ Requires: %{name} = %{version}-%{release}
%description devel
%{summary}.
%package ts-devel
Summary: Translation source for libcontacts
Group: System/Applications
%description ts-devel
Translation source for libcontacts
%files ts-devel
%defattr(-,root,root,-)
%{_datadir}/translations/source/libcontacts.ts
%prep
%setup -q -n %{name}-%{version}
......@@ -47,7 +63,7 @@ make %{?_smp_mflags}
%install
rm -rf %{buildroot}
%qmake_install
%qmake5_install
%post -p /sbin/ldconfig
......@@ -56,6 +72,7 @@ rm -rf %{buildroot}
%files
%defattr(-,root,root,-)
%{_libdir}/libcontactcache-qt5.so*
%{_datadir}/translations/libcontacts_eng_en.qm
%files tests
%defattr(-,root,root,-)
......
......@@ -1192,6 +1192,67 @@ static bool needsSpaceBetweenNames(const QString &first, const QString &second)
|| second[0].script() != QChar::Script_Han;
}
template<typename F1, typename F2>
void updateNameDetail(F1 getter, F2 setter, QContactName *nameDetail, const QString &value)
{
QString existing((nameDetail->*getter)());
if (!existing.isEmpty()) {
existing.append(QChar::fromLatin1(' '));
}
(nameDetail->*setter)(existing + value);
}
void SeasideCache::decomposeDisplayLabel(const QString &formattedDisplayLabel, QContactName *nameDetail)
{
// Try to parse the structure from the formatted name
// TODO: Use MBreakIterator for localized splitting
QStringList tokens(formattedDisplayLabel.split(QChar::fromLatin1(' '), QString::SkipEmptyParts));
if (tokens.count() >= 2) {
QString format;
if (tokens.count() == 2) {
//: Format string for allocating 2 tokens to name parts - 2 characters from the set [FMLPS]
//% "FL"
format = qtTrId("libcontacts_name_structure_2_tokens");
} else if (tokens.count() == 3) {
//: Format string for allocating 3 tokens to name parts - 3 characters from the set [FMLPS]
//% "FML"
format = qtTrId("libcontacts_name_structure_3_tokens");
} else if (tokens.count() > 3) {
//: Format string for allocating 4 tokens to name parts - 4 characters from the set [FMLPS]
//% "FFML"
format = qtTrId("libcontacts_name_structure_4_tokens");
// Coalesce the leading tokens together to limit the possibilities
int excess = tokens.count() - 4;
if (excess > 0) {
QString first(tokens.takeFirst());
while (--excess >= 0) {
QString nextNamePart = tokens.takeFirst();
first += (needsSpaceBetweenNames(first, nextNamePart) ? QChar::fromLatin1(' ') : QString()) + nextNamePart;
}
tokens.prepend(first);
}
}
if (format.length() != tokens.length()) {
qWarning() << "Invalid structure format for" << tokens.count() << "tokens:" << format;
} else {
foreach (const QChar &part, format) {
const QString token(tokens.takeFirst());
switch (part.toUpper().toLatin1()) {
case 'F': updateNameDetail(&QContactName::firstName, &QContactName::setFirstName, nameDetail, token); break;
case 'M': updateNameDetail(&QContactName::middleName, &QContactName::setMiddleName, nameDetail, token); break;
case 'L': updateNameDetail(&QContactName::lastName, &QContactName::setLastName, nameDetail, token); break;
case 'P': updateNameDetail(&QContactName::prefix, &QContactName::setPrefix, nameDetail, token); break;
case 'S': updateNameDetail(&QContactName::suffix, &QContactName::setSuffix, nameDetail, token); break;
default:
qWarning() << "Invalid structure format character:" << part;
}
}
}
}
}
// small helper to avoid inconvenience
QString SeasideCache::generateDisplayLabel(const QContact &contact, DisplayLabelOrder order)
{
......
......@@ -50,6 +50,7 @@
#include <QContactRelationshipRemoveRequest>
#include <QContactIdFilter>
#include <QContactIdFetchRequest>
#include <QContactName>
#include <QBasicTimer>
#include <QHash>
......@@ -323,6 +324,7 @@ public:
static QString primaryName(const QString &firstName, const QString &lastName);
static QString secondaryName(const QString &firstName, const QString &lastName);
static void decomposeDisplayLabel(const QString &formattedDisplayLabel, QContactName *nameDetail);
static QString generateDisplayLabel(const QContact &contact, DisplayLabelOrder order = FirstNameFirst);
static QString generateDisplayLabelFromNonNameDetails(const QContact &contact);
static QUrl filteredAvatarUrl(const QContact &contact, const QStringList &metadataFragments = QStringList());
......
TEMPLATE = aux
TS_FILE = $$OUT_PWD/libcontacts.ts
EE_QM = $$OUT_PWD/libcontacts_eng_en.qm
ts.commands += lupdate $$PWD/../src -ts $$TS_FILE
ts.output = $$TS_FILE
ts.input = .
ts_install.files = $$TS_FILE
ts_install.path = $$PREFIX/share/translations/source
ts_install.CONFIG += no_check_exist
engineering_english.commands += lrelease -idbased $$TS_FILE -qm $$EE_QM
engineering_english.depends = ts
engineering_english.input = $$TS_FILE
engineering_english.output = $$EE_QM
TRANSLATIONS_PATH = $$PREFIX/share/translations
engineering_english_install.path = $$TRANSLATIONS_PATH
engineering_english_install.files = $$EE_QM
engineering_english_install.CONFIG += no_check_exist
QMAKE_EXTRA_TARGETS += ts engineering_english
PRE_TARGETDEPS += ts engineering_english
DEFINES += TRANSLATIONS_PATH=\"\\\"\"$${TRANSLATIONS_PATH}\"\\\"\"
INSTALLS += ts_install engineering_english_install
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment