Libksieve

sieveeditortextmodewidget.cpp
1/* SPDX-FileCopyrightText: 2013-2024 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 <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>
27#endif
28
29#include "error.h"
30#include "parser.h"
31#include "scriptbuilder.h"
32
33#include <KConfigGroup>
34#include <KLocalizedString>
35#include <KMessageBox>
36#include <KSharedConfig>
37#include <KWindowStateSaver>
38
39#include <QPointer>
40#include <QPrintDialog>
41#include <QPrintPreviewDialog>
42#include <QPrinter>
43#include <QPushButton>
44#include <QShortcut>
45#include <QSplitter>
46#include <QVBoxLayout>
47
48#include <cerrno>
49#include <memory>
50
51using namespace KSieveUi;
52
53SieveEditorTextModeWidget::SieveEditorTextModeWidget(QWidget *parent)
54 : SieveEditorAbstractWidget(parent)
55 , mPurposeMenuMessageWidget(new PimCommon::PurposeMenuMessageWidget(this))
56{
57 auto lay = new QVBoxLayout(this);
58 lay->setContentsMargins({});
59
60 mMainSplitter = new QSplitter(this);
61 mMainSplitter->setOrientation(Qt::Vertical);
62 lay->addWidget(mMainSplitter);
63
64 mTemplateSplitter = new QSplitter;
65 mTemplateSplitter->setOrientation(Qt::Horizontal);
66 //
67 mSieveTemplateWidget = new SieveTemplateWidget(i18n("Sieve Template:"));
68
69 auto textEditWidget = new QWidget(this);
70 auto textEditLayout = new QVBoxLayout;
71 textEditLayout->setContentsMargins({});
72
73 mEditorWidget = new QWidget(this);
74 auto editorWidgetLayout = new QVBoxLayout;
75 editorWidgetLayout->setContentsMargins({});
76 editorWidgetLayout->setSpacing(0);
77 mEditorWidget->setLayout(editorWidgetLayout);
78
79 mTabWidget = new SieveEditorTabWidget(this);
80 connect(mTabWidget, &SieveEditorTabWidget::currentChanged, this, &SieveEditorTextModeWidget::sieveEditorTabCurrentChanged);
81 connect(mTabWidget, &SieveEditorTabWidget::copyAvailable, this, &SieveEditorTextModeWidget::copyAvailable);
82#ifdef HAVE_KTEXTADDONS_TEXT_TO_SPEECH_SUPPORT
83 mTextToSpeechWidget = new TextEditTextToSpeech::TextToSpeechContainerWidget(this);
84 editorWidgetLayout->addWidget(mTextToSpeechWidget);
85#endif
86
87 mTextEdit = new SieveTextEdit(this);
88 mPurposeMenuMessageWidget->setPosition(KMessageWidget::Header);
89 editorWidgetLayout->addWidget(mPurposeMenuMessageWidget);
90 editorWidgetLayout->addWidget(mTextEdit);
91 connect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::valueChanged);
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);
98#endif
99 connect(mTextEdit, &SieveTextEdit::editRule, this, &SieveEditorTextModeWidget::slotEditRule);
100 connect(mTextEdit, &SieveTextEdit::insertRule, this, &SieveEditorTextModeWidget::slotInsertRule);
101
102 mGotoLineSliderContainer = new TextAddonsWidgets::SlideContainer(this);
103 mGoToLine = new TextCustomEditor::TextGoToLineWidget(this);
104 mGoToLine->hide();
105 mGotoLineSliderContainer->setContent(mGoToLine);
106 editorWidgetLayout->addWidget(mGotoLineSliderContainer);
107 connect(mGoToLine, &TextCustomEditor::TextGoToLineWidget::hideGotoLine, mGotoLineSliderContainer, &TextAddonsWidgets::SlideContainer::slideOut);
108
109 connect(mGoToLine, &TextCustomEditor::TextGoToLineWidget::moveToLine, this, &SieveEditorTextModeWidget::slotGoToLine);
110 connect(mTextEdit, &SieveTextEdit::blockCountChanged, mGoToLine, &TextCustomEditor::TextGoToLineWidget::slotBlockCountChanged);
111
112 mSliderContainer = new TextAddonsWidgets::SlideContainer(this);
113 mFindBar = new TextCustomEditor::PlainTextEditFindBar(mTextEdit, textEditWidget);
114 mFindBar->setHideWhenClose(false);
115 connect(mFindBar, &TextCustomEditor::TextEditFindBarBase::hideFindBar, mSliderContainer, &TextAddonsWidgets::SlideContainer::slideOut);
116 connect(mFindBar,
117 &TextCustomEditor::TextEditFindBarBase::displayMessageIndicator,
118 mTextEdit,
119 &TextCustomEditor::PlainTextEditor::slotDisplayMessageIndicator);
120 mSliderContainer->setContent(mFindBar);
121 editorWidgetLayout->addWidget(mSliderContainer);
122
123 mSieveEditorWarning = new SieveEditorWarning(this);
124 editorWidgetLayout->addWidget(mSieveEditorWarning);
125
126 mSieveParsingWarning = new SieveEditorParsingMissingFeatureWarning(SieveEditorParsingMissingFeatureWarning::TextEditor);
127 connect(mSieveParsingWarning, &SieveEditorParsingMissingFeatureWarning::switchToGraphicalMode, this, &SieveEditorTextModeWidget::switchToGraphicalMode);
128 editorWidgetLayout->addWidget(mSieveParsingWarning);
129
130 textEditWidget->setLayout(textEditLayout);
131
132 mTemplateSplitter->addWidget(textEditWidget);
133 mTemplateSplitter->addWidget(mSieveTemplateWidget);
134 mTemplateSplitter->setCollapsible(0, false);
135 new KSplitterCollapserButton(mSieveTemplateWidget, mTemplateSplitter);
136
137 connect(mSieveTemplateWidget, &SieveTemplateWidget::insertTemplate, mTextEdit, &SieveTextEdit::insertPlainText);
138
139 //
140 connect(mTextEdit, &SieveTextEdit::findText, this, &SieveEditorTextModeWidget::slotFind);
141 connect(mTextEdit, &SieveTextEdit::replaceText, this, &SieveEditorTextModeWidget::slotReplace);
142
143 mDebugTextEdit = new TextCustomEditor::PlainTextEditorWidget(this);
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);
150
151 connect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::slotTextChanged);
152 connect(mTextEdit, &SieveTextEdit::undoAvailable, this, &SieveEditorTextModeWidget::undoAvailable);
153 connect(mTextEdit, &SieveTextEdit::redoAvailable, this, &SieveEditorTextModeWidget::redoAvailable);
154 connect(mTextEdit, &SieveTextEdit::copyAvailable, this, &SieveEditorTextModeWidget::copyAvailable);
155 readConfig();
156
157 mTextEdit->setFocus();
158}
159
160SieveEditorTextModeWidget::~SieveEditorTextModeWidget()
161{
162 disconnect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::slotTextChanged);
163 disconnect(mTextEdit, &SieveTextEdit::textChanged, this, &SieveEditorTextModeWidget::valueChanged);
164 writeConfig();
165}
166
167void SieveEditorTextModeWidget::writeConfig()
168{
169 KConfigGroup group(KSharedConfig::openStateConfig(), QStringLiteral("SieveEditor"));
170 group.writeEntry("mainSplitter", mMainSplitter->sizes());
171 group.writeEntry("templateSplitter", mTemplateSplitter->sizes());
172}
173
174QStringList SieveEditorTextModeWidget::sieveCapabilities() const
175{
176 return mSieveCapabilities;
177}
178
179SieveEditorTabWidget *SieveEditorTextModeWidget::tabWidget() const
180{
181 return mTabWidget;
182}
183
184void SieveEditorTextModeWidget::readConfig()
185{
186 KConfigGroup group(KSharedConfig::openStateConfig(), QStringLiteral("SieveEditor"));
187 const QList<int> size = {400, 100};
188
189 mMainSplitter->setSizes(group.readEntry("mainSplitter", size));
190 mTemplateSplitter->setSizes(group.readEntry("templateSplitter", size));
191}
192
193void SieveEditorTextModeWidget::slotGoToLine(int line)
194{
195 if (line > 0) {
196 QTextCursor cursor = mTextEdit->textCursor();
198 cursor.movePosition(QTextCursor::Start);
199 cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, (line - 1));
200 cursor.endEditBlock();
201 mTextEdit->setTextCursor(cursor);
202 mTextEdit->setFocus();
203 }
204}
205
206void SieveEditorTextModeWidget::slotShowGoToLine()
207{
208 mGoToLine->setMaximumLineCount(mTextEdit->document()->blockCount());
209 mGotoLineSliderContainer->slideIn();
210 mGoToLine->goToLine();
211}
212
213void SieveEditorTextModeWidget::slotShareError(const QString &message)
214{
215 mPurposeMenuMessageWidget->slotShareError(message);
216}
217
218void SieveEditorTextModeWidget::slotShareSuccess(const QString &url)
219{
220 mPurposeMenuMessageWidget->slotShareSuccess(url);
221}
222
223void SieveEditorTextModeWidget::generateXml()
224{
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);
231 if (result) {
232 dlg->setResultParsing(psb.result());
233 } else {
234 dlg->setResultParsing(i18n("Error during parsing"));
235 }
236 dlg->exec();
237 delete dlg;
238}
239
240void SieveEditorTextModeWidget::slotEditRule(const QString &selectedText)
241{
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();
247 if (result) {
249 dlg->setSieveCapabilities(mSieveCapabilities);
250 dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
251 dlg->setListOfIncludeFile(mListOfIncludeFile);
253 // qDebug() << " psb.result()" << psb.result();
254 dlg->loadScript(psb.result(), error);
255 if (dlg->exec()) {
256 QStringList requireModules;
257 const QString newScript = dlg->script(requireModules);
258 const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
259 mTextEdit->insertPlainText(newScript);
260 insertRequires(needToAddRequire);
261 }
262 delete dlg;
263 } else {
264 KMessageBox::error(this, i18n("Selected text is not a full sieve script"), i18nc("@title:window", "Parsing error"));
265 }
266}
267
268void SieveEditorTextModeWidget::insertRequires(const QStringList &needToAddRequire)
269{
270 if (!needToAddRequire.isEmpty()) {
271 QTextCursor textCursor = mTextEdit->textCursor();
272 textCursor.movePosition(QTextCursor::MoveOperation::Start);
273 textCursor.insertText(needToAddRequire.join(QLatin1Char('\n')) + QLatin1Char('\n'));
274 }
275}
276
277QStringList SieveEditorTextModeWidget::insertNecessaryRequires(const QStringList &requireModules)
278{
279 QStringList needToAddRequire;
280 const QString plainText = mTextEdit->toPlainText();
281 for (const QString &module : std::as_const(requireModules)) {
282 if (!plainText.contains(module)) {
283 needToAddRequire.append(module);
284 }
285 }
286 return needToAddRequire;
287}
288
289void SieveEditorTextModeWidget::slotInsertRule()
290{
292 dlg->setSieveCapabilities(mSieveCapabilities);
293 dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
294 dlg->setListOfIncludeFile(mListOfIncludeFile);
295 if (dlg->exec()) {
296 QStringList requireModules;
297 const QString newScript = dlg->script(requireModules);
298 const QStringList needToAddRequire = insertNecessaryRequires(requireModules);
299 mTextEdit->insertPlainText(newScript);
300 insertRequires(needToAddRequire);
301 }
302 delete dlg;
303}
304
305void SieveEditorTextModeWidget::createRulesGraphically()
306{
308 dlg->setSieveCapabilities(mSieveCapabilities);
309 dlg->setSieveImapAccountSettings(mSieveImapAccountSettings);
310 dlg->setListOfIncludeFile(mListOfIncludeFile);
311 if (dlg->exec()) {
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'));
318 }
319 mTextEdit->selectAll();
320
321 mTextEdit->insertPlainText(newPlainText);
322 }
323 delete dlg;
324}
325
326void SieveEditorTextModeWidget::find()
327{
328 slotFind();
329}
330
331void SieveEditorTextModeWidget::replace()
332{
333 slotReplace();
334}
335
336void SieveEditorTextModeWidget::undo()
337{
338 const QWidget *w = mTabWidget->currentWidget();
339 if (w == mEditorWidget) {
340 mTextEdit->undo();
341 }
342}
343
344void SieveEditorTextModeWidget::redo()
345{
346 const QWidget *w = mTabWidget->currentWidget();
347 if (w == mEditorWidget) {
348 mTextEdit->redo();
349 }
350}
351
352void SieveEditorTextModeWidget::paste()
353{
354 const QWidget *w = mTabWidget->currentWidget();
355 if (w == mEditorWidget) {
356 mTextEdit->paste();
357 }
358}
359
360void SieveEditorTextModeWidget::cut()
361{
362 const QWidget *w = mTabWidget->currentWidget();
363 if (w == mEditorWidget) {
364 mTextEdit->cut();
365 }
366}
367
368void SieveEditorTextModeWidget::copy()
369{
370 QWidget *w = mTabWidget->currentWidget();
371 if (w == mEditorWidget) {
372 mTextEdit->copy();
373 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
374 page->copy();
375 }
376}
377
378void SieveEditorTextModeWidget::selectAll()
379{
380 QWidget *w = mTabWidget->currentWidget();
381 if (w == mEditorWidget) {
382 mTextEdit->selectAll();
383 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
384 page->selectAll();
385 }
386}
387
388bool SieveEditorTextModeWidget::isUndoAvailable() const
389{
390 const QWidget *w = mTabWidget->currentWidget();
391 if (w == mEditorWidget) {
392 return mTextEdit->document()->isUndoAvailable();
393 }
394 return false;
395}
396
397bool SieveEditorTextModeWidget::isRedoAvailable() const
398{
399 const QWidget *w = mTabWidget->currentWidget();
400 if (w == mEditorWidget) {
401 return mTextEdit->document()->isRedoAvailable();
402 }
403 return false;
404}
405
406bool SieveEditorTextModeWidget::hasSelection() const
407{
408 QWidget *w = mTabWidget->currentWidget();
409 if (w == mEditorWidget) {
410 return mTextEdit->textCursor().hasSelection();
411 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
412 return page->hasSelection();
413 }
414 return false;
415}
416
417void SieveEditorTextModeWidget::zoomIn()
418{
419 QWidget *w = mTabWidget->currentWidget();
420 if (w == mEditorWidget) {
421 mTextEdit->zoomIn();
422 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
423 page->zoomIn();
424 }
425}
426
427void SieveEditorTextModeWidget::zoomOut()
428{
429 QWidget *w = mTabWidget->currentWidget();
430 if (w == mEditorWidget) {
431 mTextEdit->zoomOut();
432 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
433 page->zoomOut();
434 }
435}
436
437bool SieveEditorTextModeWidget::isWordWrap() const
438{
439 return mTextEdit->isWordWrap();
440}
441
442void SieveEditorTextModeWidget::print()
443{
444 const QWidget *w = mTabWidget->currentWidget();
445 if (w == mEditorWidget) {
446 QPrinter printer;
447
448 std::unique_ptr<QPrintDialog> dlg(new QPrintDialog(&printer));
449
450 bool restoreSpellCheck = mTextEdit->checkSpellingEnabled();
451 mTextEdit->setCheckSpellingEnabled(false);
452 if (dlg && dlg->exec() == QDialog::Accepted) {
453 mTextEdit->print(&printer);
454 }
455 mTextEdit->setCheckSpellingEnabled(restoreSpellCheck);
456 }
457}
458
459void SieveEditorTextModeWidget::printPreview()
460{
461 const QWidget *w = mTabWidget->currentWidget();
462 if (w == mEditorWidget) {
463 bool restoreSpellCheck = mTextEdit->checkSpellingEnabled();
464 mTextEdit->setCheckSpellingEnabled(false);
466 new KWindowStateSaver(previewdlg.data(), QLatin1StringView("SieveEditorPrintPreviewDialog"));
467 connect(previewdlg.data(), &QPrintPreviewDialog::paintRequested, this, [this](QPrinter *printer) {
468 mTextEdit->print(printer);
469 });
470 previewdlg->exec();
471 delete previewdlg;
472 mTextEdit->setCheckSpellingEnabled(restoreSpellCheck);
473 }
474}
475
476void SieveEditorTextModeWidget::setWordWrap(bool state)
477{
478 mTextEdit->setWordWrap(state);
479}
480
481void SieveEditorTextModeWidget::zoomReset()
482{
483 QWidget *w = mTabWidget->currentWidget();
484 if (w == mEditorWidget) {
485 mTextEdit->slotZoomReset();
486 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
487 page->resetZoom();
488 }
489}
490
491void SieveEditorTextModeWidget::slotFind()
492{
493 QWidget *w = mTabWidget->currentWidget();
494 if (w == mEditorWidget) {
495 if (mTextEdit->textCursor().hasSelection()) {
496 mFindBar->setText(mTextEdit->textCursor().selectedText());
497 }
498 mTextEdit->moveCursor(QTextCursor::Start);
499 mFindBar->showFind();
500 mSliderContainer->slideIn();
501 mFindBar->focusAndSetCursor();
502 } else if (auto page = qobject_cast<SieveEditorHelpHtmlWidget *>(w)) {
503 page->find();
504 }
505}
506
507void SieveEditorTextModeWidget::slotReplace()
508{
509 if (mTextEdit->textCursor().hasSelection()) {
510 mFindBar->setText(mTextEdit->textCursor().selectedText());
511 }
512 mFindBar->showReplace();
513 mSliderContainer->slideIn();
514 mFindBar->focusAndSetCursor();
515}
516
517QString SieveEditorTextModeWidget::currentscript()
518{
519 return mTextEdit->toPlainText();
520}
521
522void SieveEditorTextModeWidget::setImportScript(const QString &script)
523{
524 mTextEdit->selectAll();
525 mTextEdit->insertPlainText(script);
526}
527
528void SieveEditorTextModeWidget::slotTextChanged()
529{
530 const bool enabled = !script().isEmpty();
531 Q_EMIT enableButtonOk(enabled);
532}
533
534QString SieveEditorTextModeWidget::script() const
535{
536 return mTextEdit->toPlainText();
537}
538
539void SieveEditorTextModeWidget::setScript(const QString &script, bool clearUndoRedo)
540{
541 if (clearUndoRedo) {
542 mTextEdit->setPlainText(script);
543 } else {
544 mTextEdit->selectAll();
545 mTextEdit->insertPlainText(script);
546 }
547}
548
549void SieveEditorTextModeWidget::setDebugScript(const QString &debug)
550{
551 mDebugTextEdit->editor()->clear();
552 mDebugTextEdit->editor()->appendHtml(debug);
553}
554
555void SieveEditorTextModeWidget::setListOfIncludeFile(const QStringList &listOfIncludeFile)
556{
557 mListOfIncludeFile = listOfIncludeFile;
558}
559
560void SieveEditorTextModeWidget::setSieveCapabilities(const QStringList &capabilities)
561{
562 mSieveCapabilities = capabilities;
563 mTextEdit->setSieveCapabilities(mSieveCapabilities);
564 mSieveTemplateWidget->setSieveCapabilities(mSieveCapabilities);
565}
566
567void SieveEditorTextModeWidget::showEditorWarning()
568{
569 mSieveEditorWarning->animatedShow();
570}
571
572void SieveEditorTextModeWidget::hideEditorWarning()
573{
574 mSieveEditorWarning->animatedHide();
575 mSieveParsingWarning->animatedHide();
576}
577
578void SieveEditorTextModeWidget::showParsingEditorWarning()
579{
580 mSieveParsingWarning->animatedShow();
581}
582
583void SieveEditorTextModeWidget::setParsingEditorWarningError(const QString &script, const QString &error)
584{
585 mSieveParsingWarning->setErrors(script, error);
586}
587
588void SieveEditorTextModeWidget::checkSpelling()
589{
590 mTextEdit->slotCheckSpelling();
591}
592
593void SieveEditorTextModeWidget::comment()
594{
595 mTextEdit->comment();
596}
597
598void SieveEditorTextModeWidget::uncomment()
599{
600 mTextEdit->uncomment();
601}
602
603void SieveEditorTextModeWidget::setReadOnly(bool b)
604{
605 mTextEdit->setReadOnly(b);
606}
607
608void SieveEditorTextModeWidget::upperCase()
609{
610 mTextEdit->upperCase();
611}
612
613void SieveEditorTextModeWidget::lowerCase()
614{
615 mTextEdit->lowerCase();
616}
617
618void SieveEditorTextModeWidget::sentenceCase()
619{
620 mTextEdit->sentenceCase();
621}
622
623void SieveEditorTextModeWidget::reverseCase()
624{
625 mTextEdit->reverseCase();
626}
627
628QString SieveEditorTextModeWidget::currentHelpTitle() const
629{
630 return mTabWidget->currentHelpTitle();
631}
632
633QUrl SieveEditorTextModeWidget::currentHelpUrl() const
634{
635 return mTabWidget->currentHelpUrl();
636}
637
638void SieveEditorTextModeWidget::openBookmarkUrl(const QUrl &url)
639{
640 mTabWidget->slotAddHelpPage(url);
641}
642
643void SieveEditorTextModeWidget::debugSieveScript()
644{
645 QPointer<KSieveUi::SieveScriptDebuggerDialog> dlg = new KSieveUi::SieveScriptDebuggerDialog(this);
646 dlg->setScript(mTextEdit->toPlainText());
647 if (dlg->exec()) {
648 const QString script = dlg->script();
649 mTextEdit->selectAll();
650 mTextEdit->insertPlainText(script);
651 }
652 delete dlg;
653}
654
655bool SieveEditorTextModeWidget::isTextEditor() const
656{
657 const QWidget *w = mTabWidget->currentWidget();
658 return w == mEditorWidget;
659}
660
661bool SieveEditorTextModeWidget::printSupportEnabled() const
662{
663 return isTextEditor();
664}
665
666#include "moc_sieveeditortextmodewidget.cpp"
void animatedHide()
void animatedShow()
static KSharedConfig::Ptr openStateConfig(const QString &fileName=QString())
The AutoCreateScriptDialog class.
The SieveEditorTabWidget class.
The SieveTextEdit class.
Parser for the Sieve grammar.
Definition parser.h:24
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)
iterator begin()
qsizetype length() const const
void setContentsMargins(const QMargins &margins)
void append(QList< T > &&value)
bool isEmpty() const const
Q_EMITQ_EMIT
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
T qobject_cast(QObject *object)
QTextDocument * document() const const
void insertPlainText(const QString &text)
void moveCursor(QTextCursor::MoveOperation operation, QTextCursor::MoveMode mode)
void print(QPagedPaintDevice *printer) const const
void setReadOnly(bool ro)
void setPlainText(const QString &text)
void setTextCursor(const QTextCursor &cursor)
void textChanged()
QTextCursor textCursor() const const
QString toPlainText() const const
void zoomIn(int range)
void zoomOut(int range)
T * data() const const
void paintRequested(QPrinter *printer)
void setOrientation(Qt::Orientation)
void setSizes(const QList< int > &list)
QList< int > sizes() const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString & prepend(QChar ch)
QByteArray toUtf8() const const
QString join(QChar separator) const const
Vertical
QWidget * currentWidget() const const
void beginEditBlock()
bool hasSelection() const const
void insertText(const QString &text)
bool movePosition(MoveOperation operation, MoveMode mode, int n)
QString selectedText() const const
bool isRedoAvailable() const const
bool isUndoAvailable() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setFocus()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 16:57:10 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.