aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2018-02-16 12:53:35 +0100
committerJarek Kobus <jaroslaw.kobus@qt.io>2018-03-15 11:21:01 +0000
commitda2c66b1d0f0bf868f4ec88c7e61a57fd1095366 (patch)
tree5ef826190e393c70b9e92e3c13ace0c18d402ead /src
parent24db24734d92f2f3edc9bc1a17851e6ac0df643e (diff)
Move git specific stuff out of diff editor plugin
Move it to the git plugin. Change-Id: I8151573ed50df70776f7ebf0475dd41fb84fae83 Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/diffeditor/descriptionwidgetwatcher.cpp78
-rw-r--r--src/plugins/diffeditor/descriptionwidgetwatcher.h60
-rw-r--r--src/plugins/diffeditor/diffeditor.cpp75
-rw-r--r--src/plugins/diffeditor/diffeditor.pro8
-rw-r--r--src/plugins/diffeditor/diffeditor.qbs2
-rw-r--r--src/plugins/diffeditor/diffeditorconstants.h2
-rw-r--r--src/plugins/diffeditor/diffeditorcontroller.cpp19
-rw-r--r--src/plugins/diffeditor/diffeditorcontroller.h10
-rw-r--r--src/plugins/diffeditor/diffeditordocument.cpp5
-rw-r--r--src/plugins/diffeditor/diffeditordocument.h1
-rw-r--r--src/plugins/git/gitclient.cpp293
-rw-r--r--src/plugins/git/gitclient.h1
-rw-r--r--src/plugins/git/gitconstants.h2
13 files changed, 370 insertions, 186 deletions
diff --git a/src/plugins/diffeditor/descriptionwidgetwatcher.cpp b/src/plugins/diffeditor/descriptionwidgetwatcher.cpp
new file mode 100644
index 0000000000..0e310cfbcd
--- /dev/null
+++ b/src/plugins/diffeditor/descriptionwidgetwatcher.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "descriptionwidgetwatcher.h"
+#include "diffeditor.h"
+#include "diffeditorcontroller.h"
+
+#include <coreplugin/editormanager/documentmodel.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <texteditor/texteditor.h>
+
+using namespace Core;
+
+namespace DiffEditor {
+
+DescriptionWidgetWatcher::DescriptionWidgetWatcher(DiffEditorController *controller)
+ : QObject(controller), m_document(controller->document())
+{
+ const QList<IEditor *> editors = DocumentModel::editorsForDocument(controller->document());
+ for (auto *editor : editors) {
+ if (TextEditor::TextEditorWidget *widget = descriptionWidget(editor))
+ m_widgets.append(widget);
+ }
+
+ connect(EditorManager::instance(), &EditorManager::editorOpened,
+ [this](IEditor *editor) {
+ if (TextEditor::TextEditorWidget *widget = descriptionWidget(editor)) {
+ m_widgets.append(widget);
+ emit descriptionWidgetAdded(widget);
+ }
+ });
+
+ connect(EditorManager::instance(), &EditorManager::editorAboutToClose,
+ [this](IEditor *editor) {
+ if (TextEditor::TextEditorWidget *widget = descriptionWidget(editor)) {
+ emit descriptionWidgetRemoved(widget);
+ m_widgets.removeAll(widget);
+ }
+ });
+}
+
+QList<TextEditor::TextEditorWidget *> DescriptionWidgetWatcher::descriptionWidgets() const
+{
+ return m_widgets;
+}
+
+TextEditor::TextEditorWidget *DescriptionWidgetWatcher::descriptionWidget(Core::IEditor *editor) const
+{
+ if (Internal::DiffEditor *diffEditor = qobject_cast<Internal::DiffEditor *>(editor)) {
+ if (diffEditor->document() == m_document)
+ return diffEditor->descriptionWidget();
+ }
+ return nullptr;
+}
+
+} // namespace DiffEditor
diff --git a/src/plugins/diffeditor/descriptionwidgetwatcher.h b/src/plugins/diffeditor/descriptionwidgetwatcher.h
new file mode 100644
index 0000000000..46988260fe
--- /dev/null
+++ b/src/plugins/diffeditor/descriptionwidgetwatcher.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "diffeditor_global.h"
+
+#include <QObject>
+
+namespace Core {
+class IDocument;
+class IEditor;
+}
+namespace TextEditor { class TextEditorWidget; }
+
+namespace DiffEditor {
+
+class DiffEditorController;
+
+class DIFFEDITOR_EXPORT DescriptionWidgetWatcher : public QObject
+{
+ Q_OBJECT
+public:
+ explicit DescriptionWidgetWatcher(DiffEditorController *controller);
+ QList<TextEditor::TextEditorWidget *> descriptionWidgets() const;
+
+signals:
+ void descriptionWidgetAdded(TextEditor::TextEditorWidget *editor);
+ void descriptionWidgetRemoved(TextEditor::TextEditorWidget *editor);
+
+private:
+ TextEditor::TextEditorWidget *descriptionWidget(Core::IEditor *editor) const;
+
+ QList<TextEditor::TextEditorWidget *> m_widgets;
+ Core::IDocument *m_document = nullptr;
+};
+
+} // namespace DiffEditor
diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp
index d3654d5439..6288f2405b 100644
--- a/src/plugins/diffeditor/diffeditor.cpp
+++ b/src/plugins/diffeditor/diffeditor.cpp
@@ -81,22 +81,11 @@ public:
virtual QSize sizeHint() const override;
-signals:
- void requestBranchList();
-
protected:
- void mouseMoveEvent(QMouseEvent *e) override;
- void mouseReleaseEvent(QMouseEvent *e) override;
-
void setDisplaySettings(const DisplaySettings &ds) override;
void setMarginSettings(const MarginSettings &ms) override;
- bool findContentsUnderCursor(const QTextCursor &cursor);
- void highlightCurrentContents();
- void handleCurrentContents();
-
private:
- QTextCursor m_currentCursor;
Core::IContext *m_context;
};
@@ -153,68 +142,6 @@ void DescriptionEditorWidget::setMarginSettings(const MarginSettings &ms)
TextEditorWidget::setMarginSettings(MarginSettings());
}
-void DescriptionEditorWidget::mouseMoveEvent(QMouseEvent *e)
-{
- if (e->buttons()) {
- TextEditorWidget::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;
- }
-
- TextEditorWidget::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;
- }
- }
-
- TextEditorWidget::mouseReleaseEvent(e);
-}
-
-bool DescriptionEditorWidget::findContentsUnderCursor(const QTextCursor &cursor)
-{
- m_currentCursor = cursor;
- return cursor.block().text() == Constants::EXPAND_BRANCHES;
-}
-
-void DescriptionEditorWidget::highlightCurrentContents()
-{
- QTextEdit::ExtraSelection sel;
- sel.cursor = m_currentCursor;
- sel.cursor.select(QTextCursor::LineUnderCursor);
- sel.format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
- const QColor textColor = TextEditorSettings::fontSettings().formatFor(C_TEXT).foreground();
- sel.format.setUnderlineColor(textColor.isValid() ? textColor : palette().color(QPalette::Foreground));
- setExtraSelections(TextEditorWidget::OtherSelection,
- QList<QTextEdit::ExtraSelection>() << sel);
-}
-
-void DescriptionEditorWidget::handleCurrentContents()
-{
- m_currentCursor.select(QTextCursor::LineUnderCursor);
- m_currentCursor.removeSelectedText();
- m_currentCursor.insertText("Branches: Expanding...");
- emit requestBranchList();
-}
-
///////////////////////////////// DiffEditor //////////////////////////////////
DiffEditor::DiffEditor()
@@ -296,8 +223,6 @@ void DiffEditor::setDocument(QSharedPointer<DiffEditorDocument> doc)
m_document = doc;
- connect(m_descriptionWidget, &DescriptionEditorWidget::requestBranchList,
- m_document.data(), &DiffEditorDocument::requestMoreInformation);
connect(m_document.data(), &DiffEditorDocument::documentChanged,
this, &DiffEditor::documentHasChanged);
connect(m_document.data(), &DiffEditorDocument::descriptionChanged,
diff --git a/src/plugins/diffeditor/diffeditor.pro b/src/plugins/diffeditor/diffeditor.pro
index e9cf72b7fe..5c8c904495 100644
--- a/src/plugins/diffeditor/diffeditor.pro
+++ b/src/plugins/diffeditor/diffeditor.pro
@@ -1,7 +1,9 @@
DEFINES += DIFFEDITOR_LIBRARY
include(../../qtcreatorplugin.pri)
-HEADERS += diffeditor_global.h \
+HEADERS += \
+ descriptionwidgetwatcher.h \
+ diffeditor_global.h \
diffeditor.h \
diffeditorconstants.h \
diffeditorcontroller.h \
@@ -17,7 +19,9 @@ HEADERS += diffeditor_global.h \
unifieddiffeditorwidget.h \
diffeditoricons.h
-SOURCES += diffeditor.cpp \
+SOURCES += \
+ descriptionwidgetwatcher.cpp \
+ diffeditor.cpp \
diffeditorcontroller.cpp \
diffeditordocument.cpp \
diffeditorfactory.cpp \
diff --git a/src/plugins/diffeditor/diffeditor.qbs b/src/plugins/diffeditor/diffeditor.qbs
index 1c190a8dd2..8d0a1a1820 100644
--- a/src/plugins/diffeditor/diffeditor.qbs
+++ b/src/plugins/diffeditor/diffeditor.qbs
@@ -14,6 +14,8 @@ QtcPlugin {
]
files: [
+ "descriptionwidgetwatcher.cpp",
+ "descriptionwidgetwatcher.h",
"diffeditor.cpp",
"diffeditor.h",
"diffeditor.qrc",
diff --git a/src/plugins/diffeditor/diffeditorconstants.h b/src/plugins/diffeditor/diffeditorconstants.h
index c44a5fb84d..e1c9870c98 100644
--- a/src/plugins/diffeditor/diffeditorconstants.h
+++ b/src/plugins/diffeditor/diffeditorconstants.h
@@ -41,7 +41,5 @@ const char UNIFIED_VIEW_ID[] = "DiffEditor.Unified";
const char G_TOOLS_DIFF[] = "QtCreator.Group.Tools.Options";
-const char EXPAND_BRANCHES[] = "Branches: <Expand>";
-
} // namespace Constants
} // namespace DiffEditor
diff --git a/src/plugins/diffeditor/diffeditorcontroller.cpp b/src/plugins/diffeditor/diffeditorcontroller.cpp
index bb2738b985..2cf36902af 100644
--- a/src/plugins/diffeditor/diffeditorcontroller.cpp
+++ b/src/plugins/diffeditor/diffeditorcontroller.cpp
@@ -65,12 +65,6 @@ bool DiffEditorController::ignoreWhitespace() const
return m_document->ignoreWhitespace();
}
-QString DiffEditorController::revisionFromDescription() const
-{
- // TODO: This is specific for git and does not belong here at all!
- return m_document->description().mid(7, 12);
-}
-
QString DiffEditorController::makePatch(int fileIndex, int chunkIndex,
PatchOptions options) const
{
@@ -105,18 +99,9 @@ void DiffEditorController::setDescription(const QString &description)
m_document->setDescription(description);
}
-void DiffEditorController::branchesReceived(const QString &branches)
-{
- QString tmp = m_document->description();
- tmp.replace(Constants::EXPAND_BRANCHES, branches);
- m_document->setDescription(tmp);
-}
-
-void DiffEditorController::requestMoreInformation()
+QString DiffEditorController::description() const
{
- const QString rev = revisionFromDescription();
- if (!rev.isEmpty())
- emit requestInformationForCommit(rev);
+ return m_document->description();
}
/**
diff --git a/src/plugins/diffeditor/diffeditorcontroller.h b/src/plugins/diffeditor/diffeditorcontroller.h
index e5d5ca7418..4578a7f82a 100644
--- a/src/plugins/diffeditor/diffeditorcontroller.h
+++ b/src/plugins/diffeditor/diffeditorcontroller.h
@@ -51,8 +51,6 @@ public:
int contextLineCount() const;
bool ignoreWhitespace() const;
- QString revisionFromDescription() const;
-
enum PatchOption {
NoOption = 0,
Revert = 1,
@@ -65,13 +63,12 @@ public:
const QString &displayName);
static DiffEditorController *controller(Core::IDocument *document);
- void branchesReceived(const QString &branches);
void requestChunkActions(QMenu *menu, int fileIndex, int chunkIndex);
bool chunkExists(int fileIndex, int chunkIndex) const;
+ Core::IDocument *document() const;
signals:
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex);
- void requestInformationForCommit(const QString &revision);
protected:
// reloadFinished() should be called
@@ -84,14 +81,11 @@ protected:
const QString &baseDirectory = QString(),
const QString &startupFile = QString());
void setDescription(const QString &description);
+ QString description() const;
void forceContextLineCount(int lines);
- Core::IDocument *document() const;
private:
- void requestMoreInformation();
-
Internal::DiffEditorDocument *const m_document;
-
bool m_isReloading = false;
friend class Internal::DiffEditorDocument;
diff --git a/src/plugins/diffeditor/diffeditordocument.cpp b/src/plugins/diffeditor/diffeditordocument.cpp
index 0845f3ef03..224d63dc2b 100644
--- a/src/plugins/diffeditor/diffeditordocument.cpp
+++ b/src/plugins/diffeditor/diffeditordocument.cpp
@@ -69,11 +69,6 @@ void DiffEditorDocument::setController(DiffEditorController *controller)
if (m_controller)
m_controller->deleteLater();
m_controller = controller;
-
- if (m_controller) {
- connect(this, &DiffEditorDocument::requestMoreInformation,
- m_controller, &DiffEditorController::requestMoreInformation);
- }
}
DiffEditorController *DiffEditorDocument::controller() const
diff --git a/src/plugins/diffeditor/diffeditordocument.h b/src/plugins/diffeditor/diffeditordocument.h
index 2a5293dfaf..a9dff53faa 100644
--- a/src/plugins/diffeditor/diffeditordocument.h
+++ b/src/plugins/diffeditor/diffeditordocument.h
@@ -90,7 +90,6 @@ signals:
void temporaryStateChanged();
void documentChanged();
void descriptionChanged();
- void requestMoreInformation();
private:
void beginReload();
diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index f642f8ba7e..92803826d6 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -62,9 +62,14 @@
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h>
+#include <diffeditor/descriptionwidgetwatcher.h>
#include <diffeditor/diffeditorconstants.h>
#include <diffeditor/diffeditorcontroller.h>
#include <diffeditor/diffutils.h>
+
+#include <texteditor/fontsettings.h>
+#include <texteditor/texteditorsettings.h>
+
#include <utils/utilsicons.h>
#include <QAction>
@@ -76,8 +81,9 @@
#include <QMessageBox>
#include <QPushButton>
#include <QRegExp>
-#include <QTextCodec>
+#include <QTextBlock>
#include <QToolButton>
+#include <QTextCodec>
const char GIT_DIRECTORY[] = ".git";
const char graphLogFormatC[] = "%h %d %an %s %ci";
@@ -112,6 +118,153 @@ const unsigned silentFlags = unsigned(VcsCommand::SuppressCommandLogging
| VcsCommand::SuppressStdErr
| VcsCommand::SuppressFailMessage);
+static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first)
+{
+ const int limit = 12;
+ const int count = branches->count();
+ int more = 0;
+ QString output;
+ if (*first)
+ *first = false;
+ else
+ output += QString(sizeof(BRANCHES_PREFIX) - 1, ' '); // Align
+ output += prefix + ": ";
+ // If there are more than 'limit' branches, list limit/2 (first limit/4 and last limit/4)
+ if (count > limit) {
+ const int leave = limit / 2;
+ more = count - leave;
+ branches->erase(branches->begin() + leave / 2 + 1, branches->begin() + count - leave / 2);
+ (*branches)[leave / 2] = "...";
+ }
+ output += branches->join(", ");
+ //: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'"
+ // in git show.
+ if (more > 0)
+ output += ' ' + GitClient::tr("and %n more", 0, more);
+ return output;
+}
+
+class DescriptionWidgetDecorator : public QObject
+{
+ Q_OBJECT
+public:
+ DescriptionWidgetDecorator(DescriptionWidgetWatcher *watcher);
+
+ bool eventFilter(QObject *watched, QEvent *event) override;
+
+signals:
+ void branchListRequested();
+
+private:
+ bool checkContentsUnderCursor(const QTextCursor &cursor) const;
+ void highlightCurrentContents(TextEditor::TextEditorWidget *textEditor,
+ const QTextCursor &cursor);
+ void handleCurrentContents(const QTextCursor &cursor);
+ void addWatch(TextEditor::TextEditorWidget *widget);
+ void removeWatch(TextEditor::TextEditorWidget *widget);
+
+ DescriptionWidgetWatcher *m_watcher;
+ QHash<QObject *, TextEditor::TextEditorWidget *> m_viewportToTextEditor;
+};
+
+DescriptionWidgetDecorator::DescriptionWidgetDecorator(DescriptionWidgetWatcher *watcher)
+ : QObject(),
+ m_watcher(watcher)
+{
+ QList<TextEditor::TextEditorWidget *> widgets = m_watcher->descriptionWidgets();
+ for (auto *widget : widgets)
+ addWatch(widget);
+
+ connect(m_watcher, &DescriptionWidgetWatcher::descriptionWidgetAdded,
+ this, &DescriptionWidgetDecorator::addWatch);
+ connect(m_watcher, &DescriptionWidgetWatcher::descriptionWidgetRemoved,
+ this, &DescriptionWidgetDecorator::removeWatch);
+}
+
+bool DescriptionWidgetDecorator::eventFilter(QObject *watched, QEvent *event)
+{
+ TextEditor::TextEditorWidget *textEditor = m_viewportToTextEditor.value(watched);
+ if (!textEditor)
+ return QObject::eventFilter(watched, event);
+
+ if (event->type() == QEvent::MouseMove) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+ if (mouseEvent->buttons())
+ return QObject::eventFilter(watched, event);
+
+ Qt::CursorShape cursorShape;
+
+ const QTextCursor cursor = textEditor->cursorForPosition(mouseEvent->pos());
+ if (checkContentsUnderCursor(cursor)) {
+ highlightCurrentContents(textEditor, cursor);
+ cursorShape = Qt::PointingHandCursor;
+ } else {
+ textEditor->setExtraSelections(TextEditor::TextEditorWidget::OtherSelection,
+ QList<QTextEdit::ExtraSelection>());
+ cursorShape = Qt::IBeamCursor;
+ }
+
+ bool ret = QObject::eventFilter(watched, event);
+ textEditor->viewport()->setCursor(cursorShape);
+ return ret;
+ } else if (event->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
+
+ if (mouseEvent->button() == Qt::LeftButton && !(mouseEvent->modifiers() & Qt::ShiftModifier)) {
+ const QTextCursor cursor = textEditor->cursorForPosition(mouseEvent->pos());
+ if (checkContentsUnderCursor(cursor)) {
+ handleCurrentContents(cursor);
+ return true;
+ }
+ }
+
+ return QObject::eventFilter(watched, event);
+ }
+ return QObject::eventFilter(watched, event);
+}
+
+bool DescriptionWidgetDecorator::checkContentsUnderCursor(const QTextCursor &cursor) const
+{
+ return cursor.block().text() == Constants::EXPAND_BRANCHES;
+}
+
+void DescriptionWidgetDecorator::highlightCurrentContents(
+ TextEditor::TextEditorWidget *textEditor, const QTextCursor &cursor)
+{
+ QTextEdit::ExtraSelection sel;
+ sel.cursor = cursor;
+ sel.cursor.select(QTextCursor::LineUnderCursor);
+ sel.format.setUnderlineStyle(QTextCharFormat::SingleUnderline);
+ const QColor textColor = TextEditor::TextEditorSettings::fontSettings().formatFor(TextEditor::C_TEXT).foreground();
+ sel.format.setUnderlineColor(textColor.isValid() ? textColor : textEditor->palette().color(QPalette::Foreground));
+ textEditor->setExtraSelections(TextEditor::TextEditorWidget::OtherSelection,
+ QList<QTextEdit::ExtraSelection>() << sel);
+}
+
+void DescriptionWidgetDecorator::handleCurrentContents(const QTextCursor &cursor)
+{
+ QTextCursor copy = cursor;
+
+ copy.select(QTextCursor::LineUnderCursor);
+ copy.removeSelectedText();
+ copy.insertText("Branches: Expanding...");
+ emit branchListRequested();
+}
+
+void DescriptionWidgetDecorator::addWatch(TextEditor::TextEditorWidget *widget)
+{
+ m_viewportToTextEditor.insert(widget->viewport(), widget);
+ widget->viewport()->installEventFilter(this);
+}
+
+void DescriptionWidgetDecorator::removeWatch(TextEditor::TextEditorWidget *widget)
+{
+ widget->viewport()->removeEventFilter(this);
+ m_viewportToTextEditor.remove(widget->viewport());
+}
+
+///////////////////////////////
+
class GitDiffEditorController : public VcsBaseDiffEditorController
{
Q_OBJECT
@@ -124,13 +277,75 @@ protected:
QStringList addConfigurationArguments(const QStringList &args) const;
QStringList addHeadWhenCommandInProgress() const;
+
+private:
+ void updateBranchList();
+
+ DescriptionWidgetWatcher m_watcher;
+ DescriptionWidgetDecorator m_decorator;
};
GitDiffEditorController::GitDiffEditorController(IDocument *document, const QString &workingDirectory) :
- VcsBaseDiffEditorController(document, GitPlugin::client(), workingDirectory)
+ VcsBaseDiffEditorController(document, GitPlugin::client(), workingDirectory),
+ m_watcher(this),
+ m_decorator(&m_watcher)
{
+ connect(&m_decorator, &DescriptionWidgetDecorator::branchListRequested,
+ this, &GitDiffEditorController::updateBranchList);
}
+void GitDiffEditorController::updateBranchList()
+{
+ const QString revision = description().mid(7, 12);
+ if (revision.isEmpty())
+ return;
+
+ const QString workingDirectory = baseDirectory();
+ VcsCommand *command = GitPlugin::client()->vcsExec(
+ workingDirectory, {"branch", noColorOption, "-a", "--contains", revision}, nullptr,
+ false, 0, workingDirectory);
+ connect(command, &VcsCommand::stdOutText, [this](const QString &text) {
+ const QString remotePrefix = "remotes/";
+ const QString localPrefix = "<Local>";
+ const int prefixLength = remotePrefix.length();
+ QString output = BRANCHES_PREFIX;
+ QStringList branches;
+ QString previousRemote = localPrefix;
+ bool first = true;
+ for (const QString &branch : text.split('\n')) {
+ const QString b = branch.mid(2).trimmed();
+ if (b.isEmpty())
+ continue;
+ if (b.startsWith(remotePrefix)) {
+ const int nextSlash = b.indexOf('/', prefixLength);
+ if (nextSlash < 0)
+ continue;
+ const QString remote = b.mid(prefixLength, nextSlash - prefixLength);
+ if (remote != previousRemote) {
+ output += branchesDisplay(previousRemote, &branches, &first) + '\n';
+ branches.clear();
+ previousRemote = remote;
+ }
+ branches << b.mid(nextSlash + 1);
+ } else {
+ branches << b;
+ }
+ }
+ if (branches.isEmpty()) {
+ if (previousRemote == localPrefix)
+ output += tr("<None>");
+ } else {
+ output += branchesDisplay(previousRemote, &branches, &first);
+ }
+ const QString branchList = output.trimmed();
+ QString newDescription = description();
+ newDescription.replace(Constants::EXPAND_BRANCHES, branchList);
+ setDescription(newDescription);
+ });
+}
+
+///////////////////////////////
+
void GitDiffEditorController::runCommand(const QList<QStringList> &args, QTextCodec *codec)
{
VcsBaseDiffEditorController::runCommand(args, diffExecutionFlags(), codec);
@@ -679,8 +894,6 @@ void GitClient::requestReload(const QString &documentId, const QString &source,
connect(controller, &DiffEditorController::chunkActionsRequested,
this, &GitClient::chunkActionsRequested, Qt::DirectConnection);
- connect(controller, &DiffEditorController::requestInformationForCommit,
- this, &GitClient::branchesForCommit);
VcsBasePlugin::setSource(document, sourceCopy);
EditorManager::activateEditorForDocument(document);
@@ -1379,76 +1592,6 @@ void GitClient::synchronousTagsForCommit(const QString &workingDirectory, const
}
}
-static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first)
-{
- const int limit = 12;
- const int count = branches->count();
- int more = 0;
- QString output;
- if (*first)
- *first = false;
- else
- output += QString(sizeof(BRANCHES_PREFIX) - 1, ' '); // Align
- output += prefix + ": ";
- // If there are more than 'limit' branches, list limit/2 (first limit/4 and last limit/4)
- if (count > limit) {
- const int leave = limit / 2;
- more = count - leave;
- branches->erase(branches->begin() + leave / 2 + 1, branches->begin() + count - leave / 2);
- (*branches)[leave / 2] = "...";
- }
- output += branches->join(", ");
- //: Displayed after the untranslated message "Branches: branch1, branch2 'and %n more'"
- // in git show.
- if (more > 0)
- output += ' ' + GitClient::tr("and %n more", 0, more);
- return output;
-}
-
-void GitClient::branchesForCommit(const QString &revision)
-{
- auto controller = qobject_cast<DiffEditorController *>(sender());
- QString workingDirectory = controller->baseDirectory();
- VcsCommand *command = vcsExec(
- workingDirectory, {"branch", noColorOption, "-a", "--contains", revision}, nullptr,
- false, 0, workingDirectory);
- connect(command, &VcsCommand::stdOutText, controller, [controller](const QString &text) {
- const QString remotePrefix = "remotes/";
- const QString localPrefix = "<Local>";
- const int prefixLength = remotePrefix.length();
- QString output = BRANCHES_PREFIX;
- QStringList branches;
- QString previousRemote = localPrefix;
- bool first = true;
- for (const QString &branch : text.split('\n')) {
- const QString b = branch.mid(2).trimmed();
- if (b.isEmpty())
- continue;
- if (b.startsWith(remotePrefix)) {
- const int nextSlash = b.indexOf('/', prefixLength);
- if (nextSlash < 0)
- continue;
- const QString remote = b.mid(prefixLength, nextSlash - prefixLength);
- if (remote != previousRemote) {
- output += branchesDisplay(previousRemote, &branches, &first) + '\n';
- branches.clear();
- previousRemote = remote;
- }
- branches << b.mid(nextSlash + 1);
- } else {
- branches << b;
- }
- }
- if (branches.isEmpty()) {
- if (previousRemote == localPrefix)
- output += tr("<None>");
- } else {
- output += branchesDisplay(previousRemote, &branches, &first);
- }
- controller->branchesReceived(output.trimmed());
- });
-}
-
bool GitClient::isRemoteCommit(const QString &workingDirectory, const QString &commit)
{
return !vcsFullySynchronousExec(
@@ -2110,7 +2253,7 @@ QString GitClient::extendedShowDescription(const QString &workingDirectory, cons
// Empty line before headers and commit message
const int emptyLine = modText.indexOf("\n\n");
if (emptyLine != -1)
- modText.insert(emptyLine, QString('\n') + DiffEditor::Constants::EXPAND_BRANCHES);
+ modText.insert(emptyLine, QString('\n') + Constants::EXPAND_BRANCHES);
return modText;
}
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index 206a3c7b7b..655b49c9e0 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -330,7 +330,6 @@ public:
private:
void finishSubmoduleUpdate();
void chunkActionsRequested(QMenu *menu, int fileIndex, int chunkIndex);
- void branchesForCommit(const QString &revision);
void stage(DiffEditor::DiffEditorController *diffController,
const QString &patch, bool revert);
diff --git a/src/plugins/git/gitconstants.h b/src/plugins/git/gitconstants.h
index 6d81196c32..d817fcda28 100644
--- a/src/plugins/git/gitconstants.h
+++ b/src/plugins/git/gitconstants.h
@@ -53,5 +53,7 @@ const char C_GITEDITORID[] = "Git Editor";
const int OBSOLETE_COMMIT_AGE_IN_DAYS = 90;
+const char EXPAND_BRANCHES[] = "Branches: <Expand>";
+
} // namespace Constants
} // namespace Git