File indexing completed on 2024-12-29 04:54:47

0001 /* SPDX-FileCopyrightText: 2011-2024 Laurent Montel <montel@kde.org>
0002  *
0003  * SPDX-License-Identifier: LGPL-2.0-or-later
0004  */
0005 
0006 #include "sieveeditor.h"
0007 #include "sieve-editor.h"
0008 #include "sieveeditorwidget.h"
0009 
0010 #include <KLocalizedString>
0011 #include <KMessageBox>
0012 
0013 #include <KConfigGroup>
0014 #include <KSharedConfig>
0015 #include <KWindowConfig>
0016 #include <QDialogButtonBox>
0017 #include <QKeyEvent>
0018 #include <QPushButton>
0019 #include <QVBoxLayout>
0020 #include <QWindow>
0021 
0022 using namespace KSieveUi;
0023 class KSieveUi::SieveEditorPrivate
0024 {
0025 public:
0026     SieveEditorPrivate() = default;
0027 
0028     SieveEditorWidget *mSieveEditorWidget = nullptr;
0029     QPushButton *mOkButton = nullptr;
0030 };
0031 namespace
0032 {
0033 static const char mySieveEditorGroupName[] = "SieveEditor";
0034 }
0035 SieveEditor::SieveEditor(QWidget *parent)
0036     : QDialog(parent)
0037     , d(new KSieveUi::SieveEditorPrivate)
0038 {
0039     setWindowTitle(i18nc("@title:window", "Edit Sieve Script"));
0040     auto mainLayout = new QVBoxLayout(this);
0041 
0042     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0043     d->mOkButton = buttonBox->button(QDialogButtonBox::Ok);
0044     d->mOkButton->setDefault(true);
0045     d->mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0046     connect(buttonBox, &QDialogButtonBox::accepted, this, &SieveEditor::slotAccepted);
0047     connect(buttonBox, &QDialogButtonBox::rejected, this, &SieveEditor::slotCanceled);
0048     d->mSieveEditorWidget = new SieveEditorWidget(true);
0049     connect(d->mSieveEditorWidget, &SieveEditorWidget::valueChanged, this, &SieveEditor::valueChanged);
0050     mainLayout->addWidget(d->mSieveEditorWidget);
0051     mainLayout->addWidget(buttonBox);
0052     connect(d->mSieveEditorWidget, &SieveEditorWidget::enableButtonOk, this, &SieveEditor::slotEnableButtonOk);
0053     connect(this, &SieveEditor::finished, this, &SieveEditor::cancelClicked);
0054     connect(d->mSieveEditorWidget, &SieveEditorWidget::checkSyntax, this, &SieveEditor::checkSyntax);
0055     readConfig();
0056 }
0057 
0058 SieveEditor::~SieveEditor()
0059 {
0060     writeConfig();
0061 }
0062 
0063 void SieveEditor::slotAccepted()
0064 {
0065     Q_EMIT okClicked();
0066     // Don't accept here we need to check script. If it's failed we don't close this editor otherwise we will lose data
0067 }
0068 
0069 void SieveEditor::slotCanceled()
0070 {
0071     Q_EMIT cancelClicked();
0072     reject();
0073 }
0074 
0075 bool SieveEditor::event(QEvent *e)
0076 {
0077     // Close the bar when pressing Escape.
0078     // Not using a QShortcut for this because it could conflict with
0079     // window-global actions (e.g. Emil Sedgh binds Esc to "close tab").
0080     // With a shortcut override we can catch this before it gets to kactions.
0081     const bool shortCutOverride = (e->type() == QEvent::ShortcutOverride);
0082     if (shortCutOverride || e->type() == QEvent::KeyPress) {
0083         auto kev = static_cast<QKeyEvent *>(e);
0084         if (kev->key() == Qt::Key_Escape) {
0085             e->ignore();
0086             return true;
0087         }
0088     }
0089     return QDialog::event(e);
0090 }
0091 
0092 void SieveEditor::setModified(bool b)
0093 {
0094     d->mSieveEditorWidget->setModified(b);
0095 }
0096 
0097 void SieveEditor::slotEnableButtonOk(bool b)
0098 {
0099     d->mOkButton->setEnabled(b);
0100 }
0101 
0102 void SieveEditor::readConfig()
0103 {
0104     create(); // ensure a window is created
0105     windowHandle()->resize(QSize(800, 600));
0106     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(mySieveEditorGroupName));
0107     KWindowConfig::restoreWindowSize(windowHandle(), group);
0108     resize(windowHandle()->size()); // workaround for QTBUG-40584
0109 }
0110 
0111 void SieveEditor::writeConfig()
0112 {
0113     KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(mySieveEditorGroupName));
0114     KWindowConfig::saveWindowSize(windowHandle(), group);
0115     group.sync();
0116 }
0117 
0118 QString SieveEditor::script() const
0119 {
0120     return d->mSieveEditorWidget->script();
0121 }
0122 
0123 QString SieveEditor::originalScript() const
0124 {
0125     return d->mSieveEditorWidget->originalScript();
0126 }
0127 
0128 void SieveEditor::setScript(const QString &script, bool clearUndoRedo)
0129 {
0130     d->mSieveEditorWidget->setScript(script, clearUndoRedo);
0131 }
0132 
0133 void SieveEditor::setDebugScript(const QString &debug)
0134 {
0135     d->mSieveEditorWidget->setDebugScript(debug);
0136 }
0137 
0138 void SieveEditor::setScriptName(const QString &name)
0139 {
0140     d->mSieveEditorWidget->setScriptName(name);
0141 }
0142 
0143 void SieveEditor::resultDone()
0144 {
0145     d->mSieveEditorWidget->resultDone();
0146 }
0147 
0148 void SieveEditor::setSieveImapAccountSettings(const KSieveCore::SieveImapAccountSettings &account)
0149 {
0150     d->mSieveEditorWidget->setSieveImapAccountSettings(account);
0151 }
0152 
0153 void SieveEditor::setSieveCapabilities(const QStringList &capabilities)
0154 {
0155     d->mSieveEditorWidget->setSieveCapabilities(capabilities);
0156 }
0157 
0158 void SieveEditor::setListOfIncludeFile(const QStringList &listOfIncludeFile)
0159 {
0160     d->mSieveEditorWidget->setListOfIncludeFile(listOfIncludeFile);
0161 }
0162 
0163 void SieveEditor::addFailedMessage(const QString &err)
0164 {
0165     d->mSieveEditorWidget->addFailedMessage(err);
0166 }
0167 
0168 void SieveEditor::addOkMessage(const QString &msg)
0169 {
0170     d->mSieveEditorWidget->addOkMessage(msg);
0171 }
0172 
0173 void SieveEditor::addNormalMessage(const QString &msg)
0174 {
0175     d->mSieveEditorWidget->addNormalMessage(msg);
0176 }
0177 
0178 void SieveEditor::closeEvent(QCloseEvent *e)
0179 {
0180     if (d->mSieveEditorWidget->originalScript() != d->mSieveEditorWidget->script()) {
0181         const int answer = KMessageBox::warningTwoActions(this,
0182                                                           i18n("Script is modified. Do you want to close editor?"),
0183                                                           QString(),
0184                                                           KGuiItem(i18nc("@action:button", "Close Editor"), QStringLiteral("dialog-close")),
0185                                                           KGuiItem(i18nc("@action:button", "Do Not Close"), QStringLiteral("dialog-cancel")));
0186         if (answer == KMessageBox::ButtonCode::SecondaryAction) {
0187             e->ignore();
0188             return;
0189         }
0190     }
0191     Q_EMIT cancelClicked();
0192     e->accept();
0193 }
0194 
0195 #include "moc_sieveeditor.cpp"