1 /*
2    SPDX-FileCopyrightText: 2013-2021 Laurent Montel <montel@kde.org>
3 
4    SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "sieveeditorgraphicalmodewidget.h"
8 #include "autocreatescripts/sievescriptparsingerrordialog.h"
9 #include "ksieveui/editor/warningwidget/sieveeditorparsingmissingfeaturewarning.h"
10 #include "scriptsparsing/parsingutil.h"
11 #include "sievescriptlistbox.h"
12 #include "sievescriptpage.h"
13 
14 #include <KConfigGroup>
15 #include <KLocalizedString>
16 #include <KMessageBox>
17 #include <KSharedConfig>
18 
19 #include "libksieve_debug.h"
20 #include <QSplitter>
21 #include <QStackedWidget>
22 #include <QVBoxLayout>
23 
24 using namespace KSieveUi;
25 
SieveEditorGraphicalModeWidget(QWidget * parent)26 SieveEditorGraphicalModeWidget::SieveEditorGraphicalModeWidget(QWidget *parent)
27     : SieveEditorGraphicalModeWidgetAbstract::SieveEditorGraphicalModeWidgetAbstract(parent)
28     , mSieveScript(new SieveScriptListBox(i18n("Sieve Script"), this))
29     , mSplitter(new QSplitter)
30 {
31     auto vlay = new QVBoxLayout(this);
32     vlay->setContentsMargins({});
33 
34     mSplitter->setChildrenCollapsible(false);
35     mSieveScript->setSieveEditorGraphicalModeWidget(this);
36     connect(mSieveScript, &SieveScriptListBox::valueChanged, this, &SieveEditorGraphicalModeWidget::valueChanged);
37     connect(mSieveScript, &SieveScriptListBox::addNewPage, this, &SieveEditorGraphicalModeWidget::slotAddScriptPage);
38     connect(mSieveScript, &SieveScriptListBox::removePage, this, &SieveEditorGraphicalModeWidget::slotRemoveScriptPage);
39     connect(mSieveScript, &SieveScriptListBox::activatePage, this, &SieveEditorGraphicalModeWidget::slotActivateScriptPage);
40     connect(mSieveScript, &SieveScriptListBox::enableButtonOk, this, &SieveEditorGraphicalModeWidget::enableButtonOk);
41     mSplitter->addWidget(mSieveScript);
42     vlay->addWidget(mSplitter);
43 
44     mStackWidget = new QStackedWidget;
45     mSplitter->addWidget(mStackWidget);
46 
47     mSieveParsingWarning = new SieveEditorParsingMissingFeatureWarning(SieveEditorParsingMissingFeatureWarning::GraphicEditor);
48     connect(mSieveParsingWarning, &SieveEditorParsingMissingFeatureWarning::switchToTextMode, this, &SieveEditorGraphicalModeWidget::slotSwitchToTextMode);
49     vlay->addWidget(mSieveParsingWarning);
50 
51     readConfig();
52 }
53 
~SieveEditorGraphicalModeWidget()54 SieveEditorGraphicalModeWidget::~SieveEditorGraphicalModeWidget()
55 {
56     writeConfig();
57 }
58 
loadScript(const QString & doc,QString & error)59 void SieveEditorGraphicalModeWidget::loadScript(const QString &doc, QString &error)
60 {
61     for (int i = mStackWidget->count(); i >= 0; --i) {
62         mStackWidget->removeWidget(mStackWidget->widget(i));
63     }
64     mSieveScript->loadScript(doc, error);
65 }
66 
readConfig()67 void SieveEditorGraphicalModeWidget::readConfig()
68 {
69     KConfigGroup group(KSharedConfig::openStateConfig(), "AutoCreateScriptDialog");
70     const QList<int> size{100, 400};
71     mSplitter->setSizes(group.readEntry("mainSplitter", size));
72 }
73 
writeConfig()74 void SieveEditorGraphicalModeWidget::writeConfig()
75 {
76     KConfigGroup group(KSharedConfig::openStateConfig(), "AutoCreateScriptDialog");
77     group.writeEntry("mainSplitter", mSplitter->sizes());
78 }
79 
setSieveCapabilities(const QStringList & capabilities)80 void SieveEditorGraphicalModeWidget::setSieveCapabilities(const QStringList &capabilities)
81 {
82     mCapabilities = capabilities;
83 }
84 
sieveCapabilities()85 QStringList SieveEditorGraphicalModeWidget::sieveCapabilities()
86 {
87     return mCapabilities;
88 }
89 
script(QStringList & required) const90 QString SieveEditorGraphicalModeWidget::script(QStringList &required) const
91 {
92     return mSieveScript->generatedScript(required);
93 }
94 
slotAddScriptPage(KSieveUi::SieveScriptPage * page)95 void SieveEditorGraphicalModeWidget::slotAddScriptPage(KSieveUi::SieveScriptPage *page)
96 {
97     mStackWidget->addWidget(page);
98     mStackWidget->setCurrentWidget(page);
99     connect(page, &SieveScriptPage::valueChanged, this, &SieveEditorGraphicalModeWidget::valueChanged);
100 }
101 
slotRemoveScriptPage(QWidget * page)102 void SieveEditorGraphicalModeWidget::slotRemoveScriptPage(QWidget *page)
103 {
104     mStackWidget->removeWidget(page);
105 }
106 
slotActivateScriptPage(QWidget * page)107 void SieveEditorGraphicalModeWidget::slotActivateScriptPage(QWidget *page)
108 {
109     mStackWidget->setCurrentWidget(page);
110 }
111 
currentscript()112 QString SieveEditorGraphicalModeWidget::currentscript()
113 {
114     QStringList requireModules;
115     QString script = mSieveScript->generatedScript(requireModules);
116     if (!requireModules.isEmpty()) {
117         script.prepend(requireModules.join(QLatin1Char('\n')) + QStringLiteral("\n\n"));
118     }
119     return script;
120 }
121 
setImportScript(const QString & script)122 void SieveEditorGraphicalModeWidget::setImportScript(const QString &script)
123 {
124     bool result = false;
125     const QString doc = ParsingUtil::parseScript(script, result);
126     mSieveParsingWarning->animatedHide();
127     if (result) {
128         QString error;
129         loadScript(doc, error);
130         if (!error.isEmpty()) {
131             mSieveParsingWarning->setErrors(script, error);
132             mSieveParsingWarning->animatedShow();
133         }
134     } else {
135         const int answer = KMessageBox::questionYesNo(this,
136                                                       i18n("Error during importing script. Do you want to switch to text mode?"),
137                                                       QString(),
138                                                       KGuiItem(i18nc("@action:button", "Switch to Text Mode")),
139                                                       KGuiItem(i18nc("@action:button", "Do Not Switch"), QStringLiteral("dialog-cancel")));
140         if (answer == KMessageBox::Yes) {
141             Q_EMIT switchTextMode(script);
142         }
143         qCDebug(LIBKSIEVE_LOG) << " cannot import script";
144     }
145 }
146 
setListOfIncludeFile(const QStringList & listOfIncludeFile)147 void SieveEditorGraphicalModeWidget::setListOfIncludeFile(const QStringList &listOfIncludeFile)
148 {
149     mListOfIncludeFile = listOfIncludeFile;
150 }
151 
slotSwitchToTextMode()152 void SieveEditorGraphicalModeWidget::slotSwitchToTextMode()
153 {
154     Q_EMIT switchTextMode(mSieveParsingWarning->initialScript());
155 }
156 
listOfIncludeFile() const157 QStringList KSieveUi::SieveEditorGraphicalModeWidget::listOfIncludeFile() const
158 {
159     return mListOfIncludeFile;
160 }
161