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 "segmentsmapper.h" 0008 0009 #include "widgets/codeeditor.h" 0010 #include <QScrollBar> 0011 0012 SegmentsMapper::SegmentsMapper(QObject *parent) 0013 : QObject(parent) 0014 { 0015 } 0016 0017 void SegmentsMapper::addEditor(CodeEditor *editor) 0018 { 0019 mEditors.append(editor); 0020 0021 connect(editor, &CodeEditor::blockSelected, this, &SegmentsMapper::codeEditor_blockSelected); 0022 0023 mScrollBars.insert(editor->verticalScrollBar(), editor); 0024 connect(editor->verticalScrollBar(), &QScrollBar::valueChanged, this, &SegmentsMapper::codeEditor_scroll); 0025 } 0026 0027 const QList<Diff::Segment *> &SegmentsMapper::segments() const 0028 { 0029 return mSegments; 0030 } 0031 0032 void SegmentsMapper::setSegments(const QList<Diff::MergeSegment *> &newSegments) 0033 { 0034 for (const auto &s : newSegments) 0035 mSegments.append(s); 0036 } 0037 0038 int SegmentsMapper::map(int from, int to, int index) const 0039 { 0040 int offset1{0}; 0041 int offset2{0}; 0042 int offset3{0}; 0043 int &offsetFrom = from == 1 ? offset1 : (from == 2 ? offset2 : offset3); 0044 int &offsetTo = to == 1 ? offset1 : (to == 2 ? offset2 : offset3); 0045 0046 for (auto &s : mSegments) { 0047 auto ms = dynamic_cast<Diff::MergeSegment *>(s); 0048 0049 if (offsetFrom + s->get(from).size() > index) { 0050 if (s->type != Diff::SegmentType::DifferentOnBoth) 0051 return offsetFrom + (index - offsetTo); 0052 else 0053 return offsetFrom; 0054 } 0055 0056 offset1 += ms->base.size(); 0057 offset2 += ms->local.size(); 0058 offset3 += ms->remote.size(); 0059 } 0060 return -1; 0061 } 0062 0063 void SegmentsMapper::codeEditor_blockSelected() 0064 { 0065 auto s = qobject_cast<CodeEditor *>(sender()); 0066 0067 mCurrentSegment = s->currentSegment(); 0068 s->highlightSegment(mCurrentSegment); 0069 0070 for (auto &editor : mEditors) { 0071 editor->highlightSegment(mCurrentSegment); 0072 editor->gotoSegment(mCurrentSegment); 0073 /*if (s == editor) 0074 continue; 0075 auto n = map(myIndx, _editors.indexOf(editor), l); 0076 0077 if (n != -1) 0078 editor->gotoLineNumber(n); 0079 0080 editor->highlightSegment(s->currentSegment());*/ 0081 } 0082 } 0083 0084 void SegmentsMapper::codeEditor_scroll(int value) 0085 { 0086 static QAtomicInt n = 0; 0087 if (n) 0088 return; 0089 n.ref(); 0090 auto s = mScrollBars.value(sender()); 0091 if (!s) 0092 return; 0093 for (auto &editor : mEditors) { 0094 if (s == editor) 0095 continue; 0096 editor->verticalScrollBar()->setValue((int)(((float)value / (float)s->verticalScrollBar()->maximum()) * (float)s->verticalScrollBar()->maximum())); 0097 } 0098 n.deref(); 0099 } 0100 0101 Diff::Segment *SegmentsMapper::currentSegment() const 0102 { 0103 return mCurrentSegment; 0104 } 0105 0106 void SegmentsMapper::refresh() 0107 { 0108 if (!mCurrentSegment) 0109 return; 0110 for (auto &editor : mEditors) { 0111 editor->highlightSegment(mCurrentSegment); 0112 editor->gotoSegment(mCurrentSegment); 0113 } 0114 } 0115 0116 void SegmentsMapper::setCurrentSegment(Diff::Segment *newCurrentSegment) 0117 { 0118 mCurrentSegment = newCurrentSegment; 0119 refresh(); 0120 } 0121 0122 bool SegmentsMapper::isMergeable() const 0123 { 0124 for (auto &s : mSegments) { 0125 auto ms = dynamic_cast<Diff::MergeSegment *>(s); 0126 if (ms->mergeType == Diff::MergeType::None) 0127 return false; 0128 } 0129 return true; 0130 } 0131 0132 int SegmentsMapper::conflicts() const 0133 { 0134 int r{0}; 0135 for (auto &s : mSegments) { 0136 auto ms = dynamic_cast<Diff::MergeSegment *>(s); 0137 if (ms->mergeType == Diff::None) 0138 r++; 0139 } 0140 return r; 0141 } 0142 0143 void SegmentsMapper::findPrevious(Diff::SegmentType type) 0144 { 0145 int index; 0146 if (mCurrentSegment) 0147 index = mSegments.indexOf(dynamic_cast<Diff::MergeSegment *>(mCurrentSegment)) - 1; 0148 else 0149 index = mSegments.size() - 1; 0150 0151 if (index <= 0) 0152 return; 0153 for (auto i = index; i; i--) 0154 if (mSegments.at(i)->type == type) { 0155 setCurrentSegment(mSegments.at(i)); 0156 return; 0157 } 0158 } 0159 0160 void SegmentsMapper::findNext(Diff::SegmentType type) 0161 { 0162 int index; 0163 if (mCurrentSegment) 0164 index = mSegments.indexOf(dynamic_cast<Diff::MergeSegment *>(mCurrentSegment)) + 1; 0165 else 0166 index = 0; 0167 0168 for (auto i = index; i < mSegments.size(); i++) 0169 if (mSegments.at(i)->type == type) { 0170 setCurrentSegment(mSegments.at(i)); 0171 return; 0172 } 0173 } 0174 0175 // #include "moc_segmentsmapper.cpp"