summaryrefslogtreecommitdiffstats
path: root/src/gui/text
diff options
context:
space:
mode:
authorSamuel Gaist <samuel.gaist@edeltech.ch>2014-11-27 09:20:12 +0100
committerKonstantin Ritt <ritt.ks@gmail.com>2014-11-27 21:17:59 +0100
commitab3efc09b3a57e1c9e97470368040c5f75ff560b (patch)
tree9b6198798bc87d4bcf0dc083c36c6917b3ba2aa6 /src/gui/text
parentce6990c3e742e0833df0561246554cf07a888efb (diff)
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')
-rw-r--r--src/gui/text/qtextdocument.cpp76
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);
}