diff --git a/bin/app/data/gui/code_view/code_view.css b/bin/app/data/gui/code_view/code_view.css index 199f07f4..e3420beb 100644 --- a/bin/app/data/gui/code_view/code_view.css +++ b/bin/app/data/gui/code_view/code_view.css @@ -14,19 +14,28 @@ color: black; } -#code_snippet { +#code_file #code_snippet #title_label { + background-color: rgb(220,220,220); + font-family: "Source Code Pro"; + border-top-right-radius: 10px; + font-size: 14px; + text-align: left; + padding: 4px 12px; +} + +#code_area { font-family: "Source Code Pro"; font-size: 14px; margin-bottom: 2px; } -#code_snippet #line_number_area { +#code_area #line_number_area { background-color: white; font-family: "Source Code Pro"; font-size: 14px; } -#code_snippet #maximize_button { +#code_area #maximize_button { border: none; border-image: none; margin: 5px; @@ -34,7 +43,7 @@ max-width: 16px; } -#code_snippet #maximize_button:enabled { +#code_area #maximize_button:enabled { border-image: url(data/gui/code_view/images/button_maximize.png); } diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index 3a1301be..1258a0c1 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -7,6 +7,8 @@ add_files( qt/element/QtAutocompletionList.cpp qt/element/QtAutocompletionList.h + qt/element/QtCodeArea.cpp + qt/element/QtCodeArea.h qt/element/QtCodeFile.cpp qt/element/QtCodeFile.h qt/element/QtCodeFileList.cpp diff --git a/src/app/qt/element/QtCodeArea.cpp b/src/app/qt/element/QtCodeArea.cpp new file mode 100644 index 00000000..4e0c1db1 --- /dev/null +++ b/src/app/qt/element/QtCodeArea.cpp @@ -0,0 +1,438 @@ +#include "qt/element/QtCodeArea.h" + +#include +#include +#include +#include +#include + +#include "utility/messaging/type/MessageActivateTokenLocation.h" +#include "utility/messaging/type/MessageShowFile.h" + +#include "data/location/TokenLocation.h" +#include "data/location/TokenLocationFile.h" +#include "qt/element/QtCodeFile.h" +#include "qt/utility/QtHighlighter.h" +#include "settings/ApplicationSettings.h" + +QtCodeArea::LineNumberArea::LineNumberArea(QtCodeArea *codeArea) + : QWidget(codeArea) + , m_codeArea(codeArea) +{ + setObjectName("line_number_area"); +} + +QtCodeArea::LineNumberArea::~LineNumberArea() +{ +} + +QSize QtCodeArea::LineNumberArea::sizeHint() const +{ + return QSize(m_codeArea->lineNumberAreaWidth(), 0); +} + +void QtCodeArea::LineNumberArea::paintEvent(QPaintEvent *event) +{ + m_codeArea->lineNumberAreaPaintEvent(event); +} + + +QtCodeArea::QtCodeArea( + uint startLineNumber, + const std::string& code, + std::shared_ptr locationFile, + QtCodeFile* parent +) + : QPlainTextEdit(parent) + , m_parent(parent) + , m_maximizeButton(nullptr) + , m_startLineNumber(startLineNumber) + , m_hoveredAnnotation(nullptr) + , m_digits(0) +{ + setObjectName("code_area"); + setReadOnly(true); + setFrameStyle(QFrame::NoFrame); + setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Fixed); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setLineWrapMode(QPlainTextEdit::NoWrap); + + m_lineNumberArea = new LineNumberArea(this); + m_highlighter = new QtHighlighter(document()); + + std::string displayCode = code; + if (*code.rbegin() == '\n') + { + displayCode.pop_back(); + } + + setPlainText(QString::fromUtf8(displayCode.c_str())); + createAnnotations(locationFile); + annotateText(); + + m_digits = lineNumberDigits(); + updateLineNumberAreaWidth(0); + + connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(selectionChanged()), this, SLOT(clearSelection())); + + this->setMouseTracking(true); +} + +QtCodeArea::~QtCodeArea() +{ +} + +QSize QtCodeArea::sizeHint() const +{ + int width = 480; + int height = (document()->size().height() + 0.7f) * fontMetrics().lineSpacing(); + return QSize(width, height); +} + +void QtCodeArea::addMaximizeButton() +{ + QHBoxLayout* layout = new QHBoxLayout(); + layout->setMargin(0); + layout->setSpacing(0); + layout->setAlignment(Qt::AlignTop); + setLayout(layout); + + m_maximizeButton = new QPushButton(this); + m_maximizeButton->setObjectName("maximize_button"); + m_maximizeButton->setEnabled(false); + layout->addWidget(m_maximizeButton); + layout->setAlignment(m_maximizeButton, Qt::AlignRight); + + connect(m_maximizeButton, SIGNAL(clicked()), this, SLOT(clickedMaximizeButton())); +} + +void QtCodeArea::lineNumberAreaPaintEvent(QPaintEvent *event) +{ + QPainter painter(m_lineNumberArea); + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = static_cast(blockBoundingGeometry(block).translated(contentOffset()).top()); + int bottom = top + static_cast(blockBoundingRect(block).height()); + + while (block.isValid() && top <= event->rect().bottom()) + { + if (block.isVisible() && bottom >= event->rect().top()) + { + QString number = QString::number(blockNumber + m_startLineNumber); + painter.setPen(Qt::black); + painter.drawText(0, top, m_lineNumberArea->width() - 13, fontMetrics().height(), Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + static_cast(blockBoundingRect(block).height()); + blockNumber++; + } +} + +int QtCodeArea::lineNumberDigits() const +{ + int digits = 1; + int max = qMax(1, int(m_startLineNumber) + blockCount()); + + while (max >= 10) + { + max /= 10; + digits++; + } + return digits; +} + +int QtCodeArea::lineNumberAreaWidth() const +{ + return fontMetrics().width(QLatin1Char('9')) * m_digits + 30; +} + +void QtCodeArea::updateLineNumberAreaWidthForDigits(int digits) +{ + m_digits = digits; + updateLineNumberAreaWidth(0); +} + +void QtCodeArea::update() +{ + annotateText(); +} + +void QtCodeArea::resizeEvent(QResizeEvent *e) +{ + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + m_lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); +} + +void QtCodeArea::showEvent(QShowEvent* event) +{ + int tabWidth = ApplicationSettings::getInstance()->getCodeTabWidth(); + setTabStopWidth(tabWidth * fontMetrics().width('9')); + + setMaximumHeight(sizeHint().height()); +} + +void QtCodeArea::enterEvent(QEvent* event) +{ + if (m_maximizeButton) + { + m_maximizeButton->setEnabled(true); + } +} + +void QtCodeArea::leaveEvent(QEvent* event) +{ + if (m_maximizeButton) + { + m_maximizeButton->setEnabled(false); + } + + m_hoveredAnnotation = nullptr; + annotateText(); +} + +void QtCodeArea::mouseReleaseEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton) + { + QTextCursor cursor = this->cursorForPosition(event->pos()); + const Annotation* annotation = findAnnotationForPosition(cursor.position()); + + if (annotation) + { + MessageActivateTokenLocation(annotation->locationId).dispatch(); + } + } +} + +void QtCodeArea::mouseDoubleClickEvent(QMouseEvent* event) +{ + if (event->button() == Qt::LeftButton && m_maximizeButton) + { + clickedMaximizeButton(); + } +} + +void QtCodeArea::mouseMoveEvent(QMouseEvent* event) +{ + QTextCursor cursor = this->cursorForPosition(event->pos()); + const Annotation* annotation = findAnnotationForPosition(cursor.position()); + + if (annotation && annotation->isScope) + { + annotation = nullptr; + } + + if (annotation != m_hoveredAnnotation) + { + m_hoveredAnnotation = annotation; + + const std::vector& errorMessages = m_parent->getErrorMessages(); + + if (annotation && errorMessages.size() > annotation->tokenId) + { + QToolTip::showText(event->globalPos(), QString::fromStdString(m_parent->getErrorMessages()[annotation->tokenId])); + } + else + { + QToolTip::hideText(); + } + + annotateText(); + } +} + +void QtCodeArea::updateLineNumberAreaWidth(int /* newBlockCount */) +{ + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); +} + +void QtCodeArea::updateLineNumberArea(const QRect &rect, int dy) +{ + if (dy) + { + m_lineNumberArea->scroll(0, dy); + } + else + { + m_lineNumberArea->update(0, rect.y(), m_lineNumberArea->width(), rect.height()); + } + + if (rect.contains(viewport()->rect())) + { + updateLineNumberAreaWidth(0); + } +} + +void QtCodeArea::clickedMaximizeButton() +{ + MessageShowFile(m_parent->getFilePath().absoluteStr(), m_startLineNumber, m_startLineNumber + blockCount() - 1).dispatch(); +} + +void QtCodeArea::clearSelection() +{ + QTextCursor cursor = textCursor(); + cursor.clearSelection(); + setTextCursor(cursor); +} + +const QtCodeArea::Annotation* QtCodeArea::findAnnotationForPosition(int pos) const +{ + const Annotation* annotationPtr = nullptr; + int diff = endTextEditPosition() + 1; + + for (const Annotation& annotation : m_annotations) + { + if (pos >= annotation.start && pos <= annotation.end) + { + int d = annotation.end - annotation.start; + if (d < diff) + { + diff = d; + annotationPtr = &annotation; + } + } + } + + return annotationPtr; +} + +void QtCodeArea::createAnnotations(std::shared_ptr locationFile) +{ + locationFile->forEachStartTokenLocation( + [&](TokenLocation* startLocation) + { + Annotation annotation; + int endLineNumber = m_startLineNumber + blockCount() - 1; + if (startLocation->getLineNumber() <= endLineNumber) + { + if (startLocation->getLineNumber() < m_startLineNumber) + { + annotation.start = startTextEditPosition(); + } + else + { + annotation.start = toTextEditPosition(startLocation->getLineNumber(), startLocation->getColumnNumber() - 1); + } + } + else + { + return; + } + + TokenLocation* endLocation = startLocation->getEndTokenLocation(); + if (endLocation->getLineNumber() >= m_startLineNumber) + { + if (endLocation->getLineNumber() > endLineNumber) + { + annotation.end = endTextEditPosition(); + } + else + { + annotation.end = toTextEditPosition(endLocation->getLineNumber(), endLocation->getColumnNumber()); + } + } + else + { + return; + } + + annotation.tokenId = startLocation->getTokenId(); + annotation.locationId = startLocation->getId(); + annotation.isScope = (startLocation->getType() == TokenLocation::LOCATION_SCOPE); + m_annotations.push_back(annotation); + } + ); +} + +void QtCodeArea::annotateText() +{ + Colori color; + const std::vector& ids = m_parent->getActiveTokenIds(); + const std::vector& errorMessages = m_parent->getErrorMessages(); + QList extraSelections; + + for (const Annotation& annotation: m_annotations) + { + bool isActive = std::find(ids.begin(), ids.end(), annotation.tokenId) != ids.end(); + + if (&annotation == m_hoveredAnnotation && errorMessages.size()) + { + color = Colori(255, 0, 0, 128); + } + else if (&annotation == m_hoveredAnnotation) + { + color = ApplicationSettings::getInstance()->getCodeActiveLinkColor(); + } + else if (errorMessages.size()) + { + color = Colori(255, 0, 0, 255); + } + else if (isActive) + { + color = ApplicationSettings::getInstance()->getCodeActiveLinkColor(); + + if (annotation.isScope) + { + color.a /= 2; + } + } + else if (annotation.isScope) + { + color = ApplicationSettings::getInstance()->getCodeScopeColor(); + } + else + { + color = ApplicationSettings::getInstance()->getCodeLinkColor(); + } + + QTextEdit::ExtraSelection selection; + selection.format.setBackground(QColor(color.r, color.g, color.b, color.a)); + + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + selection.cursor.setPosition(annotation.start); + selection.cursor.setPosition(annotation.end, QTextCursor::KeepAnchor); + + extraSelections.append(selection); + } + + setExtraSelections(extraSelections); +} + +int QtCodeArea::toTextEditPosition(int lineNumber, int columnNumber) const +{ + lineNumber -= m_startLineNumber - 1; + int position = 0; + + for (int i = 0; i < lineNumber - 1; i++) + { + position += document()->findBlockByLineNumber(i).length(); + } + + position += columnNumber; + return position; +} + +int QtCodeArea::startTextEditPosition() const +{ + return 0; +} + +int QtCodeArea::endTextEditPosition() const +{ + int position = 0; + + for (int i = 0; i < document()->blockCount(); i++) + { + position += document()->findBlockByLineNumber(i).length(); + } + + return position - 1; +} diff --git a/src/app/qt/element/QtCodeArea.h b/src/app/qt/element/QtCodeArea.h new file mode 100644 index 00000000..68b2c111 --- /dev/null +++ b/src/app/qt/element/QtCodeArea.h @@ -0,0 +1,110 @@ +#ifndef QT_CODE_AREA_H +#define QT_CODE_AREA_H + +#include +#include + +#include + +#include "utility/types.h" + +class QPaintEvent; +class QPushButton; +class QResizeEvent; +class QSize; +class QtCodeFile; +class QtHighlighter; +class QWidget; +class TokenLocation; +class TokenLocationFile; + +class QtCodeArea: public QPlainTextEdit +{ + Q_OBJECT + +public: + class LineNumberArea: public QWidget + { + public: + LineNumberArea(QtCodeArea *codeArea); + virtual ~LineNumberArea(); + + QSize sizeHint() const; + + protected: + void paintEvent(QPaintEvent* event); + + private: + QtCodeArea *m_codeArea; + }; + + QtCodeArea( + uint startLineNumber, + const std::string& code, + std::shared_ptr locationFile, + QtCodeFile* parent + ); + virtual ~QtCodeArea(); + + QSize sizeHint() const; + + void addMaximizeButton(); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberDigits() const; + int lineNumberAreaWidth() const; + void updateLineNumberAreaWidthForDigits(int digits); + + void update(); + +protected: + virtual void resizeEvent(QResizeEvent *event); + virtual void showEvent(QShowEvent* event); + virtual void enterEvent(QEvent* event); + virtual void leaveEvent(QEvent* event); + virtual void mouseReleaseEvent(QMouseEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* event); + virtual void mouseMoveEvent(QMouseEvent* event); + +private slots: + void updateLineNumberAreaWidth(int newBlockCount); + void updateLineNumberArea(const QRect &, int); + void clickedMaximizeButton(); + void clearSelection(); + +private: + struct Annotation + { + int start; + int end; + Id tokenId; + Id locationId; + bool isScope; + }; + + const Annotation* findAnnotationForPosition(int pos) const; + void createAnnotations(std::shared_ptr locationFile); + void annotateText(); + + bool locationBelongsToSnippet(TokenLocation* location) const; + + int toTextEditPosition(int lineNumber, int columnNumber) const; + int startTextEditPosition() const; + int endTextEditPosition() const; + + QtCodeFile* m_parent; + + QWidget* m_lineNumberArea; + QtHighlighter* m_highlighter; + + QPushButton* m_maximizeButton; + + const uint m_startLineNumber; + + std::vector m_annotations; + const Annotation* m_hoveredAnnotation; + + int m_digits; +}; + +#endif // QT_CODE_AREA_H diff --git a/src/app/qt/element/QtCodeFile.cpp b/src/app/qt/element/QtCodeFile.cpp index 76d7930a..e51eb76d 100644 --- a/src/app/qt/element/QtCodeFile.cpp +++ b/src/app/qt/element/QtCodeFile.cpp @@ -61,11 +61,12 @@ const std::vector& QtCodeFile::getErrorMessages() const void QtCodeFile::addCodeSnippet( uint startLineNumber, + const std::string& title, const std::string& code, - const TokenLocationFile& locationFile + std::shared_ptr locationFile ){ std::shared_ptr snippet( - new QtCodeSnippet(startLineNumber, code, locationFile, this)); + new QtCodeSnippet(startLineNumber, title, code, locationFile, this)); if (m_parent->getShowMaximizeButton()) { diff --git a/src/app/qt/element/QtCodeFile.h b/src/app/qt/element/QtCodeFile.h index 95e4b3f2..cc834fa1 100644 --- a/src/app/qt/element/QtCodeFile.h +++ b/src/app/qt/element/QtCodeFile.h @@ -31,8 +31,9 @@ public: void addCodeSnippet( uint startLineNumber, + const std::string& title, const std::string& code, - const TokenLocationFile& locationFile + std::shared_ptr locationFile ); void update(); diff --git a/src/app/qt/element/QtCodeFileList.cpp b/src/app/qt/element/QtCodeFileList.cpp index bd3825b9..0ad7cfdf 100644 --- a/src/app/qt/element/QtCodeFileList.cpp +++ b/src/app/qt/element/QtCodeFileList.cpp @@ -36,10 +36,11 @@ QSize QtCodeFileList::sizeHint() const void QtCodeFileList::addCodeSnippet( uint startLineNumber, + const std::string& title, const std::string& code, - const TokenLocationFile& locationFile + std::shared_ptr locationFile ){ - FilePath filePath = locationFile.getFilePath(); + FilePath filePath = locationFile->getFilePath(); QtCodeFile* file = nullptr; for (std::shared_ptr filePtr : m_files) @@ -53,14 +54,14 @@ void QtCodeFileList::addCodeSnippet( if (!file) { - std::shared_ptr filePtr = std::make_shared(locationFile.getFilePath(), this); + std::shared_ptr filePtr = std::make_shared(locationFile->getFilePath(), this); m_files.push_back(filePtr); file = filePtr.get(); m_frame->layout()->addWidget(file); } - file->addCodeSnippet(startLineNumber, code, locationFile); + file->addCodeSnippet(startLineNumber, title, code, locationFile); } void QtCodeFileList::clearCodeSnippets() diff --git a/src/app/qt/element/QtCodeFileList.h b/src/app/qt/element/QtCodeFileList.h index 806b8c49..1c3918ad 100644 --- a/src/app/qt/element/QtCodeFileList.h +++ b/src/app/qt/element/QtCodeFileList.h @@ -24,8 +24,9 @@ public: void addCodeSnippet( uint startLineNumber, + const std::string& title, const std::string& code, - const TokenLocationFile& locationFile + std::shared_ptr locationFile ); void clearCodeSnippets(); diff --git a/src/app/qt/element/QtCodeSnippet.cpp b/src/app/qt/element/QtCodeSnippet.cpp index 86f8088d..ad7fea04 100644 --- a/src/app/qt/element/QtCodeSnippet.cpp +++ b/src/app/qt/element/QtCodeSnippet.cpp @@ -1,466 +1,59 @@ #include "qt/element/QtCodeSnippet.h" -#include #include -#include #include -#include -#include "utility/messaging/type/MessageActivateTokenLocation.h" -#include "utility/messaging/type/MessageShowFile.h" - -#include "data/location/TokenLocation.h" -#include "data/location/TokenLocationFile.h" #include "qt/element/QtCodeFile.h" -#include "qt/utility/QtHighlighter.h" -#include "settings/ApplicationSettings.h" - -QtCodeSnippet::LineNumberArea::LineNumberArea(QtCodeSnippet *codeSnippet) - : QWidget(codeSnippet) - , m_codeSnippet(codeSnippet) -{ - setObjectName("line_number_area"); -} - -QtCodeSnippet::LineNumberArea::~LineNumberArea() -{ -} - -QSize QtCodeSnippet::LineNumberArea::sizeHint() const -{ - return QSize(m_codeSnippet->lineNumberAreaWidth(), 0); -} - -void QtCodeSnippet::LineNumberArea::paintEvent(QPaintEvent *event) -{ - m_codeSnippet->lineNumberAreaPaintEvent(event); -} - QtCodeSnippet::QtCodeSnippet( uint startLineNumber, + const std::string& title, const std::string& code, - const TokenLocationFile& locationFile, + std::shared_ptr locationFile, QtCodeFile* parent ) - : QPlainTextEdit(parent) + : QWidget(parent) , m_parent(parent) - , m_maximizeButton(nullptr) - , m_startLineNumber(startLineNumber) - , m_hoveredAnnotation(nullptr) - , m_digits(0) + , m_codeArea(std::make_shared(startLineNumber, code, locationFile, parent)) { setObjectName("code_snippet"); - setReadOnly(true); - setFrameStyle(QFrame::NoFrame); - setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Fixed); - setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - setLineWrapMode(QPlainTextEdit::NoWrap); - m_lineNumberArea = new LineNumberArea(this); - m_highlighter = new QtHighlighter(document()); + QVBoxLayout* layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->setSpacing(0); + layout->setAlignment(Qt::AlignTop); + setLayout(layout); - std::string displayCode = code; - if (*code.rbegin() == '\n') - { - displayCode.pop_back(); - } + m_title = new QPushButton(title.c_str(), this); + m_title->setObjectName("title_label"); + m_title->minimumSizeHint(); // force font loading + m_title->setAttribute(Qt::WA_LayoutUsesWidgetRect); // fixes layouting on Mac + m_title->setSizePolicy(sizePolicy().horizontalPolicy(), QSizePolicy::Fixed); + layout->addWidget(m_title); - setPlainText(QString::fromUtf8(displayCode.c_str())); - createAnnotations(locationFile); - annotateText(); - - m_digits = lineNumberDigits(); - updateLineNumberAreaWidth(0); - - connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); - connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); - connect(this, SIGNAL(selectionChanged()), this, SLOT(clearSelection())); - - this->setMouseTracking(true); + layout->addWidget(m_codeArea.get()); } QtCodeSnippet::~QtCodeSnippet() { } -QSize QtCodeSnippet::sizeHint() const -{ - int width = 480; - int height = (document()->size().height() + 0.7f) * fontMetrics().lineSpacing(); - return QSize(width, height); -} - void QtCodeSnippet::addMaximizeButton() { - QHBoxLayout* layout = new QHBoxLayout(); - layout->setMargin(0); - layout->setSpacing(0); - layout->setAlignment(Qt::AlignTop); - setLayout(layout); - - m_maximizeButton = new QPushButton(this); - m_maximizeButton->setObjectName("maximize_button"); - m_maximizeButton->setEnabled(false); - layout->addWidget(m_maximizeButton); - layout->setAlignment(m_maximizeButton, Qt::AlignRight); - - connect(m_maximizeButton, SIGNAL(clicked()), this, SLOT(clickedMaximizeButton())); -} - -void QtCodeSnippet::lineNumberAreaPaintEvent(QPaintEvent *event) -{ - QPainter painter(m_lineNumberArea); - - QTextBlock block = firstVisibleBlock(); - int blockNumber = block.blockNumber(); - int top = static_cast(blockBoundingGeometry(block).translated(contentOffset()).top()); - int bottom = top + static_cast(blockBoundingRect(block).height()); - - while (block.isValid() && top <= event->rect().bottom()) - { - if (block.isVisible() && bottom >= event->rect().top()) - { - QString number = QString::number(blockNumber + m_startLineNumber); - painter.setPen(Qt::black); - painter.drawText(0, top, m_lineNumberArea->width() - 13, fontMetrics().height(), Qt::AlignRight, number); - } - - block = block.next(); - top = bottom; - bottom = top + static_cast(blockBoundingRect(block).height()); - blockNumber++; - } + m_codeArea->addMaximizeButton(); } int QtCodeSnippet::lineNumberDigits() const { - int digits = 1; - int max = qMax(1, int(m_startLineNumber) + blockCount()); - - while (max >= 10) - { - max /= 10; - digits++; - } - return digits; -} - -int QtCodeSnippet::lineNumberAreaWidth() const -{ - return fontMetrics().width(QLatin1Char('9')) * m_digits + 30; + return m_codeArea->lineNumberDigits(); } void QtCodeSnippet::updateLineNumberAreaWidthForDigits(int digits) { - m_digits = digits; - updateLineNumberAreaWidth(0); + m_codeArea->updateLineNumberAreaWidthForDigits(digits); } void QtCodeSnippet::update() { - annotateText(); -} - -void QtCodeSnippet::resizeEvent(QResizeEvent *e) -{ - QPlainTextEdit::resizeEvent(e); - - QRect cr = contentsRect(); - m_lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); -} - -void QtCodeSnippet::showEvent(QShowEvent* event) -{ - int tabWidth = ApplicationSettings::getInstance()->getCodeTabWidth(); - setTabStopWidth(tabWidth * fontMetrics().width('9')); - - setMaximumHeight(sizeHint().height()); -} - -void QtCodeSnippet::enterEvent(QEvent* event) -{ - if (m_maximizeButton) - { - m_maximizeButton->setEnabled(true); - } -} - -void QtCodeSnippet::leaveEvent(QEvent* event) -{ - if (m_maximizeButton) - { - m_maximizeButton->setEnabled(false); - } - - m_hoveredAnnotation = nullptr; - annotateText(); -} - -void QtCodeSnippet::mouseReleaseEvent(QMouseEvent* event) -{ - if (event->button() == Qt::LeftButton) - { - QTextCursor cursor = this->cursorForPosition(event->pos()); - const Annotation* annotation = findAnnotationForPosition(cursor.position()); - - if (annotation) - { - MessageActivateTokenLocation(annotation->locationId).dispatch(); - } - } -} - -void QtCodeSnippet::mouseDoubleClickEvent(QMouseEvent* event) -{ - if (event->button() == Qt::LeftButton && m_maximizeButton) - { - clickedMaximizeButton(); - } -} - -void QtCodeSnippet::mouseMoveEvent(QMouseEvent* event) -{ - QTextCursor cursor = this->cursorForPosition(event->pos()); - const Annotation* annotation = findAnnotationForPosition(cursor.position()); - - if (annotation && annotation->isScope) - { - annotation = nullptr; - } - - if (annotation != m_hoveredAnnotation) - { - m_hoveredAnnotation = annotation; - - const std::vector& errorMessages = m_parent->getErrorMessages(); - - if (annotation && errorMessages.size() > annotation->tokenId) - { - QToolTip::showText(event->globalPos(), QString::fromStdString(m_parent->getErrorMessages()[annotation->tokenId])); - } - else - { - QToolTip::hideText(); - } - - annotateText(); - } -} - -void QtCodeSnippet::updateLineNumberAreaWidth(int /* newBlockCount */) -{ - setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); -} - -void QtCodeSnippet::updateLineNumberArea(const QRect &rect, int dy) -{ - if (dy) - { - m_lineNumberArea->scroll(0, dy); - } - else - { - m_lineNumberArea->update(0, rect.y(), m_lineNumberArea->width(), rect.height()); - } - - if (rect.contains(viewport()->rect())) - { - updateLineNumberAreaWidth(0); - } -} - -void QtCodeSnippet::clickedMaximizeButton() -{ - MessageShowFile(m_parent->getFilePath().absoluteStr(), m_startLineNumber, m_startLineNumber + blockCount() - 1).dispatch(); -} - -void QtCodeSnippet::clearSelection() -{ - QTextCursor cursor = textCursor(); - cursor.clearSelection(); - setTextCursor(cursor); -} - -const QtCodeSnippet::Annotation* QtCodeSnippet::findAnnotationForPosition(int pos) const -{ - const Annotation* annotationPtr = nullptr; - int diff = endTextEditPosition() + 1; - - for (const Annotation& annotation : m_annotations) - { - if (pos >= annotation.start && pos <= annotation.end) - { - int d = annotation.end - annotation.start; - if (d < diff) - { - diff = d; - annotationPtr = &annotation; - } - } - } - - return annotationPtr; -} - -void QtCodeSnippet::createAnnotations(const TokenLocationFile& locationFile) -{ - locationFile.forEachTokenLocation( - [&](TokenLocation* location) - { - if (!locationBelongsToSnippet(location)) - { - return; - } - - Annotation annotation; - if (location->isStartTokenLocation() && location->getLineNumber() >= m_startLineNumber) - { - annotation.start = toTextEditPosition(location->getLineNumber(), location->getColumnNumber() - 1); - } - else - { - annotation.start = startTextEditPosition(); - } - - TokenLocation* endLocation = location->getEndTokenLocation(); - if (endLocation) - { - annotation.end = toTextEditPosition(endLocation->getLineNumber(), endLocation->getColumnNumber()); - } - else - { - annotation.end = endTextEditPosition(); - } - - annotation.tokenId = location->getTokenId(); - annotation.locationId = location->getId(); - annotation.isScope = location->getType() == TokenLocation::LOCATION_SCOPE; - - m_annotations.push_back(annotation); - } - ); -} - -void QtCodeSnippet::annotateText() -{ - Colori color; - const std::vector& ids = m_parent->getActiveTokenIds(); - const std::vector& errorMessages = m_parent->getErrorMessages(); - QList extraSelections; - - for (const Annotation& annotation: m_annotations) - { - bool isActive = std::find(ids.begin(), ids.end(), annotation.tokenId) != ids.end(); - - if (&annotation == m_hoveredAnnotation && errorMessages.size()) - { - color = Colori(255, 0, 0, 128); - } - else if (&annotation == m_hoveredAnnotation) - { - color = ApplicationSettings::getInstance()->getCodeActiveLinkColor(); - } - else if (errorMessages.size()) - { - color = Colori(255, 0, 0, 255); - } - else if (isActive) - { - color = ApplicationSettings::getInstance()->getCodeActiveLinkColor(); - - if (annotation.isScope) - { - color.a /= 2; - } - } - else if (annotation.isScope) - { - color = ApplicationSettings::getInstance()->getCodeScopeColor(); - } - else - { - color = ApplicationSettings::getInstance()->getCodeLinkColor(); - } - - QTextEdit::ExtraSelection selection; - selection.format.setBackground(QColor(color.r, color.g, color.b, color.a)); - - selection.cursor = textCursor(); - selection.cursor.clearSelection(); - selection.cursor.setPosition(annotation.start); - selection.cursor.setPosition(annotation.end, QTextCursor::KeepAnchor); - - extraSelections.append(selection); - } - - setExtraSelections(extraSelections); -} - -bool QtCodeSnippet::locationBelongsToSnippet(TokenLocation* location) const -{ - uint lineNumber = location->getLineNumber(); - - if (location->isEndTokenLocation()) - { - if (location->getStartTokenLocation() || - lineNumber < m_startLineNumber || lineNumber >= m_startLineNumber + blockCount()) - { - return false; - } - else - { - return true; - } - } - - if (lineNumber >= m_startLineNumber + blockCount()) - { - return false; - } - - if (lineNumber >= m_startLineNumber) - { - return true; - } - - TokenLocation* endLocation = location->getEndTokenLocation(); - - if (endLocation && endLocation->getLineNumber() < m_startLineNumber) - { - return false; - } - - return true; -} - -int QtCodeSnippet::toTextEditPosition(int lineNumber, int columnNumber) const -{ - lineNumber -= m_startLineNumber - 1; - int position = 0; - - for (int i = 0; i < lineNumber - 1; i++) - { - position += document()->findBlockByLineNumber(i).length(); - } - - position += columnNumber; - return position; -} - -int QtCodeSnippet::startTextEditPosition() const -{ - return 0; -} - -int QtCodeSnippet::endTextEditPosition() const -{ - int position = 0; - - for (int i = 0; i < document()->blockCount(); i++) - { - position += document()->findBlockByLineNumber(i).length(); - } - - return position - 1; + m_codeArea->update(); } diff --git a/src/app/qt/element/QtCodeSnippet.h b/src/app/qt/element/QtCodeSnippet.h index 56d708e4..dd42cf41 100644 --- a/src/app/qt/element/QtCodeSnippet.h +++ b/src/app/qt/element/QtCodeSnippet.h @@ -2,108 +2,41 @@ #define QT_CODE_SNIPPET_H #include - -#include +#include #include "utility/types.h" +#include "qt/element/QtCodeArea.h" -class QPaintEvent; -class QPushButton; -class QResizeEvent; -class QSize; class QtCodeFile; -class QtHighlighter; class QWidget; -class TokenLocation; class TokenLocationFile; -class QtCodeSnippet: public QPlainTextEdit +class QtCodeSnippet: public QWidget { Q_OBJECT public: - class LineNumberArea: public QWidget - { - public: - LineNumberArea(QtCodeSnippet *codeSnippet); - virtual ~LineNumberArea(); - - QSize sizeHint() const; - - protected: - void paintEvent(QPaintEvent* event); - - private: - QtCodeSnippet *m_codeSnippet; - }; QtCodeSnippet( uint startLineNumber, + const std::string& title, const std::string& code, - const TokenLocationFile& locationFile, + std::shared_ptr locationFile, QtCodeFile* parent ); virtual ~QtCodeSnippet(); - QSize sizeHint() const; - void addMaximizeButton(); - void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberDigits() const; - int lineNumberAreaWidth() const; - void updateLineNumberAreaWidthForDigits(int digits); + void updateLineNumberAreaWidthForDigits(int digits); void update(); -protected: - virtual void resizeEvent(QResizeEvent *event); - virtual void showEvent(QShowEvent* event); - virtual void enterEvent(QEvent* event); - virtual void leaveEvent(QEvent* event); - virtual void mouseReleaseEvent(QMouseEvent* event); - virtual void mouseDoubleClickEvent(QMouseEvent* event); - virtual void mouseMoveEvent(QMouseEvent* event); - -private slots: - void updateLineNumberAreaWidth(int newBlockCount); - void updateLineNumberArea(const QRect &, int); - void clickedMaximizeButton(); - void clearSelection(); - private: - struct Annotation - { - int start; - int end; - Id tokenId; - Id locationId; - bool isScope; - }; - - const Annotation* findAnnotationForPosition(int pos) const; - void createAnnotations(const TokenLocationFile& locationFile); - void annotateText(); - - bool locationBelongsToSnippet(TokenLocation* location) const; - - int toTextEditPosition(int lineNumber, int columnNumber) const; - int startTextEditPosition() const; - int endTextEditPosition() const; - - QtCodeFile* m_parent; - - QWidget* m_lineNumberArea; - QtHighlighter* m_highlighter; - - QPushButton* m_maximizeButton; - - const uint m_startLineNumber; - - std::vector m_annotations; - const Annotation* m_hoveredAnnotation; - - int m_digits; + QtCodeFile* m_parent; // need this? + QPushButton* m_title; + std::shared_ptr m_codeArea; }; #endif // QT_CODE_SNIPPET_H diff --git a/src/app/qt/view/QtCodeView.cpp b/src/app/qt/view/QtCodeView.cpp index d90067e7..b1033526 100644 --- a/src/app/qt/view/QtCodeView.cpp +++ b/src/app/qt/view/QtCodeView.cpp @@ -90,7 +90,7 @@ void QtCodeView::doShowCodeSnippets(const std::vector& snippe for (const CodeSnippetParams& params : snippets) { - m_widget->addCodeSnippet(params.startLineNumber, params.code, params.locationFile); + m_widget->addCodeSnippet(params.startLineNumber, params.title, params.code, params.locationFile); } } @@ -102,9 +102,9 @@ void QtCodeView::doShowCodeFile(const CodeSnippetParams& params) ptr->setShowMaximizeButton(false); ptr->setActiveTokenIds(m_activeTokenIds); ptr->setErrorMessages(m_errorMessages); - ptr->addCodeSnippet(1, params.code, params.locationFile); + ptr->addCodeSnippet(1, params.title, params.code, params.locationFile); - ptr->setWindowTitle(params.locationFile.getFilePath().fileName().c_str()); + ptr->setWindowTitle(params.locationFile->getFilePath().fileName().c_str()); ptr->show(); float percent = float(params.startLineNumber + params.endLineNumber) / float(params.lineCount) / 2; diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 5efb36ea..5a2d2be5 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -1,9 +1,11 @@ #include "component/controller/CodeController.h" +#include #include "data/access/StorageAccess.h" #include "data/location/TokenLocation.h" #include "data/location/TokenLocationCollection.h" #include "data/location/TokenLocationFile.h" +#include "data/location/TokenLocationLine.h" #include "settings/ApplicationSettings.h" #include "utility/text/TextAccess.h" @@ -54,7 +56,7 @@ void CodeController::handleMessage(MessageFinishedParsing* message) std::vector snippets; errorCollection.forEachTokenLocationFile( - [&](TokenLocationFile* file) -> void + [&](std::shared_ptr file) -> void { std::vector fileSnippets = getSnippetsForFile(file); snippets.insert(snippets.end(), fileSnippets.begin(), fileSnippets.end()); @@ -101,7 +103,7 @@ std::vector CodeController::getSnippetsForActiveTok std::vector snippets; collection.forEachTokenLocationFile( - [&](TokenLocationFile* file) -> void + [&](std::shared_ptr file) -> void { std::vector fileSnippets = getSnippetsForFile(file); @@ -116,7 +118,7 @@ std::vector CodeController::getSnippetsForActiveTok bool isDeclarationFile = false; for (const CodeView::CodeSnippetParams& snippet : fileSnippets) { - snippet.locationFile.forEachTokenLocation( + snippet.locationFile->forEachTokenLocation( [&](TokenLocation* location) { if (location->getTokenId() == declarationId) @@ -142,7 +144,7 @@ std::vector CodeController::getSnippetsForActiveTok return snippets; } -std::vector CodeController::getSnippetsForFile(const TokenLocationFile* file) const +std::vector CodeController::getSnippetsForFile(std::shared_ptr file) const { std::shared_ptr textAccess = TextAccess::createFromFile(file->getFilePath().str()); @@ -174,10 +176,24 @@ std::vector CodeController::getSnippetsForFile(cons for (const SnippetMerger::Range& range: ranges) { CodeView::CodeSnippetParams params; - params.locationFile = *file; + params.locationFile = file; params.startLineNumber = std::max(1, range.start.row - (range.start.strong ? 0 : snippetExpandRange)); params.endLineNumber = std::min(textAccess->getLineCount(), range.end.row + (range.end.strong ? 0 : snippetExpandRange)); + + std::shared_ptr tempFile = m_storageAccess->getTokenLocationsForLinesInFile(file->getFilePath().str(), params.startLineNumber, params.endLineNumber); + TokenLocationLine* firstUsedLine = nullptr; + for (rsize_t i = params.startLineNumber; i <= params.endLineNumber, firstUsedLine == nullptr; i++) + { + firstUsedLine = tempFile->findTokenLocationLineByNumber(i); + } + m_storageAccess->getTokenLocationOfParentScope(firstUsedLine->getTokenLocations().begin()->second.get())->forEachStartTokenLocation( + [&](TokenLocation* location) + { + params.title = m_storageAccess->getNameForNodeWithId(location->getTokenId()); + } + ); + for (const std::string& line: textAccess->getLines(params.startLineNumber, params.endLineNumber)) { params.code += line; diff --git a/src/lib/component/controller/CodeController.h b/src/lib/component/controller/CodeController.h index 7ce8cb5d..20bfcf85 100644 --- a/src/lib/component/controller/CodeController.h +++ b/src/lib/component/controller/CodeController.h @@ -4,6 +4,7 @@ #include #include +#include "component/controller/helper/SnippetMerger.h" #include "component/controller/Controller.h" #include "component/view/CodeView.h" #include "utility/messaging/MessageListener.h" @@ -14,10 +15,6 @@ #include "utility/messaging/type/MessageShowFile.h" #include "utility/types.h" - - -#include "component/controller/helper/SnippetMerger.h" - class StorageAccess; class TokenLocationFile; @@ -46,7 +43,7 @@ private: std::vector getSnippetsForActiveTokenIds( const std::vector& ids, Id declarationId) const; - std::vector getSnippetsForFile(const TokenLocationFile* file) const; + std::vector getSnippetsForFile(std::shared_ptr file) const; std::shared_ptr buildMergerHierarchy( TokenLocation* location, SnippetMerger& fileScopedMerger, std::map>& mergers) const; diff --git a/src/lib/component/view/CodeView.cpp b/src/lib/component/view/CodeView.cpp index 5a616f8c..8eacea55 100644 --- a/src/lib/component/view/CodeView.cpp +++ b/src/lib/component/view/CodeView.cpp @@ -7,7 +7,7 @@ CodeView::CodeSnippetParams::CodeSnippetParams() : startLineNumber(0) , endLineNumber(0) , lineCount(0) - , locationFile("") + , locationFile(std::make_shared("")) , isActive(false) , isDeclaration(false) { @@ -40,8 +40,8 @@ bool CodeView::CodeSnippetParams::sort(const CodeSnippetParams& a, const CodeSni return false; } - const FilePath& aFilePath = a.locationFile.getFilePath(); - const FilePath& bFilePath = b.locationFile.getFilePath(); + const FilePath& aFilePath = a.locationFile->getFilePath(); + const FilePath& bFilePath = b.locationFile->getFilePath(); // different files if (aFilePath != bFilePath) diff --git a/src/lib/component/view/CodeView.h b/src/lib/component/view/CodeView.h index 073ce661..03b47f99 100644 --- a/src/lib/component/view/CodeView.h +++ b/src/lib/component/view/CodeView.h @@ -1,6 +1,8 @@ #ifndef CODE_VIEW_H #define CODE_VIEW_H +#include + #include "component/view/View.h" #include "data/location/TokenLocationFile.h" #include "utility/types.h" @@ -21,9 +23,10 @@ public: uint endLineNumber; uint lineCount; + std::string title; std::string code; - TokenLocationFile locationFile; + std::shared_ptr locationFile; bool isActive; bool isDeclaration; diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp index 4cd53f0d..5a545f3f 100644 --- a/src/lib/data/Storage.cpp +++ b/src/lib/data/Storage.cpp @@ -976,9 +976,9 @@ TokenLocationCollection Storage::getTokenLocationsForTokenIds(const std::vector< return ret; } -TokenLocationFile Storage::getTokenLocationsForFile(const std::string& filePath) const +std::shared_ptr Storage::getTokenLocationsForFile(const std::string& filePath) const { - TokenLocationFile ret(filePath); + std::shared_ptr ret = std::make_shared(filePath); TokenLocationFile* locationFile = m_locationCollection.findTokenLocationFileByPath(filePath); if (!locationFile) @@ -989,18 +989,18 @@ TokenLocationFile Storage::getTokenLocationsForFile(const std::string& filePath) locationFile->forEachTokenLocation( [&](TokenLocation* tokenLocation) -> void { - ret.addTokenLocationAsPlainCopy(tokenLocation); + ret->addTokenLocationAsPlainCopy(tokenLocation); } ); return ret; } -TokenLocationFile Storage::getTokenLocationsForLinesInFile( +std::shared_ptr Storage::getTokenLocationsForLinesInFile( const std::string& filePath, uint firstLineNumber, uint lastLineNumber ) const { - TokenLocationFile ret(filePath); + std::shared_ptr ret = std::make_shared(filePath); TokenLocationFile* locationFile = m_locationCollection.findTokenLocationFileByPath(filePath); if (!locationFile) @@ -1009,7 +1009,7 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile( } uint endLineNumber = locationFile->getTokenLocationLines().rbegin()->first; - + std::set addedLocationIds; for (uint i = firstLineNumber; i <= endLineNumber; i++) { TokenLocationLine* locationLine = locationFile->findTokenLocationLineByNumber(i); @@ -1023,7 +1023,13 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile( locationLine->forEachTokenLocation( [&](TokenLocation* tokenLocation) -> void { - ret.addTokenLocationAsPlainCopy(tokenLocation); + const Id tokenId = tokenLocation->getId(); + if (addedLocationIds.find(tokenId) == addedLocationIds.end()) + { + ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation()); + ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation()); + addedLocationIds.insert(tokenId); + } } ); } @@ -1036,7 +1042,8 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile( if (tokenLocation->isEndTokenLocation() && tokenLocation->getStartTokenLocation()->getLineNumber() < firstLineNumber) { - ret.addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation()); + ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation()); + ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation()); } } ); @@ -1062,7 +1069,6 @@ std::shared_ptr Storage::getTokenLocationOfParentScope(const [&](TokenLocation* tokenLocation) -> void { if (tokenLocation->getType() == TokenLocation::LOCATION_SCOPE && - tokenLocation->isStartTokenLocation() && (*tokenLocation) < *(child->getStartTokenLocation()) && (*tokenLocation->getEndTokenLocation()) > *(child->getEndTokenLocation())) { diff --git a/src/lib/data/Storage.h b/src/lib/data/Storage.h index d1b812bc..2f79fb13 100644 --- a/src/lib/data/Storage.h +++ b/src/lib/data/Storage.h @@ -119,8 +119,8 @@ public: virtual std::vector getTokenIdsForQuery(std::string query) const; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const; - virtual TokenLocationFile getTokenLocationsForFile(const std::string& filePath) const; - virtual TokenLocationFile getTokenLocationsForLinesInFile( + virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const; + virtual std::shared_ptr getTokenLocationsForLinesInFile( const std::string& filePath, uint firstLineNumber, uint lastLineNumber ) const; diff --git a/src/lib/data/access/StorageAccess.h b/src/lib/data/access/StorageAccess.h index 0836294f..10a00a6e 100644 --- a/src/lib/data/access/StorageAccess.h +++ b/src/lib/data/access/StorageAccess.h @@ -34,8 +34,8 @@ public: virtual std::vector getTokenIdsForQuery(std::string query) const = 0; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const = 0; - virtual TokenLocationFile getTokenLocationsForFile(const std::string& filePath) const = 0; - virtual TokenLocationFile getTokenLocationsForLinesInFile( + virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const = 0; + virtual std::shared_ptr getTokenLocationsForLinesInFile( const std::string& filePath, uint firstLineNumber, uint lastLineNumber) const = 0; virtual TokenLocationCollection getErrorTokenLocations(std::vector* errorMessages) const = 0; diff --git a/src/lib/data/access/StorageAccessProxy.cpp b/src/lib/data/access/StorageAccessProxy.cpp index d4357a45..ef38f80c 100644 --- a/src/lib/data/access/StorageAccessProxy.cpp +++ b/src/lib/data/access/StorageAccessProxy.cpp @@ -122,17 +122,17 @@ TokenLocationCollection StorageAccessProxy::getTokenLocationsForTokenIds(const s return TokenLocationCollection(); } -TokenLocationFile StorageAccessProxy::getTokenLocationsForFile(const std::string& filePath) const +std::shared_ptr StorageAccessProxy::getTokenLocationsForFile(const std::string& filePath) const { if (hasSubject()) { return m_subject->getTokenLocationsForFile(filePath); } - return TokenLocationFile(""); + return std::make_shared(""); } -TokenLocationFile StorageAccessProxy::getTokenLocationsForLinesInFile( +std::shared_ptr StorageAccessProxy::getTokenLocationsForLinesInFile( const std::string& filePath, uint firstLineNumber, uint lastLineNumber ) const { @@ -141,7 +141,7 @@ TokenLocationFile StorageAccessProxy::getTokenLocationsForLinesInFile( return m_subject->getTokenLocationsForLinesInFile(filePath, firstLineNumber, lastLineNumber); } - return TokenLocationFile(""); + return std::make_shared(""); } TokenLocationCollection StorageAccessProxy::getErrorTokenLocations(std::vector* errorMessages) const diff --git a/src/lib/data/access/StorageAccessProxy.h b/src/lib/data/access/StorageAccessProxy.h index ca03ce79..1de7324e 100644 --- a/src/lib/data/access/StorageAccessProxy.h +++ b/src/lib/data/access/StorageAccessProxy.h @@ -27,8 +27,8 @@ public: virtual std::vector getTokenIdsForQuery(std::string query) const; virtual TokenLocationCollection getTokenLocationsForTokenIds(const std::vector& tokenIds) const; - virtual TokenLocationFile getTokenLocationsForFile(const std::string& filePath) const; - virtual TokenLocationFile getTokenLocationsForLinesInFile( + virtual std::shared_ptr getTokenLocationsForFile(const std::string& filePath) const; + virtual std::shared_ptr getTokenLocationsForLinesInFile( const std::string& filePath, uint firstLineNumber, uint lastLineNumber ) const; diff --git a/src/lib/data/location/TokenLocationCollection.cpp b/src/lib/data/location/TokenLocationCollection.cpp index cfe99446..022a1479 100644 --- a/src/lib/data/location/TokenLocationCollection.cpp +++ b/src/lib/data/location/TokenLocationCollection.cpp @@ -105,11 +105,11 @@ TokenLocationFile* TokenLocationCollection::findTokenLocationFileByPath(const Fi return nullptr; } -void TokenLocationCollection::forEachTokenLocationFile(std::function func) const +void TokenLocationCollection::forEachTokenLocationFile(std::function)> func) const { for (const TokenLocationFilePairType& file : m_files) { - func(file.second.get()); + func(file.second); } } @@ -188,9 +188,9 @@ TokenLocationFile* TokenLocationCollection::createTokenLocationFile(const FilePa std::ostream& operator<<(std::ostream& ostream, const TokenLocationCollection& base) { ostream << "Locations:\n"; - base.forEachTokenLocationFile([&ostream](TokenLocationFile* f) + base.forEachTokenLocationFile([&ostream](std::shared_ptr f) { - ostream << *f; + ostream << *(f.get()); }); return ostream; } diff --git a/src/lib/data/location/TokenLocationCollection.h b/src/lib/data/location/TokenLocationCollection.h index 6c7277d9..3a7505cb 100644 --- a/src/lib/data/location/TokenLocationCollection.h +++ b/src/lib/data/location/TokenLocationCollection.h @@ -38,7 +38,7 @@ public: TokenLocation* findTokenLocationById(Id id) const; TokenLocationFile* findTokenLocationFileByPath(const FilePath& filePath) const; - void forEachTokenLocationFile(std::function func) const; + void forEachTokenLocationFile(std::function)> func) const; void forEachTokenLocationLine(std::function func) const; void forEachTokenLocation(std::function func) const;