File indexing completed on 2025-01-05 05:14:52
0001 /* 0002 SPDX-FileCopyrightText: 2021 Hamed Masafi <hamed.masfi@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "segmentconnector.h" 0008 #include "widgets/codeeditor.h" 0009 0010 #include <QPainter> 0011 #include <QPainterPath> 0012 #include <kommitwidgetsglobaloptions.h> 0013 0014 SegmentConnector::SegmentConnector(QWidget *parent) 0015 : QWidget(parent) 0016 { 0017 } 0018 0019 SegmentConnector::~SegmentConnector() 0020 { 0021 qDeleteAll(mSegments); 0022 } 0023 0024 const QList<Diff::DiffSegment *> &SegmentConnector::segments() const 0025 { 0026 return mSegments; 0027 } 0028 0029 void SegmentConnector::setSegments(const QList<Diff::DiffSegment *> &newSegments) 0030 { 0031 mSegments = newSegments; 0032 0033 int oldIndex{0}; 0034 int newIndex{0}; 0035 mSegmentPos.clear(); 0036 0037 for (auto &s : mSegments) { 0038 if (m_sameSize) { 0039 auto sizeMax = qMax(s->oldText.size(), s->newText.size()); 0040 0041 SegmentPos pos{oldIndex, static_cast<int>(oldIndex + s->oldText.size() - 1), newIndex, static_cast<int>(newIndex + s->newText.size() - 1)}; 0042 0043 // if (s->oldText.isEmpty()) 0044 // pos.leftEnd = -1; 0045 // if (s->newText.isEmpty()) 0046 // pos.rightEnd = -1; 0047 mSegmentPos.insert(s, pos); 0048 0049 oldIndex += sizeMax; 0050 newIndex += sizeMax; 0051 } else { 0052 SegmentPos pos{oldIndex, static_cast<int>(oldIndex + s->oldText.size() - 1), newIndex, static_cast<int>(newIndex + s->newText.size() - 1)}; 0053 0054 if (s->oldText.isEmpty()) 0055 pos.leftEnd = -1; 0056 if (s->newText.isEmpty()) 0057 pos.rightEnd = -1; 0058 mSegmentPos.insert(s, pos); 0059 0060 oldIndex += s->oldText.size(); 0061 newIndex += s->newText.size(); 0062 } 0063 } 0064 Q_EMIT segmentsChanged(); 0065 } 0066 0067 Diff::Segment *SegmentConnector::currentSegment() const 0068 { 0069 return mCurrentSegment; 0070 } 0071 0072 void SegmentConnector::setCurrentSegment(Diff::Segment *newCurrentSegment) 0073 { 0074 mCurrentSegment = newCurrentSegment; 0075 update(); 0076 } 0077 0078 bool SegmentConnector::sameSize() const 0079 { 0080 return m_sameSize; 0081 } 0082 0083 void SegmentConnector::setSameSize(bool newSameSize) 0084 { 0085 m_sameSize = newSameSize; 0086 Q_EMIT sameSizeChanged(); 0087 } 0088 0089 CodeEditor *SegmentConnector::left() const 0090 { 0091 return mLeft; 0092 } 0093 0094 void SegmentConnector::setLeft(CodeEditor *newLeft) 0095 { 0096 mLeft = newLeft; 0097 } 0098 0099 CodeEditor *SegmentConnector::right() const 0100 { 0101 return mRight; 0102 } 0103 0104 void SegmentConnector::setRight(CodeEditor *newRight) 0105 { 0106 mRight = newRight; 0107 } 0108 0109 void SegmentConnector::paintEvent(QPaintEvent *event) 0110 { 0111 Q_UNUSED(event) 0112 0113 if (!mLeft || !mRight) 0114 return; 0115 0116 QPainter painter(this); 0117 0118 if (m_topMargin) 0119 painter.translate(QPoint(0, m_topMargin)); 0120 0121 painter.setRenderHint(QPainter::Antialiasing, true); 0122 painter.fillRect(rect(), Qt::white); 0123 0124 for (auto s = mSegmentPos.begin(); s != mSegmentPos.end(); ++s) { 0125 if (s.key()->type == Diff::SegmentType::SameOnBoth) 0126 continue; 0127 const auto leftArea = mLeft->blockArea(s->leftStart, s->leftEnd); 0128 const auto rightArea = mRight->blockArea(s->rightStart, s->rightEnd); 0129 0130 // if (s == _currentSegment) 0131 // painter.setBrush(Qt::yellow); 0132 // else 0133 switch (s.key()->type) { 0134 case Diff::SegmentType::SameOnBoth: 0135 // painter.setBrush(Qt::magenta); 0136 continue; 0137 case Diff::SegmentType::OnlyOnRight: 0138 painter.setBrush(KommitWidgetsGlobalOptions::instance()->statucColor(Git::ChangeStatus::Added)); 0139 break; 0140 case Diff::SegmentType::OnlyOnLeft: 0141 painter.setBrush(KommitWidgetsGlobalOptions::instance()->statucColor(Git::ChangeStatus::Removed)); 0142 break; 0143 case Diff::SegmentType::DifferentOnBoth: 0144 painter.setBrush(KommitWidgetsGlobalOptions::instance()->statucColor(Git::ChangeStatus::Modified)); 0145 break; 0146 } 0147 0148 QPainterPath poly; 0149 poly.moveTo(0, leftArea.first); 0150 0151 poly.cubicTo(QPointF(30, leftArea.first), QPointF(width() - 30, rightArea.first), QPointF(width() - 1, rightArea.first)); 0152 poly.lineTo(width() - 1, rightArea.second); 0153 0154 poly.cubicTo(QPoint(width() - 30, rightArea.second), QPoint(30, leftArea.second), QPoint(0, leftArea.second)); 0155 painter.setPen(Qt::NoPen); 0156 painter.drawPath(poly); 0157 } 0158 } 0159 0160 int SegmentConnector::topMargin() const 0161 { 0162 return m_topMargin; 0163 } 0164 0165 void SegmentConnector::setTopMargin(int newTopMargin) 0166 { 0167 m_topMargin = newTopMargin; 0168 update(); 0169 } 0170 0171 #include "moc_segmentconnector.cpp"