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 KComboBox(this);
96  auto edit = new KLineEdit(this);
97  edit->setTrapReturnKey(true);
98  mCountryCombo->setLineEdit(edit);
99  mCountryCombo->setObjectName(QStringLiteral("countrycombobox"));
100  mCountryCombo->setEditable(true);
101  mCountryCombo->lineEdit()->setPlaceholderText(i18n("Add a Country"));
102  mCountryCombo->setDuplicatesEnabled(false);
103  connect(mCountryCombo, &KComboBox::textHighlighted, this, &AddressLocationWidget::slotChanged);
104  gridLayout->addWidget(mCountryCombo, 6, 1);
105 
106  mPreferredCheckBox = new QCheckBox(i18nc("street/postal", "This is the preferred address"), this);
107  mPreferredCheckBox->setObjectName(QStringLiteral("preferredcheckbox"));
108  gridLayout->addWidget(mPreferredCheckBox, 7, 0, 1, 2);
109 
110  mButtonStack = new QStackedWidget(this);
111  mButtonStack->setObjectName(QStringLiteral("buttonstacked"));
112  topLayout->addWidget(mButtonStack);
113 
114  auto addButtonWidget = new QWidget(this);
115  auto addButtonWidgetLayout = new QHBoxLayout(addButtonWidget);
116  addButtonWidgetLayout->setContentsMargins(0, 0, 0, 0);
117  mAddAddress = new QPushButton(i18n("Add Address"), this);
118  mAddAddress->setObjectName(QStringLiteral("addbuttonaddress"));
119  connect(mAddAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotAddAddress);
120  addButtonWidgetLayout->addWidget(mAddAddress);
121  addButtonWidgetLayout->addStretch(1);
122  mButtonStack->addWidget(addButtonWidget);
123 
124  auto modifyButtonWidget = new QWidget(this);
125  auto modifyButtonWidgetLayout = new QHBoxLayout(modifyButtonWidget);
126  modifyButtonWidgetLayout->setContentsMargins(0, 0, 0, 0);
127  mButtonStack->addWidget(modifyButtonWidget);
128 
129  mRemoveAddress = new QPushButton(i18n("Remove Address"), this);
130  mRemoveAddress->setObjectName(QStringLiteral("removebuttonaddress"));
131  modifyButtonWidgetLayout->addWidget(mRemoveAddress);
132  connect(mRemoveAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotRemoveAddress);
133 
134  mModifyAddress = new QPushButton(i18n("Update Address"), this);
135  mModifyAddress->setObjectName(QStringLiteral("modifybuttonaddress"));
136  modifyButtonWidgetLayout->addWidget(mModifyAddress);
137  connect(mModifyAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotUpdateAddress);
138 
139  mCancelAddress = new QPushButton(i18n("Cancel"), this);
140  mCancelAddress->setObjectName(QStringLiteral("cancelbuttonaddress"));
141  connect(mCancelAddress, &QPushButton::clicked, this, &AddressLocationWidget::slotCancelModifyAddress);
142  modifyButtonWidgetLayout->addWidget(mCancelAddress);
143  modifyButtonWidgetLayout->addStretch(1);
144  const int buttonWidth = qMax(mCancelAddress->width(), mModifyAddress->width());
145  mModifyAddress->setMinimumWidth(buttonWidth);
146  mCancelAddress->setMinimumWidth(buttonWidth);
147 
148  topLayout->addStretch(1);
149  fillCountryCombo();
150  switchMode();
151 }
152 
153 AddressLocationWidget::~AddressLocationWidget()
154 {
155 }
156 
157 void AddressLocationWidget::slotChanged()
158 {
159  mWasChanged = true;
160 }
161 
162 bool AddressLocationWidget::wasChanged() const
163 {
164  return mWasChanged;
165 }
166 
167 void AddressLocationWidget::setReadOnly(bool readOnly)
168 {
169  mPreferredCheckBox->setEnabled(!readOnly);
170  mPOBoxEdit->setReadOnly(readOnly);
171  mLocalityEdit->setReadOnly(readOnly);
172  mRegionEdit->setReadOnly(readOnly);
173  mPostalCodeEdit->setReadOnly(readOnly);
174  mStreetEdit->setReadOnly(readOnly);
175  mCountryCombo->setEnabled(!readOnly);
176  mTypeCombo->setEnabled(!readOnly);
177 
178  mAddAddress->setEnabled(!readOnly);
179  mModifyAddress->setEnabled(!readOnly);
180  mCancelAddress->setEnabled(!readOnly);
181 }
182 
183 void AddressLocationWidget::fillCountryCombo()
184 {
185  QStringList countries;
187  countries.reserve(localeList.count());
188  for (const QLocale &locale : localeList) {
189  const QString localeStr = QLocale::countryToString(locale.country());
190  if (countries.contains(localeStr)) {
191  continue;
192  }
193  countries.append(localeStr);
194  }
195 
196  std::sort(countries.begin(), countries.end(), [](const auto &s1, const auto &s2) {
197  return QString::localeAwareCompare(s1, s2) < 0;
198  });
199 
200  mCountryCombo->addItems(countries);
201  mCountryCombo->setAutoCompletion(true);
202  mCountryCombo->completionObject()->setItems(countries);
203  mCountryCombo->completionObject()->setIgnoreCase(true);
204 
205  const QString currentCountry = QLocale::countryToString(QLocale().country());
206  mCountryCombo->setCurrentIndex(mCountryCombo->findText(currentCountry));
207 }
208 
209 void AddressLocationWidget::slotAddAddress()
210 {
211  KContacts::Address addr = address();
212  if (!addr.isEmpty()) {
213  Q_EMIT addNewAddress(addr);
214  reset();
215  }
216 }
217 
218 void AddressLocationWidget::setAddress(const KContacts::Address &address)
219 {
220  mAddress = address;
221  mTypeCombo->setType(mAddress.type());
222  mStreetEdit->setText(mAddress.street());
223  mRegionEdit->setText(address.region());
224  mLocalityEdit->setText(address.locality());
225  mPostalCodeEdit->setText(address.postalCode());
226  mPOBoxEdit->setText(address.postOfficeBox());
227  mPreferredCheckBox->setChecked(address.type() & KContacts::Address::Pref);
228  if (address.isEmpty()) {
229  mCountryCombo->setItemText(mCountryCombo->currentIndex(), QLocale::countryToString(QLocale().country()));
230  } else {
231  mCountryCombo->setItemText(mCountryCombo->currentIndex(), mAddress.country());
232  }
233 }
234 
235 KContacts::Address AddressLocationWidget::address() const
236 {
237  KContacts::Address address(mAddress);
238 
239  address.setType(mTypeCombo->type());
240  address.setLocality(mLocalityEdit->text());
241  address.setRegion(mRegionEdit->text());
242  address.setPostalCode(mPostalCodeEdit->text());
243  address.setCountry(mCountryCombo->currentText());
244  address.setPostOfficeBox(mPOBoxEdit->text());
245  address.setStreet(mStreetEdit->text());
246  if (mPreferredCheckBox->isChecked()) {
247  address.setType(address.type() | KContacts::Address::Pref);
248  } else {
249  address.setType(address.type() & ~(KContacts::Address::Pref));
250  }
251  return address;
252 }
253 
254 void AddressLocationWidget::switchMode()
255 {
256  switch (mCurrentMode) {
257  case CreateAddress:
258  mButtonStack->setCurrentIndex(0);
259  break;
260  case ModifyAddress:
261  mButtonStack->setCurrentIndex(1);
262  break;
263  }
264 }
265 
266 void AddressLocationWidget::slotModifyAddress(const KContacts::Address &address, int currentIndex)
267 {
268  setAddress(address);
269  mCurrentMode = ModifyAddress;
270  mCurrentAddress = currentIndex;
271  switchMode();
272 }
273 
274 void AddressLocationWidget::clear()
275 {
276  mCurrentMode = CreateAddress;
277  setAddress(KContacts::Address());
278  switchMode();
279 }
280 
281 void AddressLocationWidget::slotUpdateAddress()
282 {
283  if (mCurrentMode == ModifyAddress) {
284  Q_EMIT updateAddress(address(), mCurrentAddress);
285  reset();
286  }
287 }
288 
289 void AddressLocationWidget::slotRemoveAddress()
290 {
291  if (mCurrentMode == ModifyAddress) {
292  const auto result = KMessageBox::questionYesNo(this, i18n("Do you really want to delete this address?"));
293  if (result == KMessageBox::Yes) {
294  Q_EMIT removeAddress(mCurrentAddress);
295  reset();
296  }
297  }
298 }
299 
300 void AddressLocationWidget::reset()
301 {
302  Q_EMIT updateAddressCanceled();
303  mCurrentAddress = -1;
304  mWasChanged = false;
305  clear();
306 }
307 
308 void AddressLocationWidget::slotCancelModifyAddress()
309 {
310  reset();
311 }
QStringView country(QStringView ifopt)
QString region() const
void setLocality(const QString &locality)
int localeAwareCompare(const QString &other) const const
static QString localityLabel()
void reserve(int alloc)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
void setStreet(const QString &street)
void setType(Type type)
static QString postalCodeLabel()
int count(const T &value) const const
void append(const T &value)
PostalAddress address(const QVariant &location)
QString postOfficeBox() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QList< QLocale > matchingLocales(QLocale::Language language, QLocale::Script script, QLocale::Country country)
QString label(StandardShortcut id)
void clicked(bool checked)
void setRegion(const QString &region)
QString postalCode() const
Type type() const
QString locality() const
ButtonCode questionYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Notify)
QList::iterator end()
static QString postOfficeBoxLabel()
void setPostalCode(const QString &code)
QString i18n(const char *text, const TYPE &arg...)
void addLayout(QLayout *layout, int row, int column, Qt::Alignment alignment)
static QString streetLabel()
static QString regionLabel()
void textHighlighted(const QString &text)
void setPostOfficeBox(const QString &postOfficeBox)
void setCountry(const QString &country)
bool isEmpty() const
static QString countryLabel()
QString countryToString(QLocale::Country country)
void editingFinished()
KGuiItem reset()
void result(KJob *job)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
LocaleWrapper locale()
QList::iterator begin()
Q_EMITQ_EMIT
A widget for selecting the type of an address.
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jun 23 2021 23:09:24 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.