Libksieve

vacationeditwidget.cpp
1/*
2 SPDX-FileCopyrightText: 2013-2025 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "vacationeditwidget.h"
8#include "vacationmailactionwidget.h"
9#include "vacationmaillineedit.h"
10
11#include <KDateComboBox>
12#include <KLocalizedString>
13#include <KTimeComboBox>
14#include <QLineEdit>
15#include <QRegularExpressionValidator>
16#include <QSpinBox>
17
18#include "libksieveui_debug.h"
19#include <KLineEditEventHandler>
20#include <TextCustomEditor/PlainTextEditor>
21#include <TextCustomEditor/PlainTextEditorWidget>
22
23#include <KMime/HeaderParsing>
24
25#include <PimCommon/SpellCheckLineEdit>
26#include <QCheckBox>
27#include <QGridLayout>
28#include <QLabel>
29
30using KMime::HeaderParsing::parseAddressList;
31using KMime::Types::AddressList;
32using KMime::Types::AddrSpecList;
33
34using namespace KSieveUi;
35VacationEditWidget::VacationEditWidget(QWidget *parent)
36 : QWidget(parent)
37{
38 int row = -1;
39
40 auto glay = new QGridLayout(this);
41 glay->setContentsMargins({});
42 glay->setColumnStretch(1, 1);
43
44 // explanation label:
45 ++row;
46 auto configureVacationLabel = new QLabel(i18nc("@label:textbox",
47 "Configure vacation "
48 "notifications to be sent:"),
49 this);
50 configureVacationLabel->setObjectName(QLatin1StringView("configureVacationLabel"));
51 glay->addWidget(configureVacationLabel, row, 0, 1, 2);
52
53 // Activate checkbox:
54 ++row;
55 mActiveCheck = new QCheckBox(i18nc("@option:check", "&Activate vacation notifications"), this);
56 mActiveCheck->setObjectName(QLatin1StringView("mActiveCheck"));
57 glay->addWidget(mActiveCheck, row, 0, 1, 2);
58 connect(mActiveCheck, &QCheckBox::clicked, this, &VacationEditWidget::setWasChanged);
59
60 // Message text edit:
61 ++row;
62 glay->setRowStretch(row, 1);
63 mTextEdit = new TextCustomEditor::PlainTextEditorWidget(this);
64 mTextEdit->setObjectName(QLatin1StringView("mTextEdit"));
65 glay->addWidget(mTextEdit, row, 0, 1, 2);
66 connect(mTextEdit->editor(), &TextCustomEditor::PlainTextEditor::textChanged, this, &VacationEditWidget::setWasChanged);
67
68 // Subject
69 ++row;
70 mSubject = new PimCommon::SpellCheckLineEdit(this, QString());
72 mSubject->setObjectName(QLatin1StringView("mSubject"));
73 connect(mSubject, &PimCommon::SpellCheckLineEdit::textChanged, this, &VacationEditWidget::setWasChanged);
74 // mSubject->setClearButtonEnabled(true);
75 auto subjectOfVacationLabel = new QLabel(i18nc("@label:textbox", "&Subject of the vacation mail:"), this);
76 subjectOfVacationLabel->setObjectName(QLatin1StringView("subjectOfVacationLabel"));
77 subjectOfVacationLabel->setBuddy(mSubject);
78 glay->addWidget(subjectOfVacationLabel, row, 0);
79 glay->addWidget(mSubject, row, 1);
80 ++row;
81
82 auto timeLayout = new QHBoxLayout;
83 // Start date
84 mStartDate = new KDateComboBox(this);
85 KLineEditEventHandler::catchReturnKey(mStartDate->lineEdit());
86 mStartDate->setObjectName(QLatin1StringView("mStartDate"));
88 connect(mStartDate, &KDateComboBox::dateChanged, this, &VacationEditWidget::setWasChanged);
89 connect(mStartDate, &KDateComboBox::dateEdited, this, &VacationEditWidget::setWasChanged);
90
91 mStartTime = new KTimeComboBox(this);
92 KLineEditEventHandler::catchReturnKey(mStartTime->lineEdit());
93 mStartTime->setObjectName(QLatin1StringView("mStartTime"));
95 mStartTime->setEnabled(false); // Disable by default - we need an extension to support this
96 connect(mStartTime, &KTimeComboBox::timeChanged, this, &VacationEditWidget::setWasChanged);
97 connect(mStartTime, &KTimeComboBox::timeEdited, this, &VacationEditWidget::setWasChanged);
98
99 mStartTimeActive = new QCheckBox(this);
100 mStartTimeActive->setObjectName(QLatin1StringView("mStartTimeActive"));
101 connect(mStartTimeActive, &QCheckBox::toggled, mStartTime, &KTimeComboBox::setEnabled);
102
103 timeLayout->addWidget(mStartDate);
104 timeLayout->addWidget(mStartTimeActive);
105 timeLayout->addWidget(mStartTime);
106
107 mStartDateLabel = new QLabel(i18nc("@label:textbox", "Start date:"), this);
108 mStartDateLabel->setObjectName(QLatin1StringView("mStartDateLabel"));
109 mStartDateLabel->setBuddy(mStartDate);
110 glay->addWidget(mStartDateLabel, row, 0);
111 glay->addLayout(timeLayout, row, 1);
112
113 ++row;
114 // End date
115 timeLayout = new QHBoxLayout;
116
117 mEndDate = new KDateComboBox(this);
118 KLineEditEventHandler::catchReturnKey(mEndDate->lineEdit());
119 mEndDate->setObjectName(QLatin1StringView("mEndDate"));
121 connect(mEndDate, &KDateComboBox::dateChanged, this, &VacationEditWidget::setWasChanged);
122 connect(mEndDate, &KDateComboBox::dateEdited, this, &VacationEditWidget::setWasChanged);
123
124 mEndTime = new KTimeComboBox(this);
125 mEndTime->setObjectName(QLatin1StringView("mEndTime"));
126 KLineEditEventHandler::catchReturnKey(mEndTime->lineEdit());
128 mEndTime->setEnabled(false); // Disable by default - we need an extension to support this
129 connect(mEndTime, &KTimeComboBox::timeChanged, this, &VacationEditWidget::setWasChanged);
130 connect(mEndTime, &KTimeComboBox::timeEdited, this, &VacationEditWidget::setWasChanged);
131
132 mEndTimeActive = new QCheckBox(this);
133 mEndTimeActive->setObjectName(QLatin1StringView("mEndTimeActive"));
134 connect(mEndTimeActive, &QCheckBox::toggled, mEndTime, &KTimeComboBox::setEnabled);
135 connect(mEndTimeActive, &QCheckBox::toggled, this, &VacationEditWidget::setWasChanged);
136
137 mEndDateLabel = new QLabel(i18nc("@label:textbox", "End date:"), this);
138 mEndDateLabel->setObjectName(QLatin1StringView("mEndDateLabel"));
139 mEndDateLabel->setBuddy(mEndDate);
140 glay->addWidget(mEndDateLabel, row, 0);
141
142 timeLayout->addWidget(mEndDate);
143 timeLayout->addWidget(mEndTimeActive);
144 timeLayout->addWidget(mEndTime);
145 glay->addLayout(timeLayout, row, 1);
146
147 // Hide the date edits by default - they must be enabled by caller when the
148 // server supports this feature
149 enableDates(false);
150
151 // "Resent only after" spinbox and label:
152 ++row;
153 int defDayInterval = 7; // default day interval
154 mIntervalSpin = new QSpinBox(this);
155 mIntervalSpin->setMaximum(356);
156 mIntervalSpin->setMinimum(1);
157 mIntervalSpin->setSingleStep(1);
158 mIntervalSpin->setValue(defDayInterval);
159 mIntervalSpin->setObjectName(QLatin1StringView("mIntervalSpin"));
160 mIntervalSpin->setSuffix(i18np(" day", " days", defDayInterval));
161 connect(mIntervalSpin, &QSpinBox::valueChanged, this, &VacationEditWidget::slotIntervalSpinChanged);
162 auto resendNotificationLabel = new QLabel(i18nc("@label:textbox", "&Resend notification only after:"), this);
163 resendNotificationLabel->setObjectName(QLatin1StringView("resendNotificationLabel"));
164 resendNotificationLabel->setBuddy(mIntervalSpin);
165 glay->addWidget(resendNotificationLabel, row, 0);
166 glay->addWidget(mIntervalSpin, row, 1);
167
168 // "Send responses for these addresses" lineedit and label:
169 ++row;
170 mMailAliasesEdit = new KSieveUi::VacationMailLineEdit(this);
171 mMailAliasesEdit->setObjectName(QLatin1StringView("mMailAliasesEdit"));
172 mMailAliasesEdit->setClearButtonEnabled(true);
174 connect(mMailAliasesEdit, &KSieveUi::VacationMailLineEdit::textChanged, this, &VacationEditWidget::setWasChanged);
175 auto sendResponseLabel = new QLabel(i18nc("@label:textbox", "&Send responses for these addresses:"), this);
176 sendResponseLabel->setObjectName(QLatin1StringView("sendResponseLabel"));
177 sendResponseLabel->setBuddy(mMailAliasesEdit);
178 glay->addWidget(sendResponseLabel, row, 0);
179 glay->addWidget(mMailAliasesEdit, row, 1);
180
181 // Action for incoming mails
182 mMailAction = new QComboBox(this);
183 for (int i = 0; i < 4; ++i) {
184 mMailAction->addItem(KSieveCore::VacationUtils::mailAction(static_cast<KSieveCore::VacationUtils::MailAction>(i)));
185 }
186 mMailAction->setObjectName(QLatin1StringView("mMailAction"));
187 connect(mMailAction, &QComboBox::currentIndexChanged, this, &VacationEditWidget::mailActionChanged);
188
189 // Add imap select folder plugin here.
190 mMailActionRecipient = new VacationMailActionWidget(this);
191 mMailActionRecipient->setObjectName(QLatin1StringView("mMailActionRecipient"));
192 connect(mMailActionRecipient, &VacationMailActionWidget::wasChanged, this, &VacationEditWidget::setWasChanged);
193 // Add setChanged here too
194
195 auto hLayout = new QHBoxLayout;
196
197 hLayout->addWidget(mMailAction);
198 hLayout->addWidget(mMailActionRecipient);
199
200 ++row;
201 auto actionIncomingMailsLabel = new QLabel(i18nc("@label:textbox", "&Action for incoming mails:"), this);
202 actionIncomingMailsLabel->setBuddy(mMailAction);
203 actionIncomingMailsLabel->setObjectName(QLatin1StringView("actionIncomingMailsLabel"));
204 glay->addWidget(actionIncomingMailsLabel, row, 0);
205 glay->addLayout(hLayout, row, 1);
206
207 // "Send responses also to SPAM mail" checkbox:
208 ++row;
209 mSpamCheck = new QCheckBox(i18nc("@option:check", "Do not send vacation replies to spam messages"), this);
210 mSpamCheck->setObjectName(QLatin1StringView("mSpamCheck"));
211 mSpamCheck->setChecked(true);
212 glay->addWidget(mSpamCheck, row, 0, 1, 2);
213 connect(mSpamCheck, &QCheckBox::clicked, this, &VacationEditWidget::setWasChanged);
214
215 // domain checkbox and linedit:
216 ++row;
217 mDomainCheck = new QCheckBox(i18nc("@option:check", "Only react to mail coming from domain:"), this);
218 mDomainCheck->setObjectName(QLatin1StringView("mDomainCheck"));
219 mDomainCheck->setChecked(false);
220 connect(mDomainCheck, &QCheckBox::clicked, this, &VacationEditWidget::setWasChanged);
221
222 mDomainEdit = new QLineEdit(this);
224 mDomainEdit->setObjectName(QLatin1StringView("mDomainEdit"));
225 mDomainEdit->setClearButtonEnabled(true);
226 mDomainEdit->setEnabled(false);
227 mDomainEdit->setValidator(new QRegularExpressionValidator(QRegularExpression(QStringLiteral("[a-zA-Z0-9+-]+(?:\\.[a-zA-Z0-9+-]+)*")), mDomainEdit));
228 glay->addWidget(mDomainCheck, row, 0);
229 glay->addWidget(mDomainEdit, row, 1);
230 connect(mDomainCheck, &QCheckBox::toggled, mDomainEdit, &QLineEdit::setEnabled);
231 connect(mDomainEdit, &QLineEdit::textChanged, this, &VacationEditWidget::setWasChanged);
232}
233
234VacationEditWidget::~VacationEditWidget() = default;
235
236bool VacationEditWidget::activateVacation() const
237{
238 return mActiveCheck->isChecked();
239}
240
241void VacationEditWidget::setActivateVacation(bool activate)
242{
243 mActiveCheck->setChecked(activate);
244}
245
246QString VacationEditWidget::messageText() const
247{
248 return mTextEdit->toPlainText().trimmed();
249}
250
251void VacationEditWidget::setMessageText(const QString &text)
252{
253 mTextEdit->setPlainText(text);
254 const int height = (mTextEdit->fontMetrics().lineSpacing() + 1) * 11;
255 mTextEdit->setMinimumHeight(height);
256}
257
258int VacationEditWidget::notificationInterval() const
259{
260 return mIntervalSpin->value();
261}
262
263void VacationEditWidget::setNotificationInterval(int days)
264{
265 mIntervalSpin->setValue(days);
266}
267
268AddrSpecList VacationEditWidget::mailAliases(bool &ok) const
269{
270 QByteArray text = mMailAliasesEdit->text().toLatin1(); // ### IMAA: !ok
271 AddressList addressList;
272 const char *s = text.cbegin();
273 AddrSpecList addrSpecList;
274 if (parseAddressList(s, text.cend(), addressList)) {
275 for (const auto &address : std::as_const(addressList)) {
276 for (const auto &mail : address.mailboxList) {
277 addrSpecList.push_back(mail.addrSpec());
278 }
279 }
280 ok = true;
281 } else {
282 qCWarning(LIBKSIEVEUI_LOG) << "Impossible to parse email!" << text;
283 ok = false;
284 }
285 mMailAliasesEdit->setInvalidEmail(!ok);
286 return addrSpecList;
287}
288
289void VacationEditWidget::setMailAliases(const AddrSpecList &aliases)
290{
291 QStringList sl;
292 sl.reserve(aliases.count());
293 for (const auto &str : aliases) {
294 sl.push_back(str.asString());
295 }
296 mMailAliasesEdit->setText(sl.join(QLatin1StringView(", ")));
297}
298
299void VacationEditWidget::setMailAliases(const QString &aliases)
300{
301 mMailAliasesEdit->setText(aliases);
302}
303
304void VacationEditWidget::slotIntervalSpinChanged(int value)
305{
306 mIntervalSpin->setSuffix(i18np(" day", " days", value));
307 setWasChanged();
308}
309
310QString VacationEditWidget::domainName() const
311{
312 return mDomainCheck->isChecked() ? mDomainEdit->text() : QString();
313}
314
315void VacationEditWidget::setDomainName(const QString &domain)
316{
317 if (!domain.isEmpty()) {
318 mDomainEdit->setText(domain);
319 mDomainCheck->setChecked(true);
320 }
321}
322
323bool VacationEditWidget::domainCheck() const
324{
325 return mDomainCheck->isChecked();
326}
327
328void VacationEditWidget::setDomainCheck(bool check)
329{
330 mDomainCheck->setChecked(check);
331}
332
333bool VacationEditWidget::sendForSpam() const
334{
335 return !mSpamCheck->isChecked();
336}
337
338void VacationEditWidget::setSendForSpam(bool enable)
339{
340 mSpamCheck->setChecked(!enable);
341}
342
343QDate VacationEditWidget::endDate() const
344{
345 if (mEndDate->isEnabled()) {
346 return mEndDate->date();
347 } else {
348 return {};
349 }
350}
351
352void VacationEditWidget::setEndDate(QDate endDate)
353{
354 mEndDate->setDate(endDate);
355}
356
357QTime VacationEditWidget::endTime() const
358{
359 if (mEndTime->isEnabled()) {
360 return mEndTime->time();
361 } else {
362 return {};
363 }
364}
365
366void VacationEditWidget::setEndTime(QTime endTime)
367{
368 mEndTimeActive->setChecked(endTime.isValid());
369 mEndTime->setEnabled(endTime.isValid());
370 mEndTime->setTime(endTime);
371}
372
373QDate VacationEditWidget::startDate() const
374{
375 if (mStartDate->isEnabled()) {
376 return mStartDate->date();
377 } else {
378 return {};
379 }
380}
381
382void VacationEditWidget::setStartDate(QDate startDate)
383{
384 mStartDate->setDate(startDate);
385}
386
387QTime VacationEditWidget::startTime() const
388{
389 if (mStartTime->isEnabled()) {
390 return mStartTime->time();
391 } else {
392 return {};
393 }
394}
395
396void VacationEditWidget::setStartTime(QTime startTime)
397{
398 mStartTimeActive->setChecked(startTime.isValid());
399 mStartTime->setEnabled(startTime.isValid());
400 mStartTime->setTime(startTime);
401}
402
403void VacationEditWidget::setSubject(const QString &subject)
404{
405 mSubject->setText(subject);
406}
407
408QString VacationEditWidget::subject() const
409{
410 if (mSubject->isEnabled()) {
411 return mSubject->toPlainText();
412 } else {
413 return {};
414 }
415}
416
417void VacationEditWidget::enableDates(bool enable)
418{
419 mStartDate->setVisible(enable);
420 mStartDateLabel->setVisible(enable);
421 mEndDate->setVisible(enable);
422 mEndDateLabel->setVisible(enable);
423 mStartTime->setVisible(enable);
424 mStartTimeActive->setVisible(enable);
425 mEndTime->setVisible(enable);
426 mEndTimeActive->setVisible(enable);
427}
428
429void VacationEditWidget::mailActionChanged(int action)
430{
431 mMailActionRecipient->mailActionChanged(static_cast<KSieveCore::VacationUtils::MailAction>(action));
432 setWasChanged();
433}
434
435void VacationEditWidget::setWasChanged()
436{
437 mChanged = true;
438}
439
440bool VacationEditWidget::changed() const
441{
442 return mChanged;
443}
444
445void VacationEditWidget::setChanged(bool changed)
446{
447 mChanged = changed;
448}
449
450void VacationEditWidget::setMailAction(KSieveCore::VacationUtils::MailAction action, const QString &recipient)
451{
452 mMailAction->setCurrentIndex(action);
453 mMailActionRecipient->setMailAction(action, recipient);
454}
455
456void VacationEditWidget::setSieveImapAccountSettings(const KSieveCore::SieveImapAccountSettings &account)
457{
458 mMailActionRecipient->setSieveImapAccountSettings(account);
459}
460
461KSieveCore::VacationUtils::MailAction VacationEditWidget::mailAction() const
462{
463 return static_cast<KSieveCore::VacationUtils::MailAction>(mMailAction->currentIndex());
464}
465
466QString VacationEditWidget::mailActionRecipient(bool &valid) const
467{
468 return mMailActionRecipient->mailActionRecipient(valid);
469}
470
471void VacationEditWidget::enableDomainAndSendForSpam(bool enable)
472{
473 mDomainCheck->setEnabled(enable);
474 mDomainEdit->setEnabled(enable && mDomainCheck->isChecked());
475 mSpamCheck->setEnabled(enable);
476}
477
478void VacationEditWidget::setDefault()
479{
480 setActivateVacation(true);
481 setMessageText(KSieveCore::VacationUtils::defaultMessageText());
482 setSubject(KSieveCore::VacationUtils::defaultSubject());
483 setNotificationInterval(KSieveCore::VacationUtils::defaultNotificationInterval());
484 setMailAliases(KSieveCore::VacationUtils::defaultMailAliases());
485 setSendForSpam(KSieveCore::VacationUtils::defaultSendForSpam());
486 setDomainName(KSieveCore::VacationUtils::defaultDomainName());
487 setMailAction(KSieveCore::VacationUtils::defaultMailAction(), QString());
488 mStartTimeActive->setChecked(false);
489 mEndTimeActive->setChecked(false);
490 mStartTime->setTime(QTime());
491 mEndTime->setTime(QTime());
492 mStartDate->setDate(QDate());
493 mEndDate->setDate(QDate());
494 setDomainCheck(false);
495 mDomainEdit->clear();
496}
497
498#include "moc_vacationeditwidget.cpp"
void dateEdited(const QDate &date)
void dateChanged(const QDate &date)
void timeChanged(const QTime &time)
void timeEdited(const QTime &time)
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
PostalAddress address(const QVariant &location)
void catchReturnKey(QObject *lineEdit)
QAction * mail(const QObject *recvr, const char *slot, QObject *parent)
void clicked(bool checked)
void toggled(bool checked)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
const_iterator cbegin() const const
const_iterator cend() const const
void currentIndexChanged(int index)
void textChanged(const QString &text)
qsizetype count() const const
void push_back(parameter_type value)
void reserve(qsizetype size)
void textChanged()
void valueChanged(int i)
bool isEmpty() const const
QByteArray toLatin1() const const
QString join(QChar separator) const const
void textChanged()
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setEnabled(bool)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 31 2025 12:12:05 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.