Commit 3c342a49 authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Tobias Hunger
Browse files

VCS: Add 'Blame current revision' in blame context menu



Internal change: added decorateVersion() function for decorating
a revision. This is called for both the current version and previous ones

Change-Id: I8b23fd628c9db01b005c19d46580979c5a21c687
Reviewed-by: default avatarTobias Hunger <tobias.hunger@nokia.com>
parent 6f7ae05d
......@@ -1070,29 +1070,11 @@ bool GitClient::synchronousParentRevisions(const QString &workingDirectory,
// Short SHA1, author, subject
static const char defaultShortLogFormatC[] = "%h (%an \"%s\")";
bool GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision,
QString *description, QString *errorMessage)
QString GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision)
{
// Short SHA 1, author, subject
return synchronousShortDescription(workingDirectory, revision,
QLatin1String(defaultShortLogFormatC),
description, errorMessage);
}
// Convenience working on a list of revisions
bool GitClient::synchronousShortDescriptions(const QString &workingDirectory, const QStringList &revisions,
QStringList *descriptions, QString *errorMessage)
{
descriptions->clear();
foreach (const QString &revision, revisions) {
QString description;
if (!synchronousShortDescription(workingDirectory, revision, &description, errorMessage)) {
descriptions->clear();
return false;
}
descriptions->push_back(description);
}
return true;
QLatin1String(defaultShortLogFormatC));
}
static inline QString msgCannotDetermineBranch(const QString &workingDirectory, const QString &why)
......@@ -1161,10 +1143,10 @@ bool GitClient::synchronousTopRevision(const QString &workingDirectory, QString
}
// Format an entry in a one-liner for selection list using git log.
bool GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision,
const QString &format, QString *description,
QString *errorMessage)
QString GitClient::synchronousShortDescription(const QString &workingDirectory, const QString &revision,
const QString &format)
{
QString description;
QByteArray outputTextData;
QByteArray errorText;
QStringList arguments;
......@@ -1173,13 +1155,15 @@ bool GitClient::synchronousShortDescription(const QString &workingDirectory, con
<< QLatin1String("--max-count=1") << revision;
const bool rc = fullySynchronousGit(workingDirectory, arguments, &outputTextData, &errorText);
if (!rc) {
*errorMessage = tr("Cannot describe revision \"%1\" in \"%2\": %3").arg(revision, workingDirectory, commandOutputFromLocal8Bit(errorText));
return false;
}
*description = commandOutputFromLocal8Bit(outputTextData);
if (description->endsWith(QLatin1Char('\n')))
description->truncate(description->size() - 1);
return true;
VcsBase::VcsBaseOutputWindow *outputWindow = VcsBase::VcsBaseOutputWindow::instance();
outputWindow->appendSilently(tr("Cannot describe revision \"%1\" in \"%2\": %3")
.arg(revision, workingDirectory, commandOutputFromLocal8Bit(errorText)));
return QString();
}
description = commandOutputFromLocal8Bit(outputTextData);
if (description.endsWith(QLatin1Char('\n')))
description.truncate(description.size() - 1);
return description;
}
// Create a default message to be used for describing stashes
......
......@@ -160,12 +160,9 @@ public:
const QString &revision,
QStringList *parents,
QString *errorMessage);
bool synchronousShortDescription(const QString &workingDirectory, const QString &revision,
QString *description, QString *errorMessage);
bool synchronousShortDescription(const QString &workingDirectory, const QString &revision,
const QString &format, QString *description, QString *errorMessage);
bool synchronousShortDescriptions(const QString &workingDirectory, const QStringList &revisions,
QStringList *descriptions, QString *errorMessage);
QString synchronousShortDescription(const QString &workingDirectory, const QString &revision);
QString synchronousShortDescription(const QString &workingDirectory, const QString &revision,
const QString &format);
bool synchronousTopRevision(const QString &workingDirectory, QString *revision = 0,
QString *branch = 0, QString *errorMessage = 0);
......
......@@ -227,6 +227,15 @@ void GitEditor::commandFinishedGotoLine(bool ok, int /* exitCode */, const QVari
}
}
QString GitEditor::decorateVersion(const QString &revision) const
{
const QFileInfo fi(source());
const QString workingDirectory = fi.absolutePath();
// Format verbose, SHA1 being first token
return GitPlugin::instance()->gitClient()->synchronousShortDescription(workingDirectory, revision);
}
QStringList GitEditor::annotationPreviousVersions(const QString &revision) const
{
QStringList revisions;
......@@ -240,13 +249,7 @@ QStringList GitEditor::annotationPreviousVersions(const QString &revision) const
VcsBase::VcsBaseOutputWindow::instance()->appendSilently(errorMessage);
return QStringList();
}
// Format verbose, SHA1 being first token
QStringList descriptions;
if (!client->synchronousShortDescriptions(workingDirectory, revisions, &descriptions, &errorMessage)) {
VcsBase::VcsBaseOutputWindow::instance()->appendSilently(errorMessage);
return QStringList();
}
return descriptions;
return revisions;
}
} // namespace Internal
......
......@@ -63,6 +63,7 @@ private:
virtual VcsBase::DiffHighlighter *createDiffHighlighter() const;
virtual VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
virtual QString fileNameFromDiffSpecification(const QTextBlock &diffFileName) const;
virtual QString decorateVersion(const QString &revision) const;
virtual QStringList annotationPreviousVersions(const QString &revision) const;
mutable QRegExp m_changeNumberPattern8;
......
......@@ -157,19 +157,18 @@ static inline QString msgParseParentsOutputFailed(const QString &output)
return MercurialClient::tr("Cannot parse output: %1").arg(output);
}
bool MercurialClient::parentRevisionsSync(const QString &workingDirectory,
QStringList MercurialClient::parentRevisionsSync(const QString &workingDirectory,
const QString &file /* = QString() */,
const QString &revision,
QStringList *parents)
const QString &revision)
{
parents->clear();
QStringList parents;
QStringList args;
args << QLatin1String("parents") << QLatin1String("-r") <<revision;
if (!file.isEmpty())
args << file;
QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
return false;
return QStringList();
QString output = QString::fromLocal8Bit(outputData);
output.remove(QLatin1Char('\r'));
/* Looks like: \code
......@@ -181,12 +180,12 @@ user: ...
const QStringList lines = output.split(QLatin1Char('\n'));
if (lines.size() < 1) {
outputWindow->appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
return false;
return QStringList();
}
QStringList changeSets = lines.front().simplified().split(QLatin1Char(' '));
if (changeSets.size() < 2) {
outputWindow->appendSilently(msgParentRevisionFailed(workingDirectory, revision, msgParseParentsOutputFailed(output)));
return false;
return QStringList();
}
// Remove revision numbers
const QChar colon = QLatin1Char(':');
......@@ -195,57 +194,38 @@ user: ...
for (++it; it != end; ++it) {
const int colonIndex = it->indexOf(colon);
if (colonIndex != -1)
parents->push_back(it->mid(colonIndex + 1));
parents.push_back(it->mid(colonIndex + 1));
}
return true;
return parents;
}
// Describe a change using an optional format
bool MercurialClient::shortDescriptionSync(const QString &workingDirectory,
QString MercurialClient::shortDescriptionSync(const QString &workingDirectory,
const QString &revision,
const QString &format,
QString *description)
const QString &format)
{
description->clear();
QString description;
QStringList args;
args << QLatin1String("log") << QLatin1String("-r") <<revision;
if (!format.isEmpty())
args << QLatin1String("--template") << format;
QByteArray outputData;
if (!vcsFullySynchronousExec(workingDirectory, args, &outputData))
return false;
*description = QString::fromLocal8Bit(outputData);
description->remove(QLatin1Char('\r'));
if (description->endsWith(QLatin1Char('\n')))
description->truncate(description->size() - 1);
return true;
return QString();
description = QString::fromLocal8Bit(outputData);
description.remove(QLatin1Char('\r'));
if (description.endsWith(QLatin1Char('\n')))
description.truncate(description.size() - 1);
return description;
}
// Default format: "SHA1 (author summmary)"
static const char defaultFormatC[] = "{node} ({author|person} {desc|firstline})";
bool MercurialClient::shortDescriptionSync(const QString &workingDirectory,
const QString &revision,
QString *description)
{
if (!shortDescriptionSync(workingDirectory, revision, QLatin1String(defaultFormatC), description))
return false;
description->remove(QLatin1Char('\n'));
return true;
}
// Convenience to format a list of changes
bool MercurialClient::shortDescriptionsSync(const QString &workingDirectory, const QStringList &revisions,
QStringList *descriptions)
QString MercurialClient::shortDescriptionSync(const QString &workingDirectory,
const QString &revision)
{
descriptions->clear();
foreach(const QString &revision, revisions) {
QString description;
if (!shortDescriptionSync(workingDirectory, revision, &description))
return false;
descriptions->push_back(description);
}
return true;
return shortDescriptionSync(workingDirectory, revision, QLatin1String(defaultFormatC));
}
QString MercurialClient::vcsGetRepositoryURL(const QString &directory)
......
......@@ -54,16 +54,12 @@ public:
const QStringList &extraOptions = QStringList());
bool manifestSync(const QString &repository, const QString &filename);
QString branchQuerySync(const QString &repositoryRoot);
bool parentRevisionsSync(const QString &workingDirectory,
QStringList parentRevisionsSync(const QString &workingDirectory,
const QString &file /* = QString() */,
const QString &revision,
QStringList *parents);
bool shortDescriptionSync(const QString &workingDirectory, const QString &revision,
const QString &format /* = QString() */, QString *description);
bool shortDescriptionSync(const QString &workingDirectory, const QString &revision,
QString *description);
bool shortDescriptionsSync(const QString &workingDirectory, const QStringList &revisions,
QStringList *descriptions);
const QString &revision);
QString shortDescriptionSync(const QString &workingDirectory, const QString &revision,
const QString &format /* = QString() */);
QString shortDescriptionSync(const QString &workingDirectory, const QString &revision);
void incoming(const QString &repositoryRoot, const QString &repository = QString());
void outgoing(const QString &repositoryRoot);
QString vcsGetRepositoryURL(const QString &directory);
......
......@@ -118,19 +118,18 @@ QString MercurialEditor::fileNameFromDiffSpecification(const QTextBlock &inBlock
return QString();
}
QString MercurialEditor::decorateVersion(const QString &revision) const
{
const QFileInfo fi(source());
const QString workingDirectory = fi.absolutePath();
// Format with short summary
return MercurialPlugin::instance()->client()->shortDescriptionSync(workingDirectory, revision);
}
QStringList MercurialEditor::annotationPreviousVersions(const QString &revision) const
{
MercurialClient *client = MercurialPlugin::instance()->client();
QStringList parents;
const QFileInfo fi(source());
const QString workingDirectory = fi.absolutePath();
// Retrieve parent revisions
QStringList revisions;
if (!client->parentRevisionsSync(workingDirectory, fi.fileName(), revision, &revisions))
return QStringList();
// Format with short summary
QStringList descriptions;
if (!client->shortDescriptionsSync(workingDirectory, revisions, &descriptions))
return QStringList();
return descriptions;
return MercurialPlugin::instance()->client()->parentRevisionsSync(workingDirectory, fi.fileName(), revision);
}
......@@ -52,6 +52,7 @@ private:
virtual VcsBase::DiffHighlighter *createDiffHighlighter() const;
virtual VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet<QString> &changes, const QColor &bg) const;
virtual QString fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const;
virtual QString decorateVersion(const QString &revision) const;
virtual QStringList annotationPreviousVersions(const QString &revision) const;
mutable QRegExp exactIdentifier12;
......
......@@ -352,11 +352,12 @@ void ChangeTextCursorHandler::fillContextMenu(QMenu *menu, EditorContentType typ
menu->addSeparator();
menu->addAction(createCopyRevisionAction(m_currentChange));
menu->addAction(createDescribeAction(m_currentChange));
menu->addSeparator();
menu->addAction(createAnnotateAction(editorWidget()->decorateVersion(m_currentChange), false));
const QStringList previousVersions = editorWidget()->annotationPreviousVersions(m_currentChange);
if (!previousVersions.isEmpty()) {
menu->addSeparator();
foreach (const QString &pv, previousVersions)
menu->addAction(createAnnotateAction(pv, true));
menu->addAction(createAnnotateAction(editorWidget()->decorateVersion(pv), true));
}
break;
}
......@@ -1437,6 +1438,11 @@ bool VcsBaseEditorWidget::applyDiffChunk(const DiffChunk &dc, bool revert) const
return VcsBasePlugin::runPatch(dc.asPatch(), QString(), 0, revert);
}
QString VcsBaseEditorWidget::decorateVersion(const QString &revision) const
{
return revision;
}
void VcsBaseEditorWidget::slotApplyDiffChunk()
{
const QAction *a = qobject_cast<QAction *>(sender());
......
......@@ -254,6 +254,8 @@ private:
// Implement to return a local file name from the diff file specification
// (text cursor at position above change hunk)
virtual QString fileNameFromDiffSpecification(const QTextBlock &diffFileSpec) const = 0;
// Implement to return decorated annotation change for "Annotate version"
virtual QString decorateVersion(const QString &revision) const;
// Implement to return the previous version[s] of an annotation change
// for "Annotate previous version"
virtual QStringList annotationPreviousVersions(const QString &revision) const;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment