Commit 5b6df064 authored by Carl Schwan's avatar Carl Schwan 🚴
Browse files

Add more contact field



Signed-off-by: Carl Schwan's avatarCarl Schwan <carl@carlschwan.eu>
parent 3c6a3201
......@@ -10,6 +10,8 @@ target_sources(kalendar_contact_plugin PRIVATE
addresseewrapper.h
addressmodel.cpp
addressmodel.h
phonemodel.h
phonemodel.cpp
emailmodel.h
emailmodel.cpp
globalcontactmodel.cpp
......
......@@ -15,6 +15,7 @@ AddresseeWrapper::AddresseeWrapper(QObject *parent)
, Akonadi::ItemMonitor()
, m_addressesModel(new AddressModel(this))
, m_emailModel(new EmailModel(this))
, m_phoneModel(new PhoneModel(this))
{
Akonadi::ItemFetchScope scope;
scope.fetchFullPayload();
......@@ -35,6 +36,18 @@ void AddresseeWrapper::notifyDataChanged()
Q_EMIT phoneNumbersChanged();
Q_EMIT preferredEmailChanged();
Q_EMIT uidChanged();
Q_EMIT noteChanged();
Q_EMIT nickNameChanged();
Q_EMIT blogFeedChanged();
Q_EMIT anniversaryChanged();
Q_EMIT spousesNameChanged();
Q_EMIT organizationChanged();
Q_EMIT professionChanged();
Q_EMIT titleChanged();
Q_EMIT departmentChanged();
Q_EMIT officeChanged();
Q_EMIT managersNameChanged();
Q_EMIT assistantsNameChanged();
}
Akonadi::Item AddresseeWrapper::addresseeItem() const
......@@ -83,6 +96,7 @@ void AddresseeWrapper::setAddressee(const KContacts::Addressee &addressee)
m_addressee = addressee;
m_addressesModel->setAddresses(addressee.addresses());
m_emailModel->setEmails(addressee.emailList());
m_phoneModel->setPhoneNumbers(addressee.phoneNumbers());
notifyDataChanged();
}
......@@ -150,6 +164,11 @@ EmailModel *AddresseeWrapper::emailModel() const
return m_emailModel;
}
PhoneModel *AddresseeWrapper::phoneModel() const
{
return m_phoneModel;
}
QString AddresseeWrapper::qrCodeData() const
{
KContacts::VCardConverter converter;
......@@ -158,3 +177,171 @@ QString AddresseeWrapper::qrCodeData() const
addr.setLogo(KContacts::Picture());
return QString::fromUtf8(converter.createVCard(addr));
}
QString AddresseeWrapper::note() const
{
return m_addressee.note();
}
QDate AddresseeWrapper::anniversary() const
{
return m_addressee.anniversary();
}
QString AddresseeWrapper::spousesName() const
{
return m_addressee.spousesName();
}
QString AddresseeWrapper::organization() const
{
return m_addressee.organization();
}
QString AddresseeWrapper::profession() const
{
return m_addressee.profession();
}
QString AddresseeWrapper::title() const
{
return m_addressee.title();
}
QString AddresseeWrapper::department() const
{
return m_addressee.department();
}
QString AddresseeWrapper::office() const
{
return m_addressee.office();
}
QString AddresseeWrapper::managersName() const
{
return m_addressee.managersName();
}
QString AddresseeWrapper::assistantsName() const
{
return m_addressee.assistantsName();
}
void AddresseeWrapper::setNote(const QString &note)
{
if (note == m_addressee.note()) {
return;
}
m_addressee.setNote(note);
Q_EMIT noteChanged();
}
void AddresseeWrapper::setAnniversary(const QDate &anniversary)
{
if (anniversary == m_addressee.anniversary()) {
return;
}
m_addressee.setAnniversary(anniversary);
Q_EMIT anniversaryChanged();
}
void AddresseeWrapper::setSpousesName(const QString &spousesName)
{
if (spousesName == m_addressee.spousesName()) {
return;
}
m_addressee.setSpousesName(spousesName);
Q_EMIT spousesNameChanged();
}
void AddresseeWrapper::setOrganization(const QString &organization)
{
if (organization == m_addressee.organization()) {
return;
}
m_addressee.setOrganization(organization);
Q_EMIT organizationChanged();
}
void AddresseeWrapper::setProfession(const QString &profession)
{
if (profession == m_addressee.profession()) {
return;
}
m_addressee.setProfession(profession);
Q_EMIT professionChanged();
}
void AddresseeWrapper::setTitle(const QString &title)
{
if (title == m_addressee.title()) {
return;
}
m_addressee.setTitle(title);
Q_EMIT titleChanged();
}
void AddresseeWrapper::setDepartment(const QString &department)
{
if (department == m_addressee.department()) {
return;
}
m_addressee.setDepartment(department);
Q_EMIT departmentChanged();
}
void AddresseeWrapper::setOffice(const QString &office)
{
if (office == m_addressee.office()) {
return;
}
m_addressee.setOffice(office);
Q_EMIT officeChanged();
}
void AddresseeWrapper::setManagersName(const QString &managersName)
{
if (managersName == m_addressee.managersName()) {
return;
}
m_addressee.setManagersName(managersName);
Q_EMIT managersNameChanged();
}
void AddresseeWrapper::setAssistantsName(const QString &assistantsName)
{
if (assistantsName == m_addressee.assistantsName()) {
return;
}
m_addressee.setAssistantsName(assistantsName);
Q_EMIT assistantsNameChanged();
}
QString AddresseeWrapper::nickName() const
{
return m_addressee.nickName();
}
void AddresseeWrapper::setNickName(const QString &nickName)
{
if (nickName == m_addressee.nickName()) {
return;
}
m_addressee.setNickName(nickName);
Q_EMIT nickNameChanged();
}
QUrl AddresseeWrapper::blogFeed() const
{
return m_addressee.blogFeed();
}
void AddresseeWrapper::setBlogFeed(const QUrl &blogFeed)
{
if (blogFeed == m_addressee.blogFeed()) {
return;
}
m_addressee.setBlogFeed(blogFeed);
Q_EMIT blogFeedChanged();
}
......@@ -13,7 +13,9 @@
#include <QObject>
#include "addressmodel.h"
#include "emailmodel.h"
#include "phonemodel.h"
/// This class is a QObject wrapper for a KContact::Adressee
class AddresseeWrapper : public QObject, public Akonadi::ItemMonitor
......@@ -22,13 +24,36 @@ class AddresseeWrapper : public QObject, public Akonadi::ItemMonitor
Q_PROPERTY(Akonadi::Item addresseeItem READ addresseeItem WRITE setAddresseeItem NOTIFY addresseeItemChanged)
Q_PROPERTY(QString uid READ uid NOTIFY uidChanged)
Q_PROPERTY(qint64 collectionId READ collectionId WRITE setCollectionId NOTIFY collectionIdChanged)
// Contact information
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString nickName READ nickName WRITE setNickName NOTIFY nickNameChanged)
Q_PROPERTY(QUrl blogFeed READ blogFeed WRITE setBlogFeed NOTIFY blogFeedChanged)
Q_PROPERTY(QString preferredEmail READ preferredEmail NOTIFY preferredEmailChanged)
Q_PROPERTY(QDateTime birthday READ birthday WRITE setBirthday NOTIFY birthdayChanged)
Q_PROPERTY(KContacts::PhoneNumber::List phoneNumbers READ phoneNumbers NOTIFY phoneNumbersChanged)
Q_PROPERTY(KContacts::Picture photo READ photo NOTIFY photoChanged)
Q_PROPERTY(AddressModel *addressesModel READ addressesModel CONSTANT)
Q_PROPERTY(EmailModel *emailModel READ emailModel CONSTANT)
Q_PROPERTY(PhoneModel *phoneModel READ phoneModel CONSTANT)
// Address
Q_PROPERTY(AddressModel *addressesModel READ addressesModel CONSTANT)
// Personal information
Q_PROPERTY(QDateTime birthday READ birthday WRITE setBirthday NOTIFY birthdayChanged)
Q_PROPERTY(QDate anniversary READ anniversary WRITE setAnniversary NOTIFY anniversaryChanged)
Q_PROPERTY(QString spousesName READ spousesName WRITE setSpousesName NOTIFY spousesNameChanged)
// Buisness information
Q_PROPERTY(QString organization READ organization WRITE setOrganization NOTIFY organizationChanged)
Q_PROPERTY(QString profession READ profession WRITE setProfession NOTIFY professionChanged)
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
Q_PROPERTY(QString department READ department WRITE setDepartment NOTIFY departmentChanged)
Q_PROPERTY(QString office READ office WRITE setOffice NOTIFY officeChanged)
Q_PROPERTY(QString managersName READ managersName WRITE setManagersName NOTIFY managersNameChanged)
Q_PROPERTY(QString assistantsName READ assistantsName WRITE setAssistantsName NOTIFY assistantsNameChanged)
// Other information
Q_PROPERTY(QString note READ note WRITE setNote NOTIFY noteChanged)
Q_PROPERTY(KContacts::Picture photo READ photo NOTIFY photoChanged)
public:
AddresseeWrapper(QObject *parent = nullptr);
......@@ -38,25 +63,66 @@ public:
void setAddresseeItem(const Akonadi::Item &item);
QString uid() const;
KContacts::PhoneNumber::List phoneNumbers() const;
AddressModel *addressesModel() const;
EmailModel *emailModel() const;
qint64 collectionId() const;
void setCollectionId(qint64 collectionId);
QString name() const;
QString preferredEmail() const;
QDateTime birthday() const;
void setName(const QString &name);
QString nickName() const;
void setNickName(const QString &nickName);
QUrl blogFeed() const;
void setBlogFeed(const QUrl &blogFDeed);
QDateTime birthday() const;
void setBirthday(const QDateTime &birthday);
QString preferredEmail() const;
KContacts::Picture photo() const;
void setAddressee(const KContacts::Addressee &addressee);
void notifyDataChanged();
AddressModel *addressesModel() const;
EmailModel *emailModel() const;
PhoneModel *phoneModel() const;
KContacts::PhoneNumber::List phoneNumbers() const;
QString note() const;
void setNote(const QString &note);
QDate anniversary() const;
void setAnniversary(const QDate &anniversary);
QString organization() const;
void setOrganization(const QString &organization);
QString profession() const;
void setProfession(const QString &profession);
QString title() const;
void setTitle(const QString &title);
QString department() const;
void setDepartment(const QString &department);
QString office() const;
void setOffice(const QString &office);
QString managersName() const;
void setManagersName(const QString &managersName);
QString assistantsName() const;
void setAssistantsName(const QString &assistantsName);
void setSpousesName(const QString &spousesName);
QString spousesName() const;
// Invokable since we don't want expensive data bindings when any of the
// fields change, instead generate it on demand
Q_INVOKABLE QString qrCodeData() const;
void notifyDataChanged();
Q_SIGNALS:
void addresseeItemChanged();
void collectionIdChanged();
......@@ -66,6 +132,20 @@ Q_SIGNALS:
void phoneNumbersChanged();
void preferredEmailChanged();
void uidChanged();
void noteChanged();
void nickNameChanged();
void blogFeedChanged();
void anniversaryChanged();
void spousesNameChanged();
void organizationChanged();
void professionChanged();
void titleChanged();
void departmentChanged();
void officeChanged();
void managersNameChanged();
void assistantsNameChanged();
private:
void itemChanged(const Akonadi::Item &item) override;
......@@ -73,4 +153,5 @@ private:
qint64 m_collectionId = -1; // For when we want to edit, this is temporary
AddressModel *m_addressesModel;
EmailModel *m_emailModel;
PhoneModel *m_phoneModel;
};
......@@ -8,6 +8,8 @@ add_library(kalendar_contact STATIC
../addressmodel.h
../emailmodel.h
../emailmodel.cpp
../phonemodel.h
../phonemodel.cpp
../globalcontactmodel.cpp
../globalcontactmodel.h
../contactmanager.h
......
// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "phonemodel.h"
#include <KLocalizedString>
PhoneModel::PhoneModel(QObject *parent)
: QAbstractListModel(parent)
{
}
int PhoneModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_phoneNumbers.count();
}
QVariant PhoneModel::data(const QModelIndex &idx, int role) const
{
const auto phone = m_phoneNumbers[idx.row()];
switch (role) {
case Qt::DisplayRole:
return phone.number();
case TypeRole:
return phone.typeLabel();
case SupportSmsRole:
return phone.supportsSms();
case DefaultRole:
return phone.isPreferred();
}
return {};
}
QHash<int, QByteArray> PhoneModel::roleNames() const
{
return {
{Qt::DisplayRole, QByteArrayLiteral("display")},
{TypeRole, QByteArrayLiteral("type")},
{DefaultRole, QByteArrayLiteral("default")},
};
}
void PhoneModel::setPhoneNumbers(const KContacts::PhoneNumber::List &phoneNumbers)
{
beginResetModel();
m_phoneNumbers = phoneNumbers;
endResetModel();
}
// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: LGPL-2.1-or-later
#pragma once
#include <KContacts/PhoneNumber>
#include <QAbstractListModel>
class PhoneModel : public QAbstractListModel
{
Q_OBJECT
public:
enum ExtraRole {
TypeRole = Qt::UserRole + 1,
DefaultRole,
SupportSmsRole,
};
PhoneModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = {}) const override;
QVariant data(const QModelIndex &idx, int role) const override;
QHash<int, QByteArray> roleNames() const override;
void setPhoneNumbers(const KContacts::PhoneNumber::List &phoneNumbers);
private:
KContacts::PhoneNumber::List m_phoneNumbers;
};
......@@ -82,21 +82,10 @@ Kirigami.ScrollablePage {
backgroundSource: "qrc:/fallbackBackground.png"
contentItems: [
Kirigami.Heading {
text: addressee.name
color: "#fcfcfc"
level: 2
},
Repeater {
model: addressee.phoneNumbers
Kirigami.Heading {
text: modelData.normalizedNumber
color: "#fcfcfc"
level: 3
}
}
]
contentItems: Kirigami.Heading {
text: addressee.name
color: "#fcfcfc"
}
}
Controls.ToolBar {
......@@ -163,10 +152,49 @@ Kirigami.ScrollablePage {
ColumnLayout {
Kirigami.FormLayout {
id: addreseseForm
twinFormLayouts: [emailForm]
width: parent.width
id: contactForm
twinFormLayouts: [addreseesForm, phoneForm, contactForm, businessForm]
Item {
Kirigami.FormData.isSection: true
Kirigami.FormData.label: i18n("Contact information")
}
Controls.Label {
visible: text !== ""
text: addressee.name
Kirigami.FormData.label: i18n("Name:")
}
Controls.Label {
visible: text !== ""
text: addressee.nickName
Kirigami.FormData.label: i18n("Nickname:")
}
Controls.Label {
id: blogFeed
visible: addressee.blogFeed + '' !== ''
// We do not always have the year
text: `<a href="${addressee.blogFeed}">${addressee.blogFeed}</a>`
Kirigami.FormData.label: i18n("Blog Feed:")
MouseArea {
id: area
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: Qt.openUrlExternally(addressee.blogFeed)
onPressed: Qt.openUrlExternally(addressee.blogFeed)
}
}
Item {
visible: birthday.visible || anniversary.visible || spousesName.visible
Kirigami.FormData.isSection: true
Kirigami.FormData.label: i18n("Personal information")
}
Controls.Label {
id: birthday
visible: text !== ""
// We do not always have the year
text: if (addressee.birthday.getFullYear() === 0) {
......@@ -177,13 +205,71 @@ Kirigami.ScrollablePage {
Kirigami.FormData.label: i18n("Birthday:")
}
Controls.Label {
id: anniversary
visible: text !== ""
// We do not always have the year
text: if (addressee.anniversary.getFullYear() === 0) {
return Qt.formatDate(addressee.anniversary, i18nc('Day month format', 'dd.MM.'))
} else {
return addressee.anniversary.toLocaleDateString()
}
Kirigami.FormData.label: i18n("Anniversary:")
}
Controls.Label {
id: spousesName
visible: text !== ""
text: addressee.spousesName
Kirigami.FormData.label: i18n("Partner's name:")
}
}
Kirigami.FormLayout {
id: phoneForm
twinFormLayouts: [emailForm, contactForm, businessForm]
width: parent.width
Item {
visible: addressee.addressesModel.rowCount() > 0
visible: phoneRepeater.count > 0
Kirigami.FormData.isSection: true
Kirigami.FormData.label: i18np("Address", "Addresses", addressee.addressesModel.rowCount())
Kirigami.FormData.label: i18np("Phone Number", "Phone Numbers", addressee.phoneModel.count)
}
Repeater {
id: phoneRepeater
model: addressee.phoneModel
Controls.Label {
visible: text !== ""
text: `<a href="tel:${model.display}">${model.display}</a>`
onLinkActivated: Qt.openUrlExternally(link)
Kirigami.FormData.label: i18nc("Label for a phone number type", "%1:", model.type)
Kirigami.FormData.labelAlignment: Qt.AlignTop
MouseArea {
id: area
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: Qt.openUrlExternally(`tel:${model.display}`)
onPressed: Qt.openUrlExternally(`tel:${model.display}`)
}
}
}
}
Kirigami.FormLayout {
id: addreseesForm
twinFormLayouts: [emailForm, phoneForm, contactForm, businessForm]
width: parent.width
Item {
visible: addressesRepeater.count > 0
Kirigami.FormData.isSection: true
Kirigami.FormData.label: i18np("Address", "Addresses", addressesRepeater.count)
}