Automatic LDAP Friends lookup for calls

This commit is contained in:
Christophe Deschamps 2024-10-25 08:09:56 +02:00
parent b6b16650bf
commit a91b29cb17
20 changed files with 171 additions and 29 deletions

View file

@ -79,6 +79,28 @@ CallHistoryCore::~CallHistoryCore() {
void CallHistoryCore::setSelf(QSharedPointer<CallHistoryCore> me) { void CallHistoryCore::setSelf(QSharedPointer<CallHistoryCore> me) {
mHistoryModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CallHistoryModel>>( mHistoryModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CallHistoryModel>>(
new SafeConnection<CallHistoryCore, CallHistoryModel>(me, mCallHistoryModel), &QObject::deleteLater); new SafeConnection<CallHistoryCore, CallHistoryModel>(me, mCallHistoryModel), &QObject::deleteLater);
mCoreModelConnection = QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>>(
new SafeConnection<CallHistoryCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
if (!ToolModel::findFriendByAddress(mRemoteAddress)) {
mCoreModelConnection->makeConnectToModel(
&CoreModel::friendCreated,
[this, remoteAddress = mRemoteAddress](const std::shared_ptr<linphone::Friend> &f) {
auto inFriend = Utils::findFriendByAddress(remoteAddress);
QString displayName;
if (inFriend) {
auto friendGui = inFriend->getValue().value<FriendGui *>();
if (friendGui) displayName = friendGui->getCore()->getDisplayName();
}
if (!displayName.isEmpty()) {
mCoreModelConnection->invokeToCore([this, displayName]() {
if (displayName != mDisplayName) {
mDisplayName = displayName;
emit displayNameChanged();
}
});
}
});
}
} }
ConferenceInfoGui *CallHistoryCore::getConferenceInfoGui() const { ConferenceInfoGui *CallHistoryCore::getConferenceInfoGui() const {

View file

@ -34,7 +34,7 @@ class CallHistoryModel;
class CallHistoryCore : public QObject, public AbstractObject { class CallHistoryCore : public QObject, public AbstractObject {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString displayName MEMBER mDisplayName CONSTANT) Q_PROPERTY(QString displayName MEMBER mDisplayName NOTIFY displayNameChanged)
Q_PROPERTY(QString remoteAddress MEMBER mRemoteAddress CONSTANT) Q_PROPERTY(QString remoteAddress MEMBER mRemoteAddress CONSTANT)
Q_PROPERTY(bool isOutgoing MEMBER mIsOutgoing CONSTANT) Q_PROPERTY(bool isOutgoing MEMBER mIsOutgoing CONSTANT)
Q_PROPERTY(bool isConference MEMBER mIsConference CONSTANT) Q_PROPERTY(bool isConference MEMBER mIsConference CONSTANT)
@ -66,12 +66,14 @@ public:
signals: signals:
void durationChanged(QString duration); void durationChanged(QString duration);
void displayNameChanged();
private: private:
QString mDuration; QString mDuration;
QSharedPointer<ConferenceInfoCore> mConferenceInfo = nullptr; QSharedPointer<ConferenceInfoCore> mConferenceInfo = nullptr;
std::shared_ptr<CallHistoryModel> mCallHistoryModel; std::shared_ptr<CallHistoryModel> mCallHistoryModel;
QSharedPointer<SafeConnection<CallHistoryCore, CallHistoryModel>> mHistoryModelConnection; QSharedPointer<SafeConnection<CallHistoryCore, CallHistoryModel>> mHistoryModelConnection;
QSharedPointer<SafeConnection<CallHistoryCore, CoreModel>> mCoreModelConnection;
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT
}; };

View file

@ -22,6 +22,7 @@
#include "core/App.hpp" #include "core/App.hpp"
#include "core/conference/ConferenceCore.hpp" #include "core/conference/ConferenceCore.hpp"
#include "core/conference/ConferenceGui.hpp" #include "core/conference/ConferenceGui.hpp"
#include "core/friend/FriendCore.hpp"
#include "core/setting/SettingsCore.hpp" #include "core/setting/SettingsCore.hpp"
#include "model/tool/ToolModel.hpp" #include "model/tool/ToolModel.hpp"
#include "tool/Utils.hpp" #include "tool/Utils.hpp"
@ -129,6 +130,7 @@ CallCore::CallCore(const std::shared_ptr<linphone::Call> &call) : QObject(nullpt
mRemoteName = Utils::coreStringToAppString( mRemoteName = Utils::coreStringToAppString(
linphoneFriend->getVcard() ? linphoneFriend->getVcard()->getFullName() : linphoneFriend->getName()); linphoneFriend->getVcard() ? linphoneFriend->getVcard()->getFullName() : linphoneFriend->getName());
if (mRemoteName.isEmpty()) mRemoteName = ToolModel::getDisplayName(mRemoteAddress); if (mRemoteName.isEmpty()) mRemoteName = ToolModel::getDisplayName(mRemoteAddress);
mShouldFindRemoteLdapFriend = !linphoneFriend && !CoreModel::getInstance()->getCore()->getLdapList().empty();
mLocalAddress = Utils::coreStringToAppString(call->getCallLog()->getLocalAddress()->asStringUriOnly()); mLocalAddress = Utils::coreStringToAppString(call->getCallLog()->getLocalAddress()->asStringUriOnly());
mStatus = LinphoneEnums::fromLinphone(call->getCallLog()->getStatus()); mStatus = LinphoneEnums::fromLinphone(call->getCallLog()->getStatus());
@ -466,14 +468,11 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
setVideoStats(videoStats); setVideoStats(videoStats);
} }
}); });
if (mShouldFindRemoteLdapFriend) findRemoteLdapFriend(me);
} }
DEFINE_GET_SET_API(CallCore, bool, isStarted, IsStarted) DEFINE_GET_SET_API(CallCore, bool, isStarted, IsStarted)
QString CallCore::getRemoteName() const {
return mRemoteName;
}
QString CallCore::getRemoteAddress() const { QString CallCore::getRemoteAddress() const {
return mRemoteAddress; return mRemoteAddress;
} }
@ -818,3 +817,32 @@ void CallCore::setVideoStats(VideoStats stats) {
emit videoStatsChanged(); emit videoStatsChanged();
} }
} }
void CallCore::findRemoteLdapFriend(QSharedPointer<CallCore> me) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto linphoneSearch = CoreModel::getInstance()->getCore()->createMagicSearch();
linphoneSearch->setLimitedSearch(true);
mLdapMagicSearchModel = Utils::makeQObject_ptr<MagicSearchModel>(linphoneSearch);
mLdapMagicSearchModel->setSourceFlags((int)LinphoneEnums::MagicSearchSource::LdapServers);
mLdapMagicSearchModel->setAggregationFlag(LinphoneEnums::MagicSearchAggregation::Friend);
mLdapMagicSearchModel->setSelf(mLdapMagicSearchModel);
mLdapMagicSearchModelConnection = QSharedPointer<SafeConnection<CallCore, MagicSearchModel>>(
new SafeConnection<CallCore, MagicSearchModel>(me, mLdapMagicSearchModel), &QObject::deleteLater);
mLdapMagicSearchModelConnection->makeConnectToModel(
&MagicSearchModel::searchResultsReceived,
[this, remoteAdress = mRemoteAddress](const std::list<std::shared_ptr<linphone::SearchResult>> &results) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto ldapFriend = ToolModel::findFriendByAddress(remoteAdress);
if (ldapFriend) {
auto ldapName = Utils::coreStringToAppString(ldapFriend->getName());
mLdapMagicSearchModelConnection->invokeToCore([this, ldapName]() {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (ldapName != mRemoteName) {
mRemoteName = ldapName;
emit remoteNameChanged();
}
});
}
});
mLdapMagicSearchModel->search(mRemoteAddress);
}

View file

@ -25,6 +25,7 @@
#include "core/conference/ConferenceGui.hpp" #include "core/conference/ConferenceGui.hpp"
#include "core/videoSource/VideoSourceDescriptorGui.hpp" #include "core/videoSource/VideoSourceDescriptorGui.hpp"
#include "model/call/CallModel.hpp" #include "model/call/CallModel.hpp"
#include "model/search/MagicSearchModel.hpp"
#include "tool/LinphoneEnums.hpp" #include "tool/LinphoneEnums.hpp"
#include "tool/thread/SafeConnection.hpp" #include "tool/thread/SafeConnection.hpp"
#include <QObject> #include <QObject>
@ -104,7 +105,7 @@ class CallCore : public QObject, public AbstractObject {
Q_PROPERTY(bool speakerMuted READ getSpeakerMuted WRITE lSetSpeakerMuted NOTIFY speakerMutedChanged) Q_PROPERTY(bool speakerMuted READ getSpeakerMuted WRITE lSetSpeakerMuted NOTIFY speakerMutedChanged)
Q_PROPERTY(bool microphoneMuted READ getMicrophoneMuted WRITE lSetMicrophoneMuted NOTIFY microphoneMutedChanged) Q_PROPERTY(bool microphoneMuted READ getMicrophoneMuted WRITE lSetMicrophoneMuted NOTIFY microphoneMutedChanged)
Q_PROPERTY(bool paused READ getPaused WRITE lSetPaused NOTIFY pausedChanged) Q_PROPERTY(bool paused READ getPaused WRITE lSetPaused NOTIFY pausedChanged)
Q_PROPERTY(QString remoteName READ getRemoteName CONSTANT) Q_PROPERTY(QString remoteName MEMBER mRemoteName NOTIFY remoteNameChanged)
Q_PROPERTY(QString remoteAddress READ getRemoteAddress CONSTANT) Q_PROPERTY(QString remoteAddress READ getRemoteAddress CONSTANT)
Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT) Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT)
Q_PROPERTY(bool tokenVerified READ getTokenVerified WRITE setTokenVerified NOTIFY securityUpdated) Q_PROPERTY(bool tokenVerified READ getTokenVerified WRITE setTokenVerified NOTIFY securityUpdated)
@ -146,7 +147,6 @@ public:
~CallCore(); ~CallCore();
void setSelf(QSharedPointer<CallCore> me); void setSelf(QSharedPointer<CallCore> me);
QString getRemoteName() const;
QString getRemoteAddress() const; QString getRemoteAddress() const;
QString getLocalAddress() const; QString getLocalAddress() const;
@ -245,6 +245,8 @@ public:
VideoStats getVideoStats() const; VideoStats getVideoStats() const;
void setVideoStats(VideoStats stats); void setVideoStats(VideoStats stats);
void findRemoteLdapFriend(QSharedPointer<CallCore> me);
signals: signals:
void statusChanged(LinphoneEnums::CallStatus status); void statusChanged(LinphoneEnums::CallStatus status);
void stateChanged(LinphoneEnums::CallState state); void stateChanged(LinphoneEnums::CallState state);
@ -274,6 +276,7 @@ signals:
void zrtpStatsChanged(); void zrtpStatsChanged();
void audioStatsChanged(); void audioStatsChanged();
void videoStatsChanged(); void videoStatsChanged();
void remoteNameChanged();
// Linphone commands // Linphone commands
void lAccept(bool withVideo); // Accept an incoming call void lAccept(bool withVideo); // Accept an incoming call
@ -355,6 +358,9 @@ private:
ZrtpStats mZrtpStats; ZrtpStats mZrtpStats;
AudioStats mAudioStats; AudioStats mAudioStats;
VideoStats mVideoStats; VideoStats mVideoStats;
std::shared_ptr<MagicSearchModel> mLdapMagicSearchModel;
bool mShouldFindRemoteLdapFriend;
QSharedPointer<SafeConnection<CallCore, MagicSearchModel>> mLdapMagicSearchModelConnection;
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT
}; };

View file

@ -99,7 +99,7 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact) : QObje
mStarred = false; mStarred = false;
} }
mIsLdap = false; mIsLdap = ToolModel::friendIsInLdapFriendList(contact);
connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged); connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged);
connect(this, &FriendCore::phoneNumberChanged, &FriendCore::allAddressesChanged); connect(this, &FriendCore::phoneNumberChanged, &FriendCore::allAddressesChanged);
} }
@ -670,17 +670,11 @@ void FriendCore::undo() { // Retrieve values from model
} }
} }
bool FriendCore::getIsLdap() const { bool FriendCore::isLdap() const {
return mIsLdap; return mIsLdap;
} }
void FriendCore::setIsLdap(bool data) {
if (mIsLdap != data) {
mIsLdap = data;
emit readOnlyChanged();
}
}
bool FriendCore::getReadOnly() const { bool FriendCore::getReadOnly() const {
return getIsLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list=<URL> & return isLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list=<URL> &
// CardDAV // CardDAV
} }

View file

@ -67,7 +67,8 @@ class FriendCore : public QObject, public AbstractObject {
Q_PROPERTY(bool isSaved READ getIsSaved NOTIFY isSavedChanged) Q_PROPERTY(bool isSaved READ getIsSaved NOTIFY isSavedChanged)
Q_PROPERTY(QString pictureUri READ getPictureUri WRITE setPictureUri NOTIFY pictureUriChanged) Q_PROPERTY(QString pictureUri READ getPictureUri WRITE setPictureUri NOTIFY pictureUriChanged)
Q_PROPERTY(bool starred READ getStarred WRITE lSetStarred NOTIFY starredChanged) Q_PROPERTY(bool starred READ getStarred WRITE lSetStarred NOTIFY starredChanged)
Q_PROPERTY(bool readOnly READ getReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(bool readOnly READ getReadOnly CONSTANT)
Q_PROPERTY(bool isLdap READ isLdap CONSTANT)
public: public:
// Should be call from model Thread. Will be automatically in App thread after initialization // Should be call from model Thread. Will be automatically in App thread after initialization
@ -135,8 +136,7 @@ public:
void onPresenceReceived(LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp); void onPresenceReceived(LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp);
bool getIsLdap() const; bool isLdap() const;
void setIsLdap(bool isLdap);
bool getReadOnly() const; bool getReadOnly() const;
Q_INVOKABLE void remove(); Q_INVOKABLE void remove();
@ -168,7 +168,6 @@ signals:
void devicesChanged(); void devicesChanged();
void verifiedDevicesChanged(); void verifiedDevicesChanged();
void lSetStarred(bool starred); void lSetStarred(bool starred);
void readOnlyChanged();
protected: protected:
void writeIntoModel(std::shared_ptr<FriendModel> model) const; void writeIntoModel(std::shared_ptr<FriendModel> model) const;

View file

@ -122,8 +122,6 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber())); contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber()));
contacts->append(contact); contacts->append(contact);
} }
bool isLdap = (it->getSourceFlags() & (int)LinphoneEnums::MagicSearchSource::LdapServers) != 0;
if (contact) contact->setIsLdap(isLdap);
} }
mModelConnection->invokeToCore([this, contacts]() { mModelConnection->invokeToCore([this, contacts]() {
setResults(*contacts); setResults(*contacts);

View file

@ -74,6 +74,7 @@ private:
std::shared_ptr<MagicSearchModel> mMagicSearch; std::shared_ptr<MagicSearchModel> mMagicSearch;
QSharedPointer<SafeConnection<MagicSearchList, MagicSearchModel>> mModelConnection; QSharedPointer<SafeConnection<MagicSearchList, MagicSearchModel>> mModelConnection;
QSharedPointer<SafeConnection<MagicSearchList, CoreModel>> mCoreModelConnection; QSharedPointer<SafeConnection<MagicSearchList, CoreModel>> mCoreModelConnection;
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT
}; };

View file

@ -68,7 +68,10 @@ void MagicSearchProxy::setList(QSharedPointer<MagicSearchList> newList) {
Qt::QueuedConnection); Qt::QueuedConnection);
} }
auto sortFilterList = new SortFilterList(mList.get(), Qt::AscendingOrder); auto sortFilterList = new SortFilterList(mList.get(), Qt::AscendingOrder);
if (oldModel) sortFilterList->mShowFavoritesOnly = oldModel->mShowFavoritesOnly; if (oldModel) {
sortFilterList->mShowFavoritesOnly = oldModel->mShowFavoritesOnly;
sortFilterList->mShowLdapContacts = oldModel->mShowLdapContacts;
}
setSourceModels(sortFilterList); setSourceModels(sortFilterList);
} }
@ -133,7 +136,7 @@ void MagicSearchProxy::setAggregationFlag(LinphoneEnums::MagicSearchAggregation
bool MagicSearchProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { bool MagicSearchProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
auto friendCore = getItemAtSource<MagicSearchList, FriendCore>(sourceRow); auto friendCore = getItemAtSource<MagicSearchList, FriendCore>(sourceRow);
if (friendCore) { if (friendCore) {
return !mShowFavoritesOnly || friendCore->getStarred(); return (!mShowFavoritesOnly || friendCore->getStarred()) && (mShowLdapContacts || !friendCore->isLdap());
} }
return false; return false;
} }
@ -149,3 +152,15 @@ bool MagicSearchProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, c
} }
return true; return true;
} }
bool MagicSearchProxy::showLdapContacts() const {
return dynamic_cast<SortFilterList *>(sourceModel())->mShowLdapContacts;
}
void MagicSearchProxy::setShowLdapContacts(bool show) {
auto list = dynamic_cast<SortFilterList *>(sourceModel());
if (list->mShowLdapContacts != show) {
list->mShowLdapContacts = show;
list->invalidate();
}
}

View file

@ -36,9 +36,11 @@ class MagicSearchProxy : public LimitProxy {
NOTIFY aggregationFlagChanged) NOTIFY aggregationFlagChanged)
Q_PROPERTY(bool showFavoritesOnly READ showFavoritesOnly WRITE setShowFavoritesOnly NOTIFY showFavoriteOnlyChanged) Q_PROPERTY(bool showFavoritesOnly READ showFavoritesOnly WRITE setShowFavoritesOnly NOTIFY showFavoriteOnlyChanged)
Q_PROPERTY(MagicSearchProxy *parentProxy WRITE setParentProxy NOTIFY parentProxyChanged) Q_PROPERTY(MagicSearchProxy *parentProxy WRITE setParentProxy NOTIFY parentProxyChanged)
Q_PROPERTY(bool showLdapContacts READ showLdapContacts WRITE setShowLdapContacts CONSTANT)
public: public:
DECLARE_SORTFILTER_CLASS(bool mShowFavoritesOnly = false;) DECLARE_SORTFILTER_CLASS(bool mShowFavoritesOnly = false; bool mShowLdapContacts = false;)
MagicSearchProxy(QObject *parent = Q_NULLPTR); MagicSearchProxy(QObject *parent = Q_NULLPTR);
~MagicSearchProxy(); ~MagicSearchProxy();
@ -54,6 +56,9 @@ public:
bool showFavoritesOnly() const; bool showFavoritesOnly() const;
void setShowFavoritesOnly(bool show); void setShowFavoritesOnly(bool show);
bool showLdapContacts() const;
void setShowLdapContacts(bool show);
void setList(QSharedPointer<MagicSearchList> list); void setList(QSharedPointer<MagicSearchList> list);
Q_INVOKABLE void setParentProxy(MagicSearchProxy *proxy); Q_INVOKABLE void setParentProxy(MagicSearchProxy *proxy);

View file

@ -23,6 +23,7 @@
#include <QDebug> #include <QDebug>
#include "model/core/CoreModel.hpp" #include "model/core/CoreModel.hpp"
#include "model/tool/ToolModel.hpp"
#include "tool/Utils.hpp" #include "tool/Utils.hpp"
DEFINE_ABSTRACT_OBJECT(MagicSearchModel) DEFINE_ABSTRACT_OBJECT(MagicSearchModel)
@ -60,6 +61,10 @@ void MagicSearchModel::setAggregationFlag(LinphoneEnums::MagicSearchAggregation
} }
void MagicSearchModel::onSearchResultsReceived(const std::shared_ptr<linphone::MagicSearch> &magicSearch) { void MagicSearchModel::onSearchResultsReceived(const std::shared_ptr<linphone::MagicSearch> &magicSearch) {
for (auto it : magicSearch->getLastSearch()) {
bool isLdap = (it->getSourceFlags() & (int)LinphoneEnums::MagicSearchSource::LdapServers) != 0;
if (isLdap && it->getFriend()) updateLdapFriendListWithFriend(it->getFriend());
}
emit searchResultsReceived(magicSearch->getLastSearch()); emit searchResultsReceived(magicSearch->getLastSearch());
} }
@ -67,3 +72,32 @@ void MagicSearchModel::onLdapHaveMoreResults(const std::shared_ptr<linphone::Mag
const std::shared_ptr<linphone::Ldap> &ldap) { const std::shared_ptr<linphone::Ldap> &ldap) {
// emit ldapHaveMoreResults(ldap); // emit ldapHaveMoreResults(ldap);
} }
// Store LDAP friends in separate list so they can still be retrieved by core->findFriend() for display names,
// but can be amended only by LDAP received friends.
// Done in this place so the application can benefit from user initiated searches for faster ldap name retrieval
// upon incoming call / chat message.
void MagicSearchModel::updateLdapFriendListWithFriend(const std::shared_ptr<linphone::Friend> &linphoneFriend) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto core = CoreModel::getInstance()->getCore();
auto ldapFriendList = ToolModel::getLdapFriendList();
for (auto address : linphoneFriend->getAddresses()) {
auto existingFriend = ldapFriendList->findFriendByAddress(address);
if (existingFriend) {
ldapFriendList->removeFriend(existingFriend);
ldapFriendList->addFriend(linphoneFriend);
return;
}
}
for (auto number : linphoneFriend->getPhoneNumbers()) {
auto existingFriend = ldapFriendList->findFriendByPhoneNumber(number);
if (existingFriend) {
ldapFriendList->removeFriend(existingFriend);
ldapFriendList->addFriend(linphoneFriend);
return;
}
}
ldapFriendList->addFriend(linphoneFriend);
emit CoreModel::getInstance()->friendCreated(linphoneFriend);
}

View file

@ -58,6 +58,8 @@ private:
virtual void onSearchResultsReceived(const std::shared_ptr<linphone::MagicSearch> &magicSearch) override; virtual void onSearchResultsReceived(const std::shared_ptr<linphone::MagicSearch> &magicSearch) override;
virtual void onLdapHaveMoreResults(const std::shared_ptr<linphone::MagicSearch> &magicSearch, virtual void onLdapHaveMoreResults(const std::shared_ptr<linphone::MagicSearch> &magicSearch,
const std::shared_ptr<linphone::Ldap> &ldap) override; const std::shared_ptr<linphone::Ldap> &ldap) override;
void updateLdapFriendListWithFriend(const std::shared_ptr<linphone::Friend> &linphoneFriend);
signals: signals:
void searchResultsReceived(const std::list<std::shared_ptr<linphone::SearchResult>> &results); void searchResultsReceived(const std::list<std::shared_ptr<linphone::SearchResult>> &results);
}; };

View file

@ -275,3 +275,22 @@ bool ToolModel::isLocal(const std::shared_ptr<linphone::Conference> &conference,
auto gruuAddress = findAccount(callAddress)->getContactAddress(); auto gruuAddress = findAccount(callAddress)->getContactAddress();
return deviceAddress->equal(gruuAddress); return deviceAddress->equal(gruuAddress);
} }
std::shared_ptr<linphone::FriendList> ToolModel::getLdapFriendList() {
auto core = CoreModel::getInstance()->getCore();
auto ldapFriendList = core->getFriendListByName("ldap_friends");
if (!ldapFriendList) {
ldapFriendList = core->createFriendList();
ldapFriendList->setDisplayName("ldap_friends");
core->addFriendList(ldapFriendList);
}
return ldapFriendList;
}
bool ToolModel::friendIsInLdapFriendList(const std::shared_ptr<linphone::Friend> &f) {
auto ldapFriendList = getLdapFriendList();
for (auto ldapFriend : ldapFriendList->getFriends()) {
if (f == ldapFriend) return true;
}
return false;
}

View file

@ -59,6 +59,9 @@ public:
linphone::MediaEncryption = linphone::MediaEncryption::None, linphone::MediaEncryption = linphone::MediaEncryption::None,
QString *errorMessage = nullptr); QString *errorMessage = nullptr);
static std::shared_ptr<linphone::FriendList> getLdapFriendList();
static bool friendIsInLdapFriendList(const std::shared_ptr<linphone::Friend> &f);
private: private:
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT
}; };

View file

@ -175,6 +175,10 @@ Loader{
shadowColor: DefaultStyle.grey_1000 shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.1 shadowOpacity: 0.1
} }
Connections {
target: mainItem.call?.core ? mainItem.call.core : null
onRemoteNameChanged: initialItem.initials = UtilsCpp.getInitials(mainItem.call.core.remoteName)
}
} }
} }
Component{ Component{

View file

@ -26,6 +26,7 @@ ListView {
property bool displayNameCapitalization: true property bool displayNameCapitalization: true
property bool showFavoritesOnly: false property bool showFavoritesOnly: false
property bool showDefaultAddress: false property bool showDefaultAddress: false
property bool showLdapContacts: false
property var listProxy: MagicSearchProxy{} property var listProxy: MagicSearchProxy{}
@ -112,6 +113,7 @@ ListView {
} }
aggregationFlag: mainItem.aggregationFlag aggregationFlag: mainItem.aggregationFlag
parentProxy: mainItem.listProxy parentProxy: mainItem.listProxy
showLdapContacts: mainItem.showLdapContacts
sourceFlags: mainItem.sourceFlags sourceFlags: mainItem.sourceFlags
onInitialized: { onInitialized: {
magicSearchProxy.forceUpdate() magicSearchProxy.forceUpdate()

View file

@ -49,8 +49,7 @@ Notification {
} }
ColumnLayout { ColumnLayout {
Text { Text {
property var remoteAddress: UtilsCpp.getDisplayName(call.core.remoteAddress) text: call.core.remoteName
text: remoteAddress ? remoteAddress.value : ""
color: DefaultStyle.grey_600 color: DefaultStyle.grey_600
font { font {
pixelSize: 20 * DefaultStyle.dp pixelSize: 20 * DefaultStyle.dp

View file

@ -249,6 +249,7 @@ Item {
actionLayoutVisible: true actionLayoutVisible: true
selectionEnabled: false selectionEnabled: false
showDefaultAddress: true showDefaultAddress: true
showLdapContacts: true
Control.ScrollBar.vertical: scrollbar Control.ScrollBar.vertical: scrollbar
searchText: magicSearchBar.text searchText: magicSearchBar.text

View file

@ -655,7 +655,12 @@ AbstractMainPage {
contact: contactObj && contactObj.value || null contact: contactObj && contactObj.value || null
conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null conferenceInfo: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.conferenceInfo || null
specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || "" specificAddress: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || ""
Connections {
target: mainItem.selectedRowHistoryGui?.core ? mainItem.selectedRowHistoryGui.core : null
onDisplayNameChanged: {
mainItem.onSelectedRowHistoryGuiChanged() // to cover displayName & Avatar.
}
}
buttonContent: PopupButton { buttonContent: PopupButton {
id: detailOptions id: detailOptions
anchors.right: parent.right anchors.right: parent.right
@ -687,6 +692,7 @@ AbstractMainPage {
textColor: DefaultStyle.main2_500main textColor: DefaultStyle.main2_500main
contentImageColor: DefaultStyle.main2_600 contentImageColor: DefaultStyle.main2_600
background: Item {} background: Item {}
visible: SettingsCpp.syncLdapContacts || !detailOptions.friendGui?.core?.isLdap
onClicked: { onClicked: {
detailOptions.close() detailOptions.close()
if (detailOptions.friendGui) mainWindow.displayContactPage(contactDetail.contactAddress) if (detailOptions.friendGui) mainWindow.displayContactPage(contactDetail.contactAddress)

View file

@ -56,6 +56,7 @@ AbstractMainPage {
MagicSearchProxy { MagicSearchProxy {
id: allFriends id: allFriends
showLdapContacts: SettingsCpp.syncLdapContacts
} }
function deleteContact(contact) { function deleteContact(contact) {
@ -446,6 +447,7 @@ AbstractMainPage {
button.topPadding: 10 * DefaultStyle.dp button.topPadding: 10 * DefaultStyle.dp
button.bottomPadding: 10 * DefaultStyle.dp button.bottomPadding: 10 * DefaultStyle.dp
button.onClicked: mainItem.editContact(mainItem.selectedContact) button.onClicked: mainItem.editContact(mainItem.selectedContact)
button.visible: !mainItem.selectedContact?.core.readOnly
property string contactAddress: contact ? contact.core.defaultAddress : "" property string contactAddress: contact ? contact.core.defaultAddress : ""
property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress) property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress)
property string computedContactName: computedContactNameObj ? computedContactNameObj.value : "" property string computedContactName: computedContactNameObj ? computedContactNameObj.value : ""