Add display search results using relative paths to project root

Task-number: QTCREATORBUG-29462
Change-Id: Ic5d597846cfcc6589cbf1b81151e05c95ee8fab0
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Xavier BESSON
2023-12-14 10:50:49 +01:00
committed by Xavier BESSON (Personal)
parent 905eaf8b1e
commit 2796e69ab5
10 changed files with 112 additions and 1 deletions

View File

@@ -5,6 +5,7 @@
#include "searchresulttreeitems.h" #include "searchresulttreeitems.h"
#include "searchresulttreeitemroles.h" #include "searchresulttreeitemroles.h"
#include <coreplugin/icore.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/searchresultitem.h> #include <utils/searchresultitem.h>
@@ -27,6 +28,7 @@ public:
~SearchResultTreeModel() override; ~SearchResultTreeModel() override;
void setShowReplaceUI(bool show); void setShowReplaceUI(bool show);
void setRelativePaths(bool relative);
void setTextEditorFont(const QFont &font, const SearchResultColors &colors); void setTextEditorFont(const QFont &font, const SearchResultColors &colors);
Qt::ItemFlags flags(const QModelIndex &index) const override; Qt::ItemFlags flags(const QModelIndex &index) const override;
@@ -69,6 +71,7 @@ private:
QStringList m_currentPath; // the path that belongs to the current parent QStringList m_currentPath; // the path that belongs to the current parent
QFont m_textEditorFont; QFont m_textEditorFont;
bool m_showReplaceUI; bool m_showReplaceUI;
bool m_relativePaths;
bool m_editorFontIsUsed; bool m_editorFontIsUsed;
}; };
@@ -76,6 +79,7 @@ SearchResultTreeModel::SearchResultTreeModel(QObject *parent)
: QAbstractItemModel(parent) : QAbstractItemModel(parent)
, m_currentParent(nullptr) , m_currentParent(nullptr)
, m_showReplaceUI(false) , m_showReplaceUI(false)
, m_relativePaths(false)
, m_editorFontIsUsed(false) , m_editorFontIsUsed(false)
{ {
m_rootItem = new SearchResultTreeItem; m_rootItem = new SearchResultTreeItem;
@@ -106,6 +110,12 @@ void SearchResultTreeModel::setShowReplaceUI(bool show)
} }
} }
void SearchResultTreeModel::setRelativePaths(bool relative)
{
m_relativePaths = relative;
emit dataChanged(index(0, 0), index(rowCount() - 1, 0));
}
void SearchResultTreeModel::setTextEditorFont(const QFont &font, const SearchResultColors &colors) void SearchResultTreeModel::setTextEditorFont(const QFont &font, const SearchResultColors &colors)
{ {
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
@@ -295,9 +305,15 @@ QVariant SearchResultTreeModel::data(const SearchResultTreeItem *row, int role)
result = m_colors.value(row->item.style()).textBackground; result = m_colors.value(row->item.style()).textBackground;
break; break;
case ItemDataRoles::ResultLineRole: case ItemDataRoles::ResultLineRole:
case Qt::DisplayRole:
result = row->item.lineText(); result = row->item.lineText();
break; break;
case Qt::DisplayRole:
if (m_relativePaths && row->isGenerated()) {
result = ICore::pathRelativeToActiveProject(FilePath::fromUserInput(row->item.lineText())).toUserOutput();
} else {
result = row->item.lineText();
}
break;
case ItemDataRoles::ResultItemRole: case ItemDataRoles::ResultItemRole:
result = QVariant::fromValue(row->item); result = QVariant::fromValue(row->item);
break; break;
@@ -580,6 +596,11 @@ void SearchResultFilterModel::setShowReplaceUI(bool show)
sourceModel()->setShowReplaceUI(show); sourceModel()->setShowReplaceUI(show);
} }
void SearchResultFilterModel::setRelativePaths(bool relative)
{
sourceModel()->setRelativePaths(relative);
}
void SearchResultFilterModel::setTextEditorFont(const QFont &font, const SearchResultColors &colors) void SearchResultFilterModel::setTextEditorFont(const QFont &font, const SearchResultColors &colors)
{ {
sourceModel()->setTextEditorFont(font, colors); sourceModel()->setTextEditorFont(font, colors);

View File

@@ -24,6 +24,7 @@ public:
void setFilter(SearchResultFilter *filter); void setFilter(SearchResultFilter *filter);
void setShowReplaceUI(bool show); void setShowReplaceUI(bool show);
void setRelativePaths(bool relative);
void setTextEditorFont(const QFont &font, const Utils::SearchResultColors &colors); void setTextEditorFont(const QFont &font, const Utils::SearchResultColors &colors);
QList<QModelIndex> addResults(const Utils::SearchResultItems &items, QList<QModelIndex> addResults(const Utils::SearchResultItems &items,
SearchResult::AddMode mode); SearchResult::AddMode mode);

View File

@@ -58,6 +58,11 @@ void SearchResultTreeView::setAutoExpandResults(bool expand)
m_autoExpandResults = expand; m_autoExpandResults = expand;
} }
void SearchResultTreeView::setRelativePaths(bool relative)
{
m_model->setRelativePaths(relative);
}
void SearchResultTreeView::setTextEditorFont(const QFont &font, const SearchResultColors &colors) void SearchResultTreeView::setTextEditorFont(const QFont &font, const SearchResultColors &colors)
{ {
m_model->setTextEditorFont(font, colors); m_model->setTextEditorFont(font, colors);

View File

@@ -22,6 +22,7 @@ public:
explicit SearchResultTreeView(QWidget *parent = nullptr); explicit SearchResultTreeView(QWidget *parent = nullptr);
void setAutoExpandResults(bool expand); void setAutoExpandResults(bool expand);
void setRelativePaths(bool relative);
void setTextEditorFont(const QFont &font, const Utils::SearchResultColors &colors); void setTextEditorFont(const QFont &font, const Utils::SearchResultColors &colors);
void setTabWidth(int tabWidth); void setTabWidth(int tabWidth);

View File

@@ -348,6 +348,11 @@ void SearchResultWidget::setAutoExpandResults(bool expand)
m_searchResultTreeView->setAutoExpandResults(expand); m_searchResultTreeView->setAutoExpandResults(expand);
} }
void SearchResultWidget::setRelativePaths(bool relative)
{
m_searchResultTreeView->setRelativePaths(relative);
}
void SearchResultWidget::expandAll() void SearchResultWidget::expandAll()
{ {
m_searchResultTreeView->expandAll(); m_searchResultTreeView->expandAll();

View File

@@ -58,6 +58,7 @@ public:
void setTabWidth(int tabWidth); void setTabWidth(int tabWidth);
void setAutoExpandResults(bool expand); void setAutoExpandResults(bool expand);
void setRelativePaths(bool relative);
void expandAll(); void expandAll();
void collapseAll(); void collapseAll();

View File

@@ -27,6 +27,7 @@
static const char SETTINGSKEYSECTIONNAME[] = "SearchResults"; static const char SETTINGSKEYSECTIONNAME[] = "SearchResults";
static const char SETTINGSKEYEXPANDRESULTS[] = "ExpandResults"; static const char SETTINGSKEYEXPANDRESULTS[] = "ExpandResults";
static const char SETTINGSKEYRELATIVEPATHSRESULTS[] = "RelativePathsResults";
// Note that this is a soft limit: If all searches are still running, none of them will be // Note that this is a soft limit: If all searches are still running, none of them will be
// removed when a new one is started. // removed when a new one is started.
@@ -73,6 +74,7 @@ namespace Internal {
void moveWidgetToTop(SearchResultWidget *widget); void moveWidgetToTop(SearchResultWidget *widget);
void popupRequested(SearchResultWidget *widget, bool focus); void popupRequested(SearchResultWidget *widget, bool focus);
void handleExpandCollapseToolButton(bool checked); void handleExpandCollapseToolButton(bool checked);
void handleRelativePathsToolButton(bool checked);
void updateFilterButton(); void updateFilterButton();
int indexOfSearchToEvict() const; int indexOfSearchToEvict() const;
QList<QWidget *> toolBarWidgets(); QList<QWidget *> toolBarWidgets();
@@ -82,8 +84,11 @@ namespace Internal {
QToolButton *m_expandCollapseButton = nullptr; QToolButton *m_expandCollapseButton = nullptr;
QToolButton *m_filterButton; QToolButton *m_filterButton;
QToolButton *m_newSearchButton; QToolButton *m_newSearchButton;
QToolButton *m_relativePathsButton = nullptr;
QAction *m_expandCollapseAction = nullptr; QAction *m_expandCollapseAction = nullptr;
QAction *m_relativePathsAction = nullptr;
static const bool m_initiallyExpand; static const bool m_initiallyExpand;
static const bool m_initiallyRelativePaths;
QWidget *m_spacer; QWidget *m_spacer;
QLabel *m_historyLabel = nullptr; QLabel *m_historyLabel = nullptr;
QWidget *m_spacer2; QWidget *m_spacer2;
@@ -97,6 +102,7 @@ namespace Internal {
}; };
const bool SearchResultWindowPrivate::m_initiallyExpand = false; const bool SearchResultWindowPrivate::m_initiallyExpand = false;
const bool SearchResultWindowPrivate::m_initiallyRelativePaths = false;
SearchResultWindowPrivate::SearchResultWindowPrivate(SearchResultWindow *window, QWidget *nsp) : SearchResultWindowPrivate::SearchResultWindowPrivate(SearchResultWindow *window, QWidget *nsp) :
q(window), q(window),
@@ -126,6 +132,17 @@ namespace Internal {
m_expandCollapseButton->setDefaultAction(m_expandCollapseAction); m_expandCollapseButton->setDefaultAction(m_expandCollapseAction);
Utils::StyleHelper::setPanelWidget(m_expandCollapseButton); Utils::StyleHelper::setPanelWidget(m_expandCollapseButton);
m_relativePathsButton = new QToolButton(m_widget);
ActionBuilder(window, "Find.RelativePaths")
.setText(Tr::tr("Show Paths in Relation to Active Project"))
.setCheckable(true)
.setIconText("../")
.setEnabled(false)
.bindContextAction(&m_relativePathsAction)
.setCommandAttribute(Command::CA_UpdateText);
m_relativePathsButton->setDefaultAction(m_relativePathsAction);
m_filterButton = new QToolButton(m_widget); m_filterButton = new QToolButton(m_widget);
m_filterButton->setText(Tr::tr("Filter Results")); m_filterButton->setText(Tr::tr("Filter Results"));
m_filterButton->setIcon(Utils::Icons::FILTER.icon()); m_filterButton->setIcon(Utils::Icons::FILTER.icon());
@@ -141,6 +158,9 @@ namespace Internal {
connect(m_expandCollapseAction, &QAction::toggled, connect(m_expandCollapseAction, &QAction::toggled,
this, &SearchResultWindowPrivate::handleExpandCollapseToolButton); this, &SearchResultWindowPrivate::handleExpandCollapseToolButton);
connect(m_relativePathsAction, &QAction::toggled,
this, &SearchResultWindowPrivate::handleRelativePathsToolButton);
connect(m_filterButton, &QToolButton::clicked, this, [this] { connect(m_filterButton, &QToolButton::clicked, this, [this] {
if (!isSearchVisible()) if (!isSearchVisible())
return; return;
@@ -160,12 +180,14 @@ namespace Internal {
if (focus) if (focus)
m_widget->currentWidget()->setFocus(); m_widget->currentWidget()->setFocus();
m_expandCollapseAction->setEnabled(false); m_expandCollapseAction->setEnabled(false);
m_relativePathsAction->setEnabled(false);
m_newSearchButton->setEnabled(false); m_newSearchButton->setEnabled(false);
} else { } else {
if (focus) if (focus)
m_searchResultWidgets.at(visibleSearchIndex())->setFocusInternally(); m_searchResultWidgets.at(visibleSearchIndex())->setFocusInternally();
m_searchResultWidgets.at(visibleSearchIndex())->notifyVisibilityChanged(true); m_searchResultWidgets.at(visibleSearchIndex())->notifyVisibilityChanged(true);
m_expandCollapseAction->setEnabled(true); m_expandCollapseAction->setEnabled(true);
m_relativePathsAction->setEnabled(true);
m_newSearchButton->setEnabled(true); m_newSearchButton->setEnabled(true);
} }
q->navigateStateChanged(); q->navigateStateChanged();
@@ -485,6 +507,7 @@ SearchResult *SearchResultWindow::startNewSearch(const QString &label,
bool supportsReplace = searchOrSearchAndReplace != SearchOnly; bool supportsReplace = searchOrSearchAndReplace != SearchOnly;
widget->setSupportsReplace(supportsReplace, supportsReplace ? cfgGroup : QString()); widget->setSupportsReplace(supportsReplace, supportsReplace ? cfgGroup : QString());
widget->setAutoExpandResults(d->m_expandCollapseAction->isChecked()); widget->setAutoExpandResults(d->m_expandCollapseAction->isChecked());
widget->setRelativePaths(d->m_relativePathsAction->isChecked());
widget->setInfo(label, toolTip, searchTerm); widget->setInfo(label, toolTip, searchTerm);
auto result = new SearchResult(widget); auto result = new SearchResult(widget);
d->m_searchResults.prepend(result); d->m_searchResults.prepend(result);
@@ -513,6 +536,7 @@ void SearchResultWindow::clearContents()
d->m_currentIndex = 0; d->m_currentIndex = 0;
d->m_widget->currentWidget()->setFocus(); d->m_widget->currentWidget()->setFocus();
d->m_expandCollapseAction->setEnabled(false); d->m_expandCollapseAction->setEnabled(false);
d->m_relativePathsAction->setEnabled(false);
navigateStateChanged(); navigateStateChanged();
d->m_newSearchButton->setEnabled(false); d->m_newSearchButton->setEnabled(false);
@@ -594,6 +618,18 @@ void SearchResultWindowPrivate::handleExpandCollapseToolButton(bool checked)
} }
} }
void SearchResultWindowPrivate::handleRelativePathsToolButton(bool checked)
{
if (!isSearchVisible())
return;
m_searchResultWidgets.at(visibleSearchIndex())->setRelativePaths(checked);
if (checked) {
m_relativePathsAction->setText(Tr::tr("Show Full Paths"));
} else {
m_relativePathsAction->setText(Tr::tr("Show Paths in Relation to Active Project"));
}
}
void SearchResultWindowPrivate::updateFilterButton() void SearchResultWindowPrivate::updateFilterButton()
{ {
m_filterButton->setEnabled(isSearchVisible() m_filterButton->setEnabled(isSearchVisible()
@@ -624,6 +660,7 @@ QList<QWidget *> SearchResultWindowPrivate::toolBarWidgets()
return {m_expandCollapseButton, return {m_expandCollapseButton,
m_filterButton, m_filterButton,
m_newSearchButton, m_newSearchButton,
m_relativePathsButton,
m_spacer, m_spacer,
m_historyLabel, m_historyLabel,
m_spacer2, m_spacer2,
@@ -639,6 +676,8 @@ void SearchResultWindow::readSettings()
s->beginGroup(SETTINGSKEYSECTIONNAME); s->beginGroup(SETTINGSKEYSECTIONNAME);
d->m_expandCollapseAction->setChecked(s->value(SETTINGSKEYEXPANDRESULTS, d->m_expandCollapseAction->setChecked(s->value(SETTINGSKEYEXPANDRESULTS,
SearchResultWindowPrivate::m_initiallyExpand).toBool()); SearchResultWindowPrivate::m_initiallyExpand).toBool());
d->m_relativePathsAction->setChecked(s->value(SETTINGSKEYRELATIVEPATHSRESULTS,
SearchResultWindowPrivate::m_initiallyRelativePaths).toBool());
s->endGroup(); s->endGroup();
} }
@@ -652,6 +691,9 @@ void SearchResultWindow::writeSettings()
s->setValueWithDefault(SETTINGSKEYEXPANDRESULTS, s->setValueWithDefault(SETTINGSKEYEXPANDRESULTS,
d->m_expandCollapseAction->isChecked(), d->m_expandCollapseAction->isChecked(),
SearchResultWindowPrivate::m_initiallyExpand); SearchResultWindowPrivate::m_initiallyExpand);
s->setValueWithDefault(SETTINGSKEYRELATIVEPATHSRESULTS,
d->m_relativePathsAction->isChecked(),
SearchResultWindowPrivate::m_initiallyRelativePaths);
s->endGroup(); s->endGroup();
} }

View File

@@ -1093,6 +1093,25 @@ void ICore::restart()
exit(); exit();
} }
/*!
\internal
*/
void ICore::setRelativePathToProjectFunction(const std::function<FilePath(const FilePath &)> &func)
{
m_core->m_relativePathToProject = func;
}
/*!
\internal
*/
FilePath ICore::pathRelativeToActiveProject(const FilePath &path)
{
if (m_core->m_relativePathToProject)
return m_core->m_relativePathToProject(path);
return path;
}
/*! /*!
\internal \internal
*/ */

View File

@@ -134,6 +134,8 @@ signals:
public: public:
/* internal use */ /* internal use */
static void setRelativePathToProjectFunction(const std::function<Utils::FilePath(const Utils::FilePath &)> &func);
static Utils::FilePath pathRelativeToActiveProject(const Utils::FilePath &path);
static QStringList additionalAboutInformation(); static QStringList additionalAboutInformation();
static void clearAboutInformation(); static void clearAboutInformation();
static void appendAboutInformation(const QString &line); static void appendAboutInformation(const QString &line);
@@ -166,6 +168,9 @@ public:
static IDocument *openFiles(const Utils::FilePaths &filePaths, static IDocument *openFiles(const Utils::FilePaths &filePaths,
OpenFilesFlags flags = None, OpenFilesFlags flags = None,
const Utils::FilePath &workingDirectory = {}); const Utils::FilePath &workingDirectory = {});
private:
std::function<Utils::FilePath(const Utils::FilePath &)> m_relativePathToProject = nullptr;
}; };
} // namespace Core } // namespace Core

View File

@@ -2119,6 +2119,17 @@ void ProjectExplorerPlugin::extensionsInitialized()
// Load devices immediately, as other plugins might want to use them // Load devices immediately, as other plugins might want to use them
DeviceManager::instance()->load(); DeviceManager::instance()->load();
Core::ICore::instance()->setRelativePathToProjectFunction([=](const FilePath& path) -> FilePath
{
ProjectExplorer::Project* p = ProjectExplorer::ProjectTree::currentProject();
if (p) {
FilePath relPath = path.relativeChildPath(p->projectFilePath().absolutePath());
return !relPath.isEmpty() ? relPath : path;
} else {
return path;
}
});
} }
bool ProjectExplorerPlugin::delayedInitialize() bool ProjectExplorerPlugin::delayedInitialize()