Add carddav in parallel to ldap searches.

Hide favorites for readonly friends.
Fix hidden friend menu.
This commit is contained in:
Julien Wadel 2025-01-23 17:22:13 +01:00
parent dc45edf172
commit 1a94417139
15 changed files with 109 additions and 76 deletions

View file

@ -124,17 +124,9 @@ 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; // mShouldFindRemoteFriend = !linphoneFriend;
if (mShouldFindRemoteLdapFriend) { if (mShouldFindRemoteFriend) {
auto servers = CoreModel::getInstance()->getCore()->getRemoteContactDirectories(); mShouldFindRemoteFriend = CoreModel::getInstance()->getCore()->getRemoteContactDirectories().size() > 0;
bool haveLdap = false;
for (auto s : servers) {
if (s->getType() == linphone::RemoteContactDirectory::Type::Ldap) {
haveLdap = true;
break;
}
}
mShouldFindRemoteLdapFriend = haveLdap;
} }
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());
@ -438,7 +430,7 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
setVideoStats(videoStats); setVideoStats(videoStats);
} }
}); });
if (mShouldFindRemoteLdapFriend) findRemoteLdapFriend(me); if (mShouldFindRemoteFriend) findRemoteFriend(me);
} }
DEFINE_GET_SET_API(CallCore, bool, isStarted, IsStarted) DEFINE_GET_SET_API(CallCore, bool, isStarted, IsStarted)
@ -776,30 +768,39 @@ void CallCore::setVideoStats(VideoStats stats) {
} }
} }
void CallCore::findRemoteLdapFriend(QSharedPointer<CallCore> me) { void CallCore::findRemoteFriend(QSharedPointer<CallCore> me) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto linphoneSearch = CoreModel::getInstance()->getCore()->createMagicSearch(); auto linphoneSearch = CoreModel::getInstance()->getCore()->createMagicSearch();
linphoneSearch->setLimitedSearch(true); linphoneSearch->setLimitedSearch(true);
mLdapMagicSearchModel = Utils::makeQObject_ptr<MagicSearchModel>(linphoneSearch);
mLdapMagicSearchModel->setSelf(mLdapMagicSearchModel); mRemoteMagicSearchModel = Utils::makeQObject_ptr<MagicSearchModel>(linphoneSearch);
mLdapMagicSearchModelConnection = SafeConnection<CallCore, MagicSearchModel>::create(me, mLdapMagicSearchModel); mRemoteMagicSearchModel->setSelf(mRemoteMagicSearchModel);
mLdapMagicSearchModelConnection->makeConnectToModel( mRemoteMagicSearchModelConnection = SafeConnection<CallCore, MagicSearchModel>::create(me, mRemoteMagicSearchModel);
mRemoteMagicSearchModelConnection->makeConnectToModel(
&MagicSearchModel::searchResultsReceived, &MagicSearchModel::searchResultsReceived,
[this, remoteAdress = mRemoteAddress](const std::list<std::shared_ptr<linphone::SearchResult>> &results) { [this, remoteAdress = mRemoteAddress](const std::list<std::shared_ptr<linphone::SearchResult>> &results) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto ldapFriend = ToolModel::findFriendByAddress(remoteAdress); QString name;
if (ldapFriend) { auto remoteFriend = ToolModel::findFriendByAddress(remoteAdress); // Priorize what is stored.
auto ldapName = Utils::coreStringToAppString(ldapFriend->getName()); if (!remoteFriend && results.size() > 0) remoteFriend = results.front()->getFriend(); // Then result friend.
mLdapMagicSearchModelConnection->invokeToCore([this, ldapName]() { if (remoteFriend) name = Utils::coreStringToAppString(remoteFriend->getName());
else if (results.size() > 0) // Then result address.
name = Utils::coreStringToAppString(results.front()->getAddress()->getDisplayName());
if (name.isEmpty()) name = Utils::coreStringToAppString(results.front()->getAddress()->getUsername());
if (!name.isEmpty())
mRemoteMagicSearchModelConnection->invokeToCore([this, name]() {
mustBeInMainThread(log().arg(Q_FUNC_INFO)); mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (ldapName != mRemoteName) { if (name != mRemoteName) {
mRemoteName = ldapName; mRemoteName = name;
emit remoteNameChanged(); emit remoteNameChanged();
} }
}); });
}
}); });
mLdapMagicSearchModel->search(
SettingsModel::getInstance()->getUsernameOnlyForLdapLookupsInCalls() ? mRemoteUsername : mRemoteAddress, bool ldapSearch = SettingsModel::getInstance()->getUsernameOnlyForLdapLookupsInCalls();
(int)LinphoneEnums::MagicSearchSource::LdapServers, LinphoneEnums::MagicSearchAggregation::Friend, -1); bool cardDAVSearch = SettingsModel::getInstance()->getUsernameOnlyForCardDAVLookupsInCalls();
mRemoteMagicSearchModel->search(ldapSearch || cardDAVSearch ? mRemoteUsername : mRemoteAddress,
(ldapSearch ? (int)LinphoneEnums::MagicSearchSource::LdapServers : 0) |
(cardDAVSearch ? (int)LinphoneEnums::MagicSearchSource::RemoteCardDAV : 0),
LinphoneEnums::MagicSearchAggregation::Friend, -1);
} }

View file

@ -236,7 +236,7 @@ public:
VideoStats getVideoStats() const; VideoStats getVideoStats() const;
void setVideoStats(VideoStats stats); void setVideoStats(VideoStats stats);
void findRemoteLdapFriend(QSharedPointer<CallCore> me); void findRemoteFriend(QSharedPointer<CallCore> me);
signals: signals:
void statusChanged(LinphoneEnums::CallStatus status); void statusChanged(LinphoneEnums::CallStatus status);
@ -345,9 +345,9 @@ private:
ZrtpStats mZrtpStats; ZrtpStats mZrtpStats;
AudioStats mAudioStats; AudioStats mAudioStats;
VideoStats mVideoStats; VideoStats mVideoStats;
std::shared_ptr<MagicSearchModel> mLdapMagicSearchModel; std::shared_ptr<MagicSearchModel> mRemoteMagicSearchModel;
bool mShouldFindRemoteLdapFriend; bool mShouldFindRemoteFriend;
QSharedPointer<SafeConnection<CallCore, MagicSearchModel>> mLdapMagicSearchModelConnection; QSharedPointer<SafeConnection<CallCore, MagicSearchModel>> mRemoteMagicSearchModelConnection;
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT
}; };

View file

@ -29,14 +29,17 @@ DEFINE_ABSTRACT_OBJECT(FriendCore)
const QString _addressLabel = FriendCore::tr("Adresse SIP"); const QString _addressLabel = FriendCore::tr("Adresse SIP");
const QString _phoneLabel = FriendCore::tr("Téléphone"); const QString _phoneLabel = FriendCore::tr("Téléphone");
QSharedPointer<FriendCore> FriendCore::create(const std::shared_ptr<linphone::Friend> &contact, bool isStored) { QSharedPointer<FriendCore>
auto sharedPointer = QSharedPointer<FriendCore>(new FriendCore(contact, isStored), &QObject::deleteLater); FriendCore::create(const std::shared_ptr<linphone::Friend> &contact, bool isStored, int sourceFlags) {
auto sharedPointer =
QSharedPointer<FriendCore>(new FriendCore(contact, isStored, sourceFlags), &QObject::deleteLater);
sharedPointer->setSelf(sharedPointer); sharedPointer->setSelf(sharedPointer);
sharedPointer->moveToThread(App::getInstance()->thread()); sharedPointer->moveToThread(App::getInstance()->thread());
return sharedPointer; return sharedPointer;
} }
FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool isStored) : QObject(nullptr) { FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool isStored, int sourceFlags)
: QObject(nullptr) {
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership); App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
if (contact) { if (contact) {
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
@ -80,17 +83,19 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool is
LinphoneEnums::fromLinphone(device->getSecurityLevel()))); LinphoneEnums::fromLinphone(device->getSecurityLevel())));
} }
updateVerifiedDevicesCount(); updateVerifiedDevicesCount();
mStarred = contact->getStarred(); mStarred = contact->getStarred();
mIsSaved = true; mIsSaved = true;
mIsStored = isStored; mIsStored = isStored;
mIsLdap = ToolModel::friendIsInFriendList(ToolModel::getLdapFriendList(), contact); mIsLdap = ToolModel::friendIsInFriendList(ToolModel::getLdapFriendList(), contact);
mIsCardDAV = (sourceFlags & (int)linphone::MagicSearch::Source::RemoteCardDAV) != 0;
} else { } else {
mIsSaved = false; mIsSaved = false;
mStarred = false; mStarred = false;
mIsStored = false; mIsStored = false;
mIsLdap = false; mIsLdap = false;
mIsCardDAV = false;
} }
connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged); connect(this, &FriendCore::addressChanged, &FriendCore::allAddressesChanged);
connect(this, &FriendCore::phoneNumberChanged, &FriendCore::allAddressesChanged); connect(this, &FriendCore::phoneNumberChanged, &FriendCore::allAddressesChanged);
} }
@ -110,6 +115,7 @@ FriendCore::FriendCore(const FriendCore &friendCore) {
mIsSaved = friendCore.mIsSaved; mIsSaved = friendCore.mIsSaved;
mIsStored = friendCore.mIsStored; mIsStored = friendCore.mIsStored;
mIsLdap = friendCore.mIsLdap; mIsLdap = friendCore.mIsLdap;
mIsCardDAV = friendCore.mIsCardDAV;
} }
FriendCore::~FriendCore() { FriendCore::~FriendCore() {
@ -662,7 +668,7 @@ void FriendCore::save() { // Save Values to model
thisCopy->writeIntoModel(mFriendModel); thisCopy->writeIntoModel(mFriendModel);
thisCopy->deleteLater(); thisCopy->deleteLater();
mVCardString = mFriendModel->getVCardAsString(); mVCardString = mFriendModel->getVCardAsString();
auto carddavListForNewFriends = SettingsModel::getCarddavListForNewFriends(); auto carddavListForNewFriends = SettingsModel::getCardDAVListForNewFriends();
auto listWhereToAddFriend = carddavListForNewFriends != nullptr ? carddavListForNewFriends auto listWhereToAddFriend = carddavListForNewFriends != nullptr ? carddavListForNewFriends
: ToolModel::getAppFriendList(); : ToolModel::getAppFriendList();
bool created = (listWhereToAddFriend->addFriend(contact) == linphone::FriendList::Status::OK); bool created = (listWhereToAddFriend->addFriend(contact) == linphone::FriendList::Status::OK);
@ -702,9 +708,13 @@ bool FriendCore::isLdap() const {
return mIsLdap; return mIsLdap;
} }
bool FriendCore::isCardDAV() const {
return mIsCardDAV;
}
bool FriendCore::getReadOnly() const { bool FriendCore::getReadOnly() const {
return isLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list=<URL> & return isLdap() || isCardDAV(); // TODO add conditions for friends retrieved via HTTP
// CardDAV // [misc]vcards-contacts-list=<URL> & CardDAV
} }
std::shared_ptr<FriendModel> FriendCore::getFriendModel() { std::shared_ptr<FriendModel> FriendCore::getFriendModel() {

View file

@ -72,11 +72,13 @@ class FriendCore : public QObject, public AbstractObject {
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 CONSTANT) Q_PROPERTY(bool readOnly READ getReadOnly CONSTANT)
Q_PROPERTY(bool isLdap READ isLdap CONSTANT) Q_PROPERTY(bool isLdap READ isLdap CONSTANT)
Q_PROPERTY(bool isCardDAV READ isCardDAV 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
static QSharedPointer<FriendCore> create(const std::shared_ptr<linphone::Friend> &contact, bool isStored = true); static QSharedPointer<FriendCore>
FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool isStored = true); create(const std::shared_ptr<linphone::Friend> &contact, bool isStored = true, int sourceFlags = 0);
FriendCore(const std::shared_ptr<linphone::Friend> &contact, bool isStored = true, int sourceFlags = 0);
FriendCore(const FriendCore &friendCore); FriendCore(const FriendCore &friendCore);
~FriendCore(); ~FriendCore();
void setSelf(QSharedPointer<FriendCore> me); void setSelf(QSharedPointer<FriendCore> me);
@ -146,6 +148,7 @@ public:
void onPresenceReceived(LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp); void onPresenceReceived(LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp);
bool isLdap() const; bool isLdap() const;
bool isCardDAV() const;
bool getReadOnly() const; bool getReadOnly() const;
std::shared_ptr<FriendModel> getFriendModel(); std::shared_ptr<FriendModel> getFriendModel();
@ -204,7 +207,7 @@ protected:
bool mIsSaved; bool mIsSaved;
bool mIsStored; bool mIsStored;
QString mVCardString; QString mVCardString;
bool mIsLdap; bool mIsLdap, mIsCardDAV;
std::shared_ptr<FriendModel> mFriendModel; std::shared_ptr<FriendModel> mFriendModel;
QSharedPointer<SafeConnection<FriendCore, FriendModel>> mFriendModelConnection; QSharedPointer<SafeConnection<FriendCore, FriendModel>> mFriendModelConnection;
QSharedPointer<SafeConnection<FriendCore, CoreModel>> mCoreModelConnection; QSharedPointer<SafeConnection<FriendCore, CoreModel>> mCoreModelConnection;

View file

@ -97,12 +97,12 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
if (linphoneFriend) { if (linphoneFriend) {
isStored = isStored =
(ldapContacts->findFriendByAddress(linphoneFriend->getAddress()) != linphoneFriend); (ldapContacts->findFriendByAddress(linphoneFriend->getAddress()) != linphoneFriend);
contact = FriendCore::create(linphoneFriend, isStored); contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
contacts->append(contact); contacts->append(contact);
} else if (auto address = it->getAddress()) { } else if (auto address = it->getAddress()) {
auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend(); auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
linphoneFriend->setAddress(address); linphoneFriend->setAddress(address);
contact = FriendCore::create(linphoneFriend, isStored); contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
auto displayName = Utils::coreStringToAppString(address->getDisplayName()); auto displayName = Utils::coreStringToAppString(address->getDisplayName());
auto splitted = displayName.split(" "); auto splitted = displayName.split(" ");
if (!displayName.isEmpty() && splitted.size() > 0) { if (!displayName.isEmpty() && splitted.size() > 0) {
@ -118,7 +118,7 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
} else if (!it->getPhoneNumber().empty()) { } else if (!it->getPhoneNumber().empty()) {
linphoneFriend = CoreModel::getInstance()->getCore()->createFriend(); linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
linphoneFriend->setAddress(address); linphoneFriend->setAddress(address);
contact = FriendCore::create(linphoneFriend, isStored); contact = FriendCore::create(linphoneFriend, isStored, it->getSourceFlags());
contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber())); contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber()));
contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber())); contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber()));
contacts->append(contact); contacts->append(contact);
@ -215,7 +215,8 @@ QVariant MagicSearchList::data(const QModelIndex &index, int role) const {
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
return QVariant::fromValue(new FriendGui(mList[row].objectCast<FriendCore>())); return QVariant::fromValue(new FriendGui(mList[row].objectCast<FriendCore>()));
} else if (role == Qt::DisplayRole + 1) { } else if (role == Qt::DisplayRole + 1) {
return mList[row].objectCast<FriendCore>()->getIsStored() || mList[row].objectCast<FriendCore>()->isLdap(); return mList[row].objectCast<FriendCore>()->getIsStored() || mList[row].objectCast<FriendCore>()->isLdap() ||
mList[row].objectCast<FriendCore>()->isCardDAV();
} }
return QVariant(); return QVariant();
} }

View file

@ -54,7 +54,7 @@ void MagicSearchProxy::setList(QSharedPointer<MagicSearchList> newList) {
[this](int index, FriendGui *data) { [this](int index, FriendGui *data) {
auto sortModel = dynamic_cast<SortFilterList *>(sourceModel()); auto sortModel = dynamic_cast<SortFilterList *>(sourceModel());
sortModel->invalidate(); sortModel->invalidate();
if (!data->mCore->isLdap()) { if (!data->mCore->isLdap() && !data->mCore->isCardDAV()) {
auto proxyIndex = sortModel->mapFromSource(mList->index(index, 0)).row(); auto proxyIndex = sortModel->mapFromSource(mList->index(index, 0)).row();
// auto proxyIndex = mapFromSource(sourceModel()->index(index, 0)); // OLD (keep for checking new // auto proxyIndex = mapFromSource(sourceModel()->index(index, 0)); // OLD (keep for checking new
// proxy behavior) // proxy behavior)
@ -196,6 +196,9 @@ bool MagicSearchProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QMo
toShow = friendCore->isLdap(); toShow = friendCore->isLdap();
// if (!toShow) return false; // if (!toShow) return false;
} }
if (!toShow && (mFilterType & (int)FilteringTypes::CardDAV) > 0) {
toShow = friendCore->isCardDAV();
}
if (!toShow && (mFilterType & (int)FilteringTypes::App) > 0) { if (!toShow && (mFilterType & (int)FilteringTypes::App) > 0) {
toShow = friendCore->getIsStored() && !friendCore->isLdap(); toShow = friendCore->getIsStored() && !friendCore->isLdap();
// if (!toShow) return false; // if (!toShow) return false;
@ -220,8 +223,8 @@ bool MagicSearchProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, c
auto r = getItemAtSource<MagicSearchList, FriendCore>(sourceRight.row()); auto r = getItemAtSource<MagicSearchList, FriendCore>(sourceRight.row());
if (l && r) { if (l && r) {
bool lIsStored = l->getIsStored() || l->isLdap(); bool lIsStored = l->getIsStored() || l->isLdap() || l->isCardDAV();
bool rIsStored = r->getIsStored() || r->isLdap(); bool rIsStored = r->getIsStored() || r->isLdap() || r->isCardDAV();
if (lIsStored && !rIsStored) return true; if (lIsStored && !rIsStored) return true;
else if (!lIsStored && rIsStored) return false; else if (!lIsStored && rIsStored) return false;
auto lName = l->getFullName().toLower(); auto lName = l->getFullName().toLower();

View file

@ -41,7 +41,7 @@ class MagicSearchProxy : public LimitProxy {
Q_PROPERTY(MagicSearchProxy *hideListProxy READ getHideListProxy WRITE setHideListProxy NOTIFY hideListProxyChanged) Q_PROPERTY(MagicSearchProxy *hideListProxy READ getHideListProxy WRITE setHideListProxy NOTIFY hideListProxyChanged)
public: public:
enum class FilteringTypes { None = 0, Favorites = 1, App = 2, Ldap = 4, Other = 8 }; enum class FilteringTypes { None = 0, Favorites = 1, App = 2, Ldap = 4, CardDAV = 8, Other = 16 };
Q_ENUM(FilteringTypes) Q_ENUM(FilteringTypes)
DECLARE_SORTFILTER_CLASS(MagicSearchProxy *mHideListProxy = nullptr;) DECLARE_SORTFILTER_CLASS(MagicSearchProxy *mHideListProxy = nullptr;)

View file

@ -49,7 +49,7 @@ CarddavModel::~CarddavModel() {
bool CarddavModel::storeNewFriendsInIt() { bool CarddavModel::storeNewFriendsInIt() {
if (!mCarddavFriendList) return false; if (!mCarddavFriendList) return false;
auto carddavListForNewFriends = SettingsModel::getCarddavListForNewFriends(); auto carddavListForNewFriends = SettingsModel::getCardDAVListForNewFriends();
return carddavListForNewFriends != nullptr && return carddavListForNewFriends != nullptr &&
mCarddavFriendList->getDisplayName() == carddavListForNewFriends->getDisplayName(); mCarddavFriendList->getDisplayName() == carddavListForNewFriends->getDisplayName();
} }
@ -100,7 +100,7 @@ void CarddavModel::onSyncStatusChanged(const std::shared_ptr<linphone::FriendLis
if (status == linphone::FriendList::SyncStatus::Successful) { if (status == linphone::FriendList::SyncStatus::Successful) {
lInfo() << log().arg("Successfully synchronized:") << mCarddavFriendList->getUri(); lInfo() << log().arg("Successfully synchronized:") << mCarddavFriendList->getUri();
setMonitor(nullptr); setMonitor(nullptr);
if (mStoreNewFriendsInIt) SettingsModel::setCarddavListForNewFriends(friendList->getDisplayName()); if (mStoreNewFriendsInIt) SettingsModel::setCardDAVListForNewFriends(friendList->getDisplayName());
emit saved(true); emit saved(true);
} }
if (status == linphone::FriendList::SyncStatus::Failure) { if (status == linphone::FriendList::SyncStatus::Failure) {

View file

@ -49,6 +49,8 @@ void MagicSearchModel::search(QString filter,
if (((sourceFlags & (int)LinphoneEnums::MagicSearchSource::LdapServers) > 0) && if (((sourceFlags & (int)LinphoneEnums::MagicSearchSource::LdapServers) > 0) &&
!SettingsModel::getInstance()->getSyncLdapContacts()) !SettingsModel::getInstance()->getSyncLdapContacts())
sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::LdapServers; sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::LdapServers;
if (((sourceFlags & (int)LinphoneEnums::MagicSearchSource::RemoteCardDAV) > 0))
sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::RemoteCardDAV;
// For complete search, we search only on local contacts. // For complete search, we search only on local contacts.
// sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::CallLogs; // sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::CallLogs;
// sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::ChatRooms; // sourceFlags &= ~(int)LinphoneEnums::MagicSearchSource::ChatRooms;
@ -88,12 +90,12 @@ void MagicSearchModel::onSearchResultsReceived(const std::shared_ptr<linphone::M
<< (fList ? fList->getDisplayName().c_str() : "NoList") << result->getSourceFlags() << " / " << (fList ? fList->getDisplayName().c_str() : "NoList") << result->getSourceFlags() << " / "
<< (f ? f.get() : nullptr); << (f ? f.get() : nullptr);
bool isLdap = (result->getSourceFlags() & (int)LinphoneEnums::MagicSearchSource::LdapServers) != 0; bool isLdap = (result->getSourceFlags() & (int)linphone::MagicSearch::Source::LdapServers) != 0;
// Do not add it into ldap_friends if it already exists in app_friends. // Do not add it into ldap_friends if it already exists in app_friends.
if (isLdap && f && (!fList || fList->getDisplayName() != "app_friends") && if (isLdap && f && (!fList || fList->getDisplayName() != "app_friends") &&
!ToolModel::friendIsInFriendList(appFriends, f)) { // Double check because of SDK merging that lead to !ToolModel::friendIsInFriendList(appFriends, f)) { // Double check because of SDK merging that lead to
// use a ldap result as of app_friends/ldap_friends. // use a ldap result as of app_friends/ldap_friends.
updateLdapFriendListWithFriend(f); updateFriendListWithFriend(f, ToolModel::getLdapFriendList());
} }
auto resultIt = auto resultIt =
@ -106,9 +108,8 @@ void MagicSearchModel::onSearchResultsReceived(const std::shared_ptr<linphone::M
emit searchResultsReceived(finalResults); emit searchResultsReceived(finalResults);
} }
void MagicSearchModel::onLdapHaveMoreResults(const std::shared_ptr<linphone::MagicSearch> &magicSearch, void MagicSearchModel::onMoreResultsAvailable(const std::shared_ptr<linphone::MagicSearch> &magicSearch,
const std::shared_ptr<linphone::Ldap> &ldap) { linphone::MagicSearch::Source source) {
// emit ldapHaveMoreResults(ldap);
} }
// Store LDAP friends in separate list so they can still be retrieved by core->findFriend() for display names, // Store LDAP friends in separate list so they can still be retrieved by core->findFriend() for display names,
@ -116,29 +117,30 @@ void MagicSearchModel::onLdapHaveMoreResults(const std::shared_ptr<linphone::Mag
// Done in this place so the application can benefit from user initiated searches for faster ldap name retrieval // Done in this place so the application can benefit from user initiated searches for faster ldap name retrieval
// upon incoming call / chat message. // upon incoming call / chat message.
void MagicSearchModel::updateLdapFriendListWithFriend(const std::shared_ptr<linphone::Friend> &linphoneFriend) { void MagicSearchModel::updateFriendListWithFriend(const std::shared_ptr<linphone::Friend> &linphoneFriend,
std::shared_ptr<linphone::FriendList> friendList) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto core = CoreModel::getInstance()->getCore(); auto core = CoreModel::getInstance()->getCore();
auto ldapFriendList = ToolModel::getLdapFriendList();
if (ToolModel::friendIsInFriendList(ldapFriendList, linphoneFriend)) if (ToolModel::friendIsInFriendList(friendList, linphoneFriend))
return; // Already exist. We don't need to manipulate list. return; // Already exist. We don't need to manipulate list.
for (auto address : linphoneFriend->getAddresses()) { for (auto address : linphoneFriend->getAddresses()) {
auto existingFriend = ldapFriendList->findFriendByAddress(address); auto existingFriend = friendList->findFriendByAddress(address);
if (existingFriend) { if (existingFriend) {
ldapFriendList->removeFriend(existingFriend); friendList->removeFriend(existingFriend);
ldapFriendList->addFriend(linphoneFriend); friendList->addFriend(linphoneFriend);
return; return;
} }
} }
for (auto number : linphoneFriend->getPhoneNumbers()) { for (auto number : linphoneFriend->getPhoneNumbers()) {
auto existingFriend = ldapFriendList->findFriendByPhoneNumber(number); auto existingFriend = friendList->findFriendByPhoneNumber(number);
if (existingFriend) { if (existingFriend) {
ldapFriendList->removeFriend(existingFriend); friendList->removeFriend(existingFriend);
ldapFriendList->addFriend(linphoneFriend); friendList->addFriend(linphoneFriend);
return; return;
} }
} }
qDebug() << log().arg("Adding Friend:") << linphoneFriend.get(); qDebug() << log().arg("Adding Friend:") << linphoneFriend.get();
ldapFriendList->addFriend(linphoneFriend); friendList->addFriend(linphoneFriend);
emit CoreModel::getInstance()->friendCreated(linphoneFriend); emit CoreModel::getInstance()->friendCreated(linphoneFriend);
} }

View file

@ -53,9 +53,10 @@ private:
// LINPHONE // LINPHONE
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
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 onMoreResultsAvailable(const std::shared_ptr<linphone::MagicSearch> &magicSearch,
const std::shared_ptr<linphone::Ldap> &ldap) override; linphone::MagicSearch::Source source) override;
void updateLdapFriendListWithFriend(const std::shared_ptr<linphone::Friend> &linphoneFriend); void updateFriendListWithFriend(const std::shared_ptr<linphone::Friend> &linphoneFriend,
std::shared_ptr<linphone::FriendList> friendList);
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

@ -575,7 +575,7 @@ void SettingsModel::setIpv6Enabled(bool status) {
// Carddav storage list // Carddav storage list
// ============================================================================= // =============================================================================
const std::shared_ptr<linphone::FriendList> SettingsModel::getCarddavListForNewFriends() { const std::shared_ptr<linphone::FriendList> SettingsModel::getCardDAVListForNewFriends() {
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
auto core = CoreModel::getInstance()->getCore(); auto core = CoreModel::getInstance()->getCore();
if (core) { if (core) {
@ -586,7 +586,7 @@ const std::shared_ptr<linphone::FriendList> SettingsModel::getCarddavListForNewF
} else return nullptr; } else return nullptr;
} }
void SettingsModel::setCarddavListForNewFriends(std::string name) { void SettingsModel::setCardDAVListForNewFriends(std::string name) {
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
auto core = CoreModel::getInstance()->getCore(); auto core = CoreModel::getInstance()->getCore();
if (core) { if (core) {
@ -687,6 +687,7 @@ void SettingsModel::notifyConfigReady(){
DEFINE_NOTIFY_CONFIG_READY(shortcutCount, ShortcutCount) DEFINE_NOTIFY_CONFIG_READY(shortcutCount, ShortcutCount)
DEFINE_NOTIFY_CONFIG_READY(shortcuts, Shortcuts) DEFINE_NOTIFY_CONFIG_READY(shortcuts, Shortcuts)
DEFINE_NOTIFY_CONFIG_READY(usernameOnlyForLdapLookupsInCalls, UsernameOnlyForLdapLookupsInCalls) DEFINE_NOTIFY_CONFIG_READY(usernameOnlyForLdapLookupsInCalls, UsernameOnlyForLdapLookupsInCalls)
DEFINE_NOTIFY_CONFIG_READY(usernameOnlyForCardDAVLookupsInCalls, UsernameOnlyForCardDAVLookupsInCalls)
} }
DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, disableChatFeature, DisableChatFeature, "disable_chat_feature", true) DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, disableChatFeature, DisableChatFeature, "disable_chat_feature", true)
@ -808,4 +809,11 @@ DEFINE_GETSET_CONFIG(SettingsModel,
UsernameOnlyForLdapLookupsInCalls, UsernameOnlyForLdapLookupsInCalls,
"username_only_for_ldap_lookups_in_calls", "username_only_for_ldap_lookups_in_calls",
false) false)
DEFINE_GETSET_CONFIG(SettingsModel,
bool,
Bool,
usernameOnlyForCardDAVLookupsInCalls,
UsernameOnlyForCardDAVLookupsInCalls,
"username_only_for_carddav_lookups_in_calls",
false)
// clang-format on // clang-format on

View file

@ -138,8 +138,8 @@ public:
QString getLogsEmail() const; QString getLogsEmail() const;
static const std::shared_ptr<linphone::FriendList> getCarddavListForNewFriends(); static const std::shared_ptr<linphone::FriendList> getCardDAVListForNewFriends();
static void setCarddavListForNewFriends(std::string listName); static void setCardDAVListForNewFriends(std::string listName);
static QString getDeviceName(const std::shared_ptr<linphone::Config> &config); static QString getDeviceName(const std::shared_ptr<linphone::Config> &config);
@ -171,6 +171,7 @@ public:
DECLARE_GETSET(int, shortcutCount, ShortcutCount) DECLARE_GETSET(int, shortcutCount, ShortcutCount)
DECLARE_GETSET(QVariantList, shortcuts, Shortcuts) DECLARE_GETSET(QVariantList, shortcuts, Shortcuts)
DECLARE_GETSET(bool, usernameOnlyForLdapLookupsInCalls, UsernameOnlyForLdapLookupsInCalls) DECLARE_GETSET(bool, usernameOnlyForLdapLookupsInCalls, UsernameOnlyForLdapLookupsInCalls)
DECLARE_GETSET(bool, usernameOnlyForCardDAVLookupsInCalls, UsernameOnlyForCardDAVLookupsInCalls)
signals: signals:
void logsUploadUrlChanged(); void logsUploadUrlChanged();

View file

@ -285,7 +285,8 @@ Flickable{
model:MagicSearchProxy { model:MagicSearchProxy {
id: contactsProxy id: contactsProxy
parentProxy: mainItem.mainModel parentProxy: mainItem.mainModel
filterType: MagicSearchProxy.FilteringTypes.App | (mainItem.searchText != '*' && mainItem.searchText != '' || SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap : 0) filterType: MagicSearchProxy.FilteringTypes.App
| (mainItem.searchText != '*' && mainItem.searchText != '' || SettingsCpp.syncLdapContacts ? MagicSearchProxy.FilteringTypes.Ldap | MagicSearchProxy.FilteringTypes.CardDAV: 0)
initialDisplayItems: Math.max(20, 2 * mainItem.height / (63 * DefaultStyle.dp)) initialDisplayItems: Math.max(20, 2 * mainItem.height / (63 * DefaultStyle.dp))
displayItemsStep: 3 * initialDisplayItems / 2 displayItemsStep: 3 * initialDisplayItems / 2
onLocalFriendCreated: (index) => { onLocalFriendCreated: (index) => {

View file

@ -165,7 +165,7 @@ FocusScope {
popup.contentItem: ColumnLayout { popup.contentItem: ColumnLayout {
IconLabelButton { IconLabelButton {
visible: searchResultItem.core.isStored visible: searchResultItem.core.isStored && !searchResultItem.core.readOnly
text: searchResultItem.core.starred ? qsTr("Enlever des favoris") : qsTr("Mettre en favori") text: searchResultItem.core.starred ? qsTr("Enlever des favoris") : qsTr("Mettre en favori")
icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart
spacing: 10 * DefaultStyle.dp spacing: 10 * DefaultStyle.dp

View file

@ -703,11 +703,13 @@ AbstractMainPage {
anchors.fill: parent anchors.fill: parent
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
property bool isLdap: contactDetail.contact?.core?.isLdap
property bool isCardDAV: contactDetail.contact?.core?.isCardDAV
text: contactDetail.contact ? qsTr("Voir le contact") : qsTr("Ajouter aux contacts") text: contactDetail.contact ? qsTr("Voir le contact") : qsTr("Ajouter aux contacts")
icon.source: AppIcons.plusCircle icon.source: AppIcons.plusCircle
icon.width: 32 * DefaultStyle.dp icon.width: 32 * DefaultStyle.dp
icon.height: 32 * DefaultStyle.dp icon.height: 32 * DefaultStyle.dp
visible: SettingsCpp.syncLdapContacts || !contactDetail.contact?.core?.isLdap visible: !isLdap && !isCardDAV
onClicked: { onClicked: {
detailOptions.close() detailOptions.close()
if (contactDetail.contact) mainWindow.displayContactPage(contactDetail.contactAddress) if (contactDetail.contact) mainWindow.displayContactPage(contactDetail.contactAddress)