forked from qt-creator/qt-creator
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: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
281aa9e0d6
commit
d6583f0f47
@@ -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;
|
||||
|
Reference in New Issue
Block a user