Libksieve

managesievescriptsdialog.cpp
1/*
2 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-only
5*/
6
7#include "managesievescriptsdialog.h"
8#include "editor/sieveeditor.h"
9#include "managescriptsjob/checkscriptjob.h"
10#include "widgets/custommanagesievewidget.h"
11
12#include "util/sieveimapaccountsettings.h"
13
14#include <KConfigGroup>
15#include <KLocalizedString>
16#include <KMessageBox>
17#include <QHideEvent>
18#include <QPushButton>
19
20#include "kmanagesieve/sievejob.h"
21
22#include <QTreeWidget>
23#include <QVBoxLayout>
24
25#include <KGuiItem>
26#include <KSharedConfig>
27#include <KStandardGuiItem>
28#include <cerrno>
29
30using namespace KSieveUi;
31
32class KSieveUi::ManageSieveScriptsDialogPrivate
33{
34public:
35 ManageSieveScriptsDialogPrivate() = default;
36
37 CustomManageSieveWidget *mTreeView = nullptr;
38 SieveEditor *mSieveEditor = nullptr;
39
40 QUrl mCurrentURL;
41 QStringList mCurrentCapabilities;
42 QStringList mListOfIncludeFile;
43 KSieveCore::SieveImapAccountSettings mSieveImapAccountSettings;
44
45 QPushButton *mNewScript = nullptr;
46 QPushButton *mEditScript = nullptr;
47 QPushButton *mDeleteScript = nullptr;
48 QPushButton *mDeactivateScript = nullptr;
49
50 bool mIsNewScript = false;
51 bool mWasActive = false;
52};
53
54namespace
55{
56static const char myManageSieveScriptsDialog[] = "ManageSieveScriptsDialog";
57}
58
59ManageSieveScriptsDialog::ManageSieveScriptsDialog(KSieveCore::SieveImapPasswordProvider *passwordProvider, QWidget *parent)
60 : QDialog(parent)
61 , d(new KSieveUi::ManageSieveScriptsDialogPrivate)
62{
63 setWindowTitle(i18nc("@title:window", "Manage Sieve Scripts"));
64 setModal(false);
65 setWindowModality(Qt::WindowModal);
66 setAttribute(Qt::WA_DeleteOnClose);
67 auto mainLayout = new QVBoxLayout(this);
68 mainLayout->setContentsMargins({});
69 mainLayout->setSpacing(0);
70
71 auto frame = new QFrame;
72 mainLayout->addWidget(frame);
73 auto vlay = new QVBoxLayout(frame);
74 vlay->setSpacing(0);
75
76 d->mTreeView = new CustomManageSieveWidget(passwordProvider, frame);
77 connect(d->mTreeView, &CustomManageSieveWidget::editScript, this, &ManageSieveScriptsDialog::slotEditScript);
78 connect(d->mTreeView, &CustomManageSieveWidget::newScript, this, &ManageSieveScriptsDialog::slotNewScript);
79 connect(d->mTreeView, &CustomManageSieveWidget::updateButtons, this, &ManageSieveScriptsDialog::slotUpdateButtons);
80 vlay->addWidget(d->mTreeView);
81
82 auto buttonLayout = new QHBoxLayout;
83 vlay->addLayout(buttonLayout);
84
85 d->mNewScript = new QPushButton(i18nc("create a new sieve script", "New…"));
86 connect(d->mNewScript, &QPushButton::clicked, d->mTreeView, &CustomManageSieveWidget::slotNewScript);
87 buttonLayout->addWidget(d->mNewScript);
88
89 d->mEditScript = new QPushButton(i18nc("@action:button", "Edit…"));
90 connect(d->mEditScript, &QPushButton::clicked, d->mTreeView, &CustomManageSieveWidget::slotEditScript);
91 buttonLayout->addWidget(d->mEditScript);
92
93 d->mDeleteScript = new QPushButton(i18nc("@action:button", "Delete"));
94 connect(d->mDeleteScript, &QPushButton::clicked, d->mTreeView, &CustomManageSieveWidget::slotDeleteScript);
95 buttonLayout->addWidget(d->mDeleteScript);
96
97 d->mDeactivateScript = new QPushButton(i18nc("@action:button", "Deactivate"));
98 connect(d->mDeactivateScript, &QPushButton::clicked, d->mTreeView, &CustomManageSieveWidget::slotDeactivateScript);
99 buttonLayout->addWidget(d->mDeactivateScript);
100
101 auto close = new QPushButton;
103 connect(close, &QPushButton::clicked, this, &ManageSieveScriptsDialog::accept);
104 buttonLayout->addWidget(close);
105
106 KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myManageSieveScriptsDialog));
107 const QSize size = group.readEntry("Size", QSize());
108 if (size.isValid()) {
109 resize(size);
110 } else {
111 resize(sizeHint().width(), sizeHint().height());
112 }
113}
114
115ManageSieveScriptsDialog::~ManageSieveScriptsDialog()
116{
117 disconnect(d->mTreeView, &CustomManageSieveWidget::updateButtons, this, &ManageSieveScriptsDialog::slotUpdateButtons);
118 KConfigGroup group(KSharedConfig::openStateConfig(), QLatin1StringView(myManageSieveScriptsDialog));
119 group.writeEntry("Size", size());
120 // prevent QTreeWidget signals triggered by it's destructor from calling our slots
121 d->mTreeView->disconnect(this);
122}
123
124void ManageSieveScriptsDialog::hideEvent(QHideEvent *event)
125{
126 if (!event->spontaneous()) {
127 Q_EMIT finished();
128 }
129}
130
131void ManageSieveScriptsDialog::slotUpdateButtons(QTreeWidgetItem *item)
132{
133 Q_UNUSED(item)
134 bool newScriptAction;
135 bool editScriptAction;
136 bool deleteScriptAction;
137 bool desactivateScriptAction;
138 d->mTreeView->enableDisableActions(newScriptAction, editScriptAction, deleteScriptAction, desactivateScriptAction);
139 d->mNewScript->setEnabled(newScriptAction);
140 d->mEditScript->setEnabled(editScriptAction);
141 d->mDeleteScript->setEnabled(deleteScriptAction);
142 d->mDeactivateScript->setEnabled(desactivateScriptAction);
143}
144
145void ManageSieveScriptsDialog::slotEditScript(const ManageSieveWidget::ScriptInfo &info)
146{
147 d->mCurrentURL = info.currentUrl;
148 d->mCurrentCapabilities = info.currentCapabilities;
149 d->mListOfIncludeFile = info.scriptList;
150 d->mIsNewScript = false;
151 d->mSieveImapAccountSettings = info.sieveImapAccountSettings;
153 connect(job, &KManageSieve::SieveJob::result, this, &ManageSieveScriptsDialog::slotGetResult);
154}
155
156void ManageSieveScriptsDialog::slotNewScript(const ManageSieveWidget::ScriptInfo &info)
157{
158 d->mCurrentCapabilities = info.currentCapabilities;
159 d->mSieveImapAccountSettings = info.sieveImapAccountSettings;
160 d->mCurrentURL = info.currentUrl;
161 d->mListOfIncludeFile = info.scriptList;
162 d->mIsNewScript = true;
163 slotGetResult(nullptr, true, QString(), false);
164}
165
166void ManageSieveScriptsDialog::slotGetResult(KManageSieve::SieveJob *job, bool success, const QString &script, bool isActive)
167{
168 if (!success) {
170 i18n("Retrieving the script failed.\n"
171 "The server responded:\n%1",
172 job->errorString()),
173 i18nc("@title:window", "Sieve Error"));
174 return;
175 }
176
177 if (d->mSieveEditor) {
178 return;
179 }
180
181 disableManagerScriptsDialog(true);
182 d->mSieveEditor = new SieveEditor;
183 d->mSieveEditor->show();
184 d->mSieveEditor->setScriptName(d->mCurrentURL.fileName());
185 d->mSieveEditor->setSieveCapabilities(d->mCurrentCapabilities);
186 d->mSieveEditor->setScript(script, true); /*clear undo/redo*/
187 d->mSieveEditor->setSieveImapAccountSettings(d->mSieveImapAccountSettings);
188 d->mSieveEditor->setListOfIncludeFile(d->mListOfIncludeFile);
189
190 connect(d->mSieveEditor, &SieveEditor::okClicked, this, &ManageSieveScriptsDialog::slotSieveEditorOkClicked);
191 connect(d->mSieveEditor, &SieveEditor::cancelClicked, this, &ManageSieveScriptsDialog::slotSieveEditorCancelClicked);
192 connect(d->mSieveEditor, &SieveEditor::checkSyntax, this, &ManageSieveScriptsDialog::slotSieveEditorCheckSyntaxClicked);
193 d->mWasActive = isActive;
194 d->mSieveEditor->setModified(false);
195}
196
197void ManageSieveScriptsDialog::slotSieveEditorCheckSyntaxClicked()
198{
199 if (!d->mSieveEditor) {
200 return;
201 }
202 const QString script = d->mSieveEditor->script();
203 if (script.isEmpty()) {
204 return;
205 }
206 d->mSieveEditor->addNormalMessage(i18n("Uploading script to server for checking it, please wait…"));
207 auto checkScriptJob = new KSieveCore::CheckScriptJob(this);
208 connect(checkScriptJob, &KSieveCore::CheckScriptJob::finished, this, &ManageSieveScriptsDialog::slotCheckScriptFinished);
209 checkScriptJob->setIsActive(d->mWasActive);
210 checkScriptJob->setOriginalScript(d->mSieveEditor->originalScript());
211 checkScriptJob->setCurrentScript(script);
212 checkScriptJob->setUrl(d->mCurrentURL);
213 checkScriptJob->start();
214}
215
216void ManageSieveScriptsDialog::slotSieveEditorOkClicked()
217{
218 disableManagerScriptsDialog(false);
219 if (!d->mSieveEditor) {
220 return;
221 }
222 KManageSieve::SieveJob *job = KManageSieve::SieveJob::put(d->mCurrentURL, d->mSieveEditor->script(), d->mWasActive, d->mWasActive);
223 connect(job, &KManageSieve::SieveJob::result, this, &ManageSieveScriptsDialog::slotPutResult);
224}
225
226void ManageSieveScriptsDialog::slotSieveEditorCancelClicked()
227{
228 disableManagerScriptsDialog(false);
229 if (d->mSieveEditor) {
230 d->mSieveEditor->deleteLater();
231 d->mSieveEditor = nullptr;
232 }
233 d->mCurrentURL = QUrl();
234 if (d->mIsNewScript) {
235 d->mTreeView->slotRefresh();
236 }
237}
238
239void ManageSieveScriptsDialog::slotCheckScriptFinished(const QString &errorMsg, bool success)
240{
241 if (success) {
242 d->mSieveEditor->addOkMessage(errorMsg);
243 } else {
244 d->mSieveEditor->addFailedMessage(errorMsg);
245 }
246 d->mSieveEditor->resultDone();
247}
248
249void ManageSieveScriptsDialog::slotPutResult(KManageSieve::SieveJob *job, bool success)
250{
251 if (success) {
252 KMessageBox::information(this, i18n("The Sieve script was successfully uploaded."), i18nc("@title:window", "Sieve Script Upload"));
253 d->mSieveEditor->deleteLater();
254 d->mSieveEditor = nullptr;
255 d->mCurrentURL = QUrl();
256 } else {
257 // Don't add parent otherwise when there is an error it will parent to ManageSieveScriptsDialog and not editor
258 KMessageBox::error(nullptr,
259 i18n("Uploading the Sieve script failed.\n"
260 "The server responded:\n%1",
261 job->errorString()),
262 i18nc("@title:window", "Sieve Error"));
263 if (d->mSieveEditor) {
264 d->mSieveEditor->show();
265 }
266 }
267}
268
269void ManageSieveScriptsDialog::disableManagerScriptsDialog(bool disable)
270{
271 setDisabled(disable);
272}
273
274#include "moc_managesievescriptsdialog.cpp"
static void assign(QPushButton *button, const KGuiItem &item)
A job to manage sieve scripts.
Definition sievejob.h:31
QString errorString() const
A human-readable error message.
Definition sievejob.cpp:268
void result(KManageSieve::SieveJob *job, bool success, const QString &script, bool active)
This signal is emitted for all kind of jobs when they have finished.
static SieveJob * put(const QUrl &destination, const QString &script, bool makeActive, bool wasActive)
Stores a sieve script on an IMAP server.
Definition sievejob.cpp:278
static SieveJob * get(const QUrl &source)
Gets a sieve script from an IMAP server.
Definition sievejob.cpp:300
static KSharedConfig::Ptr openStateConfig(const QString &fileName=QString())
The CheckScriptJob class.
The SieveImapAccountSettings class.
The SieveImapPasswordProvider class.
The SieveEditor class.
Definition sieveeditor.h:23
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
KGuiItem close()
const QList< QKeySequence > & close()
void clicked(bool checked)
void addLayout(QLayout *layout, int stretch)
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
bool isValid() const const
bool isEmpty() const const
WA_DeleteOnClose
WindowModal
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
virtual bool event(QEvent *event) override
void setDisabled(bool disable)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:14:30 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.