diff options
author | Samuel Gaist <samuel.gaist@edeltech.ch> | 2014-11-27 09:20:12 +0100 |
---|---|---|
committer | Konstantin Ritt <ritt.ks@gmail.com> | 2014-11-27 21:17:59 +0100 |
commit | ab3efc09b3a57e1c9e97470368040c5f75ff560b (patch) | |
tree | 9b6198798bc87d4bcf0dc083c36c6917b3ba2aa6 /src/gui/text/qtextdocument.cpp | |
parent | ce6990c3e742e0833df0561246554cf07a888efb (diff) | |
download | qtbase-ab3efc09b3a57e1c9e97470368040c5f75ff560b.tar.gz |
QTextDocument: Don't use QRegExp for string search overloads
Currently both find function with QString input uses QRegExp under the
hood. This patch aims to use only QString search facility to allow
the proper disabling of QRegExp
Change-Id: I3525fd0e969eced635f3d98feb54eb6a05950d8f
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Diffstat (limited to 'src/gui/text/qtextdocument.cpp')
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 3a11266e0a..2eb6f232fb 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -1244,6 +1244,39 @@ void QTextDocument::setHtml(const QString &html) \sa metaInformation(), setMetaInformation() */ +static bool findInBlock(const QTextBlock &block, const QString &expression, int offset, + QTextDocument::FindFlags options, QTextCursor *cursor) +{ + QString text = block.text(); + text.replace(QChar::Nbsp, QLatin1Char(' ')); + Qt::CaseSensitivity sensitivity = options & QTextDocument::FindCaseSensitively ? Qt::CaseSensitive : Qt::CaseInsensitive; + int idx = -1; + + while (offset >= 0 && offset <= text.length()) { + idx = (options & QTextDocument::FindBackward) ? + text.lastIndexOf(expression, offset, sensitivity) : text.indexOf(expression, offset, sensitivity); + if (idx == -1) + return false; + + if (options & QTextDocument::FindWholeWords) { + const int start = idx; + const int end = start + expression.length(); + if ((start != 0 && text.at(start - 1).isLetterOrNumber()) + || (end != text.length() && text.at(end).isLetterOrNumber())) { + //if this is not a whole word, continue the search in the string + offset = (options & QTextDocument::FindBackward) ? idx-1 : end+1; + idx = -1; + continue; + } + } + //we have a hit, return the cursor for that. + *cursor = QTextCursor(block.docHandle(), block.position() + idx); + cursor->setPosition(cursor->position() + expression.length(), QTextCursor::KeepAnchor); + return true; + } + return false; +} + /*! \fn QTextCursor QTextDocument::find(const QString &subString, int position, FindFlags options) const @@ -1262,11 +1295,41 @@ void QTextDocument::setHtml(const QString &html) */ QTextCursor QTextDocument::find(const QString &subString, int from, FindFlags options) const { - QRegExp expr(subString); - expr.setPatternSyntax(QRegExp::FixedString); - expr.setCaseSensitivity((options & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive); + Q_D(const QTextDocument); - return find(expr, from, options); + if (subString.isEmpty()) + return QTextCursor(); + + int pos = from; + //the cursor is positioned between characters, so for a backward search + //do not include the character given in the position. + if (options & FindBackward) { + --pos ; + if (pos < subString.size()) + return QTextCursor(); + } + + QTextCursor cursor; + QTextBlock block = d->blocksFind(pos); + int blockOffset = pos - block.position(); + + if (!(options & FindBackward)) { + while (block.isValid()) { + if (findInBlock(block, subString, blockOffset, options, &cursor)) + return cursor; + block = block.next(); + blockOffset = 0; + } + } else { + while (block.isValid()) { + if (findInBlock(block, subString, blockOffset, options, &cursor)) + return cursor; + block = block.previous(); + blockOffset = block.length() - 2; + } + } + + return QTextCursor(); } /*! @@ -1293,11 +1356,8 @@ QTextCursor QTextDocument::find(const QString &subString, const QTextCursor &cur else pos = cursor.selectionEnd(); } - QRegExp expr(subString); - expr.setPatternSyntax(QRegExp::FixedString); - expr.setCaseSensitivity((options & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive); - return find(expr, pos, options); + return find(subString, pos, options); } |