Libksieve

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

KDE's Doxygen guidelines are available online.