feat: add RXValidator

a QRegularExpression validator with Unicode support

Needed for status-im/status-desktop#8115
This commit is contained in:
Lukáš Tinkl 2022-11-15 08:10:18 +01:00 committed by Michał
parent c96e2601d0
commit 39cce22001
4 changed files with 77 additions and 1 deletions

View File

@ -35,7 +35,7 @@ macro(add_target name type)
endif() endif()
# for DOtherSide.pc # for DOtherSide.pc
set(PC_REQUIRES "Qt5Core, Qt5Gui, Qt5Widgets, Qt5Qml, Qt5Quick, Qt5Network, Qt5DBus, Qt5Multimedia SortFilterProxyModel") set(PC_REQUIRES "Qt5Core, Qt5Gui, Qt5Widgets, Qt5Qml, Qt5Quick, Qt5Network, Qt5DBus, Qt5Multimedia, SortFilterProxyModel")
if (${Qt5QuickControls2_FOUND}) if (${Qt5QuickControls2_FOUND})
target_link_libraries(${name} PRIVATE Qt5::QuickControls2) target_link_libraries(${name} PRIVATE Qt5::QuickControls2)
set(PC_REQUIRES "${PC_REQUIRES}, Qt5QuickControls2") set(PC_REQUIRES "${PC_REQUIRES}, Qt5QuickControls2")

View File

@ -0,0 +1,30 @@
#pragma once
#include <QValidator>
// A QValidator built around QRegularExpression, but with Unicode support
// (RegularExpressionValidator doesn't expose this to QML)
class RXValidator : public QValidator
{
Q_OBJECT
Q_PROPERTY(QRegularExpression regularExpression READ regularExpression WRITE setRegularExpression NOTIFY regularExpressionChanged)
public:
RXValidator(QObject* parent = nullptr);
// helper QML function
Q_INVOKABLE bool test(QString input) const;
protected:
QValidator::State validate(QString &input, int &pos) const override;
signals:
void regularExpressionChanged(const QRegularExpression &re);
private:
QRegularExpression regularExpression() const;
void setRegularExpression(const QRegularExpression &re);
QRegularExpression m_rx;
};

View File

@ -72,6 +72,7 @@
#include "DOtherSide/Status/KeychainManager.h" #include "DOtherSide/Status/KeychainManager.h"
#include "DOtherSide/Status/SoundManager.h" #include "DOtherSide/Status/SoundManager.h"
#include "DOtherSide/Status/QClipboardProxy.h" #include "DOtherSide/Status/QClipboardProxy.h"
#include "DOtherSide/Status/RXValidator.h"
#include "DOtherSide/DosSpellchecker.h" #include "DOtherSide/DosSpellchecker.h"
#include <qqmlsortfilterproxymodeltypes.h> #include <qqmlsortfilterproxymodeltypes.h>
@ -85,6 +86,7 @@ void register_meta_types()
qmlRegisterType<StatusSyntaxHighlighterHelper>("DotherSide", 0 , 1, "StatusSyntaxHighlighter"); qmlRegisterType<StatusSyntaxHighlighterHelper>("DotherSide", 0 , 1, "StatusSyntaxHighlighter");
qmlRegisterType<SpellChecker>("DotherSide", 0, 1, "SpellChecker"); qmlRegisterType<SpellChecker>("DotherSide", 0, 1, "SpellChecker");
qmlRegisterSingletonType<QClipboardProxy>("DotherSide", 0 , 1, "QClipboardProxy", &QClipboardProxy::qmlInstance); qmlRegisterSingletonType<QClipboardProxy>("DotherSide", 0 , 1, "QClipboardProxy", &QClipboardProxy::qmlInstance);
qmlRegisterType<RXValidator>("DotherSide", 0, 1, "RXValidator");
qqsfpm::registerTypes(); qqsfpm::registerTypes();
} }

View File

@ -0,0 +1,44 @@
#include "DOtherSide/Status/RXValidator.h"
RXValidator::RXValidator(QObject* parent)
: QValidator(parent)
{
}
bool RXValidator::test(QString input) const
{
int dummy_pos = 0;
return validate(input, dummy_pos) == QValidator::Acceptable;
}
QRegularExpression RXValidator::regularExpression() const
{
return m_rx;
}
void RXValidator::setRegularExpression(const QRegularExpression& re)
{
if (m_rx != re) {
m_rx = re;
m_rx.setPatternOptions(re.patternOptions() | QRegularExpression::UseUnicodePropertiesOption);
m_rx.setPattern(QRegularExpression::anchoredPattern(re.pattern()));
emit regularExpressionChanged(m_rx);
emit changed();
}
}
QValidator::State RXValidator::validate(QString& input, int& pos) const
{
if (m_rx.pattern().isEmpty())
return Acceptable;
const QRegularExpressionMatch m = m_rx.match(input, 0, QRegularExpression::PartialPreferCompleteMatch);
if (m.hasMatch())
return Acceptable;
if (input.isEmpty() || m.hasPartialMatch())
return Intermediate;
pos = input.size();
return Invalid;
}