ui: clicking snippet title to show full scope
This change lets the user click the snippet title in the CodeView to insert the full scope. The existing snippets are merged with the new lines accordingly.
This commit is contained in:
@@ -52,6 +52,7 @@ QtCodeArea::QtCodeArea(
|
||||
: QPlainTextEdit(parent)
|
||||
, m_fileWidget(file)
|
||||
, m_startLineNumber(startLineNumber)
|
||||
, m_locationFile(locationFile)
|
||||
, m_hoveredAnnotation(nullptr)
|
||||
, m_digits(0)
|
||||
{
|
||||
@@ -102,6 +103,21 @@ QSize QtCodeArea::sizeHint() const
|
||||
return QSize(320, height + 1);
|
||||
}
|
||||
|
||||
uint QtCodeArea::getStartLineNumber() const
|
||||
{
|
||||
return m_startLineNumber;
|
||||
}
|
||||
|
||||
uint QtCodeArea::getEndLineNumber() const
|
||||
{
|
||||
return m_startLineNumber + blockCount() - 1;
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenLocationFile> QtCodeArea::getTokenLocationFile() const
|
||||
{
|
||||
return m_locationFile;
|
||||
}
|
||||
|
||||
void QtCodeArea::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
{
|
||||
QPainter painter(m_lineNumberArea);
|
||||
@@ -331,7 +347,7 @@ void QtCodeArea::createAnnotations(std::shared_ptr<TokenLocationFile> locationFi
|
||||
[&](TokenLocation* startLocation)
|
||||
{
|
||||
Annotation annotation;
|
||||
unsigned int endLineNumber = m_startLineNumber + blockCount() - 1;
|
||||
uint endLineNumber = getEndLineNumber();
|
||||
if (startLocation->getLineNumber() <= endLineNumber)
|
||||
{
|
||||
if (startLocation->getLineNumber() < m_startLineNumber)
|
||||
|
||||
@@ -51,6 +51,11 @@ public:
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
uint getStartLineNumber() const;
|
||||
uint getEndLineNumber() const;
|
||||
|
||||
std::shared_ptr<TokenLocationFile> getTokenLocationFile() const;
|
||||
|
||||
void lineNumberAreaPaintEvent(QPaintEvent *event);
|
||||
int lineNumberDigits() const;
|
||||
int lineNumberAreaWidth() const;
|
||||
@@ -115,6 +120,8 @@ private:
|
||||
|
||||
const uint m_startLineNumber;
|
||||
|
||||
std::shared_ptr<TokenLocationFile> m_locationFile;
|
||||
|
||||
std::vector<Annotation> m_annotations;
|
||||
std::vector<ScopeAnnotation> m_scopeAnnotations;
|
||||
|
||||
|
||||
@@ -78,6 +78,9 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeFileList* parent)
|
||||
m_minimizePlaceholder->setMinimumHeight(5);
|
||||
layout->addWidget(m_minimizePlaceholder);
|
||||
|
||||
m_snippetLayout = new QVBoxLayout();
|
||||
layout->addLayout(m_snippetLayout);
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -113,13 +116,14 @@ const std::vector<std::string>& QtCodeFile::getErrorMessages() const
|
||||
void QtCodeFile::addCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile
|
||||
){
|
||||
std::shared_ptr<QtCodeSnippet> snippet(
|
||||
new QtCodeSnippet(startLineNumber, title, code, locationFile, this));
|
||||
new QtCodeSnippet(startLineNumber, title, titleId, code, locationFile, this));
|
||||
|
||||
layout()->addWidget(snippet.get());
|
||||
m_snippetLayout->addWidget(snippet.get());
|
||||
|
||||
if (locationFile->isWholeCopy)
|
||||
{
|
||||
@@ -132,26 +136,53 @@ void QtCodeFile::addCodeSnippet(
|
||||
|
||||
m_snippets.push_back(snippet);
|
||||
|
||||
if (m_snippets.size() == 1)
|
||||
updateSnippets();
|
||||
}
|
||||
|
||||
QWidget* QtCodeFile::insertCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile
|
||||
){
|
||||
std::shared_ptr<QtCodeSnippet> snippet(
|
||||
new QtCodeSnippet(startLineNumber, title, titleId, code, locationFile, this));
|
||||
|
||||
size_t i = 0;
|
||||
while (i < m_snippets.size())
|
||||
{
|
||||
snippet->setProperty("isFirst", true);
|
||||
uint start = snippet->getStartLineNumber();
|
||||
uint end = snippet->getEndLineNumber();
|
||||
|
||||
std::shared_ptr<QtCodeSnippet> s = m_snippets[i];
|
||||
|
||||
if (s->getEndLineNumber() + 1 < start)
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (s->getStartLineNumber() > end + 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (s->getStartLineNumber() < start || s->getEndLineNumber() > end)
|
||||
{
|
||||
snippet = QtCodeSnippet::merged(snippet.get(), s.get(), this);
|
||||
}
|
||||
|
||||
s->hide();
|
||||
m_snippetLayout->removeWidget(s.get());
|
||||
|
||||
m_snippets.erase(m_snippets.begin() + i);
|
||||
}
|
||||
|
||||
int maxDigits = 1;
|
||||
for (std::shared_ptr<QtCodeSnippet> snippet : m_snippets)
|
||||
{
|
||||
snippet->setProperty("isLast", false);
|
||||
maxDigits = qMax(maxDigits, snippet->lineNumberDigits());
|
||||
}
|
||||
m_snippetLayout->insertWidget(i, snippet.get());
|
||||
m_snippets.insert(m_snippets.begin() + i, snippet);
|
||||
|
||||
for (std::shared_ptr<QtCodeSnippet> snippet : m_snippets)
|
||||
{
|
||||
snippet->updateLineNumberAreaWidthForDigits(maxDigits);
|
||||
}
|
||||
updateSnippets();
|
||||
|
||||
snippet->setProperty("isLast", true);
|
||||
|
||||
clickedSnippetButton();
|
||||
return snippet.get();
|
||||
}
|
||||
|
||||
QWidget* QtCodeFile::findFirstActiveSnippet() const
|
||||
@@ -251,3 +282,25 @@ void QtCodeFile::clickedMaximizeButton()
|
||||
|
||||
m_minimizePlaceholder->hide();
|
||||
}
|
||||
|
||||
void QtCodeFile::updateSnippets()
|
||||
{
|
||||
int maxDigits = 1;
|
||||
for (std::shared_ptr<QtCodeSnippet> snippet : m_snippets)
|
||||
{
|
||||
snippet->setProperty("isFirst", false);
|
||||
snippet->setProperty("isLast", false);
|
||||
|
||||
maxDigits = qMax(maxDigits, snippet->lineNumberDigits());
|
||||
}
|
||||
|
||||
for (std::shared_ptr<QtCodeSnippet> snippet : m_snippets)
|
||||
{
|
||||
snippet->updateLineNumberAreaWidthForDigits(maxDigits);
|
||||
}
|
||||
|
||||
m_snippets.front()->setProperty("isFirst", true);
|
||||
m_snippets.back()->setProperty("isLast", true);
|
||||
|
||||
clickedSnippetButton();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
class QPushButton;
|
||||
class QtCodeFileList;
|
||||
class QtCodeSnippet;
|
||||
class QVBoxLayout;
|
||||
class TokenLocationFile;
|
||||
|
||||
class QtCodeFile
|
||||
@@ -33,6 +34,15 @@ public:
|
||||
void addCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile
|
||||
);
|
||||
|
||||
QWidget* insertCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile
|
||||
);
|
||||
@@ -50,6 +60,8 @@ private slots:
|
||||
void clickedMaximizeButton();
|
||||
|
||||
private:
|
||||
void updateSnippets();
|
||||
|
||||
QtCodeFileList* m_parent;
|
||||
|
||||
QPushButton* m_title;
|
||||
@@ -57,6 +69,7 @@ private:
|
||||
QPushButton* m_snippetButton;
|
||||
QPushButton* m_maximizeButton;
|
||||
|
||||
QVBoxLayout* m_snippetLayout;
|
||||
std::vector<std::shared_ptr<QtCodeSnippet>> m_snippets;
|
||||
std::shared_ptr<QtCodeSnippet> m_fileSnippet;
|
||||
QWidget* m_minimizePlaceholder;
|
||||
|
||||
@@ -43,8 +43,10 @@ QSize QtCodeFileList::sizeHint() const
|
||||
void QtCodeFileList::addCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile
|
||||
std::shared_ptr<TokenLocationFile> locationFile,
|
||||
bool insert
|
||||
){
|
||||
FilePath filePath = locationFile->getFilePath();
|
||||
QtCodeFile* file = nullptr;
|
||||
@@ -67,7 +69,15 @@ void QtCodeFileList::addCodeSnippet(
|
||||
m_frame->layout()->addWidget(file);
|
||||
}
|
||||
|
||||
file->addCodeSnippet(startLineNumber, title, code, locationFile);
|
||||
if (insert)
|
||||
{
|
||||
QWidget* snippet = file->insertCodeSnippet(startLineNumber, title, titleId, code, locationFile);
|
||||
emit shouldScrollToSnippet(snippet);
|
||||
}
|
||||
else
|
||||
{
|
||||
file->addCodeSnippet(startLineNumber, title, titleId, code, locationFile);
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFileList::clearCodeSnippets()
|
||||
|
||||
@@ -29,8 +29,10 @@ public:
|
||||
void addCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile
|
||||
std::shared_ptr<TokenLocationFile> locationFile,
|
||||
bool insert = false
|
||||
);
|
||||
|
||||
void clearCodeSnippets();
|
||||
|
||||
@@ -3,16 +3,65 @@
|
||||
#include <QBoxLayout>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "utility/messaging/type/MessageShowScope.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "qt/element/QtCodeFile.h"
|
||||
|
||||
std::shared_ptr<QtCodeSnippet> QtCodeSnippet::merged(QtCodeSnippet* a, QtCodeSnippet* b, QtCodeFile* file)
|
||||
{
|
||||
QtCodeSnippet* first = a->getStartLineNumber() < b->getStartLineNumber() ? a : b;
|
||||
QtCodeSnippet* second = a->getStartLineNumber() > b->getStartLineNumber() ? a : b;
|
||||
|
||||
TokenLocationFile* aFile = a->m_codeArea->getTokenLocationFile().get();
|
||||
TokenLocationFile* bFile = b->m_codeArea->getTokenLocationFile().get();
|
||||
|
||||
std::shared_ptr<TokenLocationFile> locationFile = std::make_shared<TokenLocationFile>(aFile->getFilePath());
|
||||
|
||||
aFile->forEachTokenLocation(
|
||||
[&locationFile](TokenLocation* loc)
|
||||
{
|
||||
locationFile->addTokenLocationAsPlainCopy(loc);
|
||||
}
|
||||
);
|
||||
|
||||
bFile->forEachTokenLocation(
|
||||
[&locationFile](TokenLocation* loc)
|
||||
{
|
||||
locationFile->addTokenLocationAsPlainCopy(loc);
|
||||
}
|
||||
);
|
||||
|
||||
std::string code;
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(locationFile->getFilePath().str());
|
||||
for (const std::string& line: textAccess->getLines(first->getStartLineNumber(), second->getEndLineNumber()))
|
||||
{
|
||||
code += line;
|
||||
}
|
||||
|
||||
std::string title = first->m_title ? first->m_title->text().toStdString() : "";
|
||||
|
||||
return std::make_shared<QtCodeSnippet>(
|
||||
first->getStartLineNumber(),
|
||||
title,
|
||||
first->m_titleId,
|
||||
code,
|
||||
locationFile,
|
||||
file
|
||||
);
|
||||
}
|
||||
|
||||
QtCodeSnippet::QtCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile,
|
||||
QtCodeFile* file
|
||||
)
|
||||
: QFrame(file)
|
||||
, m_titleId(titleId)
|
||||
, m_dots(nullptr)
|
||||
, m_title(nullptr)
|
||||
, m_codeArea(std::make_shared<QtCodeArea>(startLineNumber, code, locationFile, file, this))
|
||||
@@ -44,6 +93,8 @@ QtCodeSnippet::QtCodeSnippet(
|
||||
m_title->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac
|
||||
m_title->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
titleLayout->addWidget(m_title);
|
||||
|
||||
connect(m_title, SIGNAL(clicked()), this, SLOT(clickedTitle()));
|
||||
}
|
||||
|
||||
layout->addWidget(m_codeArea.get());
|
||||
@@ -54,6 +105,16 @@ QtCodeSnippet::~QtCodeSnippet()
|
||||
{
|
||||
}
|
||||
|
||||
uint QtCodeSnippet::getStartLineNumber() const
|
||||
{
|
||||
return m_codeArea->getStartLineNumber();
|
||||
}
|
||||
|
||||
uint QtCodeSnippet::getEndLineNumber() const
|
||||
{
|
||||
return m_codeArea->getEndLineNumber();
|
||||
}
|
||||
|
||||
int QtCodeSnippet::lineNumberDigits() const
|
||||
{
|
||||
return m_codeArea->lineNumberDigits();
|
||||
@@ -76,6 +137,14 @@ bool QtCodeSnippet::isActive() const
|
||||
return m_codeArea->isActive();
|
||||
}
|
||||
|
||||
void QtCodeSnippet::clickedTitle()
|
||||
{
|
||||
if (m_titleId)
|
||||
{
|
||||
MessageShowScope(m_titleId).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeSnippet::updateDots()
|
||||
{
|
||||
if (!m_dots)
|
||||
|
||||
@@ -20,15 +20,21 @@ class QtCodeSnippet
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static std::shared_ptr<QtCodeSnippet> merged(QtCodeSnippet* a, QtCodeSnippet* b, QtCodeFile* file);
|
||||
|
||||
QtCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile,
|
||||
QtCodeFile* file
|
||||
);
|
||||
virtual ~QtCodeSnippet();
|
||||
|
||||
uint getStartLineNumber() const;
|
||||
uint getEndLineNumber() const;
|
||||
|
||||
int lineNumberDigits() const;
|
||||
|
||||
void updateLineNumberAreaWidthForDigits(int digits);
|
||||
@@ -36,9 +42,14 @@ public:
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
private slots:
|
||||
void clickedTitle();
|
||||
|
||||
private:
|
||||
void updateDots();
|
||||
|
||||
Id m_titleId;
|
||||
|
||||
QPushButton* m_dots;
|
||||
QPushButton* m_title;
|
||||
std::shared_ptr<QtCodeArea> m_codeArea;
|
||||
|
||||
@@ -11,6 +11,7 @@ QtCodeView::QtCodeView(ViewLayout* viewLayout)
|
||||
: CodeView(viewLayout)
|
||||
, m_refreshViewFunctor(std::bind(&QtCodeView::doRefreshView, this))
|
||||
, m_showCodeSnippetsFunctor(std::bind(&QtCodeView::doShowCodeSnippets, this, std::placeholders::_1))
|
||||
, m_addCodeSnippetFunctor(std::bind(&QtCodeView::doAddCodeSnippet, this, std::placeholders::_1))
|
||||
, m_showCodeFileFunctor(std::bind(&QtCodeView::doShowCodeFile, this, std::placeholders::_1))
|
||||
, m_doScrollToFirstActiveSnippetFunctor(std::bind(&QtCodeView::doScrollToFirstActiveSnippet, this))
|
||||
, m_focusTokenFunctor(std::bind(&QtCodeView::doFocusToken, this, std::placeholders::_1))
|
||||
@@ -53,6 +54,11 @@ void QtCodeView::showCodeSnippets(const std::vector<CodeSnippetParams>& snippets
|
||||
m_showCodeSnippetsFunctor(snippets);
|
||||
}
|
||||
|
||||
void QtCodeView::addCodeSnippet(const CodeSnippetParams& snippet)
|
||||
{
|
||||
m_addCodeSnippetFunctor(snippet);
|
||||
}
|
||||
|
||||
void QtCodeView::showCodeFile(const CodeSnippetParams& params)
|
||||
{
|
||||
m_showCodeFileFunctor(params);
|
||||
@@ -88,15 +94,22 @@ void QtCodeView::doShowCodeSnippets(const std::vector<CodeSnippetParams>& snippe
|
||||
|
||||
for (const CodeSnippetParams& params : snippets)
|
||||
{
|
||||
m_widget->addCodeSnippet(params.startLineNumber, params.title, params.code, params.locationFile);
|
||||
m_widget->addCodeSnippet(params.startLineNumber, params.title, params.titleId, params.code, params.locationFile);
|
||||
}
|
||||
|
||||
setStyleSheet(); // so property "isLast" of QtCodeSnippet is computed correctly
|
||||
}
|
||||
|
||||
void QtCodeView::doAddCodeSnippet(const CodeSnippetParams& snippet)
|
||||
{
|
||||
m_widget->addCodeSnippet(snippet.startLineNumber, snippet.title, snippet.titleId, snippet.code, snippet.locationFile, true);
|
||||
|
||||
setStyleSheet(); // so property "isLast" of QtCodeSnippet is computed correctly
|
||||
}
|
||||
|
||||
void QtCodeView::doShowCodeFile(const CodeSnippetParams& params)
|
||||
{
|
||||
m_widget->addCodeSnippet(1, params.title, params.code, params.locationFile);
|
||||
m_widget->addCodeSnippet(1, params.title, 0, params.code, params.locationFile);
|
||||
}
|
||||
|
||||
void QtCodeView::doScrollToFirstActiveSnippet()
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
virtual void setErrorMessages(const std::vector<std::string>& errorMessages);
|
||||
|
||||
virtual void showCodeSnippets(const std::vector<CodeSnippetParams>& snippets);
|
||||
virtual void addCodeSnippet(const CodeSnippetParams& snippet);
|
||||
virtual void showCodeFile(const CodeSnippetParams& params);
|
||||
|
||||
virtual void scrollToFirstActiveSnippet();
|
||||
@@ -41,6 +42,7 @@ private:
|
||||
void doRefreshView();
|
||||
|
||||
void doShowCodeSnippets(const std::vector<CodeSnippetParams>& snippets);
|
||||
void doAddCodeSnippet(const CodeSnippetParams& snippet);
|
||||
void doShowCodeFile(const CodeSnippetParams& params);
|
||||
|
||||
void doScrollToFirstActiveSnippet();
|
||||
@@ -52,6 +54,7 @@ private:
|
||||
|
||||
QtThreadedFunctor<> m_refreshViewFunctor;
|
||||
QtThreadedFunctor<const std::vector<CodeSnippetParams>&> m_showCodeSnippetsFunctor;
|
||||
QtThreadedFunctor<const CodeSnippetParams&> m_addCodeSnippetFunctor;
|
||||
QtThreadedFunctor<const CodeSnippetParams&> m_showCodeFileFunctor;
|
||||
QtThreadedFunctor<> m_doScrollToFirstActiveSnippetFunctor;
|
||||
QtThreadedFunctor<const Id&> m_focusTokenFunctor;
|
||||
|
||||
Reference in New Issue
Block a user