fix ensure visible contact edition

fix #LINQT-1569 dialer ui in call

fix address artifact due to full default address addition in address list
This commit is contained in:
Gaelle Braud 2025-01-29 10:28:49 +01:00
parent 3a4da9694c
commit 5d42559f83
10 changed files with 65 additions and 39 deletions

View file

@ -409,12 +409,14 @@ void FriendCore::appendAddress(const QString &addr) {
if (addr.isEmpty()) return; if (addr.isEmpty()) return;
mCoreModelConnection->invokeToModel([this, addr]() { mCoreModelConnection->invokeToModel([this, addr]() {
auto linphoneAddr = ToolModel::interpretUrl(addr); auto linphoneAddr = ToolModel::interpretUrl(addr);
QString interpretedAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asString()) : ""; QString interpretedFullAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asString()) : "";
mCoreModelConnection->invokeToCore([this, interpretedAddress]() { QString interpretedAddress = linphoneAddr ? Utils::coreStringToAppString(linphoneAddr->asStringUriOnly()) : "";
mCoreModelConnection->invokeToCore([this, interpretedAddress, interpretedFullAddress]() {
if (interpretedAddress.isEmpty()) Utils::showInformationPopup(tr("Erreur"), tr("Adresse invalide"), false); if (interpretedAddress.isEmpty()) Utils::showInformationPopup(tr("Erreur"), tr("Adresse invalide"), false);
else { else {
mAddressList.append(Utils::createFriendAddressVariant(_addressLabel, interpretedAddress)); mAddressList.append(Utils::createFriendAddressVariant(_addressLabel, interpretedAddress));
if (mDefaultFullAddress.isEmpty()) mDefaultFullAddress = interpretedAddress; if (mDefaultFullAddress.isEmpty()) mDefaultFullAddress = interpretedFullAddress;
if (mDefaultAddress.isEmpty()) mDefaultAddress = interpretedAddress;
emit addressChanged(); emit addressChanged();
setIsSaved(false); setIsSaved(false);
} }
@ -467,9 +469,6 @@ QString FriendCore::getDefaultFullAddress() const {
} }
void FriendCore::setDefaultFullAddress(const QString &address) { void FriendCore::setDefaultFullAddress(const QString &address) {
auto it = std::find_if(mAddressList.begin(), mAddressList.end(),
[address](const QVariant &a) { return a.toMap()["address"].toString() == address; });
if (it == mAddressList.end()) appendAddress(address);
if (mDefaultFullAddress != address) { if (mDefaultFullAddress != address) {
mDefaultFullAddress = address; mDefaultFullAddress = address;
emit defaultFullAddressChanged(); emit defaultFullAddressChanged();
@ -596,6 +595,8 @@ void FriendCore::writeFromModel(const std::shared_ptr<FriendModel> &model) {
Utils::createFriendAddressVariant(_addressLabel, Utils::coreStringToAppString(addr->asStringUriOnly()))); Utils::createFriendAddressVariant(_addressLabel, Utils::coreStringToAppString(addr->asStringUriOnly())));
} }
mAddressList = addresses; mAddressList = addresses;
mDefaultAddress = model->getDefaultAddress();
mDefaultFullAddress = model->getDefaultFullAddress();
QList<QVariant> phones; QList<QVariant> phones;
for (auto &number : model->getPhoneNumbers()) { for (auto &number : model->getPhoneNumbers()) {
@ -637,8 +638,10 @@ void FriendCore::save() { // Save Values to model
thisCopy->writeIntoModel(mFriendModel); thisCopy->writeIntoModel(mFriendModel);
thisCopy->deleteLater(); thisCopy->deleteLater();
mVCardString = mFriendModel->getVCardAsString(); mVCardString = mFriendModel->getVCardAsString();
mFriendModelConnection->invokeToCore([this]() { emit saved(); }); mFriendModelConnection->invokeToCore([this]() {
setIsSaved(true); setIsSaved(true);
emit saved();
});
}); });
} else { } else {
mCoreModelConnection->invokeToModel([this, thisCopy]() { mCoreModelConnection->invokeToModel([this, thisCopy]() {
@ -660,8 +663,11 @@ void FriendCore::save() { // Save Values to model
thisCopy->writeIntoModel(mFriendModel); thisCopy->writeIntoModel(mFriendModel);
thisCopy->deleteLater(); thisCopy->deleteLater();
mVCardString = mFriendModel->getVCardAsString(); mVCardString = mFriendModel->getVCardAsString();
mCoreModelConnection->invokeToCore([this] {
setIsSaved(true);
emit saved();
});
}); });
emit saved();
}); });
} else { } else {
auto contact = core->createFriend(); auto contact = core->createFriend();
@ -688,6 +694,7 @@ void FriendCore::save() { // Save Values to model
mCoreModelConnection->invokeToCore([this, created]() { mCoreModelConnection->invokeToCore([this, created]() {
if (created) setSelf(mCoreModelConnection->mCore); if (created) setSelf(mCoreModelConnection->mCore);
setIsSaved(created); setIsSaved(created);
if (created) emit saved();
}); });
}); });
}); });

View file

@ -169,6 +169,14 @@ void FriendModel::clearAddresses() {
emit addressesChanged(); emit addressesChanged();
} }
QString FriendModel::getDefaultAddress() const {
return Utils::coreStringToAppString(mMonitor->getAddress()->asStringUriOnly());
}
QString FriendModel::getDefaultFullAddress() const {
return Utils::coreStringToAppString(mMonitor->getAddress()->asString());
}
QString FriendModel::getFullName() const { QString FriendModel::getFullName() const {
if (mFullName.isEmpty()) return getGivenName() + " " + getFamilyName(); if (mFullName.isEmpty()) return getGivenName() + " " + getFamilyName();
else return mFullName; else return mFullName;

View file

@ -51,6 +51,8 @@ public:
QString getFamilyName() const; QString getFamilyName() const;
QString getOrganization() const; QString getOrganization() const;
QString getJob() const; QString getJob() const;
QString getDefaultAddress() const;
QString getDefaultFullAddress() const;
bool getStarred() const; bool getStarred() const;
std::shared_ptr<linphone::Friend> getFriend() const; std::shared_ptr<linphone::Friend> getFriend() const;
QString getPictureUri() const; QString getPictureUri() const;

View file

@ -164,6 +164,8 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: centerItem.bottom anchors.top: centerItem.bottom
anchors.topMargin: 21 * DefaultStyle.dp anchors.topMargin: 21 * DefaultStyle.dp
anchors.left: parent.left
anchors.right: parent.right
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter

View file

@ -8,6 +8,8 @@ import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
FocusScope{ FocusScope{
id: mainItem id: mainItem
width: numPadGrid.width
height: numPadGrid.height
property var currentCall property var currentCall
property bool lastRowVisible: true property bool lastRowVisible: true
@ -87,7 +89,6 @@ FocusScope{
Layout.GridLayout { Layout.GridLayout {
id: numPadGrid id: numPadGrid
anchors.fill: parent
columns: 3 columns: 3
columnSpacing: 40 * DefaultStyle.dp columnSpacing: 40 * DefaultStyle.dp
rowSpacing: 10 * DefaultStyle.dp rowSpacing: 10 * DefaultStyle.dp

View file

@ -14,7 +14,7 @@ FocusScope {
property string text: textField.searchText property string text: textField.searchText
property bool magnifierVisible: true property bool magnifierVisible: true
property var validator: RegularExpressionValidator{} property var validator: RegularExpressionValidator{}
property Control.Popup numericPadPopup property var numericPadPopup
property alias numericPadButton: dialerButton property alias numericPadButton: dialerButton
readonly property bool hasActiveFocus: textField.activeFocus readonly property bool hasActiveFocus: textField.activeFocus
property alias color: backgroundItem.color property alias color: backgroundItem.color

View file

@ -159,11 +159,23 @@ MainRightPanel {
contentWidth: 421 * DefaultStyle.dp contentWidth: 421 * DefaultStyle.dp
contentY: 0 contentY: 0
signal ensureVisibleRequested(Item item)
function ensureVisible(r) { function ensureVisible(r) {
if (contentY >= r.y) if (contentY >= r.y)
contentY = r.y; contentY = r.y;
else if (contentY+height <= r.y+r.height) else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height; contentY = r.y + r.height - height;
}
// Hack to ensure the empty textfield is really visible, because
// its y changes too late after the editingFinished is emitted
function connectOnce(sig, slot) {
var f = function() {
slot.apply(this, arguments)
sig.disconnect(f)
}
sig.connect(f)
} }
ScrollBar.vertical: Control.ScrollBar { ScrollBar.vertical: Control.ScrollBar {
@ -295,9 +307,12 @@ MainRightPanel {
} }
} }
FormItemLayout { FormItemLayout {
id: newAddressSipTextField
label: qsTr("Adresse SIP") label: qsTr("Adresse SIP")
Layout.fillWidth: true Layout.fillWidth: true
// onYChanged: editionLayout.ensureVisible(this) onYChanged: {
editionLayout.ensureVisibleRequested(newAddressSipTextField)
}
contentItem: TextField { contentItem: TextField {
id: newAddressTextField id: newAddressTextField
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
@ -319,7 +334,7 @@ MainRightPanel {
onEditingFinished: { onEditingFinished: {
if (text.length > 0) mainItem.contact.core.appendAddress(text) if (text.length > 0) mainItem.contact.core.appendAddress(text)
newAddressTextField.clear() newAddressTextField.clear()
editionLayout.ensureVisible(this) editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible)
} }
} }
} }
@ -381,7 +396,9 @@ MainRightPanel {
id: phoneNumberInput id: phoneNumberInput
Layout.fillWidth: true Layout.fillWidth: true
label: qsTr("Phone") label: qsTr("Phone")
// onYChanged: editionLayout.ensureVisible(this) onYChanged: {
editionLayout.ensureVisibleRequested(phoneNumberInput)
}
contentItem: TextField { contentItem: TextField {
id: phoneNumberInputTextField id: phoneNumberInputTextField
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
@ -403,7 +420,7 @@ MainRightPanel {
onEditingFinished: { onEditingFinished: {
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(phoneNumberInput.label, text) if (text.length != 0) mainItem.contact.core.appendPhoneNumber(phoneNumberInput.label, text)
phoneNumberInputTextField.clear() phoneNumberInputTextField.clear()
editionLayout.ensureVisible(this) editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible)
} }
} }
} }

View file

@ -185,7 +185,7 @@ AbstractMainPage {
placeholderText: qsTr("Rechercher un appel") placeholderText: qsTr("Rechercher un appel")
visible: historyListView.count !== 0 || text.length !== 0 visible: historyListView.count !== 0 || text.length !== 0
focus: true focus: true
KeyNavigation.up: titleLoader KeyNavigation.up: newCallButton
KeyNavigation.down: historyListView KeyNavigation.down: historyListView
Binding { Binding {
target: mainItem target: mainItem
@ -524,7 +524,7 @@ AbstractMainPage {
KeyNavigation.left: groupCallButton KeyNavigation.left: groupCallButton
onClicked: { onClicked: {
listStackView.pop() listStackView.pop()
titleLoader.item.forceActiveFocus() listStackView.currentItem?.forceActiveFocus()
} }
} }
ColumnLayout { ColumnLayout {
@ -660,8 +660,8 @@ AbstractMainPage {
anchors.fill: parent anchors.fill: parent
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
property bool isLdap: contactDetail.contact?.core?.isLdap property bool isLdap: contactDetail.contact?.core?.isLdap || false
property bool isCardDAV: contactDetail.contact?.core?.isCardDAV property bool isCardDAV: contactDetail.contact?.core?.isCardDAV || false
text: contactDetail.contact ? qsTr("Voir le contact") : qsTr("Ajouter aux contacts") text: contactDetail.contact ? qsTr("Voir le contact") : qsTr("Ajouter aux contacts")
icon.source: AppIcons.plusCircle icon.source: AppIcons.plusCircle
icon.width: 32 * DefaultStyle.dp icon.width: 32 * DefaultStyle.dp

View file

@ -630,7 +630,7 @@ AbstractMainPage {
Item{Layout.fillWidth: true} Item{Layout.fillWidth: true}
EffectImage { EffectImage {
visible: listViewModelData.securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified visible: listViewModelData.securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
source: AppIcons.trusted imageSource: AppIcons.trusted
Layout.preferredWidth: 22 * DefaultStyle.dp Layout.preferredWidth: 22 * DefaultStyle.dp
Layout.preferredHeight: 22 * DefaultStyle.dp Layout.preferredHeight: 22 * DefaultStyle.dp
} }

View file

@ -682,12 +682,8 @@ AbstractWindow {
rightPanel.visible = false rightPanel.visible = false
event.accepted = true event.accepted = true
} }
Item { Item{Layout.fillHeight: true}
Layout.fillWidth: true
Layout.fillHeight: true
}
SearchBar { SearchBar {
id: dialerTextInput
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: 10 * DefaultStyle.dp Layout.leftMargin: 10 * DefaultStyle.dp
Layout.rightMargin: 10 * DefaultStyle.dp Layout.rightMargin: 10 * DefaultStyle.dp
@ -695,24 +691,17 @@ AbstractWindow {
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
borderColor: DefaultStyle.grey_200 borderColor: DefaultStyle.grey_200
placeholderText: "" placeholderText: ""
numericPadPopup: numPadPopup numericPadPopup: numPad
numericPadButton.visible: false numericPadButton.visible: false
enabled: false enabled: false
} }
NumericPad {
NumericPadPopup { id: numPad
id: numPadPopup Layout.alignment: Qt.AlignHCenter
width: parent.width
parent: numericPadContainer
closeButtonVisible: false
roundedBottom: true
visible: dialerPanelContent.visible
currentCall: callsModel.currentCall currentCall: callsModel.currentCall
lastRowVisible: false lastRowVisible: false
leftPadding: 40 * DefaultStyle.dp Layout.topMargin: 41 * DefaultStyle.dp
rightPadding: 40 * DefaultStyle.dp Layout.bottomMargin: 18 * DefaultStyle.dp
topPadding: 41 * DefaultStyle.dp
bottomPadding: 18 * DefaultStyle.dp
onLaunchCall: { onLaunchCall: {
UtilsCpp.createCall(dialerTextInput.text) UtilsCpp.createCall(dialerTextInput.text)
} }