mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
Change contacts list to take account of all contacts in database (multiple lists, bodyless, remote provision)
This commit is contained in:
parent
04f3997fd9
commit
ced6a8b396
10 changed files with 187 additions and 33 deletions
|
|
@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- New call layouts.
|
||||
- Display a waiting room before going into a conference.
|
||||
- Log viewer.
|
||||
- Read contacts from all friends lists.
|
||||
- Option to set the display name in "using an account" tab of assistant.
|
||||
- Long pressed buttons.
|
||||
- Phone dialpad on main window.
|
||||
|
|
|
|||
|
|
@ -204,6 +204,7 @@ set(SOURCES
|
|||
src/components/core/event-count-notifier/AbstractEventCountNotifier.cpp
|
||||
src/components/file/FileDownloader.cpp
|
||||
src/components/file/FileExtractor.cpp
|
||||
src/components/friend/FriendListListener.cpp
|
||||
src/components/history/HistoryModel.cpp
|
||||
src/components/history/HistoryProxyModel.cpp
|
||||
src/components/ldap/LdapModel.cpp
|
||||
|
|
@ -338,6 +339,7 @@ set(HEADERS
|
|||
src/components/core/event-count-notifier/AbstractEventCountNotifier.hpp
|
||||
src/components/file/FileDownloader.hpp
|
||||
src/components/file/FileExtractor.hpp
|
||||
src/components/friend/FriendListListener.hpp
|
||||
src/components/history/HistoryModel.hpp
|
||||
src/components/history/HistoryProxyModel.hpp
|
||||
src/components/ldap/LdapModel.hpp
|
||||
|
|
|
|||
|
|
@ -215,3 +215,7 @@ Presence::PresenceLevel ContactModel::getPresenceLevel () const {
|
|||
bool ContactModel::hasCapability(const LinphoneEnums::FriendCapability& capability){
|
||||
return mLinphoneFriend->hasCapability(LinphoneEnums::toLinphone(capability));
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::Friend> ContactModel::getFriend() const{
|
||||
return mLinphoneFriend;
|
||||
}
|
||||
|
|
@ -57,6 +57,8 @@ public:
|
|||
Q_INVOKABLE VcardModel *cloneVcardModel () const;
|
||||
Presence::PresenceLevel getPresenceLevel () const;
|
||||
Q_INVOKABLE bool hasCapability(const LinphoneEnums::FriendCapability& capability);
|
||||
|
||||
std::shared_ptr<linphone::Friend> getFriend() const;
|
||||
|
||||
signals:
|
||||
void contactUpdated ();
|
||||
|
|
|
|||
|
|
@ -24,40 +24,26 @@
|
|||
#include "components/contact/ContactModel.hpp"
|
||||
#include "components/contact/VcardModel.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/friend/FriendListListener.hpp"
|
||||
|
||||
#include "ContactsListModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
void ContactsListModel::connectTo(FriendListListener * listener){
|
||||
connect(listener, &FriendListListener::contactCreated, this, &ContactsListModel::onContactCreated);
|
||||
connect(listener, &FriendListListener::contactDeleted, this, &ContactsListModel::onContactDeleted);
|
||||
connect(listener, &FriendListListener::contactUpdated, this, &ContactsListModel::onContactUpdated);
|
||||
connect(listener, &FriendListListener::syncStatusChanged, this, &ContactsListModel::onSyncStatusChanged);
|
||||
connect(listener, &FriendListListener::presenceReceived, this, &ContactsListModel::onPresenceReceived);
|
||||
}
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
ContactsListModel::ContactsListModel (QObject *parent) : ProxyListModel(parent) {
|
||||
mLinphoneFriends = CoreManager::getInstance()->getCore()->getFriendsLists().front();
|
||||
// Clean friends.
|
||||
{
|
||||
list<shared_ptr<linphone::Friend>> toRemove;
|
||||
for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) {
|
||||
if (!linphoneFriend->getVcard())
|
||||
toRemove.push_back(linphoneFriend);
|
||||
}
|
||||
|
||||
for (const auto &linphoneFriend : toRemove) {
|
||||
qWarning() << QStringLiteral("Remove one friend without vcard.");
|
||||
mLinphoneFriends->removeFriend(linphoneFriend);
|
||||
}
|
||||
}
|
||||
|
||||
// Init contacts with linphone friends list.
|
||||
QQmlEngine *engine = App::getInstance()->getEngine();
|
||||
for (const auto &linphoneFriend : mLinphoneFriends->getFriends()) {
|
||||
auto contact = QSharedPointer<ContactModel>::create(linphoneFriend);
|
||||
|
||||
// See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership
|
||||
// The returned value must have a explicit parent or a QQmlEngine::CppOwnership.
|
||||
engine->setObjectOwnership(contact.get(), QQmlEngine::CppOwnership);
|
||||
|
||||
addContact(contact);
|
||||
}
|
||||
mFriendListListener = std::make_shared<FriendListListener>();
|
||||
connectTo(mFriendListListener.get());
|
||||
update();
|
||||
}
|
||||
|
||||
ContactsListModel::~ContactsListModel(){
|
||||
|
|
@ -65,7 +51,7 @@ ContactsListModel::~ContactsListModel(){
|
|||
beginResetModel();
|
||||
mOptimizedSearch.clear();
|
||||
mList.clear();
|
||||
mLinphoneFriends = nullptr;
|
||||
mLinphoneFriends.clear();
|
||||
endResetModel();
|
||||
}
|
||||
}
|
||||
|
|
@ -84,7 +70,8 @@ bool ContactsListModel::removeRows (int row, int count, const QModelIndex &paren
|
|||
mOptimizedSearch.remove(address.toString());
|
||||
}
|
||||
|
||||
mLinphoneFriends->removeFriend(contact->mLinphoneFriend);
|
||||
for(auto l : mLinphoneFriends)
|
||||
l->removeFriend(contact->mLinphoneFriend);
|
||||
|
||||
emit contactRemoved(contact);
|
||||
}
|
||||
|
|
@ -123,7 +110,7 @@ ContactModel *ContactsListModel::addContact (VcardModel *vcardModel) {
|
|||
contact = QSharedPointer<ContactModel>::create(vcardModel);
|
||||
App::getInstance()->getEngine()->setObjectOwnership(contact.get(), QQmlEngine::CppOwnership);
|
||||
|
||||
if (mLinphoneFriends->addFriend(contact->mLinphoneFriend) != linphone::FriendList::Status::OK) {
|
||||
if (mLinphoneFriends.front()->addFriend(contact->mLinphoneFriend) != linphone::FriendList::Status::OK) {
|
||||
qWarning() << QStringLiteral("Unable to add contact from vcard:") << vcardModel;
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -131,9 +118,8 @@ ContactModel *ContactsListModel::addContact (VcardModel *vcardModel) {
|
|||
qInfo() << QStringLiteral("Add contact from vcard:") << contact.get() << vcardModel;
|
||||
|
||||
// Make sure new subscribe is issued.
|
||||
mLinphoneFriends->updateSubscriptions();
|
||||
mLinphoneFriends.front()->updateSubscriptions();
|
||||
|
||||
addContact(contact);
|
||||
emit layoutChanged();
|
||||
|
||||
emit contactAdded(contact);
|
||||
|
|
@ -177,3 +163,47 @@ void ContactsListModel::addContact (QSharedPointer<ContactModel> contact) {
|
|||
mOptimizedSearch[address.toString()] = contact;
|
||||
}
|
||||
}
|
||||
|
||||
void ContactsListModel::update(){
|
||||
beginResetModel();
|
||||
for(auto l : mLinphoneFriends)
|
||||
l->removeListener(mFriendListListener);
|
||||
mLinphoneFriends.clear();
|
||||
mOptimizedSearch.clear();
|
||||
mList.clear();
|
||||
endResetModel();
|
||||
|
||||
mLinphoneFriends = CoreManager::getInstance()->getCore()->getFriendsLists();
|
||||
|
||||
for(auto l : mLinphoneFriends){
|
||||
l->addListener(mFriendListListener);
|
||||
for (const auto &linphoneFriend : l->getFriends()) {
|
||||
onContactCreated(linphoneFriend);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
void ContactsListModel::onContactCreated(const std::shared_ptr<linphone::Friend> & linphoneFriend){
|
||||
QQmlEngine *engine = App::getInstance()->getEngine();
|
||||
auto haveContact = std::find_if(mList.begin(), mList.end(), [linphoneFriend] (const QSharedPointer<QObject>& item){
|
||||
return item.objectCast<ContactModel>()->getFriend() == linphoneFriend;
|
||||
});
|
||||
if(haveContact == mList.end()) {
|
||||
auto contact = QSharedPointer<ContactModel>::create(linphoneFriend);
|
||||
// See: http://doc.qt.io/qt-5/qtqml-cppintegration-data.html#data-ownership
|
||||
// The returned value must have a explicit parent or a QQmlEngine::CppOwnership.
|
||||
engine->setObjectOwnership(contact.get(), QQmlEngine::CppOwnership);
|
||||
addContact(contact);
|
||||
}
|
||||
}
|
||||
void ContactsListModel::onContactDeleted(const std::shared_ptr<linphone::Friend> & linphoneFriend){
|
||||
}
|
||||
void ContactsListModel::onContactUpdated(const std::shared_ptr<linphone::Friend> & newFriend, const std::shared_ptr<linphone::Friend> & oldFriend){
|
||||
}
|
||||
void ContactsListModel::onSyncStatusChanged(linphone::FriendList::SyncStatus status, const std::string & message){
|
||||
}
|
||||
void ContactsListModel::onPresenceReceived(const std::list<std::shared_ptr<linphone::Friend>> & friends){
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ namespace linphone {
|
|||
|
||||
class ContactModel;
|
||||
class VcardModel;
|
||||
class FriendListListener;
|
||||
|
||||
class ContactsListModel : public ProxyListModel {
|
||||
friend class SipAddressesModel;
|
||||
|
|
@ -52,6 +53,16 @@ public:
|
|||
Q_INVOKABLE void removeContact (ContactModel *contact);
|
||||
|
||||
Q_INVOKABLE void cleanAvatars ();
|
||||
Q_INVOKABLE void update ();
|
||||
|
||||
void connectTo(FriendListListener * listener);
|
||||
|
||||
public slots:
|
||||
void onContactCreated(const std::shared_ptr<linphone::Friend> & linphoneFriend);
|
||||
void onContactDeleted(const std::shared_ptr<linphone::Friend> & linphoneFriend);
|
||||
void onContactUpdated(const std::shared_ptr<linphone::Friend> & newFriend, const std::shared_ptr<linphone::Friend> & oldFriend);
|
||||
void onSyncStatusChanged(linphone::FriendList::SyncStatus status, const std::string & message);
|
||||
void onPresenceReceived(const std::list<std::shared_ptr<linphone::Friend>> & friends);
|
||||
|
||||
signals:
|
||||
void contactAdded (QSharedPointer<ContactModel>);
|
||||
|
|
@ -65,7 +76,8 @@ private:
|
|||
void addContact (QSharedPointer<ContactModel> contact);
|
||||
|
||||
QMap<QString, QSharedPointer<ContactModel>> mOptimizedSearch;
|
||||
std::shared_ptr<linphone::FriendList> mLinphoneFriends;
|
||||
std::list<std::shared_ptr<linphone::FriendList>> mLinphoneFriends;
|
||||
std::shared_ptr<FriendListListener> mFriendListListener;
|
||||
};
|
||||
|
||||
#endif // CONTACTS_LIST_MODEL_H_
|
||||
|
|
|
|||
|
|
@ -260,6 +260,7 @@ void CoreManager::createLinphoneCore (const QString &configPath) {
|
|||
Paths::getFactoryConfigFilePath(),
|
||||
nullptr
|
||||
);
|
||||
setDatabasesPaths();
|
||||
// Enable LIME on your core to use encryption.
|
||||
mCore->enableLimeX3Dh(mCore->limeX3DhAvailable());
|
||||
// Now see the CoreService.CreateGroupChatRoom to see how to create a secure chat room
|
||||
|
|
@ -279,7 +280,6 @@ void CoreManager::createLinphoneCore (const QString &configPath) {
|
|||
QString userAgent = Utils::computeUserAgent(config);
|
||||
mCore->setUserAgent(Utils::appStringToCoreString(userAgent), mCore->getVersion());
|
||||
mCore->start();
|
||||
setDatabasesPaths();
|
||||
setOtherPaths();
|
||||
mCore->enableFriendListSubscription(true);
|
||||
mCore->enableRecordAware(true);
|
||||
|
|
|
|||
51
linphone-app/src/components/friend/FriendListListener.cpp
Normal file
51
linphone-app/src/components/friend/FriendListListener.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FriendListListener.hpp"
|
||||
#include "../../utils/Utils.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
FriendListListener::FriendListListener(QObject *parent) : QObject(parent) {
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
void FriendListListener::onContactCreated(const std::shared_ptr<linphone::FriendList> & friendList, const std::shared_ptr<linphone::Friend> & linphoneFriend) {
|
||||
qDebug() << "onContactCreated: " << Utils::coreStringToAppString(linphoneFriend->getName());
|
||||
emit contactCreated(linphoneFriend);
|
||||
}
|
||||
void FriendListListener::onContactDeleted(const std::shared_ptr<linphone::FriendList> & friendList, const std::shared_ptr<linphone::Friend> & linphoneFriend) {
|
||||
qDebug() << "onContactDeleted: " << Utils::coreStringToAppString(linphoneFriend->getName());
|
||||
emit contactDeleted(linphoneFriend);
|
||||
}
|
||||
void FriendListListener::onContactUpdated(const std::shared_ptr<linphone::FriendList> & friendList, const std::shared_ptr<linphone::Friend> & newFriend, const std::shared_ptr<linphone::Friend> & oldFriend) {
|
||||
qDebug() << "onContactUpdated: " << Utils::coreStringToAppString(newFriend->getName());
|
||||
emit contactUpdated(newFriend, oldFriend);
|
||||
}
|
||||
void FriendListListener::onSyncStatusChanged(const std::shared_ptr<linphone::FriendList> & friendList, linphone::FriendList::SyncStatus status, const std::string & message) {
|
||||
qDebug() << "onSyncStatusChanged: [" << (int)status<<"] " << Utils::coreStringToAppString(message);
|
||||
emit syncStatusChanged(status, message);
|
||||
}
|
||||
void FriendListListener::onPresenceReceived(const std::shared_ptr<linphone::FriendList> & friendList, const std::list<std::shared_ptr<linphone::Friend>> & friends) {
|
||||
qDebug() << "onPresenceReceived: " <<friends.size();
|
||||
emit presenceReceived(friends);
|
||||
}
|
||||
50
linphone-app/src/components/friend/FriendListListener.hpp
Normal file
50
linphone-app/src/components/friend/FriendListListener.hpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2022 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef FRIEND_LIST_LISTENER_H_
|
||||
#define FRIEND_LIST_LISTENER_H_
|
||||
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class FriendListListener : public QObject, public linphone::FriendListListener {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FriendListListener (QObject *parent = nullptr);
|
||||
virtual void onContactCreated(const std::shared_ptr<linphone::FriendList> & friendList, const std::shared_ptr<linphone::Friend> & linphoneFriend) override;
|
||||
virtual void onContactDeleted(const std::shared_ptr<linphone::FriendList> & friendList, const std::shared_ptr<linphone::Friend> & linphoneFriend) override;
|
||||
virtual void onContactUpdated(const std::shared_ptr<linphone::FriendList> & friendList, const std::shared_ptr<linphone::Friend> & newFriend, const std::shared_ptr<linphone::Friend> & oldFriend) override;
|
||||
virtual void onSyncStatusChanged(const std::shared_ptr<linphone::FriendList> & friendList, linphone::FriendList::SyncStatus status, const std::string & message) override;
|
||||
virtual void onPresenceReceived(const std::shared_ptr<linphone::FriendList> & friendList, const std::list<std::shared_ptr<linphone::Friend>> & friends) override;
|
||||
|
||||
signals:
|
||||
void contactCreated(const std::shared_ptr<linphone::Friend> & linphoneFriend);
|
||||
void contactDeleted(const std::shared_ptr<linphone::Friend> & linphoneFriend);
|
||||
void contactUpdated(const std::shared_ptr<linphone::Friend> & newFriend, const std::shared_ptr<linphone::Friend> & oldFriend);
|
||||
void syncStatusChanged(linphone::FriendList::SyncStatus status, const std::string & message);
|
||||
void presenceReceived(const std::list<std::shared_ptr<linphone::Friend>> & friends);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -307,10 +307,12 @@ ApplicationWindow {
|
|||
visible: SettingsModel.contactsEnabled
|
||||
|
||||
onSelected: {
|
||||
ContactsListModel.update()
|
||||
timeline.model.unselectAll()
|
||||
setView('Contacts')
|
||||
}
|
||||
onClicked:{
|
||||
ContactsListModel.update()
|
||||
setView('Contacts')
|
||||
}
|
||||
Icon{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue