1 /* SPDX-FileCopyrightText: 2013-2021 Laurent Montel <montel@kde.org>
2 *
3 * SPDX-License-Identifier: LGPL-2.0-or-later
4 */
5
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"
14
15 #include "scriptsparsing/parsingresultdialog.h"
16 #include "scriptsparsing/xmlprintingscriptbuilder.h"
17
18 #include "KSplitterCollapserButton"
19 #include "webengine/sieveeditorhelphtmlwidget.h"
20 #include <KPIMTextEdit/PlainTextEditFindBar>
21 #include <KPIMTextEdit/PlainTextEditorWidget>
22 #include <KPIMTextEdit/SlideContainer>
23 #include <KPIMTextEdit/TextGotoLineWidget>
24 #include <KPIMTextEdit/TextToSpeechWidget>
25
26 #include <ksieve/error.h>
27 #include <ksieve/parser.h>
28 #include <ksieve/scriptbuilder.h>
29
30 #include <KConfigGroup>
31 #include <KLocalizedString>
32 #include <KMessageBox>
33 #include <KSharedConfig>
34
35 #include <PimCommon/KPimPrintPreviewDialog>
36 #include <QPointer>
37 #include <QPrintDialog>
38 #include <QPrinter>
39 #include <QPushButton>
40 #include <QShortcut>
41 #include <QSplitter>
42 #include <QVBoxLayout>
43
44 #include <cerrno>
45 #include <memory>
46
47 using namespace KSieveUi;
48
SieveEditorTextModeWidget(QWidget * parent)49 SieveEditorTextModeWidget::SieveEditorTextModeWidget(QWidget *parent)
50 : SieveEditorAbstractWidget(parent)
51 {
52 auto lay = new QVBoxLayout(this);
53 lay->setContentsMargins({});
54
55 mMainSplitter = new QSplitter;
56 mMainSplitter->setOrientation(Qt::Vertical);
57 lay->addWidget(mMainSplitter);
58
59 mTemplateSplitter = new QSplitter;
60 mTemplateSplitter->setOrientation(Qt::Horizontal);
61 //
62 mSieveTemplateWidget = new SieveTemplateWidget(i18n("Sieve Template:"));
63
64 auto textEditWidget = new QWidget;
65 auto textEditLayout = new QVBoxLayout;
66 textEditLayout->setContentsMargins({});
67
68 mEditorWidget = new QWidget;
69 auto editorWidgetLayout = new QVBoxLayout;
70 editorWidgetLayout->setContentsMargins({});
71 mEditorWidget->setLayout(editorWidgetLayout);
72
73 mTabWidget = new SieveEditorTabWidget;
74 connect(mTabWidget, &SieveEditorTabWidget::currentChanged, this, &SieveEditorTextModeWidget::sieveEditorTabCurrentChanged);
75 connect(mTabWidget, &SieveEditorTabWidget::copyAvailable, this, &SieveEditorTextModeWidget::copyAvailable);
76 mTextToSpeechWidget = new KPIMTextEdit::TextToSpeechWidget(this);
77 editorWidgetLayout->addWidget(mTextToSpeechWidget);
78
79 mTextEdit = new SieveTextEdit;
80 editorWidgetLayout->addWidget(mTextEdit);
81 connect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::valueChanged);
82 mTabWidget->addTab(mEditorWidget, i18n("Editor"));
83 mTabWidget->tabBar()->hide();
84 textEditLayout->addWidget(mTabWidget);
85 connect(mTextEdit, &SieveTextEdit::openHelp, mTabWidget, &SieveEditorTabWidget::slotAddHelpPage);
86 connect(mTextEdit, &SieveTextEdit::say, mTextToSpeechWidget, &KPIMTextEdit::TextToSpeechWidget::say);
87 connect(mTextEdit, &SieveTextEdit::editRule, this, &SieveEditorTextModeWidget::slotEditRule);
88 connect(mTextEdit, &SieveTextEdit::insertRule, this, &SieveEditorTextModeWidget::slotInsertRule);
89
90 mGotoLineSliderContainer = new KPIMTextEdit::SlideContainer(this);
91 mGoToLine = new KPIMTextEdit::TextGoToLineWidget;
92 mGoToLine->hide();
93 mGotoLineSliderContainer->setContent(mGoToLine);
94 editorWidgetLayout->addWidget(mGotoLineSliderContainer);
95 connect(mGoToLine, &KPIMTextEdit::TextGoToLineWidget::hideGotoLine, mGotoLineSliderContainer, &KPIMTextEdit::SlideContainer::slideOut);
96
97 connect(mGoToLine, &KPIMTextEdit::TextGoToLineWidget::moveToLine, this, &SieveEditorTextModeWidget::slotGoToLine);
98 connect(mTextEdit, &SieveTextEdit::blockCountChanged, mGoToLine, &KPIMTextEdit::TextGoToLineWidget::slotBlockCountChanged);
99
100 mSliderContainer = new KPIMTextEdit::SlideContainer(this);
101 mFindBar = new KPIMTextEdit::PlainTextEditFindBar(mTextEdit, textEditWidget);
102 mFindBar->setHideWhenClose(false);
103 connect(mFindBar, &KPIMTextEdit::TextEditFindBarBase::hideFindBar, mSliderContainer, &KPIMTextEdit::SlideContainer::slideOut);
104 connect(mFindBar, &KPIMTextEdit::TextEditFindBarBase::displayMessageIndicator, mTextEdit, &KPIMTextEdit::PlainTextEditor::slotDisplayMessageIndicator);
105 mSliderContainer->setContent(mFindBar);
106 editorWidgetLayout->addWidget(mSliderContainer);
107
108 mSieveEditorWarning = new SieveEditorWarning;
109 editorWidgetLayout->addWidget(mSieveEditorWarning);
110
111 mSieveParsingWarning = new SieveEditorParsingMissingFeatureWarning(SieveEditorParsingMissingFeatureWarning::TextEditor);
112 connect(mSieveParsingWarning, &SieveEditorParsingMissingFeatureWarning::switchToGraphicalMode, this, &SieveEditorTextModeWidget::switchToGraphicalMode);
113 editorWidgetLayout->addWidget(mSieveParsingWarning);
114
115 textEditWidget->setLayout(textEditLayout);
116
117 mTemplateSplitter->addWidget(textEditWidget);
118 mTemplateSplitter->addWidget(mSieveTemplateWidget);
119 mTemplateSplitter->setCollapsible(0, false);
120 new KSplitterCollapserButton(mSieveTemplateWidget, mTemplateSplitter);
121
122 connect(mSieveTemplateWidget, &SieveTemplateWidget::insertTemplate, mTextEdit, &SieveTextEdit::insertPlainText);
123
124 //
125 connect(mTextEdit, &SieveTextEdit::findText, this, &SieveEditorTextModeWidget::slotFind);
126 connect(mTextEdit, &SieveTextEdit::replaceText, this, &SieveEditorTextModeWidget::slotReplace);
127
128 mDebugTextEdit = new KPIMTextEdit::PlainTextEditorWidget;
129 mDebugTextEdit->editor()->setSearchSupport(false);
130 mDebugTextEdit->editor()->setReadOnly(true);
131 mDebugTextEdit->editor()->setPlaceholderText(i18n("Show result from \"check syntax\""));
132 mMainSplitter->addWidget(mTemplateSplitter);
133 mMainSplitter->addWidget(mDebugTextEdit);
134 mMainSplitter->setChildrenCollapsible(false);
135
136 connect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::slotTextChanged);
137 connect(mTextEdit, &SieveTextEdit::undoAvailable, this, &SieveEditorTextModeWidget::undoAvailable);
138 connect(mTextEdit, &SieveTextEdit::redoAvailable, this, &SieveEditorTextModeWidget::redoAvailable);
139 connect(mTextEdit, &SieveTextEdit::copyAvailable, this, &SieveEditorTextModeWidget::copyAvailable);
140 readConfig();
141
142 mTextEdit->setFocus();
143 }
144
~SieveEditorTextModeWidget()145 SieveEditorTextModeWidget::~SieveEditorTextModeWidget()
146 {
147 disconnect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::slotTextChanged);
148 disconnect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::valueChanged);
149 writeConfig();
150 }
151
writeConfig()152 void SieveEditorTextModeWidget::writeConfig()
153 {
154 KConfigGroup group(KSharedConfig::openStateConfig(), "SieveEditor");
155 group.writeEntry("mainSplitter", mMainSplitter->sizes());
156 group.writeEntry("templateSplitter", mTemplateSplitter->sizes());
157 }
158
sieveCapabilities() const159 QStringList SieveEditorTextModeWidget::sieveCapabilities() const
160 {
161 return mSieveCapabilities;
162 }
163
tabWidget() const164 SieveEditorTabWidget *SieveEditorTextModeWidget::tabWidget() const
165 {
166 return mTabWidget;
167 }
168
readConfig()169 void SieveEditorTextModeWidget::readConfig()
170 {
171 KConfigGroup group(KSharedConfig::openStateConfig(), "SieveEditor");
172 const QList<int> size = {400, 100};
173
174 mMainSplitter->setSizes(group.readEntry("mainSplitter", size));
175 mTemplateSplitter->setSizes(group.readEntry("templateSplitter", size));
176 }
177
slotGoToLine(int line)178 void SieveEditorTextModeWidget::slotGoToLine(int line)
179 {
180 if (line > 0) {
181 QTextCursor cursor = mTextEdit->textCursor();
182 cursor.beginEditBlock();
183 cursor.movePosition(QTextCursor::Start);
184 cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, (line - 1));
185 cursor.endEditBlock();
186 mTextEdit->setTextCursor(cursor);
187 mTextEdit->setFocus();
188 }
189 }
190
slotShowGoToLine()191 void SieveEditorTextModeWidget::slotShowGoToLine()
192 {
193 mGoToLine->setMaximumLineCount(mTextEdit->document()->blockCount());
194 mGotoLineSliderContainer->slideIn();
195 mGoToLine->goToLine();
196 }
197
generateXml()198 void SieveEditorTextModeWidget::generateXml()
199 {
200 const QByteArray script = mTextEdit->toPlainText().toUtf8();
201 KSieve::Parser parser(script.begin(), script.begin() + script.length());
202 KSieveUi::XMLPrintingScriptBuilder psb(2);
203 parser.setScriptBuilder(&psb);
204 const bool result = parser.parse();
205 QPointer<ParsingResultDialog> dlg = new ParsingResultDialog(this);
206 if (result) {
207 dlg->setResultParsing(psb.result());
208 } else {
209 dlg->setResultParsing(i18n("Error during parsing"));
210 }
211 dlg->exec();
212 delete dlg;
213 }
214
slotEditRule(const QString & selectedText)215 void SieveEditorTextModeWidget::slotEditRule(const QString &selectedText)
216 {
217 const QByteArray script = selectedText.toUtf8();
218 KSieve::Parser parser(script.begin(), script.begin() + script.length());
219 KSieveUi::XMLPrintingScriptBuilder psb(2);
220 parser.setScriptBuilder(&psb);
221 const bool result = parser.parse();
222 if (result) {
223 QPointer<AutoCreateScriptDialog> dlg = new AutoCreateScriptDialog(this);
224 dlg->setSieveCapabilities(mSieveCapabilities);
225 dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
226 dlg->setListOfIncludeFile(mListOfIncludeFile);
227 QString error;
228 // qDebug() << " psb.result()" << psb.result();
229 dlg->loadScript(psb.result(), error);
230 if (dlg->exec()) {
231 QStringList requireModules;
232 const QString newScript = dlg->script(requireModules);
233 const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
234 mTextEdit->insertPlainText(newScript);
235 insertRequires(needToAddRequire);
236 }
237 delete dlg;
238 } else {
239 KMessageBox::error(this, i18n("Selected text is not a full sieve script"), i18n("Parsing error"));
240 }
241 }
242
insertRequires(const QStringList & needToAddRequire)243 void SieveEditorTextModeWidget::insertRequires(const QStringList &needToAddRequire)
244 {
245 if (!needToAddRequire.isEmpty()) {
246 QTextCursor textCursor = mTextEdit->textCursor();
247 textCursor.movePosition(QTextCursor::MoveOperation::Start);
248 textCursor.insertText(needToAddRequire.join(QLatin1Char('\n')) + QLatin1Char('\n'));
249 }
250 }
251
insertNecessaryRequires(const QStringList & requireModules)252 QStringList SieveEditorTextModeWidget::insertNecessaryRequires(const QStringList &requireModules)
253 {
254 QStringList needToAddRequire;
255 const QString plainText = mTextEdit->toPlainText();
256 for (const QString &module : std::as_const(requireModules)) {
257 if (!plainText.contains(module)) {
258 needToAddRequire.append(module);
259 }
260 }
261 return needToAddRequire;
262 }
263
slotInsertRule()264 void SieveEditorTextModeWidget::slotInsertRule()
265 {
266 QPointer<AutoCreateScriptDialog> dlg = new AutoCreateScriptDialog(this);
267 dlg->setSieveCapabilities(mSieveCapabilities);
268 dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
269 dlg->setListOfIncludeFile(mListOfIncludeFile);
270 if (dlg->exec()) {
271 QStringList requireModules;
272 const QString newScript = dlg->script(requireModules);
273 const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
274 mTextEdit->insertPlainText(newScript);
275 insertRequires(needToAddRequire);
276 }
277 delete dlg;
278 }
279
createRulesGraphically()280 void SieveEditorTextModeWidget::createRulesGraphically()
281 {
282 QPointer<AutoCreateScriptDialog> dlg = new AutoCreateScriptDialog(this);
283 dlg->setSieveCapabilities(mSieveCapabilities);
284 dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
285 dlg->setListOfIncludeFile(mListOfIncludeFile);
286 if (dlg->exec()) {
287 QStringList requireModules;
288 const QString script = dlg->script(requireModules);
289 const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
290 QString newPlainText = mTextEdit->toPlainText() + script;
291 if (!needToAddRequire.isEmpty()) {
292 newPlainText.prepend(requireModules.join(QLatin1Char('\n')) + QLatin1Char('\n'));
293 }
294 mTextEdit->selectAll();
295
296 mTextEdit->insertPlainText(newPlainText);
297 }
298 delete dlg;
299 }
300
find()301 void SieveEditorTextModeWidget::find()
302 {
303 slotFind();
304 }
305
replace()306 void SieveEditorTextModeWidget::replace()
307 {
308 slotReplace();
309 }
310
undo()311 void SieveEditorTextModeWidget::undo()
312 {
313 const QWidget *w = mTabWidget->currentWidget();
314 if (w == mEditorWidget) {
315 mTextEdit->undo();
316 }
317 }
318
redo()319 void SieveEditorTextModeWidget::redo()
320 {
321 const QWidget *w = mTabWidget->currentWidget();
322 if (w == mEditorWidget) {
323 mTextEdit->redo();
324 }
325 }
326
paste()327 void SieveEditorTextModeWidget::paste()
328 {
329 const QWidget *w = mTabWidget->currentWidget();
330 if (w == mEditorWidget) {
331 mTextEdit->paste();
332 }
333 }
334
cut()335 void SieveEditorTextModeWidget::cut()
336 {
337 const QWidget *w = mTabWidget->currentWidget();
338 if (w == mEditorWidget) {
339 mTextEdit->cut();
340 }
341 }
342
copy()343 void SieveEditorTextModeWidget::copy()
344 {
345 QWidget *w = mTabWidget->currentWidget();
346 if (w == mEditorWidget) {
347 mTextEdit->copy();
348 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
349 page->copy();
350 }
351 }
352
selectAll()353 void SieveEditorTextModeWidget::selectAll()
354 {
355 QWidget *w = mTabWidget->currentWidget();
356 if (w == mEditorWidget) {
357 mTextEdit->selectAll();
358 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
359 page->selectAll();
360 }
361 }
362
isUndoAvailable() const363 bool SieveEditorTextModeWidget::isUndoAvailable() const
364 {
365 const QWidget *w = mTabWidget->currentWidget();
366 if (w == mEditorWidget) {
367 return mTextEdit->document()->isUndoAvailable();
368 }
369 return false;
370 }
371
isRedoAvailable() const372 bool SieveEditorTextModeWidget::isRedoAvailable() const
373 {
374 const QWidget *w = mTabWidget->currentWidget();
375 if (w == mEditorWidget) {
376 return mTextEdit->document()->isRedoAvailable();
377 }
378 return false;
379 }
380
hasSelection() const381 bool SieveEditorTextModeWidget::hasSelection() const
382 {
383 QWidget *w = mTabWidget->currentWidget();
384 if (w == mEditorWidget) {
385 return mTextEdit->textCursor().hasSelection();
386 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
387 return page->hasSelection();
388 }
389 return false;
390 }
391
zoomIn()392 void SieveEditorTextModeWidget::zoomIn()
393 {
394 QWidget *w = mTabWidget->currentWidget();
395 if (w == mEditorWidget) {
396 mTextEdit->zoomIn();
397 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
398 page->zoomIn();
399 }
400 }
401
zoomOut()402 void SieveEditorTextModeWidget::zoomOut()
403 {
404 QWidget *w = mTabWidget->currentWidget();
405 if (w == mEditorWidget) {
406 mTextEdit->zoomOut();
407 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
408 page->zoomOut();
409 }
410 }
411
isWordWrap() const412 bool SieveEditorTextModeWidget::isWordWrap() const
413 {
414 return mTextEdit->isWordWrap();
415 }
416
print()417 void SieveEditorTextModeWidget::print()
418 {
419 const QWidget *w = mTabWidget->currentWidget();
420 if (w == mEditorWidget) {
421 QPrinter printer;
422
423 std::unique_ptr<QPrintDialog> dlg(new QPrintDialog(&printer));
424
425 bool restoreSpellCheck = mTextEdit->checkSpellingEnabled();
426 mTextEdit->setCheckSpellingEnabled(false);
427 if (dlg && dlg->exec() == QDialog::Accepted) {
428 mTextEdit->print(&printer);
429 }
430 mTextEdit->setCheckSpellingEnabled(restoreSpellCheck);
431 }
432 }
433
printPreview()434 void SieveEditorTextModeWidget::printPreview()
435 {
436 const QWidget *w = mTabWidget->currentWidget();
437 if (w == mEditorWidget) {
438 bool restoreSpellCheck = mTextEdit->checkSpellingEnabled();
439 mTextEdit->setCheckSpellingEnabled(false);
440 QPointer<PimCommon::KPimPrintPreviewDialog> previewdlg = new PimCommon::KPimPrintPreviewDialog(this);
441 connect(previewdlg.data(), &QPrintPreviewDialog::paintRequested, this, [this](QPrinter *printer) {
442 mTextEdit->print(printer);
443 });
444 previewdlg->exec();
445 delete previewdlg;
446 mTextEdit->setCheckSpellingEnabled(restoreSpellCheck);
447 }
448 }
449
wordWrap(bool state)450 void SieveEditorTextModeWidget::wordWrap(bool state)
451 {
452 mTextEdit->wordWrap(state);
453 }
454
zoomReset()455 void SieveEditorTextModeWidget::zoomReset()
456 {
457 QWidget *w = mTabWidget->currentWidget();
458 if (w == mEditorWidget) {
459 mTextEdit->slotZoomReset();
460 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
461 page->resetZoom();
462 }
463 }
464
slotFind()465 void SieveEditorTextModeWidget::slotFind()
466 {
467 QWidget *w = mTabWidget->currentWidget();
468 if (w == mEditorWidget) {
469 if (mTextEdit->textCursor().hasSelection()) {
470 mFindBar->setText(mTextEdit->textCursor().selectedText());
471 }
472 mTextEdit->moveCursor(QTextCursor::Start);
473 mFindBar->showFind();
474 mSliderContainer->slideIn();
475 mFindBar->focusAndSetCursor();
476 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
477 page->find();
478 }
479 }
480
slotReplace()481 void SieveEditorTextModeWidget::slotReplace()
482 {
483 if (mTextEdit->textCursor().hasSelection()) {
484 mFindBar->setText(mTextEdit->textCursor().selectedText());
485 }
486 mFindBar->showReplace();
487 mSliderContainer->slideIn();
488 mFindBar->focusAndSetCursor();
489 }
490
currentscript()491 QString SieveEditorTextModeWidget::currentscript()
492 {
493 return mTextEdit->toPlainText();
494 }
495
setImportScript(const QString & script)496 void SieveEditorTextModeWidget::setImportScript(const QString &script)
497 {
498 mTextEdit->selectAll();
499 mTextEdit->insertPlainText(script);
500 }
501
slotTextChanged()502 void SieveEditorTextModeWidget::slotTextChanged()
503 {
504 const bool enabled = !script().isEmpty();
505 Q_EMIT enableButtonOk(enabled);
506 }
507
script() const508 QString SieveEditorTextModeWidget::script() const
509 {
510 return mTextEdit->toPlainText();
511 }
512
setScript(const QString & script,bool clearUndoRedo)513 void SieveEditorTextModeWidget::setScript(const QString &script, bool clearUndoRedo)
514 {
515 if (clearUndoRedo) {
516 mTextEdit->setPlainText(script);
517 } else {
518 mTextEdit->selectAll();
519 mTextEdit->insertPlainText(script);
520 }
521 }
522
setDebugScript(const QString & debug)523 void SieveEditorTextModeWidget::setDebugScript(const QString &debug)
524 {
525 mDebugTextEdit->editor()->clear();
526 mDebugTextEdit->editor()->appendHtml(debug);
527 }
528
setListOfIncludeFile(const QStringList & listOfIncludeFile)529 void SieveEditorTextModeWidget::setListOfIncludeFile(const QStringList &listOfIncludeFile)
530 {
531 mListOfIncludeFile = listOfIncludeFile;
532 }
533
setSieveCapabilities(const QStringList & capabilities)534 void SieveEditorTextModeWidget::setSieveCapabilities(const QStringList &capabilities)
535 {
536 mSieveCapabilities = capabilities;
537 mTextEdit->setSieveCapabilities(mSieveCapabilities);
538 mSieveTemplateWidget->setSieveCapabilities(mSieveCapabilities);
539 }
540
showEditorWarning()541 void SieveEditorTextModeWidget::showEditorWarning()
542 {
543 mSieveEditorWarning->animatedShow();
544 }
545
hideEditorWarning()546 void SieveEditorTextModeWidget::hideEditorWarning()
547 {
548 mSieveEditorWarning->animatedHide();
549 mSieveParsingWarning->animatedHide();
550 }
551
showParsingEditorWarning()552 void SieveEditorTextModeWidget::showParsingEditorWarning()
553 {
554 mSieveParsingWarning->animatedShow();
555 }
556
setParsingEditorWarningError(const QString & script,const QString & error)557 void SieveEditorTextModeWidget::setParsingEditorWarningError(const QString &script, const QString &error)
558 {
559 mSieveParsingWarning->setErrors(script, error);
560 }
561
checkSpelling()562 void SieveEditorTextModeWidget::checkSpelling()
563 {
564 mTextEdit->slotCheckSpelling();
565 }
566
comment()567 void SieveEditorTextModeWidget::comment()
568 {
569 mTextEdit->comment();
570 }
571
uncomment()572 void SieveEditorTextModeWidget::uncomment()
573 {
574 mTextEdit->uncomment();
575 }
576
setReadOnly(bool b)577 void SieveEditorTextModeWidget::setReadOnly(bool b)
578 {
579 mTextEdit->setReadOnly(b);
580 }
581
upperCase()582 void SieveEditorTextModeWidget::upperCase()
583 {
584 mTextEdit->upperCase();
585 }
586
lowerCase()587 void SieveEditorTextModeWidget::lowerCase()
588 {
589 mTextEdit->lowerCase();
590 }
591
sentenceCase()592 void SieveEditorTextModeWidget::sentenceCase()
593 {
594 mTextEdit->sentenceCase();
595 }
596
reverseCase()597 void SieveEditorTextModeWidget::reverseCase()
598 {
599 mTextEdit->reverseCase();
600 }
601
currentHelpTitle() const602 QString SieveEditorTextModeWidget::currentHelpTitle() const
603 {
604 return mTabWidget->currentHelpTitle();
605 }
606
currentHelpUrl() const607 QUrl SieveEditorTextModeWidget::currentHelpUrl() const
608 {
609 return mTabWidget->currentHelpUrl();
610 }
611
openBookmarkUrl(const QUrl & url)612 void SieveEditorTextModeWidget::openBookmarkUrl(const QUrl &url)
613 {
614 mTabWidget->slotAddHelpPage(url);
615 }
616
debugSieveScript()617 void SieveEditorTextModeWidget::debugSieveScript()
618 {
619 QPointer<KSieveUi::SieveScriptDebuggerDialog> dlg = new KSieveUi::SieveScriptDebuggerDialog(this);
620 dlg->setScript(mTextEdit->toPlainText());
621 if (dlg->exec()) {
622 const QString script = dlg->script();
623 mTextEdit->selectAll();
624 mTextEdit->insertPlainText(script);
625 }
626 delete dlg;
627 }
628
isTextEditor() const629 bool SieveEditorTextModeWidget::isTextEditor() const
630 {
631 const QWidget *w = mTabWidget->currentWidget();
632 return w == mEditorWidget;
633 }
634
printSupportEnabled() const635 bool SieveEditorTextModeWidget::printSupportEnabled() const
636 {
637 return isTextEditor();
638 }
639