summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qtextdocument.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/text/qtextdocument.cpp')
-rw-r--r--src/gui/text/qtextdocument.cpp166
1 files changed, 144 insertions, 22 deletions
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index ea2b794feb..3820b415a3 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -40,6 +40,7 @@
#include "qtextlist.h"
#include <qdebug.h>
#include <qregexp.h>
+#include <qregularexpression.h>
#include <qvarlengtharray.h>
#include <qtextcodec.h>
#include <qthread.h>
@@ -1269,8 +1270,6 @@ QTextCursor QTextDocument::find(const QString &subString, int from, FindFlags op
}
/*!
- \fn QTextCursor QTextDocument::find(const QString &subString, const QTextCursor &cursor, FindFlags options) const
-
Finds the next occurrence of the string, \a subString, in the document.
The search starts at the position of the given \a cursor, and proceeds
forwards through the document unless specified otherwise in the search
@@ -1285,14 +1284,14 @@ QTextCursor QTextDocument::find(const QString &subString, int from, FindFlags op
By default the search is case-sensitive, and can match text anywhere in the
document.
*/
-QTextCursor QTextDocument::find(const QString &subString, const QTextCursor &from, FindFlags options) const
+QTextCursor QTextDocument::find(const QString &subString, const QTextCursor &cursor, FindFlags options) const
{
int pos = 0;
- if (!from.isNull()) {
+ if (!cursor.isNull()) {
if (options & QTextDocument::FindBackward)
- pos = from.selectionStart();
+ pos = cursor.selectionStart();
else
- pos = from.selectionEnd();
+ pos = cursor.selectionEnd();
}
QRegExp expr(subString);
expr.setPatternSyntax(QRegExp::FixedString);
@@ -1303,7 +1302,7 @@ QTextCursor QTextDocument::find(const QString &subString, const QTextCursor &fro
static bool findInBlock(const QTextBlock &block, const QRegExp &expression, int offset,
- QTextDocument::FindFlags options, QTextCursor &cursor)
+ QTextDocument::FindFlags options, QTextCursor *cursor)
{
QRegExp expr(expression);
QString text = block.text();
@@ -1332,18 +1331,16 @@ static bool findInBlock(const QTextBlock &block, const QRegExp &expression, int
}
if (idx == -1)
return false;
- cursor = QTextCursor(block.docHandle(), block.position() + idx);
- cursor.setPosition(cursor.position() + expr.matchedLength(), QTextCursor::KeepAnchor);
+ *cursor = QTextCursor(block.docHandle(), block.position() + idx);
+ cursor->setPosition(cursor->position() + expr.matchedLength(), QTextCursor::KeepAnchor);
return true;
}
/*!
- \fn QTextCursor QTextDocument::find(const QRegExp & expr, int position, FindFlags options) const
-
\overload
Finds the next occurrence, matching the regular expression, \a expr, in the document.
- The search starts at the given \a position, and proceeds forwards
+ 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. The FindCaseSensitively
option is ignored for this overload, use QRegExp::caseSensitivity instead.
@@ -1351,7 +1348,7 @@ static bool findInBlock(const QTextBlock &block, const QRegExp &expression, int
Returns a cursor with the match selected if a match was found; otherwise
returns a null cursor.
- If the \a position is 0 (the default) the search begins from the beginning
+ 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 QRegExp & expr, int from, FindFlags options) const
@@ -1376,7 +1373,7 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option
if (!(options & FindBackward)) {
int blockOffset = qMax(0, pos - block.position());
while (block.isValid()) {
- if (findInBlock(block, expr, blockOffset, options, cursor))
+ if (findInBlock(block, expr, blockOffset, options, &cursor))
return cursor;
blockOffset = 0;
block = block.next();
@@ -1384,7 +1381,7 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option
} else {
int blockOffset = pos - block.position();
while (block.isValid()) {
- if (findInBlock(block, expr, blockOffset, options, cursor))
+ if (findInBlock(block, expr, blockOffset, options, &cursor))
return cursor;
block = block.previous();
blockOffset = block.length() - 1;
@@ -1395,10 +1392,10 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option
}
/*!
- \fn QTextCursor QTextDocument::find(const QRegExp &expr, const QTextCursor &cursor, FindFlags options) const
+ \overload
Finds the next occurrence, matching the regular expression, \a expr, in the document.
- The search starts at the position of the given \a cursor, and proceeds
+ 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. The FindCaseSensitively
option is ignored for this overload, use QRegExp::caseSensitivity instead.
@@ -1406,24 +1403,149 @@ QTextCursor QTextDocument::find(const QRegExp & expr, int from, FindFlags option
Returns a cursor with the match selected if a match was found; otherwise
returns a null cursor.
- If the given \a cursor has a selection, the search begins after the
+ 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 QRegExp &expr, const QTextCursor &from, FindFlags options) const
+QTextCursor QTextDocument::find(const QRegExp &expr, const QTextCursor &cursor, FindFlags options) const
{
int pos = 0;
- if (!from.isNull()) {
+ if (!cursor.isNull()) {
if (options & QTextDocument::FindBackward)
- pos = from.selectionStart();
+ pos = cursor.selectionStart();
else
- pos = from.selectionEnd();
+ pos = cursor.selectionEnd();
}
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 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 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 &cursor, FindFlags options) const
+{
+ int pos = 0;
+ if (!cursor.isNull()) {
+ if (options & QTextDocument::FindBackward)
+ pos = cursor.selectionStart();
+ else
+ pos = cursor.selectionEnd();
+ }
+ return find(expr, pos, options);
+}
+#endif // QT_NO_REGULAREXPRESSION
/*!
\fn QTextObject *QTextDocument::createObject(const QTextFormat &format)