From c908f0d42c01dbd1962531960c2c0b5477888ecf Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Tue, 17 Dec 2024 15:13:45 +0100 Subject: [PATCH] Fix blinkink text fields. Remove storing core from GUI on fields. Core should never be stored in GUI because they are managed by CPP and not QML. Fix crashes on account settings. Add missing exception verbosing. --- Linphone/core/App.cpp | 2 +- Linphone/core/account/AccountCore.cpp | 9 +- Linphone/core/camera/PreviewManager.cpp | 2 + Linphone/model/account/AccountModel.cpp | 15 ++-- Linphone/model/call/CallModel.cpp | 2 +- Linphone/model/conference/ConferenceModel.cpp | 12 ++- .../Control/Button/Settings/ComboSetting.qml | 14 +++- .../Control/Button/Settings/SwitchSetting.qml | 6 +- .../view/Control/Input/DecoratedTextField.qml | 6 +- Linphone/view/Control/Input/TextField.qml | 83 ++++++++++--------- .../Settings/AccountSettingsGeneralLayout.qml | 4 +- .../AccountSettingsParametersLayout.qml | 26 +++--- .../Settings/AdvancedSettingsLayout.qml | 4 +- .../Layout/Settings/CarddavSettingsLayout.qml | 12 +-- .../Layout/Settings/LdapSettingsLayout.qml | 28 +++---- 15 files changed, 129 insertions(+), 96 deletions(-) diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index d96184a44..adaf8839b 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -760,7 +760,7 @@ bool App::notify(QObject *receiver, QEvent *event) { try { done = QApplication::notify(receiver, event); } catch (const std::exception &ex) { - lCritical() << log().arg("Exception has been catch in notify"); + lCritical() << log().arg("Exception has been catch in notify: %1").arg(ex.what()); } catch (...) { lCritical() << log().arg("Generic exeption has been catch in notify"); } diff --git a/Linphone/core/account/AccountCore.cpp b/Linphone/core/account/AccountCore.cpp index 8544cb5ce..6c9b7277f 100644 --- a/Linphone/core/account/AccountCore.cpp +++ b/Linphone/core/account/AccountCore.cpp @@ -106,7 +106,7 @@ AccountCore::AccountCore(const std::shared_ptr &account) : QO AccountCore::~AccountCore() { mustBeInMainThread("~" + getClassName()); - emit mAccountModel->removeListener(); + if (mAccountModel) emit mAccountModel->removeListener(); } AccountCore::AccountCore(const AccountCore &accountCore) { @@ -752,7 +752,10 @@ void AccountCore::save() { mustBeInLinphoneThread(getClassName() + Q_FUNC_INFO); thisCopy->writeIntoModel(mAccountModel); thisCopy->deleteLater(); - mAccountModelConnection->invokeToCore([this]() { setIsSaved(true); }); + mAccountModelConnection->invokeToCore([this, thisCopy]() { + setIsSaved(true); + undo(); // Reset new values because some values can be invalid and not changed. + }); }); } } @@ -769,4 +772,4 @@ void AccountCore::undo() { }); }); } -} \ No newline at end of file +} diff --git a/Linphone/core/camera/PreviewManager.cpp b/Linphone/core/camera/PreviewManager.cpp index e52ac4810..70dcf3a67 100644 --- a/Linphone/core/camera/PreviewManager.cpp +++ b/Linphone/core/camera/PreviewManager.cpp @@ -67,6 +67,7 @@ QQuickFramebufferObject::Renderer *PreviewManager::subscribe(const CameraGui *ca } else { lDebug() << log().arg("Resubscribing") << itCandidate->first->getQmlName(); } + mCounterMutex.unlock(); App::postModelBlock([&renderer, isFirst = (itCandidate == mCandidates.begin()), name = itCandidate->first->getQmlName()]() { renderer = @@ -80,6 +81,7 @@ QQuickFramebufferObject::Renderer *PreviewManager::subscribe(const CameraGui *ca CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer); } }); + mCounterMutex.lock(); itCandidate->second = renderer; mCounterMutex.unlock(); return renderer; diff --git a/Linphone/model/account/AccountModel.cpp b/Linphone/model/account/AccountModel.cpp index 3fea2f8f0..15b57e50f 100644 --- a/Linphone/model/account/AccountModel.cpp +++ b/Linphone/model/account/AccountModel.cpp @@ -193,14 +193,18 @@ QString AccountModel::getMwiServerAddress() const { void AccountModel::setMwiServerAddress(QString value) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); - auto params = mMonitor->getParams()->clone(); auto address = value.isEmpty() ? nullptr : CoreModel::getInstance()->getCore()->interpretUrl(Utils::appStringToCoreString(value), false); + if (value.isEmpty() || address) { - params->setMwiServerAddress(address); - mMonitor->setParams(params); - emit mwiServerAddressChanged(value); + auto params = mMonitor->getParams(); + auto oldAddress = params->getMwiServerAddress(); + if (address != oldAddress && (!address || !address->weakEqual(oldAddress))) { + auto newParams = params->clone(); + newParams->setMwiServerAddress(address); + if (!mMonitor->setParams(newParams)) emit mwiServerAddressChanged(value); + } } else qWarning() << "Unable to set MWI address, failed creating address from" << value; } @@ -395,7 +399,8 @@ void AccountModel::setVoicemailAddress(QString value) { } QString AccountModel::getVoicemailAddress() const { - return Utils::coreStringToAppString(mMonitor->getParams()->getVoicemailAddress()->asString()); + auto addr = mMonitor->getParams()->getVoicemailAddress(); + return addr ? Utils::coreStringToAppString(addr->asString()) : ""; } // UserData (see hpp for explanations) diff --git a/Linphone/model/call/CallModel.cpp b/Linphone/model/call/CallModel.cpp index 87c78fbfa..34f3fb920 100644 --- a/Linphone/model/call/CallModel.cpp +++ b/Linphone/model/call/CallModel.cpp @@ -30,7 +30,7 @@ DEFINE_ABSTRACT_OBJECT(CallModel) CallModel::CallModel(const std::shared_ptr &call, QObject *parent) : ::Listener(call, parent) { - lDebug() << "[CallModel] new" << this; + lDebug() << "[CallModel] new" << this << " / SDKModel=" << call.get(); mustBeInLinphoneThread(getClassName()); mDurationTimer.setInterval(1000); mDurationTimer.setSingleShot(false); diff --git a/Linphone/model/conference/ConferenceModel.cpp b/Linphone/model/conference/ConferenceModel.cpp index dffc4ec64..53767d299 100644 --- a/Linphone/model/conference/ConferenceModel.cpp +++ b/Linphone/model/conference/ConferenceModel.cpp @@ -38,7 +38,7 @@ std::shared_ptr ConferenceModel::create(const std::shared_ptr &conference, QObject *parent) : ::Listener(conference, parent) { mustBeInLinphoneThread(getClassName()); - lDebug() << "[ConferenceModel] new" << this << conference.get(); + lDebug() << "[ConferenceModel] new " << this << ", SDKModel=" << conference.get(); connect(this, &ConferenceModel::isScreenSharingEnabledChanged, this, &ConferenceModel::onIsScreenSharingEnabledChanged); } @@ -149,8 +149,13 @@ void ConferenceModel::toggleScreenSharing() { ? linphone::MediaDirection::SendRecv : linphone::MediaDirection::SendOnly); } - if (params->isValid()) mMonitor->getCall()->update(params); - else lCritical() << log().arg("Cannot toggle screen sharing because parameters are invalid"); + if (params->isValid()) { + lInfo() << log() + .arg("Toggling screen sharing %1, direction=%2") + .arg(enable) + .arg((int)params->getVideoDirection()); + mMonitor->getCall()->update(params); + } else lCritical() << log().arg("Cannot toggle screen sharing because parameters are invalid"); } } @@ -276,6 +281,7 @@ void ConferenceModel::onAudioDeviceChanged(const std::shared_ptrgetCall(); std::shared_ptr params = CoreModel::getInstance()->getCore()->createCallParams(call); + lDebug() << log().arg("Old Layout=%1").arg((int)params->getConferenceVideoLayout()); if (params->getConferenceVideoLayout() == linphone::Conference::Layout::Grid && params->videoEnabled()) { params->setConferenceVideoLayout(linphone::Conference::Layout::ActiveSpeaker); } diff --git a/Linphone/view/Control/Button/Settings/ComboSetting.qml b/Linphone/view/Control/Button/Settings/ComboSetting.qml index 093196224..a29a1dd45 100644 --- a/Linphone/view/Control/Button/Settings/ComboSetting.qml +++ b/Linphone/view/Control/Button/Settings/ComboSetting.qml @@ -10,17 +10,25 @@ ComboBox { property string propertyName property var propertyOwner + property var propertyOwnerGui property alias entries: mainItem.model oneLine: true currentIndex: Utils.findIndex(model, function (entry) { - return Utils.equalObject(entry,propertyOwner[propertyName]) + if(propertyOwnerGui) + return Utils.equalObject(entry,propertyOwnerGui.core[propertyName]) + else + return Utils.equalObject(entry,propertyOwner[propertyName]) }) onCurrentValueChanged: { - binding.when = !Utils.equalObject(currentValue,propertyOwner[propertyName]) + if(propertyOwnerGui) { + binding.when = !Utils.equalObject(currentValue,propertyOwnerGui.core[propertyName]) + }else{ + binding.when = !Utils.equalObject(currentValue,propertyOwner[propertyName]) + } } Binding { id: binding - target: propertyOwner + target: propertyOwnerGui ? propertyOwnerGui : propertyOwner property: propertyName value: mainItem.currentValue when: false diff --git a/Linphone/view/Control/Button/Settings/SwitchSetting.qml b/Linphone/view/Control/Button/Settings/SwitchSetting.qml index e60a1c427..80d586623 100644 --- a/Linphone/view/Control/Button/Settings/SwitchSetting.qml +++ b/Linphone/view/Control/Button/Settings/SwitchSetting.qml @@ -9,6 +9,7 @@ RowLayout { property string subTitleText property string propertyName property var propertyOwner + property var propertyOwnerGui property bool enabled: true spacing : 20 * DefaultStyle.dp Layout.minimumHeight: 32 * DefaultStyle.dp @@ -38,14 +39,15 @@ RowLayout { Switch { id: switchButton Layout.alignment: Qt.AlignRight | Qt.AlignVCenter - checked: propertyOwner ? propertyOwner[mainItem.propertyName] : false + checked: propertyOwnerGui ? propertyOwnerGui.core[mainItem.propertyName] + : propertyOwner ? propertyOwner[mainItem.propertyName] : false enabled: mainItem.enabled onCheckedChanged: mainItem.checkedChanged(checked) onToggled: binding.when = true } Binding { id: binding - target: propertyOwner ? propertyOwner : null + target: propertyOwnerGui ? propertyOwnerGui : propertyOwner ? propertyOwner : null property: mainItem.propertyName value: switchButton.checked when: false diff --git a/Linphone/view/Control/Input/DecoratedTextField.qml b/Linphone/view/Control/Input/DecoratedTextField.qml index 9f3a27e12..2565de12e 100644 --- a/Linphone/view/Control/Input/DecoratedTextField.qml +++ b/Linphone/view/Control/Input/DecoratedTextField.qml @@ -12,6 +12,7 @@ FormItemLayout { enableErrorText: true property string propertyName: "value" property var propertyOwner: new Array + property var propertyOwnerGui property var title property var placeHolder property bool useTitleAsPlaceHolder: true @@ -19,7 +20,7 @@ FormItemLayout { property bool toValidate: false function value() { - return propertyOwner[propertyName] + return propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName] } property alias hidden: textField.hidden @@ -33,10 +34,11 @@ FormItemLayout { id: textField Layout.preferredWidth: 360 * DefaultStyle.dp placeholderText: useTitleAsPlaceHolder ? mainItem.title : mainItem.placeHolder - initialText: mainItem.propertyOwner[mainItem.propertyName] || '' + initialText: (mainItem.propertyOwnerGui ? mainItem.propertyOwnerGui.core[mainItem.propertyName] : mainItem.propertyOwner[mainItem.propertyName]) || '' customWidth: mainItem.parent.width propertyName: mainItem.propertyName propertyOwner: mainItem.propertyOwner + propertyOwnerGui: mainItem.propertyOwnerGui canBeEmpty: mainItem.canBeEmpty isValid: mainItem.isValid toValidate: mainItem.toValidate diff --git a/Linphone/view/Control/Input/TextField.qml b/Linphone/view/Control/Input/TextField.qml index 05725ca9b..8704fa412 100644 --- a/Linphone/view/Control/Input/TextField.qml +++ b/Linphone/view/Control/Input/TextField.qml @@ -22,6 +22,7 @@ Control.TextField { selectByMouse: true activeFocusOnTab: true KeyNavigation.right: eyeButton + text: initialText property bool controlIsDown: false property bool hidden: false @@ -37,26 +38,64 @@ Control.TextField { // fill propertyName and propertyOwner to check text validity property string propertyName property var propertyOwner + property var propertyOwnerGui property var initialReading: true property var isValid: function(text) { return true } property bool toValidate: false property int idleTimeOut: 200 - property bool empty: mainItem.propertyOwner!= undefined && mainItem.propertyOwner[mainItem.propertyName]?.length == 0 + property bool empty: propertyOwnerGui ? mainItem.propertyOwnerGui.core != undefined && mainItem.propertyOwnerGui.core[mainItem.propertyName]?.length == 0 + : mainItem.propertyOwner != undefined && mainItem.propertyOwner[mainItem.propertyName]?.length == 0 property bool canBeEmpty: true signal validationChecked(bool valid) - Component.onCompleted: { - text = initialText - } - function resetText() { text = initialText } signal enterPressed() + + onAccepted: {// No need to process changing focus because of TextEdited callback. + idleTimer.stop() + updateText() + } + onTextEdited: { + if(mainItem.toValidate) { + idleTimer.restart() + } + } + function updateText() { + mainItem.empty = text.length == 0 + if (initialReading) { + initialReading = false + } + if (mainItem.empty && !mainItem.canBeEmpty) { + mainItem.validationChecked(false) + return + } + if (mainItem.propertyName && isValid(text)) { + if(mainItem.propertyOwnerGui){ + if (mainItem.propertyOwnerGui.core[mainItem.propertyName] != text) + mainItem.propertyOwnerGui.core[mainItem.propertyName] = text + }else{ + if (mainItem.propertyOwner[mainItem.propertyName] != text) + mainItem.propertyOwner[mainItem.propertyName] = text + } + mainItem.validationChecked(true) + } else mainItem.validationChecked(false) + } + // Validation textfield functions + Timer { + id: idleTimer + running: false + interval: mainItem.idleTimeOut + repeat: false + onTriggered: { + mainItem.accepted() + } + } background: Rectangle { id: inputBackground @@ -138,39 +177,5 @@ Control.TextField { anchors.right: parent.right anchors.rightMargin: rightMargin } - - // Validation textfield functions - Timer { - id: idleTimer - running: false - interval: mainItem.idleTimeOut - repeat: false - onTriggered: mainItem.editingFinished() - } - onEditingFinished: { - updateText() - } - onTextChanged: { - if(mainItem.toValidate) { - // Restarting - idleTimer.restart() - } - // updateText() - } - function updateText() { - mainItem.empty = text.length == 0 - if (initialReading) { - initialReading = false - } - if (mainItem.empty && !mainItem.canBeEmpty) { - mainItem.validationChecked(false) - return - } - if (isValid(text) && mainItem.propertyOwner && mainItem.propertyName) { - if (mainItem.propertyOwner[mainItem.propertyName] != text) - mainItem.propertyOwner[mainItem.propertyName] = text - mainItem.validationChecked(true) - } else mainItem.validationChecked(false) - } } diff --git a/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml b/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml index a46aaa995..4c0f3e567 100644 --- a/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AccountSettingsGeneralLayout.qml @@ -151,7 +151,7 @@ AbstractSettingsLayout { Layout.topMargin: -15 * DefaultStyle.dp entries: account.core.dialPlans propertyName: "dialPlan" - propertyOwner: account.core + propertyOwnerGui: account textRole: 'text' flagRole: 'flag' } @@ -159,7 +159,7 @@ AbstractSettingsLayout { titleText: account?.core.humaneReadableRegistrationState subTitleText: account?.core.humaneReadableRegistrationStateExplained propertyName: "registerEnabled" - propertyOwner: account?.core + propertyOwnerGui: account } RowLayout { id:mainItem diff --git a/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml b/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml index 353d2885a..a4116b8f3 100644 --- a/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AccountSettingsParametersLayout.qml @@ -47,7 +47,7 @@ AbstractSettingsLayout { spacing: 20 * DefaultStyle.dp DecoratedTextField { propertyName: "mwiServerAddress" - propertyOwner: account.core + propertyOwnerGui: account title: qsTr("URI du serveur de messagerie vocale") Layout.fillWidth: true isValid: function(text) { return text.length == 0 || !text.endsWith(".") } // work around sdk crash when adress ends with . @@ -55,7 +55,7 @@ AbstractSettingsLayout { } DecoratedTextField { propertyName: "voicemailAddress" - propertyOwner: account.core + propertyOwnerGui: account title: qsTr("URI de messagerie vocale") Layout.fillWidth: true } @@ -80,44 +80,44 @@ AbstractSettingsLayout { Layout.topMargin: -15 * DefaultStyle.dp entries: account.core.transports propertyName: "transport" - propertyOwner: account.core + propertyOwnerGui: account } DecoratedTextField { Layout.fillWidth: true title: qsTr("URL du serveur mandataire") propertyName: "serverAddress" - propertyOwner: account.core + propertyOwnerGui: account } SwitchSetting { titleText: qsTr("Serveur mandataire sortant") propertyName: "outboundProxyEnabled" - propertyOwner: account.core + propertyOwnerGui: account } DecoratedTextField { Layout.fillWidth: true propertyName: "stunServer" - propertyOwner: account.core + propertyOwnerGui: account title: qsTr("Adresse du serveur STUN") } SwitchSetting { titleText: qsTr("Activer ICE") propertyName: "iceEnabled" - propertyOwner: account.core + propertyOwnerGui: account } SwitchSetting { titleText: qsTr("AVPF") propertyName: "avpfEnabled" - propertyOwner: account.core + propertyOwnerGui: account } SwitchSetting { titleText: qsTr("Mode bundle") propertyName: "bundleModeEnabled" - propertyOwner: account.core + propertyOwnerGui: account } DecoratedTextField { Layout.fillWidth: true propertyName: "expire" - propertyOwner: account.core + propertyOwnerGui: account title: qsTr("Expiration (en seconde)") canBeEmpty: false isValid: function(text) { return !isNaN(Number(text)) } @@ -127,20 +127,20 @@ AbstractSettingsLayout { Layout.fillWidth: true title: qsTr("URI de l’usine à conversations") propertyName: "conferenceFactoryAddress" - propertyOwner: account.core + propertyOwnerGui: account } DecoratedTextField { Layout.fillWidth: true title: qsTr("URI de l’usine à réunions") propertyName: "audioVideoConferenceFactoryAddress" - propertyOwner: account.core + propertyOwnerGui: account visible: !SettingsCpp.disableMeetingsFeature } DecoratedTextField { Layout.fillWidth: true title: qsTr("URL du serveur d’échange de clés de chiffrement") propertyName: "limeServerUrl" - propertyOwner: account.core + propertyOwnerGui: account } } } diff --git a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml index 24ebbbd92..434fcdfcd 100644 --- a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml @@ -139,7 +139,7 @@ AbstractSettingsLayout { titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType) subTitleText: modelData.core.clockRate + " Hz" propertyName: "enabled" - propertyOwner: modelData.core + propertyOwnerGui: modelData } } } @@ -162,7 +162,7 @@ AbstractSettingsLayout { titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType) subTitleText: modelData.core.encoderDescription propertyName: "enabled" - propertyOwner: modelData.core + propertyOwnerGui: modelData } } Repeater { diff --git a/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml index 450b867bb..27123ea4b 100644 --- a/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/CarddavSettingsLayout.qml @@ -74,7 +74,7 @@ AbstractSettingsLayout { Layout.leftMargin: 64 * DefaultStyle.dp DecoratedTextField { propertyName: "displayName" - propertyOwner: carddavGui.core + propertyOwnerGui: carddavGui title: qsTr("Nom d’affichage") canBeEmpty: false toValidate: true @@ -82,7 +82,7 @@ AbstractSettingsLayout { } DecoratedTextField { propertyName: "uri" - propertyOwner: carddavGui.core + propertyOwnerGui: carddavGui title: qsTr("URL du serveur") canBeEmpty: false toValidate: true @@ -90,7 +90,7 @@ AbstractSettingsLayout { } DecoratedTextField { propertyName: "username" - propertyOwner: carddavGui.core + propertyOwnerGui: carddavGui title: qsTr("Nom d’utilisateur") toValidate: true Layout.fillWidth: true @@ -98,14 +98,14 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "password" hidden: true - propertyOwner: carddavGui.core + propertyOwnerGui: carddavGui title: qsTr("Mot de passe") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "realm" - propertyOwner: carddavGui.core + propertyOwnerGui: carddavGui title: qsTr("Domaine d’authentification") toValidate: true Layout.fillWidth: true @@ -113,7 +113,7 @@ AbstractSettingsLayout { SwitchSetting { titleText: qsTr("Stocker ici les contacts nouvellement crées") propertyName: "storeNewFriendsInIt" - propertyOwner: carddavGui.core + propertyOwnerGui: carddavGui } } } diff --git a/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml index 939623615..1258d116d 100644 --- a/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/LdapSettingsLayout.qml @@ -70,14 +70,14 @@ AbstractSettingsLayout { DecoratedTextField { id: server propertyName: "serverUrl" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("URL du serveur (ne peut être vide)") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "bindDn" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Bind DN") toValidate: true Layout.fillWidth: true @@ -85,7 +85,7 @@ AbstractSettingsLayout { DecoratedTextField { propertyName: "password" hidden: true - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Mot de passe") toValidate: true Layout.fillWidth: true @@ -93,25 +93,25 @@ AbstractSettingsLayout { SwitchSetting { titleText: qsTr("Utiliser TLS") propertyName: "tls" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui } DecoratedTextField { propertyName: "baseObject" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Base de recherche (ne peut être vide)") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "filter" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Filtre") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "limit" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } title: qsTr("Nombre maximum de résultats") toValidate: true @@ -119,7 +119,7 @@ AbstractSettingsLayout { } DecoratedTextField { propertyName: "delay" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } title: qsTr("Délai entre 2 requêtes (en millisecondes)") toValidate: true @@ -127,7 +127,7 @@ AbstractSettingsLayout { } DecoratedTextField { propertyName: "timeout" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Durée maximun (en secondes)") validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } toValidate: true @@ -135,7 +135,7 @@ AbstractSettingsLayout { } DecoratedTextField { propertyName: "minCharacters" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Nombre minimum de caractères pour la requête") validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } toValidate: true @@ -143,21 +143,21 @@ AbstractSettingsLayout { } DecoratedTextField { propertyName: "nameAttribute" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Attributs de nom") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "sipAttribute" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Attributs SIP") toValidate: true Layout.fillWidth: true } DecoratedTextField { propertyName: "sipDomain" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui title: qsTr("Domaine SIP") toValidate: true Layout.fillWidth: true @@ -165,7 +165,7 @@ AbstractSettingsLayout { SwitchSetting { titleText: qsTr("Débogage") propertyName: "debug" - propertyOwner: ldapGui.core + propertyOwnerGui: ldapGui } } }