6#include "sieveeditortextmodewidget.h" 
    7#include "autocreatescripts/autocreatescriptdialog.h" 
    8#include "editor/sieveeditortabwidget.h" 
    9#include "editor/sievetextedit.h" 
   10#include "editor/warningwidget/sieveeditorparsingmissingfeaturewarning.h" 
   11#include "editor/warningwidget/sieveeditorwarning.h" 
   12#include "sievescriptdebugger/sievescriptdebuggerdialog.h" 
   13#include "templates/sievetemplatewidget.h" 
   15#include "scriptsparsing/parsingresultdialog.h" 
   16#include "scriptsparsing/xmlprintingscriptbuilder.h" 
   18#include "KSplitterCollapserButton" 
   19#include "webengine/sieveeditorhelphtmlwidget.h" 
   20#include <PimCommon/PurposeMenuMessageWidget> 
   21#include <TextAddonsWidgets/SlideContainer> 
   22#include <TextCustomEditor/PlainTextEditFindBar> 
   23#include <TextCustomEditor/PlainTextEditorWidget> 
   24#include <TextCustomEditor/TextGotoLineWidget> 
   25#ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT 
   26#include <TextEditTextToSpeech/TextToSpeechContainerWidget> 
   31#include "scriptbuilder.h" 
   33#include <KConfigGroup> 
   34#include <KLocalizedString> 
   36#include <KSharedConfig> 
   37#include <KWindowStateSaver> 
   40#include <QPrintDialog> 
   41#include <QPrintPreviewDialog> 
   51using namespace KSieveUi;
 
   53SieveEditorTextModeWidget::SieveEditorTextModeWidget(
QWidget *parent)
 
   54    : SieveEditorAbstractWidget(parent)
 
   55    , mPurposeMenuMessageWidget(new 
PimCommon::PurposeMenuMessageWidget(this))
 
   58    lay->setContentsMargins({});
 
   62    lay->addWidget(mMainSplitter);
 
   67    mSieveTemplateWidget = 
new SieveTemplateWidget(
i18n(
"Sieve Template:"));
 
   69    auto textEditWidget = 
new QWidget(
this);
 
   73    mEditorWidget = 
new QWidget(
this);
 
   76    editorWidgetLayout->setSpacing(0);
 
   77    mEditorWidget->setLayout(editorWidgetLayout);
 
   81    connect(mTabWidget, &SieveEditorTabWidget::copyAvailable, 
this, &SieveEditorTextModeWidget::copyAvailable);
 
   82#ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT 
   84    editorWidgetLayout->addWidget(mTextToSpeechWidget);
 
   89    editorWidgetLayout->addWidget(mPurposeMenuMessageWidget);
 
   90    editorWidgetLayout->addWidget(mTextEdit);
 
   92    mTabWidget->addTab(mEditorWidget, 
i18n(
"Editor"));
 
   93    mTabWidget->tabBar()->hide();
 
   94    textEditLayout->addWidget(mTabWidget);
 
   95    connect(mTextEdit, &SieveTextEdit::openHelp, mTabWidget, &SieveEditorTabWidget::slotAddHelpPage);
 
   96#ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT 
   97    connect(mTextEdit, &SieveTextEdit::say, mTextToSpeechWidget, &TextEditTextToSpeech::TextToSpeechContainerWidget::say);
 
   99    connect(mTextEdit, &SieveTextEdit::editRule, 
this, &SieveEditorTextModeWidget::slotEditRule);
 
  100    connect(mTextEdit, &SieveTextEdit::insertRule, 
this, &SieveEditorTextModeWidget::slotInsertRule);
 
  105    mGotoLineSliderContainer->setContent(mGoToLine);
 
  106    editorWidgetLayout->addWidget(mGotoLineSliderContainer);
 
  109    connect(mGoToLine, &TextCustomEditor::TextGoToLineWidget::moveToLine, 
this, &SieveEditorTextModeWidget::slotGoToLine);
 
  114    mFindBar->setHideWhenClose(
false);
 
  117            &TextCustomEditor::TextEditFindBarBase::displayMessageIndicator,
 
  119            &TextCustomEditor::PlainTextEditor::slotDisplayMessageIndicator);
 
  120    mSliderContainer->setContent(mFindBar);
 
  121    editorWidgetLayout->addWidget(mSliderContainer);
 
  123    mSieveEditorWarning = 
new SieveEditorWarning(
this);
 
  124    editorWidgetLayout->addWidget(mSieveEditorWarning);
 
  126    mSieveParsingWarning = 
new SieveEditorParsingMissingFeatureWarning(SieveEditorParsingMissingFeatureWarning::TextEditor);
 
  127    connect(mSieveParsingWarning, &SieveEditorParsingMissingFeatureWarning::switchToGraphicalMode, 
this, &SieveEditorTextModeWidget::switchToGraphicalMode);
 
  128    editorWidgetLayout->addWidget(mSieveParsingWarning);
 
  130    textEditWidget->setLayout(textEditLayout);
 
  132    mTemplateSplitter->addWidget(textEditWidget);
 
  133    mTemplateSplitter->addWidget(mSieveTemplateWidget);
 
  134    mTemplateSplitter->setCollapsible(0, 
false);
 
  140    connect(mTextEdit, &SieveTextEdit::findText, 
this, &SieveEditorTextModeWidget::slotFind);
 
  141    connect(mTextEdit, &SieveTextEdit::replaceText, 
this, &SieveEditorTextModeWidget::slotReplace);
 
  144    mDebugTextEdit->editor()->setSearchSupport(
false);
 
  145    mDebugTextEdit->editor()->setReadOnly(
true);
 
  146    mDebugTextEdit->editor()->setPlaceholderText(
i18nc(
"@info:placeholder", 
"Show result from \"check syntax\""));
 
  147    mMainSplitter->addWidget(mTemplateSplitter);
 
  148    mMainSplitter->addWidget(mDebugTextEdit);
 
  149    mMainSplitter->setChildrenCollapsible(
false);
 
  157    mTextEdit->setFocus();
 
  160SieveEditorTextModeWidget::~SieveEditorTextModeWidget()
 
  167void SieveEditorTextModeWidget::writeConfig()
 
  170    group.writeEntry(
"mainSplitter", mMainSplitter->sizes());
 
  171    group.writeEntry(
"templateSplitter", mTemplateSplitter->sizes());
 
  174QStringList SieveEditorTextModeWidget::sieveCapabilities()
 const 
  176    return mSieveCapabilities;
 
  184void SieveEditorTextModeWidget::readConfig()
 
  187    const QList<int> 
size = {400, 100};
 
  189    mMainSplitter->setSizes(group.readEntry(
"mainSplitter", 
size));
 
  190    mTemplateSplitter->setSizes(group.readEntry(
"templateSplitter", 
size));
 
  193void SieveEditorTextModeWidget::slotGoToLine(
int line)
 
  196        QTextCursor 
cursor = mTextEdit->textCursor();
 
  201        mTextEdit->setTextCursor(
cursor);
 
  202        mTextEdit->setFocus();
 
  206void SieveEditorTextModeWidget::slotShowGoToLine()
 
  208    mGoToLine->setMaximumLineCount(mTextEdit->document()->blockCount());
 
  209    mGotoLineSliderContainer->slideIn();
 
  210    mGoToLine->goToLine();
 
  213void SieveEditorTextModeWidget::slotShareError(
const QString &message)
 
  215    mPurposeMenuMessageWidget->slotShareError(message);
 
  218void SieveEditorTextModeWidget::slotShareSuccess(
const QString &url)
 
  220    mPurposeMenuMessageWidget->slotShareSuccess(url);
 
  223void SieveEditorTextModeWidget::generateXml()
 
  225    const QByteArray script = mTextEdit->toPlainText().toUtf8();
 
  226    KSieve::Parser parser(script.begin(), script.begin() + script.length());
 
  227    KSieveCore::XMLPrintingScriptBuilder psb(2);
 
  228    parser.setScriptBuilder(&psb);
 
  229    const bool result = parser.parse();
 
  230    QPointer<ParsingResultDialog> dlg = 
new ParsingResultDialog(
this);
 
  232        dlg->setResultParsing(psb.result());
 
  234        dlg->setResultParsing(
i18n(
"Error during parsing"));
 
  240void SieveEditorTextModeWidget::slotEditRule(
const QString &selectedText)
 
  242    const QByteArray script = selectedText.
toUtf8();
 
  243    KSieve::Parser parser(script.begin(), script.begin() + script.length());
 
  244    KSieveCore::XMLPrintingScriptBuilder psb(2);
 
  245    parser.setScriptBuilder(&psb);
 
  246    const bool result = parser.parse();
 
  248        QPointer<AutoCreateScriptDialog> dlg = 
new AutoCreateScriptDialog(
this);
 
  249        dlg->setSieveCapabilities(mSieveCapabilities);
 
  250        dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
 
  251        dlg->setListOfIncludeFile(mListOfIncludeFile);
 
  254        dlg->loadScript(psb.result(), error);
 
  256            QStringList requireModules;
 
  257            const QString newScript = dlg->script(requireModules);
 
  258            const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
 
  259            mTextEdit->insertPlainText(newScript);
 
  260            insertRequires(needToAddRequire);
 
  268void SieveEditorTextModeWidget::insertRequires(
const QStringList &needToAddRequire)
 
  270    if (!needToAddRequire.
isEmpty()) {
 
  271        QTextCursor textCursor = mTextEdit->textCursor();
 
  272        textCursor.
movePosition(QTextCursor::MoveOperation::Start);
 
  273        textCursor.
insertText(needToAddRequire.
join(QLatin1Char(
'\n')) + QLatin1Char(
'\n'));
 
  277QStringList SieveEditorTextModeWidget::insertNecessaryRequires(
const QStringList &requireModules)
 
  279    QStringList needToAddRequire;
 
  280    const QString plainText = mTextEdit->toPlainText();
 
  281    for (
const QString &module : std::as_const(requireModules)) {
 
  283            needToAddRequire.
append(module);
 
  286    return needToAddRequire;
 
  289void SieveEditorTextModeWidget::slotInsertRule()
 
  291    QPointer<AutoCreateScriptDialog> dlg = 
new AutoCreateScriptDialog(
this);
 
  292    dlg->setSieveCapabilities(mSieveCapabilities);
 
  293    dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
 
  294    dlg->setListOfIncludeFile(mListOfIncludeFile);
 
  296        QStringList requireModules;
 
  297        const QString newScript = dlg->script(requireModules);
 
  298        const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
 
  299        mTextEdit->insertPlainText(newScript);
 
  300        insertRequires(needToAddRequire);
 
  305void SieveEditorTextModeWidget::createRulesGraphically()
 
  307    QPointer<AutoCreateScriptDialog> dlg = 
new AutoCreateScriptDialog(
this);
 
  308    dlg->setSieveCapabilities(mSieveCapabilities);
 
  309    dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
 
  310    dlg->setListOfIncludeFile(mListOfIncludeFile);
 
  312        QStringList requireModules;
 
  313        const QString script = dlg->script(requireModules);
 
  314        const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
 
  315        QString newPlainText = mTextEdit->toPlainText() + script;
 
  316        if (!needToAddRequire.
isEmpty()) {
 
  317            newPlainText.
prepend(requireModules.
join(QLatin1Char(
'\n')) + QLatin1Char(
'\n'));
 
  319        mTextEdit->selectAll();
 
  321        mTextEdit->insertPlainText(newPlainText);
 
  326void SieveEditorTextModeWidget::find()
 
  331void SieveEditorTextModeWidget::replace()
 
  336void SieveEditorTextModeWidget::undo()
 
  338    const QWidget *w = mTabWidget->currentWidget();
 
  339    if (w == mEditorWidget) {
 
  344void SieveEditorTextModeWidget::redo()
 
  346    const QWidget *w = mTabWidget->currentWidget();
 
  347    if (w == mEditorWidget) {
 
  352void SieveEditorTextModeWidget::paste()
 
  354    const QWidget *w = mTabWidget->currentWidget();
 
  355    if (w == mEditorWidget) {
 
  360void SieveEditorTextModeWidget::cut()
 
  362    const QWidget *w = mTabWidget->currentWidget();
 
  363    if (w == mEditorWidget) {
 
  368void SieveEditorTextModeWidget::copy()
 
  370    QWidget *w = mTabWidget->currentWidget();
 
  371    if (w == mEditorWidget) {
 
  378void SieveEditorTextModeWidget::selectAll()
 
  380    QWidget *w = mTabWidget->currentWidget();
 
  381    if (w == mEditorWidget) {
 
  382        mTextEdit->selectAll();
 
  388bool SieveEditorTextModeWidget::isUndoAvailable()
 const 
  390    const QWidget *w = mTabWidget->currentWidget();
 
  391    if (w == mEditorWidget) {
 
  392        return mTextEdit->document()->isUndoAvailable();
 
  397bool SieveEditorTextModeWidget::isRedoAvailable()
 const 
  399    const QWidget *w = mTabWidget->currentWidget();
 
  400    if (w == mEditorWidget) {
 
  401        return mTextEdit->document()->isRedoAvailable();
 
  406bool SieveEditorTextModeWidget::hasSelection()
 const 
  408    QWidget *w = mTabWidget->currentWidget();
 
  409    if (w == mEditorWidget) {
 
  410        return mTextEdit->textCursor().hasSelection();
 
  412        return page->hasSelection();
 
  417void SieveEditorTextModeWidget::zoomIn()
 
  419    QWidget *w = mTabWidget->currentWidget();
 
  420    if (w == mEditorWidget) {
 
  427void SieveEditorTextModeWidget::zoomOut()
 
  429    QWidget *w = mTabWidget->currentWidget();
 
  430    if (w == mEditorWidget) {
 
  431        mTextEdit->zoomOut();
 
  437bool SieveEditorTextModeWidget::isWordWrap()
 const 
  439    return mTextEdit->isWordWrap();
 
  442void SieveEditorTextModeWidget::print()
 
  444    const QWidget *w = mTabWidget->currentWidget();
 
  445    if (w == mEditorWidget) {
 
  448        std::unique_ptr<QPrintDialog> dlg(
new QPrintDialog(&printer));
 
  450        bool restoreSpellCheck = mTextEdit->checkSpellingEnabled();
 
  451        mTextEdit->setCheckSpellingEnabled(
false);
 
  453            mTextEdit->print(&printer);
 
  455        mTextEdit->setCheckSpellingEnabled(restoreSpellCheck);
 
  459void SieveEditorTextModeWidget::printPreview()
 
  461    const QWidget *w = mTabWidget->currentWidget();
 
  462    if (w == mEditorWidget) {
 
  463        bool restoreSpellCheck = mTextEdit->checkSpellingEnabled();
 
  464        mTextEdit->setCheckSpellingEnabled(
false);
 
  465        QPointer<QPrintPreviewDialog> previewdlg = 
new QPrintPreviewDialog(
this);
 
  466        new KWindowStateSaver(previewdlg.
data(), QLatin1StringView(
"SieveEditorPrintPreviewDialog"));
 
  468            mTextEdit->print(printer);
 
  472        mTextEdit->setCheckSpellingEnabled(restoreSpellCheck);
 
  476void SieveEditorTextModeWidget::setWordWrap(
bool state)
 
  478    mTextEdit->setWordWrap(state);
 
  481void SieveEditorTextModeWidget::zoomReset()
 
  483    QWidget *w = mTabWidget->currentWidget();
 
  484    if (w == mEditorWidget) {
 
  485        mTextEdit->slotZoomReset();
 
  491void SieveEditorTextModeWidget::slotFind()
 
  493    QWidget *w = mTabWidget->currentWidget();
 
  494    if (w == mEditorWidget) {
 
  495        if (mTextEdit->textCursor().hasSelection()) {
 
  496            mFindBar->setText(mTextEdit->textCursor().selectedText());
 
  499        mFindBar->showFind();
 
  500        mSliderContainer->slideIn();
 
  501        mFindBar->focusAndSetCursor();
 
  507void SieveEditorTextModeWidget::slotReplace()
 
  509    if (mTextEdit->textCursor().hasSelection()) {
 
  510        mFindBar->setText(mTextEdit->textCursor().selectedText());
 
  512    mFindBar->showReplace();
 
  513    mSliderContainer->slideIn();
 
  514    mFindBar->focusAndSetCursor();
 
  517QString SieveEditorTextModeWidget::currentscript()
 
  519    return mTextEdit->toPlainText();
 
  522void SieveEditorTextModeWidget::setImportScript(
const QString &script)
 
  524    mTextEdit->selectAll();
 
  525    mTextEdit->insertPlainText(script);
 
  528void SieveEditorTextModeWidget::slotTextChanged()
 
  530    const bool enabled = !script().isEmpty();
 
  534QString SieveEditorTextModeWidget::script()
 const 
  536    return mTextEdit->toPlainText();
 
  539void SieveEditorTextModeWidget::setScript(
const QString &script, 
bool clearUndoRedo)
 
  542        mTextEdit->setPlainText(script);
 
  544        mTextEdit->selectAll();
 
  545        mTextEdit->insertPlainText(script);
 
  549void SieveEditorTextModeWidget::setDebugScript(
const QString &debug)
 
  551    mDebugTextEdit->editor()->clear();
 
  552    mDebugTextEdit->editor()->appendHtml(debug);
 
  555void SieveEditorTextModeWidget::setListOfIncludeFile(
const QStringList &listOfIncludeFile)
 
  557    mListOfIncludeFile = listOfIncludeFile;
 
  560void SieveEditorTextModeWidget::setSieveCapabilities(
const QStringList &capabilities)
 
  563    mTextEdit->setSieveCapabilities(mSieveCapabilities);
 
  564    mSieveTemplateWidget->setSieveCapabilities(mSieveCapabilities);
 
  567void SieveEditorTextModeWidget::showEditorWarning()
 
  569    mSieveEditorWarning->animatedShow();
 
  572void SieveEditorTextModeWidget::hideEditorWarning()
 
  574    mSieveEditorWarning->animatedHide();
 
  575    mSieveParsingWarning->animatedHide();
 
  578void SieveEditorTextModeWidget::showParsingEditorWarning()
 
  580    mSieveParsingWarning->animatedShow();
 
  583void SieveEditorTextModeWidget::setParsingEditorWarningError(
const QString &script, 
const QString &error)
 
  585    mSieveParsingWarning->setErrors(script, error);
 
  588void SieveEditorTextModeWidget::checkSpelling()
 
  590    mTextEdit->slotCheckSpelling();
 
  593void SieveEditorTextModeWidget::comment()
 
  595    mTextEdit->comment();
 
  598void SieveEditorTextModeWidget::uncomment()
 
  600    mTextEdit->uncomment();
 
  603void SieveEditorTextModeWidget::setReadOnly(
bool b)
 
  605    mTextEdit->setReadOnly(b);
 
  608void SieveEditorTextModeWidget::upperCase()
 
  610    mTextEdit->upperCase();
 
  613void SieveEditorTextModeWidget::lowerCase()
 
  615    mTextEdit->lowerCase();
 
  618void SieveEditorTextModeWidget::sentenceCase()
 
  620    mTextEdit->sentenceCase();
 
  623void SieveEditorTextModeWidget::reverseCase()
 
  625    mTextEdit->reverseCase();
 
  628QString SieveEditorTextModeWidget::currentHelpTitle()
 const 
  630    return mTabWidget->currentHelpTitle();
 
  633QUrl SieveEditorTextModeWidget::currentHelpUrl()
 const 
  635    return mTabWidget->currentHelpUrl();
 
  638void SieveEditorTextModeWidget::openBookmarkUrl(
const QUrl &url)
 
  640    mTabWidget->slotAddHelpPage(url);
 
  643void SieveEditorTextModeWidget::debugSieveScript()
 
  645    QPointer<KSieveUi::SieveScriptDebuggerDialog> dlg = 
new KSieveUi::SieveScriptDebuggerDialog(
this);
 
  646    dlg->setScript(mTextEdit->toPlainText());
 
  648        const QString script = dlg->script();
 
  649        mTextEdit->selectAll();
 
  650        mTextEdit->insertPlainText(script);
 
  655bool SieveEditorTextModeWidget::isTextEditor()
 const 
  657    const QWidget *w = mTabWidget->currentWidget();
 
  658    return w == mEditorWidget;
 
  661bool SieveEditorTextModeWidget::printSupportEnabled()
 const 
  663    return isTextEditor();
 
  666#include "moc_sieveeditortextmodewidget.cpp" 
static KSharedConfig::Ptr openStateConfig(const QString &fileName=QString())
 
QString i18nc(const char *context, const char *text, const TYPE &arg...)
 
QString i18n(const char *text, const TYPE &arg...)
 
Capabilities capabilities()
 
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
 
void setContentsMargins(const QMargins &margins)
 
void append(QList< T > &&value)
 
bool isEmpty() const const
 
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
 
bool disconnect(const QMetaObject::Connection &connection)
 
T qobject_cast(QObject *object)
 
void blockCountChanged(int newBlockCount)
 
void copyAvailable(bool yes)
 
void insertPlainText(const QString &text)
 
void redoAvailable(bool available)
 
void undoAvailable(bool available)
 
void paintRequested(QPrinter *printer)
 
void setOrientation(Qt::Orientation)
 
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
 
QString & prepend(QChar ch)
 
QByteArray toUtf8() const const
 
QString join(QChar separator) const const
 
void insertText(const QString &text)
 
bool movePosition(MoveOperation operation, MoveMode mode, int n)
 
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)