Subversion: Adapt to new VCSBasePlugin.

Remove logic handling several repositories.
This commit is contained in:
Friedemann Kleint
2009-12-08 16:50:27 +01:00
parent 168813e9b1
commit ff1054fc8d
9 changed files with 195 additions and 204 deletions

View File

@@ -115,7 +115,7 @@ GitPlugin::GitPlugin() :
m_blameAction(0), m_blameAction(0),
m_logProjectAction(0), m_logProjectAction(0),
m_undoFileAction(0), m_undoFileAction(0),
m_undoProjectAction(0), m_undoRepositoryAction(0),
m_showAction(0), m_showAction(0),
m_stageAction(0), m_stageAction(0),
m_unstageAction(0), m_unstageAction(0),
@@ -282,10 +282,10 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
connect(m_logProjectAction, SIGNAL(triggered()), this, SLOT(logProject())); connect(m_logProjectAction, SIGNAL(triggered()), this, SLOT(logProject()));
gitContainer->addAction(command); gitContainer->addAction(command);
m_undoProjectAction = new QAction(tr("Undo Project Changes"), this); m_undoRepositoryAction = new QAction(tr("Undo Repository Changes"), this);
command = actionManager->registerAction(m_undoProjectAction, "Git.UndoProject", globalcontext); command = actionManager->registerAction(m_undoRepositoryAction, "Git.UndoRepository", globalcontext);
command->setAttribute(Core::Command::CA_UpdateText); command->setAttribute(Core::Command::CA_UpdateText);
connect(m_undoProjectAction, SIGNAL(triggered()), this, SLOT(undoProjectChanges())); connect(m_undoRepositoryAction, SIGNAL(triggered()), this, SLOT(undoRepositoryChanges()));
gitContainer->addAction(command); gitContainer->addAction(command);
gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Global"), this)); gitContainer->addAction(createSeparator(actionManager, globalcontext, QLatin1String("Git.Sep.Global"), this));
@@ -428,7 +428,7 @@ void GitPlugin::undoFileChanges()
m_gitClient->revert(QStringList(state.currentFile())); m_gitClient->revert(QStringList(state.currentFile()));
} }
void GitPlugin::undoProjectChanges() void GitPlugin::undoRepositoryChanges()
{ {
const VCSBase::VCSBasePluginState state = currentState(); const VCSBase::VCSBasePluginState state = currentState();
QTC_ASSERT(state.hasTopLevel(), return) QTC_ASSERT(state.hasTopLevel(), return)
@@ -669,7 +669,7 @@ void GitPlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as)
m_diffProjectAction->setParameter(projectName); m_diffProjectAction->setParameter(projectName);
m_logProjectAction->setEnabled(projectEnabled); m_logProjectAction->setEnabled(projectEnabled);
m_logProjectAction->setParameter(projectName); m_logProjectAction->setParameter(projectName);
m_undoProjectAction->setEnabled(projectEnabled); m_undoRepositoryAction->setEnabled(projectEnabled);
const bool repositoryEnabled = currentState().hasTopLevel(); const bool repositoryEnabled = currentState().hasTopLevel();
m_statusRepositoryAction->setEnabled(repositoryEnabled); m_statusRepositoryAction->setEnabled(repositoryEnabled);

View File

@@ -95,7 +95,7 @@ private slots:
void blameFile(); void blameFile();
void logProject(); void logProject();
void undoFileChanges(); void undoFileChanges();
void undoProjectChanges(); void undoRepositoryChanges();
void stageFile(); void stageFile();
void unstageFile(); void unstageFile();
@@ -126,7 +126,7 @@ private:
Utils::ParameterAction *m_blameAction; Utils::ParameterAction *m_blameAction;
Utils::ParameterAction *m_logProjectAction; Utils::ParameterAction *m_logProjectAction;
Utils::ParameterAction *m_undoFileAction; Utils::ParameterAction *m_undoFileAction;
QAction *m_undoProjectAction; QAction *m_undoRepositoryAction;
QAction *m_showAction; QAction *m_showAction;
Utils::ParameterAction *m_stageAction; Utils::ParameterAction *m_stageAction;
Utils::ParameterAction *m_unstageAction; Utils::ParameterAction *m_unstageAction;

View File

@@ -30,6 +30,8 @@
#include "subversioncontrol.h" #include "subversioncontrol.h"
#include "subversionplugin.h" #include "subversionplugin.h"
#include <QtCore/QFileInfo>
using namespace Subversion; using namespace Subversion;
using namespace Subversion::Internal; using namespace Subversion::Internal;
@@ -66,12 +68,14 @@ bool SubversionControl::vcsOpen(const QString & /* fileName */)
bool SubversionControl::vcsAdd(const QString &fileName) bool SubversionControl::vcsAdd(const QString &fileName)
{ {
return m_plugin->vcsAdd(fileName); const QFileInfo fi(fileName);
return m_plugin->vcsAdd(fi.absolutePath(), fi.fileName());
} }
bool SubversionControl::vcsDelete(const QString &fileName) bool SubversionControl::vcsDelete(const QString &fileName)
{ {
return m_plugin->vcsDelete(fileName); const QFileInfo fi(fileName);
return m_plugin->vcsDelete(fi.absolutePath(), fi.fileName());
} }
bool SubversionControl::managesDirectory(const QString &directory) const bool SubversionControl::managesDirectory(const QString &directory) const

View File

@@ -28,6 +28,7 @@
**************************************************************************/ **************************************************************************/
#include "subversioneditor.h" #include "subversioneditor.h"
#include "subversionplugin.h"
#include "annotationhighlighter.h" #include "annotationhighlighter.h"
#include "subversionconstants.h" #include "subversionconstants.h"
@@ -36,6 +37,7 @@
#include <vcsbase/diffhighlighter.h> #include <vcsbase/diffhighlighter.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QFileInfo>
#include <QtGui/QTextCursor> #include <QtGui/QTextCursor>
using namespace Subversion; using namespace Subversion;
@@ -127,9 +129,10 @@ QString SubversionEditor::fileNameFromDiffSpecification(const QTextBlock &inBloc
const int tabIndex = diffFileName.lastIndexOf(QLatin1Char('\t')); const int tabIndex = diffFileName.lastIndexOf(QLatin1Char('\t'));
if (tabIndex != -1) if (tabIndex != -1)
diffFileName.truncate(tabIndex); diffFileName.truncate(tabIndex);
const QString rc = findDiffFile(diffFileName, SubversionPlugin::subversionPluginInstance()->versionControl());
if (Subversion::Constants::debug) if (Subversion::Constants::debug)
qDebug() << Q_FUNC_INFO << diffFileName; qDebug() << Q_FUNC_INFO << diffFileName << rc << source();
return diffFileName; return rc;
} }
} }
return QString(); return QString();

View File

@@ -52,9 +52,6 @@
#include <coreplugin/uniqueidmanager.h> #include <coreplugin/uniqueidmanager.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/session.h>
#include <projectexplorer/project.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
@@ -182,7 +179,6 @@ SubversionPlugin *SubversionPlugin::m_subversionPluginInstance = 0;
SubversionPlugin::SubversionPlugin() : SubversionPlugin::SubversionPlugin() :
VCSBase::VCSBasePlugin(QLatin1String(Subversion::Constants::SUBVERSIONCOMMITEDITOR_KIND)), VCSBase::VCSBasePlugin(QLatin1String(Subversion::Constants::SUBVERSIONCOMMITEDITOR_KIND)),
m_svnDirectories(svnDirectories()), m_svnDirectories(svnDirectories()),
m_projectExplorer(0),
m_addAction(0), m_addAction(0),
m_deleteAction(0), m_deleteAction(0),
m_revertAction(0), m_revertAction(0),
@@ -192,7 +188,7 @@ SubversionPlugin::SubversionPlugin() :
m_commitCurrentAction(0), m_commitCurrentAction(0),
m_filelogCurrentAction(0), m_filelogCurrentAction(0),
m_annotateCurrentAction(0), m_annotateCurrentAction(0),
m_statusAction(0), m_statusProjectAction(0),
m_updateProjectAction(0), m_updateProjectAction(0),
m_describeAction(0), m_describeAction(0),
m_submitCurrentLogAction(0), m_submitCurrentLogAction(0),
@@ -214,6 +210,7 @@ void SubversionPlugin::cleanCommitMessageFile()
if (!m_commitMessageFileName.isEmpty()) { if (!m_commitMessageFileName.isEmpty()) {
QFile::remove(m_commitMessageFileName); QFile::remove(m_commitMessageFileName);
m_commitMessageFileName.clear(); m_commitMessageFileName.clear();
m_commitRepository.clear();
} }
} }
@@ -306,9 +303,10 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *e
subversionMenu->addAction(createSeparator(this, ami, CMD_ID_SEPARATOR0, globalcontext)); subversionMenu->addAction(createSeparator(this, ami, CMD_ID_SEPARATOR0, globalcontext));
m_diffProjectAction = new QAction(tr("Diff Project"), this); m_diffProjectAction = new Utils::ParameterAction(tr("Diff Project"), tr("Diff Project \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
command = ami->registerAction(m_diffProjectAction, CMD_ID_DIFF_PROJECT, command = ami->registerAction(m_diffProjectAction, CMD_ID_DIFF_PROJECT,
globalcontext); globalcontext);
command->setAttribute(Core::Command::CA_UpdateText);
connect(m_diffProjectAction, SIGNAL(triggered()), this, SLOT(diffProject())); connect(m_diffProjectAction, SIGNAL(triggered()), this, SLOT(diffProject()));
subversionMenu->addAction(command); subversionMenu->addAction(command);
@@ -361,15 +359,17 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *e
subversionMenu->addAction(createSeparator(this, ami, CMD_ID_SEPARATOR3, globalcontext)); subversionMenu->addAction(createSeparator(this, ami, CMD_ID_SEPARATOR3, globalcontext));
m_statusAction = new QAction(tr("Project Status"), this); m_statusProjectAction = new Utils::ParameterAction(tr("Project Status"), tr("Status of Project \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
command = ami->registerAction(m_statusAction, CMD_ID_STATUS, command = ami->registerAction(m_statusProjectAction, CMD_ID_STATUS,
globalcontext); globalcontext);
connect(m_statusAction, SIGNAL(triggered()), this, SLOT(projectStatus())); command->setAttribute(Core::Command::CA_UpdateText);
connect(m_statusProjectAction, SIGNAL(triggered()), this, SLOT(projectStatus()));
subversionMenu->addAction(command); subversionMenu->addAction(command);
m_updateProjectAction = new QAction(tr("Update Project"), this); m_updateProjectAction = new Utils::ParameterAction(tr("Update Project"), tr("Update Project \"%1\""), Utils::ParameterAction::EnabledWithParameter, this);
command = ami->registerAction(m_updateProjectAction, CMD_ID_UPDATE, globalcontext); command = ami->registerAction(m_updateProjectAction, CMD_ID_UPDATE, globalcontext);
connect(m_updateProjectAction, SIGNAL(triggered()), this, SLOT(updateProject())); connect(m_updateProjectAction, SIGNAL(triggered()), this, SLOT(updateProject()));
command->setAttribute(Core::Command::CA_UpdateText);
subversionMenu->addAction(command); subversionMenu->addAction(command);
// Actions of the submit editor // Actions of the submit editor
@@ -394,7 +394,6 @@ bool SubversionPlugin::initialize(const QStringList & /*arguments */, QString *e
void SubversionPlugin::extensionsInitialized() void SubversionPlugin::extensionsInitialized()
{ {
m_projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance();
} }
bool SubversionPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor) bool SubversionPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *submitEditor)
@@ -447,16 +446,16 @@ bool SubversionPlugin::submitEditorAboutToClose(VCSBase::VCSBaseSubmitEditor *su
return closeEditor; return closeEditor;
} }
void SubversionPlugin::diffFiles(const QStringList &files) void SubversionPlugin::diffCommitFiles(const QStringList &files)
{ {
svnDiff(files); svnDiff(m_commitRepository, files);
} }
void SubversionPlugin::svnDiff(const QStringList &files, QString diffname) void SubversionPlugin::svnDiff(const QString &workingDir, const QStringList &files, QString diffname)
{ {
if (Subversion::Constants::debug) if (Subversion::Constants::debug)
qDebug() << Q_FUNC_INFO << files << diffname; qDebug() << Q_FUNC_INFO << files << diffname;
const QString source = files.empty() ? QString() : files.front(); const QString source = VCSBase::VCSBaseEditor::getSource(workingDir, files);
QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VCSBase::VCSBaseEditor::getCodec(source); QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(0) : VCSBase::VCSBaseEditor::getCodec(source);
if (files.count() == 1 && diffname.isEmpty()) if (files.count() == 1 && diffname.isEmpty())
@@ -465,7 +464,7 @@ void SubversionPlugin::svnDiff(const QStringList &files, QString diffname)
QStringList args(QLatin1String("diff")); QStringList args(QLatin1String("diff"));
args << files; args << files;
const SubversionResponse response = runSvn(args, subversionShortTimeOut, false, codec); const SubversionResponse response = runSvn(workingDir, args, subversionShortTimeOut, false, codec);
if (response.error) if (response.error)
return; return;
@@ -491,7 +490,7 @@ SubversionSubmitEditor *SubversionPlugin::openSubversionSubmitEditor(const QStri
SubversionSubmitEditor *submitEditor = qobject_cast<SubversionSubmitEditor*>(editor); SubversionSubmitEditor *submitEditor = qobject_cast<SubversionSubmitEditor*>(editor);
QTC_ASSERT(submitEditor, /**/); QTC_ASSERT(submitEditor, /**/);
submitEditor->registerActions(m_submitUndoAction, m_submitRedoAction, m_submitCurrentLogAction, m_submitDiffAction); submitEditor->registerActions(m_submitUndoAction, m_submitRedoAction, m_submitCurrentLogAction, m_submitDiffAction);
connect(submitEditor, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(diffFiles(QStringList))); connect(submitEditor, SIGNAL(diffSelectedFiles(QStringList)), this, SLOT(diffCommitFiles(QStringList)));
return submitEditor; return submitEditor;
} }
@@ -501,47 +500,49 @@ void SubversionPlugin::updateActions(VCSBase::VCSBasePlugin::ActionState as)
if (!VCSBase::VCSBasePlugin::enableMenuAction(as, m_menuAction)) if (!VCSBase::VCSBasePlugin::enableMenuAction(as, m_menuAction))
return; return;
m_diffProjectAction->setEnabled(true); const QString projectName = currentState().currentProjectName();
m_commitAllAction->setEnabled(true); m_diffProjectAction->setParameter(projectName);
m_statusAction->setEnabled(true); m_statusProjectAction->setParameter(projectName);
m_describeAction->setEnabled(true); m_updateProjectAction->setParameter(projectName);
const QString fileName = currentFileName(); const bool repoEnabled = currentState().hasTopLevel();
const QString baseName = fileName.isEmpty() ? fileName : QFileInfo(fileName).fileName(); m_commitAllAction->setEnabled(repoEnabled);
m_describeAction->setEnabled(repoEnabled);
m_addAction->setParameter(baseName); const QString fileName = currentState().currentFileName();
m_deleteAction->setParameter(baseName);
m_revertAction->setParameter(baseName); m_addAction->setParameter(fileName);
m_diffCurrentAction->setParameter(baseName); m_deleteAction->setParameter(fileName);
m_commitCurrentAction->setParameter(baseName); m_revertAction->setParameter(fileName);
m_filelogCurrentAction->setParameter(baseName); m_diffCurrentAction->setParameter(fileName);
m_annotateCurrentAction->setParameter(baseName); m_commitCurrentAction->setParameter(fileName);
m_filelogCurrentAction->setParameter(fileName);
m_annotateCurrentAction->setParameter(fileName);
} }
void SubversionPlugin::addCurrentFile() void SubversionPlugin::addCurrentFile()
{ {
const QString file = currentFileName(); const VCSBase::VCSBasePluginState state = currentState();
if (!file.isEmpty()) QTC_ASSERT(state.hasFile(), return)
vcsAdd(file); vcsAdd(state.currentFileTopLevel(), state.relativeCurrentFile());
} }
void SubversionPlugin::deleteCurrentFile() void SubversionPlugin::deleteCurrentFile()
{ {
const QString file = currentFileName(); const VCSBase::VCSBasePluginState state = currentState();
if (!file.isEmpty()) QTC_ASSERT(state.hasFile(), return)
vcsDelete(file); vcsDelete(state.currentFileTopLevel(), state.relativeCurrentFile());
} }
void SubversionPlugin::revertCurrentFile() void SubversionPlugin::revertCurrentFile()
{ {
const QString file = QDir::toNativeSeparators(currentFileName()); const VCSBase::VCSBasePluginState state = currentState();
if (file.isEmpty()) QTC_ASSERT(state.hasFile(), return)
return;
QStringList args(QLatin1String("diff")); QStringList args(QLatin1String("diff"));
args.push_back(file); args.push_back(state.relativeCurrentFile());
const SubversionResponse diffResponse = runSvn(args, subversionShortTimeOut, false); const SubversionResponse diffResponse = runSvn(state.currentFileTopLevel(), args, subversionShortTimeOut, false);
if (diffResponse.error) if (diffResponse.error)
return; return;
@@ -552,97 +553,52 @@ void SubversionPlugin::revertCurrentFile()
return; return;
Core::FileChangeBlocker fcb(file); Core::FileChangeBlocker fcb(state.currentFile());
// revert // revert
args.clear(); args.clear();
args.push_back(QLatin1String("revert")); args << QLatin1String("revert") << state.relativeCurrentFile();
args.append(file);
const SubversionResponse revertResponse = runSvn(args, subversionShortTimeOut, true); const SubversionResponse revertResponse = runSvn(state.currentFileTopLevel(), args, subversionShortTimeOut, true);
if (!revertResponse.error) { if (!revertResponse.error) {
fcb.setModifiedReload(true); fcb.setModifiedReload(true);
subVersionControl()->emitFilesChanged(QStringList(file)); subVersionControl()->emitFilesChanged(QStringList(state.currentFile()));
} }
} }
// Get a unique set of toplevel directories for the current projects.
// To be used for "diff all" or "commit all".
QStringList SubversionPlugin::currentProjectsTopLevels(QString *name) const
{
typedef QList<ProjectExplorer::Project *> ProjectList;
ProjectList projects;
// Compile list of projects
if (ProjectExplorer::Project *currentProject = m_projectExplorer->currentProject()) {
projects.push_back(currentProject);
} else {
if (const ProjectExplorer::SessionManager *session = m_projectExplorer->session())
projects.append(session->projects());
}
// Get unique set of toplevels and concat project names
QStringList toplevels;
const QChar blank(QLatin1Char(' '));
foreach (const ProjectExplorer::Project *p, projects) {
if (name) {
if (!name->isEmpty())
name->append(blank);
name->append(p->name());
}
const QString projectPath = QFileInfo(p->file()->fileName()).absolutePath();
const QString topLevel = findTopLevelForDirectory(projectPath);
if (!topLevel.isEmpty() && !toplevels.contains(topLevel))
toplevels.push_back(topLevel);
}
return toplevels;
}
void SubversionPlugin::diffProject() void SubversionPlugin::diffProject()
{ {
QString diffName; const VCSBase::VCSBasePluginState state = currentState();
const QStringList topLevels = currentProjectsTopLevels(&diffName); QTC_ASSERT(state.hasProject(), return)
if (!topLevels.isEmpty()) svnDiff(state.currentProjectTopLevel(), state.relativeCurrentProject(), state.currentProjectName());
svnDiff(topLevels, diffName);
} }
void SubversionPlugin::diffCurrentFile() void SubversionPlugin::diffCurrentFile()
{ {
svnDiff(QStringList(currentFileName())); const VCSBase::VCSBasePluginState state = currentState();
QTC_ASSERT(state.hasFile(), return)
svnDiff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()));
} }
void SubversionPlugin::startCommitCurrentFile() void SubversionPlugin::startCommitCurrentFile()
{ {
const QString file = QDir::toNativeSeparators(currentFileName()); const VCSBase::VCSBasePluginState state = currentState();
if (!file.isEmpty()) QTC_ASSERT(state.hasFile(), return)
startCommit(QStringList(file)); startCommit(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()));
} }
void SubversionPlugin::startCommitAll() void SubversionPlugin::startCommitAll()
{ {
// Make sure we have only repository for commit const VCSBase::VCSBasePluginState state = currentState();
const QStringList files = currentProjectsTopLevels(); QTC_ASSERT(state.hasTopLevel(), return);
switch (files.size()) { startCommit(state.topLevel());
case 0:
break;
case 1:
startCommit(files);
break;
default: {
const QString msg = tr("The commit list spans several repositories (%1). Please commit them one by one.").
arg(files.join(QString(QLatin1Char(' '))));
QMessageBox::warning(0, QLatin1String("svn commit"), msg, QMessageBox::Ok);
}
break;
}
} }
/* Start commit of files of a single repository by displaying /* Start commit of files of a single repository by displaying
* template and files in a submit editor. On closing, the real * template and files in a submit editor. On closing, the real
* commit will start. */ * commit will start. */
void SubversionPlugin::startCommit(const QStringList &files) void SubversionPlugin::startCommit(const QString &workingDir, const QStringList &files)
{ {
if (files.empty())
return;
if (VCSBase::VCSBaseSubmitEditor::raiseSubmitEditor()) if (VCSBase::VCSBaseSubmitEditor::raiseSubmitEditor())
return; return;
if (isCommitEditorOpen()) { if (isCommitEditorOpen()) {
@@ -652,19 +608,18 @@ void SubversionPlugin::startCommit(const QStringList &files)
QStringList args(QLatin1String("status")); QStringList args(QLatin1String("status"));
args += files; args += files;
if (args.size() == 1)
return;
const SubversionResponse response = runSvn(args, subversionShortTimeOut, false); const SubversionResponse response = runSvn(workingDir, args, subversionShortTimeOut, false);
if (response.error) if (response.error)
return; return;
// Get list of added/modified/deleted files // Get list of added/modified/deleted files
const StatusList statusOutput = parseStatusOutput(response.stdOut); const StatusList statusOutput = parseStatusOutput(response.stdOut);
if (statusOutput.empty()) { if (statusOutput.empty()) {
VCSBase::VCSBaseOutputWindow::instance()->appendWarning(tr("There are no modified files.")); VCSBase::VCSBaseOutputWindow::instance()->appendWarning(tr("There are no modified files."));
return; return;
} }
m_commitRepository = workingDir;
// Create a new submit change file containing the submit template // Create a new submit change file containing the submit template
QTemporaryFile changeTmpFile; QTemporaryFile changeTmpFile;
changeTmpFile.setAutoRemove(false); changeTmpFile.setAutoRemove(false);
@@ -695,65 +650,65 @@ bool SubversionPlugin::commit(const QString &messageFile,
QStringList args = QStringList(QLatin1String("commit")); QStringList args = QStringList(QLatin1String("commit"));
args << QLatin1String(nonInteractiveOptionC) << QLatin1String("--file") << messageFile; args << QLatin1String(nonInteractiveOptionC) << QLatin1String("--file") << messageFile;
args.append(subVersionFileList); args.append(subVersionFileList);
const SubversionResponse response = runSvn(args, subversionLongTimeOut, true); const SubversionResponse response = runSvn(m_commitRepository, args, subversionLongTimeOut, true);
return !response.error ; return !response.error ;
} }
void SubversionPlugin::filelogCurrentFile() void SubversionPlugin::filelogCurrentFile()
{ {
const QString file = currentFileName(); const VCSBase::VCSBasePluginState state = currentState();
if (!file.isEmpty()) QTC_ASSERT(state.hasFile(), return)
filelog(file); filelog(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()));
} }
void SubversionPlugin::filelog(const QString &file) void SubversionPlugin::filelog(const QString &workingDir, const QStringList &files)
{ {
QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(file); QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(workingDir, files);
// no need for temp file // no need for temp file
QStringList args(QLatin1String("log")); QStringList args(QLatin1String("log"));
args.append(QDir::toNativeSeparators(file)); foreach(const QString &file, files)
args.append(QDir::toNativeSeparators(file));
const SubversionResponse response = runSvn(args, subversionShortTimeOut, false, codec); const SubversionResponse response = runSvn(workingDir, args, subversionShortTimeOut, false, codec);
if (response.error) if (response.error)
return; return;
// Re-use an existing view if possible to support // Re-use an existing view if possible to support
// the common usage pattern of continuously changing and diffing a file // the common usage pattern of continuously changing and diffing a file
if (Core::IEditor *editor = locateEditor("logFileName", file)) { const QString id = VCSBase::VCSBaseEditor::getTitleId(workingDir, files);
if (Core::IEditor *editor = locateEditor("logFileName", id)) {
editor->createNew(response.stdOut); editor->createNew(response.stdOut);
Core::EditorManager::instance()->activateEditor(editor); Core::EditorManager::instance()->activateEditor(editor);
} else { } else {
const QString title = QString::fromLatin1("svn log %1").arg(QFileInfo(file).fileName()); const QString title = QString::fromLatin1("svn log %1").arg(id);
Core::IEditor *newEditor = showOutputInEditor(title, response.stdOut, VCSBase::LogOutput, file, codec); const QString source = VCSBase::VCSBaseEditor::getSource(workingDir, files);
newEditor->setProperty("logFileName", file); Core::IEditor *newEditor = showOutputInEditor(title, response.stdOut, VCSBase::LogOutput, source, codec);
newEditor->setProperty("logFileName", id);
} }
} }
void SubversionPlugin::updateProject() void SubversionPlugin::updateProject()
{ {
const QStringList topLevels = currentProjectsTopLevels(); const VCSBase::VCSBasePluginState state = currentState();
if (topLevels.empty()) QTC_ASSERT(state.hasProject(), return);
return;
QStringList args(QLatin1String("update")); QStringList args(QLatin1String("update"));
args.push_back(QLatin1String(nonInteractiveOptionC)); args.push_back(QLatin1String(nonInteractiveOptionC));
args.append(topLevels); args.append(state.relativeCurrentProject());
const SubversionResponse response = runSvn(args, subversionLongTimeOut, true); const SubversionResponse response = runSvn(state.currentProjectTopLevel(), args, subversionLongTimeOut, true);
if (!response.error) { if (!response.error)
foreach(const QString &repo, topLevels) subVersionControl()->emitRepositoryChanged(state.currentProjectTopLevel());
subVersionControl()->emitRepositoryChanged(repo);
}
} }
void SubversionPlugin::annotateCurrentFile() void SubversionPlugin::annotateCurrentFile()
{ {
const QString file = currentFileName(); const VCSBase::VCSBasePluginState state = currentState();
if (!file.isEmpty()) QTC_ASSERT(state.hasFile(), return);
annotate(file); annotate(state.currentFileTopLevel(), state.relativeCurrentFile());
} }
void SubversionPlugin::annotate(const QString &file) void SubversionPlugin::annotate(const QString &workingDir, const QString &file)
{ {
QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(file); QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(file);
@@ -761,38 +716,35 @@ void SubversionPlugin::annotate(const QString &file)
args.push_back(QLatin1String("-v")); args.push_back(QLatin1String("-v"));
args.append(QDir::toNativeSeparators(file)); args.append(QDir::toNativeSeparators(file));
const SubversionResponse response = runSvn(args, subversionShortTimeOut, false, codec); const SubversionResponse response = runSvn(workingDir, args, subversionShortTimeOut, false, codec);
if (response.error) if (response.error)
return; return;
// Re-use an existing view if possible to support // Re-use an existing view if possible to support
// the common usage pattern of continuously changing and diffing a file // the common usage pattern of continuously changing and diffing a file
const int lineNumber = VCSBase::VCSBaseEditor::lineNumberOfCurrentEditor(file); const QString source = workingDir + QLatin1Char('/') + file;
const int lineNumber = VCSBase::VCSBaseEditor::lineNumberOfCurrentEditor(source);
const QString id = VCSBase::VCSBaseEditor::getTitleId(workingDir, QStringList(file));
if (Core::IEditor *editor = locateEditor("annotateFileName", file)) { if (Core::IEditor *editor = locateEditor("annotateFileName", id)) {
editor->createNew(response.stdOut); editor->createNew(response.stdOut);
VCSBase::VCSBaseEditor::gotoLineOfEditor(editor, lineNumber); VCSBase::VCSBaseEditor::gotoLineOfEditor(editor, lineNumber);
Core::EditorManager::instance()->activateEditor(editor); Core::EditorManager::instance()->activateEditor(editor);
} else { } else {
const QString title = QString::fromLatin1("svn annotate %1").arg(QFileInfo(file).fileName()); const QString title = QString::fromLatin1("svn annotate %1").arg(id);
Core::IEditor *newEditor = showOutputInEditor(title, response.stdOut, VCSBase::AnnotateOutput, file, codec); Core::IEditor *newEditor = showOutputInEditor(title, response.stdOut, VCSBase::AnnotateOutput, source, codec);
newEditor->setProperty("annotateFileName", file); newEditor->setProperty("annotateFileName", id);
VCSBase::VCSBaseEditor::gotoLineOfEditor(newEditor, lineNumber); VCSBase::VCSBaseEditor::gotoLineOfEditor(newEditor, lineNumber);
} }
} }
void SubversionPlugin::projectStatus() void SubversionPlugin::projectStatus()
{ {
if (!m_projectExplorer) const VCSBase::VCSBasePluginState state = currentState();
return; QTC_ASSERT(state.hasProject(), return);
QStringList args(QLatin1String("status")); QStringList args(QLatin1String("status"));
args += currentProjectsTopLevels(); args += state.relativeCurrentProject();
runSvn(state.currentProjectTopLevel(), args, subversionShortTimeOut, true);
if (args.size() == 1)
return;
runSvn(args, subversionShortTimeOut, true);
} }
void SubversionPlugin::describe(const QString &source, const QString &changeNr) void SubversionPlugin::describe(const QString &source, const QString &changeNr)
@@ -815,8 +767,7 @@ void SubversionPlugin::describe(const QString &source, const QString &changeNr)
QStringList args(QLatin1String("log")); QStringList args(QLatin1String("log"));
args.push_back(QLatin1String("-r")); args.push_back(QLatin1String("-r"));
args.push_back(changeNr); args.push_back(changeNr);
args.push_back(topLevel); const SubversionResponse logResponse = runSvn(topLevel, args, subversionShortTimeOut, false);
const SubversionResponse logResponse = runSvn(args, subversionShortTimeOut, false);
if (logResponse.error) if (logResponse.error)
return; return;
description = logResponse.stdOut; description = logResponse.stdOut;
@@ -828,10 +779,9 @@ void SubversionPlugin::describe(const QString &source, const QString &changeNr)
QString diffArg; QString diffArg;
QTextStream(&diffArg) << (number - 1) << ':' << number; QTextStream(&diffArg) << (number - 1) << ':' << number;
args.push_back(diffArg); args.push_back(diffArg);
args.push_back(topLevel);
QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(source); QTextCodec *codec = VCSBase::VCSBaseEditor::getCodec(source);
const SubversionResponse response = runSvn(args, subversionShortTimeOut, false, codec); const SubversionResponse response = runSvn(topLevel, args, subversionShortTimeOut, false, codec);
if (response.error) if (response.error)
return; return;
description += response.stdOut; description += response.stdOut;
@@ -843,7 +793,7 @@ void SubversionPlugin::describe(const QString &source, const QString &changeNr)
editor->createNew(description); editor->createNew(description);
Core::EditorManager::instance()->activateEditor(editor); Core::EditorManager::instance()->activateEditor(editor);
} else { } else {
const QString title = QString::fromLatin1("svn describe %1#%2").arg(QFileInfo(source).fileName(), changeNr); const QString title = QString::fromLatin1("svn describe %1#%2").arg(fi.fileName(), changeNr);
Core::IEditor *newEditor = showOutputInEditor(title, description, VCSBase::DiffOutput, source, codec); Core::IEditor *newEditor = showOutputInEditor(title, description, VCSBase::DiffOutput, source, codec);
newEditor->setProperty("describeChange", id); newEditor->setProperty("describeChange", id);
} }
@@ -851,9 +801,8 @@ void SubversionPlugin::describe(const QString &source, const QString &changeNr)
void SubversionPlugin::slotDescribe() void SubversionPlugin::slotDescribe()
{ {
const QStringList topLevels = currentProjectsTopLevels(); const VCSBase::VCSBasePluginState state = currentState();
if (topLevels.size() != 1) QTC_ASSERT(state.hasTopLevel(), return);
return;
QInputDialog inputDialog(Core::ICore::instance()->mainWindow()); QInputDialog inputDialog(Core::ICore::instance()->mainWindow());
inputDialog.setWindowFlags(inputDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint); inputDialog.setWindowFlags(inputDialog.windowFlags() & ~Qt::WindowContextHelpButtonHint);
@@ -865,7 +814,7 @@ void SubversionPlugin::slotDescribe()
return; return;
const int revision = inputDialog.intValue(); const int revision = inputDialog.intValue();
describe(topLevels.front(), QString::number(revision)); describe(state.topLevel(), QString::number(revision));
} }
void SubversionPlugin::submitCurrentLog() void SubversionPlugin::submitCurrentLog()
@@ -875,17 +824,6 @@ void SubversionPlugin::submitCurrentLog()
<< Core::EditorManager::instance()->currentEditor()); << Core::EditorManager::instance()->currentEditor());
} }
QString SubversionPlugin::currentFileName() const
{
const QString fileName = Core::ICore::instance()->fileManager()->currentFile();
if (!fileName.isEmpty()) {
const QFileInfo fi(fileName);
if (fi.exists())
return fi.canonicalFilePath();
}
return QString();
}
static inline QString processStdErr(QProcess &proc) static inline QString processStdErr(QProcess &proc)
{ {
return QString::fromLocal8Bit(proc.readAllStandardError()).remove(QLatin1Char('\r')); return QString::fromLocal8Bit(proc.readAllStandardError()).remove(QLatin1Char('\r'));
@@ -898,7 +836,8 @@ static inline QString processStdOut(QProcess &proc, QTextCodec *outputCodec = 0)
return stdOut.remove(QLatin1Char('\r')); return stdOut.remove(QLatin1Char('\r'));
} }
SubversionResponse SubversionPlugin::runSvn(const QStringList &arguments, SubversionResponse SubversionPlugin::runSvn(const QString &workingDir,
const QStringList &arguments,
int timeOut, int timeOut,
bool showStdOutInOutputWindow, bool showStdOutInOutputWindow,
QTextCodec *outputCodec) QTextCodec *outputCodec)
@@ -923,6 +862,8 @@ SubversionResponse SubversionPlugin::runSvn(const QStringList &arguments,
// Run, connect stderr to the output window // Run, connect stderr to the output window
Utils::SynchronousProcess process; Utils::SynchronousProcess process;
if (!workingDir.isEmpty())
process.setWorkingDirectory(workingDir);
process.setTimeout(timeOut); process.setTimeout(timeOut);
process.setStdOutCodec(outputCodec); process.setStdOutCodec(outputCodec);
@@ -1007,24 +948,24 @@ SubversionPlugin *SubversionPlugin::subversionPluginInstance()
return m_subversionPluginInstance; return m_subversionPluginInstance;
} }
bool SubversionPlugin::vcsAdd(const QString &rawFileName) bool SubversionPlugin::vcsAdd(const QString &workingDir, const QString &rawFileName)
{ {
const QString file = QDir::toNativeSeparators(rawFileName); const QString file = QDir::toNativeSeparators(rawFileName);
QStringList args(QLatin1String("add")); QStringList args(QLatin1String("add"));
args.push_back(file); args.push_back(file);
const SubversionResponse response = runSvn(args, subversionShortTimeOut, true); const SubversionResponse response = runSvn(workingDir, args, subversionShortTimeOut, true);
return !response.error; return !response.error;
} }
bool SubversionPlugin::vcsDelete(const QString &rawFileName) bool SubversionPlugin::vcsDelete(const QString &workingDir, const QString &rawFileName)
{ {
const QString file = QDir::toNativeSeparators(rawFileName); const QString file = QDir::toNativeSeparators(rawFileName);
QStringList args(QLatin1String("delete")); QStringList args(QLatin1String("delete"));
args.push_back(file); args.push_back(file);
const SubversionResponse response = runSvn(args, subversionShortTimeOut, true); const SubversionResponse response = runSvn(workingDir, args, subversionShortTimeOut, true);
return !response.error; return !response.error;
} }

View File

@@ -33,6 +33,7 @@
#include "subversionsettings.h" #include "subversionsettings.h"
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QDir; class QDir;
@@ -48,10 +49,6 @@ namespace Utils {
class ParameterAction; class ParameterAction;
} }
namespace ProjectExplorer {
class ProjectExplorerPlugin;
}
namespace VCSBase { namespace VCSBase {
class VCSBaseSubmitEditor; class VCSBaseSubmitEditor;
} }
@@ -82,7 +79,7 @@ public:
bool initialize(const QStringList &arguments, QString *error_message); bool initialize(const QStringList &arguments, QString *error_message);
void extensionsInitialized(); void extensionsInitialized();
void svnDiff(const QStringList &files, QString diffname = QString()); void svnDiff(const QString &workingDir, const QStringList &files, QString diffname = QString());
SubversionSubmitEditor *openSubversionSubmitEditor(const QString &fileName); SubversionSubmitEditor *openSubversionSubmitEditor(const QString &fileName);
@@ -90,8 +87,8 @@ public:
void setSettings(const SubversionSettings &s); void setSettings(const SubversionSettings &s);
// IVersionControl // IVersionControl
bool vcsAdd(const QString &fileName); bool vcsAdd(const QString &workingDir, const QString &fileName);
bool vcsDelete(const QString &fileName); bool vcsDelete(const QString &workingDir, const QString &fileName);
bool managesDirectory(const QString &directory) const; bool managesDirectory(const QString &directory) const;
QString findTopLevelForDirectory(const QString &directory) const; QString findTopLevelForDirectory(const QString &directory) const;
@@ -112,7 +109,7 @@ private slots:
void slotDescribe(); void slotDescribe();
void updateProject(); void updateProject();
void submitCurrentLog(); void submitCurrentLog();
void diffFiles(const QStringList &); void diffCommitFiles(const QStringList &);
protected: protected:
virtual void updateActions(VCSBase::VCSBasePlugin::ActionState); virtual void updateActions(VCSBase::VCSBasePlugin::ActionState);
@@ -120,18 +117,17 @@ protected:
private: private:
inline bool isCommitEditorOpen() const; inline bool isCommitEditorOpen() const;
QString currentFileName() const;
Core::IEditor * showOutputInEditor(const QString& title, const QString &output, Core::IEditor * showOutputInEditor(const QString& title, const QString &output,
int editorType, const QString &source, int editorType, const QString &source,
QTextCodec *codec); QTextCodec *codec);
SubversionResponse runSvn(const QStringList &arguments, int timeOut, SubversionResponse runSvn(const QString &workingDir,
const QStringList &arguments, int timeOut,
bool showStdOutInOutputWindow, QTextCodec *outputCodec = 0); bool showStdOutInOutputWindow, QTextCodec *outputCodec = 0);
void annotate(const QString &file); void annotate(const QString &workingDir, const QString &file);
void filelog(const QString &file); void filelog(const QString &workingDir, const QStringList &file = QStringList());
bool managesDirectory(const QDir &directory) const; bool managesDirectory(const QDir &directory) const;
QString findTopLevelForDirectoryI(const QString &directory) const; QString findTopLevelForDirectoryI(const QString &directory) const;
QStringList currentProjectsTopLevels(QString *name = 0) const; void startCommit(const QString &workingDir, const QStringList &files = QStringList());
void startCommit(const QStringList &files);
bool commit(const QString &messageFile, const QStringList &subVersionFileList); bool commit(const QString &messageFile, const QStringList &subVersionFileList);
void cleanCommitMessageFile(); void cleanCommitMessageFile();
inline SubversionControl *subVersionControl() const; inline SubversionControl *subVersionControl() const;
@@ -140,20 +136,19 @@ private:
SubversionSettings m_settings; SubversionSettings m_settings;
QString m_commitMessageFileName; QString m_commitMessageFileName;
QString m_commitRepository;
ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer;
Utils::ParameterAction *m_addAction; Utils::ParameterAction *m_addAction;
Utils::ParameterAction *m_deleteAction; Utils::ParameterAction *m_deleteAction;
Utils::ParameterAction *m_revertAction; Utils::ParameterAction *m_revertAction;
QAction *m_diffProjectAction; Utils::ParameterAction *m_diffProjectAction;
Utils::ParameterAction *m_diffCurrentAction; Utils::ParameterAction *m_diffCurrentAction;
QAction *m_commitAllAction; QAction *m_commitAllAction;
Utils::ParameterAction *m_commitCurrentAction; Utils::ParameterAction *m_commitCurrentAction;
Utils::ParameterAction *m_filelogCurrentAction; Utils::ParameterAction *m_filelogCurrentAction;
Utils::ParameterAction *m_annotateCurrentAction; Utils::ParameterAction *m_annotateCurrentAction;
QAction *m_statusAction; Utils::ParameterAction *m_statusProjectAction;
QAction *m_updateProjectAction; Utils::ParameterAction *m_updateProjectAction;
QAction *m_describeAction; QAction *m_describeAction;
QAction *m_submitCurrentLogAction; QAction *m_submitCurrentLogAction;

View File

@@ -37,6 +37,7 @@
#include <coreplugin/uniqueidmanager.h> #include <coreplugin/uniqueidmanager.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/ifile.h> #include <coreplugin/ifile.h>
#include <coreplugin/iversioncontrol.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <projectexplorer/editorconfiguration.h> #include <projectexplorer/editorconfiguration.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
@@ -595,6 +596,13 @@ QTextCodec *VCSBaseEditor::getCodec(const QString &source)
return sys; return sys;
} }
QTextCodec *VCSBaseEditor::getCodec(const QString &workingDirectory, const QStringList &files)
{
if (files.empty())
return getCodec(workingDirectory);
return getCodec(workingDirectory + QLatin1Char('/') + files.front());
}
VCSBaseEditor *VCSBaseEditor::getVcsBaseEditor(const Core::IEditor *editor) VCSBaseEditor *VCSBaseEditor::getVcsBaseEditor(const Core::IEditor *editor)
{ {
if (const TextEditor::BaseTextEditorEditable *be = qobject_cast<const TextEditor::BaseTextEditorEditable *>(editor)) if (const TextEditor::BaseTextEditorEditable *be = qobject_cast<const TextEditor::BaseTextEditorEditable *>(editor))
@@ -667,4 +675,33 @@ QString VCSBaseEditor::getTitleId(const QString &workingDirectory, const QString
return fileNames.join(QLatin1String(", ")); return fileNames.join(QLatin1String(", "));
} }
// Find the complete file from a diff relative specification.
QString VCSBaseEditor::findDiffFile(const QString &f, Core::IVersionControl *control /* = 0 */) const
{
// Try the file.
const QFileInfo in(f);
if (in.isAbsolute())
return in.isFile() ? f : QString();
if (in.isFile())
return in.absoluteFilePath();
// Try in source directory
if (source().isEmpty())
return QString();
const QFileInfo sourceInfo(source());
const QString sourceDir = sourceInfo.isDir() ? sourceInfo.absoluteFilePath() : sourceInfo.absolutePath();
const QFileInfo sourceFileInfo(sourceDir + QLatin1Char('/') + f);
if (sourceFileInfo.isFile())
return sourceFileInfo.absoluteFilePath();
// Try to locate via repository.
if (!control)
return QString();
const QString topLevel = control->findTopLevelForDirectory(sourceDir);
if (topLevel.isEmpty())
return QString();
const QFileInfo topLevelFileInfo(topLevel + QLatin1Char('/') + f);
if (topLevelFileInfo.isFile())
return topLevelFileInfo.absoluteFilePath();
return QString();
}
} // namespace VCSBase } // namespace VCSBase

View File

@@ -42,6 +42,10 @@ class QTextCodec;
class QTextCursor; class QTextCursor;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Core {
class IVersionControl;
}
namespace VCSBase { namespace VCSBase {
struct VCSBaseEditorPrivate; struct VCSBaseEditorPrivate;
@@ -114,6 +118,7 @@ public:
// The codec should be set on editors displaying diff or annotation // The codec should be set on editors displaying diff or annotation
// output. // output.
static QTextCodec *getCodec(const QString &source); static QTextCodec *getCodec(const QString &source);
static QTextCodec *getCodec(const QString &workingDirectory, const QStringList &files);
// Utility to return the editor from the IEditor returned by the editor // Utility to return the editor from the IEditor returned by the editor
// manager which is a BaseTextEditable. // manager which is a BaseTextEditable.
@@ -164,6 +169,12 @@ private slots:
void slotDiffBrowse(int); void slotDiffBrowse(int);
void slotDiffCursorPositionChanged(); void slotDiffCursorPositionChanged();
protected:
/* A helper that can be used to locate a file in a diff in case it
* is relative. Tries to derive the directory from source and
* version control. */
QString findDiffFile(const QString &f, Core::IVersionControl *control = 0) const;
private: private:
// Implement to return a set of change identifiers in // Implement to return a set of change identifiers in
// annotation mode // annotation mode

View File

@@ -142,12 +142,12 @@ protected:
explicit VCSBasePlugin(const QString &submitEditorKind); explicit VCSBasePlugin(const QString &submitEditorKind);
void initialize(Core::IVersionControl *vc); void initialize(Core::IVersionControl *vc);
Core::IVersionControl *versionControl() const;
public: public:
virtual ~VCSBasePlugin(); virtual ~VCSBasePlugin();
const VCSBasePluginState &currentState() const; const VCSBasePluginState &currentState() const;
Core::IVersionControl *versionControl() const;
protected: protected:
enum ActionState { NoVCSEnabled, OtherVCSEnabled, VCSEnabled }; enum ActionState { NoVCSEnabled, OtherVCSEnabled, VCSEnabled };