From 9bc9fe73e160f9ef87979a3cf5f1276b5f1ae0cf Mon Sep 17 00:00:00 2001 From: dt <qtc-committer@nokia.com> Date: Tue, 11 May 2010 14:13:38 +0200 Subject: [PATCH] File renaming Reviewed-By: con Reviewed-By: Friedemann Kleint We now support renaming files. The version control system tries first to rename, if that doesn't support or can't rename the file we do a normal rename. (Note: git, hg, perforce > 2009.02 support renaming, cvs not. (perforce untested)). We correctly notify all editors of the renamed file and tell the project manager to rename the file in the project. Note: Only the qt4projectmanager knows how to rename files. Note: renaming folders, moving files to different folders, renaming .pro/.pri files is not supported. Those things can be later added after this has proven to work correctly in the simple case. Also we don't do any actions based on the renaming like renaming classes, changing include guards or #include lines. --- src/plugins/bineditor/bineditorplugin.cpp | 7 ++ src/plugins/bineditor/imageviewer.cpp | 3 + src/plugins/bineditor/imageviewer.h | 1 + .../cmakeprojectmanager/cmakeproject.cpp | 7 ++ .../cmakeprojectmanager/cmakeproject.h | 2 + .../cmakeprojectmanager/cmakeprojectnodes.cpp | 3 +- .../cmakeprojectmanager/cmakeprojectnodes.h | 2 +- src/plugins/coreplugin/filemanager.cpp | 65 ++++++++++++++++++- src/plugins/coreplugin/filemanager.h | 4 ++ src/plugins/coreplugin/ifile.h | 1 + src/plugins/coreplugin/iversioncontrol.h | 8 ++- src/plugins/cvs/cvscontrol.cpp | 6 ++ src/plugins/cvs/cvscontrol.h | 1 + src/plugins/designer/formwindoweditor.cpp | 1 + src/plugins/designer/formwindowfile.cpp | 9 +++ src/plugins/designer/formwindowfile.h | 1 + .../genericprojectmanager/genericproject.cpp | 7 ++ .../genericprojectmanager/genericproject.h | 1 + .../genericprojectnodes.cpp | 3 +- .../genericprojectnodes.h | 2 +- src/plugins/git/gitclient.cpp | 21 ++++++ src/plugins/git/gitclient.h | 3 + src/plugins/git/gitversioncontrol.cpp | 10 +++ src/plugins/git/gitversioncontrol.h | 1 + src/plugins/mercurial/mercurialclient.cpp | 8 +++ src/plugins/mercurial/mercurialclient.h | 1 + src/plugins/mercurial/mercurialcontrol.cpp | 8 +++ src/plugins/mercurial/mercurialcontrol.h | 1 + src/plugins/perforce/perforceplugin.cpp | 16 +++++ src/plugins/perforce/perforceplugin.h | 1 + .../perforce/perforceversioncontrol.cpp | 8 +++ src/plugins/perforce/perforceversioncontrol.h | 1 + .../projectexplorer/projectexplorer.cpp | 53 +++++++++++---- src/plugins/projectexplorer/projectexplorer.h | 5 +- .../projectexplorer/projectexplorer.pro | 4 +- .../projectfilewizardextension.cpp | 5 +- src/plugins/projectexplorer/projectmodels.cpp | 22 +++++++ src/plugins/projectexplorer/projectmodels.h | 5 +- src/plugins/projectexplorer/projectnodes.h | 5 +- src/plugins/projectexplorer/session.cpp | 2 +- .../qmlprojectmanager/qmlprojectfile.cpp | 7 ++ .../qmlprojectmanager/qmlprojectfile.h | 1 + .../qmlprojectmanager/qmlprojectnodes.cpp | 3 +- .../qmlprojectmanager/qmlprojectnodes.h | 2 +- src/plugins/qt4projectmanager/qt4nodes.cpp | 17 +++-- src/plugins/qt4projectmanager/qt4nodes.h | 3 +- src/plugins/qt4projectmanager/qt4project.cpp | 7 ++ src/plugins/qt4projectmanager/qt4project.h | 1 + .../resourceeditor/resourceeditorw.cpp | 6 ++ src/plugins/resourceeditor/resourceeditorw.h | 1 + src/plugins/subversion/subversioncontrol.cpp | 8 +++ src/plugins/subversion/subversioncontrol.h | 1 + src/plugins/subversion/subversionplugin.cpp | 10 +++ src/plugins/subversion/subversionplugin.h | 1 + src/plugins/texteditor/basetextdocument.cpp | 8 +++ src/plugins/texteditor/basetextdocument.h | 1 + src/plugins/vcsbase/submiteditorfile.cpp | 7 ++ src/plugins/vcsbase/submiteditorfile.h | 2 +- 58 files changed, 365 insertions(+), 35 deletions(-) diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index 432df20a97a..6c8bfc9bdde 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -196,6 +196,12 @@ public: } } + void rename(const QString &newName) { + m_fileName = newName; + m_editor->editorInterface()->setDisplayName(QFileInfo(fileName()).fileName()); + emit changed(); + } + bool open(const QString &fileName) { QFile file(fileName); if (file.open(QIODevice::ReadOnly)) { @@ -305,6 +311,7 @@ public: m_toolBar->addWidget(w); connect(m_editor, SIGNAL(cursorPositionChanged(int)), this, SLOT(updateCursorPosition(int))); + connect(m_file, SIGNAL(changed()), this, SIGNAL(changed())); } ~BinEditorInterface() { delete m_editor; diff --git a/src/plugins/bineditor/imageviewer.cpp b/src/plugins/bineditor/imageviewer.cpp index e8a5d7c940a..57fdf994735 100644 --- a/src/plugins/bineditor/imageviewer.cpp +++ b/src/plugins/bineditor/imageviewer.cpp @@ -155,6 +155,9 @@ ImageViewer::ImageViewer(QObject *parent) layout->setMargin(0); m_imageView->setLayout(layout); layout->addWidget(m_label, 0, 0, 1, 1); + + connect(m_file, SIGNAL(changed()), + this, SIGNAL(changed())); } ImageViewer::~ImageViewer() diff --git a/src/plugins/bineditor/imageviewer.h b/src/plugins/bineditor/imageviewer.h index 09be3e18961..b74ad90293f 100644 --- a/src/plugins/bineditor/imageviewer.h +++ b/src/plugins/bineditor/imageviewer.h @@ -70,6 +70,7 @@ public: explicit ImageViewerFile(ImageViewer *parent = 0); bool save(const QString &fileName = QString()) { Q_UNUSED(fileName); return false; } + void rename(const QString &newName) { m_fileName = newName; } QString fileName() const { return m_fileName; } QString defaultPath() const { return QString(); } diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 7e92e0140cd..283d07624cf 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -595,6 +595,13 @@ bool CMakeFile::isSaveAsAllowed() const return false; } +void CMakeFile::rename(const QString &newName) +{ + Q_ASSERT(false); + Q_UNUSED(newName); + // Can't happen.... +} + Core::IFile::ReloadBehavior CMakeFile::reloadBehavior(ChangeTrigger state, ChangeType type) const { Q_UNUSED(state) diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.h b/src/plugins/cmakeprojectmanager/cmakeproject.h index 3f383cc9dce..36f394595bf 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.h +++ b/src/plugins/cmakeprojectmanager/cmakeproject.h @@ -196,6 +196,8 @@ public: ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const; void reload(ReloadFlag flag, ChangeType type); + void rename(const QString &newName); + private: CMakeProject *m_project; QString m_fileName; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp index 4d98025af8e..ce2e2d4574e 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp @@ -43,8 +43,9 @@ bool CMakeProjectNode::hasBuildTargets() const return true; } -QList<ProjectExplorer::ProjectNode::ProjectAction> CMakeProjectNode::supportedActions() const +QList<ProjectExplorer::ProjectNode::ProjectAction> CMakeProjectNode::supportedActions(Node *node) const { + Q_UNUSED(node); return QList<ProjectAction>(); } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h index dbb6250afe7..6a75e1da60f 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.h @@ -42,7 +42,7 @@ class CMakeProjectNode : public ProjectExplorer::ProjectNode public: CMakeProjectNode(const QString &fileName); virtual bool hasBuildTargets() const; - virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions() const; + virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions(Node *node) const; virtual bool addSubProjects(const QStringList &proFilePaths); virtual bool removeSubProjects(const QStringList &proFilePaths); virtual bool addFiles(const ProjectExplorer::FileType fileType, diff --git a/src/plugins/coreplugin/filemanager.cpp b/src/plugins/coreplugin/filemanager.cpp index b38b5228476..61c2223b7fe 100644 --- a/src/plugins/coreplugin/filemanager.cpp +++ b/src/plugins/coreplugin/filemanager.cpp @@ -123,6 +123,11 @@ struct FileManagerPrivate { QString m_lastVisitedDirectory; QString m_projectsDirectory; bool m_useProjectsDirectory; + // When we are callling into a IFile + // we don't want to receive a changed() + // signal + // That makes the code easier + IFile *m_blockedIFile; }; FileManagerPrivate::FileManagerPrivate(QObject *q, QMainWindow *mw) : @@ -131,10 +136,11 @@ FileManagerPrivate::FileManagerPrivate(QObject *q, QMainWindow *mw) : m_blockActivated(false), m_lastVisitedDirectory(QDir::currentPath()), #ifdef Q_OS_MAC // Creator is in bizarre places when launched via finder. - m_useProjectsDirectory(true) + m_useProjectsDirectory(true), #else - m_useProjectsDirectory(false) + m_useProjectsDirectory(false), #endif + m_blockedIFile(0) { } @@ -252,6 +258,55 @@ void FileManager::updateFileInfo(IFile *file) d->m_states[fixedname].lastUpdatedState.insert(file, item); } +/// Dumps the state of the file manager's map +/// For debugging purposes +void FileManager::dump() +{ + QMap<QString, Internal::FileState>::const_iterator it, end; + it = d->m_states.constBegin(); + end = d->m_states.constEnd(); + for (; it != end; ++it) { + qDebug()<<" "; + qDebug() << it.key(); + qDebug() << it.value().expected.modified; + + QMap<IFile *, Internal::FileStateItem>::const_iterator jt, jend; + jt = it.value().lastUpdatedState.constBegin(); + jend = it.value().lastUpdatedState.constEnd(); + for (; jt != jend; ++jt) { + qDebug() << jt.key() << jt.value().modified; + } + } +} + +void FileManager::renamedFile(const QString &from, QString &to) +{ + QString fixedFrom = fixFileName(from); + QString fixedTo = fixFileName(to); + if (d->m_states.contains(fixedFrom)) { + QTC_ASSERT(!d->m_states.contains(to), return); + d->m_states.insert(fixedTo, d->m_states.value(fixedFrom)); + d->m_states.remove(fixedFrom); + QFileInfo fi(to); + d->m_states[fixedTo].expected.modified = fi.lastModified(); + d->m_states[fixedTo].expected.permissions = fi.permissions(); + + d->m_fileWatcher->removePath(fixedFrom); + d->m_fileWatcher->addPath(fixedTo); + + QMap<IFile *, Internal::FileStateItem>::iterator it, end; + it = d->m_states[fixedTo].lastUpdatedState.begin(); + end = d->m_states[fixedTo].lastUpdatedState.end(); + + for ( ; it != end; ++it) { + d->m_blockedIFile = it.key(); + it.key()->rename(to); + d->m_blockedIFile = it.key(); + it.value().modified = fi.lastModified(); + } + } +} + /// /// Does not use file->fileName, as such is save to use /// with renamed files and deleted files @@ -336,6 +391,10 @@ bool FileManager::removeFile(IFile *file) void FileManager::checkForNewFileName() { IFile *file = qobject_cast<IFile *>(sender()); + // We modified the IFile + // Trust the other code to also update the m_states map + if (file == d->m_blockedIFile) + return; QTC_ASSERT(file, return); const QString &fileName = fixFileName(file->fileName()); @@ -751,6 +810,7 @@ void FileManager::checkForReload() end = lastUpdated.constEnd(); for ( ; it != end; ++it) { IFile *file = it.key(); + d->m_blockedIFile = file; // Compare if (it.value().modified == fi.lastModified() && it.value().permissions == fi.permissions()) { @@ -832,6 +892,7 @@ void FileManager::checkForReload() } updateFileInfo(file); + d->m_blockedIFile = 0; } } diff --git a/src/plugins/coreplugin/filemanager.h b/src/plugins/coreplugin/filemanager.h index 4f5e3d8f2c8..9834bce17e5 100644 --- a/src/plugins/coreplugin/filemanager.h +++ b/src/plugins/coreplugin/filemanager.h @@ -63,6 +63,8 @@ public: bool isFileManaged(const QString &fileName) const; QList<IFile *> modifiedFiles() const; + void renamedFile(const QString &from, QString &to); + void blockFileChange(IFile *file); void unblockFileChange(IFile *file); @@ -74,6 +76,7 @@ public: QStringList recentFiles() const; void saveRecentFiles(); + // current file void setCurrentFile(const QString &filePath); QString currentFile() const; @@ -128,6 +131,7 @@ private slots: void syncWithEditor(Core::IContext *context); private: + void dump(); void addFileInfo(IFile *file); void removeFileInfo(IFile *file); void removeFileInfo(const QString &fileName, IFile *file); diff --git a/src/plugins/coreplugin/ifile.h b/src/plugins/coreplugin/ifile.h index 575cac9488c..42da335a92a 100644 --- a/src/plugins/coreplugin/ifile.h +++ b/src/plugins/coreplugin/ifile.h @@ -87,6 +87,7 @@ public: virtual ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const = 0; virtual void reload(ReloadFlag flag, ChangeType type) = 0; + virtual void rename(const QString &newName) = 0; virtual void checkPermissions() {} diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index 13b43a687ad..8fe0bc038e0 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -42,7 +42,7 @@ class CORE_EXPORT IVersionControl : public QObject Q_OBJECT public: enum Operation { - AddOperation, DeleteOperation, OpenOperation, + AddOperation, DeleteOperation, OpenOperation, MoveOperation, CreateRepositoryOperation, SnapshotOperations, AnnotateOperation @@ -101,6 +101,12 @@ public: */ virtual bool vcsDelete(const QString &filename) = 0; + /*! + * Called to rename a file, should do the actual on disk renaming + * (e.g. git mv, svn move, p4 move) + */ + virtual bool vcsMove(const QString &from, const QString &to) = 0; + /*! * Called to initialize the version control system in a directory. */ diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp index 33e08c03a05..f9205453883 100644 --- a/src/plugins/cvs/cvscontrol.cpp +++ b/src/plugins/cvs/cvscontrol.cpp @@ -54,6 +54,7 @@ bool CVSControl::supportsOperation(Operation operation) const case DeleteOperation: case AnnotateOperation: break; + case MoveOperation: case OpenOperation: case CreateRepositoryOperation: case SnapshotOperations: @@ -81,6 +82,11 @@ bool CVSControl::vcsDelete(const QString &fileName) return m_plugin->vcsDelete(fi.absolutePath(), fi.fileName()); } +bool CVSControl::vcsMove(const QString &from, const QString &to) +{ + return false; +} + bool CVSControl::vcsCreateRepository(const QString &) { return false; diff --git a/src/plugins/cvs/cvscontrol.h b/src/plugins/cvs/cvscontrol.h index 24483afed33..38a8ccfe8e7 100644 --- a/src/plugins/cvs/cvscontrol.h +++ b/src/plugins/cvs/cvscontrol.h @@ -52,6 +52,7 @@ public: virtual bool vcsOpen(const QString &fileName); virtual bool vcsAdd(const QString &fileName); virtual bool vcsDelete(const QString &filename); + virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); virtual QStringList vcsSnapshots(const QString &topLevel); diff --git a/src/plugins/designer/formwindoweditor.cpp b/src/plugins/designer/formwindoweditor.cpp index 6f1f55e91d4..895ac3aae16 100644 --- a/src/plugins/designer/formwindoweditor.cpp +++ b/src/plugins/designer/formwindoweditor.cpp @@ -81,6 +81,7 @@ FormWindowEditor::FormWindowEditor(Internal::DesignerXmlEditor *editor, connect(&(d->m_file), SIGNAL(reload(QString)), this, SLOT(slotOpen(QString))); // Force update of open editors model. connect(&(d->m_file), SIGNAL(saved()), this, SIGNAL(changed())); + connect(&(d->m_file), SIGNAL(changed()), this, SIGNAL(changed())); } FormWindowEditor::~FormWindowEditor() diff --git a/src/plugins/designer/formwindowfile.cpp b/src/plugins/designer/formwindowfile.cpp index a130cc9d680..ce5594e2fe9 100644 --- a/src/plugins/designer/formwindowfile.cpp +++ b/src/plugins/designer/formwindowfile.cpp @@ -91,6 +91,15 @@ bool FormWindowFile::save(const QString &name /*= QString()*/) return true; } +void FormWindowFile::rename(const QString &newName) +{ + m_formWindow->setFileName(newName); + QFileInfo fi(newName); + m_fileName = fi.absoluteFilePath(); + emit setDisplayName(fi.fileName()); + emit changed(); +} + QString FormWindowFile::fileName() const { return m_fileName; diff --git a/src/plugins/designer/formwindowfile.h b/src/plugins/designer/formwindowfile.h index 92dbc236950..42d44c78bad 100644 --- a/src/plugins/designer/formwindowfile.h +++ b/src/plugins/designer/formwindowfile.h @@ -60,6 +60,7 @@ public: virtual QString defaultPath() const; virtual QString suggestedFileName() const; virtual QString mimeType() const; + virtual void rename(const QString &newName); // Internal void setSuggestedFileName(const QString &fileName); diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 1fa74df191b..ef224384f7d 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -591,6 +591,13 @@ bool GenericProjectFile::isSaveAsAllowed() const return false; } +void GenericProjectFile::rename(const QString &newName) +{ + // Can't happen + Q_UNUSED(newName); + Q_ASSERT(false); +} + Core::IFile::ReloadBehavior GenericProjectFile::reloadBehavior(ChangeTrigger state, ChangeType type) const { Q_UNUSED(state) diff --git a/src/plugins/genericprojectmanager/genericproject.h b/src/plugins/genericprojectmanager/genericproject.h index 8e7b0bd02ba..d912192fb08 100644 --- a/src/plugins/genericprojectmanager/genericproject.h +++ b/src/plugins/genericprojectmanager/genericproject.h @@ -161,6 +161,7 @@ public: virtual bool isModified() const; virtual bool isReadOnly() const; virtual bool isSaveAsAllowed() const; + virtual void rename(const QString &newName); ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const; void reload(ReloadFlag flag, ChangeType type); diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.cpp b/src/plugins/genericprojectmanager/genericprojectnodes.cpp index 2a2397ecfbb..26b15932e3d 100644 --- a/src/plugins/genericprojectmanager/genericprojectnodes.cpp +++ b/src/plugins/genericprojectmanager/genericprojectnodes.cpp @@ -170,8 +170,9 @@ bool GenericProjectNode::hasBuildTargets() const return true; } -QList<ProjectExplorer::ProjectNode::ProjectAction> GenericProjectNode::supportedActions() const +QList<ProjectExplorer::ProjectNode::ProjectAction> GenericProjectNode::supportedActions(Node *node) const { + Q_UNUSED(node); return QList<ProjectAction>() << AddFile << RemoveFile; diff --git a/src/plugins/genericprojectmanager/genericprojectnodes.h b/src/plugins/genericprojectmanager/genericprojectnodes.h index 272785d84a2..39859a88c92 100644 --- a/src/plugins/genericprojectmanager/genericprojectnodes.h +++ b/src/plugins/genericprojectmanager/genericprojectnodes.h @@ -55,7 +55,7 @@ public: virtual bool hasBuildTargets() const; - virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions() const; + virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions(Node *node) const; virtual bool addSubProjects(const QStringList &proFilePaths); virtual bool removeSubProjects(const QStringList &proFilePaths); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 242e42db45a..8984813632c 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -525,6 +525,27 @@ bool GitClient::synchronousDelete(const QString &workingDirectory, return rc; } +bool GitClient::synchronousMove(const QString &workingDirectory, + const QString &from, + const QString &to) +{ + if (Git::Constants::debug) + qDebug() << Q_FUNC_INFO << workingDirectory << from << to; + QByteArray outputText; + QByteArray errorText; + QStringList arguments; + arguments << QLatin1String("mv"); + arguments << (from); + arguments << (to); + const bool rc = synchronousGit(workingDirectory, arguments, &outputText, &errorText); + if (!rc) { + const QString errorMessage = tr("Unable to move from %1 to %2: %3"). + arg(from, to, commandOutputFromLocal8Bit(errorText)); + outputWindow()->appendError(errorMessage); + } + return rc; +} + bool GitClient::synchronousReset(const QString &workingDirectory, const QStringList &files, QString *errorMessage) diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 99f95fd6e01..3f0d0dede7e 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -101,6 +101,9 @@ public: bool synchronousDelete(const QString &workingDirectory, bool force, const QStringList &files); + bool synchronousMove(const QString &workingDirectory, + const QString &from, + const QString &to); bool synchronousReset(const QString &workingDirectory, const QStringList &files = QStringList(), QString *errorMessage = 0); diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp index 07ff9521343..65a46e492e1 100644 --- a/src/plugins/git/gitversioncontrol.cpp +++ b/src/plugins/git/gitversioncontrol.cpp @@ -75,6 +75,9 @@ bool GitVersionControl::supportsOperation(Operation operation) const case DeleteOperation: rc = true; break; + case MoveOperation: + rc = true; + break; case OpenOperation: break; case CreateRepositoryOperation: @@ -107,6 +110,13 @@ bool GitVersionControl::vcsDelete(const QString & fileName) return gitClient()->synchronousDelete(fi.absolutePath(), true, QStringList(fi.fileName())); } +bool GitVersionControl::vcsMove(const QString &from, const QString &to) +{ + const QFileInfo fromInfo(from); + const QFileInfo toInfo(to); + return gitClient()->synchronousMove(fromInfo.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); +} + bool GitVersionControl::vcsCreateRepository(const QString &directory) { return gitClient()->synchronousInit(directory); diff --git a/src/plugins/git/gitversioncontrol.h b/src/plugins/git/gitversioncontrol.h index c53c1f2ab5c..098d8bef528 100644 --- a/src/plugins/git/gitversioncontrol.h +++ b/src/plugins/git/gitversioncontrol.h @@ -53,6 +53,7 @@ public: virtual bool vcsOpen(const QString &fileName); virtual bool vcsAdd(const QString &fileName); virtual bool vcsDelete(const QString &filename); + virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); virtual QStringList vcsSnapshots(const QString &topLevel); diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index c798e538822..9a4bbabb856 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -95,6 +95,14 @@ bool MercurialClient::remove(const QString &workingDir, const QString &filename) return executeHgSynchronously(workingDir, args, &stdOut); } +bool MercurialClient::move(const QString &workingDir, const QString &from, const QString &to) +{ + QStringList args; + args << QLatin1String("rename") << from << to; + QByteArray stdOut; + return executeHgSynchronously(workingDir, args, &stdOut); +} + bool MercurialClient::manifestSync(const QString &repository, const QString &relativeFilename) { // This only works when called from the repo and outputs paths relative to it. diff --git a/src/plugins/mercurial/mercurialclient.h b/src/plugins/mercurial/mercurialclient.h index 9e0daabc7eb..215b24f79b0 100644 --- a/src/plugins/mercurial/mercurialclient.h +++ b/src/plugins/mercurial/mercurialclient.h @@ -62,6 +62,7 @@ public: ~MercurialClient(); bool add(const QString &workingDir, const QString &fileName); bool remove(const QString &workingDir, const QString &fileName); + bool move(const QString &workingDir, const QString &from, const QString &to); bool manifestSync(const QString &repository, const QString &filename); QString branchQuerySync(const QString &repositoryRoot); bool parentRevisionsSync(const QString &workingDirectory, diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp index 1b707b9c8b7..e8cf97e1fbd 100644 --- a/src/plugins/mercurial/mercurialcontrol.cpp +++ b/src/plugins/mercurial/mercurialcontrol.cpp @@ -65,6 +65,7 @@ bool MercurialControl::supportsOperation(Operation operation) const switch (operation) { case Core::IVersionControl::AddOperation: case Core::IVersionControl::DeleteOperation: + case Core::IVersionControl::MoveOperation: case Core::IVersionControl::CreateRepositoryOperation: case Core::IVersionControl::AnnotateOperation: break; @@ -94,6 +95,13 @@ bool MercurialControl::vcsDelete(const QString &filename) return mercurialClient->remove(fi.absolutePath(), fi.fileName()); } +bool MercurialControl::vcsMove(const QString &from, const QString &to) +{ + const QFileInfo fromInfo(from); + const QFileInfo toInfo(to); + return mercurialClient->move(fromInfo.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); +} + bool MercurialControl::vcsCreateRepository(const QString &directory) { return mercurialClient->createRepositorySync(directory); diff --git a/src/plugins/mercurial/mercurialcontrol.h b/src/plugins/mercurial/mercurialcontrol.h index b6ee396b1c7..02be0951bbc 100644 --- a/src/plugins/mercurial/mercurialcontrol.h +++ b/src/plugins/mercurial/mercurialcontrol.h @@ -56,6 +56,7 @@ public: bool vcsOpen(const QString &fileName); bool vcsAdd(const QString &filename); bool vcsDelete(const QString &filename); + bool vcsMove(const QString &from, const QString &to); bool vcsCreateRepository(const QString &directory); QString vcsCreateSnapshot(const QString &topLevel); QStringList vcsSnapshots(const QString &topLevel); diff --git a/src/plugins/perforce/perforceplugin.cpp b/src/plugins/perforce/perforceplugin.cpp index eef5f6827b1..fefa63b6756 100644 --- a/src/plugins/perforce/perforceplugin.cpp +++ b/src/plugins/perforce/perforceplugin.cpp @@ -925,6 +925,22 @@ bool PerforcePlugin::vcsDelete(const QString &workingDir, const QString &fileNam return !deleteResult.error; } +bool PerforcePlugin::vcsMove(const QString &workingDir, const QString &from, const QString &to) +{ + // TODO verify this works + QStringList args; + args << QLatin1String("edit") << from; + const PerforceResponse editResult = runP4Cmd(workingDir, args, + CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow); + if (editResult.error) + return false; + args.clear(); + args << QLatin1String("move") << from << to; + const PerforceResponse moveResult = runP4Cmd(workingDir, args, + CommandToWindow|StdOutToWindow|StdErrToWindow|ErrorToWindow); + return !moveResult.error; +} + static QString formatCommand(const QString &cmd, const QStringList &args) { const QChar blank = QLatin1Char(' '); diff --git a/src/plugins/perforce/perforceplugin.h b/src/plugins/perforce/perforceplugin.h index 7c88baef1a9..feddd2bcf6a 100644 --- a/src/plugins/perforce/perforceplugin.h +++ b/src/plugins/perforce/perforceplugin.h @@ -89,6 +89,7 @@ public: bool vcsOpen(const QString &workingDir, const QString &fileName); bool vcsAdd(const QString &workingDir, const QString &fileName); bool vcsDelete(const QString &workingDir, const QString &filename); + bool vcsMove(const QString &workingDir, const QString &from, const QString &to); void p4Diff(const QString &workingDir, const QStringList &files); diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp index ecd75e7bfdf..e715fa7ec8a 100644 --- a/src/plugins/perforce/perforceversioncontrol.cpp +++ b/src/plugins/perforce/perforceversioncontrol.cpp @@ -53,6 +53,7 @@ bool PerforceVersionControl::supportsOperation(Operation operation) const switch (operation) { case AddOperation: case DeleteOperation: + case MoveOperation: case OpenOperation: case AnnotateOperation: return true; @@ -81,6 +82,13 @@ bool PerforceVersionControl::vcsDelete(const QString &fileName) return m_plugin->vcsDelete(fi.absolutePath(), fi.fileName()); } +bool PerforceVersionControl::vcsMove(const QString &from, const QString &to) +{ + const QFileInfo fromInfo(from); + const QFileInfo toInfo(to); + return m_plugin->vcsMove(fromInfo.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); +} + bool PerforceVersionControl::vcsCreateRepository(const QString &) { return false; diff --git a/src/plugins/perforce/perforceversioncontrol.h b/src/plugins/perforce/perforceversioncontrol.h index 5be2ac9826b..9fe43af676c 100644 --- a/src/plugins/perforce/perforceversioncontrol.h +++ b/src/plugins/perforce/perforceversioncontrol.h @@ -52,6 +52,7 @@ public: virtual bool vcsOpen(const QString &fileName); virtual bool vcsAdd(const QString &fileName); virtual bool vcsDelete(const QString &filename); + virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); virtual QStringList vcsSnapshots(const QString &topLevel); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 0f576fd9bd1..aa214c455f2 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -690,13 +690,15 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er globalcontext); mfilec->addAction(cmd, Constants::G_FILE_OTHER); - // renamefile action (TODO: Not supported yet) + // renamefile action d->m_renameFileAction = new QAction(tr("Rename"), this); cmd = am->registerAction(d->m_renameFileAction, ProjectExplorer::Constants::RENAMEFILE, globalcontext); mfilec->addAction(cmd, Constants::G_FILE_OTHER); - d->m_renameFileAction->setEnabled(false); - d->m_renameFileAction->setVisible(false); + // Not yet used by anyone, so hide for now +// mfolder->addAction(cmd, Constants::G_FOLDER_FILES); +// msubProject->addAction(cmd, Constants::G_FOLDER_FILES); +// mproject->addAction(cmd, Constants::G_FOLDER_FILES); // target selector d->m_projectSelectorAction = new QAction(this); @@ -1232,7 +1234,7 @@ void ProjectExplorerPlugin::showContextMenu(const QPoint &globalPos, Node *node) contextMenu = d->m_sessionContextMenu; } - updateContextMenuActions(); + updateContextMenuActions(d->m_currentNode); if (contextMenu && contextMenu->actions().count() > 0) { contextMenu->popup(globalPos); } @@ -1915,19 +1917,24 @@ void ProjectExplorerPlugin::goToTaskWindow() d->m_buildManager->gotoTaskWindow(); } -void ProjectExplorerPlugin::updateContextMenuActions() +void ProjectExplorerPlugin::updateContextMenuActions(Node *node) { d->m_addExistingFilesAction->setEnabled(false); d->m_addNewFileAction->setEnabled(false); d->m_removeFileAction->setEnabled(false); - if (FolderNode *folderNode = qobject_cast<FolderNode*>(d->m_currentNode)) { - const bool addFilesEnabled = folderNode->projectNode()->supportedActions().contains(ProjectNode::AddFile); + QList<ProjectNode::ProjectAction> actions = + d->m_currentNode->projectNode()->supportedActions(node); + + if (qobject_cast<FolderNode*>(d->m_currentNode)) { + bool addFilesEnabled = actions.contains(ProjectNode::AddFile); d->m_addExistingFilesAction->setEnabled(addFilesEnabled); d->m_addNewFileAction->setEnabled(addFilesEnabled); - } else if (FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode)) { - const bool removeFileEnabled = fileNode->projectNode()->supportedActions().contains(ProjectNode::RemoveFile); + d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename)); + } else if (qobject_cast<FileNode*>(d->m_currentNode)) { + bool removeFileEnabled = actions.contains(ProjectNode::RemoveFile); d->m_removeFileAction->setEnabled(removeFileEnabled); + d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename)); } } @@ -2025,8 +2032,7 @@ void ProjectExplorerPlugin::removeFile() FileNode *fileNode = qobject_cast<FileNode*>(d->m_currentNode); Core::ICore *core = Core::ICore::instance(); - const QString filePath = d->m_currentNode->path(); - const QString fileDir = QFileInfo(filePath).dir().absolutePath(); + QString filePath = d->m_currentNode->path(); RemoveFileDialog removeFileDialog(filePath, core->mainWindow()); if (removeFileDialog.exec() == QDialog::Accepted) { @@ -2072,6 +2078,31 @@ void ProjectExplorerPlugin::renameFile() } } +void ProjectExplorerPlugin::renameFile(Node *node, const QString &to) +{ + FileNode *fileNode = qobject_cast<FileNode *>(node); + if (!fileNode) + return; + QString orgFilePath = node->path(); + QString dir = QFileInfo(orgFilePath).absolutePath(); + QString newFilePath = dir + "/" + to; + Core::ICore *core = Core::ICore::instance(); + Core::IVersionControl *vc = core->vcsManager()->findVersionControlForDirectory(dir); + bool result = false; + if (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 = QFile::rename(orgFilePath, newFilePath); + if (result) { + // yeah we moved, tell the filemanager about it + Core::ICore::instance()->fileManager()->renamedFile(orgFilePath, newFilePath); + // Tell the project plugin about it + ProjectNode *projectNode = fileNode->projectNode(); + projectNode->renameFile(fileNode->fileType(), orgFilePath, newFilePath); + // TODO emit a signal? + } +} + void ProjectExplorerPlugin::populateOpenWithMenu(QMenu *menu, const QString &fileName) { typedef QList<Core::IEditorFactory*> EditorFactoryList; diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index 8ed599bf966..8d277ca2845 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -107,6 +107,9 @@ public: void startRunControl(RunControl *runControl, const QString &mode); + // internal public for FlatModel + void renameFile(Node *node, const QString &to); + signals: void aboutToShowContextMenu(ProjectExplorer::Project *project, ProjectExplorer::Node *node); @@ -159,7 +162,7 @@ private slots: void savePersistentSettings(); void goToTaskWindow(); - void updateContextMenuActions(); + void updateContextMenuActions(Node *node); void addNewFile(); void addExistingFiles(); void openFile(); diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro index a3ff46b692e..03c66f7da21 100644 --- a/src/plugins/projectexplorer/projectexplorer.pro +++ b/src/plugins/projectexplorer/projectexplorer.pro @@ -41,7 +41,6 @@ HEADERS += projectexplorer.h \ buildsettingspropertiespage.h \ environmenteditmodel.h \ processstep.h \ - abstractprocessstep.h \ editorconfiguration.h \ editorsettingspropertiespage.h \ runconfiguration.h \ @@ -82,7 +81,8 @@ HEADERS += projectexplorer.h \ linuxiccparser.h \ outputformatter.h \ runconfigurationmodel.h \ - buildconfigurationmodel.h + buildconfigurationmodel.h \ + abstractprocessstep.h SOURCES += projectexplorer.cpp \ projectwindow.cpp \ buildmanager.cpp \ diff --git a/src/plugins/projectexplorer/projectfilewizardextension.cpp b/src/plugins/projectexplorer/projectfilewizardextension.cpp index 44836237893..8acb805715a 100644 --- a/src/plugins/projectexplorer/projectfilewizardextension.cpp +++ b/src/plugins/projectexplorer/projectfilewizardextension.cpp @@ -60,7 +60,8 @@ typedef QList<ProjectNode *> ProjectNodeList; namespace Internal { -// AllProjectNodesVisitor: Retrieve all projects (*.pri/*.pro). +// AllProjectNodesVisitor: Retrieve all projects (*.pri/*.pro) +// which support adding files class AllProjectNodesVisitor : public NodesVisitor { public: @@ -81,7 +82,7 @@ ProjectNodeList AllProjectNodesVisitor::allProjects() void AllProjectNodesVisitor::visitProjectNode(ProjectNode *node) { - if (node->supportedActions().contains(ProjectNode::AddFile)) + if (node->supportedActions(node).contains(ProjectNode::AddFile)) m_projectNodes.push_back(node); } diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index 9675d6df61d..0bdb627aa02 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -32,6 +32,7 @@ #include "project.h" #include "projectexplorerconstants.h" #include "projectnodes.h" +#include "projectexplorer.h" #include <coreplugin/fileiconprovider.h> #include <utils/qtcassert.h> @@ -261,6 +262,27 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const return result; } +Qt::ItemFlags FlatModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + // We claim that everything is editable + // That's slightly wrong + // We control the only view, and that one does the checks + return Qt::ItemIsSelectable|Qt::ItemIsEnabled | Qt::ItemIsEditable; +} + +bool FlatModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid()) + return false; + if (role != Qt::EditRole) + return false; + + ProjectExplorerPlugin::instance()->renameFile(nodeForIndex(index), value.toString()); + return true; +} + int FlatModel::rowCount(const QModelIndex &parent) const { int rows = 0; diff --git a/src/plugins/projectexplorer/projectmodels.h b/src/plugins/projectexplorer/projectmodels.h index 9943c004bb8..810c6d50f52 100644 --- a/src/plugins/projectexplorer/projectmodels.h +++ b/src/plugins/projectexplorer/projectmodels.h @@ -43,7 +43,8 @@ class SessionNode; namespace Internal { -class FlatModel : public QAbstractItemModel { +class FlatModel : public QAbstractItemModel +{ Q_OBJECT public: FlatModel(SessionNode *rootNode, QObject *parent); @@ -52,6 +53,8 @@ public: QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, int role); int rowCount(const QModelIndex & parent = QModelIndex()) const; int columnCount(const QModelIndex & parent = QModelIndex()) const; diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 64d49e4b39b..3a4511e8b54 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -159,7 +159,8 @@ public: AddSubProject, RemoveSubProject, AddFile, - RemoveFile + RemoveFile, + Rename }; // all subFolders that are projects @@ -169,7 +170,7 @@ public: // TODO find a better name virtual bool hasBuildTargets() const = 0; - virtual QList<ProjectAction> supportedActions() const = 0; + virtual QList<ProjectAction> supportedActions(Node *node) const = 0; virtual bool addSubProjects(const QStringList &proFilePaths) = 0; diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp index b4794bd57a3..78d11fdbdb6 100644 --- a/src/plugins/projectexplorer/session.cpp +++ b/src/plugins/projectexplorer/session.cpp @@ -68,7 +68,7 @@ namespace { namespace ProjectExplorer { namespace Internal { - class SessionFile : QObject +class SessionFile : QObject { Q_OBJECT diff --git a/src/plugins/qmlprojectmanager/qmlprojectfile.cpp b/src/plugins/qmlprojectmanager/qmlprojectfile.cpp index 3bc827879f2..c3f30256cb6 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectfile.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectfile.cpp @@ -48,6 +48,13 @@ bool QmlProjectFile::save(const QString &) return false; } +void QmlProjectFile::rename(const QString &newName) +{ + // Can't happen... + Q_UNUSED(newName); + Q_ASSERT(false); +} + QString QmlProjectFile::fileName() const { return m_fileName; diff --git a/src/plugins/qmlprojectmanager/qmlprojectfile.h b/src/plugins/qmlprojectmanager/qmlprojectfile.h index b01c4f76bd8..4a493b842c8 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectfile.h +++ b/src/plugins/qmlprojectmanager/qmlprojectfile.h @@ -48,6 +48,7 @@ public: virtual bool save(const QString &fileName = QString()); virtual QString fileName() const; + virtual void rename(const QString &newName); virtual QString defaultPath() const; virtual QString suggestedFileName() const; diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp index 2569b5a0c1c..313116649b1 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp @@ -172,8 +172,9 @@ bool QmlProjectNode::hasBuildTargets() const return true; } -QList<ProjectExplorer::ProjectNode::ProjectAction> QmlProjectNode::supportedActions() const +QList<ProjectExplorer::ProjectNode::ProjectAction> QmlProjectNode::supportedActions(Node *node) const { + Q_UNUSED(node); QList<ProjectAction> actions; actions.append(AddFile); return actions; diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.h b/src/plugins/qmlprojectmanager/qmlprojectnodes.h index 19adf637f7c..60285cec9ee 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectnodes.h +++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.h @@ -56,7 +56,7 @@ public: virtual bool hasBuildTargets() const; - virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions() const; + virtual QList<ProjectExplorer::ProjectNode::ProjectAction> supportedActions(Node *node) const; virtual bool addSubProjects(const QStringList &proFilePaths); virtual bool removeSubProjects(const QStringList &proFilePaths); diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index 9db7a03b4a4..507824fc173 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -172,6 +172,13 @@ bool Qt4PriFile::save(const QString &fileName) return false; } +void Qt4PriFile::rename(const QString &newName) +{ + // Can't happen + Q_ASSERT(false); + Q_UNUSED(newName); +} + QString Qt4PriFile::fileName() const { return m_priFile->path(); @@ -537,7 +544,7 @@ void Qt4PriFileNode::update(ProFile *includeFileExact, ProFileReader *readerExac contents.updateSubFolders(this, this); } -QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions() const +QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions(Node *node) const { QList<ProjectAction> actions; @@ -558,6 +565,11 @@ QList<ProjectNode::ProjectAction> Qt4PriFileNode::supportedActions() const default: break; } + + FileNode *fileNode = qobject_cast<FileNode *>(node); + if (fileNode && fileNode->fileType() != ProjectExplorer::ProjectFileType) + actions << Rename; + return actions; } @@ -600,9 +612,6 @@ bool Qt4PriFileNode::renameFile(const FileType fileType, const QString &filePath if (newFilePath.isEmpty()) return false; - if (!QFile::rename(filePath, newFilePath)) - return false; - QStringList dummy; changeFiles(fileType, QStringList() << filePath, &dummy, RemoveFromProFile); if (!dummy.isEmpty()) diff --git a/src/plugins/qt4projectmanager/qt4nodes.h b/src/plugins/qt4projectmanager/qt4nodes.h index a9585d88379..b35f687b44c 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.h +++ b/src/plugins/qt4projectmanager/qt4nodes.h @@ -105,6 +105,7 @@ public: Qt4PriFile(Qt4PriFileNode *qt4PriFile); virtual bool save(const QString &fileName = QString()); virtual QString fileName() const; + virtual void rename(const QString &newName); virtual QString defaultPath() const; virtual QString suggestedFileName() const; @@ -133,7 +134,7 @@ public: // ProjectNode interface - QList<ProjectAction> supportedActions() const; + QList<ProjectAction> supportedActions(Node *node) const; bool hasBuildTargets() const { return false; } diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index e72aca89126..cf3f84d30bb 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -180,6 +180,13 @@ bool Qt4ProjectFile::save(const QString &) return false; } +void Qt4ProjectFile::rename(const QString &newName) +{ + // Can't happen + Q_UNUSED(newName); + Q_ASSERT(false); +} + QString Qt4ProjectFile::fileName() const { return m_filePath; diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h index 84aad0efd18..d64e241707f 100644 --- a/src/plugins/qt4projectmanager/qt4project.h +++ b/src/plugins/qt4projectmanager/qt4project.h @@ -88,6 +88,7 @@ public: bool save(const QString &fileName = QString()); QString fileName() const; + virtual void rename(const QString &newName); QString defaultPath() const; QString suggestedFileName() const; diff --git a/src/plugins/resourceeditor/resourceeditorw.cpp b/src/plugins/resourceeditor/resourceeditorw.cpp index 7fde0e20aef..b923f6ef2b3 100644 --- a/src/plugins/resourceeditor/resourceeditorw.cpp +++ b/src/plugins/resourceeditor/resourceeditorw.cpp @@ -157,6 +157,12 @@ bool ResourceEditorFile::save(const QString &name /*= QString()*/) return true; } +void ResourceEditorFile::rename(const QString &newName) +{ + m_parent->m_resourceEditor->setFileName(newName); + emit changed(); +} + QString ResourceEditorW::id() const { return QLatin1String(ResourceEditor::Constants::RESOURCEEDITOR_ID); } diff --git a/src/plugins/resourceeditor/resourceeditorw.h b/src/plugins/resourceeditor/resourceeditorw.h index bdcba539498..79e11bd3a1a 100644 --- a/src/plugins/resourceeditor/resourceeditorw.h +++ b/src/plugins/resourceeditor/resourceeditorw.h @@ -66,6 +66,7 @@ public: QString defaultPath() const; QString suggestedFileName() const; virtual QString mimeType() const; + virtual void rename(const QString &newName); private: const QString m_mimeType; diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp index c58159ff60b..f7b4648dcb8 100644 --- a/src/plugins/subversion/subversioncontrol.cpp +++ b/src/plugins/subversion/subversioncontrol.cpp @@ -52,6 +52,7 @@ bool SubversionControl::supportsOperation(Operation operation) const switch (operation) { case AddOperation: case DeleteOperation: + case MoveOperation: case AnnotateOperation: break; case OpenOperation: @@ -81,6 +82,13 @@ bool SubversionControl::vcsDelete(const QString &fileName) return m_plugin->vcsDelete(fi.absolutePath(), fi.fileName()); } +bool SubversionControl::vcsMove(const QString &from, const QString &to) +{ + const QFileInfo fromInfo(from); + const QFileInfo toInfo(to); + return m_plugin->vcsMove(fromInfo.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); +} + bool SubversionControl::vcsCreateRepository(const QString &) { return false; diff --git a/src/plugins/subversion/subversioncontrol.h b/src/plugins/subversion/subversioncontrol.h index 132aca4d8ec..8389f822495 100644 --- a/src/plugins/subversion/subversioncontrol.h +++ b/src/plugins/subversion/subversioncontrol.h @@ -52,6 +52,7 @@ public: virtual bool vcsOpen(const QString &fileName); virtual bool vcsAdd(const QString &fileName); virtual bool vcsDelete(const QString &filename); + virtual bool vcsMove(const QString &from, const QString &to); virtual bool vcsCreateRepository(const QString &directory); virtual QString vcsCreateSnapshot(const QString &topLevel); diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 36e60dcc937..b6f56a99a5c 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -1210,6 +1210,16 @@ bool SubversionPlugin::vcsDelete(const QString &workingDir, const QString &rawFi return !response.error; } +bool SubversionPlugin::vcsMove(const QString &workingDir, const QString &from, const QString &to) +{ + QStringList args(QLatin1String("move")); + args << QDir::toNativeSeparators(from) << QDir::toNativeSeparators(to); + qDebug()<<args; + const SubversionResponse response = runSvn(workingDir, args, m_settings.timeOutMS(), true); + qDebug() << response.stdOut << "\n"<<response.stdErr; + return !response.error; +} + /* Subversion has ".svn" directory in each directory * it manages. The top level is the first directory * under the directory that does not have a ".svn". */ diff --git a/src/plugins/subversion/subversionplugin.h b/src/plugins/subversion/subversionplugin.h index 2562895d9bf..a7bb187c56d 100644 --- a/src/plugins/subversion/subversionplugin.h +++ b/src/plugins/subversion/subversionplugin.h @@ -94,6 +94,7 @@ public: bool vcsAdd14(const QString &workingDir, const QString &fileName); bool vcsAdd15(const QString &workingDir, const QString &fileName); bool vcsDelete(const QString &workingDir, const QString &fileName); + bool vcsMove(const QString &workingDir, const QString &from, const QString &to); bool managesDirectory(const QString &directory) const; QString findTopLevelForDirectory(const QString &directory) const; diff --git a/src/plugins/texteditor/basetextdocument.cpp b/src/plugins/texteditor/basetextdocument.cpp index 8035f0291a3..25406e98e06 100644 --- a/src/plugins/texteditor/basetextdocument.cpp +++ b/src/plugins/texteditor/basetextdocument.cpp @@ -205,6 +205,14 @@ bool BaseTextDocument::save(const QString &fileName) return true; } +void BaseTextDocument::rename(const QString &newName) +{ + const QFileInfo fi(newName); + m_fileName = QDir::cleanPath(fi.absoluteFilePath()); + emit titleChanged(fi.fileName()); + emit changed(); +} + bool BaseTextDocument::isReadOnly() const { if (m_isBinaryData || m_hasDecodingError) diff --git a/src/plugins/texteditor/basetextdocument.h b/src/plugins/texteditor/basetextdocument.h index 2958fc3805b..07f32b7c25b 100644 --- a/src/plugins/texteditor/basetextdocument.h +++ b/src/plugins/texteditor/basetextdocument.h @@ -89,6 +89,7 @@ public: void reload(ReloadFlag flag, ChangeType type); virtual QString mimeType() const; void setMimeType(const QString &mt); + virtual void rename(const QString &newName); virtual QString defaultPath() const { return m_defaultPath; } virtual QString suggestedFileName() const { return m_suggestedFileName; } diff --git a/src/plugins/vcsbase/submiteditorfile.cpp b/src/plugins/vcsbase/submiteditorfile.cpp index 949e30c0d93..01eb9dce299 100644 --- a/src/plugins/vcsbase/submiteditorfile.cpp +++ b/src/plugins/vcsbase/submiteditorfile.cpp @@ -39,6 +39,13 @@ SubmitEditorFile::SubmitEditorFile(const QString &mimeType, QObject *parent) : { } +void SubmitEditorFile::rename(const QString &newName) +{ + Q_UNUSED(newName); + // We can't be renamed + return; +} + void SubmitEditorFile::setFileName(const QString name) { m_fileName = name; diff --git a/src/plugins/vcsbase/submiteditorfile.h b/src/plugins/vcsbase/submiteditorfile.h index e5c489c8b53..6e5402c98ab 100644 --- a/src/plugins/vcsbase/submiteditorfile.h +++ b/src/plugins/vcsbase/submiteditorfile.h @@ -54,7 +54,7 @@ public: bool save(const QString &fileName); ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const; void reload(ReloadFlag flag, ChangeType type); - + void rename(const QString &newName); void setFileName(const QString name); void setModified(bool modified = true); -- GitLab