diff options
Diffstat (limited to 'src/plugins/coreplugin/find/currentdocumentfind.cpp')
-rw-r--r-- | src/plugins/coreplugin/find/currentdocumentfind.cpp | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/src/plugins/coreplugin/find/currentdocumentfind.cpp b/src/plugins/coreplugin/find/currentdocumentfind.cpp new file mode 100644 index 0000000000..854a391003 --- /dev/null +++ b/src/plugins/coreplugin/find/currentdocumentfind.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "currentdocumentfind.h" + +#include <aggregation/aggregate.h> +#include <coreplugin/coreconstants.h> +#include <utils/qtcassert.h> + +#include <QDebug> +#include <QApplication> +#include <QWidget> + +using namespace Core; +using namespace Core; +using namespace Core::Internal; + +CurrentDocumentFind::CurrentDocumentFind() + : m_currentFind(0) +{ + connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), + this, SLOT(updateCandidateFindFilter(QWidget*,QWidget*))); +} + +void CurrentDocumentFind::removeConnections() +{ + disconnect(qApp, 0, this, 0); + removeFindSupportConnections(); +} + +void CurrentDocumentFind::resetIncrementalSearch() +{ + QTC_ASSERT(m_currentFind, return); + m_currentFind->resetIncrementalSearch(); +} + +void CurrentDocumentFind::clearResults() +{ + QTC_ASSERT(m_currentFind, return); + m_currentFind->clearResults(); +} + +bool CurrentDocumentFind::isEnabled() const +{ + return m_currentFind && (!m_currentWidget || m_currentWidget->isVisible()); +} + +bool CurrentDocumentFind::candidateIsEnabled() const +{ + return (m_candidateFind != 0); +} + +bool CurrentDocumentFind::supportsReplace() const +{ + QTC_ASSERT(m_currentFind, return false); + return m_currentFind->supportsReplace(); +} + +FindFlags CurrentDocumentFind::supportedFindFlags() const +{ + QTC_ASSERT(m_currentFind, return 0); + return m_currentFind->supportedFindFlags(); +} + +QString CurrentDocumentFind::currentFindString() const +{ + QTC_ASSERT(m_currentFind, return QString()); + return m_currentFind->currentFindString(); +} + +QString CurrentDocumentFind::completedFindString() const +{ + QTC_ASSERT(m_currentFind, return QString()); + return m_currentFind->completedFindString(); +} + +void CurrentDocumentFind::highlightAll(const QString &txt, FindFlags findFlags) +{ + QTC_ASSERT(m_currentFind, return); + m_currentFind->highlightAll(txt, findFlags); +} + +IFindSupport::Result CurrentDocumentFind::findIncremental(const QString &txt, FindFlags findFlags) +{ + QTC_ASSERT(m_currentFind, return IFindSupport::NotFound); + return m_currentFind->findIncremental(txt, findFlags); +} + +IFindSupport::Result CurrentDocumentFind::findStep(const QString &txt, FindFlags findFlags) +{ + QTC_ASSERT(m_currentFind, return IFindSupport::NotFound); + return m_currentFind->findStep(txt, findFlags); +} + +void CurrentDocumentFind::replace(const QString &before, const QString &after, FindFlags findFlags) +{ + QTC_ASSERT(m_currentFind, return); + m_currentFind->replace(before, after, findFlags); +} + +bool CurrentDocumentFind::replaceStep(const QString &before, const QString &after, FindFlags findFlags) +{ + QTC_ASSERT(m_currentFind, return false); + return m_currentFind->replaceStep(before, after, findFlags); +} + +int CurrentDocumentFind::replaceAll(const QString &before, const QString &after, FindFlags findFlags) +{ + QTC_ASSERT(m_currentFind, return 0); + return m_currentFind->replaceAll(before, after, findFlags); +} + +void CurrentDocumentFind::defineFindScope() +{ + QTC_ASSERT(m_currentFind, return); + m_currentFind->defineFindScope(); +} + +void CurrentDocumentFind::clearFindScope() +{ + QTC_ASSERT(m_currentFind, return); + m_currentFind->clearFindScope(); +} + +void CurrentDocumentFind::updateCandidateFindFilter(QWidget *old, QWidget *now) +{ + Q_UNUSED(old) + QWidget *candidate = now; + QPointer<IFindSupport> impl = 0; + while (!impl && candidate) { + impl = Aggregation::query<IFindSupport>(candidate); + if (!impl) + candidate = candidate->parentWidget(); + } + if (m_candidateWidget) + disconnect(Aggregation::Aggregate::parentAggregate(m_candidateWidget), SIGNAL(changed()), + this, SLOT(candidateAggregationChanged())); + m_candidateWidget = candidate; + m_candidateFind = impl; + if (m_candidateWidget) + connect(Aggregation::Aggregate::parentAggregate(m_candidateWidget), SIGNAL(changed()), + this, SLOT(candidateAggregationChanged())); + emit candidateChanged(); +} + +void CurrentDocumentFind::acceptCandidate() +{ + if (!m_candidateFind || m_candidateFind == m_currentFind) + return; + removeFindSupportConnections(); + if (m_currentFind) + m_currentFind->clearResults(); + + if (m_currentWidget) + disconnect(Aggregation::Aggregate::parentAggregate(m_currentWidget), SIGNAL(changed()), + this, SLOT(aggregationChanged())); + m_currentWidget = m_candidateWidget; + connect(Aggregation::Aggregate::parentAggregate(m_currentWidget), SIGNAL(changed()), + this, SLOT(aggregationChanged())); + + m_currentFind = m_candidateFind; + if (m_currentFind) { + connect(m_currentFind, SIGNAL(changed()), this, SIGNAL(changed())); + connect(m_currentFind, SIGNAL(destroyed(QObject*)), SLOT(clearFindSupport())); + } + if (m_currentWidget) + m_currentWidget->installEventFilter(this); + emit changed(); +} + +void CurrentDocumentFind::removeFindSupportConnections() +{ + if (m_currentFind) { + disconnect(m_currentFind, SIGNAL(changed()), this, SIGNAL(changed())); + disconnect(m_currentFind, SIGNAL(destroyed(QObject*)), this, SLOT(clearFindSupport())); + } + if (m_currentWidget) + m_currentWidget->removeEventFilter(this); +} + +void CurrentDocumentFind::clearFindSupport() +{ + removeFindSupportConnections(); + m_currentWidget = 0; + m_currentFind = 0; + emit changed(); +} + +bool CurrentDocumentFind::setFocusToCurrentFindSupport() +{ + if (m_currentFind && m_currentWidget) { + QWidget *w = m_currentWidget->focusWidget(); + if (!w) + w = m_currentWidget; + w->setFocus(); + return true; + } + return false; +} + +bool CurrentDocumentFind::eventFilter(QObject *obj, QEvent *event) +{ + if (m_currentWidget && obj == m_currentWidget) { + if (event->type() == QEvent::Hide || event->type() == QEvent::Show) + emit changed(); + } + return QObject::eventFilter(obj, event); +} + +void CurrentDocumentFind::aggregationChanged() +{ + if (m_currentWidget) { + QPointer<IFindSupport> currentFind = Aggregation::query<IFindSupport>(m_currentWidget); + if (currentFind != m_currentFind) { + // There's a change in the find support + if (currentFind) { + m_candidateWidget = m_currentWidget; + m_candidateFind = currentFind; + acceptCandidate(); + } else { + clearFindSupport(); + } + } + } +} + +void CurrentDocumentFind::candidateAggregationChanged() +{ + if (m_candidateWidget && m_candidateWidget != m_currentWidget) { + m_candidateFind = Aggregation::query<IFindSupport>(m_candidateWidget); + emit candidateChanged(); + } +} |