File indexing completed on 2024-12-29 04:54:48

0001 /*
0002   SPDX-FileCopyrightText: 2014-2024 Laurent Montel <montel@kde.org>
0003 
0004   SPDX-License-Identifier: LGPL-2.0-or-later
0005 
0006 */
0007 
0008 #include "sieveeditorwidget.h"
0009 #include "sievepurposemenuwidget.h"
0010 
0011 #include "autocreatescripts/sieveeditorgraphicalmodewidget.h"
0012 #include "editor/sieveinfodialog.h"
0013 #include "scriptsparsing/parsingutil.h"
0014 #include "sieve-editor.h"
0015 #include "sieveeditormenubar.h"
0016 #include "sieveeditortextmodewidget.h"
0017 
0018 #include "libksieveui_debug.h"
0019 #include <KActionMenu>
0020 #include <KLocalizedString>
0021 #include <KStandardAction>
0022 #include <PimCommon/PurposeMenuWidget>
0023 #include <QAction>
0024 #include <QLabel>
0025 #include <QLineEdit>
0026 #include <QPushButton>
0027 #include <QStackedWidget>
0028 #include <QStandardPaths>
0029 #include <QToolBar>
0030 #include <QVBoxLayout>
0031 #include <kzip.h>
0032 
0033 using namespace KSieveUi;
0034 
0035 SieveEditorWidget::SieveEditorWidget(bool useMenuBar, QWidget *parent)
0036     : QWidget(parent)
0037 {
0038     auto lay = new QVBoxLayout(this);
0039     lay->setContentsMargins({});
0040     mDebug = !qEnvironmentVariableIsEmpty("KDEPIM_DEBUGGING");
0041 
0042     auto toolbar = new QToolBar(this);
0043     toolbar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0044 
0045     mCheckSyntax = new QAction(i18n("Check Syntax"), this);
0046     connect(mCheckSyntax, &QAction::triggered, this, &SieveEditorWidget::slotCheckSyntax);
0047     toolbar->addAction(mCheckSyntax);
0048     mSaveAs = KStandardAction::saveAs(this, &SieveEditorWidget::slotSaveAs, this);
0049     toolbar->addAction(mSaveAs);
0050     toolbar->addAction(i18n("Import..."), this, &SieveEditorWidget::slotImport);
0051 
0052     mCreateRulesGraphically = new QAction(i18n("Create Rules Graphically..."), this);
0053     connect(mCreateRulesGraphically, &QAction::triggered, this, &SieveEditorWidget::slotCreateRulesGraphically);
0054     toolbar->addAction(mCreateRulesGraphically);
0055     mSwitchMode = new QAction(this);
0056     toolbar->addAction(mSwitchMode);
0057     connect(mSwitchMode, &QAction::triggered, this, &SieveEditorWidget::slotSwitchMode);
0058 
0059     if (mDebug) {
0060         // Not necessary to translate it.
0061         mGenerateXml = new QAction(QStringLiteral("Generate xml"), this);
0062         connect(mGenerateXml, &QAction::triggered, this, &SieveEditorWidget::slotGenerateXml);
0063         toolbar->addAction(mGenerateXml);
0064     }
0065     auto purposeMenu = new SievePurposeMenuWidget(this, this);
0066     auto shareAction = new KActionMenu(i18n("Share..."), this);
0067     shareAction->setPopupMode(QToolButton::InstantPopup);
0068     shareAction->setMenu(purposeMenu->menu());
0069     shareAction->setIcon(QIcon::fromTheme(QStringLiteral("document-share")));
0070     purposeMenu->setEditorWidget(this);
0071     toolbar->addAction(shareAction);
0072     mServerInfo = new QAction(i18n("Server Info"), this);
0073     connect(mServerInfo, &QAction::triggered, this, &SieveEditorWidget::slotServerInfo);
0074     toolbar->addAction(mServerInfo);
0075 
0076     SieveEditorMenuBar *menuBar = nullptr;
0077     if (useMenuBar) {
0078         menuBar = new SieveEditorMenuBar;
0079         connect(this, &SieveEditorWidget::changeModeEditor, menuBar, &SieveEditorMenuBar::setEditorMode);
0080         connect(menuBar, &SieveEditorMenuBar::copy, this, &SieveEditorWidget::copy);
0081         connect(menuBar, &SieveEditorMenuBar::find, this, &SieveEditorWidget::find);
0082         connect(menuBar, &SieveEditorMenuBar::replace, this, &SieveEditorWidget::replace);
0083         connect(menuBar, &SieveEditorMenuBar::undo, this, &SieveEditorWidget::undo);
0084         connect(menuBar, &SieveEditorMenuBar::redo, this, &SieveEditorWidget::redo);
0085         connect(menuBar, &SieveEditorMenuBar::paste, this, &SieveEditorWidget::paste);
0086         connect(menuBar, &SieveEditorMenuBar::cut, this, &SieveEditorWidget::cut);
0087         connect(menuBar, &SieveEditorMenuBar::selectAll, this, &SieveEditorWidget::selectAll);
0088         connect(menuBar, &SieveEditorMenuBar::gotoLine, this, &SieveEditorWidget::goToLine);
0089         connect(menuBar, &SieveEditorMenuBar::comment, this, &SieveEditorWidget::comment);
0090         connect(menuBar, &SieveEditorMenuBar::uncomment, this, &SieveEditorWidget::uncomment);
0091         connect(menuBar, &SieveEditorMenuBar::zoomIn, this, &SieveEditorWidget::zoomIn);
0092         connect(menuBar, &SieveEditorMenuBar::zoomOut, this, &SieveEditorWidget::zoomOut);
0093         connect(menuBar, &SieveEditorMenuBar::zoomReset, this, &SieveEditorWidget::zoomReset);
0094         connect(menuBar, &SieveEditorMenuBar::debugSieveScript, this, &SieveEditorWidget::debugSieveScript);
0095         connect(menuBar, &SieveEditorMenuBar::wordWrap, this, &SieveEditorWidget::setWordWrap);
0096         connect(menuBar, &SieveEditorMenuBar::print, this, &SieveEditorWidget::print);
0097         connect(menuBar, &SieveEditorMenuBar::printPreview, this, &SieveEditorWidget::printPreview);
0098 
0099         connect(this, &SieveEditorWidget::copyAvailable, menuBar, &SieveEditorMenuBar::slotCopyAvailable);
0100         connect(this, &SieveEditorWidget::redoAvailable, menuBar, &SieveEditorMenuBar::slotRedoAvailable);
0101         connect(this, &SieveEditorWidget::undoAvailable, menuBar, &SieveEditorMenuBar::slotUndoAvailable);
0102         menuBar->fileMenu()->addSeparator();
0103         menuBar->fileMenu()->addAction(mSaveAs);
0104         menuBar->fileMenu()->addSeparator();
0105         menuBar->toolsMenu()->addSeparator();
0106         menuBar->fileMenu()->addAction(shareAction);
0107         menuBar->toolsMenu()->addSeparator();
0108         menuBar->toolsMenu()->addAction(mCreateRulesGraphically);
0109         menuBar->toolsMenu()->addAction(mCheckSyntax);
0110         lay->addWidget(menuBar);
0111     }
0112 
0113     lay->addWidget(toolbar);
0114 
0115     auto nameLayout = new QHBoxLayout;
0116     auto label = new QLabel(i18n("Script name:"), this);
0117     nameLayout->addWidget(label);
0118     mScriptName = new QLineEdit(this);
0119     mScriptName->setReadOnly(true);
0120     nameLayout->addWidget(mScriptName);
0121     lay->addLayout(nameLayout);
0122 
0123     lay->setContentsMargins({});
0124     mStackedWidget = new QStackedWidget;
0125 
0126     mTextModeWidget = new SieveEditorTextModeWidget;
0127     connect(purposeMenu, &SievePurposeMenuWidget::shareError, mTextModeWidget, &SieveEditorTextModeWidget::slotShareError);
0128     connect(purposeMenu, &SievePurposeMenuWidget::shareSuccess, mTextModeWidget, &SieveEditorTextModeWidget::slotShareSuccess);
0129     connect(mTextModeWidget, &SieveEditorTextModeWidget::valueChanged, this, &SieveEditorWidget::slotModified);
0130     if (menuBar) {
0131         menuBar->setTextModeWidget(mTextModeWidget);
0132     }
0133     mStackedWidget->addWidget(mTextModeWidget);
0134     mGraphicalModeWidget = new SieveEditorGraphicalModeWidget;
0135     connect(mGraphicalModeWidget, &SieveEditorGraphicalModeWidget::valueChanged, this, &SieveEditorWidget::slotModified);
0136     mStackedWidget->addWidget(mGraphicalModeWidget);
0137 
0138     lay->addWidget(mStackedWidget);
0139     connect(mTextModeWidget, &SieveEditorTextModeWidget::enableButtonOk, this, &SieveEditorWidget::slotEnableButtonOk);
0140     connect(mGraphicalModeWidget, &SieveEditorGraphicalModeWidget::enableButtonOk, this, &SieveEditorWidget::slotEnableButtonOk);
0141     connect(mGraphicalModeWidget, &SieveEditorGraphicalModeWidget::switchTextMode, this, &SieveEditorWidget::slotSwitchTextMode);
0142     connect(mTextModeWidget, &SieveEditorTextModeWidget::switchToGraphicalMode, this, &SieveEditorWidget::slotSwitchToGraphicalMode);
0143     connect(mTextModeWidget, &SieveEditorTextModeWidget::undoAvailable, this, &SieveEditorWidget::undoAvailable);
0144     connect(mTextModeWidget, &SieveEditorTextModeWidget::redoAvailable, this, &SieveEditorWidget::redoAvailable);
0145     connect(mTextModeWidget, &SieveEditorTextModeWidget::copyAvailable, this, &SieveEditorWidget::copyAvailable);
0146     connect(mTextModeWidget, &SieveEditorTextModeWidget::sieveEditorTabCurrentChanged, this, &SieveEditorWidget::sieveEditorTabCurrentChanged);
0147     if (KSieveUi::EditorSettings::useGraphicEditorByDefault()) {
0148         changeMode(GraphicMode);
0149     } else {
0150         changeSwitchButtonText();
0151     }
0152 }
0153 
0154 SieveEditorWidget::~SieveEditorWidget() = default;
0155 
0156 void SieveEditorWidget::setReadOnly(bool b)
0157 {
0158     mTextModeWidget->setReadOnly(b);
0159     mGraphicalModeWidget->setDisabled(b);
0160 }
0161 
0162 void SieveEditorWidget::slotModified()
0163 {
0164     mModified = true;
0165     Q_EMIT valueChanged(mModified);
0166 }
0167 
0168 bool SieveEditorWidget::isModified() const
0169 {
0170     return mModified;
0171 }
0172 
0173 void SieveEditorWidget::undo()
0174 {
0175     if (mMode == TextMode) {
0176         mTextModeWidget->undo();
0177     }
0178 }
0179 
0180 void SieveEditorWidget::redo()
0181 {
0182     if (mMode == TextMode) {
0183         mTextModeWidget->redo();
0184     }
0185 }
0186 
0187 void SieveEditorWidget::goToLine()
0188 {
0189     if (mMode == TextMode) {
0190         mTextModeWidget->slotShowGoToLine();
0191     }
0192 }
0193 
0194 void SieveEditorWidget::cut()
0195 {
0196     if (mMode == TextMode) {
0197         mTextModeWidget->cut();
0198     }
0199 }
0200 
0201 void SieveEditorWidget::paste()
0202 {
0203     if (mMode == TextMode) {
0204         mTextModeWidget->paste();
0205     }
0206 }
0207 
0208 void SieveEditorWidget::copy()
0209 {
0210     if (mMode == TextMode) {
0211         mTextModeWidget->copy();
0212     }
0213 }
0214 
0215 void SieveEditorWidget::zoomIn()
0216 {
0217     if (mMode == TextMode) {
0218         mTextModeWidget->zoomIn();
0219     }
0220 }
0221 
0222 bool SieveEditorWidget::isWordWrap() const
0223 {
0224     if (mMode == TextMode) {
0225         return mTextModeWidget->isWordWrap();
0226     }
0227     return false;
0228 }
0229 
0230 void SieveEditorWidget::updateOriginalScript()
0231 {
0232     mOriginalScript = script();
0233 }
0234 
0235 void SieveEditorWidget::print()
0236 {
0237     switch (mMode) {
0238     case TextMode: {
0239         bool wasModified = isModified();
0240         mTextModeWidget->print();
0241         setModified(wasModified);
0242         break;
0243     }
0244     case GraphicMode:
0245         break;
0246     case Unknown:
0247         qCDebug(LIBKSIEVEUI_LOG) << " Unknown mode";
0248         break;
0249     }
0250 }
0251 
0252 void SieveEditorWidget::printPreview()
0253 {
0254     switch (mMode) {
0255     case TextMode: {
0256         bool wasModified = isModified();
0257         mTextModeWidget->printPreview();
0258         setModified(wasModified);
0259         break;
0260     }
0261     case GraphicMode:
0262         break;
0263     case Unknown:
0264         qCDebug(LIBKSIEVEUI_LOG) << " Unknown mode";
0265         break;
0266     }
0267 }
0268 
0269 void SieveEditorWidget::setWordWrap(bool state)
0270 {
0271     if (mMode == TextMode) {
0272         mTextModeWidget->setWordWrap(state);
0273     }
0274 }
0275 
0276 void SieveEditorWidget::zoomReset()
0277 {
0278     if (mMode == TextMode) {
0279         mTextModeWidget->zoomReset();
0280     }
0281 }
0282 
0283 void SieveEditorWidget::zoomOut()
0284 {
0285     if (mMode == TextMode) {
0286         mTextModeWidget->zoomOut();
0287     }
0288 }
0289 
0290 void SieveEditorWidget::selectAll()
0291 {
0292     if (mMode == TextMode) {
0293         mTextModeWidget->selectAll();
0294     }
0295 }
0296 
0297 void SieveEditorWidget::find()
0298 {
0299     if (mMode == TextMode) {
0300         mTextModeWidget->find();
0301     }
0302 }
0303 
0304 void SieveEditorWidget::replace()
0305 {
0306     if (mMode == TextMode) {
0307         mTextModeWidget->replace();
0308     }
0309 }
0310 
0311 bool SieveEditorWidget::isUndoAvailable() const
0312 {
0313     if (mMode == TextMode) {
0314         return mTextModeWidget->isUndoAvailable();
0315     }
0316     return false;
0317 }
0318 
0319 bool SieveEditorWidget::isRedoAvailable() const
0320 {
0321     if (mMode == TextMode) {
0322         return mTextModeWidget->isRedoAvailable();
0323     }
0324     return false;
0325 }
0326 
0327 bool SieveEditorWidget::hasSelection() const
0328 {
0329     if (mMode == TextMode) {
0330         return mTextModeWidget->hasSelection();
0331     }
0332     return false;
0333 }
0334 
0335 void SieveEditorWidget::comment()
0336 {
0337     if (mMode == TextMode) {
0338         mTextModeWidget->comment();
0339     }
0340 }
0341 
0342 void SieveEditorWidget::uncomment()
0343 {
0344     if (mMode == TextMode) {
0345         mTextModeWidget->uncomment();
0346     }
0347 }
0348 
0349 SieveEditorWidget::EditorMode SieveEditorWidget::mode() const
0350 {
0351     return mMode;
0352 }
0353 
0354 void SieveEditorWidget::setModified(bool b)
0355 {
0356     if (mModified != b) {
0357         mModified = b;
0358         Q_EMIT valueChanged(mModified);
0359     }
0360 }
0361 
0362 void SieveEditorWidget::changeMode(EditorMode mode)
0363 {
0364     if (mode != mMode) {
0365         mMode = mode;
0366         mStackedWidget->setCurrentIndex(static_cast<int>(mode));
0367         const bool isTextMode = (mMode == TextMode);
0368         mCreateRulesGraphically->setEnabled(isTextMode);
0369         if (mGenerateXml) {
0370             mGenerateXml->setEnabled(isTextMode);
0371         }
0372         if (isTextMode) {
0373             mCheckSyntax->setEnabled(!mTextModeWidget->currentscript().isEmpty());
0374         } else {
0375             mCheckSyntax->setEnabled(false);
0376         }
0377         Q_EMIT modeEditorChanged(mode);
0378         Q_EMIT changeModeEditor(isTextMode);
0379         changeSwitchButtonText();
0380     }
0381 }
0382 
0383 void SieveEditorWidget::changeSwitchButtonText()
0384 {
0385     mSwitchMode->setText((mMode == TextMode) ? i18n("Simple Mode") : i18n("Advanced Mode"));
0386 }
0387 
0388 void SieveEditorWidget::slotEnableButtonOk(bool b)
0389 {
0390     Q_EMIT enableButtonOk(b);
0391     mSaveAs->setEnabled(b);
0392     if (mMode == TextMode) {
0393         mCheckSyntax->setEnabled(b);
0394     } else {
0395         mCheckSyntax->setEnabled(false);
0396     }
0397 }
0398 
0399 QString SieveEditorWidget::script() const
0400 {
0401     QString currentScript;
0402     switch (mMode) {
0403     case TextMode:
0404         currentScript = mTextModeWidget->script();
0405         break;
0406     case GraphicMode:
0407         currentScript = mGraphicalModeWidget->currentscript();
0408         break;
0409     case Unknown:
0410         qCDebug(LIBKSIEVEUI_LOG) << " Unknown Mode!";
0411         break;
0412     }
0413     return currentScript;
0414 }
0415 
0416 QString SieveEditorWidget::originalScript() const
0417 {
0418     return mOriginalScript;
0419 }
0420 
0421 void SieveEditorWidget::setScript(const QString &script, bool clearUndoRedo)
0422 {
0423     mTextModeWidget->setScript(script, clearUndoRedo);
0424     // Necessary to take text from editor otherwise script has \r\n
0425     mOriginalScript = mTextModeWidget->script();
0426 }
0427 
0428 void SieveEditorWidget::addFailedMessage(const QString &err)
0429 {
0430     addMessageEntry(err, QColor(Qt::darkRed));
0431 }
0432 
0433 void SieveEditorWidget::addOkMessage(const QString &msg)
0434 {
0435     addMessageEntry(msg, QColor(Qt::darkGreen));
0436 }
0437 
0438 void SieveEditorWidget::addNormalMessage(const QString &msg)
0439 {
0440     addMessageEntry(msg, palette().color(QPalette::WindowText));
0441 }
0442 
0443 void SieveEditorWidget::addMessageEntry(const QString &errorMsg, const QColor &color)
0444 {
0445     QString msg = errorMsg;
0446     msg.replace(QLatin1Char('\n'), QStringLiteral("<br>"));
0447     const QString logText = QStringLiteral("<font color=%1>%2</font>").arg(color.name(), msg);
0448 
0449     setDebugScript(logText);
0450 }
0451 
0452 void SieveEditorWidget::setDebugScript(const QString &debug)
0453 {
0454     mTextModeWidget->setDebugScript(debug);
0455 }
0456 
0457 void SieveEditorWidget::setScriptName(const QString &name)
0458 {
0459     mScriptName->setText(name);
0460 }
0461 
0462 void SieveEditorWidget::resultDone()
0463 {
0464     mCheckSyntax->setEnabled(true);
0465 }
0466 
0467 void SieveEditorWidget::setSieveCapabilities(const QStringList &capabilities)
0468 {
0469     mTextModeWidget->setSieveCapabilities(capabilities);
0470     mGraphicalModeWidget->setSieveCapabilities(capabilities);
0471 }
0472 
0473 void SieveEditorWidget::setSieveImapAccountSettings(const KSieveCore::SieveImapAccountSettings &sieveImapAccountSettings)
0474 {
0475     mGraphicalModeWidget->setSieveImapAccountSettings(sieveImapAccountSettings);
0476     mTextModeWidget->setSieveImapAccountSettings(sieveImapAccountSettings);
0477 }
0478 
0479 void SieveEditorWidget::setListOfIncludeFile(const QStringList &listOfIncludeFile)
0480 {
0481     mTextModeWidget->setListOfIncludeFile(listOfIncludeFile);
0482     mGraphicalModeWidget->setListOfIncludeFile(listOfIncludeFile);
0483 }
0484 
0485 void SieveEditorWidget::slotCreateRulesGraphically()
0486 {
0487     switch (mMode) {
0488     case TextMode:
0489         mTextModeWidget->createRulesGraphically();
0490         break;
0491     case GraphicMode:
0492     case Unknown:
0493         break;
0494     }
0495 }
0496 
0497 void SieveEditorWidget::slotCheckSyntax()
0498 {
0499     switch (mMode) {
0500     case TextMode:
0501         mCheckSyntax->setEnabled(false);
0502         Q_EMIT checkSyntax();
0503         break;
0504     case GraphicMode:
0505     case Unknown:
0506         break;
0507     }
0508 }
0509 
0510 void SieveEditorWidget::slotGenerateXml()
0511 {
0512     switch (mMode) {
0513     case TextMode:
0514         mTextModeWidget->generateXml();
0515         break;
0516     case GraphicMode:
0517     case Unknown:
0518         break;
0519     }
0520 }
0521 
0522 void SieveEditorWidget::checkSpelling()
0523 {
0524     switch (mMode) {
0525     case TextMode:
0526         mTextModeWidget->checkSpelling();
0527         break;
0528     case GraphicMode:
0529     case Unknown:
0530         break;
0531     }
0532 }
0533 
0534 void SieveEditorWidget::slotSaveAs()
0535 {
0536     switch (mMode) {
0537     case TextMode:
0538         mTextModeWidget->saveAs(mScriptName->text());
0539         break;
0540     case GraphicMode:
0541         mGraphicalModeWidget->saveAs(mScriptName->text());
0542         break;
0543     case Unknown:
0544         qCDebug(LIBKSIEVEUI_LOG) << " Unknown mode";
0545         break;
0546     }
0547 }
0548 
0549 void SieveEditorWidget::slotImport()
0550 {
0551     switch (mMode) {
0552     case TextMode:
0553         mTextModeWidget->slotImport();
0554         break;
0555     case GraphicMode:
0556         mGraphicalModeWidget->slotImport();
0557         break;
0558     case Unknown:
0559         qCDebug(LIBKSIEVEUI_LOG) << " Unknown mode";
0560         break;
0561     }
0562 }
0563 
0564 void SieveEditorWidget::slotSwitchToGraphicalMode()
0565 {
0566     mTextModeWidget->hideEditorWarning();
0567     changeMode(GraphicMode);
0568 }
0569 
0570 void SieveEditorWidget::slotSwitchMode()
0571 {
0572     switch (mMode) {
0573     case TextMode: {
0574         bool result = false;
0575         const QString doc = KSieveCore::ParsingUtil::parseScript(mTextModeWidget->currentscript(), result);
0576         if (result) {
0577             QString error;
0578             mGraphicalModeWidget->loadScript(doc, error);
0579             if (!error.isEmpty()) {
0580                 mTextModeWidget->setParsingEditorWarningError(mTextModeWidget->currentscript(), error);
0581                 mTextModeWidget->showParsingEditorWarning();
0582             } else {
0583                 mTextModeWidget->hideEditorWarning();
0584                 changeMode(GraphicMode);
0585             }
0586         } else {
0587             mTextModeWidget->showEditorWarning();
0588             qCDebug(LIBKSIEVEUI_LOG) << "Impossible to parse file";
0589         }
0590         break;
0591     }
0592     case GraphicMode: {
0593         const QString script = mGraphicalModeWidget->currentscript();
0594         changeMode(TextMode);
0595         mTextModeWidget->setScript(script);
0596         break;
0597     }
0598     case Unknown:
0599         qCDebug(LIBKSIEVEUI_LOG) << " Unknown mode";
0600         break;
0601     }
0602 }
0603 
0604 void SieveEditorWidget::slotSwitchTextMode(const QString &script)
0605 {
0606     changeMode(TextMode);
0607     mTextModeWidget->setScript(script);
0608 }
0609 
0610 void SieveEditorWidget::reverseCase()
0611 {
0612     if (mMode == TextMode) {
0613         mTextModeWidget->reverseCase();
0614     }
0615 }
0616 
0617 void SieveEditorWidget::lowerCase()
0618 {
0619     if (mMode == TextMode) {
0620         mTextModeWidget->lowerCase();
0621     }
0622 }
0623 
0624 void SieveEditorWidget::debugSieveScript()
0625 {
0626     if (mMode == TextMode) {
0627         mTextModeWidget->debugSieveScript();
0628     }
0629 }
0630 
0631 void SieveEditorWidget::upperCase()
0632 {
0633     if (mMode == TextMode) {
0634         mTextModeWidget->upperCase();
0635     }
0636 }
0637 
0638 void SieveEditorWidget::sentenceCase()
0639 {
0640     if (mMode == TextMode) {
0641         mTextModeWidget->sentenceCase();
0642     }
0643 }
0644 
0645 void SieveEditorWidget::openBookmarkUrl(const QUrl &url)
0646 {
0647     if (mMode == TextMode) {
0648         mTextModeWidget->openBookmarkUrl(url);
0649     }
0650 }
0651 
0652 QString SieveEditorWidget::currentHelpTitle() const
0653 {
0654     if (mMode == TextMode) {
0655         return mTextModeWidget->currentHelpTitle();
0656     }
0657     return {};
0658 }
0659 
0660 QUrl SieveEditorWidget::currentHelpUrl() const
0661 {
0662     if (mMode == TextMode) {
0663         return mTextModeWidget->currentHelpUrl();
0664     }
0665     return {};
0666 }
0667 
0668 bool SieveEditorWidget::isTextEditor() const
0669 {
0670     if (mMode == TextMode) {
0671         return mTextModeWidget->isTextEditor();
0672     }
0673     return false;
0674 }
0675 
0676 bool SieveEditorWidget::printSupportEnabled() const
0677 {
0678     if (mMode == TextMode) {
0679         return mTextModeWidget->printSupportEnabled();
0680     }
0681     return false;
0682 }
0683 
0684 void SieveEditorWidget::slotServerInfo()
0685 {
0686     SieveInfoDialog dlg(this);
0687     dlg.setServerInfo(mTextModeWidget->sieveCapabilities());
0688     dlg.exec();
0689 }
0690 
0691 #include "moc_sieveeditorwidget.cpp"