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, [email protected]
5  SPDX-FileCopyrightText: 2016-2020 Laurent Montel <montel.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 <QCheckBox>
19 #include <QLabel>
20 #include <QPushButton>
21 #include <QStackedWidget>
22 #include <QVBoxLayout>
23 
24 using namespace ContactEditor;
25 
26 AddressLocationWidget::AddressLocationWidget(QWidget *parent)
27  : QWidget(parent)
28  , mCurrentMode(CreateAddress)
29 {
30  auto topLayout = new QVBoxLayout(this);
31 
32  auto gridLayout = new QGridLayout;
33  topLayout->addLayout(gridLayout);
34 
35  mTypeCombo = new SelectAddressTypeComboBox(this);
36  mTypeCombo->setObjectName(QStringLiteral("typeaddress"));
37  connect(mTypeCombo, &SelectAddressTypeComboBox::textHighlighted, this, &AddressLocationWidget::slotChanged);
38  gridLayout->addWidget(mTypeCombo, 0, 0, 1, 2);
39 
40  auto label = new QLabel(KContacts::Address::streetLabel(), this);
41  label->setObjectName(QStringLiteral("streetlabel"));
42  gridLayout->addWidget(label, 1, 0);
43 
44  mStreetEdit = new KLineEdit(this);
45  mStreetEdit->setPlaceholderText(i18n("Add Street"));
46  mStreetEdit->setObjectName(QStringLiteral("streetlineedit"));
47  mStreetEdit->setTrapReturnKey(true);
48  connect(mStreetEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
49  gridLayout->addWidget(mStreetEdit, 2, 0);
50 
52  label->setObjectName(QStringLiteral("postofficeboxlabel"));
53  gridLayout->addWidget(label, 1, 1);
54 
55  mPOBoxEdit = new KLineEdit(this);
56  mPOBoxEdit->setPlaceholderText(i18n("Add Post Office Box"));
57  mPOBoxEdit->setObjectName(QStringLiteral("postofficeboxlineedit"));
58  mPOBoxEdit->setTrapReturnKey(true);
59  connect(mPOBoxEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
60  gridLayout->addWidget(mPOBoxEdit, 2, 1);
61 
63  label->setObjectName(QStringLiteral("postalcodelabel"));
64  gridLayout->addWidget(label, 3, 0);
65  mPostalCodeEdit = new KLineEdit(this);
66  mPostalCodeEdit->setPlaceholderText(i18n("Add Postal Code"));
67  mPostalCodeEdit->setObjectName(QStringLiteral("postalcodelineedit"));
68  mPostalCodeEdit->setTrapReturnKey(true);
69  connect(mPostalCodeEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
70  gridLayout->addWidget(mPostalCodeEdit, 4, 0);
71 
73  label->setObjectName(QStringLiteral("localitylabel"));
74  gridLayout->addWidget(label, 3, 1);
75  mLocalityEdit = new KLineEdit(this);
76  mLocalityEdit->setPlaceholderText(i18n("Add Locality"));
77  mLocalityEdit->setObjectName(QStringLiteral("localitylineedit"));
78  mLocalityEdit->setTrapReturnKey(true);
79  connect(mLocalityEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
80  gridLayout->addWidget(mLocalityEdit, 4, 1);
81 
83  label->setObjectName(QStringLiteral("regionlabel"));
84  gridLayout->addWidget(label, 5, 0);
85  mRegionEdit = new KLineEdit(this);
86  mRegionEdit->setPlaceholderText(i18n("Add Region"));
87  mRegionEdit->setObjectName(QStringLiteral("regionlineedit"));
88  mRegionEdit->setTrapReturnKey(true);
89  connect(mRegionEdit, &KLineEdit::editingFinished, this, &AddressLocationWidget::slotChanged);
90  gridLayout->addWidget(mRegionEdit, 6, 0);
91 
93  label->setObjectName(QStringLiteral("countrylabel"));
94  gridLayout->addWidget(label, 5, 1);
95  mCountryCombo = new QComboBox(this);
96  mCountryCombo->setObjectName(QStringLiteral("countrycombobox"));
97  mCountryCombo->setEditable(false);
98  mCountryCombo->setDuplicatesEnabled(false);
99  connect(mCountryCombo, &KComboBox::textHighlighted, this, &AddressLocationWidget::slotChanged);
100  gridLayout->addWidget(mCountryCombo, 6, 1);
101 
102  mPreferredCheckBox = new QCheckBox(i18nc("street/postal", "This is the preferred address"), this);
103  mPreferredCheckBox->setObjectName(QStringLiteral("preferredcheckbox"));
104  gridLayout->addWidget(mPreferredCheckBox, 7, 0, 1, 2);
105 
106  mButtonStack = new QStackedWidget(this);
107  mButtonStack->setObjectName(QStringLiteral("buttonstacked"));
108  topLayout->addWidget(mButtonStack);
109 
110  auto addButtonWidget = new QWidget(this);
111  auto addButtonWidgetLayout = new QHBoxLayout(addButtonWidget);
112  addButtonWidgetLayout->setContentsMargins({});
113  mAddAddress = new QPushButton(i18n("Add Address"), this);
114  mAddAddress->setObjectName(QStringLiteral("addbuttonaddress"));
115  connect(mAddAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotAddAddress);
116  addButtonWidgetLayout->addWidget(mAddAddress);
117  addButtonWidgetLayout->addStretch(1);
118  mButtonStack->addWidget(addButtonWidget);
119 
120  auto modifyButtonWidget = new QWidget(this);
121  auto modifyButtonWidgetLayout = new QHBoxLayout(modifyButtonWidget);
122  modifyButtonWidgetLayout->setContentsMargins({});
123  mButtonStack->addWidget(modifyButtonWidget);
124 
125  mRemoveAddress = new QPushButton(i18n("Remove Address"), this);
126  mRemoveAddress->setObjectName(QStringLiteral("removebuttonaddress"));
127  modifyButtonWidgetLayout->addWidget(mRemoveAddress);
128  connect(mRemoveAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotRemoveAddress);
129 
130  mModifyAddress = new QPushButton(i18n("Update Address"), this);
131  mModifyAddress->setObjectName(QStringLiteral("modifybuttonaddress"));
132  modifyButtonWidgetLayout->addWidget(mModifyAddress);
133  connect(mModifyAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotUpdateAddress);
134 
135  mCancelAddress = new QPushButton(i18n("Cancel"), this);
136  mCancelAddress->setObjectName(QStringLiteral("cancelbuttonaddress"));
137  connect(mCancelAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotCancelModifyAddress);
138  modifyButtonWidgetLayout->addWidget(mCancelAddress);
139  modifyButtonWidgetLayout->addStretch(1);
140  const int buttonWidth = qMax(mCancelAddress->width(), mModifyAddress->width());
141  mModifyAddress->setMinimumWidth(buttonWidth);
142  mCancelAddress->setMinimumWidth(buttonWidth);
143 
144  topLayout->addStretch(1);
145  fillCountryCombo();
146  switchMode();
147 }
148 
149 AddressLocationWidget::~AddressLocationWidget() = default;
150 
151 void AddressLocationWidget::slotChanged()
152 {
153  mWasChanged = true;
154 }
155 
156 bool AddressLocationWidget::wasChanged() const
157 {
158  return mWasChanged;
159 }
160 
161 void AddressLocationWidget::setReadOnly(bool readOnly)
162 {
163  mPreferredCheckBox->setEnabled(!readOnly);
164  mPOBoxEdit->setReadOnly(readOnly);
165  mLocalityEdit->setReadOnly(readOnly);
166  mRegionEdit->setReadOnly(readOnly);
167  mPostalCodeEdit->setReadOnly(readOnly);
168  mStreetEdit->setReadOnly(readOnly);
169  mCountryCombo->setEnabled(!readOnly);
170  mTypeCombo->setEnabled(!readOnly);
171 
172  mAddAddress->setEnabled(!readOnly);
173  mModifyAddress->setEnabled(!readOnly);
174  mCancelAddress->setEnabled(!readOnly);
175 }
176 
177 void AddressLocationWidget::fillCountryCombo()
178 {
179  QStringList countries;
181  countries.reserve(localeList.count());
182  for (const QLocale &locale : localeList) {
183  const QString localeStr = QLocale::countryToString(locale.country());
184  if (countries.contains(localeStr)) {
185  continue;
186  }
187  countries.append(localeStr);
188  }
189 
190  std::sort(countries.begin(), countries.end(), [](const auto &s1, const auto &s2) {
191  return QString::localeAwareCompare(s1, s2) < 0;
192  });
193 
194  mCountryCombo->addItems(countries);
195 
196  const QString currentCountry = QLocale::countryToString(QLocale().country());
197  mCountryCombo->setCurrentIndex(mCountryCombo->findText(currentCountry));
198 }
199 
200 void AddressLocationWidget::slotAddAddress()
201 {
202  const KContacts::Address addr = address();
203  if (!mLocalityEdit->text().trimmed().isEmpty() || !mRegionEdit->text().trimmed().isEmpty() || !mPostalCodeEdit->text().trimmed().isEmpty()
204  || !mStreetEdit->text().trimmed().isEmpty() || !mPOBoxEdit->text().trimmed().isEmpty()) {
205  Q_EMIT addNewAddress(addr);
206  reset();
207  }
208 }
209 
210 void AddressLocationWidget::setAddress(const KContacts::Address &address)
211 {
212  mAddress = address;
213  mTypeCombo->setType(mAddress.type());
214  mStreetEdit->setText(mAddress.street());
215  mRegionEdit->setText(address.region());
216  mLocalityEdit->setText(address.locality());
217  mPostalCodeEdit->setText(address.postalCode());
218  mPOBoxEdit->setText(address.postOfficeBox());
219  mPreferredCheckBox->setChecked(address.type() & KContacts::Address::Pref);
220  if (address.isEmpty()) {
221  mCountryCombo->setItemText(mCountryCombo->currentIndex(), QLocale::countryToString(QLocale().country()));
222  } else {
223  mCountryCombo->setItemText(mCountryCombo->currentIndex(), mAddress.country());
224  }
225 }
226 
227 KContacts::Address AddressLocationWidget::address() const
228 {
229  KContacts::Address address(mAddress);
230 
231  address.setType(mTypeCombo->type());
232  address.setLocality(mLocalityEdit->text());
233  address.setRegion(mRegionEdit->text());
234  address.setPostalCode(mPostalCodeEdit->text());
235  address.setCountry(mCountryCombo->currentText());
236  address.setPostOfficeBox(mPOBoxEdit->text());
237  address.setStreet(mStreetEdit->text());
238  if (mPreferredCheckBox->isChecked()) {
239  address.setType(address.type() | KContacts::Address::Pref);
240  } else {
241  address.setType(address.type() & ~(KContacts::Address::Pref));
242  }
243  return address;
244 }
245 
246 void AddressLocationWidget::switchMode()
247 {
248  switch (mCurrentMode) {
249  case CreateAddress:
250  mButtonStack->setCurrentIndex(0);
251  break;
252  case ModifyAddress:
253  mButtonStack->setCurrentIndex(1);
254  break;
255  }
256 }
257 
258 void AddressLocationWidget::slotModifyAddress(const KContacts::Address &address, int currentIndex)
259 {
260  setAddress(address);
261  mCurrentMode = ModifyAddress;
262  mCurrentAddress = currentIndex;
263  switchMode();
264 }
265 
266 void AddressLocationWidget::clear()
267 {
268  mCurrentMode = CreateAddress;
269  setAddress(KContacts::Address());
270  switchMode();
271 }
272 
273 void AddressLocationWidget::slotUpdateAddress()
274 {
275  if (mCurrentMode == ModifyAddress) {
276  Q_EMIT updateAddress(address(), mCurrentAddress);
277  reset();
278  }
279 }
280 
281 void AddressLocationWidget::slotRemoveAddress()
282 {
283  if (mCurrentMode == ModifyAddress) {
284  const auto result = KMessageBox::questionTwoActions(this,
285  i18n("Do you really want to delete this address?"),
286  QString(),
289  if (result == KMessageBox::ButtonCode::PrimaryAction) {
290  Q_EMIT removeAddress(mCurrentAddress);
291  reset();
292  }
293  }
294 }
295 
296 void AddressLocationWidget::reset()
297 {
298  Q_EMIT updateAddressCanceled();
299  mCurrentAddress = -1;
300  mWasChanged = false;
301  clear();
302 }
303 
304 void AddressLocationWidget::slotCancelModifyAddress()
305 {
306  reset();
307 }
void append(const T &value)
static QString localityLabel()
static QString postalCodeLabel()
int count(const T &value) const const
KI18NLOCALEDATA_EXPORT KCountry country(const char *ianaId)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
void clicked(bool checked)
void editingFinished()
void textHighlighted(const QString &text)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void reserve(int alloc)
KGuiItem cancel()
QList< QLocale > matchingLocales(QLocale::Language language, QLocale::Script script, QLocale::Country country)
QString i18n(const char *text, const TYPE &arg...)
static QString streetLabel()
void addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment)
QString countryToString(QLocale::Country country)
PostalAddress address(const QVariant &location)
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
static QString postOfficeBoxLabel()
LocaleWrapper locale()
QString label(StandardShortcut id)
KGuiItem del()
QAction * clear(const QObject *recvr, const char *slot, QObject *parent)
static QString regionLabel()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
KGuiItem reset()
QList::iterator begin()
A widget for selecting the type of an address.
QList::iterator end()
static QString countryLabel()
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sat Apr 1 2023 04:09:04 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.