File: | home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx |
Warning: | line 225, column 17 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ | ||||||
2 | /* | ||||||
3 | * This file is part of the LibreOffice project. | ||||||
4 | * | ||||||
5 | * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
8 | * | ||||||
9 | * This file incorporates work covered by the following license notice: | ||||||
10 | * | ||||||
11 | * Licensed to the Apache Software Foundation (ASF) under one or more | ||||||
12 | * contributor license agreements. See the NOTICE file distributed | ||||||
13 | * with this work for additional information regarding copyright | ||||||
14 | * ownership. The ASF licenses this file to you under the Apache | ||||||
15 | * License, Version 2.0 (the "License"); you may not use this file | ||||||
16 | * except in compliance with the License. You may obtain a copy of | ||||||
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . | ||||||
18 | */ | ||||||
19 | |||||||
20 | #include <hintids.hxx> | ||||||
21 | #include <doc.hxx> | ||||||
22 | #include <IDocumentUndoRedo.hxx> | ||||||
23 | #include <IDocumentLayoutAccess.hxx> | ||||||
24 | #include <pam.hxx> | ||||||
25 | #include <flyfrm.hxx> | ||||||
26 | #include <ndtxt.hxx> | ||||||
27 | #include <frmfmt.hxx> | ||||||
28 | #include <fmtflcnt.hxx> | ||||||
29 | #include <txtflcnt.hxx> | ||||||
30 | #include <fmtanchr.hxx> | ||||||
31 | #include <txtfrm.hxx> | ||||||
32 | #include <flyfrms.hxx> | ||||||
33 | #include <objectformatter.hxx> | ||||||
34 | #include <calbck.hxx> | ||||||
35 | #include <dcontact.hxx> | ||||||
36 | #include <textboxhelper.hxx> | ||||||
37 | |||||||
38 | SwFormatFlyCnt::SwFormatFlyCnt( SwFrameFormat *pFrameFormat ) | ||||||
39 | : SfxPoolItem( RES_TXTATR_FLYCNT ), | ||||||
40 | m_pTextAttr( nullptr ), | ||||||
41 | m_pFormat( pFrameFormat ) | ||||||
42 | { | ||||||
43 | } | ||||||
44 | |||||||
45 | bool SwFormatFlyCnt::operator==( const SfxPoolItem& rAttr ) const | ||||||
46 | { | ||||||
47 | assert(SfxPoolItem::operator==(rAttr))(static_cast <bool> (SfxPoolItem::operator==(rAttr)) ? void (0) : __assert_fail ("SfxPoolItem::operator==(rAttr)", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx" , 47, __extension__ __PRETTY_FUNCTION__)); | ||||||
48 | return( m_pTextAttr && static_cast<const SwFormatFlyCnt&>(rAttr).m_pTextAttr && | ||||||
49 | m_pTextAttr->GetStart() == static_cast<const SwFormatFlyCnt&>(rAttr).m_pTextAttr->GetStart() && | ||||||
50 | m_pFormat == static_cast<const SwFormatFlyCnt&>(rAttr).GetFrameFormat() ); | ||||||
51 | } | ||||||
52 | |||||||
53 | SwFormatFlyCnt* SwFormatFlyCnt::Clone( SfxItemPool* ) const | ||||||
54 | { | ||||||
55 | return new SwFormatFlyCnt( m_pFormat ); | ||||||
56 | } | ||||||
57 | |||||||
58 | SwTextFlyCnt::SwTextFlyCnt( SwFormatFlyCnt& rAttr, sal_Int32 nStartPos ) | ||||||
59 | : SwTextAttr( rAttr, nStartPos ) | ||||||
60 | { | ||||||
61 | rAttr.m_pTextAttr = this; | ||||||
62 | SetHasDummyChar(true); | ||||||
63 | } | ||||||
64 | |||||||
65 | /** An overview of how a new SwTextFlyCnt is created: | ||||||
66 | * MakeTextAttr() is called e.g. by SwTextNode::CopyText(). | ||||||
67 | * The following steps are required to clone: | ||||||
68 | * 1) copying the pFormat with content, attributes etc. | ||||||
69 | * 2) setting the anchor | ||||||
70 | * 3) notification | ||||||
71 | * Because not all required information is available at all times, | ||||||
72 | * the steps are distributed variously: | ||||||
73 | * ad 1) MakeTextAttr() calls DocumentLayoutManager::CopyLayoutFormat() | ||||||
74 | * which creates the new SwFlyFrameFormat and copies the content of the | ||||||
75 | * fly frame. | ||||||
76 | * ad 2) SetAnchor() is called by SwTextNode::InsertHint() and sets the anchor | ||||||
77 | * position in the SwFlyFrameFormat to the SwPosition of the dummy | ||||||
78 | * CH_TXTATR_BREAKWORD. This cannot be done in MakeTextAttr() because it | ||||||
79 | * doesn't know the target text node. | ||||||
80 | * ad 3) GetFlyFrame_() is called during text formatting by SwTextFormatter | ||||||
81 | * and searches for the SwFlyFrame for the dummy char of the current | ||||||
82 | * SwTextFrame. If none is found, a new SwFlyInContentFrame is created. | ||||||
83 | * Important: pTextFrame->AppendFly() immediately triggers a reformat | ||||||
84 | * of pTextFrame. However, the recursion is blocked by the lock mechanism | ||||||
85 | * in SwTextFrame::Format(). | ||||||
86 | * The advantage of all this is that it's not necessary to explicitly iterate | ||||||
87 | * over all SwTextFrames that depend on the SwTextNode to create the | ||||||
88 | * SwFlyInContentFrame - this is done automatically already. | ||||||
89 | */ | ||||||
90 | |||||||
91 | void SwTextFlyCnt::CopyFlyFormat( SwDoc& rDoc ) | ||||||
92 | { | ||||||
93 | SwFrameFormat* pFormat = GetFlyCnt().GetFrameFormat(); | ||||||
94 | assert(pFormat)(static_cast <bool> (pFormat) ? void (0) : __assert_fail ("pFormat", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx" , 94, __extension__ __PRETTY_FUNCTION__)); | ||||||
95 | // The FlyFrameFormat must be copied - CopyLayoutFormat | ||||||
96 | // (DocumentLayoutManager.cxx) creates the FlyFrameFormat and copies the | ||||||
97 | // content. | ||||||
98 | |||||||
99 | // disable undo while copying attribute | ||||||
100 | ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo()); | ||||||
101 | SwFormatAnchor aAnchor( pFormat->GetAnchor() ); | ||||||
102 | if ((RndStdIds::FLY_AT_PAGE != aAnchor.GetAnchorId()) && | ||||||
103 | (&rDoc != pFormat->GetDoc())) // different documents? | ||||||
104 | { | ||||||
105 | // JP 03.06.96: ensure that the copied anchor points to valid content! | ||||||
106 | // setting it to the correct position is done later. | ||||||
107 | SwNodeIndex aIdx( rDoc.GetNodes().GetEndOfExtras(), +2 ); | ||||||
108 | SwContentNode* pCNd = aIdx.GetNode().GetContentNode(); | ||||||
109 | if( !pCNd ) | ||||||
110 | pCNd = rDoc.GetNodes().GoNext( &aIdx ); | ||||||
111 | |||||||
112 | SwPosition pos = *aAnchor.GetContentAnchor(); | ||||||
113 | pos.nNode = aIdx; | ||||||
114 | if (RndStdIds::FLY_AS_CHAR == aAnchor.GetAnchorId()) | ||||||
115 | { | ||||||
116 | pos.nContent.Assign( pCNd, 0 ); | ||||||
117 | } | ||||||
118 | else | ||||||
119 | { | ||||||
120 | pos.nContent.Assign( nullptr, 0 ); | ||||||
121 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx" , 121, __extension__ __PRETTY_FUNCTION__)); | ||||||
122 | } | ||||||
123 | aAnchor.SetAnchor( &pos ); | ||||||
124 | } | ||||||
125 | |||||||
126 | SwFrameFormat* pNew = rDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, false, false ); | ||||||
127 | const_cast<SwFormatFlyCnt&>(GetFlyCnt()).SetFlyFormat( pNew ); | ||||||
128 | } | ||||||
129 | |||||||
130 | /** SetAnchor() is called by SwTextNode::InsertHint() and sets the anchor | ||||||
131 | * position in the SwFlyFrameFormat to the SwPosition of the dummy | ||||||
132 | * CH_TXTATR_BREAKWORD. This cannot be done in MakeTextAttr() because it | ||||||
133 | * doesn't know the target text node. | ||||||
134 | */ | ||||||
135 | void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode ) | ||||||
136 | { | ||||||
137 | // for Undo, the new anchor must be known already! | ||||||
138 | |||||||
139 | SwDoc& rDoc = const_cast<SwDoc&>(pNode->GetDoc()); | ||||||
140 | |||||||
141 | SwIndex aIdx( const_cast<SwTextNode*>(pNode), GetStart() ); | ||||||
142 | SwPosition aPos( *pNode->StartOfSectionNode(), aIdx ); | ||||||
143 | SwFrameFormat* pFormat = GetFlyCnt().GetFrameFormat(); | ||||||
144 | SwFormatAnchor aAnchor( pFormat->GetAnchor() ); | ||||||
145 | SwNode *const pOldNode(aAnchor.GetContentAnchor() | ||||||
| |||||||
146 | ? &aAnchor.GetContentAnchor()->nNode.GetNode() | ||||||
147 | : nullptr); | ||||||
148 | |||||||
149 | if (!pOldNode
| ||||||
150 | pOldNode != static_cast<SwNode const *>(pNode)) | ||||||
151 | { | ||||||
152 | aPos.nNode = *pNode; | ||||||
153 | } | ||||||
154 | else | ||||||
155 | { | ||||||
156 | aPos.nNode = *pOldNode; | ||||||
157 | } | ||||||
158 | |||||||
159 | aAnchor.SetType( RndStdIds::FLY_AS_CHAR ); // default! | ||||||
160 | aAnchor.SetAnchor( &aPos ); | ||||||
161 | |||||||
162 | // in case of anchor change, delete all FlyFrames | ||||||
163 | // JP 25.04.95: if the Frames can be moved within SplitNode, they don't | ||||||
164 | // need to be deleted | ||||||
165 | if( ( !pNode->GetpSwpHints() || !pNode->GetpSwpHints()->IsInSplitNode() ) | ||||||
166 | && RES_DRAWFRMFMT != pFormat->Which() ) | ||||||
167 | pFormat->DelFrames(); | ||||||
168 | |||||||
169 | // copy into a different document? | ||||||
170 | if( &rDoc != pFormat->GetDoc() ) | ||||||
171 | { | ||||||
172 | // disable undo while copying attribute | ||||||
173 | ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo()); | ||||||
174 | SwFrameFormat* pNew = rDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, false, false ); | ||||||
175 | |||||||
176 | ::sw::UndoGuard const undoGuardFormat( | ||||||
177 | pFormat->GetDoc()->GetIDocumentUndoRedo()); | ||||||
178 | pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat( pFormat ); | ||||||
179 | const_cast<SwFormatFlyCnt&>(GetFlyCnt()).SetFlyFormat( pNew ); | ||||||
180 | } | ||||||
181 | else if( pNode->GetpSwpHints() && | ||||||
182 | pNode->GetpSwpHints()->IsInSplitNode() && | ||||||
183 | RES_DRAWFRMFMT != pFormat->Which() ) | ||||||
184 | { | ||||||
185 | pFormat->LockModify(); | ||||||
186 | pFormat->SetFormatAttr( aAnchor ); // only set the anchor | ||||||
187 | // tdf#91228 must notify the anchor nodes despite LockModify | ||||||
188 | assert(pOldNode)(static_cast <bool> (pOldNode) ? void (0) : __assert_fail ("pOldNode", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx" , 188, __extension__ __PRETTY_FUNCTION__)); | ||||||
189 | pOldNode->RemoveAnchoredFly(pFormat); | ||||||
190 | aPos.nNode.GetNode().AddAnchoredFly(pFormat); | ||||||
191 | pFormat->UnlockModify(); | ||||||
192 | } | ||||||
193 | else | ||||||
194 | { | ||||||
195 | assert(!pFormat->IsModifyLocked())(static_cast <bool> (!pFormat->IsModifyLocked()) ? void (0) : __assert_fail ("!pFormat->IsModifyLocked()", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx" , 195, __extension__ __PRETTY_FUNCTION__)); // need to notify anchor node | ||||||
196 | if (RES_DRAWFRMFMT == pFormat->Which()) | ||||||
197 | { | ||||||
198 | if (SdrObject const*const pObj = pFormat->FindSdrObject()) | ||||||
199 | { // tdf#123259 disconnect with *old* anchor position | ||||||
200 | static_cast<SwDrawContact*>(::GetUserCall(pObj))->DisconnectFromLayout(false); | ||||||
201 | } | ||||||
202 | } | ||||||
203 | pFormat->SetFormatAttr( aAnchor ); // only set the anchor | ||||||
204 | |||||||
205 | // If the draw format has a TextBox, then set its anchor as well. | ||||||
206 | if (SwFrameFormat* pTextBox | ||||||
207 | = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) | ||||||
208 | { | ||||||
209 | SwFormatAnchor aTextBoxAnchor(pTextBox->GetAnchor()); | ||||||
210 | aTextBoxAnchor.SetAnchor(aAnchor.GetContentAnchor()); | ||||||
211 | |||||||
212 | // SwFlyAtContentFrame::Modify() assumes the anchor has a matching layout frame, which | ||||||
213 | // may not be the case when we're in the process of a node split, so block | ||||||
214 | // notifications. | ||||||
215 | bool bIsInSplitNode = pNode->GetpSwpHints() && pNode->GetpSwpHints()->IsInSplitNode(); | ||||||
216 | if (bIsInSplitNode
| ||||||
217 | { | ||||||
218 | pTextBox->LockModify(); | ||||||
219 | } | ||||||
220 | |||||||
221 | pTextBox->SetFormatAttr(aTextBoxAnchor); | ||||||
222 | |||||||
223 | if (bIsInSplitNode
| ||||||
224 | { | ||||||
225 | pOldNode->RemoveAnchoredFly(pTextBox); | ||||||
| |||||||
226 | aPos.nNode.GetNode().AddAnchoredFly(pTextBox); | ||||||
227 | pTextBox->UnlockModify(); | ||||||
228 | } | ||||||
229 | } | ||||||
230 | } | ||||||
231 | |||||||
232 | // The node may have several SwTextFrames - for every SwTextFrame a | ||||||
233 | // SwFlyInContentFrame is created. | ||||||
234 | } | ||||||
235 | |||||||
236 | |||||||
237 | /** GetFlyFrame_() is called during text formatting by SwTextFormatter | ||||||
238 | * and searches for the SwFlyFrame for the dummy char of the current | ||||||
239 | * SwTextFrame. If none is found, a new SwFlyInContentFrame is created. | ||||||
240 | */ | ||||||
241 | SwFlyInContentFrame *SwTextFlyCnt::GetFlyFrame_( const SwFrame *pCurrFrame ) | ||||||
242 | { | ||||||
243 | SwFrameFormat* pFrameFormat = GetFlyCnt().GetFrameFormat(); | ||||||
244 | if( RES_DRAWFRMFMT == pFrameFormat->Which() ) | ||||||
245 | { | ||||||
246 | OSL_ENSURE( false, "SwTextFlyCnt::GetFlyFrame_: DrawInCnt-under construction!" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx" ":" "246" ": "), "%s", "SwTextFlyCnt::GetFlyFrame_: DrawInCnt-under construction!" ); } } while (false); | ||||||
247 | return nullptr; | ||||||
248 | } | ||||||
249 | |||||||
250 | SwIterator<SwFlyFrame,SwFormat> aIter( *GetFlyCnt().m_pFormat ); | ||||||
251 | assert(pCurrFrame->IsTextFrame())(static_cast <bool> (pCurrFrame->IsTextFrame()) ? void (0) : __assert_fail ("pCurrFrame->IsTextFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx" , 251, __extension__ __PRETTY_FUNCTION__)); | ||||||
252 | SwFrame* pFrame = aIter.First(); | ||||||
253 | if ( pFrame ) | ||||||
254 | { | ||||||
255 | SwTextFrame *pFirst = const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pCurrFrame)); | ||||||
256 | while ( pFirst->IsFollow() ) | ||||||
257 | pFirst = pFirst->FindMaster(); | ||||||
258 | do | ||||||
259 | { | ||||||
260 | SwTextFrame *pTmp = pFirst; | ||||||
261 | do | ||||||
262 | { if( static_cast<SwFlyFrame*>(pFrame)->GetAnchorFrame() == static_cast<SwFrame*>(pTmp) ) | ||||||
263 | { | ||||||
264 | if ( pTmp != pCurrFrame ) | ||||||
265 | { | ||||||
266 | pTmp->RemoveFly( static_cast<SwFlyFrame*>(pFrame) ); | ||||||
267 | const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pCurrFrame))->AppendFly( static_cast<SwFlyFrame*>(pFrame) ); | ||||||
268 | } | ||||||
269 | return static_cast<SwFlyInContentFrame*>(pFrame); | ||||||
270 | } | ||||||
271 | pTmp = pTmp->GetFollow(); | ||||||
272 | } while ( pTmp ); | ||||||
273 | |||||||
274 | pFrame = aIter.Next(); | ||||||
275 | |||||||
276 | } while( pFrame ); | ||||||
277 | } | ||||||
278 | |||||||
279 | // We did not find a matching FlyFrame, so create a new one. | ||||||
280 | // AppendFly() triggers a reformat of pCurrentFrame. However, the | ||||||
281 | // recursion is blocked by the lock mechanism in SwTextFrame::Format(). | ||||||
282 | SwFrame* pCurrentFrame = const_cast<SwFrame*>(pCurrFrame); | ||||||
283 | SwFlyInContentFrame *pFly = new SwFlyInContentFrame(static_cast<SwFlyFrameFormat*>(pFrameFormat), pCurrentFrame, pCurrentFrame); | ||||||
284 | pCurrentFrame->AppendFly(pFly); | ||||||
285 | pFly->RegistFlys(); | ||||||
286 | |||||||
287 | // We must ensure that the content of the FlyInCnt is fully formatted | ||||||
288 | // right after construction. | ||||||
289 | // #i26945# - Use new object formatter to format Writer | ||||||
290 | // fly frame and its content. | ||||||
291 | SwObjectFormatter::FormatObj( *pFly, const_cast<SwFrame*>(pCurrFrame), | ||||||
292 | pCurrFrame->FindPageFrame() ); | ||||||
293 | |||||||
294 | return pFly; | ||||||
295 | } | ||||||
296 | |||||||
297 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | * |
9 | * This file incorporates work covered by the following license notice: |
10 | * |
11 | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | * contributor license agreements. See the NOTICE file distributed |
13 | * with this work for additional information regarding copyright |
14 | * ownership. The ASF licenses this file to you under the Apache |
15 | * License, Version 2.0 (the "License"); you may not use this file |
16 | * except in compliance with the License. You may obtain a copy of |
17 | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | */ |
19 | #ifndef INCLUDED_SW_INC_NDHINTS_HXX |
20 | #define INCLUDED_SW_INC_NDHINTS_HXX |
21 | |
22 | #include "swtypes.hxx" |
23 | |
24 | class SwTextNode; |
25 | class SwRegHistory; // Is in RolBck.hxx. |
26 | class SwTextAttr; |
27 | class SwTextAttrNesting; |
28 | |
29 | class SfxPoolItem; |
30 | class SfxItemSet; |
31 | class SwDoc; |
32 | |
33 | enum class CopyOrNewType { Copy, New }; |
34 | |
35 | /// if COPY then pTextNode must be given! |
36 | SwTextAttr * MakeTextAttr( |
37 | SwDoc & rDoc, |
38 | SfxPoolItem & rNew, |
39 | sal_Int32 const nStt, |
40 | sal_Int32 const nEnd, |
41 | CopyOrNewType const bIsCopy = CopyOrNewType::New, |
42 | SwTextNode *const pTextNode = nullptr ); |
43 | |
44 | SwTextAttr * MakeTextAttr( |
45 | SwDoc & rDoc, |
46 | const SfxItemSet & rSet, |
47 | sal_Int32 nStt, |
48 | sal_Int32 nEnd ); |
49 | |
50 | /// create redline dummy text hint that must not be inserted into hints array |
51 | SwTextAttr* MakeRedlineTextAttr( |
52 | SwDoc & rDoc, |
53 | SfxPoolItem const & rAttr ); |
54 | |
55 | struct CompareSwpHtEnd |
56 | { |
57 | bool operator()( sal_Int32 nEndPos, const SwTextAttr* rhs ) const; |
58 | bool operator()( const SwTextAttr* lhs, const SwTextAttr* rhs ) const; |
59 | }; |
60 | struct CompareSwpHtWhichStart |
61 | { |
62 | bool operator()( const SwTextAttr* lhs, const sal_uInt16 nWhich ) const; |
63 | bool operator()( const SwTextAttr* lhs, const SwTextAttr* rhs ) const; |
64 | }; |
65 | |
66 | /// An SwTextAttr container, stores all directly formatted text portions for a text node. |
67 | class SwpHints |
68 | { |
69 | private: |
70 | const SwTextNode& m_rParent; |
71 | |
72 | // SAL_MAX_SIZE is used by GetStartOf to return |
73 | // failure, so just allow SAL_MAX_SIZE-1 hints |
74 | static const size_t MAX_HINTS = SAL_MAX_SIZE((sal_uInt64) 0xFFFFFFFFFFFFFFFFul)-1; |
75 | |
76 | std::vector<SwTextAttr*> m_HintsByStart; |
77 | std::vector<SwTextAttr*> m_HintsByEnd; |
78 | std::vector<SwTextAttr*> m_HintsByWhichAndStart; |
79 | |
80 | SwRegHistory* m_pHistory; ///< for Undo |
81 | |
82 | /// true: the Node is in Split and Frames are moved |
83 | bool m_bInSplitNode : 1; |
84 | // m_bHiddenByParaField is invalid, call CalcHiddenParaField() |
85 | mutable bool m_bCalcHiddenParaField : 1; |
86 | // if all fields controlling visibility of the paragraph require to hide it |
87 | // (if there's no such fields, or if any field requires to show, then this is false) |
88 | mutable bool m_bHiddenByParaField : 1; |
89 | bool m_bFootnote : 1; ///< footnotes |
90 | bool m_bDDEFields : 1; ///< the TextNode has DDE fields |
91 | // Sort on demand to avoid O(n^2) behaviour |
92 | mutable bool m_bStartMapNeedsSorting : 1; |
93 | mutable bool m_bEndMapNeedsSorting : 1; |
94 | mutable bool m_bWhichMapNeedsSorting : 1; |
95 | |
96 | /// records a new attribute in m_pHistory. |
97 | void NoteInHistory( SwTextAttr *pAttr, const bool bNew = false ); |
98 | |
99 | void CalcFlags( ); |
100 | |
101 | /** Delete methods may only be called by the TextNode! |
102 | Because the TextNode also guarantees removal of the Character for |
103 | attributes without an end. */ |
104 | friend class SwTextNode; |
105 | void DeleteAtPos( size_t nPos ); |
106 | /// Delete the given Hint. The Hint must actually be in the array! |
107 | void Delete( SwTextAttr const * pTextHt ); |
108 | |
109 | void SetInSplitNode(bool bInSplit) { m_bInSplitNode = bInSplit; } |
110 | void SetCalcHiddenParaField() const { m_bCalcHiddenParaField = true; } |
111 | void SetHiddenByParaField( const bool bNew ) const { m_bHiddenByParaField = bNew; } |
112 | bool IsHiddenByParaField() const |
113 | { |
114 | if ( m_bCalcHiddenParaField ) |
115 | { |
116 | CalcHiddenParaField(); |
117 | } |
118 | return m_bHiddenByParaField; |
119 | } |
120 | |
121 | void InsertNesting(SwTextAttrNesting & rNewHint); |
122 | bool TryInsertNesting(SwTextNode & rNode, SwTextAttrNesting & rNewHint); |
123 | void BuildPortions( SwTextNode& rNode, SwTextAttr& rNewHint, |
124 | const SetAttrMode nMode ); |
125 | bool MergePortions( SwTextNode& rNode ); |
126 | |
127 | void Insert(SwTextAttr* pHt); |
128 | SW_DLLPUBLIC__attribute__ ((visibility("default"))) void Resort() const; |
129 | SW_DLLPUBLIC__attribute__ ((visibility("default"))) void ResortStartMap() const; |
130 | SW_DLLPUBLIC__attribute__ ((visibility("default"))) void ResortEndMap() const; |
131 | SW_DLLPUBLIC__attribute__ ((visibility("default"))) void ResortWhichMap() const; |
132 | |
133 | size_t GetIndexOf( const SwTextAttr *pHt ) const; |
134 | |
135 | #ifdef DBG_UTIL |
136 | bool Check(bool) const; |
137 | #endif |
138 | |
139 | public: |
140 | SwpHints(const SwTextNode& rParent); |
141 | |
142 | size_t Count() const { return m_HintsByStart.size(); } |
143 | bool Contains( const SwTextAttr *pHt ) const; |
144 | SwTextAttr * Get( size_t nPos ) const |
145 | { |
146 | assert( !(nPos != 0 && m_bStartMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" )(static_cast <bool> (!(nPos != 0 && m_bStartMapNeedsSorting ) && "going to trigger a resort in the middle of an iteration, that's bad" ) ? void (0) : __assert_fail ("!(nPos != 0 && m_bStartMapNeedsSorting) && \"going to trigger a resort in the middle of an iteration, that's bad\"" , "/home/maarten/src/libreoffice/core/sw/inc/ndhints.hxx", 146 , __extension__ __PRETTY_FUNCTION__)); |
147 | if (m_bStartMapNeedsSorting) |
148 | ResortStartMap(); |
149 | return m_HintsByStart[nPos]; |
150 | } |
151 | // Get without triggering resorting - useful if we are modifying start/end pos while iterating |
152 | SwTextAttr * GetWithoutResorting( size_t nPos ) const |
153 | { |
154 | return m_HintsByStart[nPos]; |
155 | } |
156 | |
157 | int GetLastPosSortedByEnd(sal_Int32 nEndPos) const; |
158 | SwTextAttr * GetSortedByEnd( size_t nPos ) const |
159 | { |
160 | assert( !(nPos != 0 && m_bEndMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" )(static_cast <bool> (!(nPos != 0 && m_bEndMapNeedsSorting ) && "going to trigger a resort in the middle of an iteration, that's bad" ) ? void (0) : __assert_fail ("!(nPos != 0 && m_bEndMapNeedsSorting) && \"going to trigger a resort in the middle of an iteration, that's bad\"" , "/home/maarten/src/libreoffice/core/sw/inc/ndhints.hxx", 160 , __extension__ __PRETTY_FUNCTION__)); |
161 | if (m_bEndMapNeedsSorting) |
162 | ResortEndMap(); |
163 | return m_HintsByEnd[nPos]; |
164 | } |
165 | |
166 | size_t GetFirstPosSortedByWhichAndStart(sal_uInt16 nWhich) const; |
167 | SwTextAttr * GetSortedByWhichAndStart( size_t nPos ) const |
168 | { |
169 | assert( !(nPos != 0 && m_bWhichMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" )(static_cast <bool> (!(nPos != 0 && m_bWhichMapNeedsSorting ) && "going to trigger a resort in the middle of an iteration, that's bad" ) ? void (0) : __assert_fail ("!(nPos != 0 && m_bWhichMapNeedsSorting) && \"going to trigger a resort in the middle of an iteration, that's bad\"" , "/home/maarten/src/libreoffice/core/sw/inc/ndhints.hxx", 169 , __extension__ __PRETTY_FUNCTION__)); |
170 | if (m_bWhichMapNeedsSorting) |
171 | ResortWhichMap(); |
172 | return m_HintsByWhichAndStart[nPos]; |
173 | } |
174 | |
175 | /// Trigger the sorting if necessary |
176 | void SortIfNeedBe() const |
177 | { |
178 | if (m_bStartMapNeedsSorting) |
179 | ResortStartMap(); |
180 | if (m_bEndMapNeedsSorting) |
181 | ResortEndMap(); |
182 | if (m_bWhichMapNeedsSorting) |
183 | ResortWhichMap(); |
184 | } |
185 | SwTextAttr * Cut( const size_t nPosInStart ) |
186 | { |
187 | SwTextAttr *pHt = m_HintsByStart[nPosInStart]; |
188 | DeleteAtPos( nPosInStart ); |
189 | return pHt; |
190 | } |
191 | |
192 | bool CanBeDeleted() const { return m_HintsByStart.empty(); } |
193 | |
194 | /// register a History, which receives all attribute changes (for Undo) |
195 | void Register( SwRegHistory* pHist ) { m_pHistory = pHist; } |
196 | /// deregister the currently registered History |
197 | void DeRegister() { Register(nullptr); } |
198 | SwRegHistory* GetHistory() const { return m_pHistory; } |
199 | |
200 | /// try to insert the hint |
201 | /// @return true iff hint successfully inserted |
202 | bool TryInsertHint( SwTextAttr * const pHint, SwTextNode & rNode, |
203 | const SetAttrMode nMode = SetAttrMode::DEFAULT ); |
204 | |
205 | bool HasFootnote() const { return m_bFootnote; } |
206 | bool IsInSplitNode() const { return m_bInSplitNode; } |
207 | |
208 | // calc current value of m_bHiddenByParaField, returns true iff changed |
209 | bool CalcHiddenParaField() const; // changes mutable state |
210 | |
211 | // Marks the hint-maps as needing sorting because the position of something has changed |
212 | void StartPosChanged() const { m_bStartMapNeedsSorting = true; m_bEndMapNeedsSorting = true; m_bWhichMapNeedsSorting = true; } |
213 | void EndPosChanged() const { m_bStartMapNeedsSorting = true; m_bEndMapNeedsSorting = true; m_bWhichMapNeedsSorting = true; } |
214 | }; |
215 | |
216 | #endif |
217 | |
218 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ |
2 | /* |
3 | * This file is part of the LibreOffice project. |
4 | * |
5 | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | */ |
9 | #ifndef INCLUDED_SVL_TYPEDWHICH_HXX |
10 | #define INCLUDED_SVL_TYPEDWHICH_HXX |
11 | |
12 | #include <sal/config.h> |
13 | #include <sal/types.h> |
14 | |
15 | /** |
16 | * A very thin wrapper around the sal_uInt16 WhichId whose purpose is mostly to carry type information, |
17 | * so that we Put() and Get() the right subclasses of SfxPoolItem for each WhichId. |
18 | */ |
19 | template <class T> class TypedWhichId final |
20 | { |
21 | public: |
22 | explicit constexpr TypedWhichId(sal_uInt16 nWhich) |
23 | : mnWhich(nWhich) |
24 | { |
25 | } |
26 | constexpr operator sal_uInt16() const { return mnWhich; } |
27 | |
28 | private: |
29 | sal_uInt16 const mnWhich; |
30 | }; |
31 | |
32 | template <class T> constexpr bool operator==(sal_uInt16 lhs, TypedWhichId<T> const& rhs) |
33 | { |
34 | return lhs == sal_uInt16(rhs); |
35 | } |
36 | template <class T> constexpr bool operator!=(sal_uInt16 lhs, TypedWhichId<T> const& rhs) |
37 | { |
38 | return lhs != sal_uInt16(rhs); |
39 | } |
40 | template <class T> constexpr bool operator==(TypedWhichId<T> const& lhs, sal_uInt16 rhs) |
41 | { |
42 | return sal_uInt16(lhs) == rhs; |
43 | } |
44 | template <class T> constexpr bool operator!=(TypedWhichId<T> const& lhs, sal_uInt16 rhs) |
45 | { |
46 | return sal_uInt16(lhs) != rhs; |
47 | } |
48 | |
49 | #endif // INCLUDED_SVL_TYPEDWHICH_HXX |
50 | |
51 | /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ |