Libksieve

sievescriptlistbox.cpp
1/*
2 SPDX-FileCopyrightText: 2013-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7#include "sievescriptlistbox.h"
8#include "sieveeditorgraphicalmodewidget.h"
9#include "sieveforeverypartwidget.h"
10#include "sieveglobalvariablewidget.h"
11#include "sieveincludewidget.h"
12#include "sievescriptdescriptiondialog.h"
13#include "sievescriptpage.h"
14#include <KLocalizedString>
15#include <KMessageBox>
16#include <QHBoxLayout>
17#include <QIcon>
18#include <QInputDialog>
19#include <QPushButton>
20#include <QXmlStreamReader>
21
22#include "libksieveui_debug.h"
23#include <QListWidget>
24#include <QMenu>
25#include <QPointer>
26#include <QVBoxLayout>
27
28namespace
29{
30inline const QString defaultScriptName()
31{
32 return QStringLiteral("SCRIPTNAME: ");
33}
34
35inline const QString roundcubeRuleName()
36{
37 return QStringLiteral(" rule:");
38}
39}
40
41using namespace KSieveUi;
42
43SieveScriptListItem::SieveScriptListItem(const QString &text, QListWidget *parent)
44 : QListWidgetItem(text, parent)
45{
46}
47
48SieveScriptListItem::~SieveScriptListItem() = default;
49
50void SieveScriptListItem::setDescription(const QString &desc)
51{
52 mDescription = desc;
53}
54
55QString SieveScriptListItem::description() const
56{
57 return mDescription;
58}
59
60SieveScriptPage *SieveScriptListItem::scriptPage() const
61{
62 return mScriptPage;
63}
64
65void SieveScriptListItem::setScriptPage(SieveScriptPage *page)
66{
67 mScriptPage = page;
68}
69
70QString SieveScriptListItem::generatedScript(QStringList &required) const
71{
72 QString script;
73 if (!mDescription.trimmed().isEmpty()) {
74 const QList<QStringView> commentList = QStringView(mDescription).split(QLatin1Char('\n'));
75 for (const QStringView str : commentList) {
76 if (str.isEmpty()) {
77 script += QLatin1Char('\n');
78 } else {
79 script += QLatin1Char('#') + str + QLatin1Char('\n');
80 }
81 }
82 }
83 if (mScriptPage) {
84 mScriptPage->generatedScript(script, required);
85 }
86 return script;
87}
88
89SieveScriptListBox::SieveScriptListBox(const QString &title, QWidget *parent)
90 : QGroupBox(title, parent)
91 , mSieveListScript(new QListWidget(this))
92{
93 auto layout = new QVBoxLayout(this);
94 layout->setObjectName(QLatin1StringView("layout"));
95 mSieveListScript->setObjectName(QLatin1StringView("mSieveListScript"));
96 mSieveListScript->setDragDropMode(QAbstractItemView::InternalMove);
97 mSieveListScript->setContextMenuPolicy(Qt::CustomContextMenu);
98 connect(mSieveListScript, &QListWidget::customContextMenuRequested, this, &SieveScriptListBox::slotCustomMenuRequested);
99 layout->addWidget(mSieveListScript);
100
101 //----------- the first row of buttons
102 auto hb = new QWidget(this);
103 auto hbHBoxLayout = new QHBoxLayout(hb);
104 hbHBoxLayout->setContentsMargins({});
105 hbHBoxLayout->setSpacing(4);
106
107 mBtnTop = new QPushButton(hb);
108 hbHBoxLayout->addWidget(mBtnTop);
109 mBtnTop->setIcon(QIcon::fromTheme(QStringLiteral("go-top")));
110 mBtnTop->setMinimumSize(mBtnTop->sizeHint() * 1.2);
111
112 mBtnUp = new QPushButton(hb);
113 hbHBoxLayout->addWidget(mBtnUp);
114 mBtnUp->setAutoRepeat(true);
115 mBtnUp->setIcon(QIcon::fromTheme(QStringLiteral("go-up")));
116 mBtnUp->setMinimumSize(mBtnUp->sizeHint() * 1.2);
117 mBtnDown = new QPushButton(hb);
118 hbHBoxLayout->addWidget(mBtnDown);
119 mBtnDown->setAutoRepeat(true);
120 mBtnDown->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
121 mBtnDown->setMinimumSize(mBtnDown->sizeHint() * 1.2);
122
123 mBtnBottom = new QPushButton(hb);
124 hbHBoxLayout->addWidget(mBtnBottom);
125 mBtnBottom->setIcon(QIcon::fromTheme(QStringLiteral("go-bottom")));
126 mBtnBottom->setMinimumSize(mBtnBottom->sizeHint() * 1.2);
127
128 mBtnUp->setToolTip(i18nc("Move selected filter up.", "Up"));
129 mBtnDown->setToolTip(i18nc("Move selected filter down.", "Down"));
130 mBtnTop->setToolTip(i18nc("Move selected filter to the top.", "Top"));
131 mBtnBottom->setToolTip(i18nc("Move selected filter to the bottom.", "Bottom"));
132
133 layout->addWidget(hb);
134
135 hb = new QWidget(this);
136 hbHBoxLayout = new QHBoxLayout(hb);
137 hbHBoxLayout->setContentsMargins({});
138 hbHBoxLayout->setSpacing(4);
139
140 mBtnNew = new QPushButton(hb);
141 hbHBoxLayout->addWidget(mBtnNew);
142 mBtnNew->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
143 mBtnNew->setToolTip(i18n("New Script"));
144 mBtnNew->setMinimumSize(mBtnNew->sizeHint() * 1.2);
145
146 mBtnDelete = new QPushButton(hb);
147 hbHBoxLayout->addWidget(mBtnDelete);
148 mBtnDelete->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
149 mBtnDelete->setToolTip(i18n("Delete Script"));
150 mBtnDelete->setMinimumSize(mBtnDelete->sizeHint() * 1.2);
151
152 mBtnRename = new QPushButton(hb);
153 mBtnRename->setToolTip(i18n("Rename Script"));
154 mBtnRename->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
155 mBtnRename->setMinimumSize(mBtnRename->sizeHint() * 1.2);
156 hbHBoxLayout->addWidget(mBtnRename);
157
158 mBtnDescription = new QPushButton(hb);
159 mBtnDescription->setToolTip(i18n("Edit Script Description"));
160 mBtnDescription->setIcon(QIcon::fromTheme(QStringLiteral("edit-comment")));
161 mBtnDescription->setMinimumSize(mBtnDescription->sizeHint() * 1.2);
162
163 hbHBoxLayout->addWidget(mBtnDescription);
164
165 layout->addWidget(hb);
166
167 connect(mBtnNew, &QPushButton::clicked, this, &SieveScriptListBox::slotNew);
168 connect(mBtnDelete, &QPushButton::clicked, this, &SieveScriptListBox::slotDelete);
169 connect(mBtnRename, &QPushButton::clicked, this, &SieveScriptListBox::slotRename);
170 connect(mBtnDescription, &QPushButton::clicked, this, &SieveScriptListBox::slotEditDescription);
171
172 connect(mBtnUp, &QPushButton::clicked, this, &SieveScriptListBox::slotUp);
173 connect(mBtnDown, &QPushButton::clicked, this, &SieveScriptListBox::slotDown);
174 connect(mBtnTop, &QPushButton::clicked, this, &SieveScriptListBox::slotTop);
175 connect(mBtnBottom, &QPushButton::clicked, this, &SieveScriptListBox::slotBottom);
176
177 connect(mSieveListScript, &QListWidget::itemSelectionChanged, this, &SieveScriptListBox::updateButtons);
178 connect(mSieveListScript, &QListWidget::itemClicked, this, &SieveScriptListBox::slotItemClicked);
179 connect(mSieveListScript, &QListWidget::itemDoubleClicked, this, &SieveScriptListBox::slotEditDescription);
180 updateButtons();
181}
182
183SieveScriptListBox::~SieveScriptListBox() = default;
184
185void SieveScriptListBox::slotCustomMenuRequested(const QPoint &pos)
186{
187 QMenu menu(this);
188 QAction *newScriptAction = menu.addAction(i18nc("@action:inmenu", "New Script"));
189 newScriptAction->setIcon(QIcon::fromTheme(QStringLiteral("document-new")));
190 connect(newScriptAction, &QAction::triggered, this, &SieveScriptListBox::slotNew);
191
192 if (mSieveListScript->itemAt(pos)) {
193 QAction *renameScriptAction = menu.addAction(i18nc("@action:inmenu", "Rename Script"));
194 renameScriptAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
195 connect(renameScriptAction, &QAction::triggered, this, &SieveScriptListBox::slotRename);
196
197 menu.addSeparator();
198 QAction *editScriptDescriptionAction = menu.addAction(i18nc("@action:inmenu", "Edit Script Description"));
199 editScriptDescriptionAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-comment")));
200 connect(editScriptDescriptionAction, &QAction::triggered, this, &SieveScriptListBox::slotEditDescription);
201
202 menu.addSeparator();
203 QAction *deleteScriptAction = menu.addAction(i18nc("@action:inmenu", "Delete Script"));
204 deleteScriptAction->setIcon(QIcon::fromTheme(QStringLiteral("edit-delete")));
205 connect(deleteScriptAction, &QAction::triggered, this, &SieveScriptListBox::slotDelete);
206 }
207 menu.exec(QCursor::pos());
208}
209
210void SieveScriptListBox::setSieveEditorGraphicalModeWidget(SieveEditorGraphicalModeWidget *graphicalModeWidget)
211{
212 mSieveGraphicalModeWidget = graphicalModeWidget;
213}
214
215void SieveScriptListBox::slotItemClicked(QListWidgetItem *item)
216{
217 if (item) {
218 auto itemScript = static_cast<SieveScriptListItem *>(item);
219 Q_EMIT activatePage(itemScript->scriptPage());
220 }
221}
222
223void SieveScriptListBox::updateButtons()
224{
225 const int currentIndex = mSieveListScript->currentRow();
226 const bool theFirst = (currentIndex == 0);
227 const int numberOfElement(mSieveListScript->count());
228 const bool theLast = (currentIndex >= numberOfElement - 1);
229
230 const QList<QListWidgetItem *> lst = mSieveListScript->selectedItems();
231 mBtnDelete->setEnabled(!lst.isEmpty());
232 mBtnRename->setEnabled(lst.count() == 1);
233 mBtnDescription->setEnabled(lst.count() == 1);
234 mBtnBottom->setEnabled(!lst.isEmpty() && !theLast);
235 mBtnTop->setEnabled(!lst.isEmpty() && !theFirst);
236 mBtnDown->setEnabled(!lst.isEmpty() && !theLast);
237 mBtnUp->setEnabled(!lst.isEmpty() && !theFirst);
238}
239
240SieveScriptPage *SieveScriptListBox::createNewScript(const QString &newName, const QString &description)
241{
242 auto item = new SieveScriptListItem(newName, mSieveListScript);
243 item->setDescription(description);
244 auto page = new SieveScriptPage(mSieveGraphicalModeWidget);
245 page->setListOfIncludeFile(mSieveGraphicalModeWidget->listOfIncludeFile());
246 item->setScriptPage(page);
247 Q_EMIT addNewPage(page);
248 Q_EMIT enableButtonOk(true);
249 mSieveListScript->setCurrentItem(item);
250 updateButtons();
251 return page;
252}
253
254void SieveScriptListBox::slotNew()
255{
256 bool ok;
257 const QString newName = QInputDialog::getText(this, i18nc("@title:window", "New Script"), i18n("New script name:"), {}, {}, &ok);
258 if (!newName.trimmed().isEmpty() && ok) {
259 createNewScript(newName);
260 Q_EMIT valueChanged();
261 }
262}
263
264void SieveScriptListBox::slotDelete()
265{
266 QListWidgetItem *item = mSieveListScript->currentItem();
267 if (item) {
268 const int answer = KMessageBox::warningTwoActions(this,
269 i18n("Do you want to delete \"%1\" script?", item->text()),
270 i18nc("@title:window", "Delete Script"),
273 if (answer == KMessageBox::ButtonCode::PrimaryAction) {
274 auto itemScript = static_cast<SieveScriptListItem *>(item);
275 Q_EMIT removePage(itemScript->scriptPage());
276 delete item;
277 Q_EMIT enableButtonOk(mSieveListScript->count() > 0);
278 updateButtons();
279 Q_EMIT valueChanged();
280 }
281 }
282}
283
284void SieveScriptListBox::slotRename()
285{
286 QListWidgetItem *item = mSieveListScript->currentItem();
287 if (item) {
288 bool ok = false;
289 QString newName =
290 QInputDialog::getText(this, i18nc("@title:window", "Rename Script"), i18n("New name for the script:"), QLineEdit::Normal, item->text(), &ok);
291 if (ok) {
292 newName = newName.trimmed();
293 if (!newName.isEmpty()) {
294 item->setText(newName);
295 Q_EMIT valueChanged();
296 }
297 }
298 }
299}
300
301void SieveScriptListBox::slotEditDescription()
302{
303 QListWidgetItem *item = mSieveListScript->currentItem();
304 if (item) {
305 auto sieveItem = static_cast<SieveScriptListItem *>(item);
306 QPointer<SieveScriptDescriptionDialog> dlg = new SieveScriptDescriptionDialog(this);
307 dlg->setDescription(sieveItem->description());
308 if (dlg->exec()) {
309 sieveItem->setDescription(dlg->description());
310 Q_EMIT valueChanged();
311 }
312 delete dlg;
313 }
314}
315
316void SieveScriptListBox::slotTop()
317{
318 QListWidgetItem *item = mSieveListScript->currentItem();
319 if (item) {
320 const int currentIndex = mSieveListScript->currentRow();
321 if (currentIndex != 0) {
322 item = mSieveListScript->takeItem(currentIndex);
323 mSieveListScript->insertItem(0, item);
324 mSieveListScript->setCurrentItem(item);
325 Q_EMIT valueChanged();
326 }
327 }
328}
329
330void SieveScriptListBox::slotBottom()
331{
332 QListWidgetItem *item = mSieveListScript->currentItem();
333 if (item) {
334 const int currentIndex = mSieveListScript->currentRow();
335 if (currentIndex != mSieveListScript->count() - 1) {
336 item = mSieveListScript->takeItem(currentIndex);
337 mSieveListScript->insertItem(mSieveListScript->count(), item);
338 mSieveListScript->setCurrentItem(item);
339 Q_EMIT valueChanged();
340 }
341 }
342}
343
344void SieveScriptListBox::slotDown()
345{
346 QListWidgetItem *item = mSieveListScript->currentItem();
347 if (item) {
348 const int currentIndex = mSieveListScript->currentRow();
349 if (currentIndex < mSieveListScript->count() - 1) {
350 item = mSieveListScript->takeItem(currentIndex);
351 mSieveListScript->insertItem(currentIndex + 1, item);
352 mSieveListScript->setCurrentItem(item);
353 Q_EMIT valueChanged();
354 }
355 }
356}
357
358void SieveScriptListBox::slotUp()
359{
360 QListWidgetItem *item = mSieveListScript->currentItem();
361 if (item) {
362 const int currentIndex = mSieveListScript->currentRow();
363 if (currentIndex >= 1) {
364 item = mSieveListScript->takeItem(currentIndex);
365 mSieveListScript->insertItem(currentIndex - 1, item);
366 mSieveListScript->setCurrentItem(item);
367 Q_EMIT valueChanged();
368 }
369 }
370}
371
372QString SieveScriptListBox::generatedScript(QStringList &requireModules) const
373{
374 QString resultScript;
375 QStringList lstRequires;
376 const int numberOfScripts(mSieveListScript->count());
377 for (int i = 0; i < numberOfScripts; ++i) {
378 auto item = static_cast<SieveScriptListItem *>(mSieveListScript->item(i));
379 if (i != 0) {
380 resultScript += QLatin1StringView("\n\n");
381 }
382 resultScript += QLatin1Char('#') + QStringLiteral("%1[%2]").arg(roundcubeRuleName(), item->text()) + QLatin1Char('\n');
383 resultScript += item->generatedScript(lstRequires);
384 }
385 if (!resultScript.isEmpty()) {
386 resultScript += QLatin1Char('\n');
387 }
388
389 QStringList endRequires;
390 for (const QString &r : std::as_const(lstRequires)) {
391 if (!endRequires.contains(r)) {
392 endRequires.append(r);
393 requireModules += QStringLiteral("require \"%1\";").arg(r);
394 }
395 }
396
397 return resultScript;
398}
399
400void SieveScriptListBox::clear()
401{
402 mScriptNumber = 0;
403 Q_EMIT enableButtonOk(false);
404 // Clear tabpage
405 mSieveListScript->clear();
406 updateButtons();
407}
408
409void SieveScriptListBox::loadScript(const QString &doc, QString &error)
410{
411 clear();
412 QXmlStreamReader streamReader(doc);
413 if (streamReader.readNextStartElement()) {
414 if (streamReader.name() == QLatin1StringView("script")) {
415 SieveScriptPage *currentPage = nullptr;
416 ParseSieveScriptTypeBlock typeBlock = TypeUnknown;
417 loadBlock(streamReader, currentPage, typeBlock, error);
418 }
419 }
420}
421
422void SieveScriptListBox::loadBlock(QXmlStreamReader &n, SieveScriptPage *currentPage, ParseSieveScriptTypeBlock typeBlock, QString &error)
423{
424 QString scriptName;
425 QString comment;
426 bool hasCreatedAIfBlock = false;
427 bool previousElementWasAComment = false;
428 while (n.readNextStartElement()) {
429 const QStringView tagName = n.name();
430 // qDebug() <<"SieveScriptListBox::loadBlock tagName " << tagName;
431 if (tagName == QLatin1StringView("control")) {
432 previousElementWasAComment = false;
433 // Create a new page when before it was "onlyactions"
434 if (typeBlock == TypeBlockAction) {
435 currentPage = nullptr;
436 }
437 if (n.attributes().hasAttribute(QLatin1StringView("name"))) {
438 const QString controlType = n.attributes().value(QLatin1StringView("name")).toString();
439 // qCDebug(LIBKSIEVEUI_LOG)<<" controlType"<<controlType;
440 if (controlType == QLatin1StringView("if")) {
441 typeBlock = TypeBlockIf;
442 if (!currentPage || hasCreatedAIfBlock) {
443 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
444 }
445 hasCreatedAIfBlock = true;
446 comment.clear();
447 currentPage->blockIfWidget()->loadScript(n, false, error);
448 } else if (controlType == QLatin1StringView("elsif")) {
449 typeBlock = TypeBlockElsif;
450 if (!currentPage) {
451 qCDebug(LIBKSIEVEUI_LOG) << " script is not correct missing if block";
452 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
453 }
454 SieveScriptBlockWidget *blockWidget = currentPage->addScriptBlock(KSieveUi::SieveWidgetPageAbstract::BlockElsIf);
455 if (blockWidget) {
456 blockWidget->loadScript(n, false, error);
457 }
458 } else if (controlType == QLatin1StringView("else")) {
459 typeBlock = TypeBlockElse;
460 if (!currentPage) {
461 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
462 qCDebug(LIBKSIEVEUI_LOG) << " script is not correct missing if block";
463 }
464 SieveScriptBlockWidget *blockWidget = currentPage->addScriptBlock(KSieveUi::SieveWidgetPageAbstract::BlockElse);
465 if (blockWidget) {
466 blockWidget->loadScript(n, false, error);
467 }
468 // We are sure that we can't have another elsif
469 currentPage = nullptr;
470 } else if (controlType == QLatin1StringView("foreverypart")) {
471 typeBlock = TypeBlockForeachBlock;
472 if (!currentPage) {
473 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
474 comment.clear();
475 }
476 if (currentPage->forEveryPartWidget()) {
477 currentPage->forEveryPartWidget()->loadScript(n, error);
478 } else {
479 error += i18n("forEveryPart is not supported by your server") + QLatin1Char('\n');
480 }
481 // TODO verify it.
482#ifdef QDOMELEMENT_FIXME
483 QDomNode block = e.firstChildElement(QStringLiteral("block")).firstChild();
484 loadBlock(block, currentPage, typeBlock, error);
485#endif
486 } else if (controlType == QLatin1StringView("require")) {
488 // Nothing. autogenerated
489 } else {
490 qCDebug(LIBKSIEVEUI_LOG) << " unknown controlType :" << controlType;
491 }
492 }
493 } else if (tagName == QLatin1StringView("comment")) {
494 previousElementWasAComment = true;
495#ifdef FIXME_COMMENT
496 if (e.hasAttribute(QStringLiteral("hash"))) {
497 // TODO
498 } else if (e.hasAttribute(QStringLiteral("bracket"))) {
499 // TODO
500 }
501#endif
502 QString str(n.readElementText());
503 if (str.contains(defaultScriptName())) {
504 scriptName = str.remove(defaultScriptName());
505 } else if (str.contains(roundcubeRuleName())) {
506 scriptName = str.remove(roundcubeRuleName());
507 if (scriptName.startsWith(QLatin1Char('[')) && scriptName.endsWith(QLatin1Char(']'))) {
508 scriptName.removeAt(0);
509 scriptName.removeAt(scriptName.length() - 1);
510 }
511 } else {
512 if (!comment.isEmpty()) {
513 comment += QLatin1Char('\n');
514 }
515 comment += str;
516 }
517 // qDebug() << " COMMENT " << comment;
518 } else if (tagName == QLatin1StringView("action")) {
519 previousElementWasAComment = false;
520 if (n.attributes().hasAttribute(QLatin1StringView("name"))) {
521 const QString actionName = n.attributes().value(QLatin1StringView("name")).toString();
522 if (actionName == QLatin1StringView("include")) {
523 if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
524 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
525 comment.clear();
526 }
527 typeBlock = TypeBlockInclude;
528 if (currentPage->includeWidget()) {
529 currentPage->includeWidget()->loadScript(n, error);
530 } else {
531 qCDebug(LIBKSIEVEUI_LOG) << " include not supported";
532 }
533 } else if (actionName == QLatin1StringView("global")) {
534 if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
535 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
536 comment.clear();
537 }
538 typeBlock = TypeBlockGlobal;
539 if (currentPage->globalVariableWidget()) {
540 currentPage->globalVariableWidget()->loadScript(n, error);
541 } else {
542 qCDebug(LIBKSIEVEUI_LOG) << " globalVariable not supported";
543 }
544 } else if (actionName == QLatin1StringView("set") && (typeBlock == TypeBlockGlobal)) {
545 // FIXME global not global variable.
546 if (currentPage->globalVariableWidget()) {
547 const SieveGlobalVariableActionWidget::VariableElement var = currentPage->globalVariableWidget()->loadSetVariable(n, error);
548 if (var.isValid()) {
549 qCDebug(LIBKSIEVEUI_LOG) << "It's not a global variable";
550 if ((typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
551 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
552 }
553 typeBlock = TypeBlockAction;
554 comment.clear();
555 currentPage->blockIfWidget()->loadLocalVariable(var);
556 }
557 } else {
558 qCDebug(LIBKSIEVEUI_LOG) << " set not supported";
559 }
560 } else {
561 if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
562 currentPage = createNewScript(scriptName.isEmpty() ? createUniqName() : scriptName, comment);
563 }
564 typeBlock = TypeBlockAction;
565 comment.clear();
566 currentPage->blockIfWidget()->loadScript(n, true, error);
567 }
568 }
569 } else if (tagName == QLatin1StringView("crlf")) {
570 // If it was a comment previously you will create a \n
571 if (previousElementWasAComment) {
572 comment += QLatin1Char('\n');
573 }
575 } else {
576 qCDebug(LIBKSIEVEUI_LOG) << " unknown tagname" << tagName;
577 }
578 }
579}
580
581QString SieveScriptListBox::createUniqName()
582{
583 const QString pattern = i18n("Script part %1", mScriptNumber);
584 ++mScriptNumber;
585 return pattern;
586}
587
588#include "moc_sievescriptlistbox.cpp"
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ButtonCode warningTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
KGuiItem cancel()
KGuiItem del()
void clicked(bool checked)
void setIcon(const QIcon &icon)
void triggered(bool checked)
QPoint pos()
QDomNode firstChild() const const
QDomElement firstChildElement(const QString &tagName, const QString &namespaceURI) const const
QIcon fromTheme(const QString &name)
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
void append(QList< T > &&value)
qsizetype count() const const
bool isEmpty() const const
void clear()
QListWidgetItem * currentItem() const const
void insertItem(int row, QListWidgetItem *item)
QListWidgetItem * item(int row) const const
QListWidgetItem * itemAt(const QPoint &p) const const
void itemClicked(QListWidgetItem *item)
void itemDoubleClicked(QListWidgetItem *item)
void itemSelectionChanged()
QList< QListWidgetItem * > selectedItems() const const
void setCurrentItem(QListWidgetItem *item)
QListWidgetItem * takeItem(int row)
void setText(const QString &text)
QString text() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void clear()
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype length() const const
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & removeAt(qsizetype pos)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString trimmed() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QList< QStringView > split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QString toString() const const
CustomContextMenu
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void customContextMenuRequested(const QPoint &pos)
void setEnabled(bool)
bool hasAttribute(QAnyStringView namespaceUri, QAnyStringView name) const const
QStringView value(QAnyStringView namespaceUri, QAnyStringView name) const const
QXmlStreamAttributes attributes() const const
QStringView name() const const
QString readElementText(ReadElementTextBehaviour behaviour)
bool readNextStartElement()
void skipCurrentElement()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:17:19 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.