#pragma once #include "xtr/viewmodel/vmTextEdit.h" #include 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 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 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 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; } } };