summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Gaist <samuel.gaist@edeltech.ch>2014-08-27 23:14:59 +0200
committerSamuel Gaist <samuel.gaist@edeltech.ch>2014-09-15 09:35:47 +0200
commit4066a6a893dcaa1258e4801fe9e8d2d7624e37f7 (patch)
tree5c0f84f5c06e6b6ae98d2dd1c10b942c35928642 /src
parent4e8720d413ceca288408ae34bc726f768ca467c6 (diff)
Add QRegularExpression support to QTextDocument
Currently QTextDocuement only provides find using QRegExp. This patch aims to add support for QRegularExpression. [ChangeLog][QtGui][QTextDocument] Support for searching with a QRegularExpression in a document has been added. Change-Id: I6dba10545b83995d093407038a821fe54db3d261 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src')
-rw-r--r--src/gui/text/qtextdocument.cpp126
-rw-r--r--src/gui/text/qtextdocument.h6
2 files changed, 131 insertions, 1 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index fa54776b6d..438fa75492 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -48,6 +48,7 @@
#include "qtextlist.h"
#include <qdebug.h>
#include <qregexp.h>
+#include <qregularexpression.h>
#include <qvarlengtharray.h>
#include <qtextcodec.h>
#include <qthread.h>
@@ -1432,6 +1433,131 @@ QTextCursor QTextDocument::find(const QRegExp &expr, const QTextCursor &from, Fi
return find(expr, pos, options);
}
+#ifndef QT_NO_REGULAREXPRESSION
+static bool findInBlock(const QTextBlock &block, const QRegularExpression &expression, int offset,
+ QTextDocument::FindFlags options, QTextCursor *cursor)
+{
+ QRegularExpression expr(expression);
+ if (!(options & QTextDocument::FindCaseSensitively))
+ expr.setPatternOptions(expr.patternOptions() | QRegularExpression::CaseInsensitiveOption);
+ else
+ expr.setPatternOptions(expr.patternOptions() & ~QRegularExpression::CaseInsensitiveOption);
+
+ QString text = block.text();
+ text.replace(QChar::Nbsp, QLatin1Char(' '));
+ QRegularExpressionMatch match;
+ int idx = -1;
+
+ while (offset >= 0 && offset <= text.length()) {
+ idx = (options & QTextDocument::FindBackward) ?
+ text.lastIndexOf(expr, offset, &match) : text.indexOf(expr, offset, &match);
+ if (idx == -1)
+ return false;
+
+ if (options & QTextDocument::FindWholeWords) {
+ const int start = idx;
+ const int end = start + match.capturedLength();
+ 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.
+ break;
+ }
+ if (idx == -1)
+ return false;
+ *cursor = qMove(QTextCursor(block.docHandle(), block.position() + idx));
+ cursor->setPosition(cursor->position() + match.capturedLength(), QTextCursor::KeepAnchor);
+ return true;
+}
+
+/*!
+ \since 5.5
+
+ Finds the next occurrence, matching the regular expression, \a expr, in the document.
+ The search starts at the given \a from position, and proceeds forwards
+ through the document unless specified otherwise in the search options.
+ The \a options control the type of search performed.
+
+ Returns a cursor with the match selected if a match was found; otherwise
+ returns a null cursor.
+
+ If the \a from position is 0 (the default) the search begins from the beginning
+ of the document; otherwise it begins at the specified position.
+*/
+QTextCursor QTextDocument::find(const QRegularExpression &expr, int from, FindFlags options) const
+{
+ Q_D(const QTextDocument);
+
+ if (!expr.isValid())
+ 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 < 0)
+ return QTextCursor();
+ }
+
+ QTextCursor cursor;
+ QTextBlock block = d->blocksFind(pos);
+
+ if (!(options & FindBackward)) {
+ int blockOffset = qMax(0, pos - block.position());
+ while (block.isValid()) {
+ if (findInBlock(block, expr, blockOffset, options, &cursor))
+ return cursor;
+ blockOffset = 0;
+ block = block.next();
+ }
+ } else {
+ int blockOffset = pos - block.position();
+ while (block.isValid()) {
+ if (findInBlock(block, expr, blockOffset, options, &cursor))
+ return cursor;
+ block = block.previous();
+ blockOffset = block.length() - 1;
+ }
+ }
+
+ return QTextCursor();
+}
+
+/*!
+ \since 5.5
+
+ Finds the next occurrence, matching the regular expression, \a expr, in the document.
+ The search starts at the position of the given \a from cursor, and proceeds
+ forwards through the document unless specified otherwise in the search
+ options. The \a options control the type of search performed.
+
+ Returns a cursor with the match selected if a match was found; otherwise
+ returns a null cursor.
+
+ If the given \a from cursor has a selection, the search begins after the
+ selection; otherwise it begins at the cursor's position.
+
+ By default the search is case-sensitive, and can match text anywhere in the
+ document.
+*/
+QTextCursor QTextDocument::find(const QRegularExpression &expr, const QTextCursor &from, FindFlags options) const
+{
+ int pos = 0;
+ if (!from.isNull()) {
+ if (options & QTextDocument::FindBackward)
+ pos = from.selectionStart();
+ else
+ pos = from.selectionEnd();
+ }
+ return find(expr, pos, options);
+}
+#endif // QT_NO_REGULAREXPRESSION
/*!
\fn QTextObject *QTextDocument::createObject(const QTextFormat &format)
diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h
index 854cb29ed9..3f4b8b565b 100644
--- a/src/gui/text/qtextdocument.h
+++ b/src/gui/text/qtextdocument.h
@@ -169,10 +169,14 @@ public:
QTextCursor find(const QString &subString, int from = 0, FindFlags options = 0) const;
QTextCursor find(const QString &subString, const QTextCursor &from, FindFlags options = 0) const;
-
QTextCursor find(const QRegExp &expr, int from = 0, FindFlags options = 0) const;
QTextCursor find(const QRegExp &expr, const QTextCursor &from, FindFlags options = 0) const;
+#ifndef QT_NO_REGULAREXPRESSION
+ QTextCursor find(const QRegularExpression &expr, int from = 0, FindFlags options = 0) const;
+ QTextCursor find(const QRegularExpression &expr, const QTextCursor &from, FindFlags options = 0) const;
+#endif
+
QTextFrame *frameAt(int pos) const;
QTextFrame *rootFrame() const;