Commit c877080b authored by camilo higuita's avatar camilo higuita

better updating of the contacts, not losing the photo image

parent cf2af1f1
#include "contactimage.h" #include "contactimage.h"
#ifdef STATIC_MAUIKIT #ifdef Q_OS_ANDROID
#include "mauiandroid.h" #include "mauiandroid.h"
#else
#include "linuxinterface.h"
#endif #endif
#include <QDebug> #include <QDebug>
...@@ -14,8 +16,10 @@ QImage ContactImage::requestImage(const QString &id, QSize *size, const QSize &r ...@@ -14,8 +16,10 @@ QImage ContactImage::requestImage(const QString &id, QSize *size, const QSize &r
{ {
qDebug()<< "requesting contact image with id "<< id; qDebug()<< "requesting contact image with id "<< id;
QImage result; QImage result;
#ifdef STATIC_MAUIKIT #ifdef Q_OS_ANDROID
result = MAUIAndroid::contactPhoto(id); result = MAUIAndroid::contactPhoto(id);
#else
result = LinuxInterface::contactPhoto(id);
#endif #endif
if(result.isNull()) { if(result.isNull()) {
......
...@@ -30,28 +30,99 @@ ...@@ -30,28 +30,99 @@
#include <KPeople/PersonData> #include <KPeople/PersonData>
#include <KPeople/KPeopleBackend/AbstractContact> #include <KPeople/KPeopleBackend/AbstractContact>
#include <QDirIterator> #include <QDirIterator>
#include <algorithm>
using namespace KContacts; using namespace KContacts;
LinuxInterface::LinuxInterface(QObject *parent) : AbstractInterface(parent) {} LinuxInterface::LinuxInterface(QObject *parent) : AbstractInterface(parent) {}
static FMH::MODEL vCardData(const QString &url)
{
FMH::MODEL res;
QFile file(url);
if (!(file.exists()))
{
qWarning() << "Can't read vcard, file doesn't exist";
return res;
}
if (!file.open(QIODevice::ReadOnly))
{
qWarning() << "Couldn't update vCard: Couldn't open file for reading / writing.";
return res;
}
VCardConverter converter;
Addressee adr = converter.parseVCard(file.readAll());
qDebug()<< adr.url().toString() <<adr.customs() << adr.formattedName() << adr.fullEmail();
res = { {FMH::MODEL_KEY::ID, QStringLiteral("vcard:/")+url},
{FMH::MODEL_KEY::N, adr.name()},
{FMH::MODEL_KEY::ORG, adr.organization()},
{FMH::MODEL_KEY::GENDER, adr.gender().gender()},
{FMH::MODEL_KEY::TITLE, adr.title()},
{FMH::MODEL_KEY::NOTE, adr.note()},
{FMH::MODEL_KEY::URL, adr.url().toString()},
{FMH::MODEL_KEY::FAV, adr.custom("fav", "fav")},
{FMH::MODEL_KEY::EMAIL, adr.emails().join(",")},
{FMH::MODEL_KEY::TEL, [phones = adr.phoneNumbers(PhoneNumber::Cell)]()
{
return std::accumulate(phones.begin(), phones.end(), QStringList(), [](QStringList &value, const PhoneNumber &number) -> QStringList
{
return value << number.number();
});
}().join(",")
},
{FMH::MODEL_KEY::PHOTO, adr.photo().url()}
};
qDebug() << adr.toString();
// file.write(vcard);
file.close();
// return true;
return res;
}
void LinuxInterface::getContacts() void LinuxInterface::getContacts()
{ {
KPeople::PersonsModel model; KPeople::PersonsModel model;
qDebug()<< "KPEOPLE CONTACTS" << model.rowCount(); qDebug()<< "KPEOPLE CONTACTS" << model.rowCount();
for(auto i = 0 ; i< model.rowCount(); i++)
{ QDir dir;
const auto uri = model.get(i, KPeople::PersonsModel::PersonUriRole).toString(); dir.setPath(this->path);
KPeople::PersonData person(uri); // for(auto url : dir.entryList({"*.vcf"}, QDir::Filter::Files))
this->m_contacts << FMH::MODEL { // {
{FMH::MODEL_KEY::ID, person.personUri()}, // qDebug()<< url;
{FMH::MODEL_KEY::N, person.name()}, // }
{FMH::MODEL_KEY::FAV, person.contactCustomProperty(FMH::MODEL_NAME[FMH::MODEL_KEY::FAV]).toString()},
{FMH::MODEL_KEY::EMAIL, person.email()}, QDirIterator it(this->path, {"*.vcf"}, QDir::Files | QDir::NoSymLinks | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
{FMH::MODEL_KEY::TEL, person.contactCustomProperty("phoneNumber").toString()},
{FMH::MODEL_KEY::PHOTO, person.pictureUrl().toString()}}; while(it.hasNext())
} {
this->m_contacts << vCardData(it.next());
}
// for(auto i = 0 ; i< model.rowCount(); i++)
// {
// const auto uri = model.get(i, KPeople::PersonsModel::PersonUriRole).toString();
// KPeople::PersonData person(uri);
// this->m_contacts << FMH::MODEL {
// {FMH::MODEL_KEY::ID, person.personUri()},
// {FMH::MODEL_KEY::N, person.name()},
// {FMH::MODEL_KEY::FAV, person.contactCustomProperty(FMH::MODEL_NAME[FMH::MODEL_KEY::FAV]).toString()},
// {FMH::MODEL_KEY::EMAIL, person.email()},
// {FMH::MODEL_KEY::TEL, person.contactCustomProperty("phoneNumber").toString()},
// {FMH::MODEL_KEY::PHOTO, person.pictureUrl().toString()}};
//qDebug() << "CUSTOM RPOP" << person.contactCustomProperty(FMH::MODEL_NAME[FMH::MODEL_KEY::FAV]).toString();
//qDebug() << "CUSTOM RPOP" << person.contactCustomProperty("fav");
//qDebug()<< person.contactCustomProperty("phoneNumber").toString();
//}
emit this->contactsReady(this->m_contacts); emit this->contactsReady(this->m_contacts);
} }
...@@ -80,12 +151,7 @@ FMH::MODEL LinuxInterface::getContact(const QString &id) ...@@ -80,12 +151,7 @@ FMH::MODEL LinuxInterface::getContact(const QString &id)
Addressee adr = converter.parseVCard(file.readAll()); Addressee adr = converter.parseVCard(file.readAll());
res = { res = {
{FMH::MODEL_KEY::ID, id}, };
{FMH::MODEL_KEY::N, adr.name()},
// {FMH::MODEL_KEY::FAV, adr.customs()},
{FMH::MODEL_KEY::EMAIL, adr.emails().join(",")},
{FMH::MODEL_KEY::TEL, adr.phoneNumber(PhoneNumber::Cell).toString()},
{FMH::MODEL_KEY::PHOTO, adr.photo().url()}};
return res; return res;
} }
...@@ -96,7 +162,7 @@ bool LinuxInterface::insertContact(const FMH::MODEL &contact) ...@@ -96,7 +162,7 @@ bool LinuxInterface::insertContact(const FMH::MODEL &contact)
// addresses // addresses
Addressee adr; Addressee adr;
adr.setName(contact[FMH::MODEL_KEY::N]); adr.setName(contact[FMH::MODEL_KEY::N]);
adr.setUid(contact[FMH::MODEL_KEY::ID]); // adr.setUid(contact[FMH::MODEL_KEY::ID]);
adr.setUrl(contact[FMH::MODEL_KEY::URL]); adr.setUrl(contact[FMH::MODEL_KEY::URL]);
adr.setNote(contact[FMH::MODEL_KEY::NOTE]); adr.setNote(contact[FMH::MODEL_KEY::NOTE]);
adr.setTitle(contact[FMH::MODEL_KEY::TITLE]); adr.setTitle(contact[FMH::MODEL_KEY::TITLE]);
...@@ -257,3 +323,24 @@ bool LinuxInterface::removeContact(const QString &id) ...@@ -257,3 +323,24 @@ bool LinuxInterface::removeContact(const QString &id)
return QFile::remove(QString(id).remove("vcard:/")); return QFile::remove(QString(id).remove("vcard:/"));
} }
QImage LinuxInterface::contactPhoto(const QString &id)
{
auto personUri = id;
if (!(QUrl(personUri).scheme() == "vcard"))
{
qWarning() << "uri of contact is not a vcard, cannot get photo.";
return QImage();
}
QFileInfo file(personUri.remove("vcard:/"));
if (!(file.exists()))
{
qWarning() << "Can't read vcard, file doesn't exist";
return QImage();
}
qDebug()<< "IMAGE FILE REQUESTED"<< vCardData(personUri)[FMH::MODEL_KEY::PHOTO];
return QImage(vCardData(personUri)[FMH::MODEL_KEY::PHOTO].replace("file://", ""));
}
...@@ -44,6 +44,8 @@ public: ...@@ -44,6 +44,8 @@ public:
bool removeContact(const QString &id) override final; bool removeContact(const QString &id) override final;
static QImage contactPhoto(const QString &id);
private: private:
const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
+ ("/kpeoplevcard"); + ("/kpeoplevcard");
......
...@@ -79,15 +79,14 @@ void ContactsModel::sortList() ...@@ -79,15 +79,14 @@ void ContactsModel::sortList()
return; return;
const auto key = static_cast<FMH::MODEL_KEY>(this->sort); const auto key = static_cast<FMH::MODEL_KEY>(this->sort);
std::sort(this->list.begin(), this->list.end(), [key](const FMH::MODEL &e1, const FMH::MODEL &e2) -> bool std::sort(this->list.begin(), this->list.end(), [&key](const FMH::MODEL &e1, const FMH::MODEL &e2) -> bool
{ {
auto role = key;
switch(role) switch(key)
{ {
case FMH::MODEL_KEY::FAV: case FMH::MODEL_KEY::FAV:
{ {
if(e1[role].toInt() > e2[role].toInt()) if(e1[key].toInt() > e2[key].toInt())
return true; return true;
break; break;
} }
...@@ -97,8 +96,8 @@ void ContactsModel::sortList() ...@@ -97,8 +96,8 @@ void ContactsModel::sortList()
{ {
auto currentTime = QDateTime::currentDateTime(); auto currentTime = QDateTime::currentDateTime();
auto date1 = QDateTime::fromString(e1[role], Qt::TextDate); auto date1 = QDateTime::fromString(e1[key], Qt::TextDate);
auto date2 = QDateTime::fromString(e2[role], Qt::TextDate); auto date2 = QDateTime::fromString(e2[key], Qt::TextDate);
if(date1.secsTo(currentTime) < date2.secsTo(currentTime)) if(date1.secsTo(currentTime) < date2.secsTo(currentTime))
return true; return true;
...@@ -114,8 +113,8 @@ void ContactsModel::sortList() ...@@ -114,8 +113,8 @@ void ContactsModel::sortList()
case FMH::MODEL_KEY::GENDER: case FMH::MODEL_KEY::GENDER:
case FMH::MODEL_KEY::ADR: case FMH::MODEL_KEY::ADR:
{ {
const auto str1 = QString(e1[role]).toLower(); const auto str1 = QString(e1[key]).toLower();
const auto str2 = QString(e2[role]).toLower(); const auto str2 = QString(e2[key]).toLower();
if(str1 < str2) if(str1 < str2)
return true; return true;
...@@ -123,7 +122,7 @@ void ContactsModel::sortList() ...@@ -123,7 +122,7 @@ void ContactsModel::sortList()
} }
default: default:
if(e1[role] < e2[role]) if(e1[key] < e2[key])
return true; return true;
} }
...@@ -162,16 +161,16 @@ bool ContactsModel::insert(const QVariantMap &map) ...@@ -162,16 +161,16 @@ bool ContactsModel::insert(const QVariantMap &map)
if(map.isEmpty()) if(map.isEmpty())
return false; return false;
auto model = FM::toModel(map); const auto model = FM::toModel(map);
if(!this->syncer->insertContact(model)) if(!this->syncer->insertContact(model))
return false; return false;
qDebug()<< "inserting new contact count" << this->list.count(); qDebug()<< "inserting new contact count" << this->list.count();
emit this->preItemAppended(); emit this->preItemAppended();
this->list.append(model); this->list << model;
emit this->postItemAppended();
this->sortList(); this->sortList();
emit this->postItemAppended();
qDebug()<< "inserting new contact count" << this->list.count(); qDebug()<< "inserting new contact count" << this->list.count();
return true; return true;
...@@ -185,8 +184,6 @@ bool ContactsModel::update(const QVariantMap &map, const int &index) ...@@ -185,8 +184,6 @@ bool ContactsModel::update(const QVariantMap &map, const int &index)
const auto newItem = FM::toModel(map); const auto newItem = FM::toModel(map);
const auto oldItem = this->list[index]; const auto oldItem = this->list[index];
auto updatedItem = FMH::MODEL(); auto updatedItem = FMH::MODEL();
updatedItem[FMH::MODEL_KEY::ID] = oldItem[FMH::MODEL_KEY::ID]; updatedItem[FMH::MODEL_KEY::ID] = oldItem[FMH::MODEL_KEY::ID];
......
...@@ -79,7 +79,10 @@ Maui.Dialog ...@@ -79,7 +79,10 @@ Maui.Dialog
icon.name: "draw-star" icon.name: "draw-star"
text: qsTr("Fav") text: qsTr("Fav")
icon.color: contact.fav == "1" ? "#FFD700" : Kirigami.Theme.textColor checked: contact.fav == "1"
checkable: false
Kirigami.Theme.textColor: checked ? "#FFD700" : Kirigami.Theme.textColor
Kirigami.Theme.backgroundColor: checked ? "#FFD700" : Kirigami.Theme.textColor
onTriggered: onTriggered:
{ {
contact["fav"] = contact.fav == "1" ? "0" : "1" contact["fav"] = contact.fav == "1" ? "0" : "1"
...@@ -234,7 +237,6 @@ Maui.Dialog ...@@ -234,7 +237,6 @@ Maui.Dialog
width: _img.width width: _img.width
height: _img.height height: _img.height
radius: radiusV* 2 radius: radiusV* 2
border.color: borderColor
} }
} }
} }
......
...@@ -34,7 +34,7 @@ Maui.Dialog ...@@ -34,7 +34,7 @@ Maui.Dialog
email: _emailField.text, email: _emailField.text,
org: _orgField.text, org: _orgField.text,
// adr: _adrField.text, // adr: _adrField.text,
photo: _img.source, photo: control.contact.photo,
account: isAndroid ? _accountsCombobox.model[_accountsCombobox.currentIndex] :({}) account: isAndroid ? _accountsCombobox.model[_accountsCombobox.currentIndex] :({})
}) })
...@@ -63,7 +63,7 @@ Maui.Dialog ...@@ -63,7 +63,7 @@ Maui.Dialog
height: Math.min(parent.height, control.width) height: Math.min(parent.height, control.width)
width: height width: height
anchors.centerIn: parent anchors.centerIn: parent
radius: Math.min(width, height) radius: radiusV* 2
color: Qt.rgba(Math.random(),Math.random(),Math.random(),1); color: Qt.rgba(Math.random(),Math.random(),Math.random(),1);
border.color: Qt.darker(color, 1.5) border.color: Qt.darker(color, 1.5)
...@@ -77,57 +77,90 @@ Maui.Dialog ...@@ -77,57 +77,90 @@ Maui.Dialog
_fileDialog.show(function(paths) _fileDialog.show(function(paths)
{ {
console.log("selected image", paths) console.log("selected image", paths)
_img.source = "file://"+paths[0] contact.photo = "file://"+paths[0]
_contactPicLoader.sourceComponent = _imgComponent
_contactPicLoader.item.source = contact.photo
}) })
} }
} }
Image Loader
{ {
id: _img id: _contactPicLoader
width: parent.width anchors.fill: parent
height: width sourceComponent: contact.photo ? _imgComponent : _iconComponent
}
anchors.centerIn: parent Component
{
id: _imgComponent
sourceSize.width: parent.width Image
sourceSize.height: parent.height {
id: _img
width: parent.width
height: width
fillMode: Image.PreserveAspectCrop anchors.centerIn: parent
cache: true
antialiasing: true
smooth: true
asynchronous: true
layer.enabled: true sourceSize.width: parent.width
layer.effect: OpacityMask sourceSize.height: parent.height
{
maskSource: Item fillMode: Image.PreserveAspectCrop
{ cache: true
width: _img.width antialiasing: true
height: _img.height smooth: true
asynchronous: true
Rectangle source: "image://contact/"+ contact.id
layer.enabled: true
layer.effect: OpacityMask
{
maskSource: Item
{ {
anchors.centerIn: parent
width: _img.width width: _img.width
height: _img.height height: _img.height
radius: Math.min(width, height)
// border.color: borderColor Rectangle
{
anchors.centerIn: parent
width: _img.width
height: _img.height
radius: radiusV* 2
}
} }
} }
} }
} }
ToolButton Component
{ {
icon.name: "list-add" id: _iconComponent
icon.color: "white"
enabled: false // Maui.ToolButton
icon.width: iconSizes.big // {
anchors.centerIn: parent // iconName: "view-media-artist"
// size: iconSizes.big
// iconColor: "white"
// }
Label
{
anchors.fill: parent
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
color: "white"
font.pointSize: fontSizes.huge * 1.5
font.bold: true
font.weight: Font.Bold
text: "+"
}
} }
} }
} }
...@@ -316,7 +349,8 @@ Maui.Dialog ...@@ -316,7 +349,8 @@ Maui.Dialog
_emailField.clear() _emailField.clear()
_orgField.clear() _orgField.clear()
// _adrField.clear() // _adrField.clear()
_img.source = "" // _img.source = ""
_contactPicLoader.sourceComponent = _iconComponent
control.close() control.close()
} }
......
...@@ -81,7 +81,6 @@ ItemDelegate ...@@ -81,7 +81,6 @@ ItemDelegate
width: _img.width width: _img.width
height: _img.height height: _img.height
radius: radiusV radius: radiusV
border.color: borderColor
} }
} }
} }
......
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