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.
This commit is contained in:
Julien Wadel 2024-12-17 15:13:45 +01:00
parent 79b15f4178
commit c908f0d42c
15 changed files with 129 additions and 96 deletions

View file

@ -760,7 +760,7 @@ bool App::notify(QObject *receiver, QEvent *event) {
try { try {
done = QApplication::notify(receiver, event); done = QApplication::notify(receiver, event);
} catch (const std::exception &ex) { } 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 (...) { } catch (...) {
lCritical() << log().arg("Generic exeption has been catch in notify"); lCritical() << log().arg("Generic exeption has been catch in notify");
} }

View file

@ -106,7 +106,7 @@ AccountCore::AccountCore(const std::shared_ptr<linphone::Account> &account) : QO
AccountCore::~AccountCore() { AccountCore::~AccountCore() {
mustBeInMainThread("~" + getClassName()); mustBeInMainThread("~" + getClassName());
emit mAccountModel->removeListener(); if (mAccountModel) emit mAccountModel->removeListener();
} }
AccountCore::AccountCore(const AccountCore &accountCore) { AccountCore::AccountCore(const AccountCore &accountCore) {
@ -752,7 +752,10 @@ void AccountCore::save() {
mustBeInLinphoneThread(getClassName() + Q_FUNC_INFO); mustBeInLinphoneThread(getClassName() + Q_FUNC_INFO);
thisCopy->writeIntoModel(mAccountModel); thisCopy->writeIntoModel(mAccountModel);
thisCopy->deleteLater(); 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() {
}); });
}); });
} }
} }

View file

@ -67,6 +67,7 @@ QQuickFramebufferObject::Renderer *PreviewManager::subscribe(const CameraGui *ca
} else { } else {
lDebug() << log().arg("Resubscribing") << itCandidate->first->getQmlName(); lDebug() << log().arg("Resubscribing") << itCandidate->first->getQmlName();
} }
mCounterMutex.unlock();
App::postModelBlock([&renderer, isFirst = (itCandidate == mCandidates.begin()), App::postModelBlock([&renderer, isFirst = (itCandidate == mCandidates.begin()),
name = itCandidate->first->getQmlName()]() { name = itCandidate->first->getQmlName()]() {
renderer = renderer =
@ -80,6 +81,7 @@ QQuickFramebufferObject::Renderer *PreviewManager::subscribe(const CameraGui *ca
CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer); CoreModel::getInstance()->getCore()->setNativePreviewWindowId(renderer);
} }
}); });
mCounterMutex.lock();
itCandidate->second = renderer; itCandidate->second = renderer;
mCounterMutex.unlock(); mCounterMutex.unlock();
return renderer; return renderer;

View file

@ -193,14 +193,18 @@ QString AccountModel::getMwiServerAddress() const {
void AccountModel::setMwiServerAddress(QString value) { void AccountModel::setMwiServerAddress(QString value) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto params = mMonitor->getParams()->clone();
auto address = value.isEmpty() auto address = value.isEmpty()
? nullptr ? nullptr
: CoreModel::getInstance()->getCore()->interpretUrl(Utils::appStringToCoreString(value), false); : CoreModel::getInstance()->getCore()->interpretUrl(Utils::appStringToCoreString(value), false);
if (value.isEmpty() || address) { if (value.isEmpty() || address) {
params->setMwiServerAddress(address); auto params = mMonitor->getParams();
mMonitor->setParams(params); auto oldAddress = params->getMwiServerAddress();
emit mwiServerAddressChanged(value); 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; } 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 { 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) // UserData (see hpp for explanations)

View file

@ -30,7 +30,7 @@ DEFINE_ABSTRACT_OBJECT(CallModel)
CallModel::CallModel(const std::shared_ptr<linphone::Call> &call, QObject *parent) CallModel::CallModel(const std::shared_ptr<linphone::Call> &call, QObject *parent)
: ::Listener<linphone::Call, linphone::CallListener>(call, parent) { : ::Listener<linphone::Call, linphone::CallListener>(call, parent) {
lDebug() << "[CallModel] new" << this; lDebug() << "[CallModel] new" << this << " / SDKModel=" << call.get();
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
mDurationTimer.setInterval(1000); mDurationTimer.setInterval(1000);
mDurationTimer.setSingleShot(false); mDurationTimer.setSingleShot(false);

View file

@ -38,7 +38,7 @@ std::shared_ptr<ConferenceModel> ConferenceModel::create(const std::shared_ptr<l
ConferenceModel::ConferenceModel(const std::shared_ptr<linphone::Conference> &conference, QObject *parent) ConferenceModel::ConferenceModel(const std::shared_ptr<linphone::Conference> &conference, QObject *parent)
: ::Listener<linphone::Conference, linphone::ConferenceListener>(conference, parent) { : ::Listener<linphone::Conference, linphone::ConferenceListener>(conference, parent) {
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
lDebug() << "[ConferenceModel] new" << this << conference.get(); lDebug() << "[ConferenceModel] new " << this << ", SDKModel=" << conference.get();
connect(this, &ConferenceModel::isScreenSharingEnabledChanged, this, connect(this, &ConferenceModel::isScreenSharingEnabledChanged, this,
&ConferenceModel::onIsScreenSharingEnabledChanged); &ConferenceModel::onIsScreenSharingEnabledChanged);
} }
@ -149,8 +149,13 @@ void ConferenceModel::toggleScreenSharing() {
? linphone::MediaDirection::SendRecv ? linphone::MediaDirection::SendRecv
: linphone::MediaDirection::SendOnly); : linphone::MediaDirection::SendOnly);
} }
if (params->isValid()) mMonitor->getCall()->update(params); if (params->isValid()) {
else lCritical() << log().arg("Cannot toggle screen sharing because parameters are invalid"); 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_ptr<linphone::Confe
void ConferenceModel::onIsScreenSharingEnabledChanged() { void ConferenceModel::onIsScreenSharingEnabledChanged() {
auto call = mMonitor->getCall(); auto call = mMonitor->getCall();
std::shared_ptr<linphone::CallParams> params = CoreModel::getInstance()->getCore()->createCallParams(call); std::shared_ptr<linphone::CallParams> 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()) { if (params->getConferenceVideoLayout() == linphone::Conference::Layout::Grid && params->videoEnabled()) {
params->setConferenceVideoLayout(linphone::Conference::Layout::ActiveSpeaker); params->setConferenceVideoLayout(linphone::Conference::Layout::ActiveSpeaker);
} }

View file

@ -10,17 +10,25 @@ ComboBox {
property string propertyName property string propertyName
property var propertyOwner property var propertyOwner
property var propertyOwnerGui
property alias entries: mainItem.model property alias entries: mainItem.model
oneLine: true oneLine: true
currentIndex: Utils.findIndex(model, function (entry) { 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: { 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 { Binding {
id: binding id: binding
target: propertyOwner target: propertyOwnerGui ? propertyOwnerGui : propertyOwner
property: propertyName property: propertyName
value: mainItem.currentValue value: mainItem.currentValue
when: false when: false

View file

@ -9,6 +9,7 @@ RowLayout {
property string subTitleText property string subTitleText
property string propertyName property string propertyName
property var propertyOwner property var propertyOwner
property var propertyOwnerGui
property bool enabled: true property bool enabled: true
spacing : 20 * DefaultStyle.dp spacing : 20 * DefaultStyle.dp
Layout.minimumHeight: 32 * DefaultStyle.dp Layout.minimumHeight: 32 * DefaultStyle.dp
@ -38,14 +39,15 @@ RowLayout {
Switch { Switch {
id: switchButton id: switchButton
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter 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 enabled: mainItem.enabled
onCheckedChanged: mainItem.checkedChanged(checked) onCheckedChanged: mainItem.checkedChanged(checked)
onToggled: binding.when = true onToggled: binding.when = true
} }
Binding { Binding {
id: binding id: binding
target: propertyOwner ? propertyOwner : null target: propertyOwnerGui ? propertyOwnerGui : propertyOwner ? propertyOwner : null
property: mainItem.propertyName property: mainItem.propertyName
value: switchButton.checked value: switchButton.checked
when: false when: false

View file

@ -12,6 +12,7 @@ FormItemLayout {
enableErrorText: true enableErrorText: true
property string propertyName: "value" property string propertyName: "value"
property var propertyOwner: new Array property var propertyOwner: new Array
property var propertyOwnerGui
property var title property var title
property var placeHolder property var placeHolder
property bool useTitleAsPlaceHolder: true property bool useTitleAsPlaceHolder: true
@ -19,7 +20,7 @@ FormItemLayout {
property bool toValidate: false property bool toValidate: false
function value() { function value() {
return propertyOwner[propertyName] return propertyOwnerGui ? propertyOwnerGui.core[propertyName] : propertyOwner[propertyName]
} }
property alias hidden: textField.hidden property alias hidden: textField.hidden
@ -33,10 +34,11 @@ FormItemLayout {
id: textField id: textField
Layout.preferredWidth: 360 * DefaultStyle.dp Layout.preferredWidth: 360 * DefaultStyle.dp
placeholderText: useTitleAsPlaceHolder ? mainItem.title : mainItem.placeHolder 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 customWidth: mainItem.parent.width
propertyName: mainItem.propertyName propertyName: mainItem.propertyName
propertyOwner: mainItem.propertyOwner propertyOwner: mainItem.propertyOwner
propertyOwnerGui: mainItem.propertyOwnerGui
canBeEmpty: mainItem.canBeEmpty canBeEmpty: mainItem.canBeEmpty
isValid: mainItem.isValid isValid: mainItem.isValid
toValidate: mainItem.toValidate toValidate: mainItem.toValidate

View file

@ -22,6 +22,7 @@ Control.TextField {
selectByMouse: true selectByMouse: true
activeFocusOnTab: true activeFocusOnTab: true
KeyNavigation.right: eyeButton KeyNavigation.right: eyeButton
text: initialText
property bool controlIsDown: false property bool controlIsDown: false
property bool hidden: false property bool hidden: false
@ -37,26 +38,64 @@ Control.TextField {
// fill propertyName and propertyOwner to check text validity // fill propertyName and propertyOwner to check text validity
property string propertyName property string propertyName
property var propertyOwner property var propertyOwner
property var propertyOwnerGui
property var initialReading: true property var initialReading: true
property var isValid: function(text) { property var isValid: function(text) {
return true return true
} }
property bool toValidate: false property bool toValidate: false
property int idleTimeOut: 200 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 property bool canBeEmpty: true
signal validationChecked(bool valid) signal validationChecked(bool valid)
Component.onCompleted: {
text = initialText
}
function resetText() { function resetText() {
text = initialText text = initialText
} }
signal enterPressed() 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 { background: Rectangle {
id: inputBackground id: inputBackground
@ -138,39 +177,5 @@ Control.TextField {
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: rightMargin 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)
}
} }

View file

@ -151,7 +151,7 @@ AbstractSettingsLayout {
Layout.topMargin: -15 * DefaultStyle.dp Layout.topMargin: -15 * DefaultStyle.dp
entries: account.core.dialPlans entries: account.core.dialPlans
propertyName: "dialPlan" propertyName: "dialPlan"
propertyOwner: account.core propertyOwnerGui: account
textRole: 'text' textRole: 'text'
flagRole: 'flag' flagRole: 'flag'
} }
@ -159,7 +159,7 @@ AbstractSettingsLayout {
titleText: account?.core.humaneReadableRegistrationState titleText: account?.core.humaneReadableRegistrationState
subTitleText: account?.core.humaneReadableRegistrationStateExplained subTitleText: account?.core.humaneReadableRegistrationStateExplained
propertyName: "registerEnabled" propertyName: "registerEnabled"
propertyOwner: account?.core propertyOwnerGui: account
} }
RowLayout { RowLayout {
id:mainItem id:mainItem

View file

@ -47,7 +47,7 @@ AbstractSettingsLayout {
spacing: 20 * DefaultStyle.dp spacing: 20 * DefaultStyle.dp
DecoratedTextField { DecoratedTextField {
propertyName: "mwiServerAddress" propertyName: "mwiServerAddress"
propertyOwner: account.core propertyOwnerGui: account
title: qsTr("URI du serveur de messagerie vocale") title: qsTr("URI du serveur de messagerie vocale")
Layout.fillWidth: true Layout.fillWidth: true
isValid: function(text) { return text.length == 0 || !text.endsWith(".") } // work around sdk crash when adress ends with . isValid: function(text) { return text.length == 0 || !text.endsWith(".") } // work around sdk crash when adress ends with .
@ -55,7 +55,7 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
propertyName: "voicemailAddress" propertyName: "voicemailAddress"
propertyOwner: account.core propertyOwnerGui: account
title: qsTr("URI de messagerie vocale") title: qsTr("URI de messagerie vocale")
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -80,44 +80,44 @@ AbstractSettingsLayout {
Layout.topMargin: -15 * DefaultStyle.dp Layout.topMargin: -15 * DefaultStyle.dp
entries: account.core.transports entries: account.core.transports
propertyName: "transport" propertyName: "transport"
propertyOwner: account.core propertyOwnerGui: account
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("URL du serveur mandataire") title: qsTr("URL du serveur mandataire")
propertyName: "serverAddress" propertyName: "serverAddress"
propertyOwner: account.core propertyOwnerGui: account
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Serveur mandataire sortant") titleText: qsTr("Serveur mandataire sortant")
propertyName: "outboundProxyEnabled" propertyName: "outboundProxyEnabled"
propertyOwner: account.core propertyOwnerGui: account
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
propertyName: "stunServer" propertyName: "stunServer"
propertyOwner: account.core propertyOwnerGui: account
title: qsTr("Adresse du serveur STUN") title: qsTr("Adresse du serveur STUN")
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Activer ICE") titleText: qsTr("Activer ICE")
propertyName: "iceEnabled" propertyName: "iceEnabled"
propertyOwner: account.core propertyOwnerGui: account
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("AVPF") titleText: qsTr("AVPF")
propertyName: "avpfEnabled" propertyName: "avpfEnabled"
propertyOwner: account.core propertyOwnerGui: account
} }
SwitchSetting { SwitchSetting {
titleText: qsTr("Mode bundle") titleText: qsTr("Mode bundle")
propertyName: "bundleModeEnabled" propertyName: "bundleModeEnabled"
propertyOwner: account.core propertyOwnerGui: account
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
propertyName: "expire" propertyName: "expire"
propertyOwner: account.core propertyOwnerGui: account
title: qsTr("Expiration (en seconde)") title: qsTr("Expiration (en seconde)")
canBeEmpty: false canBeEmpty: false
isValid: function(text) { return !isNaN(Number(text)) } isValid: function(text) { return !isNaN(Number(text)) }
@ -127,20 +127,20 @@ AbstractSettingsLayout {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("URI de lusine à conversations") title: qsTr("URI de lusine à conversations")
propertyName: "conferenceFactoryAddress" propertyName: "conferenceFactoryAddress"
propertyOwner: account.core propertyOwnerGui: account
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("URI de lusine à réunions") title: qsTr("URI de lusine à réunions")
propertyName: "audioVideoConferenceFactoryAddress" propertyName: "audioVideoConferenceFactoryAddress"
propertyOwner: account.core propertyOwnerGui: account
visible: !SettingsCpp.disableMeetingsFeature visible: !SettingsCpp.disableMeetingsFeature
} }
DecoratedTextField { DecoratedTextField {
Layout.fillWidth: true Layout.fillWidth: true
title: qsTr("URL du serveur déchange de clés de chiffrement") title: qsTr("URL du serveur déchange de clés de chiffrement")
propertyName: "limeServerUrl" propertyName: "limeServerUrl"
propertyOwner: account.core propertyOwnerGui: account
} }
} }
} }

View file

@ -139,7 +139,7 @@ AbstractSettingsLayout {
titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType) titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType)
subTitleText: modelData.core.clockRate + " Hz" subTitleText: modelData.core.clockRate + " Hz"
propertyName: "enabled" propertyName: "enabled"
propertyOwner: modelData.core propertyOwnerGui: modelData
} }
} }
} }
@ -162,7 +162,7 @@ AbstractSettingsLayout {
titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType) titleText: Utils.capitalizeFirstLetter(modelData.core.mimeType)
subTitleText: modelData.core.encoderDescription subTitleText: modelData.core.encoderDescription
propertyName: "enabled" propertyName: "enabled"
propertyOwner: modelData.core propertyOwnerGui: modelData
} }
} }
Repeater { Repeater {

View file

@ -74,7 +74,7 @@ AbstractSettingsLayout {
Layout.leftMargin: 64 * DefaultStyle.dp Layout.leftMargin: 64 * DefaultStyle.dp
DecoratedTextField { DecoratedTextField {
propertyName: "displayName" propertyName: "displayName"
propertyOwner: carddavGui.core propertyOwnerGui: carddavGui
title: qsTr("Nom daffichage") title: qsTr("Nom daffichage")
canBeEmpty: false canBeEmpty: false
toValidate: true toValidate: true
@ -82,7 +82,7 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
propertyName: "uri" propertyName: "uri"
propertyOwner: carddavGui.core propertyOwnerGui: carddavGui
title: qsTr("URL du serveur") title: qsTr("URL du serveur")
canBeEmpty: false canBeEmpty: false
toValidate: true toValidate: true
@ -90,7 +90,7 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
propertyName: "username" propertyName: "username"
propertyOwner: carddavGui.core propertyOwnerGui: carddavGui
title: qsTr("Nom dutilisateur") title: qsTr("Nom dutilisateur")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -98,14 +98,14 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "password" propertyName: "password"
hidden: true hidden: true
propertyOwner: carddavGui.core propertyOwnerGui: carddavGui
title: qsTr("Mot de passe") title: qsTr("Mot de passe")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "realm" propertyName: "realm"
propertyOwner: carddavGui.core propertyOwnerGui: carddavGui
title: qsTr("Domaine dauthentification") title: qsTr("Domaine dauthentification")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -113,7 +113,7 @@ AbstractSettingsLayout {
SwitchSetting { SwitchSetting {
titleText: qsTr("Stocker ici les contacts nouvellement crées") titleText: qsTr("Stocker ici les contacts nouvellement crées")
propertyName: "storeNewFriendsInIt" propertyName: "storeNewFriendsInIt"
propertyOwner: carddavGui.core propertyOwnerGui: carddavGui
} }
} }
} }

View file

@ -70,14 +70,14 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
id: server id: server
propertyName: "serverUrl" propertyName: "serverUrl"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("URL du serveur (ne peut être vide)") title: qsTr("URL du serveur (ne peut être vide)")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "bindDn" propertyName: "bindDn"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Bind DN") title: qsTr("Bind DN")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -85,7 +85,7 @@ AbstractSettingsLayout {
DecoratedTextField { DecoratedTextField {
propertyName: "password" propertyName: "password"
hidden: true hidden: true
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Mot de passe") title: qsTr("Mot de passe")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -93,25 +93,25 @@ AbstractSettingsLayout {
SwitchSetting { SwitchSetting {
titleText: qsTr("Utiliser TLS") titleText: qsTr("Utiliser TLS")
propertyName: "tls" propertyName: "tls"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
} }
DecoratedTextField { DecoratedTextField {
propertyName: "baseObject" propertyName: "baseObject"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Base de recherche (ne peut être vide)") title: qsTr("Base de recherche (ne peut être vide)")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "filter" propertyName: "filter"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Filtre") title: qsTr("Filtre")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "limit" propertyName: "limit"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
title: qsTr("Nombre maximum de résultats") title: qsTr("Nombre maximum de résultats")
toValidate: true toValidate: true
@ -119,7 +119,7 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
propertyName: "delay" propertyName: "delay"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
title: qsTr("Délai entre 2 requêtes (en millisecondes)") title: qsTr("Délai entre 2 requêtes (en millisecondes)")
toValidate: true toValidate: true
@ -127,7 +127,7 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
propertyName: "timeout" propertyName: "timeout"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Durée maximun (en secondes)") title: qsTr("Durée maximun (en secondes)")
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
toValidate: true toValidate: true
@ -135,7 +135,7 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
propertyName: "minCharacters" propertyName: "minCharacters"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Nombre minimum de caractères pour la requête") title: qsTr("Nombre minimum de caractères pour la requête")
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ } validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
toValidate: true toValidate: true
@ -143,21 +143,21 @@ AbstractSettingsLayout {
} }
DecoratedTextField { DecoratedTextField {
propertyName: "nameAttribute" propertyName: "nameAttribute"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Attributs de nom") title: qsTr("Attributs de nom")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "sipAttribute" propertyName: "sipAttribute"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Attributs SIP") title: qsTr("Attributs SIP")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
} }
DecoratedTextField { DecoratedTextField {
propertyName: "sipDomain" propertyName: "sipDomain"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
title: qsTr("Domaine SIP") title: qsTr("Domaine SIP")
toValidate: true toValidate: true
Layout.fillWidth: true Layout.fillWidth: true
@ -165,7 +165,7 @@ AbstractSettingsLayout {
SwitchSetting { SwitchSetting {
titleText: qsTr("Débogage") titleText: qsTr("Débogage")
propertyName: "debug" propertyName: "debug"
propertyOwner: ldapGui.core propertyOwnerGui: ldapGui
} }
} }
} }