diff options
Diffstat (limited to 'src/gui/text/qtextdocument.cpp')
-rw-r--r-- | src/gui/text/qtextdocument.cpp | 166 |
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) |