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"