fix(StatusTextMessage): Allow user to copy parts of a message containing URLs
The root cause of this issue is that the `TextEdit.text` was replaced on hover to add specific styling for the hovered state. As a result the selection was dropped. To fix this I've moved the highlighted hyperlink style to the StatusSyntaxHighlighter.
This commit is contained in:
parent
4ca7e9b32d
commit
3b17134451
|
@ -50,6 +50,16 @@ SplitView {
|
||||||
isAReply: true
|
isAReply: true
|
||||||
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||||
}
|
}
|
||||||
|
ListElement {
|
||||||
|
timestamp: 1667937930489
|
||||||
|
senderId: "zqdeadbeef"
|
||||||
|
senderDisplayName: "replicator.stateofus.eth"
|
||||||
|
contentType: StatusMessage.ContentType.Text
|
||||||
|
message: "Test message with a link https://github.com/. Try to copy the link!"
|
||||||
|
isContact: true
|
||||||
|
isAReply: true
|
||||||
|
trustIndicator: StatusContactVerificationIcons.TrustedType.None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
readonly property var colorHash: ListModel {
|
readonly property var colorHash: ListModel {
|
||||||
ListElement { colorId: 13; segmentLength: 5 }
|
ListElement { colorId: 13; segmentLength: 5 }
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <QQmlParserStatus>
|
#include <QQmlParserStatus>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QSyntaxHighlighter>
|
#include <QSyntaxHighlighter>
|
||||||
|
#include <QFlags>
|
||||||
|
|
||||||
class QQuickTextDocument;
|
class QQuickTextDocument;
|
||||||
class QTextCharFormat;
|
class QTextCharFormat;
|
||||||
|
@ -26,9 +27,25 @@ class StatusSyntaxHighlighter : public QSyntaxHighlighter, public QQmlParserStat
|
||||||
Q_PROPERTY(QString highlightedHyperlink READ highlightedHyperlink WRITE setHighlightedHyperlink NOTIFY
|
Q_PROPERTY(QString highlightedHyperlink READ highlightedHyperlink WRITE setHighlightedHyperlink NOTIFY
|
||||||
highlightedHyperlinkChanged)
|
highlightedHyperlinkChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(Features features READ features WRITE setFeatures NOTIFY featuresChanged)
|
||||||
|
|
||||||
Q_INTERFACES(QQmlParserStatus)
|
Q_INTERFACES(QQmlParserStatus)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum FeatureFlags {
|
||||||
|
None = 0,
|
||||||
|
SingleLineBold = 1 << 0,
|
||||||
|
SingleLineItalic = 1 << 1,
|
||||||
|
Code = 1 << 2,
|
||||||
|
CodeBlock = 1 << 3,
|
||||||
|
SingleLineStrikeThrough = 1 << 4,
|
||||||
|
Hyperlink = 1 << 5,
|
||||||
|
HighlightedHyperlink = 1 << 6,
|
||||||
|
All = SingleLineBold | SingleLineItalic | Code | CodeBlock | SingleLineStrikeThrough | Hyperlink | HighlightedHyperlink
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(Features, FeatureFlags)
|
||||||
|
Q_FLAG(Features)
|
||||||
|
|
||||||
explicit StatusSyntaxHighlighter(QObject* parent = nullptr);
|
explicit StatusSyntaxHighlighter(QObject* parent = nullptr);
|
||||||
|
|
||||||
QQuickTextDocument* quickTextDocument() const;
|
QQuickTextDocument* quickTextDocument() const;
|
||||||
|
@ -47,6 +64,7 @@ signals:
|
||||||
void hyperlinkHoverColorChanged();
|
void hyperlinkHoverColorChanged();
|
||||||
void hyperlinksChanged();
|
void hyperlinksChanged();
|
||||||
void highlightedHyperlinkChanged();
|
void highlightedHyperlinkChanged();
|
||||||
|
void featuresChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QQuickTextDocument* m_quicktextdocument{nullptr};
|
QQuickTextDocument* m_quicktextdocument{nullptr};
|
||||||
|
@ -80,8 +98,15 @@ private:
|
||||||
QStringList getPossibleUrlFormats(const QUrl& url) const;
|
QStringList getPossibleUrlFormats(const QUrl& url) const;
|
||||||
QRegularExpression buildHyperlinkRegex(QStringList hyperlinks) const;
|
QRegularExpression buildHyperlinkRegex(QStringList hyperlinks) const;
|
||||||
|
|
||||||
|
Features features() const;
|
||||||
|
void setFeatures(Features features);
|
||||||
|
|
||||||
|
void buildRules();
|
||||||
|
int findRuleIndex(FeatureFlags flag) const;
|
||||||
|
|
||||||
struct HighlightingRule
|
struct HighlightingRule
|
||||||
{
|
{
|
||||||
|
int id;
|
||||||
QRegularExpression pattern;
|
QRegularExpression pattern;
|
||||||
QRegularExpression::MatchType matchType{QRegularExpression::PartialPreferCompleteMatch};
|
QRegularExpression::MatchType matchType{QRegularExpression::PartialPreferCompleteMatch};
|
||||||
QTextCharFormat format;
|
QTextCharFormat format;
|
||||||
|
@ -94,4 +119,8 @@ private:
|
||||||
QTextCharFormat singleLineStrikeThroughFormat;
|
QTextCharFormat singleLineStrikeThroughFormat;
|
||||||
QTextCharFormat hyperlinkFormat;
|
QTextCharFormat hyperlinkFormat;
|
||||||
QTextCharFormat highlightedHyperlinkFormat;
|
QTextCharFormat highlightedHyperlinkFormat;
|
||||||
|
|
||||||
|
Features m_features{All};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(StatusSyntaxHighlighter::Features)
|
|
@ -1,8 +1,9 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.15
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Components 0.1
|
||||||
import StatusQ.Controls 0.1
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
import StatusQ.Core.Utils 0.1
|
import StatusQ.Core.Utils 0.1
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ Item {
|
||||||
const editedMessage = formattedMessage.slice(0, index)
|
const editedMessage = formattedMessage.slice(0, index)
|
||||||
+ ` <span class="isEdited">` + qsTr("(edited)") + `</span>`
|
+ ` <span class="isEdited">` + qsTr("(edited)") + `</span>`
|
||||||
+ formattedMessage.slice(index);
|
+ formattedMessage.slice(index);
|
||||||
return Utils.getMessageWithStyle(Emoji.parse(editedMessage), d.hoveredLink)
|
return Utils.getMessageWithStyle(Emoji.parse(editedMessage))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root.convertToSingleLine || isQuote)
|
if (root.convertToSingleLine || isQuote)
|
||||||
|
@ -66,7 +67,7 @@ Item {
|
||||||
// short return not to add styling when no html
|
// short return not to add styling when no html
|
||||||
return formattedMessage
|
return formattedMessage
|
||||||
|
|
||||||
return Utils.getMessageWithStyle(formattedMessage, d.hoveredLink)
|
return Utils.getMessageWithStyle(formattedMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,8 +107,14 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Horizontal crop mask
|
StatusSyntaxHighlighter {
|
||||||
|
quickTextDocument: chatText.textDocument
|
||||||
|
hyperlinkHoverColor: Theme.palette.primaryColor3
|
||||||
|
highlightedHyperlink: d.hoveredLink
|
||||||
|
features: StatusSyntaxHighlighter.HighlightedHyperlink
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal crop mask
|
||||||
Loader {
|
Loader {
|
||||||
id: horizontalClipMask
|
id: horizontalClipMask
|
||||||
anchors.fill: chatText
|
anchors.fill: chatText
|
||||||
|
|
|
@ -9,86 +9,133 @@ StatusSyntaxHighlighter::StatusSyntaxHighlighter(QObject* parent)
|
||||||
|
|
||||||
void StatusSyntaxHighlighter::componentComplete()
|
void StatusSyntaxHighlighter::componentComplete()
|
||||||
{
|
{
|
||||||
HighlightingRule rule;
|
buildRules();
|
||||||
|
|
||||||
//BOLD
|
connect(this, &StatusSyntaxHighlighter::hyperlinksChanged, this, [this](){
|
||||||
singlelineBoldFormat.setFontWeight(QFont::Bold);
|
const auto index = findRuleIndex(StatusSyntaxHighlighter::Hyperlink);
|
||||||
rule.pattern = QRegularExpression(QStringLiteral("(\\*\\*(.*?)\\*\\*)|(\\_\\_(.*?)\\_\\_)"));
|
if (index == -1) return;
|
||||||
rule.format = singlelineBoldFormat;
|
|
||||||
highlightingRules.append(rule);
|
|
||||||
//BOLD
|
|
||||||
|
|
||||||
//ITALIC
|
highlightingRules[index].pattern = hyperlinksRegularExpression();
|
||||||
singleLineItalicFormat.setFontItalic(true);
|
|
||||||
rule.pattern = QRegularExpression(QStringLiteral("(\\*(.*?)\\*)|(\\_(.*?)\\_)"));
|
|
||||||
rule.format = singleLineItalicFormat;
|
|
||||||
highlightingRules.append(rule);
|
|
||||||
//ITALIC
|
|
||||||
|
|
||||||
//STRIKETHROUGH
|
|
||||||
singleLineStrikeThroughFormat.setFontStrikeOut(true);
|
|
||||||
rule.pattern = QRegularExpression(QStringLiteral("\\~\\~(.*?)\\~\\~"));
|
|
||||||
rule.format = singleLineStrikeThroughFormat;
|
|
||||||
highlightingRules.append(rule);
|
|
||||||
//STRIKETHROUGH
|
|
||||||
|
|
||||||
//CODE (`foo`)
|
|
||||||
codeFormat.setFontFamily(QStringLiteral("Roboto Mono"));
|
|
||||||
codeFormat.setBackground(m_codeBackgroundColor);
|
|
||||||
codeFormat.setForeground(m_codeForegroundColor);
|
|
||||||
rule.pattern = QRegularExpression(QStringLiteral("\\`{1}(.+)\\`{1}"),
|
|
||||||
// to not match single backtick pair inside a triple backtick block below
|
|
||||||
QRegularExpression::InvertedGreedinessOption);
|
|
||||||
rule.format = codeFormat;
|
|
||||||
highlightingRules.append(rule);
|
|
||||||
//CODE
|
|
||||||
|
|
||||||
//CODEBLOCK (```\nfoo\nbar```)
|
|
||||||
rule.pattern = QRegularExpression(QStringLiteral("\\`{3}(.+)\\`{3}"));
|
|
||||||
rule.format = codeFormat;
|
|
||||||
highlightingRules.append(rule);
|
|
||||||
//CODEBLOCK
|
|
||||||
|
|
||||||
//HYPERLINKS
|
|
||||||
//QRegularExpression to match any hyperlink in m_hyperlinks
|
|
||||||
hyperlinkFormat.setForeground(m_hyperlinkColor);
|
|
||||||
rule.pattern = hyperlinksRegularExpression();
|
|
||||||
rule.format = hyperlinkFormat;
|
|
||||||
rule.matchType = QRegularExpression::NormalMatch;
|
|
||||||
highlightingRules.append(rule);
|
|
||||||
|
|
||||||
const int hyperlinksRuleIndex = highlightingRules.size() - 1;
|
|
||||||
|
|
||||||
//HIGHLIGHTED
|
|
||||||
highlightedHyperlinkFormat.setForeground(m_hyperlinkColor);
|
|
||||||
highlightedHyperlinkFormat.setBackground(m_hyperlinkHoverColor);
|
|
||||||
rule.pattern = highlightedHyperlinkRegularExpression();
|
|
||||||
rule.format = highlightedHyperlinkFormat;
|
|
||||||
rule.matchType = QRegularExpression::NormalMatch;
|
|
||||||
highlightingRules.append(rule);
|
|
||||||
|
|
||||||
const int highlightedHyperlinkRuleIndex = highlightingRules.size() - 1;
|
|
||||||
|
|
||||||
connect(this, &StatusSyntaxHighlighter::hyperlinksChanged, this, [hyperlinksRuleIndex, this](){
|
|
||||||
highlightingRules[hyperlinksRuleIndex].pattern = hyperlinksRegularExpression();
|
|
||||||
rehighlight();
|
rehighlight();
|
||||||
});
|
});
|
||||||
connect(this, &StatusSyntaxHighlighter::hyperlinkColorChanged, this, [hyperlinksRuleIndex, this](){
|
connect(this, &StatusSyntaxHighlighter::hyperlinkColorChanged, this, [this](){
|
||||||
|
const auto index = findRuleIndex(StatusSyntaxHighlighter::Hyperlink);
|
||||||
|
if (index == -1) return;
|
||||||
|
|
||||||
hyperlinkFormat.setForeground(m_hyperlinkColor);
|
hyperlinkFormat.setForeground(m_hyperlinkColor);
|
||||||
highlightedHyperlinkFormat.setForeground(m_hyperlinkColor);
|
highlightedHyperlinkFormat.setForeground(m_hyperlinkColor);
|
||||||
highlightingRules[hyperlinksRuleIndex].format = hyperlinkFormat;
|
highlightingRules[index].format = hyperlinkFormat;
|
||||||
rehighlight();
|
rehighlight();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &StatusSyntaxHighlighter::highlightedHyperlinkChanged, this, [highlightedHyperlinkRuleIndex, this](){
|
connect(this, &StatusSyntaxHighlighter::highlightedHyperlinkChanged, this, [this](){
|
||||||
highlightingRules[highlightedHyperlinkRuleIndex].pattern = highlightedHyperlinkRegularExpression();
|
const auto index = findRuleIndex(StatusSyntaxHighlighter::HighlightedHyperlink);
|
||||||
|
if (index == -1) return;
|
||||||
|
|
||||||
|
highlightingRules[index].pattern = highlightedHyperlinkRegularExpression();
|
||||||
rehighlight();
|
rehighlight();
|
||||||
});
|
});
|
||||||
connect(this, &StatusSyntaxHighlighter::hyperlinkHoverColorChanged, this, [highlightedHyperlinkRuleIndex, this](){
|
connect(this, &StatusSyntaxHighlighter::hyperlinkHoverColorChanged, this, [this](){
|
||||||
|
const auto index = findRuleIndex(StatusSyntaxHighlighter::HighlightedHyperlink);
|
||||||
|
if (index == -1) return;
|
||||||
|
|
||||||
highlightedHyperlinkFormat.setBackground(m_hyperlinkHoverColor);
|
highlightedHyperlinkFormat.setBackground(m_hyperlinkHoverColor);
|
||||||
highlightingRules[highlightedHyperlinkRuleIndex].format = highlightedHyperlinkFormat;
|
highlightingRules[index].format = highlightedHyperlinkFormat;
|
||||||
rehighlight();
|
rehighlight();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
connect(this, &StatusSyntaxHighlighter::featuresChanged, this, [this](){
|
||||||
|
buildRules();
|
||||||
|
rehighlight();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusSyntaxHighlighter::buildRules()
|
||||||
|
{
|
||||||
|
HighlightingRule rule;
|
||||||
|
highlightingRules.clear();
|
||||||
|
|
||||||
|
if (m_features & StatusSyntaxHighlighter::SingleLineBold)
|
||||||
|
{
|
||||||
|
//BOLD
|
||||||
|
singlelineBoldFormat.setFontWeight(QFont::Bold);
|
||||||
|
rule.id = StatusSyntaxHighlighter::SingleLineBold;
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("(\\*\\*(.*?)\\*\\*)|(\\_\\_(.*?)\\_\\_)"));
|
||||||
|
rule.format = singlelineBoldFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
//BOLD
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_features & StatusSyntaxHighlighter::SingleLineItalic)
|
||||||
|
{
|
||||||
|
//ITALIC
|
||||||
|
singleLineItalicFormat.setFontItalic(true);
|
||||||
|
rule.id = StatusSyntaxHighlighter::SingleLineItalic;
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("(\\*(.*?)\\*)|(\\_(.*?)\\_)"));
|
||||||
|
rule.format = singleLineItalicFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
//ITALIC
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_features & StatusSyntaxHighlighter::SingleLineStrikeThrough)
|
||||||
|
{
|
||||||
|
//STRIKETHROUGH
|
||||||
|
singleLineStrikeThroughFormat.setFontStrikeOut(true);
|
||||||
|
rule.id = StatusSyntaxHighlighter::SingleLineStrikeThrough;
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\~\\~(.*?)\\~\\~"));
|
||||||
|
rule.format = singleLineStrikeThroughFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
//STRIKETHROUGH
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_features & StatusSyntaxHighlighter::Code)
|
||||||
|
{
|
||||||
|
//CODE (`foo`)
|
||||||
|
codeFormat.setFontFamily(QStringLiteral("Roboto Mono"));
|
||||||
|
codeFormat.setBackground(m_codeBackgroundColor);
|
||||||
|
codeFormat.setForeground(m_codeForegroundColor);
|
||||||
|
rule.id = StatusSyntaxHighlighter::Code;
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\`{1}(.+)\\`{1}"),
|
||||||
|
// to not match single backtick pair inside a triple backtick block below
|
||||||
|
QRegularExpression::InvertedGreedinessOption);
|
||||||
|
rule.format = codeFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
//CODE
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_features & StatusSyntaxHighlighter::CodeBlock)
|
||||||
|
{
|
||||||
|
//CODEBLOCK (```\nfoo\nbar```)
|
||||||
|
rule.id = StatusSyntaxHighlighter::CodeBlock;
|
||||||
|
rule.pattern = QRegularExpression(QStringLiteral("\\`{3}(.+)\\`{3}"));
|
||||||
|
rule.format = codeFormat;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
//CODEBLOCK
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_features & StatusSyntaxHighlighter::Hyperlink)
|
||||||
|
{
|
||||||
|
//HYPERLINKS
|
||||||
|
hyperlinkFormat.setForeground(m_hyperlinkColor);
|
||||||
|
rule.id = StatusSyntaxHighlighter::Hyperlink;
|
||||||
|
rule.pattern = hyperlinksRegularExpression();
|
||||||
|
rule.format = hyperlinkFormat;
|
||||||
|
rule.matchType = QRegularExpression::NormalMatch;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
//HYPERLINKS
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_features & StatusSyntaxHighlighter::HighlightedHyperlink)
|
||||||
|
{
|
||||||
|
//HIGHLIGHTED
|
||||||
|
highlightedHyperlinkFormat.setForeground(m_hyperlinkColor);
|
||||||
|
highlightedHyperlinkFormat.setBackground(m_hyperlinkHoverColor);
|
||||||
|
rule.id = StatusSyntaxHighlighter::HighlightedHyperlink;
|
||||||
|
rule.pattern = highlightedHyperlinkRegularExpression();
|
||||||
|
rule.format = highlightedHyperlinkFormat;
|
||||||
|
rule.matchType = QRegularExpression::NormalMatch;
|
||||||
|
highlightingRules.append(rule);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusSyntaxHighlighter::highlightBlock(const QString& text)
|
void StatusSyntaxHighlighter::highlightBlock(const QString& text)
|
||||||
|
@ -217,6 +264,7 @@ QStringList StatusSyntaxHighlighter::getPossibleUrlFormats(const QUrl& url) cons
|
||||||
result.append(QRegularExpression::escape(url.toString()));
|
result.append(QRegularExpression::escape(url.toString()));
|
||||||
result.append(QRegularExpression::escape(url.toString(QUrl::EncodeUnicode)));
|
result.append(QRegularExpression::escape(url.toString(QUrl::EncodeUnicode)));
|
||||||
result.append(QRegularExpression::escape(url.toString(QUrl::FullyEncoded)));
|
result.append(QRegularExpression::escape(url.toString(QUrl::FullyEncoded)));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,9 +273,32 @@ QRegularExpression StatusSyntaxHighlighter::buildHyperlinkRegex(QStringList hype
|
||||||
hyperlinks.removeAll(QString());
|
hyperlinks.removeAll(QString());
|
||||||
|
|
||||||
if(hyperlinks.isEmpty())
|
if(hyperlinks.isEmpty())
|
||||||
return QRegularExpression("(?!)");
|
return QRegularExpression(QStringLiteral("(?!)"));
|
||||||
QString matchHyperlinks = QStringLiteral("(?:^|(?<=\\s))(") + hyperlinks.join("|") + QStringLiteral(")(?:(?=\\s)|$)");
|
QString matchHyperlinks = QStringLiteral("(?:^|(?<=\\s))(") + hyperlinks.join('|') + QStringLiteral(")(?:(?=\\s|[[:punct:]])|$)");
|
||||||
auto regex = QRegularExpression(matchHyperlinks, QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption | QRegularExpression::MultilineOption);
|
auto regex = QRegularExpression(matchHyperlinks, QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption | QRegularExpression::MultilineOption);
|
||||||
regex.optimize();
|
regex.optimize();
|
||||||
return regex;
|
return regex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
StatusSyntaxHighlighter::Features StatusSyntaxHighlighter::features() const
|
||||||
|
{
|
||||||
|
return m_features;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatusSyntaxHighlighter::setFeatures(Features features)
|
||||||
|
{
|
||||||
|
if(features == m_features) return;
|
||||||
|
m_features = features;
|
||||||
|
emit featuresChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
int StatusSyntaxHighlighter::findRuleIndex(FeatureFlags flag) const
|
||||||
|
{
|
||||||
|
for (int i = 0; i < highlightingRules.size(); ++i)
|
||||||
|
{
|
||||||
|
if (highlightingRules[i].id == flag)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
Loading…
Reference in New Issue