File indexing completed on 2025-02-16 04:56:07

0001 /*
0002    SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "multiimapvacationdialog.h"
0008 #include "vacationpagewidget.h"
0009 #include <KSieveCore/MultiImapVacationManager>
0010 #include <KSieveCore/SearchServerWithVacationSupportJob>
0011 
0012 #include <KLocalizedString>
0013 #include <KMessageBox>
0014 #include <KSharedConfig>
0015 #include <QTabWidget>
0016 
0017 #include <KConfigGroup>
0018 #include <KWindowConfig>
0019 #include <QDialogButtonBox>
0020 #include <QLabel>
0021 #include <QPushButton>
0022 #include <QStackedWidget>
0023 #include <QTabBar>
0024 #include <QVBoxLayout>
0025 #include <QWindow>
0026 
0027 using namespace KSieveUi;
0028 namespace
0029 {
0030 static const char myMultiImapVacationDialogGroupName[] = "MultiImapVacationDialog";
0031 }
0032 class KSieveUi::MultiImapVacationDialogPrivate
0033 {
0034 public:
0035     MultiImapVacationDialogPrivate() = default;
0036 
0037     QList<KSieveCore::VacationCreateScriptJob *> mListCreateJob;
0038     QTabWidget *mTabWidget = nullptr;
0039     QStackedWidget *mStackedWidget = nullptr;
0040     KSieveCore::MultiImapVacationManager *mVacationManager = nullptr;
0041 };
0042 
0043 MultiImapVacationDialog::MultiImapVacationDialog(KSieveCore::MultiImapVacationManager *manager, QWidget *parent)
0044     : QDialog(parent)
0045     , d(new KSieveUi::MultiImapVacationDialogPrivate)
0046 {
0047     d->mVacationManager = manager;
0048 
0049     setWindowTitle(i18nc("@title:window", "Configure \"Out of Office\" Replies"));
0050     init();
0051     readConfig();
0052 }
0053 
0054 MultiImapVacationDialog::~MultiImapVacationDialog()
0055 {
0056     writeConfig();
0057 }
0058 
0059 void MultiImapVacationDialog::switchToServerNamePage(const QString &serverName)
0060 {
0061     const int nbTab(d->mTabWidget->count());
0062     for (int i = 0; i < nbTab; ++i) {
0063         if (d->mTabWidget->tabText(i) == serverName) {
0064             d->mTabWidget->setCurrentIndex(i);
0065             break;
0066         }
0067     }
0068 }
0069 
0070 void MultiImapVacationDialog::reject()
0071 {
0072     bool canCloseDialog = true;
0073     for (int i = 0; i < d->mTabWidget->count(); ++i) {
0074         auto vacationPage = qobject_cast<VacationPageWidget *>(d->mTabWidget->widget(i));
0075         if (vacationPage) {
0076             if (vacationPage->wasChanged()) {
0077                 const int answer = KMessageBox::questionTwoActions(this,
0078                                                                    i18nc("@info", "Do you really want to cancel?"),
0079                                                                    i18nc("@title:window", "Confirmation"),
0080                                                                    KGuiItem(i18nc("@action:button", "Cancel Editing"), QStringLiteral("dialog-ok")),
0081                                                                    KGuiItem(i18nc("@action:button", "Do Not Cancel"), QStringLiteral("dialog-cancel")));
0082                 if (answer == KMessageBox::ButtonCode::PrimaryAction) {
0083                     QDialog::reject(); // Discard current changes
0084                 }
0085                 canCloseDialog = false;
0086                 break;
0087             }
0088         }
0089     }
0090     if (canCloseDialog) {
0091         QDialog::reject();
0092     }
0093 }
0094 
0095 QList<KSieveCore::VacationCreateScriptJob *> MultiImapVacationDialog::listCreateJob() const
0096 {
0097     return d->mListCreateJob;
0098 }
0099 
0100 void MultiImapVacationDialog::init()
0101 {
0102     d->mStackedWidget = new QStackedWidget;
0103     auto mainLayout = new QVBoxLayout(this);
0104     mainLayout->addWidget(d->mStackedWidget);
0105     d->mTabWidget = new QTabWidget;
0106     d->mStackedWidget->addWidget(d->mTabWidget);
0107 
0108     auto w = new QWidget;
0109     auto vbox = new QVBoxLayout;
0110     w->setLayout(vbox);
0111     auto lab =
0112         new QLabel(i18n("KMail's Out of Office Reply functionality relies on "
0113                         "server-side filtering. You have not yet configured an "
0114                         "IMAP server for this. "
0115                         "You can do this on the \"Filtering\" tab of the IMAP "
0116                         "account configuration."));
0117     lab->setWordWrap(true);
0118     lab->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
0119     QFont font = lab->font();
0120     font.setBold(true);
0121     font.setPixelSize(font.pixelSize() + 2);
0122     lab->setFont(font);
0123     vbox->addWidget(lab);
0124     lab->setWordWrap(true);
0125     d->mStackedWidget->addWidget(w);
0126     d->mStackedWidget->setCurrentIndex(0);
0127     mButtonBox = new QDialogButtonBox(this);
0128     mButtonBox->setObjectName(QLatin1StringView("mButtonBox"));
0129     mainLayout->addWidget(mButtonBox);
0130     initialize();
0131 }
0132 
0133 void MultiImapVacationDialog::initialize()
0134 {
0135     auto job = new KSieveCore::SearchServerWithVacationSupportJob(this);
0136     job->setPasswordProvider(d->mVacationManager->passwordProvider());
0137     connect(job,
0138             &KSieveCore::SearchServerWithVacationSupportJob::searchServerWithVacationSupportFinished,
0139             this,
0140             &MultiImapVacationDialog::slotSearchServerWithVacationSupportFinished);
0141     job->start();
0142 }
0143 
0144 void MultiImapVacationDialog::slotSearchServerWithVacationSupportFinished(const QMap<QString, KSieveCore::Util::AccountInfo> &list)
0145 {
0146     bool foundOneImap = false;
0147 
0148     QMapIterator<QString, KSieveCore::Util::AccountInfo> i(list);
0149     while (i.hasNext()) {
0150         i.next();
0151         createPage(i.key(), i.value());
0152         foundOneImap = true;
0153     }
0154     if (foundOneImap) {
0155         mButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults);
0156         QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok);
0157         okButton->setDefault(true);
0158         okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0159         connect(mButtonBox, &QDialogButtonBox::accepted, this, &MultiImapVacationDialog::slotOkClicked);
0160         connect(mButtonBox, &QDialogButtonBox::rejected, this, &MultiImapVacationDialog::slotCanceled);
0161         connect(mButtonBox->button(QDialogButtonBox::RestoreDefaults), &QPushButton::clicked, this, &MultiImapVacationDialog::slotDefaultClicked);
0162     } else { // Empty
0163         d->mStackedWidget->setCurrentIndex(1);
0164         mButtonBox->setStandardButtons(QDialogButtonBox::Close);
0165         connect(mButtonBox, &QDialogButtonBox::accepted, this, &MultiImapVacationDialog::slotOkClicked);
0166         connect(mButtonBox, &QDialogButtonBox::rejected, this, &MultiImapVacationDialog::slotCanceled);
0167     }
0168     if (d->mTabWidget->count() <= 1) {
0169         d->mTabWidget->tabBar()->hide();
0170     }
0171 }
0172 
0173 void MultiImapVacationDialog::slotCanceled()
0174 {
0175     Q_EMIT cancelClicked();
0176 }
0177 
0178 void MultiImapVacationDialog::createPage(const QString &serverName, const KSieveCore::Util::AccountInfo &info)
0179 {
0180     auto page = new VacationPageWidget;
0181     page->setServerUrl(info.sieveUrl);
0182     page->setServerName(serverName);
0183     page->setVacationManager(d->mVacationManager);
0184     page->setSieveImapAccountSettings(info.sieveImapAccountSettings);
0185     d->mTabWidget->addTab(page, serverName + QStringLiteral(" (%1)").arg(info.sieveUrl.userName()));
0186 }
0187 
0188 void MultiImapVacationDialog::readConfig()
0189 {
0190     create(); // ensure a window is created
0191     windowHandle()->resize(QSize(600, 400));
0192     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myMultiImapVacationDialogGroupName));
0193     KWindowConfig::restoreWindowSize(windowHandle(), group);
0194     resize(windowHandle()->size()); // workaround for QTBUG-40584
0195 }
0196 
0197 void MultiImapVacationDialog::writeConfig()
0198 {
0199     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myMultiImapVacationDialogGroupName));
0200     KWindowConfig::saveWindowSize(windowHandle(), group);
0201     group.sync();
0202 }
0203 
0204 void MultiImapVacationDialog::slotOkClicked()
0205 {
0206     bool errorFound = false;
0207     qDeleteAll(d->mListCreateJob);
0208     d->mListCreateJob.clear();
0209     for (int i = 0; i < d->mTabWidget->count(); ++i) {
0210         auto vacationPage = qobject_cast<VacationPageWidget *>(d->mTabWidget->widget(i));
0211         if (vacationPage) {
0212             KSieveCore::VacationCreateScriptJob *job = vacationPage->writeScript(errorFound);
0213 
0214             if (job && !errorFound) {
0215                 d->mListCreateJob.append(job);
0216             }
0217             if (errorFound) {
0218                 // Clean up job
0219                 qDeleteAll(d->mListCreateJob);
0220                 d->mListCreateJob.clear();
0221                 break;
0222             }
0223         }
0224     }
0225     if (!errorFound) {
0226         Q_EMIT okClicked();
0227     }
0228 }
0229 
0230 void MultiImapVacationDialog::slotDefaultClicked()
0231 {
0232     for (int i = 0; i < d->mTabWidget->count(); ++i) {
0233         auto vacationPage = qobject_cast<VacationPageWidget *>(d->mTabWidget->widget(i));
0234         if (vacationPage) {
0235             vacationPage->setDefault();
0236         }
0237     }
0238 }
0239 
0240 #include "moc_multiimapvacationdialog.cpp"