- Support option for showing entire LDAP address book in contacts list ([ui]sync_ldap_contacts)

- Make LDAP contacts read only in the app
- Use different MagicSerach for contact list and contact searching
This commit is contained in:
Christophe Deschamps 2024-09-27 09:29:32 +02:00
parent b4a86b1d01
commit 36d63098a7
15 changed files with 73 additions and 5 deletions

View file

@ -103,4 +103,11 @@ void LdapCore::setSelf(QSharedPointer<LdapCore> me) {
DEFINE_CORE_GETSET_CONNECT(mLdapModelConnection, LdapCore, LdapModel, mLdapModel, QString, sipDomain, SipDomain) DEFINE_CORE_GETSET_CONNECT(mLdapModelConnection, LdapCore, LdapModel, mLdapModel, QString, sipDomain, SipDomain)
DEFINE_CORE_GETSET_CONNECT(mLdapModelConnection, LdapCore, LdapModel, mLdapModel, linphone::Ldap::DebugLevel, DEFINE_CORE_GETSET_CONNECT(mLdapModelConnection, LdapCore, LdapModel, mLdapModel, linphone::Ldap::DebugLevel,
debugLevel, DebugLevel) debugLevel, DebugLevel)
mLdapModelConnection->makeConnectToModel(&LdapModel::saved, [this]() {
mLdapModelConnection->invokeToCore([this]() { emit App::getInstance() -> getSettings()->ldapConfigChanged(); });
});
mLdapModelConnection->makeConnectToModel(&LdapModel::removed, [this]() {
mLdapModelConnection->invokeToCore([this]() { emit App::getInstance() -> getSettings()->ldapConfigChanged(); });
});
} }

View file

@ -648,3 +648,16 @@ void FriendCore::undo() { // Retrieve values from model
}); });
} }
} }
bool FriendCore::getIsLdap() const {
return mIsLdap;
}
void FriendCore::setIsLdap(bool data) {
if (mIsLdap != data) {
mIsLdap = data;
}
}
bool FriendCore::getReadOnly() const {
return getIsLdap(); // TODO add conditions for friends retrieved via HTTP [misc]vcards-contacts-list=<URL> & CardDAV
}

View file

@ -67,6 +67,7 @@ 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 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
@ -134,6 +135,10 @@ public:
void onPresenceReceived(LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp); void onPresenceReceived(LinphoneEnums::ConsolidatedPresence consolidatedPresence, QDateTime presenceTimestamp);
bool getIsLdap() const;
void setIsLdap(bool isLdap);
bool getReadOnly() const;
Q_INVOKABLE void remove(); Q_INVOKABLE void remove();
Q_INVOKABLE void save(); Q_INVOKABLE void save();
Q_INVOKABLE void undo(); Q_INVOKABLE void undo();
@ -184,6 +189,7 @@ protected:
QString mPictureUri; QString mPictureUri;
bool mIsSaved; bool mIsSaved;
QString mVCardString; QString mVCardString;
bool mIsLdap;
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

@ -122,6 +122,8 @@ 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);
@ -129,7 +131,6 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
}); });
}); });
emit initialized(); emit initialized();
emit lSearch(mSearchFilter);
}); });
}); });
} }

View file

@ -1,4 +1,4 @@
/* /*
* Copyright (c) 2010-2024 Belledonne Communications SARL. * Copyright (c) 2010-2024 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop

View file

@ -55,6 +55,7 @@ void MagicSearchProxy::setSourceModel(QAbstractItemModel *model) {
connect(newMagicSearchList, &MagicSearchList::initialized, this, [this, newMagicSearchList] { connect(newMagicSearchList, &MagicSearchList::initialized, this, [this, newMagicSearchList] {
emit newMagicSearchList->lSetSourceFlags(mSourceFlags); emit newMagicSearchList->lSetSourceFlags(mSourceFlags);
emit newMagicSearchList->lSetAggregationFlag(mAggregationFlag); emit newMagicSearchList->lSetAggregationFlag(mAggregationFlag);
emit initialized();
}); });
} }
QSortFilterProxyModel::setSourceModel(model); QSortFilterProxyModel::setSourceModel(model);

View file

@ -64,6 +64,7 @@ signals:
void forceUpdate(); void forceUpdate();
void friendCreated(int index); void friendCreated(int index);
void showFavoriteOnlyChanged(); void showFavoriteOnlyChanged();
void initialized();
protected: protected:
QString mSearchText; QString mSearchText;

View file

@ -91,6 +91,7 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
INIT_CORE_MEMBER(AssistantThirdPartySipAccountDomain, mSettingsModel) INIT_CORE_MEMBER(AssistantThirdPartySipAccountDomain, mSettingsModel)
INIT_CORE_MEMBER(AssistantThirdPartySipAccountTransport, mSettingsModel) INIT_CORE_MEMBER(AssistantThirdPartySipAccountTransport, mSettingsModel)
INIT_CORE_MEMBER(AutoStart, mSettingsModel) INIT_CORE_MEMBER(AutoStart, mSettingsModel)
INIT_CORE_MEMBER(SyncLdapContacts, mSettingsModel)
} }
SettingsCore::~SettingsCore() { SettingsCore::~SettingsCore() {
@ -307,6 +308,8 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport) assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, autoStart, DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool, autoStart,
AutoStart) AutoStart)
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, mSettingsModel, bool,
syncLdapContacts, SyncLdapContacts)
auto coreModelConnection = QSharedPointer<SafeConnection<SettingsCore, CoreModel>>( auto coreModelConnection = QSharedPointer<SafeConnection<SettingsCore, CoreModel>>(
new SafeConnection<SettingsCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater); new SafeConnection<SettingsCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);

View file

@ -157,7 +157,13 @@ public:
DECLARE_CORE_GETSET(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain) DECLARE_CORE_GETSET(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
DECLARE_CORE_GETSET(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport) DECLARE_CORE_GETSET(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DECLARE_CORE_GETSET(bool, autoStart, AutoStart) DECLARE_CORE_GETSET(bool, autoStart, AutoStart)
bool getAutoStart() { return mAutoStart; }; bool getAutoStart() {
return mAutoStart;
};
DECLARE_CORE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
bool getSyncLdapContacts() {
return mSyncLdapContacts;
};
signals: signals:
@ -217,6 +223,8 @@ signals:
void dndChanged(); void dndChanged();
void lEnableDnd(bool value); void lEnableDnd(bool value);
void ldapConfigChanged();
private: private:
std::shared_ptr<SettingsModel> mSettingsModel; std::shared_ptr<SettingsModel> mSettingsModel;

View file

@ -33,8 +33,9 @@ LdapModel::LdapModel(const std::shared_ptr<linphone::Ldap> &ldap, QObject *paren
mLdap = nullptr; mLdap = nullptr;
mLdapParamsClone = CoreModel::getInstance()->getCore()->createLdapParams(); mLdapParamsClone = CoreModel::getInstance()->getCore()->createLdapParams();
mLdapParamsClone->setTimeout(5); mLdapParamsClone->setTimeout(5);
mLdapParamsClone->setMaxResults(50);
mLdapParamsClone->setDelay(2000); mLdapParamsClone->setDelay(2000);
mLdapParamsClone->setMinChars(3); mLdapParamsClone->setMinChars(0); // Needs to be 0 if Contacts list should be synchronized with LDAP AB
mLdapParamsClone->enableTls(true); mLdapParamsClone->enableTls(true);
} }
} }

View file

@ -71,6 +71,7 @@ signals:
void unreadNotificationsChanged(); void unreadNotificationsChanged();
void requestFetchConfig(QString path); void requestFetchConfig(QString path);
void requestRestart(); void requestRestart();
void enabledLdapAddressBookSaved();
private: private:
QString mConfigPath; QString mConfigPath;

View file

@ -493,6 +493,7 @@ void SettingsModel::notifyConfigReady(){
DEFINE_NOTIFY_CONFIG_READY(assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain) DEFINE_NOTIFY_CONFIG_READY(assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
DEFINE_NOTIFY_CONFIG_READY(assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport) DEFINE_NOTIFY_CONFIG_READY(assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DEFINE_NOTIFY_CONFIG_READY(autoStart, AutoStart) DEFINE_NOTIFY_CONFIG_READY(autoStart, AutoStart)
DEFINE_NOTIFY_CONFIG_READY(syncLdapContacts, SyncLdapContacts)
} }
DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, disableChatFeature, DisableChatFeature, "disable_chat_feature", false) DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, disableChatFeature, DisableChatFeature, "disable_chat_feature", false)
@ -575,4 +576,11 @@ DEFINE_GETSET_CONFIG(SettingsModel,
AutoStart, AutoStart,
"auto_start", "auto_start",
false) false)
DEFINE_GETSET_CONFIG(SettingsModel,
bool,
Bool,
syncLdapContacts,
SyncLdapContacts,
"sync_ldap_contacts",
true)
// clang-format on // clang-format on

View file

@ -140,6 +140,7 @@ public:
DECLARE_GETSET(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain) DECLARE_GETSET(QString, assistantThirdPartySipAccountDomain, AssistantThirdPartySipAccountDomain)
DECLARE_GETSET(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport) DECLARE_GETSET(QString, assistantThirdPartySipAccountTransport, AssistantThirdPartySipAccountTransport)
DECLARE_GETSET(bool, autoStart, AutoStart) DECLARE_GETSET(bool, autoStart, AutoStart)
DECLARE_GETSET(bool, syncLdapContacts, SyncLdapContacts)
signals: signals:

View file

@ -5,6 +5,7 @@ import QtQuick.Controls as Control
import Linphone import Linphone
import UtilsCpp 1.0 import UtilsCpp 1.0
import ConstantsCpp 1.0 import ConstantsCpp 1.0
import SettingsCpp
ListView { ListView {
id: mainItem id: mainItem
@ -97,6 +98,18 @@ ListView {
} }
aggregationFlag: mainItem.aggregationFlag aggregationFlag: mainItem.aggregationFlag
sourceModel: mainItem.sourceModel sourceModel: mainItem.sourceModel
sourceFlags: LinphoneEnums.MagicSearchSource.Friends | ((mainItem.searchText.length > 0 && mainItem.searchText != "*") || SettingsCpp.syncLdapContacts ? LinphoneEnums.MagicSearchSource.LdapServers : 0)
onInitialized: {
magicSearchProxy.forceUpdate()
}
}
Connections {
target: SettingsCpp
onLdapConfigChanged: {
if (SettingsCpp.syncLdapContacts)
magicSearchProxy.forceUpdate()
}
} }
Control.ScrollBar.vertical: ScrollBar { Control.ScrollBar.vertical: ScrollBar {
@ -295,6 +308,7 @@ ListView {
textWeight: 400 * DefaultStyle.dp textWeight: 400 * DefaultStyle.dp
textColor: DefaultStyle.danger_500main textColor: DefaultStyle.danger_500main
contentImageColor: DefaultStyle.danger_500main contentImageColor: DefaultStyle.danger_500main
visible: !modelData.core.readOnly
onClicked: { onClicked: {
mainItem.contactDeletionRequested(modelData) mainItem.contactDeletionRequested(modelData)
friendPopup.close() friendPopup.close()

View file

@ -398,6 +398,7 @@ AbstractMainPage {
background: Item{} background: Item{}
onClicked: mainItem.editContact(mainItem.selectedContact) onClicked: mainItem.editContact(mainItem.selectedContact)
icon.source: AppIcons.pencil icon.source: AppIcons.pencil
visible: !mainItem.selectedContact.core.readOnly
} }
detailContent: ColumnLayout { detailContent: ColumnLayout {
Layout.fillWidth: false Layout.fillWidth: false
@ -694,6 +695,7 @@ AbstractMainPage {
iconSource: AppIcons.pencil iconSource: AppIcons.pencil
text: qsTr("Edit") text: qsTr("Edit")
onClicked: mainItem.editContact(mainItem.selectedContact) onClicked: mainItem.editContact(mainItem.selectedContact)
visible: !mainItem.selectedContact.core.readOnly
} }
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
@ -788,6 +790,7 @@ AbstractMainPage {
iconSource: AppIcons.trashCan iconSource: AppIcons.trashCan
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500main
text: qsTr("Delete this contact") text: qsTr("Delete this contact")
visible: !mainItem.selectedContact.core.readOnly
onClicked: { onClicked: {
mainItem.deleteContact(contact) mainItem.deleteContact(contact)
} }