Commit d6583f0f authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh
Browse files

Git: Add on-demand branches expanding



Make "branches expanding" on demand and asynchronous.
After "git show" there is clickable text: "Branches: <Expand>" in
description. If user clicks this text then branches for commit is
triggered and done asynchronously.

Task-number: QTCREATORBUG-11293
Done-with: Przemyslaw Gorszkowski <pgorszkowski@gmail.com>
Change-Id: I772cfef823d3f95e2b3060dfb5973157d81fc11a
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent 281aa9e0
......@@ -52,6 +52,7 @@
#include <QComboBox>
#include <QFileInfo>
#include <QTextCodec>
#include <QTextBlock>
static const char settingsGroupC[] = "DiffEditor";
static const char diffEditorTypeKeyC[] = "DiffEditorType";
......@@ -74,6 +75,9 @@ public:
DescriptionEditorWidget(QWidget *parent = 0);
virtual QSize sizeHint() const;
signals:
void expandBranchesRequested();
public slots:
void setDisplaySettings(const DisplaySettings &ds);
......@@ -84,6 +88,15 @@ protected:
editor->document()->setId("DiffEditor.DescriptionEditor");
return editor;
}
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
bool findContentsUnderCursor(const QTextCursor &cursor);
void highlightCurrentContents();
void handleCurrentContents();
private:
QTextCursor m_currentCursor;
};
DescriptionEditorWidget::DescriptionEditorWidget(QWidget *parent)
......@@ -118,6 +131,67 @@ void DescriptionEditorWidget::setDisplaySettings(const DisplaySettings &ds)
BaseTextEditorWidget::setDisplaySettings(settings);
}
void DescriptionEditorWidget::mouseMoveEvent(QMouseEvent *e)
{
if (e->buttons()) {
TextEditor::BaseTextEditorWidget::mouseMoveEvent(e);
return;
}
Qt::CursorShape cursorShape;
const QTextCursor cursor = cursorForPosition(e->pos());
if (findContentsUnderCursor(cursor)) {
highlightCurrentContents();
cursorShape = Qt::PointingHandCursor;
} else {
setExtraSelections(OtherSelection, QList<QTextEdit::ExtraSelection>());
cursorShape = Qt::IBeamCursor;
}
TextEditor::BaseTextEditorWidget::mouseMoveEvent(e);
viewport()->setCursor(cursorShape);
}
void DescriptionEditorWidget::mouseReleaseEvent(QMouseEvent *e)
{
if (e->button() == Qt::LeftButton && !(e->modifiers() & Qt::ShiftModifier)) {
const QTextCursor cursor = cursorForPosition(e->pos());
if (findContentsUnderCursor(cursor)) {
handleCurrentContents();
e->accept();
return;
}
}
TextEditor::BaseTextEditorWidget::mouseReleaseEvent(e);
}
bool DescriptionEditorWidget::findContentsUnderCursor(const QTextCursor &cursor)
{
m_currentCursor = cursor;
return cursor.block().text() == QLatin1String(Constants::EXPAND_BRANCHES);
}
void DescriptionEditorWidget::highlightCurrentContents()
{
QTextEdit::ExtraSelection sel;
sel.cursor = m_currentCursor;
sel.cursor.select(QTextCursor::LineUnderCursor);
sel.format.setFontUnderline(true);
setExtraSelections(BaseTextEditorWidget::OtherSelection,
QList<QTextEdit::ExtraSelection>() << sel);
}
void DescriptionEditorWidget::handleCurrentContents()
{
m_currentCursor.select(QTextCursor::LineUnderCursor);
m_currentCursor.removeSelectedText();
m_currentCursor.insertText(QLatin1String("Branches: Expanding..."));
emit expandBranchesRequested();
}
} // namespace Internal
///////////////////////////////// DiffEditor //////////////////////////////////
......@@ -179,6 +253,8 @@ void DiffEditor::ctor()
setWidget(splitter);
connect(m_descriptionWidget, SIGNAL(expandBranchesRequested()),
m_document->controller(), SLOT(expandBranchesRequested()));
connect(TextEditorSettings::instance(),
SIGNAL(displaySettingsChanged(TextEditor::DisplaySettings)),
m_descriptionWidget,
......
......@@ -44,6 +44,8 @@ const char ICON_SIDE_BY_SIDE_DIFF[] = ":/diffeditor/images/sidebysidediff.png";
const char ICON_UNIFIED_DIFF[] = ":/diffeditor/images/unifieddiff.png";
const char ICON_TOP_BAR[] = ":/diffeditor/images/topbar.png";
const char EXPAND_BRANCHES[] = "Branches: <Expand>";
} // namespace Constants
} // namespace DiffEditor
......
......@@ -27,10 +27,13 @@
**
****************************************************************************/
#include "diffeditorconstants.h"
#include "diffeditorcontroller.h"
#include <coreplugin/icore.h>
#include <QStringList>
static const char settingsGroupC[] = "DiffEditor";
static const char contextLineNumbersKeyC[] = "ContextLineNumbers";
static const char ignoreWhitespaceKeyC[] = "IgnoreWhitespace";
......@@ -148,7 +151,11 @@ void DiffEditorController::setDescription(const QString &description)
return;
m_description = description;
emit descriptionChanged(description);
// Empty line before headers and commit message
const int emptyLine = m_description.indexOf(QLatin1String("\n\n"));
if (emptyLine != -1)
m_description.insert(emptyLine, QLatin1Char('\n') + QLatin1String(Constants::EXPAND_BRANCHES));
emit descriptionChanged(m_description);
}
void DiffEditorController::setDescriptionEnabled(bool on)
......@@ -160,6 +167,44 @@ void DiffEditorController::setDescriptionEnabled(bool on)
emit descriptionEnablementChanged(on);
}
void DiffEditorController::branchesForCommitReceived(const QString &output)
{
const QString branches = prepareBranchesForCommit(output);
m_description.replace(QLatin1String(Constants::EXPAND_BRANCHES), branches);
emit descriptionChanged(m_description);
}
void DiffEditorController::expandBranchesRequested()
{
emit expandBranchesRequested(m_description.mid(7, 8));
}
QString DiffEditorController::prepareBranchesForCommit(const QString &output)
{
QString moreBranches;
QString branches;
QStringList res;
foreach (const QString &branch, output.split(QLatin1Char('\n'))) {
const QString b = branch.mid(2).trimmed();
if (!b.isEmpty())
res << b;
}
const int branchCount = res.count();
// If there are more than 20 branches, list first 10 followed by a hint
if (branchCount > 20) {
const int leave = 10;
//: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'"
// in git show.
moreBranches = QLatin1Char(' ') + tr("and %n more", 0, branchCount - leave);
res.erase(res.begin() + leave, res.end());
}
if (!res.isEmpty())
branches = (QLatin1String("Branches: ") + res.join(QLatin1String(", ")) + moreBranches);
return branches;
}
void DiffEditorController::setContextLinesNumber(int lines)
{
const int l = qMax(lines, 1);
......
......@@ -68,6 +68,8 @@ public slots:
void requestChunkActions(QMenu *menu,
int diffFileIndex,
int chunkIndex);
void branchesForCommitReceived(const QString &output);
void expandBranchesRequested();
signals:
void cleared(const QString &message);
......@@ -81,9 +83,10 @@ signals:
void chunkActionsRequested(QMenu *menu,
int diffFileIndex,
int chunkIndex);
void expandBranchesRequested(const QString &revision);
private:
QString prepareBranchesForCommit(const QString &output);
QString m_clearMessage;
QList<FileData> m_diffFiles;
......
......@@ -1139,6 +1139,10 @@ void GitClient::show(const QString &source, const QString &id, const QString &na
DiffEditor::DiffEditorManager::find(documentId);
if (!diffEditorDocument) {
diffEditorDocument = createDiffEditor(documentId, source, title);
connect(diffEditorDocument->controller(), SIGNAL(expandBranchesRequested(QString)),
this, SLOT(branchesForCommit(QString)));
diffEditorDocument->controller()->setDescriptionEnabled(true);
GitDiffEditorReloader *reloader =
......@@ -1738,23 +1742,25 @@ void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const
}
}
QStringList GitClient::synchronousBranchesForCommit(const QString &workingDirectory, const QString &revision)
void GitClient::branchesForCommit(const QString &revision)
{
QByteArray outputData;
QString output;
QStringList arguments;
arguments << QLatin1String("branch") << QLatin1String(noColorOption)
<< QLatin1String("-a") << QLatin1String("--contains") << revision;
fullySynchronousGit(workingDirectory, arguments, &outputData, 0,
VcsBasePlugin::SuppressCommandLogging);
output = commandOutputFromLocal8Bit(outputData);
QStringList res;
foreach (const QString &branch, output.split(QLatin1Char('\n'))) {
const QString b = branch.mid(2).trimmed();
if (!b.isEmpty())
res << b;
}
return res;
DiffEditor::DiffEditorController *editorController
= qobject_cast<DiffEditor::DiffEditorController *>(sender());
QString workingDirectory = editorController->workingDirectory();
VcsBase::Command *command = new VcsBase::Command(gitBinaryPath(), workingDirectory,
processEnvironment());
command->setCodec(getSourceCodec(currentDocumentPath()));
connect(command, SIGNAL(output(QString)), editorController,
SLOT(branchesForCommitReceived(QString)));
command->addJob(arguments, -1);
command->execute();
command->setCookie(workingDirectory);
}
bool GitClient::isRemoteCommit(const QString &workingDirectory, const QString &commit)
......
......@@ -241,8 +241,6 @@ public:
QString synchronousTopRevision(const QString &workingDirectory, QString *errorMessage = 0);
void synchronousTagsForCommit(const QString &workingDirectory, const QString &revision,
QString &precedes, QString &follows);
QStringList synchronousBranchesForCommit(const QString &workingDirectory,
const QString &revision);
bool isRemoteCommit(const QString &workingDirectory, const QString &commit);
bool isFastForwardMerge(const QString &workingDirectory, const QString &branch);
......@@ -349,6 +347,7 @@ private slots:
void slotChunkActionsRequested(QMenu *menu, int diffFileIndex, int chunkIndex);
void slotStageChunk();
void slotUnstageChunk();
void branchesForCommit(const QString &revision);
private:
QString makePatch(int diffFileIndex, int chunkIndex, bool revert) 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