Commit ef951eae authored by Daniel Teske's avatar Daniel Teske Committed by André Hartmann

Class Renaming: Offer to rename files that match the symbols name

Task-number: QTCREATORBUG-14696
Change-Id: I6d140dac510e47d1a19d6759148f5f24dad44062
Reviewed-by: Ivan Donchevskii's avatarIvan Donchevskii <ivan.donchevskii@qt.io>
Reviewed-by: Nikolai Kosjar's avatarNikolai Kosjar <nikolai.kosjar@qt.io>
Reviewed-by: Orgad Shaneh's avatarOrgad Shaneh <orgads@gmail.com>
parent d728317c
...@@ -185,6 +185,8 @@ SearchResultWidget::SearchResultWidget(QWidget *parent) : ...@@ -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) : ...@@ -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 ...@@ -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: ...@@ -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: ...@@ -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) ...@@ -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: ...@@ -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 @@ ...@@ -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 @@ ...@@ -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; ...@@ -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, ...@@ -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, ...@@ -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,
[&parameters, 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 &paramet ...@@ -467,6 +514,8 @@ Symbol *CppFindReferences::findSymbol(const CppFindReferencesParameters &paramet
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, ...@@ -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 ...@@ -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; ...@@ -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 ...@@ -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: ...@@ -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: ...@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment