Commit 1de0129e authored by Ronan Abhamon's avatar Ronan Abhamon

fix(ui/views/App/Main/ContactEdit): smart edition

parent 40f5c1a4
...@@ -195,7 +195,7 @@ void CallsListModel::removeCall (const shared_ptr<linphone::Call> &call) { ...@@ -195,7 +195,7 @@ void CallsListModel::removeCall (const shared_ptr<linphone::Call> &call) {
} catch (const out_of_range &) { } catch (const out_of_range &) {
// Can be a bug. Or the call model not exists because the linphone call state // Can be a bug. Or the call model not exists because the linphone call state
// `CallStateIncomingReceived`/`CallStateOutgoingInit` was not notified. // `CallStateIncomingReceived`/`CallStateOutgoingInit` was not notified.
qWarning() << QStringLiteral("Unable to found call in:") << callModel; qWarning() << QStringLiteral("Unable to found linphone call:") << &(*call);
return; return;
} }
......
...@@ -31,28 +31,39 @@ using namespace std; ...@@ -31,28 +31,39 @@ using namespace std;
// ============================================================================= // =============================================================================
ContactModel::ContactModel (QObject *parent, shared_ptr<linphone::Friend> linphoneFriend) : QObject(parent) { ContactModel::ContactModel (QObject *parent, shared_ptr<linphone::Friend> linphoneFriend) : QObject(parent) {
Q_ASSERT(linphoneFriend != nullptr);
mLinphoneFriend = linphoneFriend; mLinphoneFriend = linphoneFriend;
mVcard = make_shared<VcardModel>(linphoneFriend->getVcard());
App::getInstance()->getEngine()->setObjectOwnership(mVcard.get(), QQmlEngine::CppOwnership); mVcardModel = new VcardModel(linphoneFriend->getVcard());
App::getInstance()->getEngine()->setObjectOwnership(mVcardModel, QQmlEngine::CppOwnership);
mLinphoneFriend->setData("contact-model", *this); mLinphoneFriend->setData("contact-model", *this);
} }
ContactModel::ContactModel (QObject *parent, VcardModel *vcard) : QObject(parent) { ContactModel::ContactModel (QObject *parent, VcardModel *vcardModel) : QObject(parent) {
Q_ASSERT(vcard != nullptr); Q_ASSERT(vcardModel != nullptr);
QQmlEngine *engine = App::getInstance()->getEngine(); QQmlEngine *engine = App::getInstance()->getEngine();
if (engine->objectOwnership(vcard) == QQmlEngine::CppOwnership) if (engine->objectOwnership(vcardModel) == QQmlEngine::CppOwnership) {
throw invalid_argument("A contact is already linked to this vcard."); qWarning() << QStringLiteral("A contact is already linked to this vcard:") << vcardModel;
abort();
}
mLinphoneFriend = linphone::Friend::newFromVcard(vcard->mVcard); Q_ASSERT(vcardModel->mVcard != nullptr);
mLinphoneFriend = linphone::Friend::newFromVcard(vcardModel->mVcard);
mLinphoneFriend->setData("contact-model", *this); mLinphoneFriend->setData("contact-model", *this);
mVcard.reset(vcard); mVcardModel = vcardModel;
engine->setObjectOwnership(vcardModel, QQmlEngine::CppOwnership);
engine->setObjectOwnership(vcard, QQmlEngine::CppOwnership); qInfo() << QStringLiteral("Create contact from vcard:") << this << vcardModel;
} }
// -----------------------------------------------------------------------------
void ContactModel::refreshPresence () { void ContactModel::refreshPresence () {
Presence::PresenceStatus status = static_cast<Presence::PresenceStatus>( Presence::PresenceStatus status = static_cast<Presence::PresenceStatus>(
mLinphoneFriend->getConsolidatedPresence() mLinphoneFriend->getConsolidatedPresence()
...@@ -62,15 +73,17 @@ void ContactModel::refreshPresence () { ...@@ -62,15 +73,17 @@ void ContactModel::refreshPresence () {
emit presenceLevelChanged(Presence::getPresenceLevel(status)); emit presenceLevelChanged(Presence::getPresenceLevel(status));
} }
// -----------------------------------------------------------------------------
void ContactModel::startEdit () { void ContactModel::startEdit () {
mLinphoneFriend->edit(); mLinphoneFriend->edit();
mOldSipAddresses = mVcard->getSipAddresses(); mOldSipAddresses = mVcardModel->getSipAddresses();
} }
void ContactModel::endEdit () { void ContactModel::endEdit () {
mLinphoneFriend->done(); mLinphoneFriend->done();
QVariantList sipAddresses = mVcard->getSipAddresses(); QVariantList sipAddresses = mVcardModel->getSipAddresses();
QSet<QString> done; QSet<QString> done;
for (const auto &variantA : mOldSipAddresses) { for (const auto &variantA : mOldSipAddresses) {
...@@ -104,13 +117,13 @@ next: ...@@ -104,13 +117,13 @@ next:
} }
void ContactModel::abortEdit () { void ContactModel::abortEdit () {
// TODO: call linphone friend abort function when available.
// mLinphoneFriend->abort();
mOldSipAddresses.clear(); mOldSipAddresses.clear();
emit contactUpdated(); emit contactUpdated();
} }
// -----------------------------------------------------------------------------
Presence::PresenceStatus ContactModel::getPresenceStatus () const { Presence::PresenceStatus ContactModel::getPresenceStatus () const {
return static_cast<Presence::PresenceStatus>(mLinphoneFriend->getConsolidatedPresence()); return static_cast<Presence::PresenceStatus>(mLinphoneFriend->getConsolidatedPresence());
} }
...@@ -118,3 +131,24 @@ Presence::PresenceStatus ContactModel::getPresenceStatus () const { ...@@ -118,3 +131,24 @@ Presence::PresenceStatus ContactModel::getPresenceStatus () const {
Presence::PresenceLevel ContactModel::getPresenceLevel () const { Presence::PresenceLevel ContactModel::getPresenceLevel () const {
return Presence::getPresenceLevel(getPresenceStatus()); return Presence::getPresenceLevel(getPresenceStatus());
} }
// -----------------------------------------------------------------------------
VcardModel *ContactModel::getVcardModel () const {
return mVcardModel;
}
void ContactModel::setVcardModel (VcardModel *vcardModel) {
Q_ASSERT(vcardModel != nullptr);
Q_ASSERT(vcardModel != mVcardModel);
QQmlEngine *engine = App::getInstance()->getEngine();
engine->setObjectOwnership(vcardModel, QQmlEngine::CppOwnership);
engine->setObjectOwnership(mVcardModel, QQmlEngine::JavaScriptOwnership);
qInfo() << QStringLiteral("Set vcard on contact:") << this << vcardModel;
qInfo() << QStringLiteral("Remove vcard on contact:") << this << mVcardModel;
mLinphoneFriend->setVcard(vcardModel->mVcard);
mVcardModel = vcardModel;
}
...@@ -33,29 +33,30 @@ class ContactModel : public QObject { ...@@ -33,29 +33,30 @@ class ContactModel : public QObject {
Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged); Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged);
Q_PROPERTY(Presence::PresenceLevel presenceLevel READ getPresenceLevel NOTIFY presenceLevelChanged); Q_PROPERTY(Presence::PresenceLevel presenceLevel READ getPresenceLevel NOTIFY presenceLevelChanged);
Q_PROPERTY(VcardModel * vcard READ getVcardModelPtr NOTIFY contactUpdated); Q_PROPERTY(VcardModel * vcard READ getVcardModel WRITE setVcardModel NOTIFY contactUpdated);
// Grant access to `mLinphoneFriend`.
friend class ContactsListModel; friend class ContactsListModel;
friend class ContactsListProxyModel; friend class ContactsListProxyModel;
friend class SmartSearchBarModel; friend class SmartSearchBarModel;
public: public:
ContactModel (QObject *parent, std::shared_ptr<linphone::Friend> linphoneFriend); ContactModel (QObject *parent, std::shared_ptr<linphone::Friend> linphoneFriend);
ContactModel (QObject *parent, VcardModel *vcard); ContactModel (QObject *parent, VcardModel *vcardModel);
~ContactModel () = default; ~ContactModel () = default;
std::shared_ptr<VcardModel> getVcardModel () const {
return mVcard;
}
void refreshPresence (); void refreshPresence ();
Q_INVOKABLE void startEdit (); Q_INVOKABLE void startEdit ();
Q_INVOKABLE void endEdit (); Q_INVOKABLE void endEdit ();
Q_INVOKABLE void abortEdit (); Q_INVOKABLE void abortEdit ();
VcardModel *getVcardModel () const;
void setVcardModel (VcardModel *vcardModel);
signals: signals:
void contactUpdated (); void contactUpdated ();
void presenceStatusChanged (Presence::PresenceStatus status); void presenceStatusChanged (Presence::PresenceStatus status);
void presenceLevelChanged (Presence::PresenceLevel level); void presenceLevelChanged (Presence::PresenceLevel level);
void sipAddressAdded (const QString &sipAddress); void sipAddressAdded (const QString &sipAddress);
...@@ -65,13 +66,9 @@ private: ...@@ -65,13 +66,9 @@ private:
Presence::PresenceStatus getPresenceStatus () const; Presence::PresenceStatus getPresenceStatus () const;
Presence::PresenceLevel getPresenceLevel () const; Presence::PresenceLevel getPresenceLevel () const;
VcardModel *getVcardModelPtr () const {
return mVcard.get();
}
QVariantList mOldSipAddresses; QVariantList mOldSipAddresses;
std::shared_ptr<VcardModel> mVcard; VcardModel *mVcardModel;
std::shared_ptr<linphone::Friend> mLinphoneFriend; std::shared_ptr<linphone::Friend> mLinphoneFriend;
}; };
......
...@@ -71,6 +71,8 @@ inline shared_ptr<belcard::BelCardPhoto> findBelCardPhoto (const list<shared_ptr ...@@ -71,6 +71,8 @@ inline shared_ptr<belcard::BelCardPhoto> findBelCardPhoto (const list<shared_ptr
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
VcardModel::VcardModel (shared_ptr<linphone::Vcard> vcard) : mVcard(vcard) {}
VcardModel::~VcardModel () { VcardModel::~VcardModel () {
// If it's a detached Vcard, the linked photo must be destroyed from fs. // If it's a detached Vcard, the linked photo must be destroyed from fs.
if (App::getInstance()->getEngine()->objectOwnership(this) != QQmlEngine::CppOwnership) { if (App::getInstance()->getEngine()->objectOwnership(this) != QQmlEngine::CppOwnership) {
...@@ -87,7 +89,16 @@ VcardModel::~VcardModel () { ...@@ -87,7 +89,16 @@ VcardModel::~VcardModel () {
if (!QFile::remove(imagePath)) if (!QFile::remove(imagePath))
qWarning() << QStringLiteral("Unable to remove `%1`.").arg(imagePath); qWarning() << QStringLiteral("Unable to remove `%1`.").arg(imagePath);
}
qInfo() << QStringLiteral("Destroy detached vcard:") << this;
} else
qInfo() << QStringLiteral("Destroy attached vcard:") << this;
}
// -----------------------------------------------------------------------------
VcardModel *VcardModel::clone () const {
return new VcardModel(mVcard->clone());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
...@@ -113,7 +124,7 @@ QString VcardModel::getAvatar () const { ...@@ -113,7 +124,7 @@ QString VcardModel::getAvatar () const {
// No path found. // No path found.
if (!photo) if (!photo)
return ""; return QStringLiteral("");
// Returns right path. // Returns right path.
return QStringLiteral("image://%1/%2").arg(AvatarProvider::PROVIDER_ID).arg( return QStringLiteral("image://%1/%2").arg(AvatarProvider::PROVIDER_ID).arg(
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
// ============================================================================= // =============================================================================
class VcardModel : public QObject { class VcardModel : public QObject {
friend class ContactModel; friend class ContactModel; // Grant access to `mVcard`.
Q_OBJECT; Q_OBJECT;
...@@ -42,13 +42,15 @@ class VcardModel : public QObject { ...@@ -42,13 +42,15 @@ class VcardModel : public QObject {
Q_PROPERTY(QVariantList urls READ getUrls NOTIFY vcardUpdated); Q_PROPERTY(QVariantList urls READ getUrls NOTIFY vcardUpdated);
public: public:
VcardModel (std::shared_ptr<linphone::Vcard> vcard) : mVcard(vcard) {} VcardModel (std::shared_ptr<linphone::Vcard> vcard);
~VcardModel (); ~VcardModel ();
QString getUsername () const; QString getUsername () const;
QVariantList getSipAddresses () const; QVariantList getSipAddresses () const;
Q_INVOKABLE VcardModel *clone () const;
Q_INVOKABLE bool addSipAddress (const QString &sipAddress); Q_INVOKABLE bool addSipAddress (const QString &sipAddress);
Q_INVOKABLE void removeSipAddress (const QString &sipAddress); Q_INVOKABLE void removeSipAddress (const QString &sipAddress);
Q_INVOKABLE bool updateSipAddress (const QString &oldSipAddress, const QString &sipAddress); Q_INVOKABLE bool updateSipAddress (const QString &oldSipAddress, const QString &sipAddress);
......
...@@ -16,7 +16,6 @@ RowLayout { ...@@ -16,7 +16,6 @@ RowLayout {
property alias title: text.text property alias title: text.text
property bool readOnly: false property bool readOnly: false
property int inputMethodHints property int inputMethodHints
property var defaultData: []
property var minValues property var minValues
readonly property int count: values.count readonly property int count: values.count
...@@ -193,15 +192,5 @@ RowLayout { ...@@ -193,15 +192,5 @@ RowLayout {
} }
model: ListModel {} model: ListModel {}
// -------------------------------------------------------------------------
// Init values.
// -------------------------------------------------------------------------
Component.onCompleted: {
if (defaultData) {
setData(defaultData)
}
}
} }
} }
...@@ -332,7 +332,7 @@ function extractProperties (obj, pattern) { ...@@ -332,7 +332,7 @@ function extractProperties (obj, pattern) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Returns an array from a `object` or `array` argument. // Returns an array from an `object` or `array` argument.
function ensureArray (obj) { function ensureArray (obj) {
if (isArray(obj)) { if (isArray(obj)) {
return obj return obj
...@@ -502,18 +502,6 @@ function includes (obj, value, startIndex) { ...@@ -502,18 +502,6 @@ function includes (obj, value, startIndex) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function invert (obj) {
var out = {}
for (var key in obj) {
out[key] = obj[key]
}
return out
}
// -----------------------------------------------------------------------------
function isArray (array) { function isArray (array) {
return (array instanceof Array) return (array instanceof Array)
} }
......
...@@ -16,31 +16,37 @@ function handleCreation () { ...@@ -16,31 +16,37 @@ function handleCreation () {
if (!contact) { if (!contact) {
var vcard = Linphone.CoreManager.createDetachedVcardModel() var vcard = Linphone.CoreManager.createDetachedVcardModel()
contactEdit._vcard = vcard
if (sipAddress && sipAddress.length > 0) { if (sipAddress && sipAddress.length > 0) {
vcard.addSipAddress(sipAddress) vcard.addSipAddress(sipAddress)
} }
contactEdit._vcard = vcard
contactEdit._edition = true contactEdit._edition = true
} else { } else {
contactEdit._vcard = contact.vcard contactEdit._vcard = contact.vcard
} }
} }
function handleDestruction () { function handleVcardChanged (vcard) {
var contact = contactEdit._contact if (!vcard) {
vcard = {}
if (contactEdit._edition && contact) {
contact.abortEdit()
} }
addresses.setData(vcard.sipAddresses)
companies.setData(vcard.companies)
emails.setData(vcard.emails)
urls.setData(vcard.urls)
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function editContact () { function editContact () {
contactEdit._contact.startEdit() var contact = contactEdit._contact
contact.startEdit()
contactEdit._vcard = contact.vcard.clone()
contactEdit._edition = true contactEdit._edition = true
window.lockView({ window.lockView({
...@@ -64,12 +70,14 @@ function removeContact () { ...@@ -64,12 +70,14 @@ function removeContact () {
function save () { function save () {
var contact = contactEdit._contact var contact = contactEdit._contact
var vcard = contactEdit._vcard
if (contact) { if (contact) {
contact.vcard = vcard
contact.endEdit() contact.endEdit()
window.unlockView() window.unlockView()
} else { } else {
contactEdit._contact = Linphone.ContactsListModel.addContact(contactEdit._vcard) contactEdit._contact = Linphone.ContactsListModel.addContact(vcard)
} }
contactEdit._edition = false contactEdit._edition = false
...@@ -79,9 +87,11 @@ function cancel () { ...@@ -79,9 +87,11 @@ function cancel () {
var contact = contactEdit._contact var contact = contactEdit._contact
if (contact) { if (contact) {
contactEdit._vcard = contact.vcard
contact.abortEdit() contact.abortEdit()
contactEdit._edition = false
window.unlockView() window.unlockView()
contactEdit._edition = false
} else { } else {
window.setView('Contacts') window.setView('Contacts')
} }
...@@ -104,51 +114,41 @@ function setUsername (username) { ...@@ -104,51 +114,41 @@ function setUsername (username) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function handleSipAddressChanged (sipAddresses, index, defaultValue, newValue) { function handleValueChanged (fields, index, defaultValue, newValue, add, update) {
if (newValue === defaultValue) { if (newValue === defaultValue) {
return return
} }
var vcard = contactEdit._vcard var vcard = contactEdit._vcard
var soFarSoGood = (defaultValue.length === 0) var soFarSoGood = (defaultValue.length === 0)
? vcard.addSipAddress(newValue) ? vcard[add](newValue)
: vcard.updateSipAddress(defaultValue, newValue) : vcard[update](defaultValue, newValue)
sipAddresses.setInvalid(index, !soFarSoGood) fields.setInvalid(index, !soFarSoGood)
} }
function handleCompanyChanged (companies, index, defaultValue, newValue) { function handleSipAddressChanged () {
var vcard = contactEdit._vcard var args = Array.prototype.slice.call(arguments)
var soFarSoGood = (defaultValue.length === 0) args.push('addSipAddress', 'updateSipAddress')
? vcard.addCompany(newValue) handleValueChanged.apply(this, args)
: vcard.updateCompany(defaultValue, newValue)
companies.setInvalid(index, !soFarSoGood)
} }
function handleEmailChanged (emails, index, defaultValue, newValue) { function handleCompanyChanged () {
var vcard = contactEdit._vcard var args = Array.prototype.slice.call(arguments)
var soFarSoGood = (defaultValue.length === 0) args.push('addCompany', 'updateCompany')
? vcard.addEmail(newValue) handleValueChanged.apply(this, args)
: vcard.updateEmail(defaultValue, newValue)
emails.setInvalid(index, !soFarSoGood)
} }
function handleUrlChanged (urls, index, defaultValue, newValue) { function handleEmailChanged () {
var url = Utils.extractFirstUri(newValue) var args = Array.prototype.slice.call(arguments)
if (url === defaultValue) { args.push('addEmail', 'updateEmail')
return handleValueChanged.apply(this, args)
} }
var vcard = contactEdit._vcard
var soFarSoGood = url && (
defaultValue.length === 0
? vcard.addUrl(newValue)
: vcard.updateUrl(defaultValue, newValue)
)
urls.setInvalid(index, !soFarSoGood) function handleUrlChanged () {
var args = Array.prototype.slice.call(arguments)
args.push('addUrl', 'updateUrl')
handleValueChanged.apply(this, args)
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
......
...@@ -18,6 +18,8 @@ ColumnLayout { ...@@ -18,6 +18,8 @@ ColumnLayout {
property string sipAddress property string sipAddress
readonly property alias vcard: contactEdit._vcard
property bool _edition: false property bool _edition: false
property var _contact property var _contact
property var _vcard property var _vcard
...@@ -27,10 +29,20 @@ ColumnLayout { ...@@ -27,10 +29,20 @@ ColumnLayout {
spacing: 0 spacing: 0
Component.onCompleted: Logic.handleCreation() Component.onCompleted: Logic.handleCreation()
Component.onDestruction: Logic.handleDestruction()
onVcardChanged: Logic.handleVcardChanged(vcard)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
Loader {
active: contactEdit._contact != null
sourceComponent: Connections {
target: contactEdit._contact
onContactUpdated: Logic.handleVcardChanged(contactEdit._contact.vcard)
}
}
FileDialog { FileDialog {
id: avatarChooser id: avatarChooser
...@@ -163,163 +175,140 @@ ColumnLayout { ...@@ -163,163 +175,140 @@ ColumnLayout {
color: ContactEditStyle.content.color color: ContactEditStyle.content.color
Loader { Flickable {
anchors.fill: parent id: flick
active: _vcard != null ScrollBar.vertical: ForceScrollBar {}
sourceComponent: Flickable {
id: flick
ScrollBar.vertical: ForceScrollBar {} anchors.fill: parent
boundsBehavior: Flickable.StopAtBounds
clip: true
contentHeight: infoList.height
contentWidth: width - ScrollBar.vertical.width
flickableDirection: Flickable.VerticalFlick
boundsBehavior: Flickable.StopAtBounds // -----------------------------------------------------------------------
clip: true
contentHeight: infoList.height
contentWidth: width - ScrollBar.vertical.width
flickableDirection: Flickable.VerticalFlick
// --------------------------------------------------------------------- ColumnLayout {
id: infoList
Connections { width: flick.contentWidth
target: _vcard
onVcardUpdated: { ListForm {
addresses.setData(_vcard.sipAddresses) id: addresses
companies.setData(_vcard.companies)
emails.setData(_vcard.emails)
urls.setData(_vcard.urls)
}
}
// --------------------------------------------------------------------- Layout.leftMargin: ContactEditStyle.values.leftMargin
Layout.rightMargin: ContactEditStyle.values.rightMargin
Layout.topMargin: ContactEditStyle.values.topMargin
ColumnLayout { minValues: _contact ? 1 : 0
id: infoList placeholder: qsTr('sipAccountsPlaceholder')
readOnly: !_edition
title: qsTr('sipAccounts')
width: flick.contentWidth onChanged: Logic.handleSipAddressChanged(addresses, index, defaultValue, newValue)
onRemoved: _vcard.removeSipAddress(value)
}
ListForm { Rectangle {
id: addresses Layout.fillWidth: true
Layout.preferredHeight: ContactEditStyle.values.separator.height
color: ContactEditStyle.values.separator.color
}
Layout.leftMargin: ContactEditStyle.values.leftMargin ListForm {
Layout.rightMargin: ContactEditStyle.values.rightMargin id: companies
Layout.topMargin: ContactEditStyle.values.topMargin
defaultData: _vcard.sipAddresses Layout.leftMargin: ContactEditStyle.values.leftMargin
minValues: _contact ? 1 : 0 Layout.rightMargin: ContactEditStyle.values.rightMargin
placeholder: qsTr('sipAccountsPlaceholder')
readOnly: !_edition
title: qsTr('sipAccounts')
onChanged: Logic.handleSipAddressChanged(addresses, index, defaultValue, newValue) placeholder: qsTr('companiesPlaceholder')
onRemoved: _vcard.removeSipAddress(value) readOnly: !_edition
} title: qsTr('companies')
Rectangle { onChanged: Logic.handleCompanyChanged(companies, index, defaultValue, newValue)
Layout.fillWidth: true onRemoved: _vcard.removeCompany(value)
Layout.preferredHeight: ContactEditStyle.values.separator.height }
color: ContactEditStyle.values.separator.color
}
ListForm { Rectangle {
id: companies Layout.fillWidth: true
Layout.preferredHeight: ContactEditStyle.values.separator.height
color: ContactEditStyle.values.separator.color
}
Layout.leftMargin: ContactEditStyle.values.leftMargin ListForm {
Layout.rightMargin: ContactEditStyle.values.rightMargin id: emails
defaultData: _vcard.companies Layout.leftMargin: ContactEditStyle.values.leftMargin
placeholder: qsTr('companiesPlaceholder') Layout.rightMargin: ContactEditStyle.values.rightMargin
readOnly: !_edition
title: qsTr('companies')
onChanged: Logic.handleCompanyChanged(companies, index, defaultValue, newValue) placeholder: qsTr('emailsPlaceholder')
onRemoved: _vcard.removeCompany(value) readOnly: !_edition
} title: qsTr('emails')
Rectangle { onChanged: Logic.handleEmailChanged(emails, index, defaultValue, newValue)
Layout.fillWidth: true onRemoved: _vcard.removeEmail(value)
Layout.preferredHeight: ContactEditStyle.values.separator.height }
color: ContactEditStyle.values.separator.color
}
ListForm { Rectangle {
id: emails Layout.fillWidth: true
Layout.preferredHeight: ContactEditStyle.values.separator.height
color: ContactEditStyle.values.separator.color
}
Layout.leftMargin: ContactEditStyle.values.leftMargin ListForm {
Layout.rightMargin: ContactEditStyle.values.rightMargin id: urls
defaultData: _vcard.emails Layout.leftMargin: ContactEditStyle.values.leftMargin
inputMethodHints: Qt.ImhEmailCharactersOnly Layout.rightMargin: ContactEditStyle.values.rightMargin
placeholder: qsTr('emailsPlaceholder')
readOnly: !_edition
title: qsTr('emails')
onChanged: Logic.handleEmailChanged(emails, index, defaultValue, newValue) placeholder: qsTr('webSitesPlaceholder')
onRemoved: _vcard.removeEmail(value) readOnly: !_edition
} title: qsTr('webSites')
Rectangle { onChanged: Logic.handleUrlChanged(urls, index, defaultValue, newValue)
Layout.fillWidth: true onRemoved: _vcard.removeUrl(value)
Layout.preferredHeight: ContactEditStyle.values.separator.height }
color: ContactEditStyle.values.separator.color
}
ListForm { Rectangle {
id: urls Layout.fillWidth: true
Layout.preferredHeight: ContactEditStyle.values.separator.height
color: ContactEditStyle.values.separator.color
}
Layout.leftMargin: ContactEditStyle.values.leftMargin StaticListForm {
Layout.rightMargin: ContactEditStyle.values.rightMargin Layout.leftMargin: ContactEditStyle.values.leftMargin
Layout.rightMargin: ContactEditStyle.values.rightMargin
defaultData: _vcard.urls fields: Logic.buildAddressFields()
inputMethodHints: Qt.ImhUrlCharactersOnly
placeholder: qsTr('webSitesPlaceholder')
readOnly: !_edition
title: qsTr('webSites')
onChanged: Logic.handleUrlChanged(urls, index, defaultValue, newValue) readOnly: !_edition
onRemoved: _vcard.removeUrl(value) title: qsTr('address')
}
Rectangle { onChanged: Logic.handleAddressChanged(index, value)
Layout.fillWidth: true }
Layout.preferredHeight: ContactEditStyle.values.separator.height
color: ContactEditStyle.values.separator.color
}
StaticListForm { // ---------------------------------------------------------------------
Layout.leftMargin: ContactEditStyle.values.leftMargin // Edition buttons.
Layout.rightMargin: ContactEditStyle.values.rightMargin // ---------------------------------------------------------------------
fields: Logic.buildAddressFields() Row {
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: ContactEditStyle.values.bottomMargin
Layout.topMargin: ContactEditStyle.buttons.topMargin
readOnly: !_edition spacing: ContactEditStyle.buttons.spacing
title: qsTr('address') visible: _edition
onChanged: Logic.handleAddressChanged(index, value) TextButtonA {
text: qsTr('cancel')
onClicked: Logic.cancel()
} }
// ------------------------------------------------------------------- TextButtonB {
// Edition buttons. enabled: usernameInput.text.length > 0 && _vcard.sipAddresses.length > 0
// ------------------------------------------------------------------- text: qsTr('save')
onClicked: Logic.save()
Row {
Layout.alignment: Qt.AlignHCenter
Layout.bottomMargin: ContactEditStyle.values.bottomMargin
Layout.topMargin: ContactEditStyle.buttons.topMargin
spacing: ContactEditStyle.buttons.spacing
visible: _edition
TextButtonA {
text: qsTr('cancel')
onClicked: Logic.cancel()
}
TextButtonB {
enabled: usernameInput.text.length > 0 && _vcard.sipAddresses.length > 0
text: qsTr('save')
onClicked: Logic.save()
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment