forked from qt-creator/qt-creator
Core: add action to select all find results in an Editor
Change-Id: I71f480abde17cfdb6b64d7d12a33c9887792fc61 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -81,6 +81,13 @@ bool CurrentDocumentFind::supportsReplace() const
|
|||||||
return m_currentFind->supportsReplace();
|
return m_currentFind->supportsReplace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CurrentDocumentFind::supportsSelectAll() const
|
||||||
|
{
|
||||||
|
if (!m_currentFind)
|
||||||
|
return false;
|
||||||
|
return m_currentFind->supportsSelectAll();
|
||||||
|
}
|
||||||
|
|
||||||
FindFlags CurrentDocumentFind::supportedFindFlags() const
|
FindFlags CurrentDocumentFind::supportedFindFlags() const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_currentFind, return {});
|
QTC_ASSERT(m_currentFind, return {});
|
||||||
@@ -119,6 +126,12 @@ IFindSupport::Result CurrentDocumentFind::findStep(const QString &txt, FindFlags
|
|||||||
return m_currentFind->findStep(txt, findFlags);
|
return m_currentFind->findStep(txt, findFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CurrentDocumentFind::selectAll(const QString &txt, FindFlags findFlags)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_currentFind && m_currentFind->supportsSelectAll(), return);
|
||||||
|
m_currentFind->selectAll(txt, findFlags);
|
||||||
|
}
|
||||||
|
|
||||||
void CurrentDocumentFind::replace(const QString &before, const QString &after, FindFlags findFlags)
|
void CurrentDocumentFind::replace(const QString &before, const QString &after, FindFlags findFlags)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_currentFind, return);
|
QTC_ASSERT(m_currentFind, return);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public:
|
|||||||
void resetIncrementalSearch();
|
void resetIncrementalSearch();
|
||||||
void clearHighlights();
|
void clearHighlights();
|
||||||
bool supportsReplace() const;
|
bool supportsReplace() const;
|
||||||
|
bool supportsSelectAll() const;
|
||||||
FindFlags supportedFindFlags() const;
|
FindFlags supportedFindFlags() const;
|
||||||
QString currentFindString() const;
|
QString currentFindString() const;
|
||||||
QString completedFindString() const;
|
QString completedFindString() const;
|
||||||
@@ -51,6 +52,7 @@ public:
|
|||||||
void highlightAll(const QString &txt, FindFlags findFlags);
|
void highlightAll(const QString &txt, FindFlags findFlags);
|
||||||
IFindSupport::Result findIncremental(const QString &txt, FindFlags findFlags);
|
IFindSupport::Result findIncremental(const QString &txt, FindFlags findFlags);
|
||||||
IFindSupport::Result findStep(const QString &txt, FindFlags findFlags);
|
IFindSupport::Result findStep(const QString &txt, FindFlags findFlags);
|
||||||
|
void selectAll(const QString &txt, FindFlags findFlags);
|
||||||
void replace(const QString &before, const QString &after, FindFlags findFlags);
|
void replace(const QString &before, const QString &after, FindFlags findFlags);
|
||||||
bool replaceStep(const QString &before, const QString &after, FindFlags findFlags);
|
bool replaceStep(const QString &before, const QString &after, FindFlags findFlags);
|
||||||
int replaceAll(const QString &before, const QString &after, FindFlags findFlags);
|
int replaceAll(const QString &before, const QString &after, FindFlags findFlags);
|
||||||
|
|||||||
@@ -222,6 +222,17 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind)
|
|||||||
connect(m_findPreviousSelectedAction, &QAction::triggered,
|
connect(m_findPreviousSelectedAction, &QAction::triggered,
|
||||||
this, &FindToolBar::findPreviousSelected);
|
this, &FindToolBar::findPreviousSelected);
|
||||||
|
|
||||||
|
m_selectAllAction = new QAction(tr("Select All"), this);
|
||||||
|
cmd = ActionManager::registerAction(m_selectAllAction, Constants::FIND_SELECT_ALL);
|
||||||
|
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Return")));
|
||||||
|
mfind->addAction(cmd, Constants::G_FIND_ACTIONS);
|
||||||
|
connect(m_selectAllAction, &QAction::triggered, this, &FindToolBar::selectAll);
|
||||||
|
m_localSelectAllAction = new QAction(m_selectAllAction->text(), this);
|
||||||
|
cmd = ActionManager::registerAction(m_localSelectAllAction, Constants::FIND_SELECT_ALL, findcontext);
|
||||||
|
cmd->setDefaultKeySequence(QKeySequence(tr("Alt+Return")));
|
||||||
|
connect(m_localSelectAllAction, &QAction::triggered, this, &FindToolBar::selectAll);
|
||||||
|
m_ui.selectAllButton->setDefaultAction(m_localSelectAllAction);
|
||||||
|
|
||||||
m_replaceAction = new QAction(tr("Replace"), this);
|
m_replaceAction = new QAction(tr("Replace"), this);
|
||||||
cmd = ActionManager::registerAction(m_replaceAction, Constants::REPLACE);
|
cmd = ActionManager::registerAction(m_replaceAction, Constants::REPLACE);
|
||||||
cmd->setDefaultKeySequence(QKeySequence());
|
cmd->setDefaultKeySequence(QKeySequence());
|
||||||
@@ -400,6 +411,7 @@ void FindToolBar::updateActions()
|
|||||||
if (m_enterFindStringAction)
|
if (m_enterFindStringAction)
|
||||||
m_enterFindStringAction->setEnabled(enabled);
|
m_enterFindStringAction->setEnabled(enabled);
|
||||||
updateFindReplaceEnabled();
|
updateFindReplaceEnabled();
|
||||||
|
m_selectAllAction->setEnabled(m_currentDocumentFind->supportsSelectAll());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FindToolBar::updateToolBar()
|
void FindToolBar::updateToolBar()
|
||||||
@@ -869,6 +881,15 @@ void FindToolBar::findPreviousSelected()
|
|||||||
invokeFindPrevious();
|
invokeFindPrevious();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FindToolBar::selectAll()
|
||||||
|
{
|
||||||
|
if (m_currentDocumentFind->isEnabled()) {
|
||||||
|
const FindFlags ef = effectiveFindFlags();
|
||||||
|
Find::updateFindCompletion(getFindText(), ef);
|
||||||
|
m_currentDocumentFind->selectAll(getFindText(), ef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool FindToolBar::focusNextPrevChild(bool next)
|
bool FindToolBar::focusNextPrevChild(bool next)
|
||||||
{
|
{
|
||||||
QAbstractButton *optionsButton = m_ui.findEdit->button(Utils::FancyLineEdit::Left);
|
QAbstractButton *optionsButton = m_ui.findEdit->button(Utils::FancyLineEdit::Left);
|
||||||
@@ -1000,6 +1021,7 @@ void FindToolBar::updateFindReplaceEnabled()
|
|||||||
m_localFindPreviousAction->setEnabled(enabled);
|
m_localFindPreviousAction->setEnabled(enabled);
|
||||||
m_findEnabled = enabled;
|
m_findEnabled = enabled;
|
||||||
}
|
}
|
||||||
|
m_localSelectAllAction->setEnabled(enabled && m_currentDocumentFind->supportsSelectAll());
|
||||||
m_findNextAction->setEnabled(enabled && m_findInDocumentAction->isEnabled());
|
m_findNextAction->setEnabled(enabled && m_findInDocumentAction->isEnabled());
|
||||||
m_findPreviousAction->setEnabled(enabled && m_findInDocumentAction->isEnabled());
|
m_findPreviousAction->setEnabled(enabled && m_findInDocumentAction->isEnabled());
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ private:
|
|||||||
void openFind(bool focus = true);
|
void openFind(bool focus = true);
|
||||||
void findNextSelected();
|
void findNextSelected();
|
||||||
void findPreviousSelected();
|
void findPreviousSelected();
|
||||||
|
void selectAll();
|
||||||
void updateActions();
|
void updateActions();
|
||||||
void updateToolBar();
|
void updateToolBar();
|
||||||
void findFlagsChanged();
|
void findFlagsChanged();
|
||||||
@@ -149,6 +150,7 @@ private:
|
|||||||
QAction *m_findInDocumentAction = nullptr;
|
QAction *m_findInDocumentAction = nullptr;
|
||||||
QAction *m_findNextSelectedAction = nullptr;
|
QAction *m_findNextSelectedAction = nullptr;
|
||||||
QAction *m_findPreviousSelectedAction = nullptr;
|
QAction *m_findPreviousSelectedAction = nullptr;
|
||||||
|
QAction *m_selectAllAction = nullptr;
|
||||||
QAction *m_enterFindStringAction = nullptr;
|
QAction *m_enterFindStringAction = nullptr;
|
||||||
QAction *m_findNextAction = nullptr;
|
QAction *m_findNextAction = nullptr;
|
||||||
QAction *m_findPreviousAction = nullptr;
|
QAction *m_findPreviousAction = nullptr;
|
||||||
@@ -163,6 +165,7 @@ private:
|
|||||||
|
|
||||||
QAction *m_localFindNextAction = nullptr;
|
QAction *m_localFindNextAction = nullptr;
|
||||||
QAction *m_localFindPreviousAction = nullptr;
|
QAction *m_localFindPreviousAction = nullptr;
|
||||||
|
QAction *m_localSelectAllAction = nullptr;
|
||||||
QAction *m_localReplaceAction = nullptr;
|
QAction *m_localReplaceAction = nullptr;
|
||||||
QAction *m_localReplaceNextAction = nullptr;
|
QAction *m_localReplaceNextAction = nullptr;
|
||||||
QAction *m_localReplacePreviousAction = nullptr;
|
QAction *m_localReplacePreviousAction = nullptr;
|
||||||
|
|||||||
@@ -73,6 +73,13 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QToolButton" name="findNextButton"/>
|
<widget class="QToolButton" name="findNextButton"/>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="selectAllButton">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ using namespace Core;
|
|||||||
Returns whether the find filter supports search and replace.
|
Returns whether the find filter supports search and replace.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\fn bool Core::IFindSupport::supportsSelectAll() const
|
||||||
|
Returns whether the find filter supports selecting all results.
|
||||||
|
*/
|
||||||
|
bool IFindSupport::supportsSelectAll() const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn Core::FindFlags Core::IFindSupport::supportedFindFlags() const
|
\fn Core::FindFlags Core::IFindSupport::supportedFindFlags() const
|
||||||
Returns the find flags, such as whole words or regular expressions,
|
Returns the find flags, such as whole words or regular expressions,
|
||||||
@@ -165,6 +174,15 @@ int IFindSupport::replaceAll(const QString &before, const QString &after, FindFl
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Finds and selects all instances of \a txt with specified \a findFlags.
|
||||||
|
*/
|
||||||
|
void IFindSupport::selectAll(const QString &txt, FindFlags findFlags)
|
||||||
|
{
|
||||||
|
Q_UNUSED(txt)
|
||||||
|
Q_UNUSED(findFlags)
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Shows \a parent overlayed with the wrap indicator.
|
Shows \a parent overlayed with the wrap indicator.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public:
|
|||||||
~IFindSupport() override = default;
|
~IFindSupport() override = default;
|
||||||
|
|
||||||
virtual bool supportsReplace() const = 0;
|
virtual bool supportsReplace() const = 0;
|
||||||
|
virtual bool supportsSelectAll() const;
|
||||||
virtual FindFlags supportedFindFlags() const = 0;
|
virtual FindFlags supportedFindFlags() const = 0;
|
||||||
virtual void resetIncrementalSearch() = 0;
|
virtual void resetIncrementalSearch() = 0;
|
||||||
virtual void clearHighlights() = 0;
|
virtual void clearHighlights() = 0;
|
||||||
@@ -58,6 +59,7 @@ public:
|
|||||||
FindFlags findFlags);
|
FindFlags findFlags);
|
||||||
virtual int replaceAll(const QString &before, const QString &after,
|
virtual int replaceAll(const QString &before, const QString &after,
|
||||||
FindFlags findFlags);
|
FindFlags findFlags);
|
||||||
|
virtual void selectAll(const QString &txt, FindFlags findFlags);
|
||||||
|
|
||||||
virtual void defineFindScope(){}
|
virtual void defineFindScope(){}
|
||||||
virtual void clearFindScope(){}
|
virtual void clearFindScope(){}
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ const char ADVANCED_FIND[] = "Find.Dialog";
|
|||||||
const char FIND_IN_DOCUMENT[] = "Find.FindInCurrentDocument";
|
const char FIND_IN_DOCUMENT[] = "Find.FindInCurrentDocument";
|
||||||
const char FIND_NEXT_SELECTED[]= "Find.FindNextSelected";
|
const char FIND_NEXT_SELECTED[]= "Find.FindNextSelected";
|
||||||
const char FIND_PREV_SELECTED[]= "Find.FindPreviousSelected";
|
const char FIND_PREV_SELECTED[]= "Find.FindPreviousSelected";
|
||||||
|
const char FIND_SELECT_ALL[] = "Find.SelectAll";
|
||||||
const char FIND_NEXT[] = "Find.FindNext";
|
const char FIND_NEXT[] = "Find.FindNext";
|
||||||
const char FIND_PREVIOUS[] = "Find.FindPrevious";
|
const char FIND_PREVIOUS[] = "Find.FindPrevious";
|
||||||
const char REPLACE[] = "Find.Replace";
|
const char REPLACE[] = "Find.Replace";
|
||||||
|
|||||||
@@ -825,6 +825,76 @@ public:
|
|||||||
QStack<UndoMultiCursor> m_undoCursorStack;
|
QStack<UndoMultiCursor> m_undoCursorStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TextEditorWidgetFind : public BaseTextFind
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextEditorWidgetFind(TextEditorWidget *editor)
|
||||||
|
: BaseTextFind(editor)
|
||||||
|
, m_editor(editor)
|
||||||
|
{
|
||||||
|
setMultiTextCursorProvider([editor]() { return editor->multiTextCursor(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool supportsSelectAll() const override { return true; }
|
||||||
|
void selectAll(const QString &txt, FindFlags findFlags) override;
|
||||||
|
|
||||||
|
static void cancelCurrentSelectAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
TextEditorWidget * const m_editor;
|
||||||
|
static QFutureWatcher<FileSearchResultList> *m_selectWatcher;
|
||||||
|
};
|
||||||
|
|
||||||
|
QFutureWatcher<FileSearchResultList> *TextEditorWidgetFind::m_selectWatcher = nullptr;
|
||||||
|
|
||||||
|
void TextEditorWidgetFind::selectAll(const QString &txt, FindFlags findFlags)
|
||||||
|
{
|
||||||
|
if (txt.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
cancelCurrentSelectAll();
|
||||||
|
|
||||||
|
m_selectWatcher = new QFutureWatcher<FileSearchResultList>();
|
||||||
|
connect(m_selectWatcher, &QFutureWatcher<Utils::FileSearchResultList>::finished,
|
||||||
|
this, [this]() {
|
||||||
|
const FileSearchResultList &results = m_selectWatcher->result();
|
||||||
|
const QTextCursor c(m_editor->document());
|
||||||
|
auto cursorForResult = [c](const FileSearchResult &r) {
|
||||||
|
return Utils::Text::selectAt(c, r.lineNumber, r.matchStart + 1, r.matchLength);
|
||||||
|
};
|
||||||
|
QList<QTextCursor> cursors = Utils::transform(results, cursorForResult);
|
||||||
|
cursors = Utils::filtered(cursors, [this](const QTextCursor &c) {
|
||||||
|
return m_editor->inFindScope(c);
|
||||||
|
});
|
||||||
|
m_editor->setMultiTextCursor(MultiTextCursor(cursors));
|
||||||
|
m_editor->setFocus();
|
||||||
|
});
|
||||||
|
|
||||||
|
const QString &fileName = m_editor->textDocument()->filePath().toString();
|
||||||
|
QMap<QString, QString> fileToContentsMap;
|
||||||
|
fileToContentsMap[fileName] = m_editor->textDocument()->plainText();
|
||||||
|
|
||||||
|
FileListIterator *it = new FileListIterator({fileName},
|
||||||
|
{const_cast<QTextCodec *>(
|
||||||
|
m_editor->textDocument()->codec())});
|
||||||
|
const QTextDocument::FindFlags findFlags2 = textDocumentFlagsForFindFlags(findFlags);
|
||||||
|
|
||||||
|
if (findFlags & FindRegularExpression)
|
||||||
|
m_selectWatcher->setFuture(findInFilesRegExp(txt, it, findFlags2, fileToContentsMap));
|
||||||
|
else
|
||||||
|
m_selectWatcher->setFuture(findInFiles(txt, it, findFlags2, fileToContentsMap));
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextEditorWidgetFind::cancelCurrentSelectAll()
|
||||||
|
{
|
||||||
|
if (m_selectWatcher) {
|
||||||
|
m_selectWatcher->disconnect();
|
||||||
|
m_selectWatcher->cancel();
|
||||||
|
m_selectWatcher->deleteLater();
|
||||||
|
m_selectWatcher = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent)
|
TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent)
|
||||||
: q(parent),
|
: q(parent),
|
||||||
m_marksVisible(false),
|
m_marksVisible(false),
|
||||||
@@ -841,8 +911,7 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent)
|
|||||||
m_autoCompleter(new AutoCompleter)
|
m_autoCompleter(new AutoCompleter)
|
||||||
{
|
{
|
||||||
auto aggregate = new Aggregation::Aggregate;
|
auto aggregate = new Aggregation::Aggregate;
|
||||||
m_find = new BaseTextFind(q);
|
m_find = new TextEditorWidgetFind(q);
|
||||||
m_find->setMultiTextCursorProvider([this]() { return m_cursors; });
|
|
||||||
connect(m_find, &BaseTextFind::highlightAllRequested,
|
connect(m_find, &BaseTextFind::highlightAllRequested,
|
||||||
this, &TextEditorWidgetPrivate::highlightSearchResultsSlot);
|
this, &TextEditorWidgetPrivate::highlightSearchResultsSlot);
|
||||||
connect(m_find, &BaseTextFind::findScopeChanged,
|
connect(m_find, &BaseTextFind::findScopeChanged,
|
||||||
@@ -2307,6 +2376,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e)
|
|||||||
} else {
|
} else {
|
||||||
d->m_maybeFakeTooltipEvent = false;
|
d->m_maybeFakeTooltipEvent = false;
|
||||||
if (e->key() == Qt::Key_Escape ) {
|
if (e->key() == Qt::Key_Escape ) {
|
||||||
|
TextEditorWidgetFind::cancelCurrentSelectAll();
|
||||||
if (d->m_snippetOverlay->isVisible()) {
|
if (d->m_snippetOverlay->isVisible()) {
|
||||||
e->accept();
|
e->accept();
|
||||||
d->m_snippetOverlay->accept();
|
d->m_snippetOverlay->accept();
|
||||||
@@ -7823,7 +7893,7 @@ void TextEditorWidget::setRefactorMarkers(const RefactorMarkers &markers)
|
|||||||
emit requestBlockUpdate(marker.cursor.block());
|
emit requestBlockUpdate(marker.cursor.block());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextEditorWidget::inFindScope(const QTextCursor &cursor)
|
bool TextEditorWidget::inFindScope(const QTextCursor &cursor) const
|
||||||
{
|
{
|
||||||
return d->m_find->inScope(cursor);
|
return d->m_find->inScope(cursor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -564,6 +564,8 @@ public:
|
|||||||
void contextHelpItem(const Core::IContext::HelpCallback &callback);
|
void contextHelpItem(const Core::IContext::HelpCallback &callback);
|
||||||
void setContextHelpItem(const Core::HelpItem &item);
|
void setContextHelpItem(const Core::HelpItem &item);
|
||||||
|
|
||||||
|
Q_INVOKABLE bool inFindScope(const QTextCursor &cursor) const;
|
||||||
|
|
||||||
static TextEditorWidget *currentTextEditorWidget();
|
static TextEditorWidget *currentTextEditorWidget();
|
||||||
static TextEditorWidget *fromEditor(const Core::IEditor *editor);
|
static TextEditorWidget *fromEditor(const Core::IEditor *editor);
|
||||||
|
|
||||||
@@ -610,8 +612,6 @@ protected:
|
|||||||
virtual void slotCursorPositionChanged(); // Used in VcsBase
|
virtual void slotCursorPositionChanged(); // Used in VcsBase
|
||||||
virtual void slotCodeStyleSettingsChanged(const QVariant &); // Used in CppEditor
|
virtual void slotCodeStyleSettingsChanged(const QVariant &); // Used in CppEditor
|
||||||
|
|
||||||
Q_INVOKABLE bool inFindScope(const QTextCursor &cursor);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Internal::TextEditorWidgetPrivate *d;
|
Internal::TextEditorWidgetPrivate *d;
|
||||||
friend class BaseTextEditor;
|
friend class BaseTextEditor;
|
||||||
|
|||||||
Reference in New Issue
Block a user