Exteor/test/Mock/mockTextEdit.hpp

90 lines
2.7 KiB
C++
Raw Normal View History

2024-06-07 20:30:06 +03:00
#pragma once
#include "xtr/viewmodel/vmTextEdit.h"
#include <set>
class MockTextEditCtrl : public xtr::viewmodel::ITextEdit {
public:
struct rangeComparator {
constexpr bool operator()(const xtr::viewmodel::HighlightItem& rng1,
const xtr::viewmodel::HighlightItem& rng2) const noexcept {
return rng1.rng.start < rng2.rng.start;
}
};
public:
CString text{};
std::set<xtr::viewmodel::HighlightItem, rangeComparator> items{};
private:
[[nodiscard]] CString GetText() const override {
return text;
}
void SetText(const CString newText) override {
text = newText;
items.clear();
}
void ReplaceRange(const StrRange range, const CString replacement) override {
CString newText{};
if (range.start > 0) {
newText.Append(text.Left(range.start - 1));
}
newText.Append(replacement);
if (range.finish < text.GetLength()) {
newText.Append(text.Right(text.GetLength() - range.finish));
}
text = newText;
std::set<xtr::viewmodel::HighlightItem, rangeComparator> newItems{};
const auto shift = replacement.GetLength() - range.length();
for (auto refIt = begin(items); refIt != end(items); ++refIt) {
const auto& refPosition = refIt->rng;
if (refPosition.Meets(range) || refPosition.IsBefore(range)) {
newItems.emplace(*refIt);
} else if (range.Meets(refPosition) || refPosition.IsAfter(range)) {
auto newRef = *refIt;
newRef.rng.Shift(shift);
newItems.emplace(newRef);
} else if (range.Contains(refPosition)) {
continue;
} else {
auto newRef = *refIt;
if (refPosition.start < range.start) {
newRef.rng.SetLength(refPosition.length() - refPosition.Intersect(range)->length());
} else {
newRef.rng = StrRange::FromLength(range.start, std::max(0,
refPosition.length() - refPosition.Intersect(range)->length()));
}
newItems.emplace(newRef);
}
}
items = newItems;
}
void Highlight(xtr::viewmodel::HighlightItem item) override {
items.insert(item);
}
[[nodiscard]] std::optional<xtr::viewmodel::HighlightItem> NextHighlighted(const StrPos start) override {
if (start == 0) {
if (empty(items)) {
return std::nullopt;
} else {
return *begin(items);
}
}
if (auto it = std::find_if(begin(items), end(items),
[&](const xtr::viewmodel::HighlightItem& item) { return item.rng.start == start; });
it == end(items)) {
return std::nullopt;
} else if (++it; it == end(items)) {
return std::nullopt;
} else {
return *it;
}
}
};