summaryrefslogtreecommitdiff
path: root/src/plugins/find/basetextfind.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/find/basetextfind.cpp')
-rw-r--r--src/plugins/find/basetextfind.cpp246
1 files changed, 246 insertions, 0 deletions
diff --git a/src/plugins/find/basetextfind.cpp b/src/plugins/find/basetextfind.cpp
new file mode 100644
index 0000000000..37787596d9
--- /dev/null
+++ b/src/plugins/find/basetextfind.cpp
@@ -0,0 +1,246 @@
+/***************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+**
+** Non-Open Source Usage
+**
+** Licensees may use this file in accordance with the Qt Beta Version
+** License Agreement, Agreement version 2.2 provided with the Software or,
+** alternatively, in accordance with the terms contained in a written
+** agreement between you and Nokia.
+**
+** GNU General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the packaging
+** of this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+**
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt GPL Exception version
+** 1.2, included in the file GPL_EXCEPTION.txt in this package.
+**
+***************************************************************************/
+#include "basetextfind.h"
+#include <QtGui/QTextBlock>
+
+using namespace Find;
+
+BaseTextFind::BaseTextFind(QTextEdit *editor)
+ : m_editor(editor), m_incrementalStartPos(-1)
+{
+}
+
+BaseTextFind::BaseTextFind(QPlainTextEdit *editor)
+ : m_plaineditor(editor), m_incrementalStartPos(-1)
+{
+}
+
+QTextCursor BaseTextFind::textCursor() const
+{
+ Q_ASSERT(m_editor || m_plaineditor);
+ return m_editor ? m_editor->textCursor() : m_plaineditor->textCursor();
+
+}
+
+void BaseTextFind::setTextCursor(const QTextCursor& cursor)
+{
+ Q_ASSERT(m_editor || m_plaineditor);
+ m_editor ? m_editor->setTextCursor(cursor) : m_plaineditor->setTextCursor(cursor);
+}
+
+QTextDocument *BaseTextFind::document() const
+{
+ Q_ASSERT(m_editor || m_plaineditor);
+ return m_editor ? m_editor->document() : m_plaineditor->document();
+}
+
+bool BaseTextFind::isReadOnly() const
+{
+ Q_ASSERT(m_editor || m_plaineditor);
+ return m_editor ? m_editor->isReadOnly() : m_plaineditor->isReadOnly();
+}
+
+bool BaseTextFind::supportsReplace() const
+{
+ return !isReadOnly();
+}
+
+void BaseTextFind::resetIncrementalSearch()
+{
+ m_incrementalStartPos = -1;
+}
+
+void BaseTextFind::clearResults()
+{
+ emit highlightAll(QString(), 0);
+}
+
+QString BaseTextFind::currentFindString() const
+{
+ QTextCursor cursor = textCursor();
+ if (cursor.hasSelection() && cursor.block() != cursor.document()->findBlock(cursor.anchor())) {
+ return QString(); // multi block selection
+ }
+
+ if (cursor.hasSelection())
+ return cursor.selectedText();
+
+ if (!cursor.atBlockEnd() && !cursor.hasSelection()) {
+ cursor.movePosition(QTextCursor::StartOfWord);
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ QString s = cursor.selectedText();
+ foreach(QChar c, s) {
+ if (!c.isLetterOrNumber() && c != QLatin1Char('_')) {
+ s.clear();
+ break;
+ }
+ }
+ return s;
+ }
+
+ return QString();
+}
+
+QString BaseTextFind::completedFindString() const
+{
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(textCursor().selectionStart());
+ cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
+ return cursor.selectedText();
+}
+
+bool BaseTextFind::findIncremental(const QString &txt, QTextDocument::FindFlags findFlags)
+{
+ QTextCursor cursor = textCursor();
+ if (m_incrementalStartPos < 0)
+ m_incrementalStartPos = cursor.selectionStart();
+ cursor.setPosition(m_incrementalStartPos);
+ findFlags &= ~QTextDocument::FindBackward;
+ bool found = find(txt, findFlags, cursor);
+ if (found)
+ emit highlightAll(txt, findFlags);
+ else
+ emit highlightAll(QString(), 0);
+ return found;
+}
+
+bool BaseTextFind::findStep(const QString &txt, QTextDocument::FindFlags findFlags)
+{
+ bool found = find(txt, findFlags, textCursor());
+ if (found)
+ m_incrementalStartPos = textCursor().selectionStart();
+ return found;
+}
+
+bool BaseTextFind::replaceStep(const QString &before, const QString &after,
+ QTextDocument::FindFlags findFlags)
+{
+ QTextCursor cursor = textCursor();
+ if (cursor.selectedText().compare(before,
+ ((findFlags&QTextDocument::FindCaseSensitively)!=0) ? Qt::CaseSensitive : Qt::CaseInsensitive) == 0) {
+ int start = cursor.selectionStart();
+ cursor.insertText(after);
+ if ((findFlags&QTextDocument::FindBackward) != 0)
+ cursor.setPosition(start);
+ }
+ return find(before, findFlags, cursor);
+}
+
+int BaseTextFind::replaceAll(const QString &before, const QString &after,
+ QTextDocument::FindFlags findFlags)
+{
+ QTextCursor editCursor = textCursor();
+ editCursor.movePosition(QTextCursor::Start);
+ editCursor.beginEditBlock();
+ int count = 0;
+ QTextCursor found;
+ found = document()->find(before, editCursor, findFlags);
+ while (!found.isNull() && inScope(found.selectionStart(), found.selectionEnd())) {
+ ++count;
+ editCursor.setPosition(found.selectionStart());
+ editCursor.setPosition(found.selectionEnd(), QTextCursor::KeepAnchor);
+ editCursor.insertText(after);
+ found = document()->find(before, editCursor, findFlags);
+ }
+ editCursor.endEditBlock();
+ return count;
+}
+
+bool BaseTextFind::find(const QString &txt,
+ QTextDocument::FindFlags findFlags,
+ QTextCursor start)
+{
+ if (txt.isEmpty()) {
+ setTextCursor(start);
+ return true;
+ }
+ QTextCursor found = document()->find(txt, start, findFlags);
+
+ if (!m_findScope.isNull()) {
+
+ // scoped
+ if (found.isNull() || !inScope(found.selectionStart(), found.selectionEnd())) {
+ if ((findFlags&QTextDocument::FindBackward) == 0)
+ start.setPosition(m_findScope.selectionStart());
+ else
+ start.setPosition(m_findScope.selectionEnd());
+ found = document()->find(txt, start, findFlags);
+ if (found.isNull() || !inScope(found.selectionStart(), found.selectionEnd()))
+ return false;
+ }
+ } else {
+
+ // entire document
+ if (found.isNull()) {
+ if ((findFlags&QTextDocument::FindBackward) == 0)
+ start.movePosition(QTextCursor::Start);
+ else
+ start.movePosition(QTextCursor::End);
+ found = document()->find(txt, start, findFlags);
+ if (found.isNull()) {
+ return false;
+ }
+ }
+ }
+ if (!found.isNull()) {
+ setTextCursor(found);
+ }
+ return true;
+}
+
+bool BaseTextFind::inScope(int startPosition, int endPosition) const
+{
+ if (m_findScope.isNull())
+ return true;
+ return (m_findScope.selectionStart() <= startPosition
+ && m_findScope.selectionEnd() >= endPosition);
+}
+
+void BaseTextFind::defineFindScope()
+{
+ QTextCursor cursor = textCursor();
+ if (cursor.hasSelection() && cursor.block() != cursor.document()->findBlock(cursor.anchor())) {
+ m_findScope = cursor;
+ emit findScopeChanged(m_findScope);
+ cursor.setPosition(cursor.selectionStart());
+ setTextCursor(cursor);
+ } else {
+ clearFindScope();
+ }
+}
+
+void BaseTextFind::clearFindScope()
+{
+ m_findScope = QTextCursor();
+ emit findScopeChanged(m_findScope);
+}