Akonadi Contacts

addresslocationwidget.cpp
1/*
2 This file is part of Contact Editor.
3
4 SPDX-FileCopyrightText: 2016 eyeOS S.L.U., a Telefonica company, sales@eyeos.com
5 SPDX-FileCopyrightText: 2016-2025 Laurent Montel <montel@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.0-or-later
8*/
9
10#include "addresslocationwidget.h"
11#include "selectaddresstypecombobox.h"
12
13#include <KComboBox>
14#include <KLineEdit>
15#include <KLocalizedString>
16#include <KMessageBox>
17
18#include <KCountry>
19#include <QCheckBox>
20#include <QLabel>
21#include <QPushButton>
22#include <QStackedWidget>
23#include <QVBoxLayout>
24
25using namespace Akonadi;
26
27AddressLocationWidget::AddressLocationWidget(QWidget *parent)
28 : QWidget(parent)
29 , mCurrentMode(CreateAddress)
30{
31 auto topLayout = new QVBoxLayout(this);
32
33 auto gridLayout = new QGridLayout;
34 topLayout->addLayout(gridLayout);
35
36 mTypeCombo = new SelectAddressTypeComboBox(this);
37 mTypeCombo->setObjectName(QLatin1StringView("typeaddress"));
38 connect(mTypeCombo, &SelectAddressTypeComboBox::textHighlighted, this, &AddressLocationWidget::slotChanged);
39 gridLayout->addWidget(mTypeCombo, 0, 0, 1, 2);
40
42 label->setObjectName(QLatin1StringView("streetlabel"));
43 gridLayout->addWidget(label, 1, 0);
44
45 mStreetEdit = new KLineEdit(this);
46 mStreetEdit->setPlaceholderText(i18nc("@info:placeholder", "Add Street"));
47 mStreetEdit->setObjectName(QLatin1StringView("streetlineedit"));
48 mStreetEdit->setTrapReturnKey(true);
49 connect(mStreetEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
50 gridLayout->addWidget(mStreetEdit, 2, 0);
51
53 label->setObjectName(QLatin1StringView("postofficeboxlabel"));
54 gridLayout->addWidget(label, 1, 1);
55
56 mPOBoxEdit = new KLineEdit(this);
57 mPOBoxEdit->setPlaceholderText(i18nc("@info:placeholder", "Add Post Office Box"));
58 mPOBoxEdit->setObjectName(QLatin1StringView("postofficeboxlineedit"));
59 mPOBoxEdit->setTrapReturnKey(true);
60 connect(mPOBoxEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
61 gridLayout->addWidget(mPOBoxEdit, 2, 1);
62
64 label->setObjectName(QLatin1StringView("postalcodelabel"));
65 gridLayout->addWidget(label, 3, 0);
66 mPostalCodeEdit = new KLineEdit(this);
67 mPostalCodeEdit->setPlaceholderText(i18nc("@info:placeholder", "Add Postal Code"));
68 mPostalCodeEdit->setObjectName(QLatin1StringView("postalcodelineedit"));
69 mPostalCodeEdit->setTrapReturnKey(true);
70 connect(mPostalCodeEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
71 gridLayout->addWidget(mPostalCodeEdit, 4, 0);
72
74 label->setObjectName(QLatin1StringView("localitylabel"));
75 gridLayout->addWidget(label, 3, 1);
76 mLocalityEdit = new KLineEdit(this);
77 mLocalityEdit->setPlaceholderText(i18nc("@info:placeholder", "Add Locality"));
78 mLocalityEdit->setObjectName(QLatin1StringView("localitylineedit"));
79 mLocalityEdit->setTrapReturnKey(true);
80 connect(mLocalityEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
81 gridLayout->addWidget(mLocalityEdit, 4, 1);
82
84 label->setObjectName(QLatin1StringView("regionlabel"));
85 gridLayout->addWidget(label, 5, 0);
86 mRegionEdit = new KLineEdit(this);
87 mRegionEdit->setPlaceholderText(i18nc("@info:placeholder", "Add Region"));
88 mRegionEdit->setObjectName(QLatin1StringView("regionlineedit"));
89 mRegionEdit->setTrapReturnKey(true);
90 connect(mRegionEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
91 gridLayout->addWidget(mRegionEdit, 6, 0);
92
94 label->setObjectName(QLatin1StringView("countrylabel"));
95 gridLayout->addWidget(label, 5, 1);
96 mCountryCombo = new QComboBox(this);
97 mCountryCombo->setObjectName(QLatin1StringView("countrycombobox"));
98 mCountryCombo->setEditable(false);
99 mCountryCombo->setDuplicatesEnabled(false);
100 connect(mCountryCombo, &KComboBox::textHighlighted, this, &AddressLocationWidget::slotChanged);
101 gridLayout->addWidget(mCountryCombo, 6, 1);
102
103 mPreferredCheckBox = new QCheckBox(i18nc("street/postal", "This is the preferred address"), this);
104 mPreferredCheckBox->setObjectName(QLatin1StringView("preferredcheckbox"));
105 gridLayout->addWidget(mPreferredCheckBox, 7, 0, 1, 2);
106
107 mButtonStack = new QStackedWidget(this);
108 mButtonStack->setObjectName(QLatin1StringView("buttonstacked"));
109 topLayout->addWidget(mButtonStack);
110
111 auto addButtonWidget = new QWidget(this);
112 auto addButtonWidgetLayout = new QHBoxLayout(addButtonWidget);
113 addButtonWidgetLayout->setContentsMargins({});
114 mAddAddress = new QPushButton(i18nc("@action:button", "Add Address"), this);
115 mAddAddress->setObjectName(QLatin1StringView("addbuttonaddress"));
116 connect(mAddAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotAddAddress);
117 addButtonWidgetLayout->addWidget(mAddAddress);
118 addButtonWidgetLayout->addStretch(1);
119 mButtonStack->addWidget(addButtonWidget);
120
121 auto modifyButtonWidget = new QWidget(this);
122 auto modifyButtonWidgetLayout = new QHBoxLayout(modifyButtonWidget);
123 modifyButtonWidgetLayout->setContentsMargins({});
124 mButtonStack->addWidget(modifyButtonWidget);
125
126 mRemoveAddress = new QPushButton(i18nc("@action:button", "Remove Address"), this);
127 mRemoveAddress->setObjectName(QLatin1StringView("removebuttonaddress"));
128 modifyButtonWidgetLayout->addWidget(mRemoveAddress);
129 connect(mRemoveAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotRemoveAddress);
130
131 mModifyAddress = new QPushButton(i18nc("@action:button", "Update Address"), this);
132 mModifyAddress->setObjectName(QLatin1StringView("modifybuttonaddress"));
133 modifyButtonWidgetLayout->addWidget(mModifyAddress);
134 connect(mModifyAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotUpdateAddress);
135
136 mCancelAddress = new QPushButton(i18nc("@action:button", "Cancel"), this);
137 mCancelAddress->setObjectName(QLatin1StringView("cancelbuttonaddress"));
138 connect(mCancelAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotCancelModifyAddress);
139 modifyButtonWidgetLayout->addWidget(mCancelAddress);
140 modifyButtonWidgetLayout->addStretch(1);
141 const int buttonWidth = qMax(mCancelAddress->width(), mModifyAddress->width());
142 mModifyAddress->setMinimumWidth(buttonWidth);
143 mCancelAddress->setMinimumWidth(buttonWidth);
144
145 topLayout->addStretch(1);
146 fillCountryCombo();
147 switchMode();
148 mWasChanged = false;
149}
150
151AddressLocationWidget::~AddressLocationWidget() = default;
152
153void AddressLocationWidget::slotChanged()
154{
155 mWasChanged = true;
156}
157
158bool AddressLocationWidget::wasChanged() const
159{
160 return mWasChanged;
161}
162
163void AddressLocationWidget::setReadOnly(bool readOnly)
164{
165 mPreferredCheckBox->setEnabled(!readOnly);
166 mPOBoxEdit->setReadOnly(readOnly);
167 mLocalityEdit->setReadOnly(readOnly);
168 mRegionEdit->setReadOnly(readOnly);
169 mPostalCodeEdit->setReadOnly(readOnly);
170 mStreetEdit->setReadOnly(readOnly);
171 mCountryCombo->setEnabled(!readOnly);
172 mTypeCombo->setEnabled(!readOnly);
173
174 mAddAddress->setEnabled(!readOnly);
175 mModifyAddress->setEnabled(!readOnly);
176 mCancelAddress->setEnabled(!readOnly);
177}
178
179void AddressLocationWidget::fillCountryCombo()
180{
181 QStringList countries;
182 for (const auto &country : KCountry::allCountries()) {
183 countries.append(country.name());
184 }
185
186 mCountryCombo->addItems(countries);
187
188 const QString currentCountry = QLocale::territoryToString(QLocale().territory());
189 mCountryCombo->setCurrentIndex(mCountryCombo->findText(currentCountry));
190}
191
192void AddressLocationWidget::slotAddAddress()
193{
194 const KContacts::Address addr = address();
195 if (!mLocalityEdit->text().trimmed().isEmpty() || !mRegionEdit->text().trimmed().isEmpty() || !mPostalCodeEdit->text().trimmed().isEmpty()
196 || !mStreetEdit->text().trimmed().isEmpty() || !mPOBoxEdit->text().trimmed().isEmpty()) {
197 Q_EMIT addNewAddress(addr);
198 reset();
199 }
200}
201
202void AddressLocationWidget::setAddress(const KContacts::Address &address)
203{
204 mAddress = address;
205 mTypeCombo->setType(mAddress.type());
206 mStreetEdit->setText(mAddress.street());
207 mRegionEdit->setText(address.region());
208 mLocalityEdit->setText(address.locality());
209 mPostalCodeEdit->setText(address.postalCode());
210 mPOBoxEdit->setText(address.postOfficeBox());
211 mPreferredCheckBox->setChecked(address.type() & KContacts::Address::Pref);
212 if (address.isEmpty()) {
213 mCountryCombo->setItemText(mCountryCombo->currentIndex(), QLocale::territoryToString(QLocale().territory()));
214 } else {
215 mCountryCombo->setItemText(mCountryCombo->currentIndex(), mAddress.country());
216 }
217}
218
219KContacts::Address AddressLocationWidget::address() const
220{
221 KContacts::Address address(mAddress);
222
223 address.setType(mTypeCombo->type());
224 address.setLocality(mLocalityEdit->text());
225 address.setRegion(mRegionEdit->text());
226 address.setPostalCode(mPostalCodeEdit->text());
227 address.setCountry(mCountryCombo->currentText());
228 address.setPostOfficeBox(mPOBoxEdit->text());
229 address.setStreet(mStreetEdit->text());
230 if (mPreferredCheckBox->isChecked()) {
231 address.setType(address.type() | KContacts::Address::Pref);
232 } else {
233 address.setType(address.type() & ~(KContacts::Address::Pref));
234 }
235 return address;
236}
237
238void AddressLocationWidget::switchMode()
239{
240 switch (mCurrentMode) {
241 case CreateAddress:
242 mButtonStack->setCurrentIndex(0);
243 break;
244 case ModifyAddress:
245 mButtonStack->setCurrentIndex(1);
246 break;
247 }
248}
249
250void AddressLocationWidget::slotModifyAddress(const KContacts::Address &address, int currentIndex)
251{
252 setAddress(address);
253 mCurrentMode = ModifyAddress;
254 mCurrentAddress = currentIndex;
255 switchMode();
256}
257
258void AddressLocationWidget::clear()
259{
260 mCurrentMode = CreateAddress;
261 setAddress(KContacts::Address());
262 switchMode();
263}
264
265void AddressLocationWidget::slotUpdateAddress()
266{
267 if (mCurrentMode == ModifyAddress) {
268 Q_EMIT updateAddress(address(), mCurrentAddress);
269 reset();
270 }
271}
272
273void AddressLocationWidget::slotRemoveAddress()
274{
275 if (mCurrentMode == ModifyAddress) {
276 const auto result = KMessageBox::questionTwoActions(this,
277 i18n("Do you really want to delete this address?"),
278 QString(),
281 if (result == KMessageBox::ButtonCode::PrimaryAction) {
282 Q_EMIT removeAddress(mCurrentAddress);
283 reset();
284 }
285 }
286}
287
288void AddressLocationWidget::reset()
289{
290 Q_EMIT updateAddressCanceled();
291 mCurrentAddress = -1;
292 mWasChanged = false;
293 clear();
294}
295
296void AddressLocationWidget::slotCancelModifyAddress()
297{
298 reset();
299}
300
301#include "moc_addresslocationwidget.cpp"
A widget for selecting the type of an address.
static QString streetLabel()
static QString countryLabel()
static QString regionLabel()
static QString postalCodeLabel()
static QString postOfficeBoxLabel()
static QString localityLabel()
static QList< KCountry > allCountries()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
A widget for editing the display name of a contact.
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
QStringView country(QStringView ifopt)
KGuiItem cancel()
KGuiItem del()
QString label(StandardShortcut id)
void clicked(bool checked)
void textHighlighted(const QString &text)
void addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment)
void editingFinished()
void append(QList< T > &&value)
QString territoryToString(Territory territory)
Q_EMITQ_EMIT
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:55:33 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.