diff --git a/README.md b/README.md index ad130b786..41990ff5d 100644 --- a/README.md +++ b/README.md @@ -52,8 +52,7 @@ For Desktop : you will need [Qt5](https://www.qt.io/download-thank-you) (_5.12 o Qt5_DIR="~/Qt/5.12.5/gcc_64/lib/cmake" PATH="~/Qt/5.12.5/gcc_64/bin/:$PATH" -Note: If you have `qtchooser` set in your `PATH`, the best use is : - +Note: If you have the third party tool `qtchooser` installed : eval "$(qtchooser -print-env)" export Qt5_DIR=${QTLIBDIR}/cmake/Qt5 export PATH=${QTTOOLDIR}:$PATH @@ -71,14 +70,8 @@ Note: If you have `qtchooser` set in your `PATH`, the best use is : ### Get sources -1. Clone repository: - git clone https://gitlab.linphone.org/BC/public/linphone-desktop.git --recursive -2. Update sub-modules - - git submodule update --init --recursive - ### Building : General Steps @@ -98,6 +91,8 @@ Note : For XCode or Visual Studio, you have to add `--config ` if y When all are over, the files will be in the OUTPUT folder in the build directory. When rebuilding, you have to use `cmake --build . --target install` (or `cmake --install .`) to put the application in the correct configuration. +Binaries inside other folders (like `linphone-app` and `linphone-sdk`) are not supposed to work. + 4. When doing some modifications in the SDK, you can rebuild only the SDK with the target `sdk` and the same for the application with `linphone-qt-only` 5. In order to get packages, you can use `cmake .. -DENABLE_APP_PACKAGING=YES`. The files will be in `OUTPUT/packages` folder. @@ -155,17 +150,7 @@ Before you install packages with Brew, you may have to change directories permis pip install pystache pip install graphviz -6. Build as usual (General Steps) : - - `cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo` - - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` - -7. The project folder will be in the build directory and binaries should be in the OUTPUT folder. - -8. When updating the project, the next build steps are a bit different: - - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` - - `cmake --install .` -OR - - `cmake --build . --target install --parallel 10 --config RelWithDebInfo` +6. Build as usual (General Steps). ## Specific instructions for the Windows platform @@ -201,34 +186,39 @@ The default build is very long. It is prefered to use the Ninja generator `-G "N 5. The project folder will be in the build directory and binaries should be in the OUTPUT folder. -6. When updating the project, the next build steps are a bit different: - - `cmake --build . --target ALL_BUILD --parallel 10 --config RelWithDebInfo` - - `cmake --install .` -OR - - `cmake --build . --target install --parallel 10 --config RelWithDebInfo` -## Specific instructions for the Mac Os X platform +## Installing dependencies -1. Build as usual (General Steps) : - - `cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=10 -DCMAKE_BUILD_TYPE=RelWithDebInfo` - - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` +There are [docker files](docker-files) configurations where dependencies can be retrieved. -2. The project folder will be in the build directory and binaries should be in the OUTPUT folder. +Also, more configurations are available in the docker-files folder of linphone-sdk submodule. -3. When updating the project, the next build steps are a bit different: - - `cmake --build . --target all --parallel 10 --config RelWithDebInfo` - - `cmake --install .` -OR - - `cmake --build . --target install --parallel 10 --config RelWithDebInfo` +## Options -## Installing Linux dependencies +| Options | Description | Default value | +| :--- | :---: | ---: | +| ENABLE_APP_PACKAGING | Enable packaging. Package will be deployed in `OUTPUT/packages` | NO | +| ENABLE_APP_LICENSE | Enable the license in packages. | YES | +| ENABLE_BUILD_APP_PLUGINS | Enable the build of plugins | YES | +| ENABLE_BUILD_VERBOSE | Enable the build generation to be more verbose | NO | +| ENABLE_BUILD_EXAMPLES | Enable the build of examples | NO | +| ENABLE_DAEMON | Enable the linphone daemon interface. | NO | +| ENABLE_STRICT | Build with strict compilator flags e.g. -Wall -Werror | NO | +| ENABLE_TESTS | Build with testing binaries of SDK | NO | +| ENABLE_TESTS_COMPONENTS | Build libbctoolbox-tester | NO | +| ENABLE_TOOLS | Enable tools of SDK | NO | +| ENABLE_UNIT_TESTS | Enable unit test of SDK. | NO | +| ENABLE_UPDATE_CHECK | Enable update check. | YES | -Dependencies from 4.1 version of Desktop (refer it only if you have issues): - -apt-get install libqt53dcore5:amd64 libqt53dextras5:amd64 libqt53dinput5:amd64 libqt53dlogic5:amd64 libqt53dquick5:amd64 libqt53dquickextras5:amd64 libqt53dquickinput5:amd64 libqt53dquickrender5:amd64 libqt53drender5:amd64 libqt5concurrent5:amd64 libqt5core5a:amd64 libqt5dbus5:amd64 libqt5designer5:amd64 libqt5designercomponents5:amd64 libqt5gui5:amd64 libqt5help5:amd64 libqt5multimedia5:amd64 libqt5multimedia5-plugins:amd64 libqt5multimediawidgets5:amd64 libqt5network5:amd64 libqt5opengl5:amd64 libqt5opengl5-dev:amd64 libqt5positioning5:amd64 libqt5printsupport5:amd64 libqt5qml5:amd64 libqt5quick5:amd64 libqt5quickcontrols2-5:amd64 libqt5quickparticles5:amd64 libqt5quicktemplates2-5:amd64 libqt5quicktest5:amd64 libqt5quickwidgets5:amd64 libqt5script5:amd64 libqt5scripttools5:amd64 libqt5sensors5:amd64 libqt5serialport5:amd64 libqt5sql5:amd64 libqt5sql5-sqlite:amd64 libqt5svg5:amd64 libqt5svg5-dev:amd64 libqt5test5:amd64 libqt5webchannel5:amd64 libqt5webengine-data libqt5webenginecore5:amd64 libqt5webenginewidgets5:amd64 libqt5webkit5:amd64 libqt5widgets5:amd64 libqt5x11extras5:amd64 libqt5xml5:amd64 libqt5xmlpatterns5:amd64 qt5-default:amd64 qt5-doc qt5-gtk-platformtheme:amd64 qt5-qmake:amd64 qt5-qmltooling-plugins:amd64 - + ## Contributing diff --git a/linphone-app/src/components/core/CoreHandlers.cpp b/linphone-app/src/components/core/CoreHandlers.cpp index bcc8a57ee..5efb6a8fd 100644 --- a/linphone-app/src/components/core/CoreHandlers.cpp +++ b/linphone-app/src/components/core/CoreHandlers.cpp @@ -191,7 +191,7 @@ void CoreHandlers::onMessageReceived ( const shared_ptr &chatRoom, const shared_ptr &message ) { - if( message->isOutgoing() ) + if( !message || message->isOutgoing() ) return; const string contentType = message->getContentType(); diff --git a/linphone-app/src/components/ldap/LdapListModel.cpp b/linphone-app/src/components/ldap/LdapListModel.cpp index 144dc6cc2..9c3cc9678 100644 --- a/linphone-app/src/components/ldap/LdapListModel.cpp +++ b/linphone-app/src/components/ldap/LdapListModel.cpp @@ -95,15 +95,9 @@ bool LdapListModel::removeRows (int row, int count, const QModelIndex &parent) { void LdapListModel::initLdap () { CoreManager *coreManager = CoreManager::getInstance(); - auto lConfig = coreManager->getCore()->getConfig(); - auto bcSections = lConfig->getSectionsNamesList(); - // Loop on all sections and load configuration. If this is not a LDAP configuration, the model is discarded. - for(auto itSections = bcSections.begin(); itSections != bcSections.end(); ++itSections) { - LdapModel * ldap = new LdapModel(); - if(ldap->load(*itSections)){ - mServers.append(ldap); - }else - delete ldap; + auto ldapList = coreManager->getCore()->getLdapList(); + for(auto ldap : ldapList){ + mServers.append(new LdapModel(ldap)); } } @@ -122,7 +116,8 @@ void LdapListModel::enable(int id, bool status){ void LdapListModel::add(){ int row = mServers.count(); beginInsertRows(QModelIndex(), row, row); - auto ldap= new LdapModel(row); + auto ldap= new LdapModel(nullptr); + connect(ldap, &LdapModel::indexChanged, this, &LdapListModel::indexChanged); ldap->init(); mServers << ldap; endInsertRows(); diff --git a/linphone-app/src/components/ldap/LdapListModel.hpp b/linphone-app/src/components/ldap/LdapListModel.hpp index 1ecb2b114..b67ac56d9 100644 --- a/linphone-app/src/components/ldap/LdapListModel.hpp +++ b/linphone-app/src/components/ldap/LdapListModel.hpp @@ -49,6 +49,9 @@ public: Q_INVOKABLE void add(); // Remove a Server Q_INVOKABLE void remove (LdapModel *importer); + +signals: + void indexChanged(); private: bool removeRow (int row, const QModelIndex &parent = QModelIndex()); diff --git a/linphone-app/src/components/ldap/LdapModel.cpp b/linphone-app/src/components/ldap/LdapModel.cpp index f7794c83a..1d9e52e33 100644 --- a/linphone-app/src/components/ldap/LdapModel.cpp +++ b/linphone-app/src/components/ldap/LdapModel.cpp @@ -33,16 +33,17 @@ using namespace std; -LdapModel::LdapModel (const int& id,QObject *parent ) : QObject(parent), mId(id){ - mIsValid = false; - mMaxResults = 50; - mTimeout = 5; - mDebug = false; - mVerifyServerCertificates = -1; - mUseTls = true; - mUseSal = false; - mServer = "ldap://ldap.example.org"; - mConfig["enable"] = "0"; +LdapModel::LdapModel (std::shared_ptr ldap, QObject *parent ) : QObject(parent){ + mLdap = ldap; + if(mLdap) + mLdapParams = ldap->getParams()->clone(); + else{ + mLdapParams = CoreManager::getInstance()->getCore()->createLdapParams(); + mLdapParams->setMaxResults(50); // Desktop default + mLdapParams->setEnabled(false); + } + + unset(); } void LdapModel::init(){ @@ -70,98 +71,71 @@ bool LdapModel::isValid(){ 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()); - lConfig->sync(); + if(!mLdap) { + mLdap = CoreManager::getInstance()->getCore()->createLdapWithParams(mLdapParams); + emit indexChanged(); + }else{ + int oldIndex = getIndex(); + mLdap->setParams(mLdapParams); + if( oldIndex != getIndex()) + emit indexChanged(); + } } } 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); - lConfig->sync(); - } + if(mLdap) + mLdap->removeFromConfigFile(); } - -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; + //return mConfig; + return QVariantMap(); } void LdapModel::setConfig(const QVariantMap& config){ - mConfig = 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["timeout"] = mTimeout; - mConfig["password"] = mPassword; - mConfig["bind_dn"] = mBindDn; - mConfig["base_object"] = mBaseObject; - mConfig["filter"] = mFilter; - mConfig["name_attribute"] = mNameAttributes; - mConfig["sip_attribute"] = mSipAttributes; - mConfig["sip_domain"] = mSipDomain; - mConfig["debug"] = (mDebug?"1":"0"); - mConfig["verify_server_certificates"] = mVerifyServerCertificates; + mLdapParams->setServer(mServer.toStdString()); + mLdapParams->setCustomValue("display_name", mDisplayName.toStdString()); + mLdapParams->enableSal(mUseSal); + mLdapParams->enableTls(mUseTls); + mLdapParams->setMaxResults(mMaxResults); + mLdapParams->setTimeout(mTimeout); + mLdapParams->setPassword(mPassword.toStdString()); + mLdapParams->setBindDn(mBindDn.toStdString()); + mLdapParams->setBaseObject(mBaseObject.toStdString()); + mLdapParams->setFilter(mFilter.toStdString()); + mLdapParams->setNameAttribute(mNameAttributes.toStdString()); + mLdapParams->setSipAttribute(mSipAttributes.toStdString()); + mLdapParams->setSipDomain(mSipDomain.toStdString()); + mLdapParams->setDebugLevel( (linphone::LdapDebugLevel) mDebug); + mLdapParams->setServerCertificatesVerificationMode((linphone::LdapCertVerificationMode)mVerifyServerCertificates); + static int gCount = 0; + mLdapParams->setAuthMethod((++gCount % 2) == 0 ? linphone::LdapAuthMethod::Anonymous : linphone::LdapAuthMethod::Simple); } 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(); - mTimeout = mConfig["timeout"].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(); - mSipDomain = mConfig["sip_domain"].toString(); - mDebug = mConfig["debug"].toString() == "1"; - mVerifyServerCertificates = mConfig["verify_server_certificates"].toInt(); - + mServer = QString::fromStdString(mLdapParams->getServer()); + std::string t = mLdapParams->getCustomValue("display_name"); + mDisplayName = QString::fromStdString(t); + mUseTls = mLdapParams->tlsEnabled(); + mUseSal = mLdapParams->salEnabled(); + mMaxResults = mLdapParams->getMaxResults(); + mTimeout = mLdapParams->getTimeout(); + mPassword = QString::fromStdString(mLdapParams->getPassword()); + mBindDn = QString::fromStdString(mLdapParams->getBindDn()); + mBaseObject = QString::fromStdString(mLdapParams->getBaseObject()); + mFilter = QString::fromStdString(mLdapParams->getFilter()); + mNameAttributes = QString::fromStdString(mLdapParams->getNameAttribute()); + mSipAttributes = QString::fromStdString(mLdapParams->getSipAttribute()); + mSipDomain = QString::fromStdString(mLdapParams->getSipDomain()); + mDebug = (int)mLdapParams->getDebugLevel(); + mVerifyServerCertificates = (int)mLdapParams->getServerCertificatesVerificationMode(); + int c = (int) mLdapParams->getAuthMethod(); + qWarning() << c; testServerField(); testMaxResultsField(); testTimeoutField(); @@ -175,14 +149,14 @@ void LdapModel::unset(){ isValid(); } bool LdapModel::isEnabled(){ - return mConfig["enable"].toString() == "1"; + return mLdapParams->getEnabled(); } void LdapModel::setEnabled(const bool& data){ if(isValid()){ - mConfig["enable"] = (data?"1":"0"); + mLdapParams->setEnabled(data); save(); }else - mConfig["enable"] = "0"; + mLdapParams->setEnabled(false); emit enabledChanged(); } //------------------------------------------------------------------------------------ @@ -214,6 +188,11 @@ void LdapModel::testServerField(){ } } +void LdapModel::setDisplayName(const QString& displayName){ + mDisplayName = displayName; + emit displayNameChanged(); +} + void LdapModel::setMaxResults(const int& data){ mMaxResults = data; testMaxResultsField(); @@ -351,3 +330,10 @@ void LdapModel::testSipDomainField(){ isValid(); } } + +int LdapModel::getIndex() const{ + if(mLdap) + return mLdap->getIndex(); + else + return -2; +} diff --git a/linphone-app/src/components/ldap/LdapModel.hpp b/linphone-app/src/components/ldap/LdapModel.hpp index 3ea2edc73..41425f0aa 100644 --- a/linphone-app/src/components/ldap/LdapModel.hpp +++ b/linphone-app/src/components/ldap/LdapModel.hpp @@ -24,6 +24,7 @@ #include #include +#include // ============================================================================= @@ -37,7 +38,7 @@ class LdapModel : public QObject { 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(QString displayName MEMBER mDisplayName WRITE setDisplayName NOTIFY displayNameChanged) Q_PROPERTY(bool useTls MEMBER mUseTls NOTIFY useTlsChanged) Q_PROPERTY(bool useSal MEMBER mUseSal NOTIFY useSalChanged) @@ -76,11 +77,11 @@ class LdapModel : public QObject { Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) public: - LdapModel (const int& id = 0,QObject *parent = nullptr); + LdapModel (std::shared_ptr ldap, QObject *parent = nullptr); - QVariantMap mConfig; + //QVariantMap mConfig; bool mIsValid; - int mId; // "ldap_mId" from section name + //int mId; // "ldap_mId" from section name QString mServer; QString mServerFieldError; @@ -88,6 +89,7 @@ public: void testServerField(); QString mDisplayName; + void setDisplayName(const QString& displayName); bool mUseSal; bool mUseTls; @@ -136,8 +138,10 @@ public: QString mSipDomainFieldError; void setSipDomain(const QString& data); void testSipDomainField(); + + int getIndex() const; - bool mDebug; + int mDebug; int mVerifyServerCertificates; // Test if the configuration is valid @@ -145,7 +149,6 @@ public: void init();// init configuration by default value Q_INVOKABLE void save(); // Save configuration to linphonerc void unsave(); // Remove configuration from linphonerc - bool load(const std::string& sectionName);// Load a configuration : ldap_x where x is a unique number void set(); // Fix Configuration from variables Q_INVOKABLE void unset(); // Set variables from Configuration @@ -174,6 +177,7 @@ signals: void sipDomainChanged(); void debugChanged(); void verifyServerCertificatesChanged(); + void indexChanged(); void serverFieldErrorChanged(); @@ -188,6 +192,10 @@ signals: void sipDomainFieldErrorChanged(); void enabledChanged(); + +private: + std::shared_ptr mLdap; + std::shared_ptr mLdapParams; }; Q_DECLARE_METATYPE(LdapModel*); #endif // LDAP_MODEL_H_ diff --git a/linphone-app/src/components/ldap/LdapProxyModel.cpp b/linphone-app/src/components/ldap/LdapProxyModel.cpp index be8341689..f66752c9c 100644 --- a/linphone-app/src/components/ldap/LdapProxyModel.cpp +++ b/linphone-app/src/components/ldap/LdapProxyModel.cpp @@ -27,8 +27,10 @@ // ----------------------------------------------------------------------------- LdapProxyModel::LdapProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { - setSourceModel(CoreManager::getInstance()->getLdapListModel()); - sort(0); + auto list = CoreManager::getInstance()->getLdapListModel(); + setSourceModel(list); + connect(list, &LdapListModel::indexChanged, this, &LdapProxyModel::invalidate); + sort(0); } // ----------------------------------------------------------------------------- @@ -45,5 +47,5 @@ bool LdapProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right const LdapModel* ldapA = sourceModel()->data(left).value(); const LdapModel* ldapB = sourceModel()->data(right).value(); - return ldapA->mId < ldapB->mId; + return ldapA->getIndex() < ldapB->getIndex(); } diff --git a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml index 345ec0754..56887e27c 100644 --- a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml +++ b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml @@ -63,7 +63,7 @@ Item { id:retryAction anchors.fill: parent visible: iconId.isError || $chatEntry.state == LinphoneEnums.ChatMessageStateIdle - onClicked: proxyModel.resendMessage(index) + onClicked: $chatEntry.resendMessage() } TooltipArea { diff --git a/linphone-sdk b/linphone-sdk index 0a4f40d12..e9ce4178e 160000 --- a/linphone-sdk +++ b/linphone-sdk @@ -1 +1 @@ -Subproject commit 0a4f40d12d3573d0e6b981f637209b23fb11d0a9 +Subproject commit e9ce4178eb91013d23f9aef6c080a8c9b2c978c9