// This file is part of Desktop App Toolkit, // a set of libraries for developing nice desktop applications. // // For license and copyright information please follow this link: // https://github.com/desktop-app/legal/blob/master/LEGAL // #pragma once #include // input_fields.h #include "base/timer.h" #include "spellcheck/platform/platform_spellcheck.h" #include "spellcheck/spellcheck_types.h" #include "ui/widgets/fields/input_field.h" #include #include #include #include #include namespace Ui { struct ExtendedContextMenu; class PopupMenu; } // namespace Ui namespace Spellchecker { class SpellingHighlighter final : public QSyntaxHighlighter { public: struct CustomContextMenuItem { QString title; Fn callback; }; SpellingHighlighter( not_null field, rpl::producer enabled, std::optional customContextMenuItem = std::nullopt); void contentsChange(int pos, int removed, int added); void checkCurrentText(); bool enabled(); auto contextMenuCreated() { return _contextMenuCreated.events(); } // Windows system spellchecker forces us to perform spell operations // In another thread, so the word check and getting a list of suggestions // Are run asynchronously. // And then the context menu is filled in the main thread. void addSpellcheckerActions( not_null parentMenu, QTextCursor cursorForPosition, Fn showMenuCallback, QPoint mousePosition); void fillSpellcheckerMenu( not_null menu, QTextCursor cursorForPosition, FnMut show); protected: void highlightBlock(const QString &text) override; bool eventFilter(QObject *o, QEvent *e) override; private: void updatePalette(); void setEnabled(bool enabled); void checkText(const QString &text); void showSpellcheckerMenu(); void invokeCheckText( int textPosition, int textLength, Fn callback); void checkChangedText(); void checkSingleWord(const MisspelledWord &singleWord); MisspelledWords filterSkippableWords(MisspelledWords &ranges); bool isSkippableWord(const MisspelledWord &range); bool isSkippableWord(int position, int length); bool hasUnspellcheckableTag(int begin, int length); MisspelledWord getWordUnderPosition(int position); QString documentText(); void updateDocumentText(); QString partDocumentText(int pos, int length); int compareDocumentText(const QString &text, int textPos, int textLen); QString _lastPlainText; std::vector blocksFromRange(int pos, int length); int size(); QTextBlock findBlock(int pos); int _countOfCheckingTextAsync = 0; QTextCharFormat _misspelledFormat; QTextCursor _cursor; MisspelledWords _cachedRanges; EntitiesInText _cachedSkippableEntities; int _addedSymbols = 0; int _removedSymbols = 0; int _lastPosition = 0; bool _enabled = true; bool _isLastKeyRepeat = false; base::Timer _coldSpellcheckingTimer; not_null _field; not_null _textEdit; base::unique_qptr _menu; const std::optional _customContextMenuItem; rpl::lifetime _lifetime; using ContextMenu = Ui::InputField::ExtendedContextMenu; rpl::event_stream _contextMenuCreated; }; } // namespace Spellchecker