22 #include <string_view>
27 #include <com/sun/star/i18n/ScriptType.hpp>
60 bool const m_isHideRedlines;
66 std::pair<sw::mark::IFieldmark const*, std::unique_ptr<SwPosition>> m_Fieldmark;
67 std::optional<SwPosition> m_oNextFieldmarkHide;
73 SwPosition const* GetStartPos()
const {
return m_pStartPos; }
74 SwPosition const* GetEndPos()
const {
return m_pEndPos; }
78 : m_rIDRA(rTextNode.getIDocumentRedlineAccess())
79 , m_rIDMA(*rTextNode.getIDocumentMarkAccess())
80 , m_isHideRedlines(isHideRedlines)
81 , m_eFieldmarkMode(eMode)
82 , m_Start(rTextNode, 0)
83 , m_RedlineIndex(m_rIDRA.GetRedlinePos(rTextNode,
RedlineType::
Any))
84 , m_pStartPos(nullptr)
107 if (pRed->
GetType() != RedlineType::Delete)
112 if (*pStart == *pEnd)
117 if (pStart->nNode.GetNode().IsTableNode())
122 if (*m_pEndPos <= *pStart)
124 pNextRedlineHide = pStart;
131 m_oNextFieldmarkHide.reset();
138 sal_Int32
const nPos = pTextNode ? pTextNode->
GetText().indexOf(
142 m_oNextFieldmarkHide.emplace(*pTextNode, nPos);
148 m_Fieldmark.first = pFieldmark;
155 m_Fieldmark.second.reset(
157 ++m_Fieldmark.second->nContent;
158 ++m_oNextFieldmarkHide->nContent;
162 m_Fieldmark.second.reset(
164 --m_Fieldmark.second->nContent;
171 assert(!pNextRedlineHide || !m_oNextFieldmarkHide
172 || *pNextRedlineHide != *m_oNextFieldmarkHide
173 || *m_rIDRA.
GetRedlineTable()[m_RedlineIndex]->End() < *m_Fieldmark.second);
175 && (!m_oNextFieldmarkHide || *pNextRedlineHide < *m_oNextFieldmarkHide))
178 m_pStartPos = pRed->
Start();
179 m_pEndPos = pRed->
End();
183 else if (m_oNextFieldmarkHide)
185 assert(!pNextRedlineHide || *m_oNextFieldmarkHide <= *pNextRedlineHide);
186 m_pStartPos = &*m_oNextFieldmarkHide;
187 m_pEndPos = m_Fieldmark.second.get();
192 assert(!pNextRedlineHide && !m_oNextFieldmarkHide);
193 m_pStartPos =
nullptr;
204 std::unique_ptr<sw::MergedPara>
212 bool bHaveRedlines(
false);
213 std::vector<SwTextNode *> nodes{ &rTextNode };
214 std::vector<SwTableNode *> tables;
215 std::vector<SwSectionNode *> sections;
216 std::vector<sw::Extent> extents;
217 OUStringBuffer mergedText;
220 sal_Int32 nLastEnd(0);
221 for (
auto iter = HideIterator(rTextNode,
225 SwPosition const*
const pStart(iter.GetStartPos());
226 SwPosition const*
const pEnd(iter.GetEndPos());
227 bHaveRedlines =
true;
228 assert(pNode != &rTextNode || &pStart->nNode.GetNode() == &rTextNode);
229 if (pStart->nContent != nLastEnd)
231 extents.emplace_back(pNode, nLastEnd, pStart->nContent.
GetIndex());
232 mergedText.append(std::u16string_view(pNode->
GetText()).substr(nLastEnd, pStart->nContent.GetIndex() - nLastEnd));
234 if (&pEnd->nNode.GetNode() != pNode)
236 if (pNode == &rTextNode)
246 if (pTmp->IsTextNode())
248 nodes.push_back(pTmp->GetTextNode());
250 else if (pTmp->IsTableNode())
252 tables.push_back(pTmp->GetTableNode());
254 else if (pTmp->IsSectionNode())
256 sections.push_back(pTmp->GetSectionNode());
259 if (pTmp->IsStartNode())
263 else if (pTmp->IsEndNode())
271 if (!pEnd->nNode.GetNode().IsTextNode())
273 assert(pEnd->nNode != pStart->nNode);
275 pNode = nodes.back();
277 if (pNode != &rTextNode)
281 nLastEnd = pNode->
Len();
286 nodes.push_back(pNode);
288 nLastEnd = pEnd->nContent.GetIndex();
293 nLastEnd = pEnd->nContent.GetIndex();
296 if (pNode == &rTextNode)
314 if (!pTmp->IsCreateFrameWhenHidingRedlines())
318 if (pTmp->IsStartNode())
322 else if (pTmp->IsEndNode())
330 else if (pTmp->IsTextNode())
338 j = pTmp->EndOfSectionIndex() - 1;
350 if (nLastEnd != pNode->
Len())
352 extents.emplace_back(pNode, nLastEnd, pNode->
Len());
353 mergedText.append(std::u16string_view(pNode->
GetText()).substr(nLastEnd, pNode->
Len() - nLastEnd));
357 assert(mergedText.isEmpty());
358 pParaPropsNode = pNode;
362 assert(!mergedText.isEmpty());
363 pParaPropsNode = extents.begin()->pNode;
371 for (
auto const pTextNode : nodes)
373 if (pTextNode != pParaPropsNode)
387 auto itExtent(extents.begin());
388 for (
auto const pTextNode : nodes)
391 std::vector<std::pair<sal_Int32, sal_Int32>> hidden;
392 for ( ; itExtent != extents.end(); ++itExtent)
394 if (itExtent->pNode != pTextNode)
398 if (itExtent->nStart != 0)
400 assert(itExtent->nStart != nLast);
401 hidden.emplace_back(nLast, itExtent->nStart);
403 nLast = itExtent->nEnd;
405 if (nLast != pTextNode->
Len())
407 hidden.emplace_back(nLast, pTextNode->
Len());
413 auto const end(--nodes.rend());
414 for (
auto iter = nodes.rbegin(); iter !=
end; ++iter)
419 for (
auto const pTableNode : tables)
423 for (
auto const pSectionNode : sections)
428 auto pRet(std::make_unique<sw::MergedPara>(rFrame, std::move(extents),
429 mergedText.makeStringAndClear(), pParaPropsNode, &rTextNode,
433 pRet->listener.StartListening(pTmp);
444 OUString
const& rText,
445 bool const*
const pbVertLayout,
446 bool const*
const pbVertLayoutLRBT)
456 *
m_pFont = aFontAccess.Get()->GetFont();
465 bool bVertLayoutLRBT =
false;
466 if (pbVertLayoutLRBT)
467 bVertLayoutLRBT = *pbVertLayoutLRBT;
499 case i18n::ScriptType::ASIAN :
502 case i18n::ScriptType::COMPLEX :
527 bool bVertLayout =
false;
528 bool bVertLayoutLRBT =
false;
538 bVertLayoutLRBT =
true;
558 SwDoc& rDoc = rTextNode.GetDoc();
570 if (rExtent.pNode != pNode)
572 pNode = rExtent.pNode;
590 if (rExtent.pNode != pNode)
592 pNode = rExtent.pNode;
608 const std::vector<ExtTextInputAttr> *pArr =
nullptr;
621 pArr, pExtInp ? pExtInp->
Start() :
nullptr));
642 const std::vector<ExtTextInputAttr> *pArr,
644 :
m_rDoc( rTextNd.GetDoc() )
645 , m_rAttrHandler( rAH )
646 , m_nNdIdx( rTextNd.GetIndex() )
673 sal_uLong const nNode, sal_Int32
const nNew, sal_Int32
const nOld)
732 sal_uInt16 nWhich = aIter.FirstWhich();
737 ( SfxItemState::SET ==
m_pSet->GetItemState( nWhich,
true, &pItem ) ) )
740 const_cast<SwDoc&>(
m_rDoc),
741 *const_cast<SfxPoolItem*>(pItem) );
746 nWhich = aIter.NextWhich();
774 SwPosition const*
const pStart(pRedline->Start());
775 if (pRedline->GetType() == RedlineType::Delete
776 && (nNode < pStart->nNode.GetIndex()
777 || (nNode == pStart->nNode.GetIndex()
778 && nNew <= pStart->nContent.GetIndex())))
794 case RedlineType::Insert:
797 case RedlineType::Delete:
800 case RedlineType::Format:
801 case RedlineType::FmtColl:
811 OSL_ENSURE(
IsOn(),
"SwRedlineItr::ChangeTextAttr: Off?" );
825 OSL_ENSURE( !
m_pExt || !
m_pExt->IsOn(),
"Pop of attribute during opened extension" );
832 OSL_ENSURE(
m_bOn,
"SwRedlineItr::Clear: Off?" );
834 for (
auto const& hint :
m_Hints)
849 std::pair<sal_Int32, std::pair<SwRangeRedline const*, size_t>>
857 return std::make_pair(nNext, std::make_pair(
nullptr, 0));
870 || pRedline->GetType() == RedlineType::Delete)
879 return std::make_pair(nNext, std::make_pair(
nullptr, 0));
886 else if (nStart <= nNext)
897 assert(pRedline->GetType() == RedlineType::Delete);
898 if (pRedline->GetType() == RedlineType::Delete)
902 while (rAct + nSkipped <
907 if (*pRedline->End() < *pNext->
Start())
911 else if (*pNext->
Start() == *pRedline->End() &&
912 pNext->
GetType() == RedlineType::Delete)
919 return std::make_pair(nNext, std::make_pair(pRedline, nSkipped));
923 return std::make_pair(nNext, std::make_pair(
nullptr, 0));
933 const sal_uInt16 nWhich = pHint->Which();
942 sal_uLong const nStartNode, sal_Int32
const nChkStart,
943 sal_uLong const nEndNode, sal_Int32 nChkEnd, OUString& rRedlineText,
950 if( nChkEnd == nChkStart )
953 sal_Int32 nOldEnd =
m_nEnd;
955 bool bRet = bRedlineEnd =
false;
956 eRedlineEnd = RedlineType::None;
967 bool isExtendText(
false);
978 eRedlineEnd = pRedline->GetType();
988 if (rRedlineText.isEmpty() && !pRedline->IsVisible())
990 rRedlineText =
const_cast<SwRangeRedline*
>(pRedline)->GetDescr(
true);
991 pPrevRedline = pRedline;
996 else if (pPrevRedline && !pRedline->IsVisible() &&
997 *pRedline->Start() == *pPrevRedline->Start() && *pRedline->End() == *pPrevRedline->End() )
999 OUString sExtendText(const_cast<SwRangeRedline*>(pRedline)->GetDescr(
true));
1000 if (!sExtendText.isEmpty())
1002 if (rRedlineText.getLength() < 12)
1006 rRedlineText = rRedlineText +
1007 const_cast<SwRangeRedline*
>(pRedline)->GetDescr(
true).subView(1);
1010 rRedlineText = OUString::Concat(rRedlineText.subView(0, rRedlineText.getLength() - 3)) +
"...";
1012 isExtendText =
true;
1019 if (isBreak && !isExtendText)
1033 if ( nAttr & ExtTextInputAttr::Underline )
1035 else if ( nAttr & ExtTextInputAttr::BoldUnderline )
1037 else if ( nAttr & ExtTextInputAttr::DottedUnderline )
1039 else if ( nAttr & ExtTextInputAttr::DashDotUnderline )
1042 if ( nAttr & ExtTextInputAttr::RedText )
1045 if ( nAttr & ExtTextInputAttr::Highlight )
1051 if ( nAttr & ExtTextInputAttr::GrayWaveline )
1057 OSL_ENSURE( !
m_pFont,
"SwExtend: Enter with Font" );
1060 OSL_ENSURE( !
Inside(),
"SwExtend: Enter without Leave" );
1073 OSL_ENSURE(nNode ==
m_nNode &&
Inside(),
"SwExtend: Leave without Enter");
1081 if( nOldAttr != nAttr )
SwScriptInfo * m_pScriptInfo
Represents the visualization of a paragraph.
std::deque< SwTextAttr * > m_Hints
SwFontScript WhichFont(TextFrameIndex nIdx) const
sal_uLong GetIndex() const
TextFrameIndex GetInvalidityA() const
virtual ::sw::mark::IFieldmark * getFieldmarkAt(const SwPosition &rPos) const =0
get Fieldmark for CH_TXT_ATR_FIELDSTART/CH_TXT_ATR_FIELDEND at rPos
Marks a position in the document model.
constexpr TypedWhichId< SvxEscapementItem > RES_CHRATR_ESCAPEMENT(6)
void Pop(const SwTextAttr &rAttr)
Only used during redlining.
const SwNodeNum * GetNum(SwRootFrame const *pLayout=nullptr) const
SwComparePosition ComparePosition(const T &rStt1, const T &rEnd1, const T &rStt2, const T &rEnd2)
const OUString & GetText() const
virtual const SwRootFrame * GetCurrentLayout() const =0
void PopAndChg(const SwTextAttr &rAttr, SwFont &rFnt)
std::unique_ptr< SwFont > m_pFont
const Color & GetHighlightTextColor() const
constexpr::Color COL_RED(0x80, 0x00, 0x00)
void SetPriorityAttr(bool bFlag)
virtual sal_Int32 Len() const override
Pos1 is as large as Pos2.
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
size_t m_nEndIndex
current iteration index in HintEnds
sw::MergedPara * GetMergedPara()
void SetGreyWave(const bool bNew)
Pos1 completely contained in Pos2.
Provides access to the marks of a document.
short Seek(SwFont &rFnt, sal_uLong nNode, sal_Int32 nNew, sal_Int32 nOld)
SwPosition FindFieldSep(IFieldmark const &rMark)
return position of the CH_TXT_ATR_FIELDSEP for rMark
constexpr TypedWhichId< SvxUnderlineItem > RES_CHRATR_UNDERLINE(14)
Dialog to specify the properties of date form field.
void CalcStartEnd(sal_uLong nNdIdx, sal_Int32 &rStart, sal_Int32 &rEnd) const
Calculates the intersection with text node number nNdIdx.
The root element of a Writer document layout.
Degree10 GetOrientation(const bool bVertLayout=false, const bool bVertFormatLRBT=false) const
bool Seek(TextFrameIndex nPos)
Enables the attributes used at char pos nPos in the logical font.
const Color & GetHighlightColor() const
static bool IsShowChanges(const RedlineFlags eM)
void SetColor(const Color &rColor)
Pos1 end touches at Pos2 start.
sal_Int32 m_nPosition
current iteration index in text node
void RemoveFromListRLHidden()
void CtorInitAttrIter(SwTextNode &rTextNode, SwScriptInfo &rScrInf, SwTextFrame const *pFrame=nullptr)
o3tl::enumarray< SwFontScript, sal_uInt16 > m_aFontIdx
SwRedlineTable::size_type m_nAct
void FillHints(std::size_t nAuthor, RedlineType eType)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
virtual ::sw::mark::IFieldmark * getFieldmarkFor(const SwPosition &pos) const =0
bool Leave_(SwFont &rFnt, sal_uLong nNode, sal_Int32 nNew)
std::unique_ptr< sw::MergedPara > CheckParaRedlineMerge(SwTextFrame &rFrame, SwTextNode &rTextNode, FrameMode eMode)
Used by Attribute Iterators to organize attributes on stacks to find the valid attribute in each cate...
sal_uLong GetIndex() const
void InitScriptInfo(const SwTextNode &rNode, sw::MergedPara const *pMerged, bool bRTL)
Pos2 completely contained in Pos1.
void SetUnderline(const FontLineStyle eUnderline)
sal_Int32 Next(sal_uLong nNode, sal_Int32 nNext)
std::unique_ptr< SwRedlineItr, o3tl::default_delete< SwRedlineItr > > m_pRedline
sal_uInt16 GetStackCount() const
sal_Int32 m_nPos
current position (inside)
SwFormatColl & GetAnyFormatColl() const
std::vector< Extent > extents
void InitFontAndAttrHandler(SwTextNode const &rPropsNode, SwTextNode const &rTextNode, OUString const &rText, bool const *pbVertLayout, bool const *pbVertLayoutLRBT)
std::unique_ptr< SfxItemSet > m_pSet
sw::MergedPara const * m_pMergedPara
const SwAttrSet * GetpSwAttrSet() const
virtual SwRedlineTable::size_type GetRedlinePos(const SwNode &rNode, RedlineType nType) const =0
void Init(const SwAttrSet &rAttrSet, const IDocumentSettingAccess &rIDocumentSettingAccess)
Pos1 start touches at Pos2 end.
sw::FieldmarkMode GetFieldmarkMode() const
bool IsVertLayout() const
void SetVertical(Degree10 nDir, const bool bVertLayout=false, const bool bVertLayoutLRBT=false)
vector_type::size_type size_type
std::unique_ptr< SwExtend > m_pExt
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
#define CH_TXT_ATR_FIELDSTART
sal_Int32 const m_nEnd
position of end of SwExtTextInput (in same node as start)
SwTextNode * pParaPropsNode
most paragraph properties are taken from the first non-empty node
~SwRedlineItr() COVERITY_NOEXCEPT_FALSE
void RemoveFootnotesForNode(SwRootFrame const &rLayout, SwTextNode const &rTextNode, std::vector< std::pair< sal_Int32, sal_Int32 >> const *const pExtents)
const IDocumentSettingAccess * getIDocumentSettingAccess() const
Provides access to the document setting interface.
SwNodes & GetNodes()
Node is in which nodes-array/doc?
sal_uLong const m_nNode
position of start of SwExtTextInput
OUString mergedText
note: cannot be const currently to avoid UB because SwTextGuess::Guess const_casts it and modifies it...
enumrange< T >::Iterator end(enumrange< T >)
const SwPosition * Start() const
size_t m_nStartIndex
current iteration index in HintStarts
const IDocumentLayoutAccess & getIDocumentLayoutAccess() const
Provides access to the document layout interface.
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
SwRedlineTable::size_type const m_nFirst
SwTextNode is a paragraph in the document model.
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
void Clear_(SwFont *pFnt)
o3tl::enumarray< SwFontScript, const void * > m_aFontCacheIds
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
std::size_t GetAuthor(sal_uInt16 nPos=0) const
void SetBackColor(std::optional< Color > xNewColor)
std::pair< sal_Int32, std::pair< SwRangeRedline const *, size_t > > GetNextRedln(sal_Int32 nNext, SwTextNode const *pNode, SwRedlineTable::size_type &rAct)
Ignore mode: does nothing.
Pos1 overlaps Pos2 at the end.
SwAttrHandler m_aAttrHandler
sal_uInt8 GetScriptType(const size_t nCnt) const
sal_Int32 GetIndex() const
const SwPosition * End() const
bool IsRightToLeft() const
static void Destroy(SwTextAttr *pToDestroy, SfxItemPool &rPool)
destroy instance
RedlineType GetType(sal_uInt16 nPos=0) const
bool ChkSpecialUnderline_() const
bool IsHideRedlines() const
Replacement for sw::DocumentRedlineManager::GetRedlineFlags() (this is layout-level redline hiding)...
constexpr sal_uInt16 RES_CHRATR_END(46)
void ChangeTextAttr(SwFont *pFnt, SwTextAttr const &rHt, bool bChg)
void PushAndChg(const SwTextAttr &rAttr, SwFont &rFnt)
const std::vector< ExtTextInputAttr > & m_rArr
TextFrameIndex GetScriptChg(const size_t nCnt) const
virtual RedlineFlags GetRedlineFlags() const =0
Query the currently set redline mode.
size_t CountScriptChg() const
bool CheckLine(sal_uLong nStartNode, sal_Int32 nChkStart, sal_uLong nEndNode, sal_Int32 nChkEnd, OUString &rRedlineText, bool &bRedlineEnd, RedlineType &eRedlineEnd)
SwRedlineItr(const SwTextNode &rTextNd, SwFont &rFnt, SwAttrHandler &rAH, sal_Int32 nRedlPos, Mode mode, const std::vector< ExtTextInputAttr > *pArr=nullptr, SwPosition const *pExtInputStart=nullptr)
bool HasMergedParas() const
short Enter(SwFont &rFnt, sal_uLong nNode, sal_Int32 nNew)
SwAttrHandler & m_rAttrHandler
SwViewShell * m_pViewShell
virtual const SwRedlineTable & GetRedlineTable() const =0
short m_nChgCnt
count currently open hints, redlines, ext-input
short EnterExtend(SwFont &rFnt, sal_uLong const nNode, sal_Int32 const nNew)
#define CH_TXT_ATR_FIELDSEP
void SetRedlineMergeFlag(Merge const eMerge)
SwViewShell * GetCurrShell() const
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
static constexpr size_type npos
static void ActualizeFont(SwFont &rFnt, ExtTextInputAttr nAttr)
Merge GetRedlineMergeFlag() const
const sal_Int32 COMPLETE_STRING
SwRootFrame * getRootFrame()
Pos1 overlaps Pos2 at the beginning.
SwExtTextInput * GetExtTextInput(const SwNode &rNd, sal_Int32 nContentPos=-1) const
const std::vector< ExtTextInputAttr > & GetAttrs() const
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Base class of the Writer document model elements.
sal_Int32 NextExtend(sal_uLong const nNode, sal_Int32 const nNext)
SwTextAttr * MakeRedlineTextAttr(SwDoc &rDoc, SfxPoolItem const &rAttr)
create redline dummy text hint that must not be inserted into hints array