mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
Add OpenLDAP supports
- set defaults for LDAP - add unsaving a server - adapt design for LDAP (placement, debug and verifications options) - Add hidden options in linphonerc to hide local sip account, start video call button and start chat button
This commit is contained in:
parent
77a3f294e0
commit
384bd0675a
44 changed files with 2489 additions and 44 deletions
|
|
@ -163,7 +163,7 @@ endif()
|
|||
|
||||
|
||||
if(ENABLE_BUILD_APP_PLUGINS)
|
||||
file(GLOB children RELATIVE plugins plugins/*)
|
||||
file(GLOB children "plugins/*")
|
||||
set(dirlist "")
|
||||
foreach(child ${children})
|
||||
if(IS_DIRECTORY ${curdir}/${child} AND (ENABLE_BUILD_EXAMPLES OR NOT ${child} MATCHES "example"))
|
||||
|
|
|
|||
|
|
@ -145,6 +145,9 @@ set(SOURCES
|
|||
src/components/file/FileExtractor.cpp
|
||||
src/components/history/HistoryModel.cpp
|
||||
src/components/history/HistoryProxyModel.cpp
|
||||
src/components/ldap/LdapModel.cpp
|
||||
src/components/ldap/LdapListModel.cpp
|
||||
src/components/ldap/LdapProxyModel.cpp
|
||||
src/components/notifier/Notifier.cpp
|
||||
src/components/other/clipboard/Clipboard.cpp
|
||||
src/components/other/colors/Colors.cpp
|
||||
|
|
@ -152,11 +155,13 @@ set(SOURCES
|
|||
src/components/other/units/Units.cpp
|
||||
src/components/presence/OwnPresenceModel.cpp
|
||||
src/components/presence/Presence.cpp
|
||||
src/components/search/SearchHandler.cpp
|
||||
src/components/settings/AccountSettingsModel.cpp
|
||||
src/components/settings/SettingsModel.cpp
|
||||
src/components/sip-addresses/SipAddressesModel.cpp
|
||||
src/components/sip-addresses/SipAddressesProxyModel.cpp
|
||||
src/components/sip-addresses/SipAddressObserver.cpp
|
||||
src/components/sip-addresses/SearchSipAddressesModel.cpp
|
||||
src/components/sound-player/SoundPlayer.cpp
|
||||
src/components/telephone-numbers/TelephoneNumbersModel.cpp
|
||||
src/components/timeline/TimelineModel.cpp
|
||||
|
|
@ -215,6 +220,9 @@ set(HEADERS
|
|||
src/components/file/FileExtractor.hpp
|
||||
src/components/history/HistoryModel.hpp
|
||||
src/components/history/HistoryProxyModel.hpp
|
||||
src/components/ldap/LdapModel.hpp
|
||||
src/components/ldap/LdapListModel.hpp
|
||||
src/components/ldap/LdapProxyModel.hpp
|
||||
src/components/notifier/Notifier.hpp
|
||||
src/components/other/clipboard/Clipboard.hpp
|
||||
src/components/other/colors/Colors.hpp
|
||||
|
|
@ -223,11 +231,13 @@ set(HEADERS
|
|||
src/components/other/units/Units.hpp
|
||||
src/components/presence/OwnPresenceModel.hpp
|
||||
src/components/presence/Presence.hpp
|
||||
src/components/search/SearchHandler.hpp
|
||||
src/components/settings/AccountSettingsModel.hpp
|
||||
src/components/settings/SettingsModel.hpp
|
||||
src/components/sip-addresses/SipAddressesModel.hpp
|
||||
src/components/sip-addresses/SipAddressesProxyModel.hpp
|
||||
src/components/sip-addresses/SipAddressObserver.hpp
|
||||
src/components/sip-addresses/SearchSipAddressesModel.hpp
|
||||
src/components/sound-player/SoundPlayer.hpp
|
||||
src/components/telephone-numbers/TelephoneNumbersModel.hpp
|
||||
src/components/timeline/TimelineModel.hpp
|
||||
|
|
@ -378,7 +388,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.cmake" "${CMAKE_CURRENT
|
|||
# ------------------------------------------------------------------------------
|
||||
|
||||
include_directories(src/)
|
||||
include_directories("${LINPHONE_OUTPUT_DIR}}/include/OpenGL")
|
||||
include_directories("${LINPHONE_OUTPUT_DIR}/include/OpenGL")
|
||||
|
||||
if (CMAKE_INSTALL_RPATH)
|
||||
#Retrieve lib path from a know QT executable
|
||||
|
|
@ -500,7 +510,8 @@ target_link_libraries(${TARGET_NAME} ${LIBRARIES})
|
|||
target_link_libraries(${TARGET_NAME} ${APP_PLUGIN})
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(${TARGET_NAME} wsock32 ws2_32)
|
||||
find_library(LDAP_LIBRARIES NAMES ldap HINTS "${LINPHONE_OUTPUT_DIR}/lib")
|
||||
target_link_libraries(${TARGET_NAME} wsock32 ws2_32 ${LDAP_LIBRARIES})
|
||||
endif()
|
||||
|
||||
add_dependencies(${APP_LIBRARY} update_translations ${TARGET_NAME}-git-version ${APP_PLUGIN})
|
||||
|
|
|
|||
|
|
@ -489,5 +489,9 @@
|
|||
<file>ui/dev-modules/Colors/Colors.qml</file>
|
||||
<file>ui/dev-modules/Units/Units.qml</file>
|
||||
<file>assets/icon.ico</file>
|
||||
<file>ui/views/App/Settings/SettingsLdap.qml</file>
|
||||
<file>ui/views/App/Settings/SettingsLdapDescription.qml</file>
|
||||
<file>ui/views/App/Settings/Dialogs/SettingsLdapEdit.qml</file>
|
||||
<file>ui/views/App/Settings/Dialogs/SettingsLdapEdit.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
|||
|
|
@ -579,6 +579,8 @@ void App::registerTypes () {
|
|||
|
||||
qRegisterMetaType<shared_ptr<linphone::ProxyConfig>>();
|
||||
qRegisterMetaType<ChatModel::EntryType>();
|
||||
qRegisterMetaType<shared_ptr<linphone::SearchResult>>();
|
||||
qRegisterMetaType<std::list<std::shared_ptr<linphone::SearchResult> > >();
|
||||
|
||||
registerType<AssistantModel>("AssistantModel");
|
||||
registerType<AuthenticationNotifier>("AuthenticationNotifier");
|
||||
|
|
@ -593,7 +595,10 @@ void App::registerTypes () {
|
|||
registerType<FileDownloader>("FileDownloader");
|
||||
registerType<FileExtractor>("FileExtractor");
|
||||
registerType<HistoryProxyModel>("HistoryProxyModel");
|
||||
registerType<LdapProxyModel>("LdapProxyModel");
|
||||
registerType<SipAddressesProxyModel>("SipAddressesProxyModel");
|
||||
registerType<SearchSipAddressesModel>("SearchSipAddressesModel");
|
||||
|
||||
registerType<SoundPlayer>("SoundPlayer");
|
||||
registerType<TelephoneNumbersModel>("TelephoneNumbersModel");
|
||||
|
||||
|
|
@ -610,6 +615,7 @@ void App::registerTypes () {
|
|||
registerUncreatableType<ContactModel>("ContactModel");
|
||||
registerUncreatableType<ContactsImporterModel>("ContactsImporterModel");
|
||||
registerUncreatableType<HistoryModel>("HistoryModel");
|
||||
registerUncreatableType<LdapModel>("LdapModel");
|
||||
registerUncreatableType<SipAddressObserver>("SipAddressObserver");
|
||||
registerUncreatableType<VcardModel>("VcardModel");
|
||||
}
|
||||
|
|
@ -625,6 +631,7 @@ void App::registerSharedTypes () {
|
|||
registerSharedSingletonType<CallsListModel, &CoreManager::getCallsListModel>("CallsListModel");
|
||||
registerSharedSingletonType<ContactsListModel, &CoreManager::getContactsListModel>("ContactsListModel");
|
||||
registerSharedSingletonType<ContactsImporterListModel, &CoreManager::getContactsImporterListModel>("ContactsImporterListModel");
|
||||
registerSharedSingletonType<LdapListModel, &CoreManager::getLdapListModel>("LdapListModel");
|
||||
}
|
||||
|
||||
void App::registerToolTypes () {
|
||||
|
|
|
|||
|
|
@ -46,12 +46,16 @@
|
|||
#include "file/FileDownloader.hpp"
|
||||
#include "file/FileExtractor.hpp"
|
||||
#include "history/HistoryProxyModel.hpp"
|
||||
#include "ldap/LdapModel.hpp"
|
||||
#include "ldap/LdapListModel.hpp"
|
||||
#include "ldap/LdapProxyModel.hpp"
|
||||
#include "notifier/Notifier.hpp"
|
||||
#include "presence/OwnPresenceModel.hpp"
|
||||
#include "settings/AccountSettingsModel.hpp"
|
||||
#include "settings/SettingsModel.hpp"
|
||||
#include "sip-addresses/SipAddressesModel.hpp"
|
||||
#include "sip-addresses/SipAddressesProxyModel.hpp"
|
||||
#include "sip-addresses/SearchSipAddressesModel.hpp"
|
||||
#include "sound-player/SoundPlayer.hpp"
|
||||
#include "telephone-numbers/TelephoneNumbersModel.hpp"
|
||||
#include "timeline/TimelineModel.hpp"
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@
|
|||
#include "utils/MediastreamerUtils.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
//#include "linphone/api/c-magic-search.h"
|
||||
#include "linphone/api/c-search-result.h"
|
||||
//#include "linphone/api/friends.h"
|
||||
|
||||
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -45,10 +49,33 @@ namespace {
|
|||
constexpr char AutoAnswerObjectName[] = "auto-answer-timer";
|
||||
}
|
||||
|
||||
CallModel::CallModel (shared_ptr<linphone::Call> call) {
|
||||
void CallModel::searchReceived(std::list<std::shared_ptr<linphone::SearchResult>> results){
|
||||
bool found = false;
|
||||
for(auto it = results.begin() ; it != results.end() && !found ; ++it){
|
||||
if((*it)->getFriend()){
|
||||
if((*it)->getFriend()->getAddress()->weakEqual(mRemoteAddress)){
|
||||
setRemoteDisplayName((*it)->getFriend()->getName());
|
||||
found = true;
|
||||
}
|
||||
}else{
|
||||
if((*it)->getAddress()->weakEqual(mRemoteAddress)){
|
||||
setRemoteDisplayName((*it)->getAddress()->getDisplayName());
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CallModel::setRemoteDisplayName(const std::string& name){
|
||||
mRemoteAddress->setDisplayName(name);
|
||||
emit fullPeerAddressChanged();
|
||||
}
|
||||
|
||||
CallModel::CallModel (shared_ptr<linphone::Call> call){
|
||||
Q_CHECK_PTR(call);
|
||||
mCall = call;
|
||||
mCall->setData("call-model", *this);
|
||||
|
||||
|
||||
updateIsInConference();
|
||||
|
||||
|
|
@ -78,23 +105,34 @@ CallModel::CallModel (shared_ptr<linphone::Call> call) {
|
|||
coreHandlers, &CoreHandlers::callEncryptionChanged,
|
||||
this, &CallModel::handleCallEncryptionChanged
|
||||
);
|
||||
// Update fields
|
||||
mMagicSearch = CoreManager::getInstance()->getCore()->createMagicSearch();
|
||||
mSearch = std::make_shared<SearchHandler>(this);
|
||||
QObject::connect(mSearch.get(), SIGNAL(searchReceived(std::list<std::shared_ptr<linphone::SearchResult>> )), this, SLOT(searchReceived(std::list<std::shared_ptr<linphone::SearchResult>>)));
|
||||
mMagicSearch->addListener(mSearch);
|
||||
|
||||
mRemoteAddress = mCall->getRemoteAddress()->clone();
|
||||
mMagicSearch->getContactListFromFilterAsync(mRemoteAddress->getUsername(),mRemoteAddress->getDomain());
|
||||
|
||||
|
||||
}
|
||||
|
||||
CallModel::~CallModel () {
|
||||
mCall->unsetData("call-model");
|
||||
mMagicSearch->removeListener(mSearch);
|
||||
mCall->unsetData("call-model");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString CallModel::getPeerAddress () const {
|
||||
return Utils::coreStringToAppString(mCall->getRemoteAddress()->asStringUriOnly());
|
||||
return Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
|
||||
}
|
||||
|
||||
QString CallModel::getLocalAddress () const {
|
||||
return Utils::coreStringToAppString(mCall->getCallLog()->getLocalAddress()->asStringUriOnly());
|
||||
}
|
||||
QString CallModel::getFullPeerAddress () const {
|
||||
return QString::fromStdString(mCall->getRemoteAddress()->asString());
|
||||
return QString::fromStdString(mRemoteAddress->asString());
|
||||
}
|
||||
|
||||
QString CallModel::getFullLocalAddress () const {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include "../search/SearchHandler.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ class CallModel : public QObject {
|
|||
|
||||
Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT);
|
||||
Q_PROPERTY(QString localAddress READ getLocalAddress CONSTANT);
|
||||
Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress CONSTANT);
|
||||
Q_PROPERTY(QString fullPeerAddress READ getFullPeerAddress NOTIFY fullPeerAddressChanged);
|
||||
Q_PROPERTY(QString fullLocalAddress READ getFullLocalAddress CONSTANT);
|
||||
|
||||
Q_PROPERTY(CallStatus status READ getStatus NOTIFY statusChanged);
|
||||
|
|
@ -132,8 +132,17 @@ public:
|
|||
Q_INVOKABLE void updateStreams ();
|
||||
|
||||
Q_INVOKABLE void toggleSpeakerMute();
|
||||
|
||||
void setRemoteDisplayName(const std::string& name);
|
||||
|
||||
static constexpr int DtmfSoundDelay = 200;
|
||||
|
||||
std::shared_ptr<linphone::Call> mCall;
|
||||
std::shared_ptr<linphone::Address> mRemoteAddress;
|
||||
std::shared_ptr<linphone::MagicSearch> mMagicSearch;
|
||||
|
||||
public slots:
|
||||
void searchReceived(std::list<std::shared_ptr<linphone::SearchResult>> results);
|
||||
|
||||
signals:
|
||||
void callErrorChanged (const QString &callError);
|
||||
|
|
@ -149,10 +158,14 @@ signals:
|
|||
void microVolumeGainChanged (float volume);
|
||||
|
||||
void cameraFirstFrameReceived (unsigned int width, unsigned int height);
|
||||
|
||||
void fullPeerAddressChanged();
|
||||
|
||||
private:
|
||||
void handleCallEncryptionChanged (const std::shared_ptr<linphone::Call> &call);
|
||||
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
|
||||
|
||||
|
||||
|
||||
void accept (bool withVideo);
|
||||
|
||||
|
|
@ -230,8 +243,8 @@ private:
|
|||
|
||||
QVariantList mAudioStats;
|
||||
QVariantList mVideoStats;
|
||||
std::shared_ptr<SearchHandler> mSearch;
|
||||
|
||||
std::shared_ptr<linphone::Call> mCall;
|
||||
};
|
||||
|
||||
#endif // CALL_MODEL_H_
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "components/contacts/ContactsListModel.hpp"
|
||||
#include "components/contacts/ContactsImporterListModel.hpp"
|
||||
#include "components/history/HistoryModel.hpp"
|
||||
#include "components/ldap/LdapListModel.hpp"
|
||||
#include "components/settings/AccountSettingsModel.hpp"
|
||||
#include "components/settings/SettingsModel.hpp"
|
||||
#include "components/sip-addresses/SipAddressesModel.hpp"
|
||||
|
|
@ -101,6 +102,7 @@ void CoreManager::initCoreManager(){
|
|||
mContactsListModel = new ContactsListModel(this);
|
||||
mContactsImporterListModel = new ContactsImporterListModel(this);
|
||||
mAccountSettingsModel = new AccountSettingsModel(this);
|
||||
mLdapListModel = new LdapListModel(this);
|
||||
mSettingsModel = new SettingsModel(this);
|
||||
mSipAddressesModel = new SipAddressesModel(this);
|
||||
mEventCountNotifier = new EventCountNotifier(this);
|
||||
|
|
@ -108,6 +110,10 @@ void CoreManager::initCoreManager(){
|
|||
QObject::connect(mEventCountNotifier, &EventCountNotifier::eventCountChanged,this, &CoreManager::eventCountChanged);
|
||||
migrate();
|
||||
mStarted = true;
|
||||
//std::list<std::string> dns;
|
||||
//dns.push_back("10.0.3.50");
|
||||
//mCore->setDnsServers(dns);
|
||||
|
||||
qInfo() << QStringLiteral("CoreManager initialized");
|
||||
emit coreManagerInitialized();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,10 +39,12 @@ class ContactsImporterListModel;
|
|||
class CoreHandlers;
|
||||
class EventCountNotifier;
|
||||
class HistoryModel;
|
||||
class LdapListModel;
|
||||
class SettingsModel;
|
||||
class SipAddressesModel;
|
||||
class VcardModel;
|
||||
|
||||
|
||||
class CoreManager : public QObject {
|
||||
Q_OBJECT;
|
||||
|
||||
|
|
@ -116,7 +118,9 @@ public:
|
|||
Q_CHECK_PTR(mAccountSettingsModel);
|
||||
return mAccountSettingsModel;
|
||||
}
|
||||
|
||||
LdapListModel *getLdapListModel() const{
|
||||
return mLdapListModel;
|
||||
}
|
||||
static CoreManager *getInstance ();
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -199,6 +203,7 @@ private:
|
|||
|
||||
QHash<QPair<QString, QString>, std::weak_ptr<ChatModel>> mChatModels;
|
||||
HistoryModel * mHistoryModel = nullptr;
|
||||
LdapListModel *mLdapListModel = nullptr;
|
||||
|
||||
QTimer *mCbsTimer = nullptr;
|
||||
|
||||
|
|
|
|||
139
linphone-app/src/components/ldap/LdapListModel.cpp
Normal file
139
linphone-app/src/components/ldap/LdapListModel.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 <QDateTime>
|
||||
#include <QElapsedTimer>
|
||||
#include <QUrl>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "components/core/CoreHandlers.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "utils/LinphoneUtils.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "LdapListModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
LdapListModel::LdapListModel (QObject *parent) : QAbstractListModel(parent) {
|
||||
initLdap();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void LdapListModel::reset(){
|
||||
resetInternalData();
|
||||
initLdap();
|
||||
}
|
||||
int LdapListModel::rowCount (const QModelIndex &) const {
|
||||
return mServers.count();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> LdapListModel::roleNames () const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Qt::DisplayRole] = "$ldapServer";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant LdapListModel::data (const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
|
||||
if (!index.isValid() || row < 0 || row >= mServers.count())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariant::fromValue(mServers[row]);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool LdapListModel::removeRow (int row, const QModelIndex &parent) {
|
||||
return removeRows(row, 1, parent);
|
||||
}
|
||||
|
||||
bool LdapListModel::removeRows (int row, int count, const QModelIndex &parent) {
|
||||
int limit = row + count - 1;
|
||||
|
||||
if (row < 0 || count < 0 || limit >= mServers.count())
|
||||
return false;
|
||||
|
||||
beginRemoveRows(parent, row, limit);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
delete mServers.takeAt(row);
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void LdapListModel::initLdap () {
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
auto lConfig = coreManager->getCore()->getConfig();
|
||||
auto bcSections = lConfig->getSectionsNamesList();
|
||||
for(auto itSections = bcSections.begin(); itSections != bcSections.end(); ++itSections) {
|
||||
LdapModel * ldap = new LdapModel();
|
||||
if(ldap->load(*itSections)){
|
||||
mServers.append(ldap);
|
||||
}else
|
||||
delete ldap;
|
||||
}
|
||||
}
|
||||
|
||||
void LdapListModel::enable(int id, bool status){
|
||||
if( mServers[id]->isValid()){
|
||||
QVariantMap config = mServers[id]->getConfig();
|
||||
config["enable"] = status;
|
||||
mServers[id]->setConfig(config);
|
||||
mServers[id]->save();
|
||||
|
||||
}
|
||||
|
||||
emit dataChanged(index(id, 0), index(id, 0));
|
||||
}
|
||||
|
||||
void LdapListModel::add(){
|
||||
int row = mServers.count();
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
auto ldap= new LdapModel(row);
|
||||
ldap->init();
|
||||
mServers << ldap;
|
||||
endInsertRows();
|
||||
//emit dataChanged(index(row, 0), index(row, 0));
|
||||
resetInternalData();
|
||||
}
|
||||
void LdapListModel::remove (LdapModel *ldap) {
|
||||
int index = mServers.indexOf(ldap);
|
||||
if (index >=0){
|
||||
ldap->unsave();
|
||||
removeRow(index);
|
||||
}
|
||||
}
|
||||
62
linphone-app/src/components/ldap/LdapListModel.hpp
Normal file
62
linphone-app/src/components/ldap/LdapListModel.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 LDAP_LIST_MODEL_H_
|
||||
#define LDAP_LIST_MODEL_H_
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QDateTime>
|
||||
|
||||
#include "LdapModel.hpp"
|
||||
// =============================================================================
|
||||
|
||||
class CoreHandlers;
|
||||
|
||||
class LdapListModel : public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
LdapListModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
void reset();
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames () const override;
|
||||
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
Q_INVOKABLE void enable(int id, bool status);
|
||||
Q_INVOKABLE void add();
|
||||
Q_INVOKABLE void remove (LdapModel *importer);
|
||||
|
||||
|
||||
private:
|
||||
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
|
||||
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void initLdap ();
|
||||
|
||||
QList<LdapModel*> mServers;
|
||||
};
|
||||
|
||||
#endif // LDAP_LIST_MODEL_H_
|
||||
349
linphone-app/src/components/ldap/LdapModel.cpp
Normal file
349
linphone-app/src/components/ldap/LdapModel.cpp
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 <QDateTime>
|
||||
#include <QElapsedTimer>
|
||||
#include <QUrl>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "components/core/CoreHandlers.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "utils/LinphoneUtils.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "LdapModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
LdapModel::LdapModel (const int& id,QObject *parent ) : QObject(parent), mId(id){
|
||||
mIsValid = false;
|
||||
mMaxResults = 50;
|
||||
mDebug = false;
|
||||
mVerifyServerCertificates = -1;
|
||||
mUseTls = true;
|
||||
mUseSal = false;
|
||||
mServer = "ldap://ldap.example.org";
|
||||
mConfig["enable"] = "0";
|
||||
}
|
||||
|
||||
void LdapModel::init(){
|
||||
set();
|
||||
unset();
|
||||
}
|
||||
|
||||
bool LdapModel::isValid(){
|
||||
bool valid = mServerFieldError==""
|
||||
&& mMaxResultsFieldError==""
|
||||
&& mPasswordFieldError==""
|
||||
&& mBindDnFieldError==""
|
||||
&& mBaseObjectFieldError==""
|
||||
&& mFilterFieldError==""
|
||||
&& mNameAttributesFieldError==""
|
||||
&& mSipAttributesFieldError==""
|
||||
&& mSipSchemeFieldError==""
|
||||
&& mSipDomainFieldError=="";
|
||||
if( valid != mIsValid){
|
||||
mIsValid = valid;
|
||||
emit isValidChanged();
|
||||
}
|
||||
return mIsValid;
|
||||
}
|
||||
void LdapModel::save(){
|
||||
if(isValid()){
|
||||
set();
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
auto lConfig = coreManager->getCore()->getConfig();
|
||||
std::string section = ("ldap_"+QString::number(mId)).toStdString();
|
||||
lConfig->cleanSection(section);
|
||||
for(auto it = mConfig.begin() ; it != mConfig.end() ; ++it)
|
||||
lConfig->setString(section, it.key().toStdString(), it.value().toString().toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::unsave(){
|
||||
if(mId>=0){
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
auto lConfig = coreManager->getCore()->getConfig();
|
||||
std::string section = ("ldap_"+QString::number(mId)).toStdString();
|
||||
lConfig->cleanSection(section);
|
||||
}
|
||||
}
|
||||
|
||||
bool LdapModel::load(const std::string& section){
|
||||
bool ok = false;
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
auto lConfig = coreManager->getCore()->getConfig();
|
||||
std::string sectionName;
|
||||
size_t i = section.length()-1;
|
||||
while(i>0 && section[i] != '_')// Get the name strip number
|
||||
--i;
|
||||
if(i>0){
|
||||
sectionName = section.substr(0,i);
|
||||
mId = atoi(section.substr(i+1).c_str());
|
||||
}else{
|
||||
sectionName = section;
|
||||
mId = 0;
|
||||
}
|
||||
if(sectionName == "ldap"){
|
||||
mConfig.clear();
|
||||
auto keys = lConfig->getKeysNamesList(section);
|
||||
for(auto itKeys = keys.begin() ; itKeys != keys.end() ; ++itKeys){
|
||||
mConfig[QString::fromStdString(*itKeys)] = QString::fromStdString(lConfig->getString(section, *itKeys, ""));
|
||||
}
|
||||
unset();
|
||||
ok = true;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
QVariantMap LdapModel::getConfig(){
|
||||
return mConfig;
|
||||
}
|
||||
|
||||
void LdapModel::setConfig(const QVariantMap& config){
|
||||
mConfig = config;
|
||||
emit configChanged();
|
||||
}
|
||||
|
||||
void LdapModel::set(){
|
||||
mConfig["server"] = mServer;
|
||||
mConfig["display_name"] = mDisplayName;
|
||||
mConfig["use_sal"] = (mUseSal?"1":"0");
|
||||
mConfig["use_tls"] = (mUseTls?"1":"0");
|
||||
mConfig["server"] = mServer;
|
||||
mConfig["max_results"] = mMaxResults;
|
||||
mConfig["password"] = mPassword;
|
||||
mConfig["bind_dn"] = mBindDn;
|
||||
mConfig["base_object"] = mBaseObject;
|
||||
mConfig["filter"] = mFilter;
|
||||
mConfig["name_attribute"] = mNameAttributes;
|
||||
mConfig["sip_attribute"] = mSipAttributes;
|
||||
mConfig["sip_scheme"] = mSipScheme;
|
||||
mConfig["sip_domain"] = mSipDomain;
|
||||
mConfig["debug"] = (mDebug?"1":"0");
|
||||
mConfig["verify_server_certificates"] = mVerifyServerCertificates;
|
||||
}
|
||||
|
||||
void LdapModel::unset(){
|
||||
mServer = mConfig["server"].toString();
|
||||
mDisplayName = mConfig["display_name"].toString();
|
||||
mUseTls = mConfig["use_tls"].toString() == "1";
|
||||
mUseSal = mConfig["use_sal"].toString() == "1";
|
||||
mMaxResults = mConfig["max_results"].toInt();
|
||||
mPassword = mConfig["password"].toString();
|
||||
mBindDn = mConfig["bind_dn"].toString();
|
||||
mBaseObject = mConfig["base_object"].toString();
|
||||
mFilter = mConfig["filter"].toString();
|
||||
mNameAttributes = mConfig["name_attribute"].toString();
|
||||
mSipAttributes = mConfig["sip_attribute"].toString();
|
||||
mSipScheme = mConfig["sip_scheme"].toString();
|
||||
mSipDomain = mConfig["sip_domain"].toString();
|
||||
mDebug = mConfig["debug"].toString() == "1";
|
||||
mVerifyServerCertificates = mConfig["verify_server_certificates"].toInt();
|
||||
|
||||
testServerField();
|
||||
testMaxResultsField();
|
||||
testPasswordField();
|
||||
testBindDnField();
|
||||
testBaseObjectField();
|
||||
testFilterField();
|
||||
testNameAttributesField();
|
||||
testSipAttributesField();
|
||||
testSipSchemeField();
|
||||
testSipDomainField();
|
||||
isValid();
|
||||
}
|
||||
bool LdapModel::isEnabled(){
|
||||
return mConfig["enable"].toString() == "1";
|
||||
}
|
||||
void LdapModel::setEnabled(const bool& data){
|
||||
if(isValid()){
|
||||
mConfig["enable"] = (data?"1":"0");
|
||||
save();
|
||||
}else
|
||||
mConfig["enable"] = "0";
|
||||
emit enabledChanged();
|
||||
}
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
void LdapModel::setServer(const QString& server){
|
||||
mServer = server;
|
||||
testServerField();
|
||||
emit serverChanged();
|
||||
}
|
||||
void LdapModel::testServerField(){
|
||||
QString valid;
|
||||
if(mServer == "")
|
||||
valid = "Server must not be empty";
|
||||
else{
|
||||
QUrl url(mServer);
|
||||
if(!url.isValid())
|
||||
valid = "Server is not an URL";
|
||||
else if(url.scheme().left(4) != "ldap")
|
||||
valid = "URL must begin by a ldap scheme";
|
||||
else
|
||||
valid = "";
|
||||
}
|
||||
if( valid != mServerFieldError){
|
||||
mServerFieldError = valid;
|
||||
emit serverFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setMaxResults(const int& data){
|
||||
mMaxResults = data;
|
||||
testMaxResultsField();
|
||||
emit maxResultsChanged();
|
||||
}
|
||||
void LdapModel::testMaxResultsField(){
|
||||
QString valid;
|
||||
if(mMaxResults <= 0)
|
||||
valid = "Max Results must be greater than 0";
|
||||
else
|
||||
valid = "";
|
||||
if( valid != mMaxResultsFieldError){
|
||||
mMaxResultsFieldError = valid;
|
||||
emit maxResultsFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setPassword(const QString& data){
|
||||
mPassword = data;
|
||||
testPasswordField();
|
||||
emit passwordChanged();
|
||||
}
|
||||
void LdapModel::testPasswordField(){
|
||||
QString valid = "";
|
||||
if( valid != mPasswordFieldError){
|
||||
mPasswordFieldError = valid;
|
||||
emit passwordFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setBindDn(const QString& data){
|
||||
mBindDn = data;
|
||||
testBindDnField();
|
||||
emit bindDnChanged();
|
||||
}
|
||||
void LdapModel::testBindDnField(){
|
||||
QString valid;
|
||||
if(mBindDn == "")
|
||||
valid = "Bind DN must not be empty";
|
||||
else
|
||||
valid = "";
|
||||
if( valid != mBindDnFieldError){
|
||||
mBindDnFieldError = valid;
|
||||
emit bindDnFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setBaseObject(const QString& data){
|
||||
mBaseObject = data;
|
||||
testBaseObjectField();
|
||||
emit baseObjectChanged();
|
||||
}
|
||||
void LdapModel::testBaseObjectField(){
|
||||
QString valid;
|
||||
if(mBaseObject == "")
|
||||
valid = "Base Object must not be empty";
|
||||
else
|
||||
valid = "";
|
||||
if( valid != mBaseObjectFieldError){
|
||||
mBaseObjectFieldError = valid;
|
||||
emit baseObjectFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setFilter(const QString& data){
|
||||
mFilter = data;
|
||||
testFilterField();
|
||||
emit filterChanged();
|
||||
}
|
||||
void LdapModel::testFilterField(){
|
||||
QString valid = "";
|
||||
if( valid != mFilterFieldError){
|
||||
mFilterFieldError = valid;
|
||||
emit filterFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setNameAttributes(const QString& data){
|
||||
mNameAttributes = data;
|
||||
testNameAttributesField();
|
||||
emit nameAttributesChanged();
|
||||
}
|
||||
void LdapModel::testNameAttributesField(){
|
||||
QString valid = "";
|
||||
if( valid != mNameAttributesFieldError){
|
||||
mNameAttributesFieldError = valid;
|
||||
emit nameAttributesFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setSipAttributes(const QString& data){
|
||||
mSipAttributes = data;
|
||||
testSipAttributesField();
|
||||
emit sipAttributesChanged();
|
||||
}
|
||||
void LdapModel::testSipAttributesField(){
|
||||
QString valid = "";
|
||||
if( valid != mSipAttributesFieldError){
|
||||
mSipAttributesFieldError = valid;
|
||||
emit sipAttributesFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setSipScheme(const QString& data){
|
||||
mSipScheme = data;
|
||||
testSipSchemeField();
|
||||
emit sipSchemeChanged();
|
||||
}
|
||||
void LdapModel::testSipSchemeField(){
|
||||
QString valid = "";
|
||||
if( valid != mSipSchemeFieldError){
|
||||
mSipSchemeFieldError = valid;
|
||||
emit sipSchemeFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapModel::setSipDomain(const QString& data){
|
||||
mSipDomain = data;
|
||||
testSipDomainField();
|
||||
emit sipDomainChanged();
|
||||
}
|
||||
void LdapModel::testSipDomainField(){
|
||||
QString valid = "";
|
||||
if( valid != mSipDomainFieldError){
|
||||
mSipDomainFieldError = valid;
|
||||
emit sipDomainFieldErrorChanged();
|
||||
isValid();
|
||||
}
|
||||
}
|
||||
191
linphone-app/src/components/ldap/LdapModel.hpp
Normal file
191
linphone-app/src/components/ldap/LdapModel.hpp
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 LDAP_MODEL_H_
|
||||
#define LDAP_MODEL_H_
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QDateTime>
|
||||
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class CoreHandlers;
|
||||
|
||||
class LdapModel : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QVariantMap config READ getConfig WRITE setConfig NOTIFY configChanged)
|
||||
Q_PROPERTY(bool isValid MEMBER mIsValid NOTIFY isValidChanged)
|
||||
|
||||
Q_PROPERTY(QString server MEMBER mServer WRITE setServer NOTIFY serverChanged)
|
||||
Q_PROPERTY(QString serverFieldError MEMBER mServerFieldError NOTIFY serverFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString displayName MEMBER mDisplayName NOTIFY displayNameChanged)
|
||||
|
||||
Q_PROPERTY(bool useTls MEMBER mUseTls NOTIFY useTlsChanged)
|
||||
Q_PROPERTY(bool useSal MEMBER mUseSal NOTIFY useSalChanged)
|
||||
|
||||
Q_PROPERTY(int maxResults MEMBER mMaxResults WRITE setMaxResults NOTIFY maxResultsChanged)
|
||||
Q_PROPERTY(QString maxResultsFieldError MEMBER mMaxResultsFieldError NOTIFY maxResultsFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString password MEMBER mPassword WRITE setPassword NOTIFY passwordChanged)
|
||||
Q_PROPERTY(QString passwordFieldError MEMBER mPasswordFieldError NOTIFY passwordFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString bindDn MEMBER mBindDn WRITE setBindDn NOTIFY bindDnChanged)
|
||||
Q_PROPERTY(QString bindDnFieldError MEMBER mBindDnFieldError NOTIFY bindDnFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString baseObject MEMBER mBaseObject WRITE setBaseObject NOTIFY baseObjectChanged)
|
||||
Q_PROPERTY(QString baseObjectFieldError MEMBER mBaseObjectFieldError NOTIFY baseObjectFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString filter MEMBER mFilter WRITE setFilter NOTIFY filterChanged)
|
||||
Q_PROPERTY(QString filterFieldError MEMBER mFilterFieldError NOTIFY filterFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString nameAttributes MEMBER mNameAttributes WRITE setNameAttributes NOTIFY nameAttributesChanged)
|
||||
Q_PROPERTY(QString nameAttributesFieldError MEMBER mNameAttributesFieldError NOTIFY nameAttributesFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString sipAttributes MEMBER mSipAttributes WRITE setSipAttributes NOTIFY sipAttributesChanged)
|
||||
Q_PROPERTY(QString sipAttributesFieldError MEMBER mSipAttributesFieldError NOTIFY sipAttributesFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString sipScheme MEMBER mSipScheme WRITE setSipScheme NOTIFY sipSchemeChanged)
|
||||
Q_PROPERTY(QString sipSchemeFieldError MEMBER mSipSchemeFieldError NOTIFY sipSchemeFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(QString sipDomain MEMBER mSipDomain WRITE setSipDomain NOTIFY sipDomainChanged)
|
||||
Q_PROPERTY(QString sipDomainFieldError MEMBER mSipDomainFieldError NOTIFY sipDomainFieldErrorChanged)
|
||||
|
||||
Q_PROPERTY(bool debug MEMBER mDebug NOTIFY debugChanged)
|
||||
Q_PROPERTY(int verifyServerCertificates MEMBER mVerifyServerCertificates NOTIFY verifyServerCertificatesChanged)
|
||||
|
||||
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
|
||||
public:
|
||||
|
||||
LdapModel (const int& id = 0,QObject *parent = nullptr);
|
||||
|
||||
QVariantMap mConfig;
|
||||
bool mIsValid;
|
||||
int mId; // "ldap_mId" from section name
|
||||
|
||||
QString mServer;
|
||||
QString mServerFieldError;
|
||||
void setServer(const QString& server);
|
||||
void testServerField();
|
||||
|
||||
QString mDisplayName;
|
||||
|
||||
bool mUseSal;
|
||||
bool mUseTls;
|
||||
|
||||
int mMaxResults;
|
||||
QString mMaxResultsFieldError;
|
||||
void setMaxResults(const int& data);
|
||||
void testMaxResultsField();
|
||||
|
||||
QString mPassword;
|
||||
QString mPasswordFieldError;
|
||||
void setPassword(const QString& data);
|
||||
void testPasswordField();
|
||||
|
||||
QString mBindDn;
|
||||
QString mBindDnFieldError;
|
||||
void setBindDn(const QString& data);
|
||||
void testBindDnField();
|
||||
|
||||
QString mBaseObject;
|
||||
QString mBaseObjectFieldError;
|
||||
void setBaseObject(const QString& data);
|
||||
void testBaseObjectField();
|
||||
|
||||
QString mFilter;
|
||||
QString mFilterFieldError;
|
||||
void setFilter(const QString& data);
|
||||
void testFilterField();
|
||||
|
||||
QString mNameAttributes;
|
||||
QString mNameAttributesFieldError;
|
||||
void setNameAttributes(const QString& data);
|
||||
void testNameAttributesField();
|
||||
|
||||
QString mSipAttributes;
|
||||
QString mSipAttributesFieldError;
|
||||
void setSipAttributes(const QString& data);
|
||||
void testSipAttributesField();
|
||||
|
||||
QString mSipScheme;
|
||||
QString mSipSchemeFieldError;
|
||||
void setSipScheme(const QString& data);
|
||||
void testSipSchemeField();
|
||||
|
||||
QString mSipDomain;
|
||||
QString mSipDomainFieldError;
|
||||
void setSipDomain(const QString& data);
|
||||
void testSipDomainField();
|
||||
|
||||
bool mDebug;
|
||||
int mVerifyServerCertificates;
|
||||
|
||||
bool isValid();
|
||||
void init();// init by default value
|
||||
Q_INVOKABLE void save();
|
||||
void unsave();
|
||||
bool load(const std::string& sectionName);
|
||||
void set();
|
||||
Q_INVOKABLE void unset();
|
||||
|
||||
QVariantMap getConfig();
|
||||
void setConfig(const QVariantMap& config);
|
||||
|
||||
bool isEnabled();
|
||||
void setEnabled(const bool& data);
|
||||
|
||||
signals:
|
||||
void configChanged();
|
||||
void isValidChanged();
|
||||
void serverChanged();
|
||||
void displayNameChanged();
|
||||
void useTlsChanged();
|
||||
void useSalChanged();
|
||||
void isServerValidChanged();
|
||||
void maxResultsChanged();
|
||||
void passwordChanged();
|
||||
void bindDnChanged();
|
||||
void baseObjectChanged();
|
||||
void filterChanged();
|
||||
void nameAttributesChanged();
|
||||
void sipAttributesChanged();
|
||||
void sipSchemeChanged();
|
||||
void sipDomainChanged();
|
||||
void debugChanged();
|
||||
void verifyServerCertificatesChanged();
|
||||
|
||||
|
||||
void serverFieldErrorChanged();
|
||||
void maxResultsFieldErrorChanged();
|
||||
void passwordFieldErrorChanged();
|
||||
void bindDnFieldErrorChanged();
|
||||
void baseObjectFieldErrorChanged();
|
||||
void filterFieldErrorChanged();
|
||||
void nameAttributesFieldErrorChanged();
|
||||
void sipAttributesFieldErrorChanged();
|
||||
void sipSchemeFieldErrorChanged();
|
||||
void sipDomainFieldErrorChanged();
|
||||
|
||||
void enabledChanged();
|
||||
};
|
||||
Q_DECLARE_METATYPE(LdapModel*);
|
||||
#endif // LDAP_MODEL_H_
|
||||
49
linphone-app/src/components/ldap/LdapProxyModel.cpp
Normal file
49
linphone-app/src/components/ldap/LdapProxyModel.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 "components/core/CoreManager.hpp"
|
||||
|
||||
#include "LdapModel.hpp"
|
||||
#include "LdapListModel.hpp"
|
||||
#include "LdapProxyModel.hpp"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LdapProxyModel::LdapProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSourceModel(CoreManager::getInstance()->getLdapListModel());
|
||||
sort(0);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool LdapProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
|
||||
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LdapProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
|
||||
const LdapModel* ldapA = sourceModel()->data(left).value<LdapModel*>();
|
||||
const LdapModel* ldapB = sourceModel()->data(right).value<LdapModel*>();
|
||||
|
||||
return ldapA->mId <= ldapB->mId;
|
||||
}
|
||||
39
linphone-app/src/components/ldap/LdapProxyModel.hpp
Normal file
39
linphone-app/src/components/ldap/LdapProxyModel.hpp
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 LDAP_PROXY_MODEL_H_
|
||||
#define LDAP_PROXY_MODEL_H_
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class LdapProxyModel : public QSortFilterProxyModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
LdapProxyModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
};
|
||||
|
||||
#endif // LDAP_PROXY_MODEL_H_
|
||||
31
linphone-app/src/components/search/SearchHandler.cpp
Normal file
31
linphone-app/src/components/search/SearchHandler.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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 "SearchHandler.hpp"
|
||||
|
||||
#include "linphone/api/c-search-result.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
SearchHandler::SearchHandler(QObject * parent) : QObject(parent){
|
||||
}
|
||||
|
||||
void SearchHandler::onSearchResultsReceived(const std::shared_ptr<linphone::MagicSearch> & magicSearch){
|
||||
emit searchReceived(magicSearch->getLastSearch());
|
||||
}
|
||||
38
linphone-app/src/components/search/SearchHandler.hpp
Normal file
38
linphone-app/src/components/search/SearchHandler.hpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 SEARCH_HANDLER_H_
|
||||
#define SEARCH_HANDLER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include <list>
|
||||
// =============================================================================
|
||||
class SearchHandler : public QObject, public linphone::MagicSearchListener{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SearchHandler(QObject * parent = nullptr);
|
||||
virtual void onSearchResultsReceived(const std::shared_ptr<linphone::MagicSearch> & magicSearch);
|
||||
signals:
|
||||
void searchReceived(std::list<std::shared_ptr<linphone::SearchResult>> );
|
||||
};
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<linphone::SearchResult>);
|
||||
#endif // SEARCH_HANDLER_H_
|
||||
|
|
@ -397,7 +397,7 @@ QVariantList AccountSettingsModel::getAccounts () const {
|
|||
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
|
||||
QVariantList accounts;
|
||||
|
||||
{
|
||||
if(CoreManager::getInstance()->getSettingsModel()->getShowLocalSipAccount()) {
|
||||
QVariantMap account;
|
||||
account["sipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asStringUriOnly());
|
||||
account["fullSipAddress"] = QString::fromStdString(core->createPrimaryContactParsed()->asString());
|
||||
|
|
|
|||
|
|
@ -1188,6 +1188,20 @@ void SettingsModel::setExitOnClose (bool value) {
|
|||
emit exitOnCloseChanged(value);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool SettingsModel::getShowLocalSipAccount()const{
|
||||
return !!mConfig->getInt(UiSection, "show_local_sip_account", 1);
|
||||
}
|
||||
|
||||
bool SettingsModel::getShowStartChatButton ()const{
|
||||
return !!mConfig->getInt(UiSection, "show_start_chat_button", 1);
|
||||
}
|
||||
|
||||
bool SettingsModel::getShowStartVideoCallButton ()const{
|
||||
return !!mConfig->getInt(UiSection, "show_start_video_button", 1);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Advanced.
|
||||
// =============================================================================
|
||||
|
|
|
|||
|
|
@ -170,6 +170,10 @@ class SettingsModel : public QObject {
|
|||
|
||||
Q_PROPERTY(bool exitOnClose READ getExitOnClose WRITE setExitOnClose NOTIFY exitOnCloseChanged)
|
||||
|
||||
Q_PROPERTY(bool showLocalSipAccount READ getShowLocalSipAccount CONSTANT)
|
||||
Q_PROPERTY(bool showStartChat READ getShowStartChatButton CONSTANT)
|
||||
Q_PROPERTY(bool showStartVideoCallButton READ getShowStartVideoCallButton CONSTANT)
|
||||
|
||||
// Advanced. -----------------------------------------------------------------
|
||||
|
||||
Q_PROPERTY(QString logsFolder READ getLogsFolder WRITE setLogsFolder NOTIFY logsFolderChanged)
|
||||
|
|
@ -426,6 +430,10 @@ public:
|
|||
bool getExitOnClose () const;
|
||||
void setExitOnClose (bool value);
|
||||
|
||||
bool getShowLocalSipAccount () const;
|
||||
bool getShowStartChatButton () const;
|
||||
bool getShowStartVideoCallButton () const;
|
||||
|
||||
// Advanced. ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 <QDateTime>
|
||||
#include <QElapsedTimer>
|
||||
#include <QUrl>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "components/call/CallModel.hpp"
|
||||
#include "components/chat/ChatModel.hpp"
|
||||
#include "components/contact/ContactModel.hpp"
|
||||
#include "components/contact/VcardModel.hpp"
|
||||
#include "components/contacts/ContactsListModel.hpp"
|
||||
#include "components/core/CoreHandlers.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
#include "components/history/HistoryModel.hpp"
|
||||
#include "components/settings/AccountSettingsModel.hpp"
|
||||
#include "utils/LinphoneUtils.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
|
||||
#include "SearchSipAddressesModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
using namespace std;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
static inline QVariantMap buildVariantMap (const SearchSipAddressesModel::SipAddressEntry &sipAddressEntry) {
|
||||
return QVariantMap{
|
||||
{ "sipAddress", sipAddressEntry.sipAddress },
|
||||
{ "contact", QVariant::fromValue(sipAddressEntry.contact) },
|
||||
{ "presenceStatus", sipAddressEntry.presenceStatus },
|
||||
{ "__localToConferenceEntry", QVariant::fromValue(&sipAddressEntry.localAddressToConferenceEntry) }
|
||||
};
|
||||
}
|
||||
*/
|
||||
SearchSipAddressesModel::SearchSipAddressesModel (QObject *parent) : QAbstractListModel(parent) {
|
||||
|
||||
mMagicSearch = CoreManager::getInstance()->getCore()->createMagicSearch();
|
||||
mSearch = std::make_shared<SearchHandler>(this);
|
||||
QObject::connect(mSearch.get(), SIGNAL(searchReceived(std::list<std::shared_ptr<linphone::SearchResult>> )), this, SLOT(searchReceived(std::list<std::shared_ptr<linphone::SearchResult>>)));
|
||||
mMagicSearch->addListener(mSearch);
|
||||
|
||||
}
|
||||
SearchSipAddressesModel::~SearchSipAddressesModel(){
|
||||
|
||||
mMagicSearch->removeListener(mSearch);
|
||||
|
||||
}
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
int SearchSipAddressesModel::rowCount (const QModelIndex &) const {
|
||||
return mAddresses.count()-1;
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> SearchSipAddressesModel::roleNames () const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Qt::DisplayRole] = "$sipAddress";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant SearchSipAddressesModel::data (const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
|
||||
if (!index.isValid() || row < 0 || row >= mAddresses.count())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariantMap{{"sipAddress", mAddresses[row]}};
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool SearchSipAddressesModel::removeRow (int row, const QModelIndex &parent) {
|
||||
return removeRows(row, 1, parent);
|
||||
}
|
||||
|
||||
bool SearchSipAddressesModel::removeRows (int row, int count, const QModelIndex &parent) {
|
||||
int limit = row + count - 1;
|
||||
|
||||
if (row < 0 || count < 0 || limit >= mAddresses.count())
|
||||
return false;
|
||||
|
||||
beginRemoveRows(parent, row, limit);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
mAddresses.removeAt(row);
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
return true;
|
||||
}
|
||||
static std::list<std::pair<std::shared_ptr<linphone::MagicSearch>, std::shared_ptr<SearchHandler> > > searches;
|
||||
class DeleteMagic{
|
||||
public:
|
||||
std::shared_ptr<linphone::MagicSearch> magic;
|
||||
std::shared_ptr<SearchHandler> search;
|
||||
};
|
||||
|
||||
void SearchSipAddressesModel::setFilter(const QString& filter){
|
||||
mMagicSearch->getContactListFromFilterAsync(filter.toStdString(),"");
|
||||
//searchReceived(mMagicSearch->getContactListFromFilter(filter.toStdString(),"")); // Just to show how to use sync method
|
||||
|
||||
}
|
||||
|
||||
void SearchSipAddressesModel::searchReceived(std::list<std::shared_ptr<linphone::SearchResult>> results){
|
||||
beginResetModel();
|
||||
mAddresses.clear();
|
||||
for(auto it = results.begin() ; it != results.end() ; ++it){
|
||||
if((*it)->getFriend()){
|
||||
//QString username = QString::fromStdString((*it)->getFriend()->getName());
|
||||
//auto f = (*it)->getFriend();
|
||||
//auto vcard = f->getVcard();
|
||||
//if(vcard)
|
||||
// qDebug() << QString::fromStdString(vcard->asVcard4String());
|
||||
|
||||
mAddresses << QString::fromStdString((*it)->getFriend()->getAddress()->asString());
|
||||
//qDebug() << username << " " << QString::fromStdString((*it)->getFriend()->getAddress()->getDisplayName());
|
||||
}else{
|
||||
//QString username = QString::fromStdString((*it)->getAddress()->getDisplayName());
|
||||
mAddresses << QString::fromStdString((*it)->getAddress()->asString());
|
||||
//qDebug() << username;
|
||||
}
|
||||
}
|
||||
//invalidate();
|
||||
endResetModel();
|
||||
/*
|
||||
mMagicSearch->removeListener(mSearch);
|
||||
mMagicSearch = nullptr;
|
||||
mSearch = nullptr;*/
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 SEARCH_SIP_ADDRESSES_MODEL_H_
|
||||
#define SEARCH_SIP_ADDRESSES_MODEL_H_
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QDateTime>
|
||||
#include <list>
|
||||
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include "../search/SearchHandler.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
||||
class SearchSipAddressesModel : public QAbstractListModel {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
SearchSipAddressesModel (QObject *parent = Q_NULLPTR);
|
||||
~SearchSipAddressesModel();
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames () const override;
|
||||
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
Q_INVOKABLE void setFilter (const QString &pattern);
|
||||
|
||||
QStringList mAddresses;
|
||||
|
||||
std::shared_ptr<linphone::MagicSearch> mMagicSearch;
|
||||
std::shared_ptr<SearchHandler> mSearch;
|
||||
|
||||
public slots:
|
||||
void searchReceived(std::list<std::shared_ptr<linphone::SearchResult>> results);
|
||||
|
||||
private:
|
||||
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
|
||||
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
|
||||
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(SearchSipAddressesModel *);
|
||||
|
||||
#endif // SIP_ADDRESSES_MODEL_H_
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 "components/contact/ContactModel.hpp"
|
||||
#include "components/contact/VcardModel.hpp"
|
||||
#include "components/core/CoreManager.hpp"
|
||||
|
||||
#include "SearchSipAddressesModel.hpp"
|
||||
#include "SearchSipAddressesProxyModel.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
namespace {
|
||||
constexpr int WeightPos0 = 5;
|
||||
constexpr int WeightPos1 = 4;
|
||||
constexpr int WeightPos2 = 3;
|
||||
constexpr int WeightPos3 = 2;
|
||||
constexpr int WeightPosOther = 1;
|
||||
}
|
||||
|
||||
const QRegExp SearchSipAddressesProxyModel::SearchSeparators("^[^_.-;@ ][_.-;@ ]");
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
SearchSipAddressesProxyModel::SearchSipAddressesProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSourceModel(CoreManager::getInstance()->getSipAddressesModel());
|
||||
sort(0);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void SearchSipAddressesProxyModel::setFilter (const QString &pattern) {
|
||||
mFilter = pattern;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool SearchSipAddressesProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
|
||||
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
return computeEntryWeight(index.data().toMap()) > 0;
|
||||
}
|
||||
|
||||
bool SearchSipAddressesProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
|
||||
const QVariantMap mapA = sourceModel()->data(left).toMap();
|
||||
const QVariantMap mapB = sourceModel()->data(right).toMap();
|
||||
|
||||
const QString sipAddressA = mapA["sipAddress"].toString();
|
||||
const QString sipAddressB = mapB["sipAddress"].toString();
|
||||
|
||||
// TODO: Use a cache, do not compute the same value as `filterAcceptsRow`.
|
||||
int weightA = computeEntryWeight(mapA);
|
||||
int weightB = computeEntryWeight(mapB);
|
||||
|
||||
// 1. Not the same weight.
|
||||
if (weightA != weightB)
|
||||
return weightA > weightB;
|
||||
|
||||
const ContactModel *contactA = mapA.value("contact").value<ContactModel *>();
|
||||
const ContactModel *contactB = mapB.value("contact").value<ContactModel *>();
|
||||
|
||||
// 2. No contacts.
|
||||
if (!contactA && !contactB)
|
||||
return sipAddressA <= sipAddressB;
|
||||
|
||||
// 3. No contact for a or b.
|
||||
if (!contactA || !contactB)
|
||||
return !!contactA;
|
||||
|
||||
// 4. Same contact (address).
|
||||
if (contactA == contactB)
|
||||
return sipAddressA <= sipAddressB;
|
||||
|
||||
// 5. Not the same contact name.
|
||||
int diff = contactA->mLinphoneFriend->getName().compare(contactB->mLinphoneFriend->getName());
|
||||
if (diff)
|
||||
return diff <= 0;
|
||||
|
||||
// 6. Same contact name, so compare sip addresses.
|
||||
return sipAddressA <= sipAddressB;
|
||||
}
|
||||
|
||||
int SearchSipAddressesProxyModel::computeEntryWeight (const QVariantMap &entry) const {
|
||||
int weight = computeStringWeight(entry["sipAddress"].toString().mid(4));
|
||||
|
||||
const ContactModel *contact = entry.value("contact").value<ContactModel *>();
|
||||
if (contact)
|
||||
weight += computeStringWeight(contact->getVcardModel()->getUsername());
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
int SearchSipAddressesProxyModel::computeStringWeight (const QString &string) const {
|
||||
int index = -1;
|
||||
int offset = -1;
|
||||
|
||||
while ((index = string.indexOf(mFilter, index + 1, Qt::CaseInsensitive)) != -1) {
|
||||
int tmpOffset = index - string.lastIndexOf(SearchSeparators, index) - 1;
|
||||
if ((tmpOffset != -1 && tmpOffset < offset) || offset == -1)
|
||||
if ((offset = tmpOffset) == 0) break;
|
||||
}
|
||||
|
||||
switch (offset) {
|
||||
case -1: return 0;
|
||||
case 0: return WeightPos0;
|
||||
case 1: return WeightPos1;
|
||||
case 2: return WeightPos2;
|
||||
case 3: return WeightPos3;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return WeightPosOther;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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 SEARCH_SIP_ADDRESSES_PROXY_MODEL_H_
|
||||
#define SEARCH_SIP_ADDRESSES_PROXY_MODEL_H_
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class SearchSipAddressesProxyModel : public QSortFilterProxyModel {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
SearchSipAddressesProxyModel (QObject *parent = Q_NULLPTR);
|
||||
|
||||
Q_INVOKABLE void setFilter (const QString &pattern);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
private:
|
||||
int computeEntryWeight (const QVariantMap &entry) const;
|
||||
int computeStringWeight (const QString &string) const;
|
||||
|
||||
QString mFilter;
|
||||
|
||||
static const QRegExp SearchSeparators;
|
||||
};
|
||||
|
||||
#endif // SIP_ADDRESSES_PROXY_MODEL_H_
|
||||
|
|
@ -92,4 +92,22 @@ Controls.TextField {
|
|||
iconSize: parent.contentHeight
|
||||
visible: !parent.text
|
||||
}
|
||||
bottomPadding: (statusItem.visible?statusItem.height:0)
|
||||
TextEdit{
|
||||
id:statusItem
|
||||
selectByMouse: true
|
||||
readOnly:true
|
||||
color: TextFieldStyle.background.border.color.error
|
||||
width:parent.width
|
||||
anchors.bottom:parent.bottom
|
||||
anchors.right:parent.right
|
||||
anchors.rightMargin:10 + toolsContainer.width
|
||||
horizontalAlignment:Text.AlignRight
|
||||
font {
|
||||
italic: true
|
||||
pointSize: TextFieldStyle.text.pointSize
|
||||
}
|
||||
visible:error!= ''
|
||||
text:error
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import QtQuick 2.7
|
|||
import QtQuick.Layouts 1.3
|
||||
|
||||
import Common.Styles 1.0
|
||||
import Common 1.0
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -9,6 +10,8 @@ Column {
|
|||
property alias title: title.text
|
||||
property bool dealWithErrors: false
|
||||
property int orientation: Qt.Horizontal
|
||||
property bool addButton : false
|
||||
signal addButtonClicked;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -21,14 +24,26 @@ Column {
|
|||
visible: parent.title.length > 0
|
||||
width: parent.width
|
||||
|
||||
Text {
|
||||
id: title
|
||||
|
||||
color: FormStyle.header.title.color
|
||||
font {
|
||||
bold: true
|
||||
pointSize: FormStyle.header.title.pointSize
|
||||
}
|
||||
Row{
|
||||
spacing:10
|
||||
Text {
|
||||
id: title
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
color: FormStyle.header.title.color
|
||||
font {
|
||||
bold: true
|
||||
pointSize: FormStyle.header.title.pointSize
|
||||
}
|
||||
}
|
||||
ActionButton {
|
||||
visible:addButton
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon: 'add'
|
||||
iconSize:38
|
||||
scale:0.8
|
||||
onClicked:addButtonClicked()
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Common.Styles 1.0
|
|||
// =============================================================================
|
||||
|
||||
Row {
|
||||
readonly property double maxItemWidth: {
|
||||
property double maxItemWidth: {
|
||||
var n = children.length
|
||||
var curWidth = width / n - (n - 1) * spacing
|
||||
var maxWidth = orientation === Qt.Horizontal
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Controls 2.2 as Controls
|
||||
|
||||
import Common 1.0
|
||||
import Common.Styles 1.0
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Switch {
|
||||
Controls.Switch {
|
||||
id: control
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@ TextField 1.0 Form/Fields/TextField.qml
|
|||
Form 1.0 Form/Placements/Form.qml
|
||||
FormEmptyLine 1.0 Form/Placements/FormEmptyLine.qml
|
||||
FormGroup 1.0 Form/Placements/FormGroup.qml
|
||||
FormHGroup 1.0 Form/Placements/FormHGroup.qml
|
||||
FormVGroup 1.0 Form/Placements/FormVGroup.qml
|
||||
FormLine 1.0 Form/Placements/FormLine.qml
|
||||
FormTable 1.0 Form/Placements/FormTable.qml
|
||||
FormTableEntry 1.0 Form/Placements/FormTableEntry.qml
|
||||
|
|
|
|||
|
|
@ -33,11 +33,11 @@ Notification {
|
|||
|
||||
Contact {
|
||||
Layout.fillWidth: true
|
||||
|
||||
entry: {
|
||||
var call = notification.call
|
||||
return SipAddressesModel.getSipAddressObserver(call ? call.fullPeerAddress : '', call ? call.fullLocalAddress : '')
|
||||
}
|
||||
property var peerAddress: notification.call ? notification.call.fullPeerAddress : ''
|
||||
onPeerAddressChanged: {
|
||||
entry=SipAddressesModel.getSipAddressObserver(peerAddress, notification.call ? notification.call.fullLocalAddress : '')
|
||||
}
|
||||
entry: SipAddressesModel.getSipAddressObserver(peerAddress, notification.call ? notification.call.fullLocalAddress : '')
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ SearchBox {
|
|||
searchBox.closeMenu()
|
||||
searchBox.launchVideoCall(entry.sipAddress)
|
||||
},
|
||||
visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled
|
||||
visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
|
||||
}, {
|
||||
icon: 'call',
|
||||
handler: function (entry) {
|
||||
|
|
@ -55,7 +55,7 @@ SearchBox {
|
|||
},
|
||||
visible: SettingsModel.outgoingCallsEnabled
|
||||
}, {
|
||||
icon: SettingsModel.chatEnabled ? 'chat' : 'history',
|
||||
icon: SettingsModel.chatEnabled && SettingsModel.showStartChatButton ? 'chat' : 'history',
|
||||
handler: function (entry) {
|
||||
searchBox.closeMenu()
|
||||
searchBox.launchChat(entry.sipAddress)
|
||||
|
|
@ -71,7 +71,7 @@ SearchBox {
|
|||
|
||||
genSipAddress: searchBox.filter
|
||||
|
||||
model: SipAddressesProxyModel {}
|
||||
model: SearchSipAddressesModel {}
|
||||
|
||||
onEntryClicked: {
|
||||
searchBox.closeMenu()
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ DialogPlus {
|
|||
CallsListModel.launchVideoCall(entry.sipAddress)
|
||||
exit(1)
|
||||
},
|
||||
visible: SettingsModel.videoSupported
|
||||
visible: SettingsModel.videoSupported && SettingsModel.showStartVideoCallButton
|
||||
}, {
|
||||
icon: 'call',
|
||||
handler: function (entry) {
|
||||
|
|
@ -75,7 +75,7 @@ DialogPlus {
|
|||
|
||||
genSipAddress: filter.text
|
||||
|
||||
model: SipAddressesProxyModel {
|
||||
model: SearchSipAddressesModel {
|
||||
id: sipAddressesModel
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ DialogPlus {
|
|||
|
||||
genSipAddress: filter.text
|
||||
|
||||
model: SipAddressesProxyModel {
|
||||
model: SearchSipAddressesModel {
|
||||
id: sipAddressesModel
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -420,7 +420,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
ActionButton {
|
||||
icon: SettingsModel.chatEnabled ? 'chat' : 'history'
|
||||
icon: SettingsModel.chatEnabled && SettingsModel.showStartChatButton ? 'chat' : 'history'
|
||||
|
||||
onClicked: {
|
||||
if (window.chatIsOpened) {
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ ColumnLayout {
|
|||
|
||||
ActionButton {
|
||||
icon: 'video_call'
|
||||
visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled
|
||||
visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
|
||||
|
||||
onClicked: actions.itemAt(0).open()
|
||||
}
|
||||
|
|
@ -145,7 +145,7 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
ActionButton {
|
||||
icon: SettingsModel.chatEnabled ? 'chat' : 'history'
|
||||
icon: SettingsModel.chatEnabled && SettingsModel.showStartChatButton ? 'chat' : 'history'
|
||||
onClicked: actions.itemAt(2).open()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ ColumnLayout {
|
|||
|
||||
ActionButton {
|
||||
icon: 'video_call'
|
||||
visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled
|
||||
visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
|
||||
|
||||
onClicked: CallsListModel.launchVideoCall(conversation.peerAddress)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ ColumnLayout {
|
|||
|
||||
ActionButton {
|
||||
icon: 'video_call'
|
||||
visible: peerAddress && SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled
|
||||
visible: peerAddress && SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton
|
||||
|
||||
onClicked: CallsListModel.launchVideoCall(historyView.peerAddress)
|
||||
}
|
||||
|
|
|
|||
149
linphone-app/ui/views/App/Settings/Dialogs/SettingsLdapEdit.js
Normal file
149
linphone-app/ui/views/App/Settings/Dialogs/SettingsLdapEdit.js
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2020 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/>.
|
||||
*/
|
||||
// =============================================================================
|
||||
// `SettingsSipAccounts.qml` Logic.
|
||||
// =============================================================================
|
||||
|
||||
.import Linphone 1.0 as Linphone
|
||||
|
||||
.import 'qrc:/ui/scripts/Utils/utils.js' as Utils
|
||||
|
||||
// =============================================================================
|
||||
|
||||
var proxyConfig
|
||||
|
||||
function initForm (ldap) {
|
||||
/*
|
||||
var AccountSettingsModel = Linphone.AccountSettingsModel
|
||||
|
||||
proxyConfig = account
|
||||
? account.proxyConfig
|
||||
: AccountSettingsModel.createProxyConfig()
|
||||
|
||||
var config = AccountSettingsModel.getProxyConfigDescription(proxyConfig)
|
||||
|
||||
sipAddress.text = config.sipAddress
|
||||
serverAddress.text = config.serverAddress
|
||||
registrationDuration.text = config.registrationDuration
|
||||
|
||||
var currentTransport = config.transport.toUpperCase()
|
||||
transport.currentIndex = Number(
|
||||
Utils.findIndex(transport.model, function (value) {
|
||||
return value === currentTransport
|
||||
})
|
||||
)
|
||||
|
||||
route.text = config.route
|
||||
contactParams.text = config.contactParams
|
||||
avpfInterval.text = config.avpfInterval
|
||||
registerEnabled.checked = config.registerEnabled
|
||||
publishPresence.checked = config.publishPresence
|
||||
avpfEnabled.checked = config.avpfEnabled
|
||||
iceEnabled.checked = config.iceEnabled
|
||||
turnEnabled.checked = config.turnEnabled
|
||||
stunServer.text = config.stunServer
|
||||
turnPassword.text = config.turnPassword
|
||||
turnUser.text = config.turnUser
|
||||
|
||||
if (account) {
|
||||
dialog._sipAddressOk = true
|
||||
dialog._serverAddressOk = true
|
||||
}
|
||||
|
||||
|
||||
dialog._routeOk = true
|
||||
*/
|
||||
}
|
||||
|
||||
function formIsValid () {
|
||||
//return dialog._sipAddressOk && dialog._serverAddressOk && dialog._routeOk
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function validProxyConfig () {
|
||||
/*
|
||||
if (Linphone.AccountSettingsModel.addOrUpdateProxyConfig(proxyConfig, {
|
||||
sipAddress: sipAddress.text,
|
||||
serverAddress: serverAddress.text,
|
||||
registrationDuration: registrationDuration.text,
|
||||
transport: transport.currentText,
|
||||
route: route.text,
|
||||
contactParams: contactParams.text,
|
||||
avpfInterval: avpfInterval.text,
|
||||
registerEnabled: registerEnabled.checked,
|
||||
publishPresence: publishPresence.checked,
|
||||
avpfEnabled: avpfEnabled.checked,
|
||||
iceEnabled: iceEnabled.checked,
|
||||
turnEnabled: turnEnabled.checked,
|
||||
stunServer: stunServer.text,
|
||||
turnUser: turnUser.text,
|
||||
turnPassword: turnPassword.text
|
||||
})) {
|
||||
dialog.exit(1)
|
||||
} else {
|
||||
// TODO: Display errors on the form (if necessary).
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
function handleRouteChanged (route) {
|
||||
// dialog._routeOk = route.length === 0 || Linphone.SipAddressesModel.addressIsValid(route)
|
||||
}
|
||||
|
||||
function handleServerAddressChanged (address) {
|
||||
/*
|
||||
if (address.length === 0) {
|
||||
dialog._serverAddressOk = false
|
||||
return
|
||||
}
|
||||
|
||||
var newTransport = Linphone.SipAddressesModel.getTransportFromSipAddress(address)
|
||||
|
||||
if (newTransport.length > 0) {
|
||||
transport.currentIndex = Utils.findIndex(transport.model, function (value) {
|
||||
return value === newTransport
|
||||
})
|
||||
dialog._serverAddressOk = true
|
||||
} else {
|
||||
dialog._serverAddressOk = false
|
||||
}*/
|
||||
}
|
||||
|
||||
function handleSipAddressChanged (address) {
|
||||
/*
|
||||
dialog._sipAddressOk = address.length > 0 &&
|
||||
Linphone.SipAddressesModel.sipAddressIsValid(address)*/
|
||||
}
|
||||
|
||||
function handleTransportChanged (transport) {
|
||||
/*
|
||||
var newServerAddress = Linphone.SipAddressesModel.addTransportToSipAddress(serverAddress.text, transport)
|
||||
if (newServerAddress.length > 0) {
|
||||
serverAddress.text = newServerAddress
|
||||
dialog._serverAddressOk = true
|
||||
} else {
|
||||
dialog._serverAddressOk = false
|
||||
}*/
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
332
linphone-app/ui/views/App/Settings/Dialogs/SettingsLdapEdit.qml
Normal file
332
linphone-app/ui/views/App/Settings/Dialogs/SettingsLdapEdit.qml
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
|
||||
import 'SettingsLdapEdit.js' as Logic
|
||||
|
||||
// =============================================================================
|
||||
|
||||
DialogPlus {
|
||||
id: dialog
|
||||
|
||||
property LdapModel ldapData
|
||||
|
||||
buttons: [
|
||||
TextButtonA {
|
||||
text: qsTr('cancel')
|
||||
|
||||
onClicked: {
|
||||
ldapData.unset()
|
||||
exit(0)}
|
||||
},
|
||||
TextButtonB {
|
||||
enabled: ldapData.isValid
|
||||
text: qsTr('confirm')
|
||||
|
||||
onClicked: {ldapData.save()
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
centeredButtons: true
|
||||
|
||||
height: SettingsSipAccountsEditStyle.height
|
||||
width: SettingsSipAccountsEditStyle.width
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
//Component.onCompleted: Logic.initForm(ldapData)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
TabContainer {
|
||||
anchors.fill: parent
|
||||
|
||||
Column {
|
||||
width: parent.width
|
||||
Form {
|
||||
title: ''
|
||||
width: parent.width
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Display Name'
|
||||
TextField {
|
||||
id:displayName
|
||||
placeholderText : (serverUrl.text?serverUrl.text:serverUrl.placeholderText)
|
||||
text:ldapData.displayName
|
||||
onTextChanged: ldapData.displayName = text
|
||||
Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus()
|
||||
TooltipArea{
|
||||
text : 'LDAP Server. eg: ldap:/// for a localhost server or ldap://ldap.example.org/'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Form {
|
||||
title: 'Connection'
|
||||
width: parent.width
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Server URL *'
|
||||
TextField {
|
||||
id:serverUrl
|
||||
placeholderText :"Server"
|
||||
text:ldapData.server
|
||||
onTextChanged: ldapData.server = text
|
||||
Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus()
|
||||
error : ldapData.serverFieldError
|
||||
TooltipArea{
|
||||
text : 'LDAP Server. eg: ldap:/// for a localhost server or ldap://ldap.example.org/'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Bind DN *'
|
||||
|
||||
TextField {
|
||||
id: bindDn
|
||||
placeholderText :"Bind DN"
|
||||
text:ldapData.bindDn
|
||||
error : ldapData.bindDnFieldError
|
||||
onTextChanged: ldapData.bindDn= text
|
||||
TooltipArea{
|
||||
text : 'The bindDN DN is the credential that is used to authenticate against an LDAP.\n eg: cn=ausername,ou=people,dc=bc,dc=com'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Password'
|
||||
PasswordField {
|
||||
id:password
|
||||
text:ldapData.password
|
||||
error : ldapData.passwordFieldError
|
||||
onTextChanged: ldapData.password = text
|
||||
placeholderText :"Password"
|
||||
}
|
||||
}
|
||||
}
|
||||
FormLine {
|
||||
id:useRow
|
||||
FormGroup {
|
||||
label: 'Use TLS'
|
||||
Switch {
|
||||
id: useTls
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: ldapData.useTls
|
||||
onClicked: {
|
||||
ldapData.useTls = !checked
|
||||
}
|
||||
TooltipArea{
|
||||
tooltipParent:useRow
|
||||
text : 'Encrypt transactions by LDAP over TLS(StartTLS). You must use \'ldap\' scheme. \'ldaps\' for LDAP over SSL is non-standardized and deprecated.\nStartTLS in an extension to the LDAP protocol which uses the TLS protocol to encrypt communication. \nIt works by establishing a normal - i.e. unsecured - connection with the LDAP server before a handshake negotiation between the server and the web services is carried out. Here, the server sends its certificate to prove its identity before the secure connection is established.'
|
||||
}
|
||||
}
|
||||
}
|
||||
FormGroup {
|
||||
label: 'Use Sal'
|
||||
Switch {
|
||||
id: useSal
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: ldapData.useSal
|
||||
onClicked: {
|
||||
ldapData.useSal = !checked
|
||||
}
|
||||
TooltipArea{
|
||||
tooltipParent:useRow
|
||||
text : 'The dns resolution is done by Linphone using Sal. It will pass an IP to LDAP. By doing that, the TLS negociation could not check the hostname. You may deactivate the verifications if wanted to force the connection.'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FormLine{
|
||||
id:useSalRow
|
||||
|
||||
FormGroup {
|
||||
label: 'Verify Certificates on TLS'
|
||||
ComboBox {
|
||||
id:verifyServerCertificates
|
||||
currentIndex: ldapData.verifyServerCertificates+1
|
||||
model: ["Auto", "Off", "On"]
|
||||
width: parent.width
|
||||
|
||||
onActivated: ldapData.verifyServerCertificates = index-1
|
||||
TooltipArea{
|
||||
text : 'Specify whether the tls server certificate must be verified when connecting to a LDAP server.'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// NAT and Firewall.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Form {
|
||||
title: 'Search'
|
||||
width: parent.width
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Base Object *'
|
||||
TextField {
|
||||
id:baseObject
|
||||
placeholderText :"Base Object"
|
||||
text:ldapData.baseObject
|
||||
error : ldapData.baseObjectFieldError
|
||||
onTextChanged: ldapData.baseObject = text
|
||||
TooltipArea{
|
||||
text : 'BaseObject is a specification for LDAP Search Scopes that specifies that the Search Request should only be performed against the entry specified as the search base DN.\n\nNo entries below it will be considered.'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Filter'
|
||||
TextField {
|
||||
id:filter
|
||||
text:ldapData.filter
|
||||
error : ldapData.filterFieldError
|
||||
onTextChanged: ldapData.filter = text
|
||||
placeholderText :"(sn=%s)"
|
||||
TooltipArea{
|
||||
text : 'The search is base on this filter to search friends. Default value : (sn=%s)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Max Results'
|
||||
|
||||
NumericField {
|
||||
id:maxResults
|
||||
text:ldapData.maxResults
|
||||
error : ldapData.maxResultsFieldError
|
||||
onTextChanged: ldapData.maxResults = text
|
||||
TooltipArea{
|
||||
text : 'The max results when requesting searches'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------------------
|
||||
// Parsing
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Form {
|
||||
title: 'Parsing'
|
||||
width: parent.width
|
||||
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Name Attributes'
|
||||
TextField {
|
||||
id:nameAttributes
|
||||
placeholderText :'sn'
|
||||
text:ldapData.nameAttributes
|
||||
error : ldapData.nameAttributesFieldError
|
||||
onTextChanged: ldapData.nameAttributes = text
|
||||
TooltipArea{
|
||||
text : 'Check these attributes To build Name Friend, separated by a comma and the first is the highest priority. The default value is: sn'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Sip Attributes'
|
||||
TextField {
|
||||
id:sipAttributes
|
||||
placeholderText :'mobile,telephoneNumber,homePhone,sn'
|
||||
text:ldapData.sipAttributes
|
||||
error : ldapData.sipAttributesFieldError
|
||||
onTextChanged: ldapData.sipAttributes = text
|
||||
TooltipArea{
|
||||
text : 'Check these attributes to build the SIP username in address of Friend. Attributes are separated by a comma and the first is the highest priority. The default value is: mobile,telephoneNumber,homePhone,sn'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Scheme'
|
||||
TextField {
|
||||
id:scheme
|
||||
placeholderText :'sip'
|
||||
text:ldapData.sipScheme
|
||||
error : ldapData.sipSchemeFieldError
|
||||
onTextChanged: ldapData.sipScheme = text
|
||||
TooltipArea{
|
||||
text : 'Add the scheme to the sip address(scheme:username@domain). The default value is sip'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
FormLine {
|
||||
FormGroup {
|
||||
label: 'Domain'
|
||||
TextField {
|
||||
id:domain
|
||||
placeholderText :'sip.linphone.org'
|
||||
text:ldapData.sipDomain
|
||||
error : ldapData.sipDomainFieldError
|
||||
onTextChanged: ldapData.sipDomain = text
|
||||
TooltipArea{
|
||||
text : 'Add the domain to the sip address(scheme:username@domain). The default value is sip.linphone.org'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Misc
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Form {
|
||||
title: 'Misc'
|
||||
width: parent.width
|
||||
|
||||
FormLine {
|
||||
id:miscLine
|
||||
FormGroup {
|
||||
label: 'Debug'
|
||||
Switch {
|
||||
id: debugMode
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: ldapData.debug
|
||||
onClicked: {
|
||||
ldapData.debug = !checked
|
||||
}
|
||||
TooltipArea{
|
||||
tooltipParent:miscLine
|
||||
text : 'Get verbose logs in Linphone log file when doing transactions (useful to debug TLS connections)'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,6 +27,12 @@
|
|||
|
||||
// =============================================================================
|
||||
|
||||
function editLdap (ldap) {
|
||||
window.attachVirtualWindow(Qt.resolvedUrl('Dialogs/SettingsLdapEdit.qml'), {
|
||||
ldapData: ldap
|
||||
})
|
||||
}
|
||||
|
||||
function cleanLogs () {
|
||||
window.attachVirtualWindow(Utils.buildDialogUri('ConfirmDialog'), {
|
||||
descriptionText: qsTr('cleanLogsDescription'),
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@ import 'SettingsAdvanced.js' as Logic
|
|||
// =============================================================================
|
||||
|
||||
TabContainer {
|
||||
Column {
|
||||
color: "#00000000"
|
||||
Column {
|
||||
id: column
|
||||
spacing: SettingsWindowStyle.forms.spacing
|
||||
width: parent.width
|
||||
|
||||
|
|
@ -97,7 +99,22 @@ TabContainer {
|
|||
}
|
||||
}
|
||||
onVisibleChanged: sendLogsBlock.setText('')
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// LDAP
|
||||
// -------------------------------------------------------------------------
|
||||
Form {
|
||||
title: 'LDAP'
|
||||
width: parent.width
|
||||
addButton:true
|
||||
onAddButtonClicked:ldapSection.add()
|
||||
SettingsLdap{
|
||||
id:ldapSection
|
||||
width: parent.width
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// ADDRESS BOOK
|
||||
// -------------------------------------------------------------------------
|
||||
|
|
@ -173,7 +190,6 @@ TabContainer {
|
|||
Component{
|
||||
id: textComponent
|
||||
Text {
|
||||
id: text
|
||||
color: FormTableStyle.entry.text.color
|
||||
elide: Text.ElideRight
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
|
@ -300,7 +316,7 @@ TabContainer {
|
|||
|
||||
Form {
|
||||
title: qsTr('developerSettingsTitle')
|
||||
visible: SettingsModel.developerSettingsEnabled
|
||||
// visible: SettingsModel.developerSettingsEnabled
|
||||
width: parent.width
|
||||
|
||||
FormLine {
|
||||
|
|
@ -317,3 +333,9 @@ TabContainer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*##^##
|
||||
Designer {
|
||||
D{i:0;autoSize:true;height:480;width:640}
|
||||
}
|
||||
##^##*/
|
||||
|
|
|
|||
77
linphone-app/ui/views/App/Settings/SettingsLdap.qml
Normal file
77
linphone-app/ui/views/App/Settings/SettingsLdap.qml
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
import Linphone.Styles 1.0
|
||||
import Common.Styles 1.0
|
||||
|
||||
import 'SettingsAdvanced.js' as Logic
|
||||
// =============================================================================
|
||||
|
||||
|
||||
Column {
|
||||
id: mainColumn
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
function add(){
|
||||
LdapListModel.add()
|
||||
}
|
||||
|
||||
spacing: FormStyle.spacing
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
Repeater{
|
||||
id: ldapList
|
||||
model:LdapProxyModel{id:ldapProxy}
|
||||
delegate:Item{
|
||||
id: swipeView
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
clip:true
|
||||
height:summaryRowItem.height
|
||||
Item{
|
||||
id: summaryRow
|
||||
anchors.fill:parent
|
||||
Row{
|
||||
id:summaryRowItem
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing:20
|
||||
ActionButton {
|
||||
id:removeldap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon: 'cancel'
|
||||
iconSize:CallsStyle.entry.iconActionSize
|
||||
scale:0.8
|
||||
onClicked:LdapListModel.remove(modelData)
|
||||
}
|
||||
Text {
|
||||
id: summaryTitle
|
||||
color: FormStyle.header.title.color
|
||||
text: (modelData.displayName?modelData.displayName:(modelData.server?modelData.server:'New server'))
|
||||
font {
|
||||
bold: true
|
||||
pointSize: FormStyle.header.title.pointSize
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
MouseArea{
|
||||
anchors.fill:parent
|
||||
onClicked:Logic.editLdap(modelData)
|
||||
}
|
||||
}
|
||||
Switch {
|
||||
id: ldapActivation
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: modelData.enabled
|
||||
onClicked: {
|
||||
modelData.enabled = !checked
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
421
linphone-app/ui/views/App/Settings/SettingsLdapDescription.qml
Normal file
421
linphone-app/ui/views/App/Settings/SettingsLdapDescription.qml
Normal file
|
|
@ -0,0 +1,421 @@
|
|||
import QtQuick 2.7
|
||||
import QtQuick.Layouts 1.3
|
||||
//import QtQuick.Controls 2.15 // SwipeView : Qt 5.7
|
||||
import QtQuick.Controls 1.4 // TabView
|
||||
import Common 1.0
|
||||
import Linphone 1.0
|
||||
|
||||
import App.Styles 1.0
|
||||
import Linphone.Styles 1.0
|
||||
import Common.Styles 1.0
|
||||
|
||||
// =============================================================================
|
||||
//Qt *View override childs geometry. Do not use them
|
||||
Item{
|
||||
id: swipeView
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
property LdapModel ldapData
|
||||
property int currentIndex: ldapData.isValid?0:1
|
||||
clip:true
|
||||
Component.onCompleted:updateHeight()
|
||||
onCurrentIndexChanged:updateHeight()
|
||||
|
||||
function updateHeight(){
|
||||
if( currentIndex==0)
|
||||
swipeView.height=summaryRowItem.height
|
||||
else if( currentIndex==1)
|
||||
swipeView.height=mainColumn.height
|
||||
}
|
||||
Item{
|
||||
id: summaryRow
|
||||
anchors.fill:parent
|
||||
visible:currentIndex == 0
|
||||
Row{
|
||||
id:summaryRowItem
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
spacing:10
|
||||
ActionButton {
|
||||
id:removeldap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
icon: 'cancel'
|
||||
iconSize:CallsStyle.entry.iconActionSize
|
||||
scale:0.8
|
||||
}
|
||||
Text {
|
||||
id: summaryTitle
|
||||
color: FormStyle.header.title.color
|
||||
text: serverUrl.text?serverUrl.text:'New server'
|
||||
font {
|
||||
bold: true
|
||||
pointSize: FormStyle.header.title.pointSize
|
||||
}
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
MouseArea{
|
||||
anchors.fill:parent
|
||||
onClicked:swipeView.currentIndex = 1
|
||||
}
|
||||
}
|
||||
Switch {
|
||||
id: ldapActivation
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
checked: false
|
||||
onClicked: {
|
||||
checked = !checked
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: page2
|
||||
anchors.fill:parent
|
||||
visible:currentIndex == 1
|
||||
Column {
|
||||
id: mainColumn
|
||||
property bool dealWithErrors: false
|
||||
property int orientation: Qt.Horizontal
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
height:centerRow.height+titleRow.height+spacing*2
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
spacing: FormStyle.spacing
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Column{
|
||||
id:titleRow
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
spacing: FormStyle.header.spacing
|
||||
|
||||
Text {
|
||||
id: title
|
||||
text:"LDAP Server settings :"+serverUrl.text
|
||||
color: FormStyle.header.title.color
|
||||
font {
|
||||
bold: true
|
||||
pointSize: FormStyle.header.title.pointSize
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.left:parent.left
|
||||
anchors.right:parent.right
|
||||
|
||||
color: FormStyle.header.separator.color
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id: centerRow
|
||||
anchors.left:parent.left
|
||||
anchors.right:parent.right
|
||||
transformOrigin: Item.Center
|
||||
layer.wrapMode: ShaderEffectSource.ClampToEdge
|
||||
height:detailsRow.height
|
||||
ActionButton {
|
||||
id:back
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 0
|
||||
icon: 'edit'
|
||||
iconSize:CallsStyle.entry.iconActionSize
|
||||
onClicked:swipeView.currentIndex = 0
|
||||
}
|
||||
RowLayout{// Details row have its size from children
|
||||
id:detailsRow
|
||||
anchors.left: back.right
|
||||
anchors.right: deleteLdap.left
|
||||
anchors.rightMargin: 10
|
||||
anchors.leftMargin: 10
|
||||
ColumnLayout{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth:true
|
||||
TextField {
|
||||
id:serverUrl
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Server"
|
||||
TooltipArea{
|
||||
text : 'LDAP Server. eg: ldap:/// for a localhost server or ldap://ldap.example.org/'
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Bind DN"
|
||||
TooltipArea{
|
||||
text : 'The bindDN DN is the credential that is used to authenticate against an LDAP.\n eg: cn=ausername,ou=people,dc=bc,dc=com'
|
||||
}
|
||||
}
|
||||
PasswordField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Password"
|
||||
}
|
||||
Switch {
|
||||
id: useTlsLdap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
checked: false
|
||||
onClicked: {
|
||||
checked = !checked
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth:true
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Base Object"
|
||||
TooltipArea{
|
||||
text : ''
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
text: "Filter"
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Filter"
|
||||
TooltipArea{
|
||||
text : 'The search is base on this filter to search friends. Default value : (sn=%s)'
|
||||
}
|
||||
}
|
||||
NumericField {
|
||||
text: "MaxResults"
|
||||
Layout.fillWidth: true
|
||||
TooltipArea{
|
||||
text : 'The max results when requesting searches'
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth:true
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Names Attributes"
|
||||
TooltipArea{
|
||||
text : 'Check these attributes To build Name Friend, separated by a comma and the first is the highest priority. The default value is: sn'
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Sip Attributes"
|
||||
TooltipArea{
|
||||
text : 'Check these attributes To build the SIP username in address of Friend, separated by a comma and the first is the highest priority. The default value is: mobile,telephoneNumber,homePhone,sn'
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Scheme"
|
||||
TooltipArea{
|
||||
text : 'Add the scheme to the sip address(scheme:username@domain). The default value is sip'
|
||||
}
|
||||
}
|
||||
TextField {
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Domain"
|
||||
TooltipArea{
|
||||
text : 'Add the domain to the sip address(scheme:username@domain). The default value is the ldap server url'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Switch {
|
||||
id: deleteLdap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
checked: false
|
||||
onClicked: {
|
||||
checked = !checked
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
Column{
|
||||
id:summaryRow
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
spacing: FormStyle.header.spacing
|
||||
//visible: parent.title.length > 0
|
||||
height:summaryTitle.height
|
||||
|
||||
Text {
|
||||
id: summaryTitle
|
||||
color: FormStyle.header.title.color
|
||||
text: "Summary of "// +serverUrl.text
|
||||
font {
|
||||
bold: true
|
||||
pointSize: FormStyle.header.title.pointSize
|
||||
}
|
||||
}
|
||||
MouseArea{
|
||||
onClicked: swipeView.currentIndex = 2
|
||||
anchors.fill:parent
|
||||
Rectangle{
|
||||
anchors.fill:parent
|
||||
color:"red"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: mainColumn
|
||||
property alias title: title.text
|
||||
property bool dealWithErrors: false
|
||||
property int orientation: Qt.Horizontal
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
height:centerRow.height+titleRow.height+spacing*2
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
spacing: FormStyle.spacing
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Column{
|
||||
id:titleRow
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 0
|
||||
anchors.rightMargin: 0
|
||||
spacing: FormStyle.header.spacing
|
||||
//visible: parent.title.length > 0
|
||||
|
||||
Text {
|
||||
id: title
|
||||
text:"LDAP Server :"+serverUrl.text
|
||||
color: FormStyle.header.title.color
|
||||
font {
|
||||
bold: true
|
||||
pointSize: FormStyle.header.title.pointSize
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.left:parent.left
|
||||
anchors.right:parent.right
|
||||
|
||||
color: FormStyle.header.separator.color
|
||||
}
|
||||
}
|
||||
Item{
|
||||
id: centerRow
|
||||
anchors.left:parent.left
|
||||
anchors.right:parent.right
|
||||
transformOrigin: Item.Center
|
||||
layer.wrapMode: ShaderEffectSource.ClampToEdge
|
||||
height:detailsRow.height
|
||||
ActionButton {
|
||||
id:removeldap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 0
|
||||
icon: 'cancel'
|
||||
iconSize:CallsStyle.entry.iconActionSize-2
|
||||
}
|
||||
RowLayout{// Details row have its size from children
|
||||
id:detailsRow
|
||||
anchors.left: removeldap.right
|
||||
anchors.right: deleteLdap.left
|
||||
anchors.rightMargin: 10
|
||||
anchors.leftMargin: 10
|
||||
ColumnLayout{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth:true
|
||||
TextField {
|
||||
id:serverUrl
|
||||
text: "Server"
|
||||
Layout.fillWidth: true
|
||||
placeholderText :"Server"
|
||||
}
|
||||
TextField {
|
||||
text: "Bind DN"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
text: "Password"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
}
|
||||
ColumnLayout{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth:true
|
||||
TextField {
|
||||
text: "Base Object"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
text: "Filter"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
text: "MaxResults"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
ColumnLayout{
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth:true
|
||||
TextField {
|
||||
text: "Names Attributes"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
text: "Sip Attributes"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
text: "Scheme"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
TextField {
|
||||
text: "Domain"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
Switch {
|
||||
id: deleteLdap
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 0
|
||||
checked: false
|
||||
onClicked: {
|
||||
checked = !checked
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "Summary"
|
||||
when: swipeView.index==1
|
||||
},
|
||||
State {
|
||||
name: "Details"
|
||||
when: swipeView.index==2
|
||||
}
|
||||
]
|
||||
*/
|
||||
}
|
||||
|
||||
/*##^##
|
||||
Designer {
|
||||
D{i:0;autoSize:true;formeditorZoom:0.75;height:480;width:640}
|
||||
}
|
||||
##^##*/
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit b1d5c79e31e9b4604a9094ae604143c010051e83
|
||||
Subproject commit b95fee70fc3456b024a8dc9c00d6adb694c58092
|
||||
Loading…
Add table
Reference in a new issue