forked from qt-creator/qt-creator
VCS: Pass links to the correct VCS
Current implementation requires each VCS to connect to the referenceClicked signal. Only Git does it, but this is conceptually wrong. If other VCSs would connect to the same signal, all of them will act upon clicking a link, which can result in multiple editors, most of them are likely to be invalid anyway. By default executes vcsDescribe. Can be extended or modified by subclasses. Change-Id: Ib953009efd77446a4b2963f0aa8a2f3f3d26509f Reviewed-by: Artur Shepilko <artur.shepilko@nomadbyte.com> Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
committed by
Orgad Shaneh
parent
cb0b8556c8
commit
92a4c0d38a
@@ -489,20 +489,26 @@ void OutputFormatter::dumpIncompleteLine(const QString &line, OutputFormat forma
|
|||||||
d->incompleteLine.second = format;
|
d->incompleteLine.second = format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OutputFormatter::handleFileLink(const QString &href)
|
||||||
|
{
|
||||||
|
if (!OutputLineParser::isLinkTarget(href))
|
||||||
|
return false;
|
||||||
|
FilePath filePath;
|
||||||
|
int line;
|
||||||
|
int column;
|
||||||
|
OutputLineParser::parseLinkTarget(href, filePath, line, column);
|
||||||
|
QTC_ASSERT(!filePath.isEmpty(), return false);
|
||||||
|
emit openInEditorRequested(filePath, line, column);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void OutputFormatter::handleLink(const QString &href)
|
void OutputFormatter::handleLink(const QString &href)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!href.isEmpty(), return);
|
QTC_ASSERT(!href.isEmpty(), return);
|
||||||
// We can handle absolute file paths ourselves. Other types of references are forwarded
|
// We can handle absolute file paths ourselves. Other types of references are forwarded
|
||||||
// to the line parsers.
|
// to the line parsers.
|
||||||
if (OutputLineParser::isLinkTarget(href)) {
|
if (handleFileLink(href))
|
||||||
FilePath filePath;
|
|
||||||
int line;
|
|
||||||
int column;
|
|
||||||
OutputLineParser::parseLinkTarget(href, filePath, line, column);
|
|
||||||
QTC_ASSERT(!filePath.isEmpty(), return);
|
|
||||||
emit openInEditorRequested(filePath, line, column);
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
for (OutputLineParser * const f : qAsConst(d->lineParsers)) {
|
for (OutputLineParser * const f : qAsConst(d->lineParsers)) {
|
||||||
if (f->handleLink(href))
|
if (f->handleLink(href))
|
||||||
return;
|
return;
|
||||||
|
@@ -151,6 +151,7 @@ public:
|
|||||||
void clear(); // Clears the text edit, if there is one.
|
void clear(); // Clears the text edit, if there is one.
|
||||||
void reset(); // Wipes everything except the text edit.
|
void reset(); // Wipes everything except the text edit.
|
||||||
|
|
||||||
|
bool handleFileLink(const QString &href);
|
||||||
void handleLink(const QString &href);
|
void handleLink(const QString &href);
|
||||||
void setBoldFontEnabled(bool enabled);
|
void setBoldFontEnabled(bool enabled);
|
||||||
|
|
||||||
|
@@ -201,6 +201,13 @@ void IVersionControl::fillLinkContextMenu(QMenu *, const QString &, const QStrin
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IVersionControl::handleLink(const QString &workingDirectory, const QString &reference)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(!reference.isEmpty(), return false);
|
||||||
|
vcsDescribe(workingDirectory, reference);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
|
||||||
#if defined(WITH_TESTS)
|
#if defined(WITH_TESTS)
|
||||||
|
@@ -237,6 +237,8 @@ public:
|
|||||||
const QString &workingDirectory,
|
const QString &workingDirectory,
|
||||||
const QString &reference);
|
const QString &reference);
|
||||||
|
|
||||||
|
virtual bool handleLink(const QString &workingDirectory, const QString &reference);
|
||||||
|
|
||||||
class CORE_EXPORT RepoUrl {
|
class CORE_EXPORT RepoUrl {
|
||||||
public:
|
public:
|
||||||
RepoUrl(const QString &location);
|
RepoUrl(const QString &location);
|
||||||
|
@@ -183,13 +183,17 @@ void OutputWindow::mousePressEvent(QMouseEvent *e)
|
|||||||
QPlainTextEdit::mousePressEvent(e);
|
QPlainTextEdit::mousePressEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputWindow::mouseReleaseEvent(QMouseEvent *e)
|
void OutputWindow::handleLink(const QPoint &pos)
|
||||||
{
|
{
|
||||||
if (d->linksActive && d->mouseButtonPressed == Qt::LeftButton) {
|
const QString href = anchorAt(pos);
|
||||||
const QString href = anchorAt(e->pos());
|
|
||||||
if (!href.isEmpty())
|
if (!href.isEmpty())
|
||||||
d->formatter.handleLink(href);
|
d->formatter.handleLink(href);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputWindow::mouseReleaseEvent(QMouseEvent *e)
|
||||||
|
{
|
||||||
|
if (d->linksActive && d->mouseButtonPressed == Qt::LeftButton)
|
||||||
|
handleLink(e->pos());
|
||||||
|
|
||||||
// Mouse was released, activate links again
|
// Mouse was released, activate links again
|
||||||
d->linksActive = true;
|
d->linksActive = true;
|
||||||
|
@@ -92,6 +92,7 @@ public slots:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool isScrollbarAtBottom() const;
|
bool isScrollbarAtBottom() const;
|
||||||
|
virtual void handleLink(const QPoint &pos);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMimeData *createMimeDataFromSelection() const override;
|
QMimeData *createMimeDataFromSelection() const override;
|
||||||
|
@@ -271,6 +271,15 @@ public:
|
|||||||
GitClient::addChangeActions(menu, workingDirectory, reference);
|
GitClient::addChangeActions(menu, workingDirectory, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool handleLink(const QString &workingDirectory, const QString &reference) final
|
||||||
|
{
|
||||||
|
if (reference.contains(".."))
|
||||||
|
GitClient::instance()->log(workingDirectory, {}, false, {reference});
|
||||||
|
else
|
||||||
|
GitClient::instance()->show(workingDirectory, reference);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
RepoUrl getRepoUrl(const QString &location) const override;
|
RepoUrl getRepoUrl(const QString &location) const override;
|
||||||
|
|
||||||
QStringList additionalToolsPath() const final;
|
QStringList additionalToolsPath() const final;
|
||||||
@@ -1001,16 +1010,6 @@ GitPluginPrivate::GitPluginPrivate()
|
|||||||
m_gerritPlugin->updateActions(currentState());
|
m_gerritPlugin->updateActions(currentState());
|
||||||
m_gerritPlugin->addToLocator(m_commandLocator);
|
m_gerritPlugin->addToLocator(m_commandLocator);
|
||||||
|
|
||||||
connect(VcsOutputWindow::instance(), &VcsOutputWindow::referenceClicked,
|
|
||||||
this, [this](const QString &name) {
|
|
||||||
const VcsBasePluginState state = currentState();
|
|
||||||
QTC_ASSERT(state.hasTopLevel(), return);
|
|
||||||
if (name.contains(".."))
|
|
||||||
m_gitClient.log(state.topLevel(), {}, false, {name});
|
|
||||||
else
|
|
||||||
m_gitClient.show(state.topLevel(), name);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GitPluginPrivate::diffCurrentFile()
|
void GitPluginPrivate::diffCurrentFile()
|
||||||
|
@@ -64,14 +64,17 @@ Utils::OutputLineParser::Result VcsOutputLineParser::handleLine(const QString &t
|
|||||||
return {Status::Done, linkSpecs};
|
return {Status::Done, linkSpecs};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VcsOutputLineParser::handleLink(const QString &href)
|
bool VcsOutputLineParser::handleVcsLink(const QString &workingDirectory, const QString &href)
|
||||||
{
|
{
|
||||||
|
using namespace Core;
|
||||||
QTC_ASSERT(!href.isEmpty(), return false);
|
QTC_ASSERT(!href.isEmpty(), return false);
|
||||||
if (href.startsWith("http://") || href.startsWith("https://"))
|
if (href.startsWith("http://") || href.startsWith("https://")) {
|
||||||
QDesktopServices::openUrl(QUrl(href));
|
QDesktopServices::openUrl(QUrl(href));
|
||||||
else
|
|
||||||
emit referenceClicked(href);
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
if (IVersionControl *vcs = VcsManager::findVersionControlForDirectory(workingDirectory))
|
||||||
|
return vcs->handleLink(workingDirectory, href);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VcsOutputLineParser::fillLinkContextMenu(
|
void VcsOutputLineParser::fillLinkContextMenu(
|
||||||
|
@@ -37,13 +37,10 @@ class VcsOutputLineParser : public Utils::OutputLineParser
|
|||||||
public:
|
public:
|
||||||
VcsOutputLineParser();
|
VcsOutputLineParser();
|
||||||
void fillLinkContextMenu(QMenu *menu, const QString &workingDirectory, const QString &href);
|
void fillLinkContextMenu(QMenu *menu, const QString &workingDirectory, const QString &href);
|
||||||
|
bool handleVcsLink(const QString &workingDirectory, const QString &href);
|
||||||
signals:
|
|
||||||
void referenceClicked(const QString &reference);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Result handleLine(const QString &text, Utils::OutputFormat format) override;
|
Result handleLine(const QString &text, Utils::OutputFormat format) override;
|
||||||
bool handleLink(const QString &href) override;
|
|
||||||
|
|
||||||
const QRegularExpression m_regexp;
|
const QRegularExpression m_regexp;
|
||||||
};
|
};
|
||||||
|
@@ -104,6 +104,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||||
|
void handleLink(const QPoint &pos) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setFormat(VcsOutputWindow::MessageStyle style);
|
void setFormat(VcsOutputWindow::MessageStyle style);
|
||||||
@@ -214,6 +215,23 @@ void OutputWindowPlainTextEdit::contextMenuEvent(QContextMenuEvent *event)
|
|||||||
delete menu;
|
delete menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OutputWindowPlainTextEdit::handleLink(const QPoint &pos)
|
||||||
|
{
|
||||||
|
const QString href = anchorAt(pos);
|
||||||
|
if (href.isEmpty())
|
||||||
|
return;
|
||||||
|
QString repository;
|
||||||
|
identifierUnderCursor(pos, &repository);
|
||||||
|
if (repository.isEmpty()) {
|
||||||
|
OutputWindow::handleLink(pos);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (outputFormatter()->handleFileLink(href))
|
||||||
|
return;
|
||||||
|
if (VcsOutputLineParser * const p = parser())
|
||||||
|
p->handleVcsLink(repository, href);
|
||||||
|
}
|
||||||
|
|
||||||
void OutputWindowPlainTextEdit::appendLines(const QString &s, const QString &repository)
|
void OutputWindowPlainTextEdit::appendLines(const QString &s, const QString &repository)
|
||||||
{
|
{
|
||||||
if (s.isEmpty())
|
if (s.isEmpty())
|
||||||
@@ -310,8 +328,6 @@ VcsOutputWindow::VcsOutputWindow()
|
|||||||
connect(this, &IOutputPane::resetZoom, &d->widget, &Core::OutputWindow::resetZoom);
|
connect(this, &IOutputPane::resetZoom, &d->widget, &Core::OutputWindow::resetZoom);
|
||||||
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,
|
connect(TextEditor::TextEditorSettings::instance(), &TextEditor::TextEditorSettings::behaviorSettingsChanged,
|
||||||
this, updateBehaviorSettings);
|
this, updateBehaviorSettings);
|
||||||
connect(d->widget.parser(), &VcsOutputLineParser::referenceClicked,
|
|
||||||
VcsOutputWindow::instance(), &VcsOutputWindow::referenceClicked);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString filterPasswordFromUrls(QString input)
|
static QString filterPasswordFromUrls(QString input)
|
||||||
|
@@ -76,9 +76,6 @@ public:
|
|||||||
Message, // A blue message text (e.g. "command has finished successfully")
|
Message, // A blue message text (e.g. "command has finished successfully")
|
||||||
};
|
};
|
||||||
|
|
||||||
signals:
|
|
||||||
void referenceClicked(const QString &reference);
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
static void setRepository(const QString &);
|
static void setRepository(const QString &);
|
||||||
static void clearRepository();
|
static void clearRepository();
|
||||||
|
Reference in New Issue
Block a user