Merge ~radonapps/dekko:fix-1341547 into dekko:master

Proposed by Daniyaal Rasheed
Status: Approved
Approved by: Dan Chapman 
Approved revision: 240d9603c7e6a5297bc0487fe46c8230433367d2
Proposed branch: ~radonapps/dekko:fix-1341547
Merge into: dekko:master
Diff against target: 379 lines (+110/-14)
13 files modified
qml/Settings/user/NewIdentityPage.qml (+27/-10)
qml/Settings/user/SenderIdentityInput.qml (+9/-0)
qml/SetupWizard/IdentityInput.qml (+15/-2)
qml/SetupWizard/ManualSetup.qml (+11/-0)
qml/SetupWizard/SetupWizard.qml (+4/-0)
src/3rdParty/trojita/Common/SettingsNames.cpp (+1/-0)
src/3rdParty/trojita/Common/SettingsNames.h (+1/-1)
src/app/Accounts/SenderIdentity.cpp (+14/-0)
src/app/Accounts/SenderIdentity.h (+16/-0)
src/app/Accounts/SenderIdentityModel.cpp (+9/-0)
src/app/Accounts/SenderIdentityModel.h (+1/-0)
src/app/Settings/SettingsNames.cpp (+1/-0)
src/app/Settings/SettingsNames.h (+1/-1)
Reviewer Review Type Date Requested Status
Dan Chapman  (community) Approve
Review via email: mp+281487@code.launchpad.net

Description of the change

Implemented a Reply-To field as part of an Identity

This patch implements the skeleton required for future use of a reply-to
email by adding the GUI necessary for a user to configure their reply-to
email address.

fixes: bug 1341547

To post a comment you must log in.
Revision history for this message
Daniyaal Rasheed (radonapps) wrote :

Both NotificationWorker classes are not supposed to be there, when I pulled in the new code it apparently made changes to this file, which I blindly staged because everything above it was right. I don't how I can "uncommit" this but still have the changes I've made to all the other files inside my local repository.

Revision history for this message
Dan Chapman  (dpniel) wrote :

Good start. See comments inline

review: Needs Fixing
~radonapps/dekko:fix-1341547 updated
240d960... by Daniyaal Rasheed

Fixed invalid email popup's title and message.

Revision history for this message
Dan Chapman  (dpniel) wrote :

Looks good to me. Nice job

I'll get this new field added to the message headers in the next couple of days while i finish off this smtp owrk.

Thanks again!

review: Approve

Unmerged commits

240d960... by Daniyaal Rasheed

Fixed invalid email popup's title and message.

6f6affa... by Daniyaal Rasheed

Implemented a Reply-To field as part of an Identity

This patch implements the skeleton required for future use of a reply-to
email by adding the GUI necessary for a user to configure their reply-to
email address.

fixes: bug 1341547

d498ade... by Daniyaal Rasheed

Merge branch 'fix-1522549'

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/qml/Settings/user/NewIdentityPage.qml b/qml/Settings/user/NewIdentityPage.qml
2index 9d51aea..990e7a7 100644
3--- a/qml/Settings/user/NewIdentityPage.qml
4+++ b/qml/Settings/user/NewIdentityPage.qml
5@@ -1,5 +1,6 @@
6 import QtQuick 2.4
7 import Ubuntu.Components 1.2
8+import Ubuntu.Components.Popups 1.0
9 import DekkoCore 0.2
10 import "../../Components"
11
12@@ -14,11 +15,24 @@ Page {
13 if (edit) {
14 input.nameField = identity.name
15 input.emailField = identity.email
16+ input.replyToField = identity.replyTo
17 input.organizationField = identity.organization
18 input.signatureField = identity.signature
19 }
20 }
21
22+ function validateAddress(address) {
23+ if (address && !EmailValidator.validate(address)) {
24+ var msg = qsTr("%1 is not a valid email address").arg(address)
25+ PopupUtils.open(Qt.resolvedUrl("../../Dialogs/InfoDialog.qml"), dekko, {
26+ title: qsTr("Invaid address"),
27+ text: msg
28+ })
29+ return false
30+ }
31+ return true
32+ }
33+
34 DekkoHeader {
35 id: header
36 title: edit ? qsTr("Edit identity") : qsTr("New identity")
37@@ -30,16 +44,19 @@ Page {
38 id: saveAction
39 iconName: "ok"
40 onTriggered: {
41- if (edit) {
42- identity.name = input.nameField
43- identity.email = input.emailField
44- identity.organization = input.organizationField
45- identity.signature = input.signatureField
46- } else {
47- model.appendRow(newIdentity)
48+ if (validateAddress(input.emailField) && validateAddress(input.replyToField)) {
49+ if (edit) {
50+ identity.name = input.nameField
51+ identity.email = input.emailField
52+ identity.replyTo = input.replyToField
53+ identity.organization = input.organizationField
54+ identity.signature = input.signatureField
55+ } else {
56+ model.appendRow(newIdentity)
57+ }
58+ closing()
59+ rootPageStack.pop()
60 }
61- closing()
62- rootPageStack.pop()
63 }
64 }
65 }
66@@ -52,9 +69,9 @@ Page {
67 id: newIdentity
68 name: input.nameField
69 email: input.emailField
70+ replyTo: input.replyToField
71 organization: input.organizationField
72 signature: input.signatureField
73-
74 }
75 Flickable {
76 anchors {
77diff --git a/qml/Settings/user/SenderIdentityInput.qml b/qml/Settings/user/SenderIdentityInput.qml
78index 6818ac5..e92cf7a 100644
79--- a/qml/Settings/user/SenderIdentityInput.qml
80+++ b/qml/Settings/user/SenderIdentityInput.qml
81@@ -27,6 +27,7 @@ Column {
82
83 property alias nameField: nameField.text
84 property alias emailField: emailField.text
85+ property alias replyToField: replyToField.text
86 property alias organizationField: organizationField.text
87 property alias signatureField: signatureField.text
88 property alias signatureFieldVisible: signatureField.visible
89@@ -61,6 +62,14 @@ Column {
90 inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhEmailCharactersOnly
91 sendTabEventOnEnter: true
92 KeyNavigation.priority: KeyNavigation.BeforeItem
93+ KeyNavigation.tab: replyToField.textFieldFocusHandle
94+ }
95+ TitledTextField {
96+ id: replyToField
97+ title: qsTr("Reply-To")
98+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText | Qt.ImhEmailCharactersOnly
99+ sendTabEventOnEnter: true
100+ KeyNavigation.priority: KeyNavigation.BeforeItem
101 KeyNavigation.tab: organizationField.textFieldFocusHandle
102 }
103 TitledTextField {
104diff --git a/qml/SetupWizard/IdentityInput.qml b/qml/SetupWizard/IdentityInput.qml
105index 4809ca2..f7ad072 100644
106--- a/qml/SetupWizard/IdentityInput.qml
107+++ b/qml/SetupWizard/IdentityInput.qml
108@@ -32,6 +32,7 @@ Item {
109 property alias name: input.nameField
110 property alias email: input.emailField
111 property alias organization: input.organizationField
112+ property alias replyTo: input.replyToField
113
114 DekkoHeader {
115 id: header
116@@ -50,6 +51,18 @@ Item {
117 }
118 }
119
120+ function validateAddress(address) {
121+ if (address && !EmailValidator.validate(address)) {
122+ var msg = qsTr("%1 is not a valid email address").arg(address)
123+ PopupUtils.open(Qt.resolvedUrl("../../Dialogs/InfoDialog.qml"), dekko, {
124+ title: qsTr("Invaid address"),
125+ text: msg
126+ })
127+ return false
128+ }
129+ return true
130+ }
131+
132 Action {
133 id: nextAction
134 iconName: "next"
135@@ -58,8 +71,7 @@ Item {
136 input.showMissingFields = true
137 return
138 }
139- if (!EmailValidator.validate(email)) {
140- PopupUtils.open(Qt.resolvedUrl("../Dialogs/InfoDialog.qml"), wizard, {title: qsTr("Invalid address"), text: qsTr("%1 is not a valid email address").arg(email)})
141+ if (!validateAddress(email) || !validateAddress(replyTo)) {
142 return
143 }
144 inputComplete()
145@@ -80,6 +92,7 @@ Item {
146 nameField: wizard.identity.name
147 emailField: EmailValidator.validate(wizard.account.smtpSettings.username) ? wizard.account.smtpSettings.username : wizard.identity.email
148 organizationField: wizard.identity.organization
149+ replyToField: wizard.identity.replyTo
150 }
151 }
152 }
153diff --git a/qml/SetupWizard/ManualSetup.qml b/qml/SetupWizard/ManualSetup.qml
154index 5da64b9..2393723 100644
155--- a/qml/SetupWizard/ManualSetup.qml
156+++ b/qml/SetupWizard/ManualSetup.qml
157@@ -41,6 +41,7 @@ Column {
158 property alias smtpPort: smtpPortField.text
159 function parsedSmtpPort(){ return parseInt(smtpPortField.text)}
160 property alias smtpUsername: smtpEmailField.text
161+ property alias smtpReplyTo: smtpReplyToField.text
162 property alias smtpPassword: smtpPasswordField.text
163 readonly property bool isImap: serverInput.state === "imap"
164 readonly property bool isSmtp: serverInput.state === "smtp"
165@@ -219,6 +220,16 @@ Column {
166 sendTabEventOnEnter: true
167 requiredField: internal.invalidFields
168 KeyNavigation.priority: KeyNavigation.BeforeItem
169+ KeyNavigation.tab: smtpReplyToField.textFieldFocusHandle
170+ }
171+
172+ TitledTextField {
173+ id: smtpReplyToField
174+ title: qsTr("Reply-To")
175+ visible: !isImap
176+ inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhEmailCharactersOnly | Qt.ImhNoPredictiveText
177+ sendTabEventOnEnter: true
178+ KeyNavigation.priority: KeyNavigation.BeforeItem
179 KeyNavigation.tab: smtpPasswordField.textFieldFocusHandle
180 }
181
182diff --git a/qml/SetupWizard/SetupWizard.qml b/qml/SetupWizard/SetupWizard.qml
183index 8925a7b..af07c85 100644
184--- a/qml/SetupWizard/SetupWizard.qml
185+++ b/qml/SetupWizard/SetupWizard.qml
186@@ -80,6 +80,10 @@ Item {
187 when: identityInput.active
188 value: loader.item.organization
189 }
190+ Binding on replyTo {
191+ when: identityInput.active
192+ value: loader.item.replyTo
193+ }
194 }
195
196 // For now let's just create seperate ones
197diff --git a/src/3rdParty/trojita/Common/SettingsNames.cpp b/src/3rdParty/trojita/Common/SettingsNames.cpp
198index 8b803bc..ce7286b 100644
199--- a/src/3rdParty/trojita/Common/SettingsNames.cpp
200+++ b/src/3rdParty/trojita/Common/SettingsNames.cpp
201@@ -29,6 +29,7 @@ const QString SettingsNames::realNameKey = QLatin1String("realName");
202 const QString SettingsNames::addressKey = QLatin1String("address");
203 const QString SettingsNames::organisationKey = QLatin1String("organisation");
204 const QString SettingsNames::signatureKey = QLatin1String("signature");
205+const QString SettingsNames::replyToKey = QLatin1String("replyTo");
206 const QString SettingsNames::obsRealNameKey = QLatin1String("identity.realName");
207 const QString SettingsNames::obsAddressKey = QLatin1String("identity.address");
208 const QString SettingsNames::msaMethodKey = QLatin1String("msa.method");
209diff --git a/src/3rdParty/trojita/Common/SettingsNames.h b/src/3rdParty/trojita/Common/SettingsNames.h
210index 1a47a70..7a52e40 100644
211--- a/src/3rdParty/trojita/Common/SettingsNames.h
212+++ b/src/3rdParty/trojita/Common/SettingsNames.h
213@@ -28,7 +28,7 @@ namespace Common
214 {
215
216 struct SettingsNames {
217- static const QString identitiesKey, realNameKey, addressKey, organisationKey, signatureKey, obsRealNameKey, obsAddressKey;
218+ static const QString identitiesKey, realNameKey, addressKey, organisationKey, signatureKey, replyToKey, obsRealNameKey, obsAddressKey;
219 static const QString msaMethodKey, methodSMTP, methodSSMTP, methodSENDMAIL, methodImapSendmail, smtpHostKey,
220 smtpPortKey, smtpAuthKey, smtpStartTlsKey, smtpUserKey,
221 sendmailKey, sendmailDefaultCmd;
222diff --git a/src/app/Accounts/SenderIdentity.cpp b/src/app/Accounts/SenderIdentity.cpp
223index aa293ac..0a98a82 100644
224--- a/src/app/Accounts/SenderIdentity.cpp
225+++ b/src/app/Accounts/SenderIdentity.cpp
226@@ -85,6 +85,20 @@ void SenderIdentity::setSignature(const QString &signature)
227 emit dataChanged();
228 }
229
230+QString SenderIdentity::replyTo() const
231+{
232+ return m_replyTo;
233+}
234+
235+void SenderIdentity::setReplyTo(const QString &replyTo)
236+{
237+ if (replyTo == m_replyTo) {
238+ return;
239+ }
240+ m_replyTo = replyTo;
241+ emit dataChanged();
242+}
243+
244 QString SenderIdentity::getDefaultSignature() const
245 {
246 return QString(tr("Sent using Dekko from my Ubuntu device"));
247diff --git a/src/app/Accounts/SenderIdentity.h b/src/app/Accounts/SenderIdentity.h
248index 0b814e0..a3ce49c 100644
249--- a/src/app/Accounts/SenderIdentity.h
250+++ b/src/app/Accounts/SenderIdentity.h
251@@ -38,6 +38,7 @@ class SenderIdentity : public QObject
252 Q_PROPERTY(QString email READ email WRITE setEmail NOTIFY dataChanged)
253 Q_PROPERTY(QString organization READ organization WRITE setOrganization NOTIFY dataChanged)
254 Q_PROPERTY(QString signature READ signature WRITE setSignature NOTIFY dataChanged)
255+ Q_PROPERTY(QString replyTo READ replyTo WRITE setReplyTo NOTIFY dataChanged)
256 Q_PROPERTY(bool useDefaultSignature READ useDefaultSignature WRITE setUseDefaultSignature NOTIFY dataChanged)
257 public:
258 /*!
259@@ -113,6 +114,20 @@ public:
260 /*!
261 \brief
262
263+ \fn replyTo
264+ \return QString
265+ */
266+ QString replyTo() const;
267+ /*!
268+ \breif
269+
270+ \fn setReplyTo
271+ \param replyTo
272+ */
273+ void setReplyTo(const QString &replyTo);
274+ /*!
275+ \brief
276+
277 \fn useDefaultSignature
278 \return bool
279 */
280@@ -146,6 +161,7 @@ private:
281 QString m_email; /*!< TODO */
282 QString m_organization; /*!< TODO */
283 QString m_signature; /*!< TODO */
284+ QString m_replyTo;
285 bool m_useDefaultSignature; /*!< TODO */
286
287 /*!
288diff --git a/src/app/Accounts/SenderIdentityModel.cpp b/src/app/Accounts/SenderIdentityModel.cpp
289index 5dbfae4..7e4bcc8 100644
290--- a/src/app/Accounts/SenderIdentityModel.cpp
291+++ b/src/app/Accounts/SenderIdentityModel.cpp
292@@ -56,6 +56,7 @@ void SenderIdentityModel::reloadIdentities()
293 identity->setOrganization(settings.value(Common::SettingsNames::organisationKey).toString());
294 identity->setUseDefaultSignature(settings.value("useDefaultSignature", true).toBool());
295 identity->setSignature(settings.value(Common::SettingsNames::signatureKey).toString());
296+ identity->setReplyTo(settings.value(Common::SettingsNames::replyToKey).toString());
297 appendRow(identity);
298 }
299 settings.endArray();
300@@ -75,6 +76,7 @@ void SenderIdentityModel::saveIdentites()
301 settings.setValue(Common::SettingsNames::organisationKey, m_identities[i]->organization());
302 settings.setValue("useDefaultSignature", m_identities[i]->useDefaultSignature());
303 settings.setValue(Common::SettingsNames::signatureKey, m_identities[i]->signature());
304+ settings.setValue(Common::SettingsNames::replyToKey, m_identities[i]->replyTo());
305 }
306 settings.endArray();
307 settings.endGroup();
308@@ -87,6 +89,7 @@ QHash<int, QByteArray> SenderIdentityModel::roleNames() const
309 roles[IdentityEmailRole] = "email";
310 roles[IdentityOrganizationRole] = "organization";
311 roles[IdentitySignatureRole] = "signature";
312+ roles[IdentityReplyToRole] = "replyTo";
313 roles[IdentityRecipientStringRole] = "formattedString";
314 roles[IdentityUseDefaultSignature] = "useDefaultSignature";
315 return roles;
316@@ -106,6 +109,8 @@ QVariant SenderIdentityModel::data(const QModelIndex &index, int role) const
317 return m_identities[index.row()]->organization();
318 case IdentitySignatureRole:
319 return m_identities[index.row()]->signature();
320+ case IdentityReplyToRole:
321+ return m_identities[index.row()]->replyTo();
322 case IdentityUseDefaultSignature:
323 return m_identities[index.row()]->useDefaultSignature();
324 case IdentityRecipientStringRole:
325@@ -173,6 +178,7 @@ QVariant SenderIdentityModel::get(int index)
326 identityData.insert(QString("email"), identity->email());
327 identityData.insert(QString("organization"), identity->organization());
328 identityData.insert(QString("signature"), identity->signature());
329+ identityData.insert(QString("replyTo"), identity->replyTo());
330 identityData.insert(QString("formattedString"), identity->toFormattedString());
331 identityData.insert(QString("useDefaultSignature"), identity->useDefaultSignature());
332 return identityData;
333@@ -202,6 +208,9 @@ bool SenderIdentityModel::setData(const QModelIndex &index, const QVariant &valu
334 case IdentitySignatureRole:
335 m_identities[index.row()]->setSignature(value.toString());
336 break;
337+ case IdentityReplyToRole:
338+ m_identities[index.row()]->setReplyTo(value.toString());
339+ break;
340 case IdentityUseDefaultSignature:
341 m_identities[index.row()]->setUseDefaultSignature(value.toBool());
342 break;
343diff --git a/src/app/Accounts/SenderIdentityModel.h b/src/app/Accounts/SenderIdentityModel.h
344index 08544f8..dbaaf5e 100644
345--- a/src/app/Accounts/SenderIdentityModel.h
346+++ b/src/app/Accounts/SenderIdentityModel.h
347@@ -63,6 +63,7 @@ public:
348 IdentityEmailRole,
349 IdentityOrganizationRole,
350 IdentitySignatureRole,
351+ IdentityReplyToRole,
352 IdentityUseDefaultSignature,
353 IdentityRecipientStringRole
354 };
355diff --git a/src/app/Settings/SettingsNames.cpp b/src/app/Settings/SettingsNames.cpp
356index f457612..720c66a 100644
357--- a/src/app/Settings/SettingsNames.cpp
358+++ b/src/app/Settings/SettingsNames.cpp
359@@ -7,6 +7,7 @@ const QString SettingsNames::realNameKey = QLatin1String("realName");
360 const QString SettingsNames::addressKey = QLatin1String("address");
361 const QString SettingsNames::organisationKey = QLatin1String("organisation");
362 const QString SettingsNames::signatureKey = QLatin1String("signature");
363+const QString SettingsNames::replyToKey = QLatin1String("replyTo");
364 const QString SettingsNames::obsRealNameKey = QLatin1String("identity.realName");
365 const QString SettingsNames::obsAddressKey = QLatin1String("identity.address");
366 const QString SettingsNames::msaMethodKey = QLatin1String("msa.method");
367diff --git a/src/app/Settings/SettingsNames.h b/src/app/Settings/SettingsNames.h
368index 28f4260..12ed3e0 100644
369--- a/src/app/Settings/SettingsNames.h
370+++ b/src/app/Settings/SettingsNames.h
371@@ -6,7 +6,7 @@
372 namespace Dekko {
373
374 struct SettingsNames {
375- static const QString identitiesKey, realNameKey, addressKey, organisationKey, signatureKey, obsRealNameKey, obsAddressKey;
376+ static const QString identitiesKey, realNameKey, addressKey, organisationKey, signatureKey, replyToKey, obsRealNameKey, obsAddressKey;
377 static const QString msaMethodKey, methodSMTP, methodSSMTP, methodSENDMAIL, methodImapSendmail, smtpHostKey,
378 smtpPortKey, smtpAuthKey, smtpStartTlsKey, smtpUserKey, smtpAuthType,
379 sendmailKey, sendmailDefaultCmd;

Subscribers

People subscribed via source and target branches