forked from qt-creator/qt-creator
Class Renaming: Offer to rename files that match the symbols name
Task-number: QTCREATORBUG-14696 Change-Id: I6d140dac510e47d1a19d6759148f5f24dad44062 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io> Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
committed by
André Hartmann
parent
d728317c87
commit
ef951eaea7
@@ -185,6 +185,8 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
|
|||||||
m_preserveCaseCheck = new QCheckBox(m_topReplaceWidget);
|
m_preserveCaseCheck = new QCheckBox(m_topReplaceWidget);
|
||||||
m_preserveCaseCheck->setText(tr("Preser&ve case"));
|
m_preserveCaseCheck->setText(tr("Preser&ve case"));
|
||||||
m_preserveCaseCheck->setEnabled(false);
|
m_preserveCaseCheck->setEnabled(false);
|
||||||
|
m_renameFilesCheckBox = new QCheckBox(m_topReplaceWidget);
|
||||||
|
m_renameFilesCheckBox->setVisible(false);
|
||||||
|
|
||||||
m_preserveCaseCheck->setChecked(Find::hasFindFlag(FindPreserveCase));
|
m_preserveCaseCheck->setChecked(Find::hasFindFlag(FindPreserveCase));
|
||||||
connect(m_preserveCaseCheck, &QAbstractButton::clicked, Find::instance(), &Find::setPreserveCase);
|
connect(m_preserveCaseCheck, &QAbstractButton::clicked, Find::instance(), &Find::setPreserveCase);
|
||||||
@@ -201,6 +203,7 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) :
|
|||||||
topReplaceLayout->addWidget(m_replaceTextEdit);
|
topReplaceLayout->addWidget(m_replaceTextEdit);
|
||||||
topReplaceLayout->addWidget(m_replaceButton);
|
topReplaceLayout->addWidget(m_replaceButton);
|
||||||
topReplaceLayout->addWidget(m_preserveCaseCheck);
|
topReplaceLayout->addWidget(m_preserveCaseCheck);
|
||||||
|
topReplaceLayout->addWidget(m_renameFilesCheckBox);
|
||||||
topReplaceLayout->addStretch(2);
|
topReplaceLayout->addStretch(2);
|
||||||
setShowReplaceUI(m_replaceSupported);
|
setShowReplaceUI(m_replaceSupported);
|
||||||
setSupportPreserveCase(true);
|
setSupportPreserveCase(true);
|
||||||
@@ -228,6 +231,11 @@ void SearchResultWidget::setInfo(const QString &label, const QString &toolTip, c
|
|||||||
m_searchTerm->setVisible(!term.isEmpty());
|
m_searchTerm->setVisible(!term.isEmpty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *SearchResultWidget::additionalReplaceWidget() const
|
||||||
|
{
|
||||||
|
return m_renameFilesCheckBox;
|
||||||
|
}
|
||||||
|
|
||||||
void SearchResultWidget::addResult(const QString &fileName,
|
void SearchResultWidget::addResult(const QString &fileName,
|
||||||
const QString &rowText,
|
const QString &rowText,
|
||||||
Search::TextRange mainRange,
|
Search::TextRange mainRange,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public:
|
|||||||
~SearchResultWidget();
|
~SearchResultWidget();
|
||||||
|
|
||||||
void setInfo(const QString &label, const QString &toolTip, const QString &term);
|
void setInfo(const QString &label, const QString &toolTip, const QString &term);
|
||||||
|
QWidget *additionalReplaceWidget() const;
|
||||||
|
|
||||||
void addResult(const QString &fileName,
|
void addResult(const QString &fileName,
|
||||||
const QString &lineText,
|
const QString &lineText,
|
||||||
@@ -130,6 +131,7 @@ private:
|
|||||||
QToolButton *m_replaceButton;
|
QToolButton *m_replaceButton;
|
||||||
QToolButton *m_searchAgainButton;
|
QToolButton *m_searchAgainButton;
|
||||||
QCheckBox *m_preserveCaseCheck;
|
QCheckBox *m_preserveCaseCheck;
|
||||||
|
QCheckBox *m_renameFilesCheckBox = nullptr;
|
||||||
QWidget *m_descriptionContainer;
|
QWidget *m_descriptionContainer;
|
||||||
QLabel *m_label;
|
QLabel *m_label;
|
||||||
QLabel *m_searchTerm;
|
QLabel *m_searchTerm;
|
||||||
|
|||||||
@@ -643,6 +643,11 @@ void SearchResult::setSearchAgainSupported(bool supported)
|
|||||||
m_widget->setSearchAgainSupported(supported);
|
m_widget->setSearchAgainSupported(supported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QWidget *SearchResult::additionalReplaceWidget() const
|
||||||
|
{
|
||||||
|
return m_widget->additionalReplaceWidget();
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Adds a single result line to the \gui {Search Results} output pane.
|
Adds a single result line to the \gui {Search Results} output pane.
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ public:
|
|||||||
QString textToReplace() const;
|
QString textToReplace() const;
|
||||||
int count() const;
|
int count() const;
|
||||||
void setSearchAgainSupported(bool supported);
|
void setSearchAgainSupported(bool supported);
|
||||||
|
QWidget *additionalReplaceWidget() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void addResult(const QString &fileName,
|
void addResult(const QString &fileName,
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/progressmanager/futureprogress.h>
|
#include <coreplugin/progressmanager/futureprogress.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
#include <projectexplorer/projectnodes.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
#include <texteditor/basefilefind.h>
|
#include <texteditor/basefilefind.h>
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
@@ -42,6 +45,7 @@
|
|||||||
|
|
||||||
#include <cplusplus/Overview.h>
|
#include <cplusplus/Overview.h>
|
||||||
#include <QtConcurrentMap>
|
#include <QtConcurrentMap>
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@@ -50,6 +54,7 @@ using namespace Core;
|
|||||||
using namespace CppTools::Internal;
|
using namespace CppTools::Internal;
|
||||||
using namespace CppTools;
|
using namespace CppTools;
|
||||||
using namespace CPlusPlus;
|
using namespace CPlusPlus;
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
static QByteArray getSource(const Utils::FileName &fileName,
|
static QByteArray getSource(const Utils::FileName &fileName,
|
||||||
const WorkingCopy &workingCopy)
|
const WorkingCopy &workingCopy)
|
||||||
@@ -336,6 +341,12 @@ void CppFindReferences::findUsages(Symbol *symbol,
|
|||||||
CppFindReferencesParameters parameters;
|
CppFindReferencesParameters parameters;
|
||||||
parameters.symbolId = fullIdForSymbol(symbol);
|
parameters.symbolId = fullIdForSymbol(symbol);
|
||||||
parameters.symbolFileName = QByteArray(symbol->fileName());
|
parameters.symbolFileName = QByteArray(symbol->fileName());
|
||||||
|
|
||||||
|
if (symbol->isClass() || symbol->isForwardClassDeclaration()) {
|
||||||
|
Overview overview;
|
||||||
|
parameters.prettySymbolName = overview.prettyName(context.path(symbol).last());
|
||||||
|
}
|
||||||
|
|
||||||
search->setUserData(qVariantFromValue(parameters));
|
search->setUserData(qVariantFromValue(parameters));
|
||||||
findAll_helper(search, symbol, context);
|
findAll_helper(search, symbol, context);
|
||||||
}
|
}
|
||||||
@@ -382,12 +393,48 @@ void CppFindReferences::onReplaceButtonClicked(const QString &text,
|
|||||||
m_modelManager->updateSourceFiles(fileNames.toSet());
|
m_modelManager->updateSourceFiles(fileNames.toSet());
|
||||||
SearchResultWindow::instance()->hide();
|
SearchResultWindow::instance()->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto search = qobject_cast<SearchResult *>(sender());
|
||||||
|
QTC_ASSERT(search, return);
|
||||||
|
|
||||||
|
CppFindReferencesParameters parameters = search->userData().value<CppFindReferencesParameters>();
|
||||||
|
if (parameters.filesToRename.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto renameFilesCheckBox = qobject_cast<QCheckBox *>(search->additionalReplaceWidget());
|
||||||
|
if (!renameFilesCheckBox || !renameFilesCheckBox->isChecked())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const QStringList newPaths =
|
||||||
|
Utils::transform<QList>(parameters.filesToRename,
|
||||||
|
[¶meters, text](const Node *node) -> QString {
|
||||||
|
const QFileInfo fi = node->filePath().toFileInfo();
|
||||||
|
const QString fileName = fi.fileName();
|
||||||
|
QString newName = fileName;
|
||||||
|
newName.replace(parameters.prettySymbolName, text, Qt::CaseInsensitive);
|
||||||
|
|
||||||
|
if (newName != fileName) {
|
||||||
|
newName = Utils::matchCaseReplacement(fileName, newName);
|
||||||
|
|
||||||
|
return fi.absolutePath() + "/" + newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int i = 0; i < parameters.filesToRename.size(); ++i) {
|
||||||
|
if (!newPaths.at(i).isEmpty()) {
|
||||||
|
Node *node = parameters.filesToRename.at(i);
|
||||||
|
ProjectExplorerPlugin::renameFile(node, newPaths.at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppFindReferences::searchAgain()
|
void CppFindReferences::searchAgain()
|
||||||
{
|
{
|
||||||
SearchResult *search = qobject_cast<SearchResult *>(sender());
|
SearchResult *search = qobject_cast<SearchResult *>(sender());
|
||||||
CppFindReferencesParameters parameters = search->userData().value<CppFindReferencesParameters>();
|
CppFindReferencesParameters parameters = search->userData().value<CppFindReferencesParameters>();
|
||||||
|
parameters.filesToRename.clear();
|
||||||
Snapshot snapshot = CppModelManager::instance()->snapshot();
|
Snapshot snapshot = CppModelManager::instance()->snapshot();
|
||||||
search->restart();
|
search->restart();
|
||||||
LookupContext context;
|
LookupContext context;
|
||||||
@@ -467,6 +514,8 @@ Symbol *CppFindReferences::findSymbol(const CppFindReferencesParameters ¶met
|
|||||||
static void displayResults(SearchResult *search, QFutureWatcher<Usage> *watcher,
|
static void displayResults(SearchResult *search, QFutureWatcher<Usage> *watcher,
|
||||||
int first, int last)
|
int first, int last)
|
||||||
{
|
{
|
||||||
|
CppFindReferencesParameters parameters = search->userData().value<CppFindReferencesParameters>();
|
||||||
|
|
||||||
for (int index = first; index != last; ++index) {
|
for (int index = first; index != last; ++index) {
|
||||||
Usage result = watcher->future().resultAt(index);
|
Usage result = watcher->future().resultAt(index);
|
||||||
search->addResult(result.path.toString(),
|
search->addResult(result.path.toString(),
|
||||||
@@ -474,7 +523,45 @@ static void displayResults(SearchResult *search, QFutureWatcher<Usage> *watcher,
|
|||||||
result.lineText,
|
result.lineText,
|
||||||
result.col,
|
result.col,
|
||||||
result.len);
|
result.len);
|
||||||
|
|
||||||
|
if (parameters.prettySymbolName.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Utils::contains(parameters.filesToRename, Utils::equal(&Node::filePath, result.path)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Node *node = SessionManager::nodeForFile(result.path);
|
||||||
|
if (!node) // Not part of any project
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const QFileInfo fi = node->filePath().toFileInfo();
|
||||||
|
if (fi.baseName().compare(parameters.prettySymbolName, Qt::CaseInsensitive) == 0)
|
||||||
|
parameters.filesToRename.append(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
search->setUserData(qVariantFromValue(parameters));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void searchFinished(SearchResult *search, QFutureWatcher<Usage> *watcher)
|
||||||
|
{
|
||||||
|
search->finishSearch(watcher->isCanceled());
|
||||||
|
|
||||||
|
CppFindReferencesParameters parameters = search->userData().value<CppFindReferencesParameters>();
|
||||||
|
if (!parameters.filesToRename.isEmpty()) {
|
||||||
|
const QStringList filesToRename
|
||||||
|
= Utils::transform<QList>(parameters.filesToRename, [](const Node *node) {
|
||||||
|
return node->filePath().toUserOutput();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto renameCheckBox = qobject_cast<QCheckBox *>(search->additionalReplaceWidget());
|
||||||
|
if (renameCheckBox) {
|
||||||
|
renameCheckBox->setText(CppFindReferences::tr("Re&name %1 files.").arg(filesToRename.size()));
|
||||||
|
renameCheckBox->setToolTip(CppFindReferences::tr("Files:\n%1").arg(filesToRename.join('\n')));
|
||||||
|
renameCheckBox->setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watcher->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppFindReferences::openEditor(const SearchResultItem &item)
|
void CppFindReferences::openEditor(const SearchResultItem &item)
|
||||||
@@ -651,7 +738,9 @@ void CppFindReferences::createWatcher(const QFuture<Usage> &future, SearchResult
|
|||||||
{
|
{
|
||||||
QFutureWatcher<Usage> *watcher = new QFutureWatcher<Usage>();
|
QFutureWatcher<Usage> *watcher = new QFutureWatcher<Usage>();
|
||||||
// auto-delete:
|
// auto-delete:
|
||||||
connect(watcher, &QFutureWatcherBase::finished, watcher, &QObject::deleteLater);
|
connect(watcher, &QFutureWatcherBase::finished, watcher, [search, watcher]() {
|
||||||
|
searchFinished(search, watcher);
|
||||||
|
});
|
||||||
|
|
||||||
connect(watcher, &QFutureWatcherBase::resultsReadyAt, search,
|
connect(watcher, &QFutureWatcherBase::resultsReadyAt, search,
|
||||||
[search, watcher](int first, int last) {
|
[search, watcher](int first, int last) {
|
||||||
|
|||||||
@@ -40,6 +40,10 @@ class SearchResultItem;
|
|||||||
class SearchResult;
|
class SearchResult;
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class Node;
|
||||||
|
}
|
||||||
|
|
||||||
namespace CppTools {
|
namespace CppTools {
|
||||||
class CppModelManager;
|
class CppModelManager;
|
||||||
|
|
||||||
@@ -50,6 +54,8 @@ class CppFindReferencesParameters
|
|||||||
public:
|
public:
|
||||||
QList<QByteArray> symbolId;
|
QList<QByteArray> symbolId;
|
||||||
QByteArray symbolFileName;
|
QByteArray symbolFileName;
|
||||||
|
QString prettySymbolName;
|
||||||
|
QVector<ProjectExplorer::Node *> filesToRename;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CppFindReferences: public QObject
|
class CppFindReferences: public QObject
|
||||||
|
|||||||
@@ -180,6 +180,8 @@ public:
|
|||||||
static void setRefactoringEngine(RefactoringEngineInterface *refactoringEngine);
|
static void setRefactoringEngine(RefactoringEngineInterface *refactoringEngine);
|
||||||
static RefactoringEngineInterface *refactoringEngine();
|
static RefactoringEngineInterface *refactoringEngine();
|
||||||
|
|
||||||
|
void renameIncludes(const QString &oldFileName, const QString &newFileName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/// Project data might be locked while this is emitted.
|
/// Project data might be locked while this is emitted.
|
||||||
void aboutToRemoveFiles(const QStringList &files);
|
void aboutToRemoveFiles(const QStringList &files);
|
||||||
@@ -205,7 +207,6 @@ private:
|
|||||||
// This should be executed in the GUI thread.
|
// This should be executed in the GUI thread.
|
||||||
friend class Tests::ModelManagerTestHelper;
|
friend class Tests::ModelManagerTestHelper;
|
||||||
void onAboutToLoadSession();
|
void onAboutToLoadSession();
|
||||||
void renameIncludes(const QString &oldFileName, const QString &newFileName);
|
|
||||||
void onProjectAdded(ProjectExplorer::Project *project);
|
void onProjectAdded(ProjectExplorer::Project *project);
|
||||||
void onAboutToRemoveProject(ProjectExplorer::Project *project);
|
void onAboutToRemoveProject(ProjectExplorer::Project *project);
|
||||||
void onActiveProjectChanged(ProjectExplorer::Project *project);
|
void onActiveProjectChanged(ProjectExplorer::Project *project);
|
||||||
|
|||||||
Reference in New Issue
Block a user