diff options
author | Eike Ziller <eike.ziller@nokia.com> | 2011-09-06 13:03:15 +0200 |
---|---|---|
committer | Eike Ziller <eike.ziller@nokia.com> | 2011-09-07 08:49:30 +0200 |
commit | b0b35a356d78210000d62fa8c77669944bc83d19 (patch) | |
tree | 9d9f63e416f0a77af6a82a79d0d25a01e2a987aa /src/plugins/find | |
parent | e850586b770ab9330347354b01c31eff1053ad78 (diff) | |
download | qt-creator-b0b35a356d78210000d62fa8c77669944bc83d19.tar.gz |
Refactor the search result widget to its own class.
To be used for switching between multiple search result lists.
Change-Id: I4cf62f7e5adf71bac7d4fdfed05d74cea4f3ca44
Rubber-stamped-by: Daniel Teske
Reviewed-on: http://codereview.qt.nokia.com/4255
Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
Diffstat (limited to 'src/plugins/find')
-rw-r--r-- | src/plugins/find/find.pro | 8 | ||||
-rw-r--r-- | src/plugins/find/searchresultwidget.cpp | 489 | ||||
-rw-r--r-- | src/plugins/find/searchresultwidget.h | 125 | ||||
-rw-r--r-- | src/plugins/find/searchresultwindow.cpp | 506 | ||||
-rw-r--r-- | src/plugins/find/searchresultwindow.h | 25 |
5 files changed, 670 insertions, 483 deletions
diff --git a/src/plugins/find/find.pro b/src/plugins/find/find.pro index ba9f99fcf2..ac24d23064 100644 --- a/src/plugins/find/find.pro +++ b/src/plugins/find/find.pro @@ -17,7 +17,8 @@ HEADERS += findtoolwindow.h \ searchresulttreeitems.h \ searchresulttreemodel.h \ searchresulttreeview.h \ - searchresultwindow.h + searchresultwindow.h \ + searchresultwidget.h SOURCES += findtoolwindow.cpp \ currentdocumentfind.cpp \ basetextfind.cpp \ @@ -29,7 +30,10 @@ SOURCES += findtoolwindow.cpp \ searchresulttreeview.cpp \ searchresultwindow.cpp \ ifindfilter.cpp \ - ifindsupport.cpp + ifindsupport.cpp \ + searchresultwidget.cpp FORMS += findwidget.ui \ finddialog.ui RESOURCES += find.qrc + + diff --git a/src/plugins/find/searchresultwidget.cpp b/src/plugins/find/searchresultwidget.cpp new file mode 100644 index 0000000000..8bd7f0c032 --- /dev/null +++ b/src/plugins/find/searchresultwidget.cpp @@ -0,0 +1,489 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "searchresultwidget.h" +#include "searchresulttreeview.h" +#include "searchresulttreemodel.h" +#include "searchresulttreeitems.h" + +#include "ifindsupport.h" + +#include <aggregation/aggregate.h> +#include <coreplugin/icore.h> + +#include <QtCore/QDir> +#include <QtCore/QSettings> +#include <QtGui/QVBoxLayout> + +namespace Find { +namespace Internal { + +class WideEnoughLineEdit : public QLineEdit { + Q_OBJECT +public: + WideEnoughLineEdit(QWidget *parent):QLineEdit(parent){ + connect(this, SIGNAL(textChanged(QString)), + this, SLOT(updateGeometry())); + } + ~WideEnoughLineEdit(){} + QSize sizeHint() const { + QSize sh = QLineEdit::minimumSizeHint(); + sh.rwidth() += qMax(25 * fontMetrics().width(QLatin1Char('x')), + fontMetrics().width(text())); + return sh; + } +public slots: + void updateGeometry() { QLineEdit::updateGeometry(); } +}; + +class SearchResultFindSupport : public IFindSupport +{ + Q_OBJECT +public: + SearchResultFindSupport(SearchResultTreeView *view) + : m_view(view), + m_incrementalWrappedState(false) + { + } + + bool supportsReplace() const { return false; } + + Find::FindFlags supportedFindFlags() const + { + return Find::FindBackward | Find::FindCaseSensitively + | Find::FindRegularExpression | Find::FindWholeWords; + } + + void resetIncrementalSearch() + { + m_incrementalFindStart = QModelIndex(); + m_incrementalWrappedState = false; + } + + void clearResults() { } + + QString currentFindString() const + { + return QString(); + } + + QString completedFindString() const + { + return QString(); + } + + void highlightAll(const QString &txt, Find::FindFlags findFlags) + { + Q_UNUSED(txt) + Q_UNUSED(findFlags) + return; + } + + IFindSupport::Result findIncremental(const QString &txt, Find::FindFlags findFlags) + { + if (!m_incrementalFindStart.isValid()) { + m_incrementalFindStart = m_view->currentIndex(); + m_incrementalWrappedState = false; + } + m_view->setCurrentIndex(m_incrementalFindStart); + bool wrapped = false; + IFindSupport::Result result = find(txt, findFlags, &wrapped); + if (wrapped != m_incrementalWrappedState) { + m_incrementalWrappedState = wrapped; + showWrapIndicator(m_view); + } + return result; + } + + IFindSupport::Result findStep(const QString &txt, Find::FindFlags findFlags) + { + bool wrapped = false; + IFindSupport::Result result = find(txt, findFlags, &wrapped); + if (wrapped) + showWrapIndicator(m_view); + if (result == IFindSupport::Found) { + m_incrementalFindStart = m_view->currentIndex(); + m_incrementalWrappedState = false; + } + return result; + } + + IFindSupport::Result find(const QString &txt, Find::FindFlags findFlags, bool *wrapped) + { + if (wrapped) + *wrapped = false; + if (txt.isEmpty()) + return IFindSupport::NotFound; + QModelIndex index; + if (findFlags & Find::FindRegularExpression) { + bool sensitive = (findFlags & Find::FindCaseSensitively); + index = m_view->model()->find(QRegExp(txt, (sensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)), + m_view->currentIndex(), + Find::textDocumentFlagsForFindFlags(findFlags), + wrapped); + } else { + index = m_view->model()->find(txt, + m_view->currentIndex(), + Find::textDocumentFlagsForFindFlags(findFlags), + wrapped); + } + if (index.isValid()) { + m_view->setCurrentIndex(index); + m_view->scrollTo(index); + if (index.parent().isValid()) + m_view->expand(index.parent()); + return IFindSupport::Found; + } + return IFindSupport::NotFound; + } + + void replace(const QString &before, const QString &after, + Find::FindFlags findFlags) + { + Q_UNUSED(before) + Q_UNUSED(after) + Q_UNUSED(findFlags) + } + + bool replaceStep(const QString &before, const QString &after, + Find::FindFlags findFlags) + { + Q_UNUSED(before) + Q_UNUSED(after) + Q_UNUSED(findFlags) + return false; + } + + int replaceAll(const QString &before, const QString &after, + Find::FindFlags findFlags) + { + Q_UNUSED(before) + Q_UNUSED(after) + Q_UNUSED(findFlags) + return 0; + } + +private: + SearchResultTreeView *m_view; + QModelIndex m_incrementalFindStart; + bool m_incrementalWrappedState; +}; + +} // Internal +} // Find + +using namespace Find; +using namespace Find::Internal; + +SearchResultWidget::SearchResultWidget(QWidget *parent) : + QWidget(parent), + m_count(0), + m_isShowingReplaceUI(false) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + setLayout(layout); + + m_noMatchesFoundDisplay = new QListWidget(this); + m_noMatchesFoundDisplay->addItem(tr("No matches found!")); + m_noMatchesFoundDisplay->setFrameStyle(QFrame::NoFrame); + m_noMatchesFoundDisplay->hide(); + + m_searchResultTreeView = new Internal::SearchResultTreeView(this); + m_searchResultTreeView->setFrameStyle(QFrame::NoFrame); + m_searchResultTreeView->setAttribute(Qt::WA_MacShowFocusRect, false); + Aggregation::Aggregate * agg = new Aggregation::Aggregate; + agg->add(m_searchResultTreeView); + agg->add(new SearchResultFindSupport(m_searchResultTreeView)); + + layout->addWidget(m_noMatchesFoundDisplay); + layout->addWidget(m_searchResultTreeView); + + m_infoBarDisplay.setTarget(layout, 0); + m_infoBarDisplay.setInfoBar(&m_infoBar); + + m_replaceLabel = new QLabel(tr("Replace with:"), parent); + m_replaceLabel->setContentsMargins(12, 0, 5, 0); + m_replaceTextEdit = new WideEnoughLineEdit(parent); + m_replaceButton = new QToolButton(parent); + m_replaceButton->setToolTip(tr("Replace all occurrences")); + m_replaceButton->setText(tr("Replace")); + m_replaceButton->setToolButtonStyle(Qt::ToolButtonTextOnly); + m_replaceButton->setAutoRaise(true); + m_replaceTextEdit->setTabOrder(m_replaceTextEdit, m_searchResultTreeView); + setShowReplaceUI(false); + + connect(m_searchResultTreeView, SIGNAL(jumpToSearchResult(SearchResultItem)), + this, SLOT(handleJumpToSearchResult(SearchResultItem))); + connect(m_replaceTextEdit, SIGNAL(returnPressed()), this, SLOT(handleReplaceButton())); + connect(m_replaceButton, SIGNAL(clicked()), this, SLOT(handleReplaceButton())); +} + +void SearchResultWidget::addResult(const QString &fileName, int lineNumber, const QString &rowText, + int searchTermStart, int searchTermLength, const QVariant &userData) +{ + SearchResultItem item; + item.path = QStringList() << QDir::toNativeSeparators(fileName); + item.lineNumber = lineNumber; + item.text = rowText; + item.textMarkPos = searchTermStart; + item.textMarkLength = searchTermLength; + item.useTextEditorFont = true; + item.userData = userData; + addResults(QList<SearchResultItem>() << item, SearchResult::AddOrdered); +} + +void SearchResultWidget::addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode) +{ + bool firstItems = (m_count == 0); + m_count += items.size(); + m_searchResultTreeView->addResults(items, mode); + if (firstItems) { + if (!m_dontAskAgainGroup.isEmpty() && showWarningMessage()) { + Core::InfoBarEntry info("warninglabel", tr("This change cannot be undone.")); + info.setCustomButtonInfo(tr("Do not warn again"), this, SLOT(hideNoUndoWarning())); + m_infoBar.addInfo(info); + } + + m_replaceTextEdit->setEnabled(true); + // We didn't have an item before, set the focus to the search widget or replace text edit + if (m_isShowingReplaceUI) { + m_replaceTextEdit->setFocus(); + m_replaceTextEdit->selectAll(); + } else { + m_searchResultTreeView->setFocus(); + } + m_searchResultTreeView->selectionModel()->select(m_searchResultTreeView->model()->index(0, 0, QModelIndex()), QItemSelectionModel::Select); + emit navigateStateChanged(); + } +} + +int SearchResultWidget::count() const +{ + return m_count; +} + +QString SearchResultWidget::dontAskAgainGroup() const +{ + return m_dontAskAgainGroup; +} + +void SearchResultWidget::setDontAskAgainGroup(const QString &group) +{ + m_dontAskAgainGroup = group; +} + + +void SearchResultWidget::setTextToReplace(const QString &textToReplace) +{ + m_replaceTextEdit->setText(textToReplace); +} + +QString SearchResultWidget::textToReplace() const +{ + return m_replaceTextEdit->text(); +} + +void SearchResultWidget::setShowReplaceUI(bool visible) +{ + m_searchResultTreeView->model()->setShowReplaceUI(visible); + m_replaceLabel->setVisible(visible); + m_replaceTextEdit->setVisible(visible); + m_replaceButton->setVisible(visible); + m_isShowingReplaceUI = visible; +} + +bool SearchResultWidget::hasFocusInternally() const +{ + return m_searchResultTreeView->hasFocus() || (m_isShowingReplaceUI && m_replaceTextEdit->hasFocus()); +} + +void SearchResultWidget::setFocusInternally() +{ + if (m_count > 0) { + if (m_isShowingReplaceUI) { + if (!focusWidget() || focusWidget() == m_replaceTextEdit) { + m_replaceTextEdit->setFocus(); + m_replaceTextEdit->selectAll(); + } else { + m_searchResultTreeView->setFocus(); + } + } else { + m_searchResultTreeView->setFocus(); + } + } +} + +bool SearchResultWidget::canFocusInternally() const +{ + return m_count > 0; +} + +void SearchResultWidget::notifyVisibilityChanged(bool visible) +{ + emit visibilityChanged(visible); +} + +void SearchResultWidget::setTextEditorFont(const QFont &font) +{ + m_searchResultTreeView->setTextEditorFont(font); +} + +void SearchResultWidget::setAutoExpandResults(bool expand) +{ + m_searchResultTreeView->setAutoExpandResults(expand); +} + +void SearchResultWidget::expandAll() +{ + m_searchResultTreeView->expandAll(); +} + +void SearchResultWidget::collapseAll() +{ + m_searchResultTreeView->collapseAll(); +} + +void SearchResultWidget::goToNext() +{ + if (m_count == 0) + return; + QModelIndex idx = m_searchResultTreeView->model()->next(m_searchResultTreeView->currentIndex()); + if (idx.isValid()) { + m_searchResultTreeView->setCurrentIndex(idx); + m_searchResultTreeView->emitJumpToSearchResult(idx); + } +} + +void SearchResultWidget::goToPrevious() +{ + if (!m_searchResultTreeView->model()->rowCount()) + return; + QModelIndex idx = m_searchResultTreeView->model()->prev(m_searchResultTreeView->currentIndex()); + if (idx.isValid()) { + m_searchResultTreeView->setCurrentIndex(idx); + m_searchResultTreeView->emitJumpToSearchResult(idx); + } +} + +void SearchResultWidget::finishSearch() +{ + if (m_count > 0) { + m_replaceButton->setEnabled(true); + } else { + showNoMatchesFound(); + } +} + +void SearchResultWidget::clear() +{ + m_replaceTextEdit->setEnabled(false); + m_replaceButton->setEnabled(false); + m_replaceTextEdit->clear(); + m_searchResultTreeView->clear(); + m_count = 0; + m_noMatchesFoundDisplay->hide(); + m_infoBar.clear(); +} + +void SearchResultWidget::showNoMatchesFound() +{ + m_replaceTextEdit->setEnabled(false); + m_replaceButton->setEnabled(false); + m_noMatchesFoundDisplay->show(); +} + +void SearchResultWidget::hideNoUndoWarning() +{ + setShowWarningMessage(false); + m_infoBar.clear(); +} + +void SearchResultWidget::handleJumpToSearchResult(const SearchResultItem &item) +{ + emit activated(item); +} + +void SearchResultWidget::handleReplaceButton() +{ + // check if button is actually enabled, because this is also triggered + // by pressing return in replace line edit + if (m_replaceButton->isEnabled()) { + m_infoBar.clear(); + emit replaceButtonClicked(m_replaceTextEdit->text(), checkedItems()); + } +} + +bool SearchResultWidget::showWarningMessage() const +{ + // read settings + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(m_dontAskAgainGroup); + settings->beginGroup(QLatin1String("Rename")); + const bool showWarningMessage = settings->value(QLatin1String("ShowWarningMessage"), true).toBool(); + settings->endGroup(); + settings->endGroup(); + return showWarningMessage; +} + +void SearchResultWidget::setShowWarningMessage(bool showWarningMessage) +{ + // write to settings + QSettings *settings = Core::ICore::instance()->settings(); + settings->beginGroup(m_dontAskAgainGroup); + settings->beginGroup(QLatin1String("Rename")); + settings->setValue(QLatin1String("ShowWarningMessage"), showWarningMessage); + settings->endGroup(); + settings->endGroup(); +} + +QList<SearchResultItem> SearchResultWidget::checkedItems() const +{ + QList<SearchResultItem> result; + Internal::SearchResultTreeModel *model = m_searchResultTreeView->model(); + const int fileCount = model->rowCount(QModelIndex()); + for (int i = 0; i < fileCount; ++i) { + QModelIndex fileIndex = model->index(i, 0, QModelIndex()); + Internal::SearchResultTreeItem *fileItem = static_cast<Internal::SearchResultTreeItem *>(fileIndex.internalPointer()); + Q_ASSERT(fileItem != 0); + for (int rowIndex = 0; rowIndex < fileItem->childrenCount(); ++rowIndex) { + QModelIndex textIndex = model->index(rowIndex, 0, fileIndex); + Internal::SearchResultTreeItem *rowItem = static_cast<Internal::SearchResultTreeItem *>(textIndex.internalPointer()); + if (rowItem->checkState()) + result << rowItem->item; + } + } + return result; +} + +#include "searchresultwidget.moc" diff --git a/src/plugins/find/searchresultwidget.h b/src/plugins/find/searchresultwidget.h new file mode 100644 index 0000000000..bd6f1df952 --- /dev/null +++ b/src/plugins/find/searchresultwidget.h @@ -0,0 +1,125 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef SEARCHRESULTWIDGET_H +#define SEARCHRESULTWIDGET_H + +#include "searchresultwindow.h" + +#include <coreplugin/infobar.h> + +#include <QtGui/QLabel> +#include <QtGui/QLineEdit> +#include <QtGui/QListWidget> +#include <QtGui/QToolButton> +#include <QtGui/QWidget> + +namespace Find { +namespace Internal { + +class SearchResultTreeView; + +class SearchResultWidget : public QWidget +{ + Q_OBJECT +public: + explicit SearchResultWidget(QWidget *parent = 0); + + void addResult(const QString &fileName, int lineNumber, const QString &lineText, + int searchTermStart, int searchTermLength, const QVariant &userData = QVariant()); + void addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode); + + int count() const; + + QString dontAskAgainGroup() const; + void setDontAskAgainGroup(const QString &group); + + void setTextToReplace(const QString &textToReplace); + QString textToReplace() const; + void setShowReplaceUI(bool visible); + + bool hasFocusInternally() const; + void setFocusInternally(); + bool canFocusInternally() const; + + void notifyVisibilityChanged(bool visible); + + void setTextEditorFont(const QFont &font); + + void setAutoExpandResults(bool expand); + void expandAll(); + void collapseAll(); + + void goToNext(); + void goToPrevious(); + + // TODO: temporary + QList<QWidget*> toolBarWidgets() const { return QList<QWidget*>() << m_replaceLabel << m_replaceTextEdit << m_replaceButton; } + +public slots: + void finishSearch(); + void clear(); + void showNoMatchesFound(); + +signals: + void activated(const Find::SearchResultItem &item); + void replaceButtonClicked(const QString &replaceText, const QList<Find::SearchResultItem> &checkedItems); + void visibilityChanged(bool visible); + + void navigateStateChanged(); + +private slots: + void hideNoUndoWarning(); + void handleJumpToSearchResult(const SearchResultItem &item); + void handleReplaceButton(); + +private: + bool showWarningMessage() const; + void setShowWarningMessage(bool showWarningMessage); + QList<SearchResultItem> checkedItems() const; + + SearchResultTreeView *m_searchResultTreeView; + int m_count; + QString m_dontAskAgainGroup; + Core::InfoBar m_infoBar; + Core::InfoBarDisplay m_infoBarDisplay; + QListWidget *m_noMatchesFoundDisplay; + bool m_isShowingReplaceUI; + QLabel *m_replaceLabel; + QLineEdit *m_replaceTextEdit; + QToolButton *m_replaceButton; +}; + +} // Internal +} // Find + +#endif // SEARCHRESULTWIDGET_H diff --git a/src/plugins/find/searchresultwindow.cpp b/src/plugins/find/searchresultwindow.cpp index 73957b9e5d..0bba9a8bc0 100644 --- a/src/plugins/find/searchresultwindow.cpp +++ b/src/plugins/find/searchresultwindow.cpp @@ -31,31 +31,19 @@ **************************************************************************/ #include "searchresultwindow.h" -#include "searchresulttreemodel.h" -#include "searchresulttreeitems.h" -#include "searchresulttreeview.h" -#include "ifindsupport.h" +#include "searchresultwidget.h" -#include <aggregation/aggregate.h> #include <coreplugin/icore.h> -#include <coreplugin/infobar.h> #include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/command.h> #include <coreplugin/coreconstants.h> #include <coreplugin/icontext.h> -#include <coreplugin/id.h> #include <utils/qtcassert.h> #include <QtCore/QFile> -#include <QtCore/QTextStream> #include <QtCore/QSettings> #include <QtCore/QDebug> -#include <QtCore/QDir> -#include <QtGui/QListWidget> -#include <QtGui/QToolButton> -#include <QtGui/QLineEdit> #include <QtGui/QVBoxLayout> -#include <QtGui/QLabel> #include <QtGui/QFont> #include <QtGui/QAction> @@ -66,183 +54,19 @@ namespace Find { namespace Internal { - class WideEnoughLineEdit : public QLineEdit { - Q_OBJECT - public: - WideEnoughLineEdit(QWidget *parent):QLineEdit(parent){ - connect(this, SIGNAL(textChanged(QString)), - this, SLOT(updateGeometry())); - } - ~WideEnoughLineEdit(){} - QSize sizeHint() const { - QSize sh = QLineEdit::minimumSizeHint(); - sh.rwidth() += qMax(25 * fontMetrics().width(QLatin1Char('x')), - fontMetrics().width(text())); - return sh; - } - public slots: - void updateGeometry() { QLineEdit::updateGeometry(); } - }; - - class SearchResultFindSupport : public IFindSupport - { - Q_OBJECT - public: - SearchResultFindSupport(SearchResultTreeView *view) - : m_view(view), - m_incrementalWrappedState(false) - { - } - - bool supportsReplace() const { return false; } - - Find::FindFlags supportedFindFlags() const - { - return Find::FindBackward | Find::FindCaseSensitively - | Find::FindRegularExpression | Find::FindWholeWords; - } - - void resetIncrementalSearch() - { - m_incrementalFindStart = QModelIndex(); - m_incrementalWrappedState = false; - } - - void clearResults() { } - - QString currentFindString() const - { - return QString(); - } - - QString completedFindString() const - { - return QString(); - } - - void highlightAll(const QString &txt, Find::FindFlags findFlags) - { - Q_UNUSED(txt) - Q_UNUSED(findFlags) - return; - } - - IFindSupport::Result findIncremental(const QString &txt, Find::FindFlags findFlags) - { - if (!m_incrementalFindStart.isValid()) { - m_incrementalFindStart = m_view->currentIndex(); - m_incrementalWrappedState = false; - } - m_view->setCurrentIndex(m_incrementalFindStart); - bool wrapped = false; - IFindSupport::Result result = find(txt, findFlags, &wrapped); - if (wrapped != m_incrementalWrappedState) { - m_incrementalWrappedState = wrapped; - showWrapIndicator(m_view); - } - return result; - } - - IFindSupport::Result findStep(const QString &txt, Find::FindFlags findFlags) - { - bool wrapped = false; - IFindSupport::Result result = find(txt, findFlags, &wrapped); - if (wrapped) - showWrapIndicator(m_view); - if (result == IFindSupport::Found) { - m_incrementalFindStart = m_view->currentIndex(); - m_incrementalWrappedState = false; - } - return result; - } - - IFindSupport::Result find(const QString &txt, Find::FindFlags findFlags, bool *wrapped) - { - if (wrapped) - *wrapped = false; - if (txt.isEmpty()) - return IFindSupport::NotFound; - QModelIndex index; - if (findFlags & Find::FindRegularExpression) { - bool sensitive = (findFlags & Find::FindCaseSensitively); - index = m_view->model()->find(QRegExp(txt, (sensitive ? Qt::CaseSensitive : Qt::CaseInsensitive)), - m_view->currentIndex(), - Find::textDocumentFlagsForFindFlags(findFlags), - wrapped); - } else { - index = m_view->model()->find(txt, - m_view->currentIndex(), - Find::textDocumentFlagsForFindFlags(findFlags), - wrapped); - } - if (index.isValid()) { - m_view->setCurrentIndex(index); - m_view->scrollTo(index); - if (index.parent().isValid()) - m_view->expand(index.parent()); - return IFindSupport::Found; - } - return IFindSupport::NotFound; - } - - void replace(const QString &before, const QString &after, - Find::FindFlags findFlags) - { - Q_UNUSED(before) - Q_UNUSED(after) - Q_UNUSED(findFlags) - } - - bool replaceStep(const QString &before, const QString &after, - Find::FindFlags findFlags) - { - Q_UNUSED(before) - Q_UNUSED(after) - Q_UNUSED(findFlags) - return false; - } - - int replaceAll(const QString &before, const QString &after, - Find::FindFlags findFlags) - { - Q_UNUSED(before) - Q_UNUSED(after) - Q_UNUSED(findFlags) - return 0; - } - - private: - SearchResultTreeView *m_view; - QModelIndex m_incrementalFindStart; - bool m_incrementalWrappedState; - }; - struct SearchResultWindowPrivate { SearchResultWindowPrivate(); - Internal::SearchResultTreeView *m_searchResultTreeView; - QListWidget *m_noMatchesFoundDisplay; + Internal::SearchResultWidget *m_searchResultWidget; QToolButton *m_expandCollapseButton; QAction *m_expandCollapseAction; - QLabel *m_replaceLabel; - QLineEdit *m_replaceTextEdit; - QToolButton *m_replaceButton; static const bool m_initiallyExpand = false; QWidget *m_widget; SearchResult *m_currentSearch; - int m_itemCount; - bool m_isShowingReplaceUI; - bool m_focusReplaceEdit; - QString m_dontAskAgainGroup; - Core::InfoBar m_infoBar; - Core::InfoBarDisplay m_infoBarDisplay; }; SearchResultWindowPrivate::SearchResultWindowPrivate() - : m_currentSearch(0), - m_itemCount(0), - m_isShowingReplaceUI(false), - m_focusReplaceEdit(false) + : m_currentSearch(0) { } } @@ -311,7 +135,7 @@ using namespace Find::Internal; After the search has finished call finishSearch to inform the search result window about it. - After that you get activated signals via your SearchResult instance when + You will get activated signals via your SearchResult instance when the user selects a search result item, and, if you started the search with the SearchAndReplace option, the replaceButtonClicked signal when the user requests a replace. @@ -334,27 +158,13 @@ SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate) d->m_widget = new QWidget; d->m_widget->setWindowTitle(displayName()); - d->m_searchResultTreeView = new Internal::SearchResultTreeView(d->m_widget); - d->m_searchResultTreeView->setFrameStyle(QFrame::NoFrame); - d->m_searchResultTreeView->setAttribute(Qt::WA_MacShowFocusRect, false); - Aggregation::Aggregate * agg = new Aggregation::Aggregate; - agg->add(d->m_searchResultTreeView); - agg->add(new SearchResultFindSupport(d->m_searchResultTreeView)); - - d->m_noMatchesFoundDisplay = new QListWidget(d->m_widget); - d->m_noMatchesFoundDisplay->addItem(tr("No matches found!")); - d->m_noMatchesFoundDisplay->setFrameStyle(QFrame::NoFrame); - d->m_noMatchesFoundDisplay->hide(); + d->m_searchResultWidget = new Internal::SearchResultWidget(d->m_widget); QVBoxLayout *vlay = new QVBoxLayout; d->m_widget->setLayout(vlay); vlay->setMargin(0); vlay->setSpacing(0); - vlay->addWidget(d->m_noMatchesFoundDisplay); - vlay->addWidget(d->m_searchResultTreeView); - - d->m_infoBarDisplay.setTarget(vlay, 0); - d->m_infoBarDisplay.setInfoBar(&d->m_infoBar); + vlay->addWidget(d->m_searchResultWidget); d->m_expandCollapseButton = new QToolButton(d->m_widget); d->m_expandCollapseButton->setAutoRaise(true); @@ -368,24 +178,9 @@ SearchResultWindow::SearchResultWindow() : d(new SearchResultWindowPrivate) cmd->setAttribute(Core::Command::CA_UpdateText); d->m_expandCollapseButton->setDefaultAction(cmd->action()); - d->m_replaceLabel = new QLabel(tr("Replace with:"), d->m_widget); - d->m_replaceLabel->setContentsMargins(12, 0, 5, 0); - d->m_replaceTextEdit = new WideEnoughLineEdit(d->m_widget); - d->m_replaceButton = new QToolButton(d->m_widget); - d->m_replaceButton->setToolTip(tr("Replace all occurrences")); - d->m_replaceButton->setText(tr("Replace")); - d->m_replaceButton->setToolButtonStyle(Qt::ToolButtonTextOnly); - d->m_replaceButton->setAutoRaise(true); - d->m_replaceTextEdit->setTabOrder(d->m_replaceTextEdit, d->m_searchResultTreeView); - - connect(d->m_searchResultTreeView, SIGNAL(jumpToSearchResult(SearchResultItem)), - this, SLOT(handleJumpToSearchResult(SearchResultItem))); connect(d->m_expandCollapseAction, SIGNAL(toggled(bool)), this, SLOT(handleExpandCollapseToolButton(bool))); - connect(d->m_replaceTextEdit, SIGNAL(returnPressed()), this, SLOT(handleReplaceButton())); - connect(d->m_replaceButton, SIGNAL(clicked()), this, SLOT(handleReplaceButton())); - + connect(d->m_searchResultWidget, SIGNAL(navigateStateChanged()), this, SLOT(navigateStateChanged())); readSettings(); - setShowReplaceUI(false); } /*! @@ -399,7 +194,6 @@ SearchResultWindow::~SearchResultWindow() d->m_currentSearch = 0; delete d->m_widget; d->m_widget = 0; - d->m_itemCount = 0; delete d; } @@ -413,82 +207,12 @@ SearchResultWindow *SearchResultWindow::instance() } /*! - \fn void SearchResultWindow::setTextToReplace(const QString &textToReplace) - \internal -*/ -void SearchResultWindow::setTextToReplace(const QString &textToReplace) -{ - d->m_replaceTextEdit->setText(textToReplace); -} - -/*! - \fn QString SearchResultWindow::textToReplace() const - \internal -*/ -QString SearchResultWindow::textToReplace() const -{ - return d->m_replaceTextEdit->text(); -} - -/*! - \fn void SearchResultWindow::setShowReplaceUI(bool show) - \internal -*/ -void SearchResultWindow::setShowReplaceUI(bool show) -{ - d->m_searchResultTreeView->model()->setShowReplaceUI(show); - d->m_replaceLabel->setVisible(show); - d->m_replaceTextEdit->setVisible(show); - d->m_replaceButton->setVisible(show); - d->m_isShowingReplaceUI = show; -} - -/*! - \fn void SearchResultWindow::handleReplaceButton() - \internal -*/ -void SearchResultWindow::handleReplaceButton() -{ - QTC_ASSERT(d->m_currentSearch, return); - // check if button is actually enabled, because this is also triggered - // by pressing return in replace line edit - if (d->m_replaceButton->isEnabled()) { - d->m_infoBar.clear(); - d->m_currentSearch->replaceButtonClicked(d->m_replaceTextEdit->text(), checkedItems()); - } -} - -/*! - \fn QList<SearchResultItem> SearchResultWindow::checkedItems() const - \internal -*/ -QList<SearchResultItem> SearchResultWindow::checkedItems() const -{ - QList<SearchResultItem> result; - Internal::SearchResultTreeModel *model = d->m_searchResultTreeView->model(); - const int fileCount = model->rowCount(QModelIndex()); - for (int i = 0; i < fileCount; ++i) { - QModelIndex fileIndex = model->index(i, 0, QModelIndex()); - Internal::SearchResultTreeItem *fileItem = static_cast<Internal::SearchResultTreeItem *>(fileIndex.internalPointer()); - Q_ASSERT(fileItem != 0); - for (int rowIndex = 0; rowIndex < fileItem->childrenCount(); ++rowIndex) { - QModelIndex textIndex = model->index(rowIndex, 0, fileIndex); - Internal::SearchResultTreeItem *rowItem = static_cast<Internal::SearchResultTreeItem *>(textIndex.internalPointer()); - if (rowItem->checkState()) - result << rowItem->item; - } - } - return result; -} - -/*! \fn void SearchResultWindow::visibilityChanged(bool) \internal */ void SearchResultWindow::visibilityChanged(bool visible) { - if (d->m_currentSearch) - d->m_currentSearch->visibilityChanged(visible); + d->m_searchResultWidget->notifyVisibilityChanged(visible); } /*! @@ -506,7 +230,7 @@ QWidget *SearchResultWindow::outputWidget(QWidget *) */ QList<QWidget*> SearchResultWindow::toolBarWidgets() const { - return QList<QWidget*>() << d->m_expandCollapseButton << d->m_replaceLabel << d->m_replaceTextEdit << d->m_replaceButton; + return QList<QWidget*>() << d->m_expandCollapseButton << d->m_searchResultWidget->toolBarWidgets(); } /*! @@ -524,69 +248,30 @@ QList<QWidget*> SearchResultWindow::toolBarWidgets() const SearchResult *SearchResultWindow::startNewSearch(SearchMode searchOrSearchAndReplace, const QString &cfgGroup) { clearContents(); - setShowReplaceUI(searchOrSearchAndReplace != SearchOnly); - d->m_dontAskAgainGroup = cfgGroup; + d->m_searchResultWidget->setShowReplaceUI(searchOrSearchAndReplace != SearchOnly); + d->m_searchResultWidget->setDontAskAgainGroup(cfgGroup); delete d->m_currentSearch; - d->m_currentSearch = new SearchResult; + d->m_currentSearch = new SearchResult(d->m_searchResultWidget); return d->m_currentSearch; } /*! - \fn void SearchResultWindow::finishSearch() - \internal -*/ -void SearchResultWindow::finishSearch() -{ - if (d->m_itemCount > 0) { - d->m_replaceButton->setEnabled(true); - } else { - showNoMatchesFound(); - } -} - -/*! \fn void SearchResultWindow::clearContents() \brief Clears the current contents in the search result window. */ void SearchResultWindow::clearContents() { - d->m_replaceTextEdit->setEnabled(false); - d->m_replaceButton->setEnabled(false); - d->m_replaceTextEdit->clear(); - d->m_searchResultTreeView->clear(); - d->m_itemCount = 0; - d->m_noMatchesFoundDisplay->hide(); - d->m_infoBar.clear(); + d->m_searchResultWidget->clear(); navigateStateChanged(); } /*! - \fn void SearchResultWindow::showNoMatchesFound() - \internal -*/ -void SearchResultWindow::showNoMatchesFound() -{ - d->m_replaceTextEdit->setEnabled(false); - d->m_replaceButton->setEnabled(false); - d->m_noMatchesFoundDisplay->show(); -} - -/*! - \fn bool SearchResultWindow::isEmpty() const - Returns if the search result window currently doesn't show any results. -*/ -bool SearchResultWindow::isEmpty() const -{ - return (d->m_searchResultTreeView->model()->rowCount() < 1); -} - -/*! \fn bool SearchResultWindow::hasFocus() \internal */ bool SearchResultWindow::hasFocus() { - return d->m_searchResultTreeView->hasFocus() || (d->m_isShowingReplaceUI && d->m_replaceTextEdit->hasFocus()); + return d->m_searchResultWidget->hasFocusInternally(); } /*! @@ -595,7 +280,7 @@ bool SearchResultWindow::hasFocus() */ bool SearchResultWindow::canFocus() { - return d->m_itemCount > 0; + return d->m_searchResultWidget->canFocusInternally(); } /*! @@ -604,20 +289,7 @@ bool SearchResultWindow::canFocus() */ void SearchResultWindow::setFocus() { - if (d->m_itemCount > 0) { - if (!d->m_isShowingReplaceUI) { - d->m_searchResultTreeView->setFocus(); - } else { - if (!d->m_widget->focusWidget() - || d->m_widget->focusWidget() == d->m_replaceTextEdit - || d->m_focusReplaceEdit) { - d->m_replaceTextEdit->setFocus(); - d->m_replaceTextEdit->selectAll(); - } else { - d->m_searchResultTreeView->setFocus(); - } - } - } + d->m_searchResultWidget->setFocusInternally(); } /*! @@ -626,90 +298,7 @@ void SearchResultWindow::setFocus() */ void SearchResultWindow::setTextEditorFont(const QFont &font) { - d->m_searchResultTreeView->setTextEditorFont(font); -} - -/*! - \fn void SearchResultWindow::handleJumpToSearchResult(const SearchResultItem &item) - \internal -*/ -void SearchResultWindow::handleJumpToSearchResult(const SearchResultItem &item) -{ - QTC_ASSERT(d->m_currentSearch, return); - d->m_currentSearch->activated(item); -} - -/*! - \fn void SearchResultWindow::addResult(const QString &fileName, int lineNumber, const QString &rowText, int searchTermStart, int searchTermLength, const QVariant &userData) - \internal -*/ -void SearchResultWindow::addResult(const QString &fileName, int lineNumber, const QString &rowText, - int searchTermStart, int searchTermLength, const QVariant &userData) -{ - SearchResultItem item; - item.path = QStringList() << QDir::toNativeSeparators(fileName); - item.lineNumber = lineNumber; - item.text = rowText; - item.textMarkPos = searchTermStart; - item.textMarkLength = searchTermLength; - item.useTextEditorFont = true; - item.userData = userData; - addResults(QList<SearchResultItem>() << item, SearchResult::AddOrdered); -} - -/*! - \fn void SearchResultWindow::addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode) - \internal -*/ -void SearchResultWindow::addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode) -{ - bool firstItems = (d->m_itemCount == 0); - d->m_itemCount += items.size(); - d->m_searchResultTreeView->addResults(items, mode); - if (firstItems) { - if (!d->m_dontAskAgainGroup.isEmpty() && showWarningMessage()) { - Core::InfoBarEntry info("warninglabel", tr("This change cannot be undone.")); - info.setCustomButtonInfo(tr("Do not warn again"), this, SLOT(hideNoUndoWarning())); - d->m_infoBar.addInfo(info); - } - - d->m_replaceTextEdit->setEnabled(true); - // We didn't have an item before, set the focus to the search widget - d->m_focusReplaceEdit = true; - setFocus(); - d->m_focusReplaceEdit = false; - d->m_searchResultTreeView->selectionModel()->select(d->m_searchResultTreeView->model()->index(0, 0, QModelIndex()), QItemSelectionModel::Select); - emit navigateStateChanged(); - } -} - -bool SearchResultWindow::showWarningMessage() const -{ - // Restore settings - QSettings *settings = Core::ICore::instance()->settings(); - settings->beginGroup(d->m_dontAskAgainGroup); - settings->beginGroup(QLatin1String("Rename")); - const bool showWarningMessage = settings->value(QLatin1String("ShowWarningMessage"), true).toBool(); - settings->endGroup(); - settings->endGroup(); - return showWarningMessage; -} - -void SearchResultWindow::setShowWarningMessage(bool showWarningMessage) -{ - // Restore settings - QSettings *settings = Core::ICore::instance()->settings(); - settings->beginGroup(d->m_dontAskAgainGroup); - settings->beginGroup(QLatin1String("Rename")); - settings->setValue(QLatin1String("ShowWarningMessage"), showWarningMessage); - settings->endGroup(); - settings->endGroup(); -} - -void SearchResultWindow::hideNoUndoWarning() -{ - setShowWarningMessage(false); - d->m_infoBar.clear(); + d->m_searchResultWidget->setTextEditorFont(font); } /*! @@ -718,13 +307,13 @@ void SearchResultWindow::hideNoUndoWarning() */ void SearchResultWindow::handleExpandCollapseToolButton(bool checked) { - d->m_searchResultTreeView->setAutoExpandResults(checked); + d->m_searchResultWidget->setAutoExpandResults(checked); if (checked) { d->m_expandCollapseAction->setText(tr("Collapse All")); - d->m_searchResultTreeView->expandAll(); + d->m_searchResultWidget->expandAll(); } else { d->m_expandCollapseAction->setText(tr("Expand All")); - d->m_searchResultTreeView->collapseAll(); + d->m_searchResultWidget->collapseAll(); } } @@ -771,7 +360,7 @@ int SearchResultWindow::priorityInStatusBar() const */ bool SearchResultWindow::canNext() { - return d->m_itemCount > 0; + return d->m_searchResultWidget->count() > 0; } /*! @@ -780,7 +369,7 @@ bool SearchResultWindow::canNext() */ bool SearchResultWindow::canPrevious() { - return d->m_itemCount > 0; + return d->m_searchResultWidget->count() > 0; } /*! @@ -789,13 +378,7 @@ bool SearchResultWindow::canPrevious() */ void SearchResultWindow::goToNext() { - if (d->m_itemCount == 0) - return; - QModelIndex idx = d->m_searchResultTreeView->model()->next(d->m_searchResultTreeView->currentIndex()); - if (idx.isValid()) { - d->m_searchResultTreeView->setCurrentIndex(idx); - d->m_searchResultTreeView->emitJumpToSearchResult(idx); - } + d->m_searchResultWidget->goToNext(); } /*! @@ -804,13 +387,7 @@ void SearchResultWindow::goToNext() */ void SearchResultWindow::goToPrev() { - if (!d->m_searchResultTreeView->model()->rowCount()) - return; - QModelIndex idx = d->m_searchResultTreeView->model()->prev(d->m_searchResultTreeView->currentIndex()); - if (idx.isValid()) { - d->m_searchResultTreeView->setCurrentIndex(idx); - d->m_searchResultTreeView->emitJumpToSearchResult(idx); - } + d->m_searchResultWidget->goToPrevious(); } /*! @@ -823,6 +400,21 @@ bool SearchResultWindow::canNavigate() } /*! + \fn SearchResult::SearchResult(SearchResultWidget *widget) + \internal +*/ +SearchResult::SearchResult(SearchResultWidget *widget) + : m_widget(widget) +{ + connect(widget, SIGNAL(activated(Find::SearchResultItem)), + this, SIGNAL(activated(Find::SearchResultItem))); + connect(widget, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>)), + this, SIGNAL(replaceButtonClicked(QString,QList<Find::SearchResultItem>))); + connect(widget, SIGNAL(visibilityChanged(bool)), + this, SIGNAL(visibilityChanged(bool))); +} + +/*! \fn void SearchResult::setUserData(const QVariant &data) \brief Attach some random \a data to this search, that you can use later. @@ -850,8 +442,7 @@ QVariant SearchResult::userData() const */ QString SearchResult::textToReplace() const { - // TODO: should point to associated SearchResultWidget - return SearchResultWindow::instance()->textToReplace(); + return m_widget->textToReplace(); } /*! @@ -869,9 +460,8 @@ QString SearchResult::textToReplace() const void SearchResult::addResult(const QString &fileName, int lineNumber, const QString &lineText, int searchTermStart, int searchTermLength, const QVariant &userData) { - // TODO: should point to associated SearchResultWidget - SearchResultWindow::instance()->addResult(fileName, lineNumber, lineText, - searchTermStart, searchTermLength, userData); + m_widget->addResult(fileName, lineNumber, lineText, + searchTermStart, searchTermLength, userData); } /*! @@ -883,8 +473,7 @@ void SearchResult::addResult(const QString &fileName, int lineNumber, const QStr */ void SearchResult::addResults(const QList<SearchResultItem> &items, AddMode mode) { - // TODO: should point to associated SearchResultWidget - SearchResultWindow::instance()->addResults(items, mode); + m_widget->addResults(items, mode); } /*! @@ -894,8 +483,7 @@ void SearchResult::addResults(const QList<SearchResultItem> &items, AddMode mode */ void SearchResult::finishSearch() { - // TODO: should point to associated SearchResultWidget - SearchResultWindow::instance()->finishSearch(); + m_widget->finishSearch(); } /*! @@ -905,11 +493,7 @@ void SearchResult::finishSearch() */ void SearchResult::setTextToReplace(const QString &textToReplace) { - // TODO: should point to associated SearchResultWidget - SearchResultWindow::instance()->setTextToReplace(textToReplace); + m_widget->setTextToReplace(textToReplace); } } // namespace Find - - -#include "searchresultwindow.moc" diff --git a/src/plugins/find/searchresultwindow.h b/src/plugins/find/searchresultwindow.h index 5203f3cba7..6a17ec5987 100644 --- a/src/plugins/find/searchresultwindow.h +++ b/src/plugins/find/searchresultwindow.h @@ -49,6 +49,7 @@ namespace Find { namespace Internal { class SearchResultTreeView; struct SearchResultWindowPrivate; + class SearchResultWidget; } class SearchResultWindow; @@ -110,9 +111,12 @@ signals: void replaceButtonClicked(const QString &replaceText, const QList<Find::SearchResultItem> &checkedItems); void visibilityChanged(bool visible); - friend class SearchResultWindow; +private: + SearchResult(Internal::SearchResultWidget *widget); + friend class SearchResultWindow; // for the constructor private: + Internal::SearchResultWidget *m_widget; QVariant m_userData; }; @@ -137,7 +141,6 @@ public: QString displayName() const { return tr("Search Results"); } int priorityInStatusBar() const; void visibilityChanged(bool visible); - bool isEmpty() const; bool hasFocus(); bool canFocus(); void setFocus(); @@ -159,31 +162,13 @@ public slots: private slots: void handleExpandCollapseToolButton(bool checked); - void handleJumpToSearchResult(const SearchResultItem &item); - void handleReplaceButton(); - void showNoMatchesFound(); - void hideNoUndoWarning(); private: - // TODO: move to the new SearchResultWidget - void addResult(const QString &fileName, int lineNumber, const QString &lineText, - int searchTermStart, int searchTermLength, const QVariant &userData); - void addResults(const QList<SearchResultItem> &items, SearchResult::AddMode mode); // TODO: move to SearchResultWidget) - void finishSearch(); - void setTextToReplace(const QString &textToReplace); - QString textToReplace() const; - - - void setShowReplaceUI(bool show); void readSettings(); void writeSettings(); - QList<SearchResultItem> checkedItems() const; - bool showWarningMessage() const; - void setShowWarningMessage(bool showWarningMessage); Internal::SearchResultWindowPrivate *d; static SearchResultWindow *m_instance; - friend class SearchResult; }; } // namespace Find |