File: | home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx |
Warning: | line 810, column 58 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 <editeng/protitem.hxx> | |||
22 | #include <tools/gen.hxx> | |||
23 | #include <com/sun/star/i18n/CharacterIteratorMode.hpp> | |||
24 | #include <com/sun/star/i18n/XBreakIterator.hpp> | |||
25 | #include <fmtcntnt.hxx> | |||
26 | #include <fmtanchr.hxx> | |||
27 | #include <frmfmt.hxx> | |||
28 | #include <txtftn.hxx> | |||
29 | #include <ftnfrm.hxx> | |||
30 | #include <doc.hxx> | |||
31 | #include <docary.hxx> | |||
32 | #include <node.hxx> | |||
33 | #include <ndindex.hxx> | |||
34 | #include <numrule.hxx> | |||
35 | #include <swtable.hxx> | |||
36 | #include <ndtxt.hxx> | |||
37 | #include <pam.hxx> | |||
38 | #include <swcache.hxx> | |||
39 | #include <section.hxx> | |||
40 | #include <cntfrm.hxx> | |||
41 | #include <flyfrm.hxx> | |||
42 | #include <txtfrm.hxx> | |||
43 | #include <tabfrm.hxx> | |||
44 | #include <viewsh.hxx> | |||
45 | #include <paratr.hxx> | |||
46 | #include <ftnidx.hxx> | |||
47 | #include <fmtftn.hxx> | |||
48 | #include <fmthdft.hxx> | |||
49 | #include <frmatr.hxx> | |||
50 | #include <fmtautofmt.hxx> | |||
51 | #include <frmtool.hxx> | |||
52 | #include <pagefrm.hxx> | |||
53 | #include <node2lay.hxx> | |||
54 | #include <pagedesc.hxx> | |||
55 | #include <fmtpdsc.hxx> | |||
56 | #include <breakit.hxx> | |||
57 | #include <SwStyleNameMapper.hxx> | |||
58 | #include <scriptinfo.hxx> | |||
59 | #include <rootfrm.hxx> | |||
60 | #include <istyleaccess.hxx> | |||
61 | #include <IDocumentListItems.hxx> | |||
62 | #include <DocumentSettingManager.hxx> | |||
63 | #include <IDocumentLinksAdministration.hxx> | |||
64 | #include <IDocumentRedlineAccess.hxx> | |||
65 | #include <IDocumentLayoutAccess.hxx> | |||
66 | #include <calbck.hxx> | |||
67 | #include <ndole.hxx> | |||
68 | #include <memory> | |||
69 | #include <swcrsr.hxx> | |||
70 | #include <hints.hxx> | |||
71 | #include <frameformats.hxx> | |||
72 | ||||
73 | using namespace ::com::sun::star::i18n; | |||
74 | ||||
75 | ||||
76 | /* | |||
77 | * Some local helper functions for the attribute set handle of a content node. | |||
78 | * Since the attribute set of a content node may not be modified directly, | |||
79 | * we always have to create a new SwAttrSet, do the modifications, and get | |||
80 | * a new handle from the style access | |||
81 | */ | |||
82 | ||||
83 | namespace AttrSetHandleHelper | |||
84 | { | |||
85 | ||||
86 | static void GetNewAutoStyle( std::shared_ptr<const SfxItemSet>& rpAttrSet, | |||
87 | const SwContentNode& rNode, | |||
88 | SwAttrSet const & rNewAttrSet ) | |||
89 | { | |||
90 | const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(rpAttrSet.get()); | |||
91 | if( rNode.GetModifyAtAttr() ) | |||
92 | const_cast<SwAttrSet*>(pAttrSet)->SetModifyAtAttr( nullptr ); | |||
93 | IStyleAccess& rSA = pAttrSet->GetPool()->GetDoc()->GetIStyleAccess(); | |||
94 | rpAttrSet = rSA.getAutomaticStyle( rNewAttrSet, rNode.IsTextNode() ? | |||
95 | IStyleAccess::AUTO_STYLE_PARA : | |||
96 | IStyleAccess::AUTO_STYLE_NOTXT ); | |||
97 | const bool bSetModifyAtAttr = const_cast<SwAttrSet*>(static_cast<const SwAttrSet*>(rpAttrSet.get()))->SetModifyAtAttr( &rNode ); | |||
98 | rNode.SetModifyAtAttr( bSetModifyAtAttr ); | |||
99 | } | |||
100 | ||||
101 | static void SetParent( std::shared_ptr<const SfxItemSet>& rpAttrSet, | |||
102 | const SwContentNode& rNode, | |||
103 | const SwFormat* pParentFormat, | |||
104 | const SwFormat* pConditionalFormat ) | |||
105 | { | |||
106 | const SwAttrSet* pAttrSet = static_cast<const SwAttrSet*>(rpAttrSet.get()); | |||
107 | OSL_ENSURE( pAttrSet, "no SwAttrSet" )do { if (true && (!(pAttrSet))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "107" ": "), "%s", "no SwAttrSet"); } } while (false); | |||
108 | OSL_ENSURE( pParentFormat || !pConditionalFormat, "ConditionalFormat without ParentFormat?" )do { if (true && (!(pParentFormat || !pConditionalFormat ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "108" ": "), "%s", "ConditionalFormat without ParentFormat?" ); } } while (false); | |||
109 | ||||
110 | const SwAttrSet* pParentSet = pParentFormat ? &pParentFormat->GetAttrSet() : nullptr; | |||
111 | ||||
112 | if ( pParentSet == pAttrSet->GetParent() ) | |||
113 | return; | |||
114 | ||||
115 | SwAttrSet aNewSet( *pAttrSet ); | |||
116 | aNewSet.SetParent( pParentSet ); | |||
117 | aNewSet.ClearItem( RES_FRMATR_STYLE_NAME ); | |||
118 | aNewSet.ClearItem( RES_FRMATR_CONDITIONAL_STYLE_NAME ); | |||
119 | ||||
120 | if ( pParentFormat ) | |||
121 | { | |||
122 | OUString sVal; | |||
123 | SwStyleNameMapper::FillProgName( pParentFormat->GetName(), sVal, SwGetPoolIdFromName::TxtColl ); | |||
124 | const SfxStringItem aAnyFormatColl( RES_FRMATR_STYLE_NAME, sVal ); | |||
125 | aNewSet.Put( aAnyFormatColl ); | |||
126 | ||||
127 | if ( pConditionalFormat != pParentFormat ) | |||
128 | SwStyleNameMapper::FillProgName( pConditionalFormat->GetName(), sVal, SwGetPoolIdFromName::TxtColl ); | |||
129 | ||||
130 | const SfxStringItem aFormatColl( RES_FRMATR_CONDITIONAL_STYLE_NAME, sVal ); | |||
131 | aNewSet.Put( aFormatColl ); | |||
132 | } | |||
133 | ||||
134 | GetNewAutoStyle( rpAttrSet, rNode, aNewSet ); | |||
135 | } | |||
136 | ||||
137 | static const SfxPoolItem* Put( std::shared_ptr<const SfxItemSet>& rpAttrSet, | |||
138 | const SwContentNode& rNode, | |||
139 | const SfxPoolItem& rAttr ) | |||
140 | { | |||
141 | SwAttrSet aNewSet( static_cast<const SwAttrSet&>(*rpAttrSet) ); | |||
142 | const SfxPoolItem* pRet = aNewSet.Put( rAttr ); | |||
143 | if ( pRet ) | |||
144 | GetNewAutoStyle( rpAttrSet, rNode, aNewSet ); | |||
145 | return pRet; | |||
146 | } | |||
147 | ||||
148 | static bool Put( std::shared_ptr<const SfxItemSet>& rpAttrSet, const SwContentNode& rNode, | |||
149 | const SfxItemSet& rSet ) | |||
150 | { | |||
151 | SwAttrSet aNewSet( static_cast<const SwAttrSet&>(*rpAttrSet) ); | |||
152 | ||||
153 | // #i76273# Robust | |||
154 | std::unique_ptr<SfxItemSet> pStyleNames; | |||
155 | if ( SfxItemState::SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, false ) ) | |||
156 | { | |||
157 | pStyleNames.reset(new SfxItemSet( *aNewSet.GetPool(), svl::Items<RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME>{} )); | |||
158 | pStyleNames->Put( aNewSet ); | |||
159 | } | |||
160 | ||||
161 | const bool bRet = aNewSet.Put( rSet ); | |||
162 | ||||
163 | // #i76273# Robust | |||
164 | if ( pStyleNames ) | |||
165 | { | |||
166 | aNewSet.Put( *pStyleNames ); | |||
167 | } | |||
168 | ||||
169 | if ( bRet ) | |||
170 | GetNewAutoStyle( rpAttrSet, rNode, aNewSet ); | |||
171 | ||||
172 | return bRet; | |||
173 | } | |||
174 | ||||
175 | static bool Put_BC( std::shared_ptr<const SfxItemSet>& rpAttrSet, | |||
176 | const SwContentNode& rNode, const SfxPoolItem& rAttr, | |||
177 | SwAttrSet* pOld, SwAttrSet* pNew ) | |||
178 | { | |||
179 | SwAttrSet aNewSet( static_cast<const SwAttrSet&>(*rpAttrSet) ); | |||
180 | ||||
181 | // for a correct broadcast, we need to do a SetModifyAtAttr with the items | |||
182 | // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle | |||
183 | if( rNode.GetModifyAtAttr() ) | |||
184 | aNewSet.SetModifyAtAttr( &rNode ); | |||
185 | ||||
186 | const bool bRet = aNewSet.Put_BC( rAttr, pOld, pNew ); | |||
187 | ||||
188 | if ( bRet ) | |||
189 | GetNewAutoStyle( rpAttrSet, rNode, aNewSet ); | |||
190 | ||||
191 | return bRet; | |||
192 | } | |||
193 | ||||
194 | static bool Put_BC( std::shared_ptr<const SfxItemSet>& rpAttrSet, | |||
195 | const SwContentNode& rNode, const SfxItemSet& rSet, | |||
196 | SwAttrSet* pOld, SwAttrSet* pNew ) | |||
197 | { | |||
198 | SwAttrSet aNewSet( static_cast<const SwAttrSet&>(*rpAttrSet) ); | |||
199 | ||||
200 | // #i76273# Robust | |||
201 | std::unique_ptr<SfxItemSet> pStyleNames; | |||
202 | if ( SfxItemState::SET == rSet.GetItemState( RES_FRMATR_STYLE_NAME, false ) ) | |||
203 | { | |||
204 | pStyleNames.reset(new SfxItemSet( *aNewSet.GetPool(), svl::Items<RES_FRMATR_STYLE_NAME, RES_FRMATR_CONDITIONAL_STYLE_NAME>{} )); | |||
205 | pStyleNames->Put( aNewSet ); | |||
206 | } | |||
207 | ||||
208 | // for a correct broadcast, we need to do a SetModifyAtAttr with the items | |||
209 | // from aNewSet. The 'regular' SetModifyAtAttr is done in GetNewAutoStyle | |||
210 | if( rNode.GetModifyAtAttr() ) | |||
211 | aNewSet.SetModifyAtAttr( &rNode ); | |||
212 | ||||
213 | const bool bRet = aNewSet.Put_BC( rSet, pOld, pNew ); | |||
214 | ||||
215 | // #i76273# Robust | |||
216 | if ( pStyleNames ) | |||
217 | { | |||
218 | aNewSet.Put( *pStyleNames ); | |||
219 | } | |||
220 | ||||
221 | if ( bRet ) | |||
222 | GetNewAutoStyle( rpAttrSet, rNode, aNewSet ); | |||
223 | ||||
224 | return bRet; | |||
225 | } | |||
226 | ||||
227 | static sal_uInt16 ClearItem_BC( std::shared_ptr<const SfxItemSet>& rpAttrSet, | |||
228 | const SwContentNode& rNode, sal_uInt16 nWhich, | |||
229 | SwAttrSet* pOld, SwAttrSet* pNew ) | |||
230 | { | |||
231 | SwAttrSet aNewSet( static_cast<const SwAttrSet&>(*rpAttrSet) ); | |||
232 | if( rNode.GetModifyAtAttr() ) | |||
233 | aNewSet.SetModifyAtAttr( &rNode ); | |||
234 | const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich, pOld, pNew ); | |||
235 | if ( nRet ) | |||
236 | GetNewAutoStyle( rpAttrSet, rNode, aNewSet ); | |||
237 | return nRet; | |||
238 | } | |||
239 | ||||
240 | static sal_uInt16 ClearItem_BC( std::shared_ptr<const SfxItemSet>& rpAttrSet, | |||
241 | const SwContentNode& rNode, | |||
242 | sal_uInt16 nWhich1, sal_uInt16 nWhich2, | |||
243 | SwAttrSet* pOld, SwAttrSet* pNew ) | |||
244 | { | |||
245 | SwAttrSet aNewSet( static_cast<const SwAttrSet&>(*rpAttrSet) ); | |||
246 | if( rNode.GetModifyAtAttr() ) | |||
247 | aNewSet.SetModifyAtAttr( &rNode ); | |||
248 | const sal_uInt16 nRet = aNewSet.ClearItem_BC( nWhich1, nWhich2, pOld, pNew ); | |||
249 | if ( nRet ) | |||
250 | GetNewAutoStyle( rpAttrSet, rNode, aNewSet ); | |||
251 | return nRet; | |||
252 | } | |||
253 | ||||
254 | } | |||
255 | ||||
256 | /** Returns the section level at the position given by aIndex. | |||
257 | * | |||
258 | * We use the following logic: | |||
259 | * S = Start, E = End, C = ContentNode | |||
260 | * Level 0 = E | |||
261 | * 1 = S E | |||
262 | * 2 = SC | |||
263 | * | |||
264 | * All EndNodes of the BaseSection have level 0 | |||
265 | * All StartNodes of the BaseSection have level 1 | |||
266 | */ | |||
267 | sal_uInt16 SwNode::GetSectionLevel() const | |||
268 | { | |||
269 | // EndNode of a BaseSection? They are always 0! | |||
270 | if( IsEndNode() && 0 == m_pStartOfSection->StartOfSectionIndex() ) | |||
271 | return 0; | |||
272 | ||||
273 | sal_uInt16 nLevel; | |||
274 | const SwNode* pNode = IsStartNode() ? this : m_pStartOfSection; | |||
275 | for( nLevel = 1; 0 != pNode->StartOfSectionIndex(); ++nLevel ) | |||
276 | pNode = pNode->m_pStartOfSection; | |||
277 | return IsEndNode() ? nLevel-1 : nLevel; | |||
278 | } | |||
279 | ||||
280 | #ifdef DBG_UTIL | |||
281 | long SwNode::s_nSerial = 0; | |||
282 | #endif | |||
283 | ||||
284 | SwNode::SwNode( const SwNodeIndex &rWhere, const SwNodeType nNdType ) | |||
285 | : m_nNodeType( nNdType ) | |||
286 | , m_nAFormatNumLvl( 0 ) | |||
287 | , m_bIgnoreDontExpand( false) | |||
288 | , m_eMerge(Merge::None) | |||
289 | #ifdef DBG_UTIL | |||
290 | , m_nSerial( s_nSerial++) | |||
291 | #endif | |||
292 | , m_pStartOfSection( nullptr ) | |||
293 | { | |||
294 | if( !rWhere.GetIndex() ) | |||
295 | return; | |||
296 | ||||
297 | SwNodes& rNodes = const_cast<SwNodes&> (rWhere.GetNodes()); | |||
298 | SwNode* pNd = rNodes[ rWhere.GetIndex() -1 ]; | |||
299 | rNodes.InsertNode( this, rWhere ); | |||
300 | m_pStartOfSection = pNd->GetStartNode(); | |||
301 | if( nullptr == m_pStartOfSection ) | |||
302 | { | |||
303 | m_pStartOfSection = pNd->m_pStartOfSection; | |||
304 | if( pNd->GetEndNode() ) // Skip EndNode ? Section | |||
305 | { | |||
306 | pNd = m_pStartOfSection; | |||
307 | m_pStartOfSection = pNd->m_pStartOfSection; | |||
308 | } | |||
309 | } | |||
310 | } | |||
311 | ||||
312 | /** Inserts a node into the rNodes array at the rWhere position | |||
313 | * | |||
314 | * @param rNodes the variable array in that the node will be inserted | |||
315 | * @param nPos position within the array where the node will be inserted | |||
316 | * @param nNdType the type of node to insert | |||
317 | */ | |||
318 | SwNode::SwNode( SwNodes& rNodes, sal_uLong nPos, const SwNodeType nNdType ) | |||
319 | : m_nNodeType( nNdType ) | |||
320 | , m_nAFormatNumLvl( 0 ) | |||
321 | , m_bIgnoreDontExpand( false) | |||
322 | , m_eMerge(Merge::None) | |||
323 | #ifdef DBG_UTIL | |||
324 | , m_nSerial( s_nSerial++) | |||
325 | #endif | |||
326 | , m_pStartOfSection( nullptr ) | |||
327 | { | |||
328 | if( !nPos ) | |||
329 | return; | |||
330 | ||||
331 | SwNode* pNd = rNodes[ nPos - 1 ]; | |||
332 | rNodes.InsertNode( this, nPos ); | |||
333 | m_pStartOfSection = pNd->GetStartNode(); | |||
334 | if( nullptr == m_pStartOfSection ) | |||
335 | { | |||
336 | m_pStartOfSection = pNd->m_pStartOfSection; | |||
337 | if( pNd->GetEndNode() ) // Skip EndNode ? Section! | |||
338 | { | |||
339 | pNd = m_pStartOfSection; | |||
340 | m_pStartOfSection = pNd->m_pStartOfSection; | |||
341 | } | |||
342 | } | |||
343 | } | |||
344 | ||||
345 | SwNode::~SwNode() | |||
346 | { | |||
347 | assert(!m_pAnchoredFlys || GetDoc().IsInDtor())(static_cast <bool> (!m_pAnchoredFlys || GetDoc().IsInDtor ()) ? void (0) : __assert_fail ("!m_pAnchoredFlys || GetDoc().IsInDtor()" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 347, __extension__ __PRETTY_FUNCTION__)); // must all be deleted | |||
348 | } | |||
349 | ||||
350 | /// Find the TableNode in which it is located. | |||
351 | /// If we're not in a table: return 0 | |||
352 | SwTableNode* SwNode::FindTableNode() | |||
353 | { | |||
354 | if( IsTableNode() ) | |||
355 | return GetTableNode(); | |||
356 | SwStartNode* pTmp = m_pStartOfSection; | |||
357 | while( !pTmp->IsTableNode() && pTmp->GetIndex() ) | |||
358 | pTmp = pTmp->m_pStartOfSection; | |||
359 | return pTmp->GetTableNode(); | |||
360 | } | |||
361 | ||||
362 | /// Is the node located in the visible area of the Shell? | |||
363 | bool SwNode::IsInVisibleArea( SwViewShell const * pSh ) const | |||
364 | { | |||
365 | bool bRet = false; | |||
366 | const SwContentNode* pNd; | |||
367 | ||||
368 | if( SwNodeType::Start & m_nNodeType ) | |||
369 | { | |||
370 | SwNodeIndex aIdx( *this ); | |||
371 | pNd = GetNodes().GoNext( &aIdx ); | |||
372 | } | |||
373 | else if( SwNodeType::End & m_nNodeType ) | |||
374 | { | |||
375 | SwNodeIndex aIdx( *EndOfSectionNode() ); | |||
376 | pNd = SwNodes::GoPrevious( &aIdx ); | |||
377 | } | |||
378 | else | |||
379 | pNd = GetContentNode(); | |||
380 | ||||
381 | if( !pSh ) | |||
382 | // Get the Shell from the Doc | |||
383 | pSh = GetDoc().getIDocumentLayoutAccess().GetCurrentViewShell(); | |||
384 | ||||
385 | if( pSh ) | |||
386 | { | |||
387 | const SwFrame* pFrame; | |||
388 | if (pNd && nullptr != (pFrame = pNd->getLayoutFrame(pSh->GetLayout(), nullptr, nullptr))) | |||
389 | { | |||
390 | ||||
391 | if ( pFrame->IsInTab() ) | |||
392 | pFrame = pFrame->FindTabFrame(); | |||
393 | ||||
394 | if( !pFrame->isFrameAreaDefinitionValid() ) | |||
395 | { | |||
396 | do | |||
397 | { | |||
398 | pFrame = pFrame->FindPrev(); | |||
399 | } | |||
400 | while ( pFrame && !pFrame->isFrameAreaDefinitionValid() ); | |||
401 | } | |||
402 | ||||
403 | if( !pFrame || pSh->VisArea().IsOver( pFrame->getFrameArea() ) ) | |||
404 | bRet = true; | |||
405 | } | |||
406 | } | |||
407 | ||||
408 | return bRet; | |||
409 | } | |||
410 | ||||
411 | bool SwNode::IsInProtectSect() const | |||
412 | { | |||
413 | const SwNode* pNd = SwNodeType::Section == m_nNodeType ? m_pStartOfSection : this; | |||
414 | const SwSectionNode* pSectNd = pNd->FindSectionNode(); | |||
415 | return pSectNd && pSectNd->GetSection().IsProtectFlag(); | |||
416 | } | |||
417 | ||||
418 | /// Does the node contain anything protected? | |||
419 | /// I.e.: Area/Frame/Table rows/... including the Anchor for | |||
420 | /// Frames/Footnotes/... | |||
421 | bool SwNode::IsProtect() const | |||
422 | { | |||
423 | const SwNode* pNd = SwNodeType::Section == m_nNodeType ? m_pStartOfSection : this; | |||
424 | const SwStartNode* pSttNd = pNd->FindSectionNode(); | |||
425 | if( pSttNd && static_cast<const SwSectionNode*>(pSttNd)->GetSection().IsProtectFlag() ) | |||
426 | return true; | |||
427 | ||||
428 | pSttNd = FindTableBoxStartNode(); | |||
429 | if( nullptr != pSttNd ) | |||
430 | { | |||
431 | SwContentFrame* pCFrame; | |||
432 | if( IsContentNode() && nullptr != (pCFrame = static_cast<const SwContentNode*>(this)->getLayoutFrame( GetDoc().getIDocumentLayoutAccess().GetCurrentLayout() ) )) | |||
433 | return pCFrame->IsProtected(); | |||
434 | ||||
435 | const SwTableBox* pBox = pSttNd->FindTableNode()->GetTable(). | |||
436 | GetTableBox( pSttNd->GetIndex() ); | |||
437 | //Robust #149568 | |||
438 | if( pBox && pBox->GetFrameFormat()->GetProtect().IsContentProtected() ) | |||
439 | return true; | |||
440 | } | |||
441 | ||||
442 | SwFrameFormat* pFlyFormat = GetFlyFormat(); | |||
443 | if( pFlyFormat ) | |||
444 | { | |||
445 | if (pFlyFormat->GetProtect().IsContentProtected()) | |||
446 | return true; | |||
447 | const SwFormatAnchor& rAnchor = pFlyFormat->GetAnchor(); | |||
448 | const SwPosition* pAnchorPos = rAnchor.GetContentAnchor(); | |||
449 | if (!pAnchorPos) | |||
450 | return false; | |||
451 | const SwNode& rAnchorNd = pAnchorPos->nNode.GetNode(); | |||
452 | return &rAnchorNd != this && rAnchorNd.IsProtect(); | |||
453 | } | |||
454 | ||||
455 | pSttNd = FindFootnoteStartNode(); | |||
456 | if( nullptr != pSttNd ) | |||
457 | { | |||
458 | const SwTextFootnote* pTFootnote = GetDoc().GetFootnoteIdxs().SeekEntry( | |||
459 | SwNodeIndex( *pSttNd ) ); | |||
460 | if( pTFootnote ) | |||
461 | return pTFootnote->GetTextNode().IsProtect(); | |||
462 | } | |||
463 | ||||
464 | return false; | |||
465 | } | |||
466 | ||||
467 | /// Find the PageDesc that is used to format this node. If the Layout is available, | |||
468 | /// we search through that. Else we can only do it the hard way by searching onwards through the nodes. | |||
469 | const SwPageDesc* SwNode::FindPageDesc( size_t* pPgDescNdIdx ) const | |||
470 | { | |||
471 | if ( !GetNodes().IsDocNodes() ) | |||
472 | { | |||
473 | return nullptr; | |||
474 | } | |||
475 | ||||
476 | const SwPageDesc* pPgDesc = nullptr; | |||
477 | ||||
478 | const SwContentNode* pNode; | |||
479 | if( SwNodeType::Start & m_nNodeType ) | |||
480 | { | |||
481 | SwNodeIndex aIdx( *this ); | |||
482 | pNode = GetNodes().GoNext( &aIdx ); | |||
483 | } | |||
484 | else if( SwNodeType::End & m_nNodeType ) | |||
485 | { | |||
486 | SwNodeIndex aIdx( *EndOfSectionNode() ); | |||
487 | pNode = SwNodes::GoPrevious( &aIdx ); | |||
488 | } | |||
489 | else | |||
490 | { | |||
491 | pNode = GetContentNode(); | |||
492 | if( pNode ) | |||
493 | pPgDesc = static_cast<const SwFormatPageDesc&>(pNode->GetAttr( RES_PAGEDESC )).GetPageDesc(); | |||
494 | } | |||
495 | ||||
496 | // Are we going through the layout? | |||
497 | if( !pPgDesc ) | |||
498 | { | |||
499 | const SwFrame* pFrame; | |||
500 | const SwPageFrame* pPage; | |||
501 | if (pNode && nullptr != (pFrame = pNode->getLayoutFrame(pNode->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, nullptr)) && | |||
502 | nullptr != ( pPage = pFrame->FindPageFrame() ) ) | |||
503 | { | |||
504 | pPgDesc = pPage->GetPageDesc(); | |||
505 | if ( pPgDescNdIdx ) | |||
506 | { | |||
507 | *pPgDescNdIdx = pNode->GetIndex(); | |||
508 | } | |||
509 | } | |||
510 | } | |||
511 | ||||
512 | if( !pPgDesc ) | |||
513 | { | |||
514 | // Thus via the nodes array | |||
515 | const SwDoc& rDoc = GetDoc(); | |||
516 | const SwNode* pNd = this; | |||
517 | const SwStartNode* pSttNd; | |||
518 | if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() && | |||
519 | nullptr != ( pSttNd = pNd->FindFlyStartNode() ) ) | |||
520 | { | |||
521 | // Find the right Anchor first | |||
522 | const SwFrameFormat* pFormat = nullptr; | |||
523 | const SwFrameFormats& rFormats = *rDoc.GetSpzFrameFormats(); | |||
524 | ||||
525 | for( size_t n = 0; n < rFormats.size(); ++n ) | |||
526 | { | |||
527 | const SwFrameFormat* pFrameFormat = rFormats[ n ]; | |||
528 | const SwFormatContent& rContent = pFrameFormat->GetContent(); | |||
529 | if( rContent.GetContentIdx() && | |||
530 | &rContent.GetContentIdx()->GetNode() == static_cast<SwNode const *>(pSttNd) ) | |||
531 | { | |||
532 | pFormat = pFrameFormat; | |||
533 | break; | |||
534 | } | |||
535 | } | |||
536 | ||||
537 | if( pFormat ) | |||
538 | { | |||
539 | const SwFormatAnchor* pAnchor = &pFormat->GetAnchor(); | |||
540 | if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) && | |||
541 | pAnchor->GetContentAnchor() ) | |||
542 | { | |||
543 | pNd = &pAnchor->GetContentAnchor()->nNode.GetNode(); | |||
544 | const SwNode* pFlyNd = pNd->FindFlyStartNode(); | |||
545 | while( pFlyNd ) | |||
546 | { | |||
547 | // Get up through the Anchor | |||
548 | size_t n; | |||
549 | for( n = 0; n < rFormats.size(); ++n ) | |||
550 | { | |||
551 | const SwFrameFormat* pFrameFormat = rFormats[ n ]; | |||
552 | const SwNodeIndex* pIdx = pFrameFormat->GetContent(). | |||
553 | GetContentIdx(); | |||
554 | if( pIdx && pFlyNd == &pIdx->GetNode() ) | |||
555 | { | |||
556 | if( pFormat == pFrameFormat ) | |||
557 | { | |||
558 | pNd = pFlyNd; | |||
559 | pFlyNd = nullptr; | |||
560 | break; | |||
561 | } | |||
562 | pAnchor = &pFrameFormat->GetAnchor(); | |||
563 | if ((RndStdIds::FLY_AT_PAGE == pAnchor->GetAnchorId()) || | |||
564 | !pAnchor->GetContentAnchor() ) | |||
565 | { | |||
566 | pFlyNd = nullptr; | |||
567 | break; | |||
568 | } | |||
569 | ||||
570 | pFlyNd = pAnchor->GetContentAnchor()->nNode. | |||
571 | GetNode().FindFlyStartNode(); | |||
572 | break; | |||
573 | } | |||
574 | } | |||
575 | if( n >= rFormats.size() ) | |||
576 | { | |||
577 | OSL_ENSURE( false, "FlySection, but no Format found" )do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "577" ": "), "%s", "FlySection, but no Format found"); } } while (false); | |||
578 | return nullptr; | |||
579 | } | |||
580 | } | |||
581 | } | |||
582 | } | |||
583 | // pNd should now contain the correct Anchor or it's still this | |||
584 | } | |||
585 | ||||
586 | if( pNd->GetIndex() < GetNodes().GetEndOfExtras().GetIndex() ) | |||
587 | { | |||
588 | if( pNd->GetIndex() > GetNodes().GetEndOfAutotext().GetIndex() ) | |||
589 | { | |||
590 | pPgDesc = &rDoc.GetPageDesc( 0 ); | |||
591 | pNd = nullptr; | |||
592 | } | |||
593 | else | |||
594 | { | |||
595 | // Find the Body text node | |||
596 | if( nullptr != ( pSttNd = pNd->FindHeaderStartNode() ) || | |||
597 | nullptr != ( pSttNd = pNd->FindFooterStartNode() )) | |||
598 | { | |||
599 | // Then find this StartNode in the PageDescs | |||
600 | sal_uInt16 nId; | |||
601 | UseOnPage eAskUse; | |||
602 | if( SwHeaderStartNode == pSttNd->GetStartNodeType()) | |||
603 | { | |||
604 | nId = RES_HEADER; | |||
605 | eAskUse = UseOnPage::HeaderShare; | |||
606 | } | |||
607 | else | |||
608 | { | |||
609 | nId = RES_FOOTER; | |||
610 | eAskUse = UseOnPage::FooterShare; | |||
611 | } | |||
612 | ||||
613 | for( size_t n = rDoc.GetPageDescCnt(); n && !pPgDesc; ) | |||
614 | { | |||
615 | const SwPageDesc& rPgDsc = rDoc.GetPageDesc( --n ); | |||
616 | const SwFrameFormat* pFormat = &rPgDsc.GetMaster(); | |||
617 | int nStt = 0, nLast = 1; | |||
618 | if( !( eAskUse & rPgDsc.ReadUseOn() )) ++nLast; | |||
619 | ||||
620 | for( ; nStt < nLast; ++nStt, pFormat = &rPgDsc.GetLeft() ) | |||
621 | { | |||
622 | const SwFrameFormat * pHdFtFormat = nId == RES_HEADER | |||
623 | ? static_cast<SwFormatHeader const &>( | |||
624 | pFormat->GetFormatAttr(nId)).GetHeaderFormat() | |||
625 | : static_cast<SwFormatFooter const &>( | |||
626 | pFormat->GetFormatAttr(nId)).GetFooterFormat(); | |||
627 | if( pHdFtFormat ) | |||
628 | { | |||
629 | const SwFormatContent& rContent = pHdFtFormat->GetContent(); | |||
630 | if( rContent.GetContentIdx() && | |||
631 | &rContent.GetContentIdx()->GetNode() == | |||
632 | static_cast<SwNode const *>(pSttNd) ) | |||
633 | { | |||
634 | pPgDesc = &rPgDsc; | |||
635 | break; | |||
636 | } | |||
637 | } | |||
638 | } | |||
639 | } | |||
640 | ||||
641 | if( !pPgDesc ) | |||
642 | pPgDesc = &rDoc.GetPageDesc( 0 ); | |||
643 | pNd = nullptr; | |||
644 | } | |||
645 | else if( nullptr != ( pSttNd = pNd->FindFootnoteStartNode() )) | |||
646 | { | |||
647 | // the Anchor can only be in the Body text | |||
648 | const SwTextFootnote* pTextFootnote; | |||
649 | const SwFootnoteIdxs& rFootnoteArr = rDoc.GetFootnoteIdxs(); | |||
650 | for( size_t n = 0; n < rFootnoteArr.size(); ++n ) | |||
651 | if( nullptr != ( pTextFootnote = rFootnoteArr[ n ])->GetStartNode() && | |||
652 | static_cast<SwNode const *>(pSttNd) == | |||
653 | &pTextFootnote->GetStartNode()->GetNode() ) | |||
654 | { | |||
655 | pNd = &pTextFootnote->GetTextNode(); | |||
656 | break; | |||
657 | } | |||
658 | } | |||
659 | else | |||
660 | { | |||
661 | // Can only be a page-bound Fly (or something newer). | |||
662 | // we can only return the standard here | |||
663 | OSL_ENSURE( pNd->FindFlyStartNode(),do { if (true && (!(pNd->FindFlyStartNode()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "664" ": "), "%s", "Where is this Node?"); } } while (false ) | |||
664 | "Where is this Node?" )do { if (true && (!(pNd->FindFlyStartNode()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "664" ": "), "%s", "Where is this Node?"); } } while (false ); | |||
665 | ||||
666 | pPgDesc = &rDoc.GetPageDesc( 0 ); | |||
667 | pNd = nullptr; | |||
668 | } | |||
669 | } | |||
670 | } | |||
671 | ||||
672 | if( pNd ) | |||
673 | { | |||
674 | SwFindNearestNode aInfo( *pNd ); | |||
675 | // Over all Nodes of all PageDescs | |||
676 | for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(RES_PAGEDESC)) | |||
677 | { | |||
678 | auto pPageDescItem = dynamic_cast<const SwFormatPageDesc*>(pItem); | |||
679 | if( pPageDescItem && pPageDescItem->GetDefinedIn() ) | |||
680 | { | |||
681 | const SwModify* pMod = pPageDescItem->GetDefinedIn(); | |||
682 | if( auto pContentNode = dynamic_cast<const SwContentNode*>( pMod) ) | |||
683 | aInfo.CheckNode( *pContentNode ); | |||
684 | else if( auto pFormat = dynamic_cast<const SwFormat*>( pMod) ) | |||
685 | pFormat->GetInfo( aInfo ); | |||
686 | } | |||
687 | } | |||
688 | ||||
689 | pNd = aInfo.GetFoundNode(); | |||
690 | if( nullptr != pNd ) | |||
691 | { | |||
692 | if( pNd->IsContentNode() ) | |||
693 | pPgDesc = static_cast<const SwFormatPageDesc&>(pNd->GetContentNode()-> | |||
694 | GetAttr( RES_PAGEDESC )).GetPageDesc(); | |||
695 | else if( pNd->IsTableNode() ) | |||
696 | pPgDesc = pNd->GetTableNode()->GetTable(). | |||
697 | GetFrameFormat()->GetPageDesc().GetPageDesc(); | |||
698 | else if( pNd->IsSectionNode() ) | |||
699 | pPgDesc = pNd->GetSectionNode()->GetSection(). | |||
700 | GetFormat()->GetPageDesc().GetPageDesc(); | |||
701 | if ( pPgDescNdIdx ) | |||
702 | { | |||
703 | *pPgDescNdIdx = pNd->GetIndex(); | |||
704 | } | |||
705 | } | |||
706 | if( !pPgDesc ) | |||
707 | pPgDesc = &rDoc.GetPageDesc( 0 ); | |||
708 | } | |||
709 | } | |||
710 | return pPgDesc; | |||
711 | } | |||
712 | ||||
713 | /// If the node is located in a Fly, we return it formatted accordingly | |||
714 | SwFrameFormat* SwNode::GetFlyFormat() const | |||
715 | { | |||
716 | SwFrameFormat* pRet = nullptr; | |||
717 | const SwNode* pSttNd = FindFlyStartNode(); | |||
718 | if( pSttNd ) | |||
719 | { | |||
720 | if( IsContentNode() ) | |||
721 | { | |||
722 | SwContentFrame* pFrame = SwIterator<SwContentFrame, SwContentNode, sw::IteratorMode::UnwrapMulti>(*static_cast<const SwContentNode*>(this)).First(); | |||
723 | if( pFrame ) | |||
724 | pRet = pFrame->FindFlyFrame()->GetFormat(); | |||
725 | } | |||
726 | if( !pRet ) | |||
727 | { | |||
728 | // The hard way through the Doc is our last way out | |||
729 | const SwFrameFormats& rFrameFormatTable = *GetDoc().GetSpzFrameFormats(); | |||
730 | for( size_t n = 0; n < rFrameFormatTable.size(); ++n ) | |||
731 | { | |||
732 | SwFrameFormat* pFormat = rFrameFormatTable[n]; | |||
733 | // Only Writer fly frames can contain Writer nodes. | |||
734 | if (pFormat->Which() != RES_FLYFRMFMT) | |||
735 | continue; | |||
736 | const SwFormatContent& rContent = pFormat->GetContent(); | |||
737 | if( rContent.GetContentIdx() && | |||
738 | &rContent.GetContentIdx()->GetNode() == pSttNd ) | |||
739 | { | |||
740 | pRet = pFormat; | |||
741 | break; | |||
742 | } | |||
743 | } | |||
744 | } | |||
745 | } | |||
746 | return pRet; | |||
747 | } | |||
748 | ||||
749 | SwTableBox* SwNode::GetTableBox() const | |||
750 | { | |||
751 | SwTableBox* pBox = nullptr; | |||
752 | const SwNode* pSttNd = FindTableBoxStartNode(); | |||
753 | if( pSttNd ) | |||
754 | pBox = const_cast<SwTableBox*>(pSttNd->FindTableNode()->GetTable().GetTableBox( | |||
755 | pSttNd->GetIndex() )); | |||
756 | return pBox; | |||
757 | } | |||
758 | ||||
759 | SwStartNode* SwNode::FindSttNodeByType( SwStartNodeType eTyp ) | |||
760 | { | |||
761 | SwStartNode* pTmp = IsStartNode() ? static_cast<SwStartNode*>(this) : m_pStartOfSection; | |||
762 | ||||
763 | while( eTyp != pTmp->GetStartNodeType() && pTmp->GetIndex() ) | |||
764 | pTmp = pTmp->m_pStartOfSection; | |||
765 | return eTyp == pTmp->GetStartNodeType() ? pTmp : nullptr; | |||
766 | } | |||
767 | ||||
768 | const SwTextNode* SwNode::FindOutlineNodeOfLevel(sal_uInt8 const nLvl, | |||
769 | SwRootFrame const*const pLayout) const | |||
770 | { | |||
771 | const SwTextNode* pRet = nullptr; | |||
| ||||
772 | const SwOutlineNodes& rONds = GetNodes().GetOutLineNds(); | |||
773 | if( MAXLEVEL > nLvl && !rONds.empty() ) | |||
774 | { | |||
775 | SwOutlineNodes::size_type nPos; | |||
776 | SwNode* pNd = const_cast<SwNode*>(this); | |||
777 | bool bCheckFirst = false; | |||
778 | if( !rONds.Seek_Entry( pNd, &nPos )) | |||
779 | { | |||
780 | if (nPos == 0) | |||
781 | bCheckFirst = true; | |||
782 | } | |||
783 | else | |||
784 | { | |||
785 | ++nPos; | |||
786 | } | |||
787 | ||||
788 | if( bCheckFirst
| |||
789 | { | |||
790 | // The first OutlineNode comes after the one asking. | |||
791 | // Test if both are on the same page. | |||
792 | // If not it's invalid. | |||
793 | for (nPos = 0; nPos < rONds.size(); ++nPos) | |||
794 | { | |||
795 | pRet = rONds[nPos]->GetTextNode(); | |||
796 | if (!pLayout || sw::IsParaPropsNode(*pLayout, *pRet)) | |||
797 | { | |||
798 | break; | |||
799 | } | |||
800 | } | |||
801 | if (nPos == rONds.size()) | |||
802 | { | |||
803 | return nullptr; | |||
804 | } | |||
805 | ||||
806 | const SwContentNode* pCNd = GetContentNode(); | |||
807 | ||||
808 | Point aPt( 0, 0 ); | |||
809 | std::pair<Point, bool> const tmp(aPt, false); | |||
810 | const SwFrame* pFrame = pRet->getLayoutFrame(pRet->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp), | |||
| ||||
811 | * pMyFrame = pCNd ? pCNd->getLayoutFrame(pCNd->GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), nullptr, &tmp) : nullptr; | |||
812 | const SwPageFrame* pPgFrame = pFrame ? pFrame->FindPageFrame() : nullptr; | |||
813 | if( pPgFrame && pMyFrame && | |||
814 | pPgFrame->getFrameArea().Top() > pMyFrame->getFrameArea().Top() ) | |||
815 | { | |||
816 | // The one asking precedes the Page, thus its invalid | |||
817 | pRet = nullptr; | |||
818 | } | |||
819 | } | |||
820 | else | |||
821 | { | |||
822 | for ( ; 0 < nPos; --nPos) | |||
823 | { | |||
824 | SwTextNode const*const pNode = rONds[nPos - 1]->GetTextNode(); | |||
825 | if ((nPos == 1 /*as before*/ || pNode->GetAttrOutlineLevel() - 1 <= nLvl) | |||
826 | && (!pLayout || sw::IsParaPropsNode(*pLayout, *pNode))) | |||
827 | { | |||
828 | pRet = pNode; | |||
829 | break; | |||
830 | } | |||
831 | } | |||
832 | } | |||
833 | } | |||
834 | return pRet; | |||
835 | } | |||
836 | ||||
837 | static bool IsValidNextPrevNd( const SwNode& rNd ) | |||
838 | { | |||
839 | return SwNodeType::Table == rNd.GetNodeType() || | |||
840 | ( SwNodeType::ContentMask & rNd.GetNodeType() ) || | |||
841 | ( SwNodeType::End == rNd.GetNodeType() && rNd.StartOfSectionNode() && | |||
842 | SwNodeType::Table == rNd.StartOfSectionNode()->GetNodeType() ); | |||
843 | } | |||
844 | ||||
845 | sal_uInt8 SwNode::HasPrevNextLayNode() const | |||
846 | { | |||
847 | // assumption: <this> node is a node inside the document nodes array section. | |||
848 | ||||
849 | sal_uInt8 nRet = 0; | |||
850 | if( IsValidNextPrevNd( *this )) | |||
851 | { | |||
852 | SwNodeIndex aIdx( *this, -1 ); | |||
853 | // #i77805# - skip section start and end nodes | |||
854 | while ( aIdx.GetNode().IsSectionNode() || | |||
855 | ( aIdx.GetNode().IsEndNode() && | |||
856 | aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) ) | |||
857 | { | |||
858 | --aIdx; | |||
859 | } | |||
860 | if( IsValidNextPrevNd( aIdx.GetNode() )) | |||
861 | nRet |= ND_HAS_PREV_LAYNODE; | |||
862 | // #i77805# - skip section start and end nodes | |||
863 | aIdx.Assign(*this, +1); | |||
864 | while ( aIdx.GetNode().IsSectionNode() || | |||
865 | ( aIdx.GetNode().IsEndNode() && | |||
866 | aIdx.GetNode().StartOfSectionNode()->IsSectionNode() ) ) | |||
867 | { | |||
868 | ++aIdx; | |||
869 | } | |||
870 | if( IsValidNextPrevNd( aIdx.GetNode() )) | |||
871 | nRet |= ND_HAS_NEXT_LAYNODE; | |||
872 | } | |||
873 | return nRet; | |||
874 | } | |||
875 | ||||
876 | void SwNode::dumpAsXml(xmlTextWriterPtr pWriter) const | |||
877 | { | |||
878 | const char* pName = "???"; | |||
879 | switch (GetNodeType()) | |||
880 | { | |||
881 | case SwNodeType::End: | |||
882 | pName = "end"; | |||
883 | break; | |||
884 | case SwNodeType::Start: | |||
885 | case SwNodeType::Text: | |||
886 | case SwNodeType::Ole: | |||
887 | abort(); // overridden | |||
888 | case SwNodeType::Table: | |||
889 | pName = "table"; | |||
890 | break; | |||
891 | case SwNodeType::Grf: | |||
892 | pName = "grf"; | |||
893 | break; | |||
894 | default: break; | |||
895 | } | |||
896 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)(pName)); | |||
897 | ||||
898 | xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST(xmlChar *)("ptr"), "%p", this); | |||
899 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("type"), BAD_CAST(xmlChar *)(OString::number(static_cast<sal_uInt8>(GetNodeType())).getStr())); | |||
900 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("index"), BAD_CAST(xmlChar *)(OString::number(GetIndex()).getStr())); | |||
901 | ||||
902 | switch (GetNodeType()) | |||
903 | { | |||
904 | case SwNodeType::Grf: | |||
905 | { | |||
906 | auto pNoTextNode = static_cast<const SwNoTextNode*>(this); | |||
907 | const tools::PolyPolygon* pContour = pNoTextNode->HasContour(); | |||
908 | if (pContour) | |||
909 | { | |||
910 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("pContour")); | |||
911 | for (sal_uInt16 i = 0; i < pContour->Count(); ++i) | |||
912 | { | |||
913 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("polygon")); | |||
914 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("index"), | |||
915 | BAD_CAST(xmlChar *)(OString::number(i).getStr())); | |||
916 | const tools::Polygon& rPolygon = pContour->GetObject(i); | |||
917 | for (sal_uInt16 j = 0; j < rPolygon.GetSize(); ++j) | |||
918 | { | |||
919 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("point")); | |||
920 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("index"), | |||
921 | BAD_CAST(xmlChar *)(OString::number(j).getStr())); | |||
922 | const Point& rPoint = rPolygon.GetPoint(j); | |||
923 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("x"), | |||
924 | BAD_CAST(xmlChar *)(OString::number(rPoint.X()).getStr())); | |||
925 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("y"), | |||
926 | BAD_CAST(xmlChar *)(OString::number(rPoint.Y()).getStr())); | |||
927 | xmlTextWriterEndElement(pWriter); | |||
928 | } | |||
929 | xmlTextWriterEndElement(pWriter); | |||
930 | } | |||
931 | xmlTextWriterEndElement(pWriter); | |||
932 | } | |||
933 | } | |||
934 | break; | |||
935 | default: | |||
936 | break; | |||
937 | } | |||
938 | ||||
939 | xmlTextWriterEndElement(pWriter); | |||
940 | if (GetNodeType() == SwNodeType::End) | |||
941 | xmlTextWriterEndElement(pWriter); // end start node | |||
942 | } | |||
943 | ||||
944 | SwStartNode::SwStartNode( const SwNodeIndex &rWhere, const SwNodeType nNdType, | |||
945 | SwStartNodeType eSttNd ) | |||
946 | : SwNode( rWhere, nNdType ), m_eStartNodeType( eSttNd ) | |||
947 | { | |||
948 | if( !rWhere.GetIndex() ) | |||
949 | { | |||
950 | SwNodes& rNodes = const_cast<SwNodes&> (rWhere.GetNodes()); | |||
951 | rNodes.InsertNode( this, rWhere ); | |||
952 | m_pStartOfSection = this; | |||
953 | } | |||
954 | // Just do this temporarily until the EndNode is inserted | |||
955 | m_pEndOfSection = reinterpret_cast<SwEndNode*>(this); | |||
956 | } | |||
957 | ||||
958 | SwStartNode::SwStartNode( SwNodes& rNodes, sal_uLong nPos ) | |||
959 | : SwNode( rNodes, nPos, SwNodeType::Start ), m_eStartNodeType( SwNormalStartNode ) | |||
960 | { | |||
961 | if( !nPos ) | |||
962 | { | |||
963 | rNodes.InsertNode( this, nPos ); | |||
964 | m_pStartOfSection = this; | |||
965 | } | |||
966 | // Just do this temporarily until the EndNode is inserted | |||
967 | m_pEndOfSection = reinterpret_cast<SwEndNode*>(this); | |||
968 | } | |||
969 | ||||
970 | void SwStartNode::CheckSectionCondColl() const | |||
971 | { | |||
972 | //FEATURE::CONDCOLL | |||
973 | SwNodeIndex aIdx( *this ); | |||
974 | sal_uLong nEndIdx = EndOfSectionIndex(); | |||
975 | const SwNodes& rNds = GetNodes(); | |||
976 | SwContentNode* pCNd; | |||
977 | while( nullptr != ( pCNd = rNds.GoNext( &aIdx )) && pCNd->GetIndex() < nEndIdx ) | |||
978 | pCNd->ChkCondColl(); | |||
979 | //FEATURE::CONDCOLL | |||
980 | } | |||
981 | ||||
982 | void SwStartNode::dumpAsXml(xmlTextWriterPtr pWriter) const | |||
983 | { | |||
984 | const char* pName = "???"; | |||
985 | switch (GetNodeType()) | |||
986 | { | |||
987 | case SwNodeType::Table: | |||
988 | pName = "table"; | |||
989 | break; | |||
990 | case SwNodeType::Section: | |||
991 | pName = "section"; | |||
992 | break; | |||
993 | default: | |||
994 | switch(GetStartNodeType()) | |||
995 | { | |||
996 | case SwNormalStartNode: | |||
997 | pName = "start"; | |||
998 | break; | |||
999 | case SwTableBoxStartNode: | |||
1000 | pName = "tablebox"; | |||
1001 | break; | |||
1002 | case SwFlyStartNode: | |||
1003 | pName = "fly"; | |||
1004 | break; | |||
1005 | case SwFootnoteStartNode: | |||
1006 | pName = "footnote"; | |||
1007 | break; | |||
1008 | case SwHeaderStartNode: | |||
1009 | pName = "header"; | |||
1010 | break; | |||
1011 | case SwFooterStartNode: | |||
1012 | pName = "footer"; | |||
1013 | break; | |||
1014 | } | |||
1015 | break; | |||
1016 | } | |||
1017 | ||||
1018 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)(pName)); | |||
1019 | xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST(xmlChar *)("ptr"), "%p", this); | |||
1020 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("type"), BAD_CAST(xmlChar *)(OString::number(static_cast<sal_uInt8>(GetNodeType())).getStr())); | |||
1021 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("index"), BAD_CAST(xmlChar *)(OString::number(GetIndex()).getStr())); | |||
1022 | ||||
1023 | if (IsTableNode()) | |||
1024 | { | |||
1025 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("attrset")); | |||
1026 | GetTableNode()->GetTable().GetFrameFormat()->GetAttrSet().dumpAsXml(pWriter); | |||
1027 | xmlTextWriterEndElement(pWriter); | |||
1028 | } | |||
1029 | else if (GetStartNodeType() == SwTableBoxStartNode) | |||
1030 | { | |||
1031 | if (SwTableBox* pBox = GetTableBox()) | |||
1032 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("rowspan"), BAD_CAST(xmlChar *)(OString::number(pBox->getRowSpan()).getStr())); | |||
1033 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("attrset")); | |||
1034 | if (SwTableBox* pBox = GetTableBox()) | |||
1035 | pBox->GetFrameFormat()->GetAttrSet().dumpAsXml(pWriter); | |||
1036 | xmlTextWriterEndElement(pWriter); | |||
1037 | } | |||
1038 | ||||
1039 | // xmlTextWriterEndElement(pWriter); - it is a start node, so don't end, will make xml better nested | |||
1040 | } | |||
1041 | ||||
1042 | ||||
1043 | /** Insert a node into the array | |||
1044 | * | |||
1045 | * The StartOfSection pointer is set to the given node. | |||
1046 | * | |||
1047 | * The EndOfSection pointer of the corresponding start node is set to this node. | |||
1048 | * | |||
1049 | * @param rWhere position where the node shoul be inserted | |||
1050 | * @param rSttNd the start note of the section | |||
1051 | */ | |||
1052 | ||||
1053 | SwEndNode::SwEndNode( const SwNodeIndex &rWhere, SwStartNode& rSttNd ) | |||
1054 | : SwNode( rWhere, SwNodeType::End ) | |||
1055 | { | |||
1056 | m_pStartOfSection = &rSttNd; | |||
1057 | m_pStartOfSection->m_pEndOfSection = this; | |||
1058 | } | |||
1059 | ||||
1060 | SwEndNode::SwEndNode( SwNodes& rNds, sal_uLong nPos, SwStartNode& rSttNd ) | |||
1061 | : SwNode( rNds, nPos, SwNodeType::End ) | |||
1062 | { | |||
1063 | m_pStartOfSection = &rSttNd; | |||
1064 | m_pStartOfSection->m_pEndOfSection = this; | |||
1065 | } | |||
1066 | ||||
1067 | SwContentNode::SwContentNode( const SwNodeIndex &rWhere, const SwNodeType nNdType, | |||
1068 | SwFormatColl *pColl ) | |||
1069 | : SwNode( rWhere, nNdType ) | |||
1070 | , m_aCondCollListener( *this ) | |||
1071 | , m_pCondColl( nullptr ) | |||
1072 | , mbSetModifyAtAttr( false ) | |||
1073 | { | |||
1074 | if(pColl) | |||
1075 | pColl->Add(this); | |||
1076 | } | |||
1077 | ||||
1078 | SwContentNode::~SwContentNode() | |||
1079 | { | |||
1080 | // The base class SwClient of SwFrame excludes itself from the dependency list! | |||
1081 | // Thus, we need to delete all Frames in the dependency list. | |||
1082 | if (!IsTextNode()) // see ~SwTextNode | |||
1083 | { | |||
1084 | DelFrames(nullptr); | |||
1085 | } | |||
1086 | ||||
1087 | m_aCondCollListener.EndListeningAll(); | |||
1088 | m_pCondColl = nullptr; | |||
1089 | ||||
1090 | if ( mpAttrSet && mbSetModifyAtAttr ) | |||
1091 | const_cast<SwAttrSet*>(static_cast<const SwAttrSet*>(mpAttrSet.get()))->SetModifyAtAttr( nullptr ); | |||
1092 | } | |||
1093 | ||||
1094 | void SwContentNode::SwClientNotify( const SwModify&, const SfxHint& rHint) | |||
1095 | { | |||
1096 | if (auto pLegacyHint = dynamic_cast<const sw::LegacyModifyHint*>(&rHint)) | |||
1097 | { | |||
1098 | const sal_uInt16 nWhich = pLegacyHint->m_pOld | |||
1099 | ? pLegacyHint->m_pOld->Which() | |||
1100 | : pLegacyHint->m_pNew | |||
1101 | ? pLegacyHint->m_pNew->Which() | |||
1102 | : 0 ; | |||
1103 | ||||
1104 | bool bSetParent = false; | |||
1105 | bool bCalcHidden = false; | |||
1106 | SwFormatColl* pFormatColl = nullptr; | |||
1107 | switch(nWhich) | |||
1108 | { | |||
1109 | case RES_OBJECTDYING: | |||
1110 | { | |||
1111 | SwFormat* pFormat = pLegacyHint->m_pNew | |||
1112 | ? static_cast<SwFormat*>(static_cast<const SwPtrMsgPoolItem*>(pLegacyHint->m_pNew)->pObject) | |||
1113 | : nullptr; | |||
1114 | // Do not mangle pointers if it is the upper-most format! | |||
1115 | if(pFormat && GetRegisteredIn() == pFormat) | |||
1116 | { | |||
1117 | if(pFormat->GetRegisteredIn()) | |||
1118 | { | |||
1119 | // If Parent, register anew in the new Parent | |||
1120 | pFormat->GetRegisteredIn()->Add(this); | |||
1121 | pFormatColl = GetFormatColl(); | |||
1122 | } | |||
1123 | else | |||
1124 | EndListeningAll(); | |||
1125 | bSetParent = true; | |||
1126 | } | |||
1127 | } | |||
1128 | break; | |||
1129 | ||||
1130 | case RES_FMT_CHG: | |||
1131 | // If the Format parent was switched, register the Attrset at the new one | |||
1132 | // Skip own Modify! | |||
1133 | if(GetpSwAttrSet() | |||
1134 | && pLegacyHint->m_pNew | |||
1135 | && static_cast<const SwFormatChg*>(pLegacyHint->m_pNew)->pChangedFormat == GetRegisteredIn()) | |||
1136 | { | |||
1137 | pFormatColl = GetFormatColl(); | |||
1138 | bSetParent = true; | |||
1139 | } | |||
1140 | break; | |||
1141 | ||||
1142 | case RES_CONDCOLL_CONDCHG: | |||
1143 | if(pLegacyHint->m_pNew | |||
1144 | && static_cast<const SwCondCollCondChg*>(pLegacyHint->m_pNew)->pChangedFormat == GetRegisteredIn() | |||
1145 | && &GetNodes() == &GetDoc().GetNodes() ) | |||
1146 | ChkCondColl(); | |||
1147 | return; // Do not pass through to the base class/Frames | |||
1148 | ||||
1149 | case RES_ATTRSET_CHG: | |||
1150 | if (GetNodes().IsDocNodes() | |||
1151 | && IsTextNode() | |||
1152 | && pLegacyHint->m_pOld | |||
1153 | && SfxItemState::SET == static_cast<const SwAttrSetChg*>(pLegacyHint->m_pOld)->GetChgSet()->GetItemState(RES_CHRATR_HIDDEN, false)) | |||
1154 | bCalcHidden = true; | |||
1155 | break; | |||
1156 | ||||
1157 | case RES_UPDATE_ATTR: | |||
1158 | if (GetNodes().IsDocNodes() | |||
1159 | && IsTextNode() | |||
1160 | && pLegacyHint->m_pNew | |||
1161 | && RES_ATTRSET_CHG == static_cast<const SwUpdateAttr*>(pLegacyHint->m_pNew)->getWhichAttr()) | |||
1162 | bCalcHidden = true; | |||
1163 | break; | |||
1164 | } | |||
1165 | if(bSetParent && GetpSwAttrSet()) | |||
1166 | AttrSetHandleHelper::SetParent(mpAttrSet, *this, pFormatColl, pFormatColl); | |||
1167 | if(bCalcHidden) | |||
1168 | static_cast<SwTextNode*>(this)->SetCalcHiddenCharFlags(); | |||
1169 | NotifyClients(pLegacyHint->m_pOld, pLegacyHint->m_pNew); | |||
1170 | } | |||
1171 | else if (auto pModifyChangedHint = dynamic_cast<const sw::ModifyChangedHint*>(&rHint)) | |||
1172 | { | |||
1173 | m_pCondColl = const_cast<SwFormatColl*>(static_cast<const SwFormatColl*>(pModifyChangedHint->m_pNew)); | |||
1174 | } | |||
1175 | } | |||
1176 | ||||
1177 | bool SwContentNode::InvalidateNumRule() | |||
1178 | { | |||
1179 | SwNumRule* pRule = nullptr; | |||
1180 | const SfxPoolItem* pItem; | |||
1181 | if( GetNodes().IsDocNodes() && | |||
1182 | nullptr != ( pItem = GetNoCondAttr( RES_PARATR_NUMRULE, true )) && | |||
1183 | !static_cast<const SwNumRuleItem*>(pItem)->GetValue().isEmpty() && | |||
1184 | nullptr != (pRule = GetDoc().FindNumRulePtr( | |||
1185 | static_cast<const SwNumRuleItem*>(pItem)->GetValue() ) ) ) | |||
1186 | { | |||
1187 | pRule->SetInvalidRule( true ); | |||
1188 | } | |||
1189 | return nullptr != pRule; | |||
1190 | } | |||
1191 | ||||
1192 | SwContentFrame *SwContentNode::getLayoutFrame( const SwRootFrame* _pRoot, | |||
1193 | const SwPosition *const pPos, | |||
1194 | std::pair<Point, bool> const*const pViewPosAndCalcFrame) const | |||
1195 | { | |||
1196 | return static_cast<SwContentFrame*>( ::GetFrameOfModify( _pRoot, *this, FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt), | |||
1197 | pPos, pViewPosAndCalcFrame)); | |||
1198 | } | |||
1199 | ||||
1200 | SwRect SwContentNode::FindLayoutRect( const bool bPrtArea, const Point* pPoint ) const | |||
1201 | { | |||
1202 | SwRect aRet; | |||
1203 | std::pair<Point, bool> tmp; | |||
1204 | if (pPoint) | |||
1205 | { | |||
1206 | tmp.first = *pPoint; | |||
1207 | tmp.second = false; | |||
1208 | } | |||
1209 | SwContentFrame* pFrame = static_cast<SwContentFrame*>( ::GetFrameOfModify( nullptr, *this, | |||
1210 | FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt), nullptr, pPoint ? &tmp : nullptr) ); | |||
1211 | if( pFrame ) | |||
1212 | aRet = bPrtArea ? pFrame->getFramePrintArea() : pFrame->getFrameArea(); | |||
1213 | return aRet; | |||
1214 | } | |||
1215 | ||||
1216 | SwRect SwContentNode::FindPageFrameRect() const | |||
1217 | { | |||
1218 | SwRect aRet; | |||
1219 | SwFrame* pFrame = ::GetFrameOfModify( nullptr, *this, FRM_CNTNT(SwFrameType::Txt | SwFrameType::NoTxt) ); | |||
1220 | if( pFrame && nullptr != ( pFrame = pFrame->FindPageFrame() )) | |||
1221 | aRet = pFrame->getFrameArea(); | |||
1222 | return aRet; | |||
1223 | } | |||
1224 | ||||
1225 | sal_Int32 SwContentNode::Len() const { return 0; } | |||
1226 | ||||
1227 | SwFormatColl *SwContentNode::ChgFormatColl( SwFormatColl *pNewColl ) | |||
1228 | { | |||
1229 | OSL_ENSURE( pNewColl, "Collectionpointer is 0." )do { if (true && (!(pNewColl))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1229" ": "), "%s", "Collectionpointer is 0."); } } while (false); | |||
1230 | SwFormatColl *pOldColl = GetFormatColl(); | |||
1231 | ||||
1232 | if( pNewColl != pOldColl ) | |||
1233 | { | |||
1234 | pNewColl->Add( this ); | |||
1235 | ||||
1236 | // Set the Parent of out AutoAttributes to the new Collection | |||
1237 | if( GetpSwAttrSet() ) | |||
1238 | AttrSetHandleHelper::SetParent( mpAttrSet, *this, pNewColl, pNewColl ); | |||
1239 | ||||
1240 | SetCondFormatColl( nullptr ); | |||
1241 | ||||
1242 | if( !IsModifyLocked() ) | |||
1243 | { | |||
1244 | SwFormatChg aTmp1( pOldColl ); | |||
1245 | SwFormatChg aTmp2( pNewColl ); | |||
1246 | SwClientNotify( *this, sw::LegacyModifyHint(&aTmp1, &aTmp2) ); | |||
1247 | } | |||
1248 | } | |||
1249 | if ( IsInCache() ) | |||
1250 | { | |||
1251 | SwFrame::GetCache().Delete( this ); | |||
1252 | SetInCache( false ); | |||
1253 | } | |||
1254 | return pOldColl; | |||
1255 | } | |||
1256 | ||||
1257 | bool SwContentNode::GoNext(SwIndex * pIdx, sal_uInt16 nMode ) const | |||
1258 | { | |||
1259 | bool bRet = true; | |||
1260 | if( pIdx->GetIndex() < Len() ) | |||
1261 | { | |||
1262 | if( !IsTextNode() ) | |||
1263 | ++(*pIdx); | |||
1264 | else | |||
1265 | { | |||
1266 | const SwTextNode& rTNd = *GetTextNode(); | |||
1267 | sal_Int32 nPos = pIdx->GetIndex(); | |||
1268 | assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is())(static_cast <bool> (g_pBreakIt && g_pBreakIt-> GetBreakIter().is()) ? void (0) : __assert_fail ("g_pBreakIt && g_pBreakIt->GetBreakIter().is()" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1268, __extension__ __PRETTY_FUNCTION__)); | |||
1269 | sal_Int32 nDone = 0; | |||
1270 | sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ? | |||
1271 | CharacterIteratorMode::SKIPCELL : | |||
1272 | CharacterIteratorMode::SKIPCONTROLCHARACTER; | |||
1273 | nPos = g_pBreakIt->GetBreakIter()->nextCharacters( rTNd.GetText(), nPos, | |||
1274 | g_pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), | |||
1275 | nItrMode, 1, nDone ); | |||
1276 | ||||
1277 | // Check if nPos is inside hidden text range: | |||
1278 | if ( CRSR_SKIP_HIDDEN & nMode ) | |||
1279 | { | |||
1280 | sal_Int32 nHiddenStart; | |||
1281 | sal_Int32 nHiddenEnd; | |||
1282 | SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd ); | |||
1283 | if ( nHiddenStart != COMPLETE_STRING && nHiddenStart != nPos ) | |||
1284 | nPos = nHiddenEnd; | |||
1285 | } | |||
1286 | ||||
1287 | if( 1 == nDone ) | |||
1288 | *pIdx = nPos; | |||
1289 | else | |||
1290 | bRet = false; | |||
1291 | } | |||
1292 | } | |||
1293 | else | |||
1294 | bRet = false; | |||
1295 | return bRet; | |||
1296 | } | |||
1297 | ||||
1298 | bool SwContentNode::GoPrevious(SwIndex * pIdx, sal_uInt16 nMode ) const | |||
1299 | { | |||
1300 | bool bRet = true; | |||
1301 | if( pIdx->GetIndex() > 0 ) | |||
1302 | { | |||
1303 | if( !IsTextNode() ) | |||
1304 | --(*pIdx); | |||
1305 | else | |||
1306 | { | |||
1307 | const SwTextNode& rTNd = *GetTextNode(); | |||
1308 | sal_Int32 nPos = pIdx->GetIndex(); | |||
1309 | assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is())(static_cast <bool> (g_pBreakIt && g_pBreakIt-> GetBreakIter().is()) ? void (0) : __assert_fail ("g_pBreakIt && g_pBreakIt->GetBreakIter().is()" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1309, __extension__ __PRETTY_FUNCTION__)); | |||
1310 | sal_Int32 nDone = 0; | |||
1311 | sal_uInt16 nItrMode = ( CRSR_SKIP_CELLS & nMode ) ? | |||
1312 | CharacterIteratorMode::SKIPCELL : | |||
1313 | CharacterIteratorMode::SKIPCONTROLCHARACTER; | |||
1314 | nPos = g_pBreakIt->GetBreakIter()->previousCharacters( rTNd.GetText(), nPos, | |||
1315 | g_pBreakIt->GetLocale( rTNd.GetLang( nPos ) ), | |||
1316 | nItrMode, 1, nDone ); | |||
1317 | ||||
1318 | // Check if nPos is inside hidden text range: | |||
1319 | if ( CRSR_SKIP_HIDDEN & nMode ) | |||
1320 | { | |||
1321 | sal_Int32 nHiddenStart; | |||
1322 | sal_Int32 nHiddenEnd; | |||
1323 | SwScriptInfo::GetBoundsOfHiddenRange( rTNd, nPos, nHiddenStart, nHiddenEnd ); | |||
1324 | if ( nHiddenStart != COMPLETE_STRING ) | |||
1325 | nPos = nHiddenStart; | |||
1326 | } | |||
1327 | ||||
1328 | if( 1 == nDone ) | |||
1329 | *pIdx = nPos; | |||
1330 | else | |||
1331 | bRet = false; | |||
1332 | } | |||
1333 | } | |||
1334 | else | |||
1335 | bRet = false; | |||
1336 | return bRet; | |||
1337 | } | |||
1338 | ||||
1339 | /** | |||
1340 | * Creates all Views for the Doc for this Node. | |||
1341 | * The created ContentFrames are attached to the corresponding Layout. | |||
1342 | */ | |||
1343 | void SwContentNode::MakeFramesForAdjacentContentNode(SwContentNode& rNode) | |||
1344 | { | |||
1345 | OSL_ENSURE( &rNode != this,do { if (true && (!(&rNode != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1346" ": "), "%s", "No ContentNode or CopyNode and new Node identical." ); } } while (false) | |||
1346 | "No ContentNode or CopyNode and new Node identical." )do { if (true && (!(&rNode != this))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1346" ": "), "%s", "No ContentNode or CopyNode and new Node identical." ); } } while (false); | |||
1347 | ||||
1348 | if( !HasWriterListeners() || &rNode == this ) // Do we actually have Frames? | |||
1349 | return; | |||
1350 | ||||
1351 | SwFrame *pFrame; | |||
1352 | SwLayoutFrame *pUpper; | |||
1353 | // Create Frames for Nodes which come after the Table? | |||
1354 | OSL_ENSURE( FindTableNode() == rNode.FindTableNode(), "Table confusion" )do { if (true && (!(FindTableNode() == rNode.FindTableNode ()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1354" ": "), "%s", "Table confusion"); } } while (false ); | |||
1355 | ||||
1356 | SwNode2Layout aNode2Layout( *this, rNode.GetIndex() ); | |||
1357 | ||||
1358 | while( nullptr != (pUpper = aNode2Layout.UpperFrame( pFrame, rNode )) ) | |||
1359 | { | |||
1360 | if (pUpper->getRootFrame()->IsHideRedlines() | |||
1361 | && !rNode.IsCreateFrameWhenHidingRedlines()) | |||
1362 | { | |||
1363 | continue; | |||
1364 | } | |||
1365 | SwFrame *pNew = rNode.MakeFrame( pUpper ); | |||
1366 | pNew->Paste( pUpper, pFrame ); | |||
1367 | // #i27138# | |||
1368 | // notify accessibility paragraphs objects about changed | |||
1369 | // CONTENT_FLOWS_FROM/_TO relation. | |||
1370 | // Relation CONTENT_FLOWS_FROM for next paragraph will change | |||
1371 | // and relation CONTENT_FLOWS_TO for previous paragraph will change. | |||
1372 | if ( pNew->IsTextFrame() ) | |||
1373 | { | |||
1374 | SwViewShell* pViewShell( pNew->getRootFrame()->GetCurrShell() ); | |||
1375 | if ( pViewShell && pViewShell->GetLayout() && | |||
1376 | pViewShell->GetLayout()->IsAnyShellAccessible() ) | |||
1377 | { | |||
1378 | pViewShell->InvalidateAccessibleParaFlowRelation( | |||
1379 | dynamic_cast<SwTextFrame*>(pNew->FindNextCnt( true )), | |||
1380 | dynamic_cast<SwTextFrame*>(pNew->FindPrevCnt()) ); | |||
1381 | } | |||
1382 | } | |||
1383 | } | |||
1384 | } | |||
1385 | ||||
1386 | /** | |||
1387 | * Deletes all Views from the Doc for this Node. | |||
1388 | * The ContentFrames are removed from the corresponding Layout. | |||
1389 | */ | |||
1390 | void SwContentNode::DelFrames(SwRootFrame const*const pLayout) | |||
1391 | { | |||
1392 | if( !HasWriterListeners() ) | |||
1393 | return; | |||
1394 | ||||
1395 | SwIterator<SwContentFrame, SwContentNode, sw::IteratorMode::UnwrapMulti> aIter(*this); | |||
1396 | for( SwContentFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next() ) | |||
1397 | { | |||
1398 | if (pLayout && pLayout != pFrame->getRootFrame()) | |||
1399 | { | |||
1400 | continue; // skip it | |||
1401 | } | |||
1402 | if (pFrame->IsTextFrame()) | |||
1403 | { | |||
1404 | if (sw::MergedPara * pMerged = | |||
1405 | static_cast<SwTextFrame *>(pFrame)->GetMergedPara()) | |||
1406 | { | |||
1407 | if (this != pMerged->pFirstNode) | |||
1408 | { | |||
1409 | // SwNodes::RemoveNode iterates *backwards* - so | |||
1410 | // ensure there are no more extents pointing to this | |||
1411 | // node as SwFrame::InvalidatePage() will access them. | |||
1412 | // Note: cannot send via SwClientNotify from dtor | |||
1413 | // because that would access deleted wrong-lists | |||
1414 | sw::UpdateMergedParaForDelete(*pMerged, true, | |||
1415 | *static_cast<SwTextNode*>(this), 0, Len()); | |||
1416 | if (this == pMerged->pParaPropsNode) | |||
1417 | { | |||
1418 | // otherwise pointer should have been updated to a different node | |||
1419 | assert(this == pMerged->pLastNode)(static_cast <bool> (this == pMerged->pLastNode) ? void (0) : __assert_fail ("this == pMerged->pLastNode", "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1419, __extension__ __PRETTY_FUNCTION__)); | |||
1420 | assert(pMerged->extents.empty())(static_cast <bool> (pMerged->extents.empty()) ? void (0) : __assert_fail ("pMerged->extents.empty()", "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1420, __extension__ __PRETTY_FUNCTION__)); | |||
1421 | for (sal_uLong i = pMerged->pLastNode->GetIndex() - 1;; | |||
1422 | --i) | |||
1423 | { | |||
1424 | assert(pMerged->pFirstNode->GetIndex() <= i)(static_cast <bool> (pMerged->pFirstNode->GetIndex () <= i) ? void (0) : __assert_fail ("pMerged->pFirstNode->GetIndex() <= i" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1424, __extension__ __PRETTY_FUNCTION__)); | |||
1425 | SwNode *const pNode(GetNodes()[i]); | |||
1426 | if (pNode->IsTextNode() | |||
1427 | && pNode->GetRedlineMergeFlag() != Merge::Hidden) | |||
1428 | { | |||
1429 | pMerged->pParaPropsNode = pNode->GetTextNode(); | |||
1430 | break; | |||
1431 | } | |||
1432 | } | |||
1433 | assert(pMerged->listener.IsListeningTo(pMerged->pParaPropsNode))(static_cast <bool> (pMerged->listener.IsListeningTo (pMerged->pParaPropsNode)) ? void (0) : __assert_fail ("pMerged->listener.IsListeningTo(pMerged->pParaPropsNode)" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1433, __extension__ __PRETTY_FUNCTION__)); | |||
1434 | } | |||
1435 | assert(GetIndex() <= pMerged->pLastNode->GetIndex())(static_cast <bool> (GetIndex() <= pMerged->pLastNode ->GetIndex()) ? void (0) : __assert_fail ("GetIndex() <= pMerged->pLastNode->GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1435, __extension__ __PRETTY_FUNCTION__)); | |||
1436 | if (this == pMerged->pLastNode) | |||
1437 | { | |||
1438 | // tdf#130680 find the previous node that is a | |||
1439 | // listener of pMerged; see CheckParaRedlineMerge() | |||
1440 | for (sal_uLong i = GetIndex() - 1; | |||
1441 | this == pMerged->pLastNode; --i) | |||
1442 | { | |||
1443 | SwNode *const pNode = GetNodes()[i]; | |||
1444 | if (pNode->IsTextNode()) | |||
1445 | { | |||
1446 | pMerged->pLastNode = pNode->GetTextNode(); | |||
1447 | } | |||
1448 | else if (SwEndNode const*const pEnd = pNode->GetEndNode()) | |||
1449 | { | |||
1450 | SwStartNode const*const pStart(pEnd->StartOfSectionNode()); | |||
1451 | i = pStart->GetIndex(); // skip table or section | |||
1452 | } | |||
1453 | } | |||
1454 | assert(pMerged->pFirstNode->GetIndex() <= pMerged->pLastNode->GetIndex())(static_cast <bool> (pMerged->pFirstNode->GetIndex () <= pMerged->pLastNode->GetIndex()) ? void (0) : __assert_fail ("pMerged->pFirstNode->GetIndex() <= pMerged->pLastNode->GetIndex()" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1454, __extension__ __PRETTY_FUNCTION__)); | |||
1455 | assert(pMerged->listener.IsListeningTo(pMerged->pLastNode))(static_cast <bool> (pMerged->listener.IsListeningTo (pMerged->pLastNode)) ? void (0) : __assert_fail ("pMerged->listener.IsListeningTo(pMerged->pLastNode)" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 1455, __extension__ __PRETTY_FUNCTION__)); | |||
1456 | } | |||
1457 | // avoid re-parenting mess (ModifyChangedHint) | |||
1458 | pMerged->listener.EndListening(this); | |||
1459 | continue; // don't delete | |||
1460 | } | |||
1461 | } | |||
1462 | // #i27138# | |||
1463 | // notify accessibility paragraphs objects about changed | |||
1464 | // CONTENT_FLOWS_FROM/_TO relation. | |||
1465 | // Relation CONTENT_FLOWS_FROM for current next paragraph will change | |||
1466 | // and relation CONTENT_FLOWS_TO for current previous paragraph will change. | |||
1467 | SwViewShell* pViewShell( pFrame->getRootFrame()->GetCurrShell() ); | |||
1468 | if ( pViewShell && pViewShell->GetLayout() && | |||
1469 | pViewShell->GetLayout()->IsAnyShellAccessible() ) | |||
1470 | { | |||
1471 | pViewShell->InvalidateAccessibleParaFlowRelation( | |||
1472 | dynamic_cast<SwTextFrame*>(pFrame->FindNextCnt( true )), | |||
1473 | dynamic_cast<SwTextFrame*>(pFrame->FindPrevCnt()) ); | |||
1474 | } | |||
1475 | } | |||
1476 | ||||
1477 | if( pFrame->IsFollow() ) | |||
1478 | { | |||
1479 | SwContentFrame* pMaster = pFrame->FindMaster(); | |||
1480 | pMaster->SetFollow( pFrame->GetFollow() ); | |||
1481 | } | |||
1482 | pFrame->SetFollow( nullptr );//So it doesn't get funny ideas. | |||
1483 | //Otherwise it could be possible that a follow | |||
1484 | //gets destroyed before its master. Following | |||
1485 | //the now invalid pointer will then lead to an | |||
1486 | //illegal memory access. The chain can be | |||
1487 | //crushed here because we'll destroy all of it | |||
1488 | //anyway. | |||
1489 | ||||
1490 | if( pFrame->GetUpper() && pFrame->IsInFootnote() && !pFrame->GetIndNext() && | |||
1491 | !pFrame->GetIndPrev() ) | |||
1492 | { | |||
1493 | SwFootnoteFrame *pFootnote = pFrame->FindFootnoteFrame(); | |||
1494 | OSL_ENSURE( pFootnote, "You promised a FootnoteFrame?" )do { if (true && (!(pFootnote))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1494" ": "), "%s", "You promised a FootnoteFrame?"); } } while (false); | |||
1495 | SwContentFrame* pCFrame; | |||
1496 | if( !pFootnote->GetFollow() && !pFootnote->GetMaster() && | |||
1497 | nullptr != ( pCFrame = pFootnote->GetRefFromAttr()) && pCFrame->IsFollow() ) | |||
1498 | { | |||
1499 | OSL_ENSURE( pCFrame->IsTextFrame(), "NoTextFrame has Footnote?" )do { if (true && (!(pCFrame->IsTextFrame()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1499" ": "), "%s", "NoTextFrame has Footnote?"); } } while (false); | |||
1500 | pCFrame->FindMaster()->Prepare( PrepareHint::FootnoteInvalidationGone ); | |||
1501 | } | |||
1502 | } | |||
1503 | pFrame->Cut(); | |||
1504 | SwFrame::DestroyFrame(pFrame); | |||
1505 | } | |||
1506 | } | |||
1507 | ||||
1508 | SwContentNode *SwContentNode::JoinNext() | |||
1509 | { | |||
1510 | return this; | |||
1511 | } | |||
1512 | ||||
1513 | /// Get info from Modify | |||
1514 | bool SwContentNode::GetInfo( SfxPoolItem& rInfo ) const | |||
1515 | { | |||
1516 | switch( rInfo.Which() ) | |||
1517 | { | |||
1518 | case RES_AUTOFMT_DOCNODE: | |||
1519 | if( &GetNodes() == static_cast<SwAutoFormatGetDocNode&>(rInfo).pNodes ) | |||
1520 | { | |||
1521 | return false; | |||
1522 | } | |||
1523 | break; | |||
1524 | ||||
1525 | case RES_FINDNEARESTNODE: | |||
1526 | if( static_cast<const SwFormatPageDesc&>(GetAttr( RES_PAGEDESC )).GetPageDesc() ) | |||
1527 | static_cast<SwFindNearestNode&>(rInfo).CheckNode( *this ); | |||
1528 | return true; | |||
1529 | ||||
1530 | case RES_CONTENT_VISIBLE: | |||
1531 | { | |||
1532 | static_cast<SwPtrMsgPoolItem&>(rInfo).pObject = | |||
1533 | SwIterator<SwFrame, SwContentNode, sw::IteratorMode::UnwrapMulti>(*this).First(); | |||
1534 | } | |||
1535 | return false; | |||
1536 | } | |||
1537 | ||||
1538 | return SwModify::GetInfo( rInfo ); | |||
1539 | } | |||
1540 | ||||
1541 | /// @param rAttr the attribute to set | |||
1542 | bool SwContentNode::SetAttr(const SfxPoolItem& rAttr ) | |||
1543 | { | |||
1544 | if( !GetpSwAttrSet() ) // Have the Nodes created by the corresponding AttrSets | |||
1545 | NewAttrSet( GetDoc().GetAttrPool() ); | |||
1546 | ||||
1547 | OSL_ENSURE( GetpSwAttrSet(), "Why did't we create an AttrSet?")do { if (true && (!(GetpSwAttrSet()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1547" ": "), "%s", "Why did't we create an AttrSet?"); } } while (false); | |||
1548 | ||||
1549 | if ( IsInCache() ) | |||
1550 | { | |||
1551 | SwFrame::GetCache().Delete( this ); | |||
1552 | SetInCache( false ); | |||
1553 | } | |||
1554 | ||||
1555 | bool bRet = false; | |||
1556 | // If Modify is locked, we do not send any Modifys | |||
1557 | if( IsModifyLocked() || | |||
1558 | ( !HasWriterListeners() && RES_PARATR_NUMRULE != rAttr.Which() )) | |||
1559 | { | |||
1560 | bRet = nullptr != AttrSetHandleHelper::Put( mpAttrSet, *this, rAttr ); | |||
1561 | } | |||
1562 | else | |||
1563 | { | |||
1564 | SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), | |||
1565 | aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); | |||
1566 | bRet = AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rAttr, &aOld, &aNew ); | |||
1567 | if( bRet ) | |||
1568 | { | |||
1569 | SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); | |||
1570 | SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); | |||
1571 | ModifyNotification( &aChgOld, &aChgNew ); // Send all changed ones | |||
1572 | } | |||
1573 | } | |||
1574 | return bRet; | |||
1575 | } | |||
1576 | ||||
1577 | bool SwContentNode::SetAttr( const SfxItemSet& rSet ) | |||
1578 | { | |||
1579 | if ( IsInCache() ) | |||
1580 | { | |||
1581 | SwFrame::GetCache().Delete( this ); | |||
1582 | SetInCache( false ); | |||
1583 | } | |||
1584 | ||||
1585 | const SfxPoolItem* pFnd = nullptr; | |||
1586 | if( SfxItemState::SET == rSet.GetItemState( RES_AUTO_STYLE, false, &pFnd ) ) | |||
1587 | { | |||
1588 | OSL_ENSURE( rSet.Count() == 1, "SetAutoStyle mixed with other attributes?!" )do { if (true && (!(rSet.Count() == 1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1588" ": "), "%s", "SetAutoStyle mixed with other attributes?!" ); } } while (false); | |||
1589 | const SwFormatAutoFormat* pTmp = static_cast<const SwFormatAutoFormat*>(pFnd); | |||
1590 | ||||
1591 | // If there already is an attribute set (usually containing a numbering | |||
1592 | // item), we have to merge the attribute of the new set into the old set: | |||
1593 | bool bSetParent = true; | |||
1594 | if ( GetpSwAttrSet() ) | |||
1595 | { | |||
1596 | bSetParent = false; | |||
1597 | AttrSetHandleHelper::Put( mpAttrSet, *this, *pTmp->GetStyleHandle() ); | |||
1598 | } | |||
1599 | else | |||
1600 | { | |||
1601 | mpAttrSet = pTmp->GetStyleHandle(); | |||
1602 | } | |||
1603 | ||||
1604 | if ( bSetParent ) | |||
1605 | { | |||
1606 | // If the content node has a conditional style, we have to set the | |||
1607 | // string item containing the correct conditional style name (the | |||
1608 | // style name property has already been set during the import!) | |||
1609 | // In case we do not have a conditional style, we make use of the | |||
1610 | // fact that nobody else uses the attribute set behind the handle. | |||
1611 | // FME 2007-07-10 #i78124# If autostyle does not have a parent, | |||
1612 | // the string is empty. | |||
1613 | const SfxPoolItem* pNameItem = nullptr; | |||
1614 | if ( nullptr != GetCondFormatColl() || | |||
1615 | SfxItemState::SET != mpAttrSet->GetItemState( RES_FRMATR_STYLE_NAME, false, &pNameItem ) || | |||
1616 | static_cast<const SfxStringItem*>(pNameItem)->GetValue().isEmpty() ) | |||
1617 | AttrSetHandleHelper::SetParent( mpAttrSet, *this, &GetAnyFormatColl(), GetFormatColl() ); | |||
1618 | else | |||
1619 | const_cast<SfxItemSet*>(mpAttrSet.get())->SetParent( &GetFormatColl()->GetAttrSet() ); | |||
1620 | } | |||
1621 | ||||
1622 | return true; | |||
1623 | } | |||
1624 | ||||
1625 | if( !GetpSwAttrSet() ) // Have the AttrsSets created by the corresponding Nodes | |||
1626 | NewAttrSet( GetDoc().GetAttrPool() ); | |||
1627 | ||||
1628 | bool bRet = false; | |||
1629 | // If Modify is locked, do not send any Modifys | |||
1630 | if ( IsModifyLocked() || | |||
1631 | ( !HasWriterListeners() && | |||
1632 | SfxItemState::SET != rSet.GetItemState( RES_PARATR_NUMRULE, false ) ) ) | |||
1633 | { | |||
1634 | // Some special treatment for Attributes | |||
1635 | bRet = AttrSetHandleHelper::Put( mpAttrSet, *this, rSet ); | |||
1636 | } | |||
1637 | else | |||
1638 | { | |||
1639 | SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), | |||
1640 | aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); | |||
1641 | bRet = AttrSetHandleHelper::Put_BC( mpAttrSet, *this, rSet, &aOld, &aNew ); | |||
1642 | if( bRet ) | |||
1643 | { | |||
1644 | // Some special treatment for Attributes | |||
1645 | SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); | |||
1646 | SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); | |||
1647 | ModifyNotification( &aChgOld, &aChgNew ); // Send out all changed ones | |||
1648 | } | |||
1649 | } | |||
1650 | return bRet; | |||
1651 | } | |||
1652 | ||||
1653 | // With nWhich it takes the Hint from the Delta array | |||
1654 | bool SwContentNode::ResetAttr( sal_uInt16 nWhich1, sal_uInt16 nWhich2 ) | |||
1655 | { | |||
1656 | if( !GetpSwAttrSet() ) | |||
1657 | return false; | |||
1658 | ||||
1659 | if ( IsInCache() ) | |||
1660 | { | |||
1661 | SwFrame::GetCache().Delete( this ); | |||
1662 | SetInCache( false ); | |||
1663 | } | |||
1664 | ||||
1665 | // If Modify is locked, do not send out any Modifys | |||
1666 | if( IsModifyLocked() ) | |||
1667 | { | |||
1668 | sal_uInt16 nDel = 0; | |||
1669 | if ( !nWhich2 || nWhich2 < nWhich1 ) | |||
1670 | { | |||
1671 | std::vector<sal_uInt16> aClearWhichIds; | |||
1672 | aClearWhichIds.push_back( nWhich1 ); | |||
1673 | nDel = ClearItemsFromAttrSet( aClearWhichIds ); | |||
1674 | } | |||
1675 | else | |||
1676 | nDel = AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, nullptr, nullptr ); | |||
1677 | ||||
1678 | if( !GetpSwAttrSet()->Count() ) // Empty? Delete | |||
1679 | mpAttrSet.reset(); | |||
1680 | return 0 != nDel; | |||
1681 | } | |||
1682 | ||||
1683 | // No valid area defined? | |||
1684 | if( !nWhich2 || nWhich2 < nWhich1 ) | |||
1685 | nWhich2 = nWhich1; // Then set only this Item to 1st Id | |||
1686 | ||||
1687 | SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), | |||
1688 | aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); | |||
1689 | bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, nWhich1, nWhich2, &aOld, &aNew ); | |||
1690 | ||||
1691 | if( bRet ) | |||
1692 | { | |||
1693 | SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); | |||
1694 | SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); | |||
1695 | ModifyNotification( &aChgOld, &aChgNew ); // All changed ones are sent | |||
1696 | ||||
1697 | if( !GetpSwAttrSet()->Count() ) // Empty?, delete it | |||
1698 | mpAttrSet.reset(); | |||
1699 | } | |||
1700 | return bRet; | |||
1701 | } | |||
1702 | ||||
1703 | bool SwContentNode::ResetAttr( const std::vector<sal_uInt16>& rWhichArr ) | |||
1704 | { | |||
1705 | if( !GetpSwAttrSet() ) | |||
1706 | return false; | |||
1707 | ||||
1708 | if ( IsInCache() ) | |||
1709 | { | |||
1710 | SwFrame::GetCache().Delete( this ); | |||
1711 | SetInCache( false ); | |||
1712 | } | |||
1713 | ||||
1714 | // If Modify is locked, do not send out any Modifys | |||
1715 | sal_uInt16 nDel = 0; | |||
1716 | if( IsModifyLocked() ) | |||
1717 | { | |||
1718 | nDel = ClearItemsFromAttrSet( rWhichArr ); | |||
1719 | } | |||
1720 | else | |||
1721 | { | |||
1722 | SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), | |||
1723 | aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); | |||
1724 | ||||
1725 | for ( const auto& rWhich : rWhichArr ) | |||
1726 | if( AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, rWhich, &aOld, &aNew )) | |||
1727 | ++nDel; | |||
1728 | ||||
1729 | if( nDel ) | |||
1730 | { | |||
1731 | SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); | |||
1732 | SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); | |||
1733 | ModifyNotification( &aChgOld, &aChgNew ); // All changed ones are sent | |||
1734 | } | |||
1735 | } | |||
1736 | if( !GetpSwAttrSet()->Count() ) // Empty?, delete it | |||
1737 | mpAttrSet.reset(); | |||
1738 | return 0 != nDel ; | |||
1739 | } | |||
1740 | ||||
1741 | sal_uInt16 SwContentNode::ResetAllAttr() | |||
1742 | { | |||
1743 | if( !GetpSwAttrSet() ) | |||
1744 | return 0; | |||
1745 | ||||
1746 | if ( IsInCache() ) | |||
1747 | { | |||
1748 | SwFrame::GetCache().Delete( this ); | |||
1749 | SetInCache( false ); | |||
1750 | } | |||
1751 | ||||
1752 | // If Modify is locked, do not send out any Modifys | |||
1753 | if( IsModifyLocked() ) | |||
1754 | { | |||
1755 | std::vector<sal_uInt16> aClearWhichIds; | |||
1756 | aClearWhichIds.push_back(0); | |||
1757 | sal_uInt16 nDel = ClearItemsFromAttrSet( aClearWhichIds ); | |||
1758 | if( !GetpSwAttrSet()->Count() ) // Empty? Delete | |||
1759 | mpAttrSet.reset(); | |||
1760 | return nDel; | |||
1761 | } | |||
1762 | ||||
1763 | SwAttrSet aOld( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ), | |||
1764 | aNew( *GetpSwAttrSet()->GetPool(), GetpSwAttrSet()->GetRanges() ); | |||
1765 | bool bRet = 0 != AttrSetHandleHelper::ClearItem_BC( mpAttrSet, *this, 0, &aOld, &aNew ); | |||
1766 | ||||
1767 | if( bRet ) | |||
1768 | { | |||
1769 | SwAttrSetChg aChgOld( *GetpSwAttrSet(), aOld ); | |||
1770 | SwAttrSetChg aChgNew( *GetpSwAttrSet(), aNew ); | |||
1771 | ModifyNotification( &aChgOld, &aChgNew ); // All changed ones are sent | |||
1772 | ||||
1773 | if( !GetpSwAttrSet()->Count() ) // Empty? Delete | |||
1774 | mpAttrSet.reset(); | |||
1775 | } | |||
1776 | return aNew.Count(); | |||
1777 | } | |||
1778 | ||||
1779 | bool SwContentNode::GetAttr( SfxItemSet& rSet ) const | |||
1780 | { | |||
1781 | if( rSet.Count() ) | |||
1782 | rSet.ClearItem(); | |||
1783 | ||||
1784 | const SwAttrSet& rAttrSet = GetSwAttrSet(); | |||
1785 | return rSet.Set( rAttrSet ); | |||
1786 | } | |||
1787 | ||||
1788 | sal_uInt16 SwContentNode::ClearItemsFromAttrSet( const std::vector<sal_uInt16>& rWhichIds ) | |||
1789 | { | |||
1790 | sal_uInt16 nRet = 0; | |||
1791 | if ( rWhichIds.empty() ) | |||
1792 | return nRet; | |||
1793 | ||||
1794 | OSL_ENSURE( GetpSwAttrSet(), "no item set" )do { if (true && (!(GetpSwAttrSet()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" ":" "1794" ": "), "%s", "no item set"); } } while (false); | |||
1795 | SwAttrSet aNewAttrSet( *GetpSwAttrSet() ); | |||
1796 | for ( const auto& rWhichId : rWhichIds ) | |||
1797 | { | |||
1798 | nRet = nRet + aNewAttrSet.ClearItem( rWhichId ); | |||
1799 | } | |||
1800 | if ( nRet ) | |||
1801 | AttrSetHandleHelper::GetNewAutoStyle( mpAttrSet, *this, aNewAttrSet ); | |||
1802 | ||||
1803 | return nRet; | |||
1804 | } | |||
1805 | ||||
1806 | const SfxPoolItem* SwContentNode::GetNoCondAttr( sal_uInt16 nWhich, | |||
1807 | bool bInParents ) const | |||
1808 | { | |||
1809 | const SfxPoolItem* pFnd = nullptr; | |||
1810 | if( m_pCondColl && m_pCondColl->GetRegisteredIn() ) | |||
1811 | { | |||
1812 | if( !GetpSwAttrSet() || ( SfxItemState::SET != GetpSwAttrSet()->GetItemState( | |||
1813 | nWhich, false, &pFnd ) && bInParents )) | |||
1814 | { | |||
1815 | (void)static_cast<const SwFormat*>(GetRegisteredIn())->GetItemState( nWhich, bInParents, &pFnd ); | |||
1816 | } | |||
1817 | } | |||
1818 | // undo change of issue #i51029# | |||
1819 | // Note: <GetSwAttrSet()> returns <mpAttrSet>, if set, otherwise it returns | |||
1820 | // the attribute set of the paragraph style, which is valid for the | |||
1821 | // content node - see file <node.hxx> | |||
1822 | else | |||
1823 | { | |||
1824 | GetSwAttrSet().GetItemState( nWhich, bInParents, &pFnd ); | |||
1825 | } | |||
1826 | return pFnd; | |||
1827 | } | |||
1828 | ||||
1829 | static bool lcl_CheckMaxLength(SwNode const& rPrev, SwNode const& rNext) | |||
1830 | { | |||
1831 | if (rPrev.GetNodeType() != rNext.GetNodeType()) | |||
1832 | { | |||
1833 | return false; | |||
1834 | } | |||
1835 | if (!rPrev.IsTextNode()) | |||
1836 | { | |||
1837 | return true; | |||
1838 | } | |||
1839 | ||||
1840 | // Check if a node can contain the other (order is not significant) | |||
1841 | return rPrev.GetTextNode()->GetSpaceLeft() > rNext.GetTextNode()->Len(); | |||
1842 | } | |||
1843 | ||||
1844 | /// Can we join two Nodes? | |||
1845 | /// We can return the 2nd position in pIdx. | |||
1846 | bool SwContentNode::CanJoinNext( SwNodeIndex* pIdx ) const | |||
1847 | { | |||
1848 | const SwNodes& rNds = GetNodes(); | |||
1849 | SwNodeIndex aIdx( *this, 1 ); | |||
1850 | ||||
1851 | const SwNode* pNd = this; | |||
1852 | while( aIdx < rNds.Count()-1 && | |||
1853 | (( pNd = &aIdx.GetNode())->IsSectionNode() || | |||
1854 | ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) | |||
1855 | ++aIdx; | |||
1856 | ||||
1857 | if (rNds.Count()-1 == aIdx.GetIndex()) | |||
1858 | return false; | |||
1859 | if (!lcl_CheckMaxLength(*this, *pNd)) | |||
1860 | { | |||
1861 | return false; | |||
1862 | } | |||
1863 | if( pIdx ) | |||
1864 | *pIdx = aIdx; | |||
1865 | return true; | |||
1866 | } | |||
1867 | ||||
1868 | /// Can we join two Nodes? | |||
1869 | /// We can return the 2nd position in pIdx. | |||
1870 | bool SwContentNode::CanJoinPrev( SwNodeIndex* pIdx ) const | |||
1871 | { | |||
1872 | SwNodeIndex aIdx( *this, -1 ); | |||
1873 | ||||
1874 | const SwNode* pNd = this; | |||
1875 | while( aIdx.GetIndex() && | |||
1876 | (( pNd = &aIdx.GetNode())->IsSectionNode() || | |||
1877 | ( pNd->IsEndNode() && pNd->StartOfSectionNode()->IsSectionNode() ))) | |||
1878 | --aIdx; | |||
1879 | ||||
1880 | if (0 == aIdx.GetIndex()) | |||
1881 | return false; | |||
1882 | if (!lcl_CheckMaxLength(*pNd, *this)) | |||
1883 | { | |||
1884 | return false; | |||
1885 | } | |||
1886 | if( pIdx ) | |||
1887 | *pIdx = aIdx; | |||
1888 | return true; | |||
1889 | } | |||
1890 | ||||
1891 | void SwContentNode::SetCondFormatColl(SwFormatColl* pColl) | |||
1892 | { | |||
1893 | if( !((!pColl && m_pCondColl) || ( pColl && !m_pCondColl ) || | |||
1894 | ( pColl && pColl != m_pCondColl->GetRegisteredIn() )) ) | |||
1895 | return; | |||
1896 | ||||
1897 | SwFormatColl* pOldColl = GetCondFormatColl(); | |||
1898 | m_aCondCollListener.EndListeningAll(); | |||
1899 | if(pColl) | |||
1900 | m_aCondCollListener.StartListening(pColl); | |||
1901 | m_pCondColl = pColl; | |||
1902 | if(GetpSwAttrSet()) | |||
1903 | AttrSetHandleHelper::SetParent(mpAttrSet, *this, &GetAnyFormatColl(), GetFormatColl()); | |||
1904 | ||||
1905 | if(!IsModifyLocked()) | |||
1906 | { | |||
1907 | SwFormatChg aTmp1(pOldColl ? pOldColl : GetFormatColl()); | |||
1908 | SwFormatChg aTmp2(pColl ? pColl : GetFormatColl()); | |||
1909 | NotifyClients(&aTmp1, &aTmp2); | |||
1910 | } | |||
1911 | if(IsInCache()) | |||
1912 | { | |||
1913 | SwFrame::GetCache().Delete(this); | |||
1914 | SetInCache(false); | |||
1915 | } | |||
1916 | } | |||
1917 | ||||
1918 | bool SwContentNode::IsAnyCondition( SwCollCondition& rTmp ) const | |||
1919 | { | |||
1920 | const SwNodes& rNds = GetNodes(); | |||
1921 | { | |||
1922 | Master_CollCondition nCond = Master_CollCondition::NONE; | |||
1923 | const SwStartNode* pSttNd = StartOfSectionNode(); | |||
1924 | while( pSttNd ) | |||
1925 | { | |||
1926 | switch( pSttNd->GetNodeType() ) | |||
1927 | { | |||
1928 | case SwNodeType::Table: nCond = Master_CollCondition::PARA_IN_TABLEBODY; break; | |||
1929 | case SwNodeType::Section: nCond = Master_CollCondition::PARA_IN_SECTION; break; | |||
1930 | ||||
1931 | default: | |||
1932 | switch( pSttNd->GetStartNodeType() ) | |||
1933 | { | |||
1934 | case SwTableBoxStartNode: | |||
1935 | { | |||
1936 | nCond = Master_CollCondition::PARA_IN_TABLEBODY; | |||
1937 | const SwTableNode* pTableNd = pSttNd->FindTableNode(); | |||
1938 | const SwTableBox* pBox; | |||
1939 | if( pTableNd && nullptr != ( pBox = pTableNd->GetTable(). | |||
1940 | GetTableBox(pSttNd->GetIndex()) ) && | |||
1941 | pBox->IsInHeadline( &pTableNd->GetTable() ) ) | |||
1942 | nCond = Master_CollCondition::PARA_IN_TABLEHEAD; | |||
1943 | } | |||
1944 | break; | |||
1945 | case SwFlyStartNode: nCond = Master_CollCondition::PARA_IN_FRAME; break; | |||
1946 | case SwFootnoteStartNode: | |||
1947 | { | |||
1948 | nCond = Master_CollCondition::PARA_IN_FOOTNOTE; | |||
1949 | const SwFootnoteIdxs& rFootnoteArr = rNds.GetDoc().GetFootnoteIdxs(); | |||
1950 | const SwTextFootnote* pTextFootnote; | |||
1951 | const SwNode* pSrchNd = pSttNd; | |||
1952 | ||||
1953 | for( size_t n = 0; n < rFootnoteArr.size(); ++n ) | |||
1954 | if( nullptr != ( pTextFootnote = rFootnoteArr[ n ])->GetStartNode() && | |||
1955 | pSrchNd == &pTextFootnote->GetStartNode()->GetNode() ) | |||
1956 | { | |||
1957 | if( pTextFootnote->GetFootnote().IsEndNote() ) | |||
1958 | nCond = Master_CollCondition::PARA_IN_ENDNOTE; | |||
1959 | break; | |||
1960 | } | |||
1961 | } | |||
1962 | break; | |||
1963 | case SwHeaderStartNode: nCond = Master_CollCondition::PARA_IN_HEADER; break; | |||
1964 | case SwFooterStartNode: nCond = Master_CollCondition::PARA_IN_FOOTER; break; | |||
1965 | case SwNormalStartNode: break; | |||
1966 | } | |||
1967 | } | |||
1968 | ||||
1969 | if( nCond != Master_CollCondition::NONE ) | |||
1970 | { | |||
1971 | rTmp.SetCondition( nCond, 0 ); | |||
1972 | return true; | |||
1973 | } | |||
1974 | pSttNd = pSttNd->GetIndex() | |||
1975 | ? pSttNd->StartOfSectionNode() | |||
1976 | : nullptr; | |||
1977 | } | |||
1978 | } | |||
1979 | ||||
1980 | { | |||
1981 | SwOutlineNodes::size_type nPos; | |||
1982 | const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); | |||
1983 | if( !rOutlNds.empty() ) | |||
1984 | { | |||
1985 | if( !rOutlNds.Seek_Entry( const_cast<SwContentNode*>(this), &nPos ) && nPos ) | |||
1986 | --nPos; | |||
1987 | if( nPos < rOutlNds.size() && | |||
1988 | rOutlNds[ nPos ]->GetIndex() < GetIndex() ) | |||
1989 | { | |||
1990 | SwTextNode* pOutlNd = rOutlNds[ nPos ]->GetTextNode(); | |||
1991 | ||||
1992 | if( pOutlNd->IsOutline()) | |||
1993 | { | |||
1994 | rTmp.SetCondition( Master_CollCondition::PARA_IN_OUTLINE, pOutlNd->GetAttrOutlineLevel() - 1 ); | |||
1995 | return true; | |||
1996 | } | |||
1997 | } | |||
1998 | } | |||
1999 | } | |||
2000 | ||||
2001 | return false; | |||
2002 | } | |||
2003 | ||||
2004 | void SwContentNode::ChkCondColl() | |||
2005 | { | |||
2006 | // Check, just to be sure | |||
2007 | if( RES_CONDTXTFMTCOLL != GetFormatColl()->Which() ) | |||
2008 | return; | |||
2009 | ||||
2010 | SwCollCondition aTmp( nullptr, Master_CollCondition::NONE, 0 ); | |||
2011 | const SwCollCondition* pCColl; | |||
2012 | ||||
2013 | bool bDone = false; | |||
2014 | ||||
2015 | if( IsAnyCondition( aTmp )) | |||
2016 | { | |||
2017 | pCColl = static_cast<SwConditionTextFormatColl*>(GetFormatColl()) | |||
2018 | ->HasCondition( aTmp ); | |||
2019 | ||||
2020 | if (pCColl) | |||
2021 | { | |||
2022 | SetCondFormatColl( pCColl->GetTextFormatColl() ); | |||
2023 | bDone = true; | |||
2024 | } | |||
2025 | } | |||
2026 | ||||
2027 | if (bDone) | |||
2028 | return; | |||
2029 | ||||
2030 | if( IsTextNode() && static_cast<SwTextNode*>(this)->GetNumRule()) | |||
2031 | { | |||
2032 | // Is at which Level in a list? | |||
2033 | aTmp.SetCondition( Master_CollCondition::PARA_IN_LIST, | |||
2034 | static_cast<SwTextNode*>(this)->GetActualListLevel() ); | |||
2035 | pCColl = static_cast<SwConditionTextFormatColl*>(GetFormatColl())-> | |||
2036 | HasCondition( aTmp ); | |||
2037 | } | |||
2038 | else | |||
2039 | pCColl = nullptr; | |||
2040 | ||||
2041 | if( pCColl ) | |||
2042 | SetCondFormatColl( pCColl->GetTextFormatColl() ); | |||
2043 | else if( m_pCondColl ) | |||
2044 | SetCondFormatColl( nullptr ); | |||
2045 | } | |||
2046 | ||||
2047 | // #i42921# | |||
2048 | SvxFrameDirection SwContentNode::GetTextDirection( const SwPosition& rPos, | |||
2049 | const Point* pPt ) const | |||
2050 | { | |||
2051 | SvxFrameDirection nRet = SvxFrameDirection::Unknown; | |||
2052 | ||||
2053 | Point aPt; | |||
2054 | if( pPt ) | |||
2055 | aPt = *pPt; | |||
2056 | ||||
2057 | // #i72024# - No format of the frame, because this can cause recursive layout actions | |||
2058 | std::pair<Point, bool> const tmp(aPt, false); | |||
2059 | SwFrame* pFrame = getLayoutFrame(GetDoc().getIDocumentLayoutAccess().GetCurrentLayout(), &rPos, &tmp); | |||
2060 | ||||
2061 | if ( pFrame ) | |||
2062 | { | |||
2063 | if ( pFrame->IsVertical() ) | |||
2064 | { | |||
2065 | if (pFrame->IsVertLRBT()) | |||
2066 | nRet = SvxFrameDirection::Vertical_LR_BT; | |||
2067 | else if (pFrame->IsRightToLeft()) | |||
2068 | nRet = SvxFrameDirection::Vertical_LR_TB; | |||
2069 | else | |||
2070 | nRet = SvxFrameDirection::Vertical_RL_TB; | |||
2071 | } | |||
2072 | else | |||
2073 | { | |||
2074 | if ( pFrame->IsRightToLeft() ) | |||
2075 | nRet = SvxFrameDirection::Horizontal_RL_TB; | |||
2076 | else | |||
2077 | nRet = SvxFrameDirection::Horizontal_LR_TB; | |||
2078 | } | |||
2079 | } | |||
2080 | ||||
2081 | return nRet; | |||
2082 | } | |||
2083 | ||||
2084 | std::unique_ptr<SwOLENodes> SwContentNode::CreateOLENodesArray( const SwFormatColl& rColl, bool bOnlyWithInvalidSize ) | |||
2085 | { | |||
2086 | std::unique_ptr<SwOLENodes> pNodes; | |||
2087 | SwIterator<SwContentNode,SwFormatColl> aIter( rColl ); | |||
2088 | for( SwContentNode* pNd = aIter.First(); pNd; pNd = aIter.Next() ) | |||
2089 | { | |||
2090 | SwOLENode *pONd = pNd->GetOLENode(); | |||
2091 | if ( pONd && (!bOnlyWithInvalidSize || pONd->IsOLESizeInvalid()) ) | |||
2092 | { | |||
2093 | if ( !pNodes ) | |||
2094 | pNodes.reset(new SwOLENodes); | |||
2095 | pNodes->push_back( pONd ); | |||
2096 | } | |||
2097 | } | |||
2098 | ||||
2099 | return pNodes; | |||
2100 | } | |||
2101 | ||||
2102 | drawinglayer::attribute::SdrAllFillAttributesHelperPtr SwContentNode::getSdrAllFillAttributesHelper() const | |||
2103 | { | |||
2104 | return drawinglayer::attribute::SdrAllFillAttributesHelperPtr(); | |||
2105 | } | |||
2106 | ||||
2107 | /* | |||
2108 | * Document Interface Access | |||
2109 | */ | |||
2110 | const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return &GetDoc().GetDocumentSettingManager(); } | |||
2111 | const IDocumentDeviceAccess& SwNode::getIDocumentDeviceAccess() const { return GetDoc().getIDocumentDeviceAccess(); } | |||
2112 | const IDocumentRedlineAccess& SwNode::getIDocumentRedlineAccess() const { return GetDoc().getIDocumentRedlineAccess(); } | |||
2113 | const IDocumentStylePoolAccess& SwNode::getIDocumentStylePoolAccess() const { return GetDoc().getIDocumentStylePoolAccess(); } | |||
2114 | const IDocumentDrawModelAccess& SwNode::getIDocumentDrawModelAccess() const { return GetDoc().getIDocumentDrawModelAccess(); } | |||
2115 | const IDocumentLayoutAccess& SwNode::getIDocumentLayoutAccess() const { return GetDoc().getIDocumentLayoutAccess(); } | |||
2116 | IDocumentLayoutAccess& SwNode::getIDocumentLayoutAccess() { return GetDoc().getIDocumentLayoutAccess(); } | |||
2117 | const IDocumentLinksAdministration& SwNode::getIDocumentLinksAdministration() const { return GetDoc().getIDocumentLinksAdministration(); } | |||
2118 | IDocumentLinksAdministration& SwNode::getIDocumentLinksAdministration() { return GetDoc().getIDocumentLinksAdministration(); } | |||
2119 | const IDocumentFieldsAccess& SwNode::getIDocumentFieldsAccess() const { return GetDoc().getIDocumentFieldsAccess(); } | |||
2120 | IDocumentFieldsAccess& SwNode::getIDocumentFieldsAccess() { return GetDoc().getIDocumentFieldsAccess(); } | |||
2121 | IDocumentContentOperations& SwNode::getIDocumentContentOperations() { return GetDoc().getIDocumentContentOperations(); } | |||
2122 | IDocumentListItems& SwNode::getIDocumentListItems() { return GetDoc().getIDocumentListItems(); } // #i83479# | |||
2123 | ||||
2124 | const IDocumentMarkAccess* SwNode::getIDocumentMarkAccess() const { return GetDoc().getIDocumentMarkAccess(); } | |||
2125 | IStyleAccess& SwNode::getIDocumentStyleAccess() { return GetDoc().GetIStyleAccess(); } | |||
2126 | ||||
2127 | bool SwNode::IsInRedlines() const | |||
2128 | { | |||
2129 | const SwDoc& rDoc = GetDoc(); | |||
2130 | ||||
2131 | return rDoc.getIDocumentRedlineAccess().IsInRedlines(*this); | |||
2132 | } | |||
2133 | ||||
2134 | void SwNode::AddAnchoredFly(SwFrameFormat *const pFlyFormat) | |||
2135 | { | |||
2136 | assert(pFlyFormat)(static_cast <bool> (pFlyFormat) ? void (0) : __assert_fail ("pFlyFormat", "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 2136, __extension__ __PRETTY_FUNCTION__)); | |||
2137 | assert(&pFlyFormat->GetAnchor(false).GetContentAnchor()->nNode.GetNode() == this)(static_cast <bool> (&pFlyFormat->GetAnchor(false ).GetContentAnchor()->nNode.GetNode() == this) ? void (0) : __assert_fail ("&pFlyFormat->GetAnchor(false).GetContentAnchor()->nNode.GetNode() == this" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 2137, __extension__ __PRETTY_FUNCTION__)); | |||
2138 | // check node type, cf. SwFormatAnchor::SetAnchor() | |||
2139 | assert(IsTextNode() || IsStartNode() || IsTableNode())(static_cast <bool> (IsTextNode() || IsStartNode() || IsTableNode ()) ? void (0) : __assert_fail ("IsTextNode() || IsStartNode() || IsTableNode()" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 2139, __extension__ __PRETTY_FUNCTION__)); | |||
2140 | if (!m_pAnchoredFlys) | |||
2141 | { | |||
2142 | m_pAnchoredFlys.reset(new std::vector<SwFrameFormat*>); | |||
2143 | } | |||
2144 | m_pAnchoredFlys->push_back(pFlyFormat); | |||
2145 | } | |||
2146 | ||||
2147 | void SwNode::RemoveAnchoredFly(SwFrameFormat *const pFlyFormat) | |||
2148 | { | |||
2149 | assert(pFlyFormat)(static_cast <bool> (pFlyFormat) ? void (0) : __assert_fail ("pFlyFormat", "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 2149, __extension__ __PRETTY_FUNCTION__)); | |||
2150 | // cannot assert this in Remove because it is called when new anchor is already set | |||
2151 | // assert(&pFlyFormat->GetAnchor(false).GetContentAnchor()->nNode.GetNode() == this); | |||
2152 | assert(IsTextNode() || IsStartNode() || IsTableNode())(static_cast <bool> (IsTextNode() || IsStartNode() || IsTableNode ()) ? void (0) : __assert_fail ("IsTextNode() || IsStartNode() || IsTableNode()" , "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 2152, __extension__ __PRETTY_FUNCTION__)); | |||
2153 | assert(m_pAnchoredFlys)(static_cast <bool> (m_pAnchoredFlys) ? void (0) : __assert_fail ("m_pAnchoredFlys", "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 2153, __extension__ __PRETTY_FUNCTION__)); | |||
2154 | auto it(std::find(m_pAnchoredFlys->begin(), m_pAnchoredFlys->end(), pFlyFormat)); | |||
2155 | assert(it != m_pAnchoredFlys->end())(static_cast <bool> (it != m_pAnchoredFlys->end()) ? void (0) : __assert_fail ("it != m_pAnchoredFlys->end()", "/home/maarten/src/libreoffice/core/sw/source/core/docnode/node.cxx" , 2155, __extension__ __PRETTY_FUNCTION__)); | |||
2156 | m_pAnchoredFlys->erase(it); | |||
2157 | if (m_pAnchoredFlys->empty()) | |||
2158 | { | |||
2159 | m_pAnchoredFlys.reset(); | |||
2160 | } | |||
2161 | } | |||
2162 | ||||
2163 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |