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> 18 #include <QInputDialog> 19 #include <QPushButton> 20 #include <QXmlStreamReader> 22 #include "libksieve_debug.h" 23 #include <QListWidget> 26 #include <QVBoxLayout> 30 inline const QString defaultScriptName()
32 return QStringLiteral(
"SCRIPTNAME: ");
43 SieveScriptListItem::~SieveScriptListItem()
47 void SieveScriptListItem::setDescription(
const QString &desc)
52 QString SieveScriptListItem::description()
const 57 SieveScriptPage *SieveScriptListItem::scriptPage()
const 62 void SieveScriptListItem::setScriptPage(SieveScriptPage *page)
70 if (!mDescription.trimmed().isEmpty()) {
81 mScriptPage->generatedScript(script, required);
92 mSieveListScript->setObjectName(QStringLiteral(
"mSieveListScript"));
101 hbHBoxLayout->setContentsMargins({});
102 hbHBoxLayout->setSpacing(4);
105 hbHBoxLayout->addWidget(mBtnTop);
107 mBtnTop->setMinimumSize(mBtnTop->sizeHint() * 1.2);
110 hbHBoxLayout->addWidget(mBtnUp);
111 mBtnUp->setAutoRepeat(
true);
113 mBtnUp->setMinimumSize(mBtnUp->sizeHint() * 1.2);
115 hbHBoxLayout->addWidget(mBtnDown);
116 mBtnDown->setAutoRepeat(
true);
118 mBtnDown->setMinimumSize(mBtnDown->sizeHint() * 1.2);
121 hbHBoxLayout->addWidget(mBtnBottom);
123 mBtnBottom->setMinimumSize(mBtnBottom->sizeHint() * 1.2);
125 mBtnUp->setToolTip(
i18nc(
"Move selected filter up.",
"Up"));
126 mBtnDown->setToolTip(
i18nc(
"Move selected filter down.",
"Down"));
127 mBtnTop->setToolTip(
i18nc(
"Move selected filter to the top.",
"Top"));
128 mBtnBottom->setToolTip(
i18nc(
"Move selected filter to the bottom.",
"Bottom"));
134 hbHBoxLayout->setContentsMargins({});
135 hbHBoxLayout->setSpacing(4);
138 hbHBoxLayout->addWidget(mBtnNew);
140 mBtnNew->setToolTip(
i18n(
"New Script"));
141 mBtnNew->setMinimumSize(mBtnNew->sizeHint() * 1.2);
144 hbHBoxLayout->addWidget(mBtnDelete);
146 mBtnDelete->setToolTip(
i18n(
"Delete Script"));
147 mBtnDelete->setMinimumSize(mBtnDelete->sizeHint() * 1.2);
150 mBtnRename->setToolTip(
i18n(
"Rename Script"));
152 mBtnRename->setMinimumSize(mBtnRename->sizeHint() * 1.2);
153 hbHBoxLayout->addWidget(mBtnRename);
156 mBtnDescription->setToolTip(
i18n(
"Edit Script Description"));
158 mBtnDescription->setMinimumSize(mBtnDescription->sizeHint() * 1.2);
160 hbHBoxLayout->addWidget(mBtnDescription);
180 SieveScriptListBox::~SieveScriptListBox()
184 void SieveScriptListBox::slotCustomMenuRequested(
const QPoint &
pos)
187 QAction *newScriptAction = menu.addAction(
i18nc(
"@action:inmenu",
"New Script"));
191 if (mSieveListScript->itemAt(pos)) {
192 QAction *renameScriptAction = menu.addAction(
i18nc(
"@action:inmenu",
"Rename Script"));
197 QAction *deleteScriptAction = menu.addAction(
i18nc(
"@action:inmenu",
"Delete Script"));
204 void SieveScriptListBox::setSieveEditorGraphicalModeWidget(SieveEditorGraphicalModeWidget *graphicalModeWidget)
206 mSieveGraphicalModeWidget = graphicalModeWidget;
212 auto itemScript =
static_cast<SieveScriptListItem *
>(item);
213 Q_EMIT activatePage(itemScript->scriptPage());
217 void SieveScriptListBox::updateButtons()
219 const int currentIndex = mSieveListScript->currentRow();
220 const bool theFirst = (currentIndex == 0);
221 const int numberOfElement(mSieveListScript->count());
222 const bool theLast = (currentIndex >= numberOfElement - 1);
225 mBtnDelete->setEnabled(!lst.
isEmpty());
226 mBtnRename->setEnabled(lst.
count() == 1);
227 mBtnDescription->setEnabled(lst.
count() == 1);
228 mBtnBottom->setEnabled(!lst.
isEmpty() && !theLast);
229 mBtnTop->setEnabled(!lst.
isEmpty() && !theFirst);
230 mBtnDown->setEnabled(!lst.
isEmpty() && !theLast);
231 mBtnUp->setEnabled(!lst.
isEmpty() && !theFirst);
234 SieveScriptPage *SieveScriptListBox::createNewScript(
const QString &newName,
const QString &description)
236 auto item =
new SieveScriptListItem(newName, mSieveListScript);
237 item->setDescription(description);
238 auto page =
new SieveScriptPage(mSieveGraphicalModeWidget);
239 page->setListOfIncludeFile(mSieveGraphicalModeWidget->listOfIncludeFile());
240 item->setScriptPage(page);
242 Q_EMIT enableButtonOk(
true);
243 mSieveListScript->setCurrentItem(item);
248 void SieveScriptListBox::slotNew()
252 createNewScript(newName);
257 void SieveScriptListBox::slotDelete()
262 == KMessageBox::Yes) {
263 auto itemScript =
static_cast<SieveScriptListItem *
>(item);
264 Q_EMIT removePage(itemScript->scriptPage());
266 Q_EMIT enableButtonOk(mSieveListScript->count() > 0);
273 void SieveScriptListBox::slotRename()
280 if (!newName.isEmpty()) {
287 void SieveScriptListBox::slotEditDescription()
291 auto sieveItem =
static_cast<SieveScriptListItem *
>(item);
293 dlg->setDescription(sieveItem->description());
295 sieveItem->setDescription(dlg->description());
302 void SieveScriptListBox::slotTop()
306 const int currentIndex = mSieveListScript->currentRow();
307 if (currentIndex != 0) {
308 item = mSieveListScript->takeItem(currentIndex);
309 mSieveListScript->insertItem(0, item);
310 mSieveListScript->setCurrentItem(item);
316 void SieveScriptListBox::slotBottom()
320 const int currentIndex = mSieveListScript->currentRow();
321 if (currentIndex != mSieveListScript->count() - 1) {
322 item = mSieveListScript->takeItem(currentIndex);
323 mSieveListScript->insertItem(mSieveListScript->count(), item);
324 mSieveListScript->setCurrentItem(item);
330 void SieveScriptListBox::slotDown()
334 const int currentIndex = mSieveListScript->currentRow();
335 if (currentIndex < mSieveListScript->count() - 1) {
336 item = mSieveListScript->takeItem(currentIndex);
337 mSieveListScript->insertItem(currentIndex + 1, item);
338 mSieveListScript->setCurrentItem(item);
344 void SieveScriptListBox::slotUp()
348 const int currentIndex = mSieveListScript->currentRow();
349 if (currentIndex >= 1) {
350 item = mSieveListScript->takeItem(currentIndex);
351 mSieveListScript->insertItem(currentIndex - 1, item);
352 mSieveListScript->setCurrentItem(item);
362 const int numberOfScripts(mSieveListScript->count());
363 for (
int i = 0; i < numberOfScripts; ++i) {
364 auto item =
static_cast<SieveScriptListItem *
>(mSieveListScript->item(i));
369 resultScript += item->generatedScript(lstRequires);
376 for (
const QString &r : qAsConst(lstRequires)) {
379 requireModules += QStringLiteral(
"require \"%1\";").arg(r);
386 void SieveScriptListBox::clear()
389 Q_EMIT enableButtonOk(
false);
391 mSieveListScript->clear();
395 void SieveScriptListBox::loadScript(
const QString &doc,
QString &error)
399 if (streamReader.readNextStartElement()) {
401 SieveScriptPage *currentPage =
nullptr;
402 ParseSieveScriptTypeBlock typeBlock = TypeUnknown;
403 loadBlock(streamReader, currentPage, typeBlock, error);
408 void SieveScriptListBox::loadBlock(
QXmlStreamReader &n, SieveScriptPage *currentPage, ParseSieveScriptTypeBlock typeBlock,
QString &error)
412 bool hasCreatedAIfBlock =
false;
413 bool previousElementWasAComment =
false;
418 previousElementWasAComment =
false;
420 if (typeBlock == TypeBlockAction) {
421 currentPage =
nullptr;
427 typeBlock = TypeBlockIf;
428 if (!currentPage || hasCreatedAIfBlock) {
429 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
431 hasCreatedAIfBlock =
true;
433 currentPage->blockIfWidget()->loadScript(n,
false, error);
435 typeBlock = TypeBlockElsif;
437 qCDebug(LIBKSIEVE_LOG) <<
" script is not correct missing if block";
438 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
440 SieveScriptBlockWidget *blockWidget = currentPage->addScriptBlock(KSieveUi::SieveWidgetPageAbstract::BlockElsIf);
442 blockWidget->loadScript(n,
false, error);
445 typeBlock = TypeBlockElse;
447 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
448 qCDebug(LIBKSIEVE_LOG) <<
" script is not correct missing if block";
450 SieveScriptBlockWidget *blockWidget = currentPage->addScriptBlock(KSieveUi::SieveWidgetPageAbstract::BlockElse);
452 blockWidget->loadScript(n,
false, error);
455 currentPage =
nullptr;
457 typeBlock = TypeBlockForeachBlock;
459 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
462 if (currentPage->forEveryPartWidget()) {
463 currentPage->forEveryPartWidget()->loadScript(n, error);
465 error +=
i18n(
"forEveryPart is not supported by your server") +
QLatin1Char(
'\n');
468 #ifdef QDOMELEMENT_FIXME 470 loadBlock(block, currentPage, typeBlock, error);
476 qCDebug(LIBKSIEVE_LOG) <<
" unknown controlType :" << controlType;
480 previousElementWasAComment =
true;
482 if (e.hasAttribute(QStringLiteral(
"hash"))) {
484 }
else if (e.hasAttribute(QStringLiteral(
"bracket"))) {
489 if (str.contains(defaultScriptName())) {
490 scriptName = str.
remove(defaultScriptName());
499 previousElementWasAComment =
false;
503 if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
504 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
507 typeBlock = TypeBlockInclude;
508 if (currentPage->includeWidget()) {
509 currentPage->includeWidget()->loadScript(n, error);
511 qCDebug(LIBKSIEVE_LOG) <<
" include not supported";
514 if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
515 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
518 typeBlock = TypeBlockGlobal;
519 if (currentPage->globalVariableWidget()) {
520 currentPage->globalVariableWidget()->loadScript(n, error);
522 qCDebug(LIBKSIEVE_LOG) <<
" globalVariable not supported";
524 }
else if (actionName ==
QLatin1String(
"set") && (typeBlock == TypeBlockGlobal)) {
526 if (currentPage->globalVariableWidget()) {
527 const SieveGlobalVariableActionWidget::VariableElement var = currentPage->globalVariableWidget()->loadSetVariable(n, error);
529 qCDebug(LIBKSIEVE_LOG) <<
"It's not a global variable";
530 if ((typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
531 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
533 typeBlock = TypeBlockAction;
535 currentPage->blockIfWidget()->loadLocalVariable(var);
538 qCDebug(LIBKSIEVE_LOG) <<
" set not supported";
541 if (!currentPage || (typeBlock == TypeBlockIf) || (typeBlock == TypeBlockElse) || (typeBlock == TypeBlockElsif)) {
542 currentPage = createNewScript(scriptName.
isEmpty() ? createUniqName() : scriptName, comment);
544 typeBlock = TypeBlockAction;
546 currentPage->blockIfWidget()->loadScript(n,
true, error);
551 if (previousElementWasAComment) {
556 qCDebug(LIBKSIEVE_LOG) <<
" unknown tagname" << tagName;
561 QString SieveScriptListBox::createUniqName()
void triggered(bool checked)
bool readNextStartElement()
QString toString() const const
void setIcon(const QIcon &icon)
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QStringRef value(const QString &namespaceUri, const QString &name) const const
QString & remove(int position, int n)
void skipCurrentElement()
int count(const T &value) const const
void append(const T &value)
QString pattern(Mode mode=Reading)
QString readElementText(QXmlStreamReader::ReadElementTextBehaviour behaviour)
QString i18nc(const char *context, const char *text, const TYPE &arg...)
bool isEmpty() const const
void setObjectName(const QString &name)
bool isEmpty() const const
QString trimmed() const const
QString getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode, const QString &text, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
bool hasAttribute(const QString &qualifiedName) const const
QString i18n(const char *text, const TYPE &arg...)
QDomNode firstChild() const const
QDomElement firstChildElement(const QString &tagName) const const
QXmlStreamAttributes attributes() const const
QIcon fromTheme(const QString &name)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QStringRef name() const const
QString text() const const
void setText(const QString &text)
ButtonCode warningYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))