diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index 3e99eba356e..015c260fdb2 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -59,6 +59,8 @@ #include #include +#include +#include using namespace Utils; @@ -221,11 +223,53 @@ bool FlatModel::setData(const QModelIndex &index, const QVariant &value, int rol Node *node = nodeForIndex(index); QTC_ASSERT(node, return false); + std::vector> toRename; const Utils::FilePath orgFilePath = node->filePath(); const Utils::FilePath newFilePath = orgFilePath.parentDir().pathAppended(value.toString()); + const QFileInfo orgFileInfo = orgFilePath.toFileInfo(); + toRename.emplace_back(std::make_tuple(node, orgFilePath, newFilePath)); - ProjectExplorerPlugin::renameFile(node, newFilePath.toString()); - emit renamed(orgFilePath, newFilePath); + // The base name of the file was changed. Go look for other files with the same base name + // and offer to rename them as well. + if (orgFilePath != newFilePath && orgFileInfo.suffix() == newFilePath.toFileInfo().suffix()) { + ProjectNode *productNode = node->parentProjectNode(); + while (productNode && !productNode->isProduct()) + productNode = productNode->parentProjectNode(); + if (productNode) { + const auto filter = [&orgFilePath, &orgFileInfo](const Node *n) { + return n->asFileNode() + && n->filePath().toFileInfo().dir() == orgFileInfo.dir() + && n->filePath().toFileInfo().completeBaseName() + == orgFileInfo.completeBaseName() + && n->filePath() != orgFilePath; + }; + const QList candidateNodes = productNode->findNodes(filter); + if (!candidateNodes.isEmpty()) { + const QMessageBox::StandardButton reply = QMessageBox::question( + Core::ICore::mainWindow(), tr("Rename More Files?"), + tr("Would you like to rename these files as well?\n %1") + .arg(transform(candidateNodes, [](const Node *n) { + return n->filePath().toFileInfo().fileName(); + }).join("\n "))); + if (reply == QMessageBox::Yes) { + for (Node * const n : candidateNodes) { + QString targetFilePath = orgFileInfo.absolutePath() + '/' + + newFilePath.toFileInfo().completeBaseName(); + const QString suffix = n->filePath().toFileInfo().suffix(); + if (!suffix.isEmpty()) + targetFilePath.append('.').append(suffix); + toRename.emplace_back(std::make_tuple(n, n->filePath(), + FilePath::fromString(targetFilePath))); + } + } + } + } + } + + for (const auto &f : toRename) { + ProjectExplorerPlugin::renameFile(std::get<0>(f), std::get<2>(f).toString()); + emit renamed(std::get<1>(f), std::get<2>(f)); + } return true; } diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index eb4513b5cd7..f18b21a9be2 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -335,18 +335,20 @@ int ProjectTreeWidget::expandedCount(Node *node) void ProjectTreeWidget::rowsInserted(const QModelIndex &parent, int start, int end) { + if (m_delayedRename.isEmpty()) + return; Node *node = m_model->nodeForIndex(parent); QTC_ASSERT(node, return); - int i = start; - while (i <= end) { + for (int i = start; i <= end && !m_delayedRename.isEmpty(); ++i) { QModelIndex idx = m_model->index(i, 0, parent); Node *n = m_model->nodeForIndex(idx); - if (n && n->filePath() == m_delayedRename) { + if (!n) + continue; + const int renameIdx = m_delayedRename.indexOf(n->filePath()); + if (renameIdx != -1) { m_view->setCurrentIndex(idx); - m_delayedRename.clear(); - break; + m_delayedRename.removeAt(renameIdx); } - ++i; } } @@ -467,7 +469,7 @@ void ProjectTreeWidget::renamed(const FilePath &oldPath, const FilePath &newPath if (node) m_view->setCurrentIndex(m_model->indexForNode(node)); else - m_delayedRename = newPath; + m_delayedRename << newPath; } } diff --git a/src/plugins/projectexplorer/projecttreewidget.h b/src/plugins/projectexplorer/projecttreewidget.h index c4b729f097e..74b301e93bd 100644 --- a/src/plugins/projectexplorer/projecttreewidget.h +++ b/src/plugins/projectexplorer/projecttreewidget.h @@ -94,7 +94,7 @@ private: QString m_modelId; bool m_autoSync = true; - Utils::FilePath m_delayedRename; + QList m_delayedRename; static QList m_projectTreeWidgets; friend class ProjectTreeWidgetFactory;