diff --git a/bin/app/data/src/sample/sample.cpp b/bin/app/data/src/sample/sample.cpp new file mode 100644 index 00000000..5c43ee12 --- /dev/null +++ b/bin/app/data/src/sample/sample.cpp @@ -0,0 +1,32 @@ +class Player { +public: + void Do() {} +}; + +class Base {}; + +class Game : public Base { +public: + Game() { + Init(); + } + + void Init() {} + + void Run() { + player.Do(); + } + + Player player; +}; + +Game* game; + +int main() { + game = new Game(); + + game->Run(); + + delete game; + return 0; +} \ No newline at end of file diff --git a/src/app/qt/element/QtCodeFileList.cpp b/src/app/qt/element/QtCodeFileList.cpp index 30dc853d..80c7ccbb 100644 --- a/src/app/qt/element/QtCodeFileList.cpp +++ b/src/app/qt/element/QtCodeFileList.cpp @@ -1,5 +1,6 @@ #include "qt/element/QtCodeFileList.h" +#include #include #include "data/location/TokenLocationFile.h" @@ -65,6 +66,7 @@ void QtCodeFileList::addCodeSnippet( void QtCodeFileList::clearCodeSnippets() { m_files.clear(); + this->verticalScrollBar()->setValue(0); } const std::vector& QtCodeFileList::getActiveTokenIds() const diff --git a/src/app/qt/element/QtCodeSnippet.cpp b/src/app/qt/element/QtCodeSnippet.cpp index d9e39149..89f20114 100644 --- a/src/app/qt/element/QtCodeSnippet.cpp +++ b/src/app/qt/element/QtCodeSnippet.cpp @@ -191,6 +191,9 @@ void QtCodeSnippet::leaveEvent(QEvent* event) { m_maximizeButton->setEnabled(false); } + + m_hoveredAnnotation = nullptr; + annotateText(); } void QtCodeSnippet::mouseReleaseEvent(QMouseEvent* event) @@ -220,7 +223,12 @@ void QtCodeSnippet::mouseMoveEvent(QMouseEvent* event) QTextCursor cursor = this->cursorForPosition(event->pos()); const Annotation* annotation = findAnnotationForPosition(cursor.position()); - if (annotation != nullptr ? annotation != m_hoveredAnnotation && !annotation->isScope : m_hoveredAnnotation != nullptr) + if (annotation && annotation->isScope) + { + annotation = nullptr; + } + + if (annotation != m_hoveredAnnotation) { m_hoveredAnnotation = annotation; @@ -359,6 +367,11 @@ void QtCodeSnippet::annotateText() else if (isActive) { color = ApplicationSettings::getInstance()->getCodeActiveLinkColor(); + + if (annotation.isScope) + { + color.a /= 2; + } } else if (annotation.isScope) { diff --git a/src/app/qt/view/graphElements/QtGraphEdge.cpp b/src/app/qt/view/graphElements/QtGraphEdge.cpp index 68f39de6..4d0d76b5 100644 --- a/src/app/qt/view/graphElements/QtGraphEdge.cpp +++ b/src/app/qt/view/graphElements/QtGraphEdge.cpp @@ -25,7 +25,9 @@ QtStraightConnection::QtStraightConnection(Vec4i ownerRect, Vec4i targetRect, in this->setLine(a.x, a.y, b.x, b.y); this->setAcceptHoverEvents(true); + Vec2f mid = (a + b) / 2; Vec2f u = b - a; + float len = u.getLength(); u.normalize(); float alpha = atan2(u.y, u.x); @@ -34,12 +36,17 @@ QtStraightConnection::QtStraightConnection(Vec4i ownerRect, Vec4i targetRect, in w.x = (o.z - o.x) / 2 * cos(alpha); w.y = (o.w - o.y) / 2 * sin(alpha); a += u * w.getLength(); + float newLen = w.getLength(); w.x = (t.z - t.x) / 2 * cos(alpha); w.y = (t.w - t.y) / 2 * sin(alpha); b += u * -w.getLength(); + newLen -= w.getLength(); - Vec2f mid = (a + b) / 2; + if (newLen > 0 && newLen < len) + { + mid = (a + b) / 2; + } m_circle = new QtGraphicsRoundedRectItem(this); m_circle->setRect(mid.x - 10, mid.y - 10, 20, 20); @@ -88,6 +95,8 @@ QtCorneredConnection::QtCorneredConnection( , m_targetRect(targetRect) , m_ownerParentRect(ownerParentRect) , m_targetParentRect(targetParentRect) + , m_closed(false) + , m_big(false) { this->setAcceptHoverEvents(true); @@ -103,11 +112,12 @@ QtCorneredConnection::~QtCorneredConnection() QPainterPath QtCorneredConnection::shape() const { + int w = m_big ? 10 : 5; QPainterPath path; QPolygon poly = getPath(); for (int i = 0; i < poly.size() - 1; i++) { - path.addRect(QRectF(poly.at(i), poly.at(i + 1)).normalized().adjusted(-5, -5, 5, 5)); + path.addRect(QRectF(poly.at(i), poly.at(i + 1)).normalized().adjusted(-w, -w, w, w)); } return path; } @@ -125,112 +135,134 @@ void QtCorneredConnection::paint(QPainter *painter, const QStyleOptionGraphicsIt int radius = 10; int dir = getDirection(poly.at(i), poly.at(i - 1)); - while (i > 0) + while (i > 1) { i--; - if (i == 0) + + QPointF a = poly.at(i); + QPointF b = poly.at(i - 1); + + int newDir = getDirection(a, b); + int ar = radius; + int br = 10; + + if (i != 1) { - path.lineTo(poly.at(i)); + if (dir % 2 == 1 && std::abs(a.y() - b.y()) < 2 * br) + { + br = std::abs(a.y() - b.y()) / 2; + } + else if (dir % 2 == 0 && std::abs(a.x() - b.x()) < 2 * br) + { + br = std::abs(a.x() - b.x()) / 2; + } } - else + + switch (dir) { - QPointF a = poly.at(i); - QPointF b = poly.at(i - 1); - - int newDir = getDirection(a, b); - int ar = radius; - int br = 10; - - if (i != 1) - { - if (dir % 2 == 1 && std::abs(a.y() - b.y()) < 2 * br) - { - br = std::abs(a.y() - b.y()) / 2; - } - else if (dir % 2 == 0 && std::abs(a.x() - b.x()) < 2 * br) - { - br = std::abs(a.x() - b.x()) / 2; - } - } - - switch (dir) - { - case 0: a.setY(a.y() + ar); break; - case 1: a.setX(a.x() - ar); break; - case 2: a.setY(a.y() - ar); break; - case 3: a.setX(a.x() + ar); break; - } - - b = poly.at(i); - switch (newDir) - { - case 0: b.setY(b.y() - br); break; - case 1: b.setX(b.x() + br); break; - case 2: b.setY(b.y() + br); break; - case 3: b.setX(b.x() - br); break; - } - - switch (dir) - { - case 0: - if (newDir == 1) - { - path.arcTo(a.x(), b.y(), 2 * br, 2 * ar, 180, -90); - } - else if (newDir == 3) - { - path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, 90); - } - break; - case 1: - if (newDir == 0) - { - path.arcTo(a.x() - ar, b.y() - br, 2 * ar, 2 * br, -90, 90); - } - else if (newDir == 2) - { - path.arcTo(a.x() - ar, a.y(), 2 * ar, 2 * br, 90, -90); - } - break; - case 2: - if (newDir == 1) - { - path.arcTo(a.x(), a.y() - ar, 2 * br, 2 * ar, 180, 90); - } - else if (newDir == 3) - { - path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, -90); - } - break; - case 3: - if (newDir == 0) - { - path.arcTo(b.x(), b.y() - br, 2 * ar, 2 * br, -90, -90); - } - else if (newDir == 2) - { - path.arcTo(b.x(), a.y(), 2 * ar, 2 * br, 90, 90); - } - break; - } - - dir = newDir; - radius = br; + case 0: a.setY(a.y() + ar); break; + case 1: a.setX(a.x() - ar); break; + case 2: a.setY(a.y() - ar); break; + case 3: a.setX(a.x() + ar); break; } + + b = poly.at(i); + switch (newDir) + { + case 0: b.setY(b.y() - br); break; + case 1: b.setX(b.x() + br); break; + case 2: b.setY(b.y() + br); break; + case 3: b.setX(b.x() - br); break; + } + + switch (dir) + { + case 0: + if (newDir == 1) + { + path.arcTo(a.x(), b.y(), 2 * br, 2 * ar, 180, -90); + } + else if (newDir == 3) + { + path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, 90); + } + break; + case 1: + if (newDir == 0) + { + path.arcTo(a.x() - ar, b.y() - br, 2 * ar, 2 * br, -90, 90); + } + else if (newDir == 2) + { + path.arcTo(a.x() - ar, a.y(), 2 * ar, 2 * br, 90, -90); + } + break; + case 2: + if (newDir == 1) + { + path.arcTo(a.x(), a.y() - ar, 2 * br, 2 * ar, 180, 90); + } + else if (newDir == 3) + { + path.arcTo(b.x() - br, a.y() - ar, 2 * br, 2 * ar, 0, -90); + } + break; + case 3: + if (newDir == 0) + { + path.arcTo(b.x(), b.y() - br, 2 * ar, 2 * br, -90, -90); + } + else if (newDir == 2) + { + path.arcTo(b.x(), a.y(), 2 * ar, 2 * br, 90, 90); + } + break; + } + + dir = newDir; + radius = br; } - int arrowLength = 5; - int arrowWidth = 8; + int arrowLength = m_big ? 15 : 5; + int arrowWidth = m_big ? 20 : 8; + QPointF arrow = poly.at(0) + QPointF((poly.at(0).x() - poly.at(1).x() > 0 ? -1 : 1) * arrowLength, 0); - QPointF arrow = poly.at(0) + QPointF((poly.at(0).x() - poly.at(1).x() > 0 ? -1 : 1) * arrowLength, -arrowWidth / 2); + if (m_closed) + { + path.lineTo(arrow); + path.moveTo(poly.at(0)); + } + else + { + path.lineTo(poly.at(0)); + } + + arrow.setY(arrow.y() - arrowWidth / 2); path.lineTo(arrow); arrow.setY(arrow.y() + arrowWidth); - path.moveTo(arrow); + if (m_closed) + { + path.lineTo(arrow); + } + else + { + path.moveTo(arrow); + } path.lineTo(poly.at(0)); painter->drawPath(path); } +void QtCorneredConnection::setClosed(bool closed) +{ + m_closed = closed; +} + +void QtCorneredConnection::setBig(bool big) +{ + m_big = big; +} + QPolygon QtCorneredConnection::getPath() const { const Vec4i& oR = m_ownerRect; @@ -257,32 +289,33 @@ QPolygon QtCorneredConnection::getPath() const } } - float offset = 15; + float offsetO = 15; + float offsetT = m_big ? 25 : 15; - QPoint tp((it ? 1 : -1) * offset + t[it].x, t[it].y); - QPoint op((io ? 1 : -1) * offset + o[io].x, o[io].y); + QPoint tp((it ? 1 : -1) * offsetT + t[it].x, t[it].y); + QPoint op((io ? 1 : -1) * offsetO + o[io].x, o[io].y); if (it != io) { if (it && tp.x() < op.x()) { io = 0; - op = QPoint(o[io].x - offset, o[io].y); + op = QPoint(o[io].x - offsetO, o[io].y); } else if (!it && tp.x() < op.x()) { it = 1; - tp = QPoint(t[it].x + offset, t[it].y); + tp = QPoint(t[it].x + offsetT, t[it].y); } else if (io && tp.x() > op.x()) { io = 1; - op = QPoint(o[io].x + offset, o[io].y); + op = QPoint(o[io].x + offsetO, o[io].y); } else if (!io && tp.x() > op.x()) { it = 0; - tp = QPoint(t[it].x - offset, t[it].y); + tp = QPoint(t[it].x - offsetT, t[it].y); } } @@ -387,11 +420,19 @@ void QtGraphEdge::updateLine() } else { - m_child = new QtCorneredConnection( + QtCorneredConnection* child = new QtCorneredConnection( owner->getBoundingRect(), target->getBoundingRect(), owner->getParentBoundingRect(), target->getParentBoundingRect(), this ); + + if (isInheritance()) + { + child->setClosed(true); + child->setBig(true); + } + + m_child = child; } QColor color; @@ -517,6 +558,11 @@ bool QtGraphEdge::isAggregation() const return getData()->getType() == Edge::EDGE_AGGREGATION; } +bool QtGraphEdge::isInheritance() const +{ + return getData()->getType() == Edge::EDGE_INHERITANCE; +} + int QtGraphEdge::getZValue(bool active) const { if (isAggregation()) @@ -541,7 +587,7 @@ float QtGraphEdge::getPenWidth() const { return getAggregationCount() + 1; } - return 1.5; + return 1; } int QtGraphEdge::getAggregationCount() const diff --git a/src/app/qt/view/graphElements/QtGraphEdge.h b/src/app/qt/view/graphElements/QtGraphEdge.h index ae459851..5abea7da 100644 --- a/src/app/qt/view/graphElements/QtGraphEdge.h +++ b/src/app/qt/view/graphElements/QtGraphEdge.h @@ -36,6 +36,9 @@ public: virtual QPainterPath shape() const; virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem* options, QWidget* widget); + void setClosed(bool closed); + void setBig(bool big); + private: QPolygon getPath() const; int getDirection(const QPointF& a, const QPointF& b) const; @@ -45,6 +48,9 @@ private: Vec4i m_ownerParentRect; Vec4i m_targetParentRect; + + bool m_closed; + bool m_big; }; @@ -76,6 +82,8 @@ protected: private: bool isAggregation() const; + bool isInheritance() const; + int getZValue(bool active) const; float getPenWidth() const; int getAggregationCount() const; diff --git a/src/lib/component/controller/CodeController.cpp b/src/lib/component/controller/CodeController.cpp index 82b01446..57f85297 100644 --- a/src/lib/component/controller/CodeController.cpp +++ b/src/lib/component/controller/CodeController.cpp @@ -181,18 +181,21 @@ std::vector> CodeController::getSnippetRangesForFile(const if (location->isStartTokenLocation()) { + if (start && end && lineNumber > end + 2 * s_lineRadius + 1) + { + ranges.push_back(std::make_pair(uint(start), uint(end))); + start = end = 0; + } + if (!start) { start = lineNumber; } - else if (end && lineNumber > end + 2 * s_lineRadius + 1) - { - ranges.push_back(std::make_pair(uint(start), uint(end))); - start = lineNumber; - end = 0; - } + + lineNumber = location->getEndTokenLocation()->getLineNumber(); } - else + + if (lineNumber > end) { end = lineNumber; } diff --git a/src/lib/data/graph/StorageGraph.cpp b/src/lib/data/graph/StorageGraph.cpp index 2ccb81d9..48dfe975 100644 --- a/src/lib/data/graph/StorageGraph.cpp +++ b/src/lib/data/graph/StorageGraph.cpp @@ -77,9 +77,9 @@ Node* StorageGraph::createNodeHierarchyWithDistinctSignature( Edge* StorageGraph::createEdge(Edge::EdgeType type, Node* from, Node* to) { Edge* edge = from->findEdgeOfType(type, - [to](Edge* e) + [from, to](Edge* e) { - return e->getTo() == to; + return e->getFrom() == from && e->getTo() == to; } );