Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
133 lines
3.4 KiB
C++
133 lines
3.4 KiB
C++
// 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 <QtWidgets/QWidget> // 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 <QtGui/QSyntaxHighlighter>
|
|
#include <QtGui/QTextBlock>
|
|
#include <QtWidgets/QMenu>
|
|
#include <QtWidgets/QTextEdit>
|
|
|
|
#include <rpl/event_stream.h>
|
|
|
|
namespace Ui {
|
|
struct ExtendedContextMenu;
|
|
class PopupMenu;
|
|
} // namespace Ui
|
|
|
|
namespace Spellchecker {
|
|
|
|
class SpellingHighlighter final : public QSyntaxHighlighter {
|
|
|
|
public:
|
|
struct CustomContextMenuItem {
|
|
QString title;
|
|
Fn<void()> callback;
|
|
};
|
|
|
|
SpellingHighlighter(
|
|
not_null<Ui::InputField*> field,
|
|
rpl::producer<bool> enabled,
|
|
std::optional<CustomContextMenuItem> 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<QMenu*> parentMenu,
|
|
QTextCursor cursorForPosition,
|
|
Fn<void()> showMenuCallback,
|
|
QPoint mousePosition);
|
|
|
|
void fillSpellcheckerMenu(
|
|
not_null<QMenu*> menu,
|
|
QTextCursor cursorForPosition,
|
|
FnMut<void(int firstSuggestionIndex)> 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<void(MisspelledWords &&ranges)> 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<QTextBlock> 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<Ui::InputField*> _field;
|
|
not_null<QTextEdit*> _textEdit;
|
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
|
|
|
const std::optional<CustomContextMenuItem> _customContextMenuItem;
|
|
|
|
rpl::lifetime _lifetime;
|
|
|
|
using ContextMenu = Ui::InputField::ExtendedContextMenu;
|
|
rpl::event_stream<ContextMenu> _contextMenuCreated;
|
|
|
|
};
|
|
|
|
} // namespace Spellchecker
|