forked from qt-creator/qt-creator
Implemented file rename in ResourceEditor.
Renaming supports version control. To prevent code duplication part of ProjectExplorerPlugin::renameFile implementation was separated into FileUtils::renameFile. Change-Id: I28481bea89d0824339e5db025ceb7216713bd5a0 Reviewed-by: Eike Ziller <eike.ziller@nokia.com>
This commit is contained in:
committed by
Eike Ziller
parent
bb66e54626
commit
eef043e055
@@ -32,6 +32,9 @@
|
||||
|
||||
#include "fileutils.h"
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/iversioncontrol.h>
|
||||
#include <coreplugin/vcsmanager.h>
|
||||
#include <utils/environment.h>
|
||||
|
||||
#include <QDir>
|
||||
@@ -41,6 +44,10 @@
|
||||
#include <QMessageBox>
|
||||
#include <QWidget>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
#include <QAbstractFileEngine>
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
#include <coreplugin/icore.h>
|
||||
#include <utils/consoleprocess.h>
|
||||
@@ -165,3 +172,35 @@ QString FileUtils::msgTerminalAction()
|
||||
return QApplication::translate("Core::Internal", "Open Terminal Here");
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool fileSystemRenameFile(const QString &orgFilePath,
|
||||
const QString &newFilePath)
|
||||
{
|
||||
#if QT_VERSION < 0x050000 // ### fixme: QTBUG-3570 might be fixed in Qt 5?
|
||||
QFile f(orgFilePath); // Due to QTBUG-3570
|
||||
QAbstractFileEngine *fileEngine = f.fileEngine();
|
||||
if (!fileEngine->caseSensitive() && orgFilePath.compare(newFilePath, Qt::CaseInsensitive) == 0)
|
||||
return fileEngine->rename(newFilePath);
|
||||
#endif
|
||||
return QFile::rename(orgFilePath, newFilePath);
|
||||
}
|
||||
|
||||
bool FileUtils::renameFile(const QString &orgFilePath, const QString &newFilePath)
|
||||
{
|
||||
if (orgFilePath == newFilePath)
|
||||
return false;
|
||||
|
||||
QString dir = QFileInfo(orgFilePath).absolutePath();
|
||||
Core::IVersionControl *vc = Core::ICore::vcsManager()->findVersionControlForDirectory(dir);
|
||||
|
||||
bool result = false;
|
||||
if (vc && vc->supportsOperation(Core::IVersionControl::MoveOperation))
|
||||
result = vc->vcsMove(orgFilePath, newFilePath);
|
||||
if (!result) // The moving via vcs failed or the vcs does not support moving, fall back
|
||||
result = fileSystemRenameFile(orgFilePath, newFilePath);
|
||||
if (result) {
|
||||
// yeah we moved, tell the filemanager about it
|
||||
Core::DocumentManager::renamedFile(orgFilePath, newFilePath);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,8 @@ struct CORE_EXPORT FileUtils
|
||||
// Platform-dependent action descriptions
|
||||
static QString msgGraphicalShellAction();
|
||||
static QString msgTerminalAction();
|
||||
// File rename aware of version control and file system case-insensitiveness
|
||||
static bool renameFile(const QString &from, const QString &to);
|
||||
};
|
||||
|
||||
} // namespace Core
|
||||
|
||||
@@ -127,10 +127,6 @@
|
||||
#include <QFileInfo>
|
||||
#include <QSettings>
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
#include <QAbstractFileEngine>
|
||||
#endif
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QFileDialog>
|
||||
@@ -2822,18 +2818,6 @@ void ProjectExplorerPlugin::renameFile()
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool fileSystemRenameFile(const QString &orgFilePath,
|
||||
const QString &newFilePath)
|
||||
{
|
||||
#if QT_VERSION < 0x050000 // ### fixme: QTBUG-3570 might be fixed in Qt 5?
|
||||
QFile f(orgFilePath); // Due to QTBUG-3570
|
||||
QAbstractFileEngine *fileEngine = f.fileEngine();
|
||||
if (!fileEngine->caseSensitive() && orgFilePath.compare(newFilePath, Qt::CaseInsensitive) == 0)
|
||||
return fileEngine->rename(newFilePath);
|
||||
#endif
|
||||
return QFile::rename(orgFilePath, newFilePath);
|
||||
}
|
||||
|
||||
void ProjectExplorerPlugin::renameFile(Node *node, const QString &to)
|
||||
{
|
||||
FileNode *fileNode = qobject_cast<FileNode *>(node);
|
||||
@@ -2843,20 +2827,8 @@ void ProjectExplorerPlugin::renameFile(Node *node, const QString &to)
|
||||
QString dir = QFileInfo(orgFilePath).absolutePath();
|
||||
QString newFilePath = dir + QLatin1Char('/') + to;
|
||||
|
||||
if (orgFilePath == newFilePath)
|
||||
return;
|
||||
|
||||
Core::IVersionControl *vc = Core::ICore::vcsManager()->findVersionControlForDirectory(dir);
|
||||
|
||||
bool result = false;
|
||||
if (vc && vc->supportsOperation(Core::IVersionControl::MoveOperation))
|
||||
result = vc->vcsMove(orgFilePath, newFilePath);
|
||||
if (!result) // The moving via vcs failed or the vcs does not support moving, fall back
|
||||
result = fileSystemRenameFile(orgFilePath, newFilePath);
|
||||
if (result) {
|
||||
// yeah we moved, tell the filemanager about it
|
||||
Core::DocumentManager::renamedFile(orgFilePath, newFilePath);
|
||||
// Tell the project plugin about it
|
||||
if (Core::FileUtils::renameFile(orgFilePath, newFilePath)) {
|
||||
// Tell the project plugin about rename
|
||||
ProjectNode *projectNode = fileNode->projectNode();
|
||||
if (!projectNode->renameFile(fileNode->fileType(), orgFilePath, newFilePath)) {
|
||||
QMessageBox::warning(Core::ICore::mainWindow(), tr("Project Editing Failed"),
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QToolBar>
|
||||
#include <QInputDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
namespace ResourceEditor {
|
||||
namespace Internal {
|
||||
@@ -103,6 +105,7 @@ ResourceEditorW::ResourceEditorW(const Core::Context &context,
|
||||
m_resourceEditor->setResourceDragEnabled(true);
|
||||
m_contextMenu->addAction(tr("Open File"), this, SLOT(openCurrentFile()));
|
||||
m_openWithMenu = m_contextMenu->addMenu(tr("Open With"));
|
||||
m_renameAction = m_contextMenu->addAction(tr("Rename File..."), this, SLOT(renameCurrentFile()), Qt::Key_F2);
|
||||
// Below we need QueuedConnection because otherwise, if this qrc file
|
||||
// is inside of the qrc file, crashes happen when using "Open With" on it.
|
||||
// (That is because this editor instance is deleted in executeOpenWithMenuAction
|
||||
@@ -298,11 +301,10 @@ void ResourceEditorW::onUndoStackChanged(bool canUndo, bool canRedo)
|
||||
void ResourceEditorW::showContextMenu(const QPoint &globalPoint, const QString &fileName)
|
||||
{
|
||||
Core::DocumentManager::populateOpenWithMenu(m_openWithMenu, fileName);
|
||||
if (!m_openWithMenu->actions().isEmpty()) {
|
||||
m_currentFileName = fileName;
|
||||
m_renameAction->setEnabled(!document()->isFileReadOnly());
|
||||
m_contextMenu->popup(globalPoint);
|
||||
}
|
||||
}
|
||||
|
||||
void ResourceEditorW::openCurrentFile()
|
||||
{
|
||||
@@ -320,6 +322,11 @@ void ResourceEditorW::onRefresh()
|
||||
m_resourceEditor.data()->refresh();
|
||||
}
|
||||
|
||||
void ResourceEditorW::renameCurrentFile()
|
||||
{
|
||||
m_resourceEditor->editCurrentItem();
|
||||
}
|
||||
|
||||
void ResourceEditorW::onUndo()
|
||||
{
|
||||
if (!m_resourceEditor.isNull())
|
||||
|
||||
@@ -111,6 +111,7 @@ private slots:
|
||||
void showContextMenu(const QPoint &globalPoint, const QString &fileName);
|
||||
void openCurrentFile();
|
||||
void openFile(const QString &fileName);
|
||||
void renameCurrentFile();
|
||||
|
||||
private:
|
||||
const QString m_extension;
|
||||
@@ -126,6 +127,7 @@ private:
|
||||
QMenu *m_openWithMenu;
|
||||
QString m_currentFileName;
|
||||
QToolBar *m_toolBar;
|
||||
QAction *m_renameAction;
|
||||
|
||||
public slots:
|
||||
void onRefresh();
|
||||
|
||||
@@ -349,12 +349,12 @@ void QrcEditor::addFile(const QString &prefix, const QString &file)
|
||||
m_treeview->addFile(prefix, file);
|
||||
}
|
||||
|
||||
/*
|
||||
void QrcEditor::removeFile(const QString &prefix, const QString &file)
|
||||
void QrcEditor::editCurrentItem()
|
||||
{
|
||||
m_treeview->removeFile(prefix, file);
|
||||
if (m_treeview->selectionModel()->currentIndex().isValid())
|
||||
m_treeview->edit(m_treeview->selectionModel()->currentIndex());
|
||||
}
|
||||
*/
|
||||
|
||||
// Slot for change of line edit content 'alias'
|
||||
void QrcEditor::onAliasChanged(const QString &alias)
|
||||
{
|
||||
|
||||
@@ -63,11 +63,11 @@ public:
|
||||
bool resourceDragEnabled() const;
|
||||
|
||||
void addFile(const QString &prefix, const QString &file);
|
||||
// void removeFile(const QString &prefix, const QString &file);
|
||||
|
||||
const QUndoStack *commandHistory() const { return &m_history; }
|
||||
|
||||
void refresh();
|
||||
void editCurrentItem();
|
||||
|
||||
signals:
|
||||
void dirtyChanged(bool dirty);
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include "resourcefile_p.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/fileutils.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
@@ -89,6 +91,11 @@ bool File::exists()
|
||||
return m_exists;
|
||||
}
|
||||
|
||||
void File::setExists(bool exists)
|
||||
{
|
||||
m_exists = exists;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
** FileList
|
||||
*/
|
||||
@@ -378,6 +385,41 @@ void ResourceFile::replaceAlias(int prefix_idx, int file_idx, const QString &ali
|
||||
fileList[file_idx]->alias = alias;
|
||||
}
|
||||
|
||||
bool ResourceFile::renameFile(const QString fileName, const QString &newFileName)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
FileList entries;
|
||||
for (int i = 0; i < prefixCount(); ++i) {
|
||||
const FileList &file_list = m_prefix_list.at(i)->file_list;
|
||||
foreach (File *file, file_list) {
|
||||
if (file->name == fileName)
|
||||
entries.append(file);
|
||||
if (file->name == newFileName)
|
||||
return false; // prevent conflicts
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT(!entries.isEmpty());
|
||||
|
||||
entries.at(0)->checkExistence();
|
||||
if (entries.at(0)->exists()) {
|
||||
foreach (File *file, entries)
|
||||
file->setExists(true);
|
||||
success = Core::FileUtils::renameFile(entries.at(0)->name, newFileName);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
bool exists = QFile::exists(newFileName);
|
||||
foreach (File *file, entries) {
|
||||
file->name = newFileName;
|
||||
file->setExists(exists);
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
void ResourceFile::replaceFile(int pref_idx, int file_idx, const QString &file)
|
||||
{
|
||||
@@ -646,6 +688,22 @@ void ResourceModel::refresh()
|
||||
m_resource_file.refresh();
|
||||
}
|
||||
|
||||
Qt::ItemFlags ResourceModel::flags(const QModelIndex &index) const
|
||||
{
|
||||
Qt::ItemFlags f = QAbstractItemModel::flags(index);
|
||||
|
||||
const void *internalPointer = index.internalPointer();
|
||||
const Node *node = reinterpret_cast<const Node *>(internalPointer);
|
||||
const Prefix *prefix = node->prefix();
|
||||
Q_ASSERT(prefix);
|
||||
const bool isFileNode = (prefix != node);
|
||||
|
||||
if (isFileNode)
|
||||
f |= Qt::ItemIsEditable;
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
bool ResourceModel::iconFileExtension(const QString &path)
|
||||
{
|
||||
static QStringList ext_list;
|
||||
@@ -701,7 +759,7 @@ QVariant ResourceModel::data(const QModelIndex &index, int role) const
|
||||
// File node
|
||||
Q_ASSERT(file);
|
||||
QString conv_file = m_resource_file.relativePath(file->name);
|
||||
stringRes = conv_file.replace(QDir::separator(), QLatin1Char('/'));
|
||||
stringRes = QDir::fromNativeSeparators(conv_file);
|
||||
const QString alias = file->alias;
|
||||
if (!alias.isEmpty())
|
||||
appendParenthesized(alias, stringRes);
|
||||
@@ -727,6 +785,13 @@ QVariant ResourceModel::data(const QModelIndex &index, int role) const
|
||||
result = m_prefixIcon;
|
||||
}
|
||||
break;
|
||||
case Qt::EditRole:
|
||||
if (isFileNode) {
|
||||
Q_ASSERT(file);
|
||||
QString conv_file = m_resource_file.relativePath(file->name);
|
||||
result = QDir::fromNativeSeparators(conv_file);
|
||||
}
|
||||
break;
|
||||
case Qt::ForegroundRole:
|
||||
if (isFileNode) {
|
||||
// File node
|
||||
@@ -741,6 +806,26 @@ QVariant ResourceModel::data(const QModelIndex &index, int role) const
|
||||
return result;
|
||||
}
|
||||
|
||||
bool ResourceModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||
{
|
||||
if (!index.isValid())
|
||||
return false;
|
||||
if (role != Qt::EditRole)
|
||||
return false;
|
||||
|
||||
const QDir baseDir = QFileInfo(fileName()).absoluteDir();
|
||||
Utils::FileName newFileName = Utils::FileName::fromUserInput(
|
||||
baseDir.absoluteFilePath(value.toString()));
|
||||
|
||||
if (newFileName.isEmpty())
|
||||
return false;
|
||||
|
||||
if (!newFileName.isChildOf(Utils::FileName::fromString(baseDir.absolutePath())))
|
||||
return false;
|
||||
|
||||
return renameFile(file(index), newFileName.toString());
|
||||
}
|
||||
|
||||
void ResourceModel::getItem(const QModelIndex &index, QString &prefix, QString &file) const
|
||||
{
|
||||
prefix.clear();
|
||||
@@ -924,6 +1009,14 @@ void ResourceModel::insertFile(int prefixIndex, int fileIndex,
|
||||
setDirty(true);
|
||||
}
|
||||
|
||||
bool ResourceModel::renameFile(const QString &fileName, const QString &newFileName)
|
||||
{
|
||||
bool success = m_resource_file.renameFile(fileName, newFileName);
|
||||
if (success)
|
||||
setDirty(true);
|
||||
return success;
|
||||
}
|
||||
|
||||
void ResourceModel::changePrefix(const QModelIndex &model_idx, const QString &prefix)
|
||||
{
|
||||
if (!model_idx.isValid())
|
||||
|
||||
@@ -77,6 +77,7 @@ public:
|
||||
File(Prefix *prefix, const QString &_name, const QString &_alias = QString());
|
||||
void checkExistence();
|
||||
bool exists();
|
||||
void setExists(bool exists);
|
||||
|
||||
bool operator < (const File &other) const { return name < other.name; }
|
||||
bool operator == (const File &other) const { return name == other.name; }
|
||||
@@ -161,6 +162,8 @@ public:
|
||||
void replaceLang(int prefix_idx, const QString &lang);
|
||||
void replaceAlias(int prefix_idx, int file_idx, const QString &alias);
|
||||
|
||||
bool renameFile(const QString fileName, const QString &newFileName);
|
||||
|
||||
private:
|
||||
void replaceFile(int pref_idx, int file_idx, const QString &file);
|
||||
public:
|
||||
@@ -211,11 +214,13 @@ public:
|
||||
int rowCount(const QModelIndex &parent) const;
|
||||
int columnCount(const QModelIndex &parent) const;
|
||||
bool hasChildren(const QModelIndex &parent) const;
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||
|
||||
void refresh();
|
||||
|
||||
protected:
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
||||
|
||||
public:
|
||||
QString fileName() const { return m_resource_file.fileName(); }
|
||||
@@ -247,6 +252,7 @@ private:
|
||||
QString relativePath(const QString &path) const
|
||||
{ return m_resource_file.relativePath(path); }
|
||||
QString lastResourceOpenDirectory() const;
|
||||
bool renameFile(const QString &fileName, const QString &newFileName);
|
||||
|
||||
public:
|
||||
virtual bool reload();
|
||||
|
||||
@@ -183,6 +183,7 @@ ResourceView::ResourceView(QUndoStack *history, QWidget *parent) :
|
||||
advanceMergeId();
|
||||
setModel(m_qrcModel);
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
setEditTriggers(EditKeyPressed);
|
||||
|
||||
header()->hide();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user