Commit 5537900b authored by Ronan's avatar Ronan

feat(ui/views/App/Settings/SettingsUi): add a button to remove avatars

parent 277e5d40
......@@ -1110,6 +1110,14 @@ your friend&apos;s SIP address or username.</translation>
<source>systemLocale</source>
<translation>System locale</translation>
</message>
<message>
<source>cleanAvatars</source>
<translation>CLEAN AVATARS</translation>
</message>
<message>
<source>cleanAvatarsDescription</source>
<translation>Are you sure you want to clean all avatars?</translation>
</message>
</context>
<context>
<name>SettingsVideo</name>
......
......@@ -1109,6 +1109,14 @@ un chat ou ajouter un contact.</translation>
<source>systemLocale</source>
<translation>Locale du système</translation>
</message>
<message>
<source>cleanAvatars</source>
<translation>SUPPRIMER AVATARS</translation>
</message>
<message>
<source>cleanAvatarsDescription</source>
<translation>Voulez-vous vraiment supprimer tous les avatars ?</translation>
</message>
</context>
<context>
<name>SettingsVideo</name>
......
......@@ -377,6 +377,7 @@
<file>ui/views/App/Settings/SettingsSipAccountsEdit.qml</file>
<file>ui/views/App/Settings/SettingsSipAccounts.js</file>
<file>ui/views/App/Settings/SettingsSipAccounts.qml</file>
<file>ui/views/App/Settings/SettingsUi.js</file>
<file>ui/views/App/Settings/SettingsUi.qml</file>
<file>ui/views/App/Settings/SettingsVideo.js</file>
<file>ui/views/App/Settings/SettingsVideoPreview.qml</file>
......
......@@ -52,10 +52,6 @@ namespace Utils {
return findParentType<T>(parent);
}
// Bring a window to front.
// See: http://stackoverflow.com/questions/6087887/bring-window-to-front-raise-show-activatewindow-don-t-work
void smartShowWindow (QQuickWindow *window);
// Reverse function of strstr.
char *rstrstr (const char *a, const char *b);
}
......
......@@ -303,7 +303,7 @@ void registerType (const char *name) {
}
void App::registerTypes () {
qInfo() << "Registering types...";
qInfo() << QStringLiteral("Registering types...");
registerType<AssistantModel>("AssistantModel");
registerType<AuthenticationNotifier>("AuthenticationNotifier");
......
......@@ -56,7 +56,8 @@ inline shared_ptr<T> findBelCardValue (const list<shared_ptr<T> > &list, const Q
return nullptr;
}
inline shared_ptr<belcard::BelCardPhoto> findBelCardPhoto (const list<shared_ptr<belcard::BelCardPhoto> > &photos) {
inline shared_ptr<belcard::BelCardPhoto> findBelcardPhoto (const shared_ptr<belcard::BelCard> &belcard) {
const list<shared_ptr<belcard::BelCardPhoto> > &photos = belcard->getPhotos();
auto it = find_if(
photos.cbegin(), photos.cend(), [](const shared_ptr<belcard::BelCardPhoto> &photo) {
return !photo->getValue().compare(0, sizeof(VCARD_SCHEME) - 1, VCARD_SCHEME);
......@@ -69,6 +70,21 @@ inline shared_ptr<belcard::BelCardPhoto> findBelCardPhoto (const list<shared_ptr
return nullptr;
}
inline void removeBelcardPhoto (const shared_ptr<belcard::BelCard> &belcard) {
shared_ptr<belcard::BelCardPhoto> oldPhoto = findBelcardPhoto(belcard);
if (oldPhoto) {
QString imagePath(
::Utils::linphoneStringToQString(
Paths::getAvatarsDirPath() + oldPhoto->getValue().substr(sizeof(VCARD_SCHEME) - 1)
)
);
if (!QFile::remove(imagePath))
qWarning() << QStringLiteral("Unable to remove `%1`.").arg(imagePath);
belcard->removePhoto(oldPhoto);
}
}
// -----------------------------------------------------------------------------
VcardModel::VcardModel (shared_ptr<linphone::Vcard> vcard) {
......@@ -77,9 +93,11 @@ VcardModel::VcardModel (shared_ptr<linphone::Vcard> vcard) {
}
VcardModel::~VcardModel () {
// If it's a detached Vcard, the linked photo must be destroyed from fs.
// If it's a detached Vcard and if necessary the linked photo must be destroyed from fs.
if (App::getInstance()->getEngine()->objectOwnership(this) != QQmlEngine::CppOwnership) {
shared_ptr<belcard::BelCardPhoto> photo(findBelCardPhoto(mVcard->getVcard()->getPhotos()));
qInfo() << QStringLiteral("Destroy detached vcard:") << this;
shared_ptr<belcard::BelCardPhoto> photo(findBelcardPhoto(mVcard->getVcard()));
if (!photo)
return;
......@@ -92,8 +110,6 @@ VcardModel::~VcardModel () {
if (!QFile::remove(imagePath))
qWarning() << QStringLiteral("Unable to remove `%1`.").arg(imagePath);
qInfo() << QStringLiteral("Destroy detached vcard:") << this;
} else
qInfo() << QStringLiteral("Destroy attached vcard:") << this;
}
......@@ -113,24 +129,9 @@ VcardModel *VcardModel::clone () const {
// -----------------------------------------------------------------------------
QString VcardModel::getUsername () const {
return ::Utils::linphoneStringToQString(mVcard->getFullName());
}
void VcardModel::setUsername (const QString &username) {
if (username.length() == 0 || username == getUsername())
return;
mVcard->setFullName(::Utils::qStringToLinphoneString(username));
emit vcardUpdated();
}
// -----------------------------------------------------------------------------
QString VcardModel::getAvatar () const {
// Find desktop avatar.
list<shared_ptr<belcard::BelCardPhoto> > photos = mVcard->getVcard()->getPhotos();
shared_ptr<belcard::BelCardPhoto> photo = findBelCardPhoto(photos);
shared_ptr<belcard::BelCardPhoto> photo = findBelcardPhoto(mVcard->getVcard());
// No path found.
if (!photo)
......@@ -143,6 +144,16 @@ QString VcardModel::getAvatar () const {
}
bool VcardModel::setAvatar (const QString &path) {
shared_ptr<belcard::BelCard> belcard = mVcard->getVcard();
// Remove avatar if path is empty.
if (path.isEmpty()) {
removeBelcardPhoto(belcard);
emit vcardUpdated();
return true;
}
// 1. Try to copy photo in avatars folder.
QFile file(path);
......@@ -162,37 +173,37 @@ bool VcardModel::setAvatar (const QString &path) {
qInfo() << QStringLiteral("Update avatar of `%1`. (path=%2)").arg(getUsername()).arg(dest);
// 2. Edit vcard.
shared_ptr<belcard::BelCard> belcard = mVcard->getVcard();
list<shared_ptr<belcard::BelCardPhoto> > photos = belcard->getPhotos();
// 2. Remove oldest photo.
removeBelcardPhoto(belcard);
// 3. Remove oldest photo.
shared_ptr<belcard::BelCardPhoto> oldPhoto = findBelCardPhoto(photos);
if (oldPhoto) {
QString imagePath(
::Utils::linphoneStringToQString(
Paths::getAvatarsDirPath() + oldPhoto->getValue().substr(sizeof(VCARD_SCHEME) - 1)
)
);
if (!QFile::remove(imagePath))
qWarning() << QStringLiteral("Unable to remove `%1`.").arg(imagePath);
belcard->removePhoto(oldPhoto);
}
// 4. Update.
// 3. Update new photo.
shared_ptr<belcard::BelCardPhoto> photo = belcard::BelCardGeneric::create<belcard::BelCardPhoto>();
photo->setValue(VCARD_SCHEME + ::Utils::qStringToLinphoneString(fileId));
emit vcardUpdated();
if (!belcard->addPhoto(photo))
return false;
emit vcardUpdated();
return true;
}
// -----------------------------------------------------------------------------
QString VcardModel::getUsername () const {
return ::Utils::linphoneStringToQString(mVcard->getFullName());
}
void VcardModel::setUsername (const QString &username) {
if (username.length() == 0 || username == getUsername())
return;
mVcard->setFullName(::Utils::qStringToLinphoneString(username));
emit vcardUpdated();
}
// -----------------------------------------------------------------------------
inline shared_ptr<belcard::BelCardAddress> getOrCreateBelCardAddress (shared_ptr<belcard::BelCard> belcard) {
list<shared_ptr<belcard::BelCardAddress> > addresses = belcard->getAddresses();
shared_ptr<belcard::BelCardAddress> address;
......
......@@ -41,13 +41,30 @@ class VcardModel : public QObject {
Q_PROPERTY(QVariantList emails READ getEmails NOTIFY vcardUpdated);
Q_PROPERTY(QVariantList urls READ getUrls NOTIFY vcardUpdated);
// ---------------------------------------------------------------------------
public:
VcardModel (std::shared_ptr<linphone::Vcard> vcard);
~VcardModel ();
// ---------------------------------------------------------------------------
QString getAvatar () const;
bool setAvatar (const QString &path);
QString getUsername () const;
void setUsername (const QString &username);
// ---------------------------------------------------------------------------
QVariantList getSipAddresses () const;
QVariantMap getAddress () const;
QVariantList getEmails () const;
QVariantList getCompanies () const;
QVariantList getUrls () const;
// ---------------------------------------------------------------------------
Q_INVOKABLE VcardModel *clone () const;
......@@ -72,20 +89,14 @@ public:
Q_INVOKABLE void setPostalCode (const QString &postalCode);
Q_INVOKABLE void setCountry (const QString &country);
// ---------------------------------------------------------------------------
signals:
void vcardUpdated ();
private:
void setUsername (const QString &username);
QString getAvatar () const;
bool setAvatar (const QString &path);
QVariantMap getAddress () const;
QVariantList getCompanies () const;
QVariantList getEmails () const;
QVariantList getUrls () const;
// ---------------------------------------------------------------------------
private:
std::shared_ptr<linphone::Vcard> mVcard;
};
......
......@@ -139,6 +139,18 @@ void ContactsListModel::removeContact (ContactModel *contact) {
// -----------------------------------------------------------------------------
void ContactsListModel::cleanAvatars () {
qInfo() << QStringLiteral("Delete all avatars.");
for (const auto &contact : mList) {
contact->startEdit();
contact->getVcardModel()->setAvatar("");
contact->endEdit();
}
}
// -----------------------------------------------------------------------------
void ContactsListModel::addContact (ContactModel *contact) {
QObject::connect(
contact, &ContactModel::contactUpdated,
......
......@@ -50,6 +50,8 @@ public:
Q_INVOKABLE ContactModel *addContact (VcardModel *vcard);
Q_INVOKABLE void removeContact (ContactModel *contact);
Q_INVOKABLE void cleanAvatars ();
signals:
void contactAdded (ContactModel *contact);
void contactRemoved (const ContactModel *contact);
......
......@@ -8,6 +8,19 @@
// =============================================================================
function handleContactUpdated () {
var contact = contactEdit._contact
if (!contactEdit._edition) {
// Edition ended.
handleVcardChanged(contact.vcard)
} else {
// Edition not ended, the contact was updated in other place.
// Update fields with new data.
contactEdit._vcard = contact.vcard.clone()
}
}
function handleCreation () {
var sipAddress = contactEdit.sipAddress
var contact = contactEdit._contact = Linphone.SipAddressesModel.mapSipAddressToContact(
......@@ -74,6 +87,8 @@ function save () {
var contact = contactEdit._contact
var vcard = contactEdit._vcard
contactEdit._edition = false
if (contact) {
contact.vcard = vcard
contact.endEdit()
......@@ -81,8 +96,6 @@ function save () {
} else {
contactEdit._contact = Linphone.ContactsListModel.addContact(vcard)
}
contactEdit._edition = false
}
function cancel () {
......@@ -121,7 +134,6 @@ function handleValueChanged (fields, index, oldValue, newValue, add, update) {
return
}
console.log('handle', oldValue, newValue)
var vcard = contactEdit._vcard
var soFarSoGood = (oldValue.length === 0)
? vcard[add](newValue)
......
......@@ -39,7 +39,7 @@ ColumnLayout {
sourceComponent: Connections {
target: contactEdit._contact
onContactUpdated: Logic.handleVcardChanged(contactEdit._contact.vcard)
onContactUpdated: Logic.handleContactUpdated()
}
}
......
// =============================================================================
// `SettingsUi.qml` Logic.
// =============================================================================
.import Linphone 1.0 as Linphone
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
function cleanAvatars () {
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
descriptionText: qsTr('cleanAvatarsDescription'),
}, function (status) {
if (status) {
Linphone.ContactsListModel.cleanAvatars()
}
})
}
......@@ -6,6 +6,8 @@ import Utils 1.0
import App.Styles 1.0
import 'SettingsUi.js' as Logic
// =============================================================================
TabContainer {
......@@ -106,6 +108,15 @@ TabContainer {
}
}
}
FormEmptyLine {}
}
TextButtonB {
anchors.right: parent.right
text: qsTr('cleanAvatars')
onClicked: Logic.cleanAvatars()
}
}
}
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