Bug Summary

File:home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx
Warning:line 225, column 17
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name atrflyin.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SW_DLLIMPLEMENTATION -D SWUI_DLL_NAME="libswuilo.so" -D SYSTEM_LIBXML -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/sw/source/core/inc -I /home/maarten/src/libreoffice/core/sw/source/filter/inc -I /home/maarten/src/libreoffice/core/sw/source/uibase/inc -I /home/maarten/src/libreoffice/core/sw/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sw/sdi -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/sw/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx

/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <hintids.hxx>
21#include <doc.hxx>
22#include <IDocumentUndoRedo.hxx>
23#include <IDocumentLayoutAccess.hxx>
24#include <pam.hxx>
25#include <flyfrm.hxx>
26#include <ndtxt.hxx>
27#include <frmfmt.hxx>
28#include <fmtflcnt.hxx>
29#include <txtflcnt.hxx>
30#include <fmtanchr.hxx>
31#include <txtfrm.hxx>
32#include <flyfrms.hxx>
33#include <objectformatter.hxx>
34#include <calbck.hxx>
35#include <dcontact.hxx>
36#include <textboxhelper.hxx>
37
38SwFormatFlyCnt::SwFormatFlyCnt( SwFrameFormat *pFrameFormat )
39 : SfxPoolItem( RES_TXTATR_FLYCNT ),
40 m_pTextAttr( nullptr ),
41 m_pFormat( pFrameFormat )
42{
43}
44
45bool SwFormatFlyCnt::operator==( const SfxPoolItem& rAttr ) const
46{
47 assert(SfxPoolItem::operator==(rAttr))(static_cast <bool> (SfxPoolItem::operator==(rAttr)) ? void
(0) : __assert_fail ("SfxPoolItem::operator==(rAttr)", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx"
, 47, __extension__ __PRETTY_FUNCTION__))
;
48 return( m_pTextAttr && static_cast<const SwFormatFlyCnt&>(rAttr).m_pTextAttr &&
49 m_pTextAttr->GetStart() == static_cast<const SwFormatFlyCnt&>(rAttr).m_pTextAttr->GetStart() &&
50 m_pFormat == static_cast<const SwFormatFlyCnt&>(rAttr).GetFrameFormat() );
51}
52
53SwFormatFlyCnt* SwFormatFlyCnt::Clone( SfxItemPool* ) const
54{
55 return new SwFormatFlyCnt( m_pFormat );
56}
57
58SwTextFlyCnt::SwTextFlyCnt( SwFormatFlyCnt& rAttr, sal_Int32 nStartPos )
59 : SwTextAttr( rAttr, nStartPos )
60{
61 rAttr.m_pTextAttr = this;
62 SetHasDummyChar(true);
63}
64
65/** An overview of how a new SwTextFlyCnt is created:
66 * MakeTextAttr() is called e.g. by SwTextNode::CopyText().
67 * The following steps are required to clone:
68 * 1) copying the pFormat with content, attributes etc.
69 * 2) setting the anchor
70 * 3) notification
71 * Because not all required information is available at all times,
72 * the steps are distributed variously:
73 * ad 1) MakeTextAttr() calls DocumentLayoutManager::CopyLayoutFormat()
74 * which creates the new SwFlyFrameFormat and copies the content of the
75 * fly frame.
76 * ad 2) SetAnchor() is called by SwTextNode::InsertHint() and sets the anchor
77 * position in the SwFlyFrameFormat to the SwPosition of the dummy
78 * CH_TXTATR_BREAKWORD. This cannot be done in MakeTextAttr() because it
79 * doesn't know the target text node.
80 * ad 3) GetFlyFrame_() is called during text formatting by SwTextFormatter
81 * and searches for the SwFlyFrame for the dummy char of the current
82 * SwTextFrame. If none is found, a new SwFlyInContentFrame is created.
83 * Important: pTextFrame->AppendFly() immediately triggers a reformat
84 * of pTextFrame. However, the recursion is blocked by the lock mechanism
85 * in SwTextFrame::Format().
86 * The advantage of all this is that it's not necessary to explicitly iterate
87 * over all SwTextFrames that depend on the SwTextNode to create the
88 * SwFlyInContentFrame - this is done automatically already.
89 */
90
91void SwTextFlyCnt::CopyFlyFormat( SwDoc& rDoc )
92{
93 SwFrameFormat* pFormat = GetFlyCnt().GetFrameFormat();
94 assert(pFormat)(static_cast <bool> (pFormat) ? void (0) : __assert_fail
("pFormat", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx"
, 94, __extension__ __PRETTY_FUNCTION__))
;
95 // The FlyFrameFormat must be copied - CopyLayoutFormat
96 // (DocumentLayoutManager.cxx) creates the FlyFrameFormat and copies the
97 // content.
98
99 // disable undo while copying attribute
100 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
101 SwFormatAnchor aAnchor( pFormat->GetAnchor() );
102 if ((RndStdIds::FLY_AT_PAGE != aAnchor.GetAnchorId()) &&
103 (&rDoc != pFormat->GetDoc())) // different documents?
104 {
105 // JP 03.06.96: ensure that the copied anchor points to valid content!
106 // setting it to the correct position is done later.
107 SwNodeIndex aIdx( rDoc.GetNodes().GetEndOfExtras(), +2 );
108 SwContentNode* pCNd = aIdx.GetNode().GetContentNode();
109 if( !pCNd )
110 pCNd = rDoc.GetNodes().GoNext( &aIdx );
111
112 SwPosition pos = *aAnchor.GetContentAnchor();
113 pos.nNode = aIdx;
114 if (RndStdIds::FLY_AS_CHAR == aAnchor.GetAnchorId())
115 {
116 pos.nContent.Assign( pCNd, 0 );
117 }
118 else
119 {
120 pos.nContent.Assign( nullptr, 0 );
121 assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail (
"false", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx"
, 121, __extension__ __PRETTY_FUNCTION__))
;
122 }
123 aAnchor.SetAnchor( &pos );
124 }
125
126 SwFrameFormat* pNew = rDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, false, false );
127 const_cast<SwFormatFlyCnt&>(GetFlyCnt()).SetFlyFormat( pNew );
128}
129
130/** SetAnchor() is called by SwTextNode::InsertHint() and sets the anchor
131 * position in the SwFlyFrameFormat to the SwPosition of the dummy
132 * CH_TXTATR_BREAKWORD. This cannot be done in MakeTextAttr() because it
133 * doesn't know the target text node.
134 */
135void SwTextFlyCnt::SetAnchor( const SwTextNode *pNode )
136{
137 // for Undo, the new anchor must be known already!
138
139 SwDoc& rDoc = const_cast<SwDoc&>(pNode->GetDoc());
140
141 SwIndex aIdx( const_cast<SwTextNode*>(pNode), GetStart() );
142 SwPosition aPos( *pNode->StartOfSectionNode(), aIdx );
143 SwFrameFormat* pFormat = GetFlyCnt().GetFrameFormat();
144 SwFormatAnchor aAnchor( pFormat->GetAnchor() );
145 SwNode *const pOldNode(aAnchor.GetContentAnchor()
1
Assuming the condition is false
2
'?' condition is false
3
'pOldNode' initialized to a null pointer value
146 ? &aAnchor.GetContentAnchor()->nNode.GetNode()
147 : nullptr);
148
149 if (!pOldNode
3.1
'pOldNode' is null
3.1
'pOldNode' is null
3.1
'pOldNode' is null
|| !pOldNode->GetNodes().IsDocNodes() ||
150 pOldNode != static_cast<SwNode const *>(pNode))
151 {
152 aPos.nNode = *pNode;
153 }
154 else
155 {
156 aPos.nNode = *pOldNode;
157 }
158
159 aAnchor.SetType( RndStdIds::FLY_AS_CHAR ); // default!
160 aAnchor.SetAnchor( &aPos );
161
162 // in case of anchor change, delete all FlyFrames
163 // JP 25.04.95: if the Frames can be moved within SplitNode, they don't
164 // need to be deleted
165 if( ( !pNode->GetpSwpHints() || !pNode->GetpSwpHints()->IsInSplitNode() )
4
Assuming pointer value is null
5
Assuming the condition is false
166 && RES_DRAWFRMFMT != pFormat->Which() )
167 pFormat->DelFrames();
168
169 // copy into a different document?
170 if( &rDoc != pFormat->GetDoc() )
6
Assuming the condition is false
7
Taking false branch
171 {
172 // disable undo while copying attribute
173 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
174 SwFrameFormat* pNew = rDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, false, false );
175
176 ::sw::UndoGuard const undoGuardFormat(
177 pFormat->GetDoc()->GetIDocumentUndoRedo());
178 pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
179 const_cast<SwFormatFlyCnt&>(GetFlyCnt()).SetFlyFormat( pNew );
180 }
181 else if( pNode->GetpSwpHints() &&
15
Taking false branch
182 pNode->GetpSwpHints()->IsInSplitNode() &&
8
Calling 'SwpHints::IsInSplitNode'
10
Returning from 'SwpHints::IsInSplitNode'
183 RES_DRAWFRMFMT != pFormat->Which() )
11
Calling 'operator!=<SwDrawFrameFormat>'
14
Returning from 'operator!=<SwDrawFrameFormat>'
184 {
185 pFormat->LockModify();
186 pFormat->SetFormatAttr( aAnchor ); // only set the anchor
187 // tdf#91228 must notify the anchor nodes despite LockModify
188 assert(pOldNode)(static_cast <bool> (pOldNode) ? void (0) : __assert_fail
("pOldNode", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx"
, 188, __extension__ __PRETTY_FUNCTION__))
;
189 pOldNode->RemoveAnchoredFly(pFormat);
190 aPos.nNode.GetNode().AddAnchoredFly(pFormat);
191 pFormat->UnlockModify();
192 }
193 else
194 {
195 assert(!pFormat->IsModifyLocked())(static_cast <bool> (!pFormat->IsModifyLocked()) ? void
(0) : __assert_fail ("!pFormat->IsModifyLocked()", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx"
, 195, __extension__ __PRETTY_FUNCTION__))
; // need to notify anchor node
16
Assuming the condition is true
17
'?' condition is true
196 if (RES_DRAWFRMFMT == pFormat->Which())
18
Taking true branch
197 {
198 if (SdrObject const*const pObj = pFormat->FindSdrObject())
19
Assuming 'pObj' is null
20
Taking false branch
199 { // tdf#123259 disconnect with *old* anchor position
200 static_cast<SwDrawContact*>(::GetUserCall(pObj))->DisconnectFromLayout(false);
201 }
202 }
203 pFormat->SetFormatAttr( aAnchor ); // only set the anchor
204
205 // If the draw format has a TextBox, then set its anchor as well.
206 if (SwFrameFormat* pTextBox
21
Assuming 'pTextBox' is non-null
22
Taking true branch
207 = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT))
208 {
209 SwFormatAnchor aTextBoxAnchor(pTextBox->GetAnchor());
210 aTextBoxAnchor.SetAnchor(aAnchor.GetContentAnchor());
211
212 // SwFlyAtContentFrame::Modify() assumes the anchor has a matching layout frame, which
213 // may not be the case when we're in the process of a node split, so block
214 // notifications.
215 bool bIsInSplitNode = pNode->GetpSwpHints() && pNode->GetpSwpHints()->IsInSplitNode();
216 if (bIsInSplitNode
22.1
'bIsInSplitNode' is true
22.1
'bIsInSplitNode' is true
22.1
'bIsInSplitNode' is true
)
23
Taking true branch
217 {
218 pTextBox->LockModify();
219 }
220
221 pTextBox->SetFormatAttr(aTextBoxAnchor);
222
223 if (bIsInSplitNode
23.1
'bIsInSplitNode' is true
23.1
'bIsInSplitNode' is true
23.1
'bIsInSplitNode' is true
)
24
Taking true branch
224 {
225 pOldNode->RemoveAnchoredFly(pTextBox);
25
Called C++ object pointer is null
226 aPos.nNode.GetNode().AddAnchoredFly(pTextBox);
227 pTextBox->UnlockModify();
228 }
229 }
230 }
231
232 // The node may have several SwTextFrames - for every SwTextFrame a
233 // SwFlyInContentFrame is created.
234}
235
236
237/** GetFlyFrame_() is called during text formatting by SwTextFormatter
238 * and searches for the SwFlyFrame for the dummy char of the current
239 * SwTextFrame. If none is found, a new SwFlyInContentFrame is created.
240 */
241SwFlyInContentFrame *SwTextFlyCnt::GetFlyFrame_( const SwFrame *pCurrFrame )
242{
243 SwFrameFormat* pFrameFormat = GetFlyCnt().GetFrameFormat();
244 if( RES_DRAWFRMFMT == pFrameFormat->Which() )
245 {
246 OSL_ENSURE( false, "SwTextFlyCnt::GetFlyFrame_: DrawInCnt-under construction!" )do { if (true && (!(false))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx"
":" "246" ": "), "%s", "SwTextFlyCnt::GetFlyFrame_: DrawInCnt-under construction!"
); } } while (false)
;
247 return nullptr;
248 }
249
250 SwIterator<SwFlyFrame,SwFormat> aIter( *GetFlyCnt().m_pFormat );
251 assert(pCurrFrame->IsTextFrame())(static_cast <bool> (pCurrFrame->IsTextFrame()) ? void
(0) : __assert_fail ("pCurrFrame->IsTextFrame()", "/home/maarten/src/libreoffice/core/sw/source/core/txtnode/atrflyin.cxx"
, 251, __extension__ __PRETTY_FUNCTION__))
;
252 SwFrame* pFrame = aIter.First();
253 if ( pFrame )
254 {
255 SwTextFrame *pFirst = const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pCurrFrame));
256 while ( pFirst->IsFollow() )
257 pFirst = pFirst->FindMaster();
258 do
259 {
260 SwTextFrame *pTmp = pFirst;
261 do
262 { if( static_cast<SwFlyFrame*>(pFrame)->GetAnchorFrame() == static_cast<SwFrame*>(pTmp) )
263 {
264 if ( pTmp != pCurrFrame )
265 {
266 pTmp->RemoveFly( static_cast<SwFlyFrame*>(pFrame) );
267 const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pCurrFrame))->AppendFly( static_cast<SwFlyFrame*>(pFrame) );
268 }
269 return static_cast<SwFlyInContentFrame*>(pFrame);
270 }
271 pTmp = pTmp->GetFollow();
272 } while ( pTmp );
273
274 pFrame = aIter.Next();
275
276 } while( pFrame );
277 }
278
279 // We did not find a matching FlyFrame, so create a new one.
280 // AppendFly() triggers a reformat of pCurrentFrame. However, the
281 // recursion is blocked by the lock mechanism in SwTextFrame::Format().
282 SwFrame* pCurrentFrame = const_cast<SwFrame*>(pCurrFrame);
283 SwFlyInContentFrame *pFly = new SwFlyInContentFrame(static_cast<SwFlyFrameFormat*>(pFrameFormat), pCurrentFrame, pCurrentFrame);
284 pCurrentFrame->AppendFly(pFly);
285 pFly->RegistFlys();
286
287 // We must ensure that the content of the FlyInCnt is fully formatted
288 // right after construction.
289 // #i26945# - Use new object formatter to format Writer
290 // fly frame and its content.
291 SwObjectFormatter::FormatObj( *pFly, const_cast<SwFrame*>(pCurrFrame),
292 pCurrFrame->FindPageFrame() );
293
294 return pFly;
295}
296
297/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/sw/inc/ndhints.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_SW_INC_NDHINTS_HXX
20#define INCLUDED_SW_INC_NDHINTS_HXX
21
22#include "swtypes.hxx"
23
24class SwTextNode;
25class SwRegHistory; // Is in RolBck.hxx.
26class SwTextAttr;
27class SwTextAttrNesting;
28
29class SfxPoolItem;
30class SfxItemSet;
31class SwDoc;
32
33enum class CopyOrNewType { Copy, New };
34
35/// if COPY then pTextNode must be given!
36SwTextAttr * MakeTextAttr(
37 SwDoc & rDoc,
38 SfxPoolItem & rNew,
39 sal_Int32 const nStt,
40 sal_Int32 const nEnd,
41 CopyOrNewType const bIsCopy = CopyOrNewType::New,
42 SwTextNode *const pTextNode = nullptr );
43
44SwTextAttr * MakeTextAttr(
45 SwDoc & rDoc,
46 const SfxItemSet & rSet,
47 sal_Int32 nStt,
48 sal_Int32 nEnd );
49
50/// create redline dummy text hint that must not be inserted into hints array
51SwTextAttr* MakeRedlineTextAttr(
52 SwDoc & rDoc,
53 SfxPoolItem const & rAttr );
54
55struct CompareSwpHtEnd
56{
57 bool operator()( sal_Int32 nEndPos, const SwTextAttr* rhs ) const;
58 bool operator()( const SwTextAttr* lhs, const SwTextAttr* rhs ) const;
59};
60struct CompareSwpHtWhichStart
61{
62 bool operator()( const SwTextAttr* lhs, const sal_uInt16 nWhich ) const;
63 bool operator()( const SwTextAttr* lhs, const SwTextAttr* rhs ) const;
64};
65
66/// An SwTextAttr container, stores all directly formatted text portions for a text node.
67class SwpHints
68{
69private:
70 const SwTextNode& m_rParent;
71
72 // SAL_MAX_SIZE is used by GetStartOf to return
73 // failure, so just allow SAL_MAX_SIZE-1 hints
74 static const size_t MAX_HINTS = SAL_MAX_SIZE((sal_uInt64) 0xFFFFFFFFFFFFFFFFul)-1;
75
76 std::vector<SwTextAttr*> m_HintsByStart;
77 std::vector<SwTextAttr*> m_HintsByEnd;
78 std::vector<SwTextAttr*> m_HintsByWhichAndStart;
79
80 SwRegHistory* m_pHistory; ///< for Undo
81
82 /// true: the Node is in Split and Frames are moved
83 bool m_bInSplitNode : 1;
84 // m_bHiddenByParaField is invalid, call CalcHiddenParaField()
85 mutable bool m_bCalcHiddenParaField : 1;
86 // if all fields controlling visibility of the paragraph require to hide it
87 // (if there's no such fields, or if any field requires to show, then this is false)
88 mutable bool m_bHiddenByParaField : 1;
89 bool m_bFootnote : 1; ///< footnotes
90 bool m_bDDEFields : 1; ///< the TextNode has DDE fields
91 // Sort on demand to avoid O(n^2) behaviour
92 mutable bool m_bStartMapNeedsSorting : 1;
93 mutable bool m_bEndMapNeedsSorting : 1;
94 mutable bool m_bWhichMapNeedsSorting : 1;
95
96 /// records a new attribute in m_pHistory.
97 void NoteInHistory( SwTextAttr *pAttr, const bool bNew = false );
98
99 void CalcFlags( );
100
101 /** Delete methods may only be called by the TextNode!
102 Because the TextNode also guarantees removal of the Character for
103 attributes without an end. */
104 friend class SwTextNode;
105 void DeleteAtPos( size_t nPos );
106 /// Delete the given Hint. The Hint must actually be in the array!
107 void Delete( SwTextAttr const * pTextHt );
108
109 void SetInSplitNode(bool bInSplit) { m_bInSplitNode = bInSplit; }
110 void SetCalcHiddenParaField() const { m_bCalcHiddenParaField = true; }
111 void SetHiddenByParaField( const bool bNew ) const { m_bHiddenByParaField = bNew; }
112 bool IsHiddenByParaField() const
113 {
114 if ( m_bCalcHiddenParaField )
115 {
116 CalcHiddenParaField();
117 }
118 return m_bHiddenByParaField;
119 }
120
121 void InsertNesting(SwTextAttrNesting & rNewHint);
122 bool TryInsertNesting(SwTextNode & rNode, SwTextAttrNesting & rNewHint);
123 void BuildPortions( SwTextNode& rNode, SwTextAttr& rNewHint,
124 const SetAttrMode nMode );
125 bool MergePortions( SwTextNode& rNode );
126
127 void Insert(SwTextAttr* pHt);
128 SW_DLLPUBLIC__attribute__ ((visibility("default"))) void Resort() const;
129 SW_DLLPUBLIC__attribute__ ((visibility("default"))) void ResortStartMap() const;
130 SW_DLLPUBLIC__attribute__ ((visibility("default"))) void ResortEndMap() const;
131 SW_DLLPUBLIC__attribute__ ((visibility("default"))) void ResortWhichMap() const;
132
133 size_t GetIndexOf( const SwTextAttr *pHt ) const;
134
135#ifdef DBG_UTIL
136 bool Check(bool) const;
137#endif
138
139public:
140 SwpHints(const SwTextNode& rParent);
141
142 size_t Count() const { return m_HintsByStart.size(); }
143 bool Contains( const SwTextAttr *pHt ) const;
144 SwTextAttr * Get( size_t nPos ) const
145 {
146 assert( !(nPos != 0 && m_bStartMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" )(static_cast <bool> (!(nPos != 0 && m_bStartMapNeedsSorting
) && "going to trigger a resort in the middle of an iteration, that's bad"
) ? void (0) : __assert_fail ("!(nPos != 0 && m_bStartMapNeedsSorting) && \"going to trigger a resort in the middle of an iteration, that's bad\""
, "/home/maarten/src/libreoffice/core/sw/inc/ndhints.hxx", 146
, __extension__ __PRETTY_FUNCTION__))
;
147 if (m_bStartMapNeedsSorting)
148 ResortStartMap();
149 return m_HintsByStart[nPos];
150 }
151 // Get without triggering resorting - useful if we are modifying start/end pos while iterating
152 SwTextAttr * GetWithoutResorting( size_t nPos ) const
153 {
154 return m_HintsByStart[nPos];
155 }
156
157 int GetLastPosSortedByEnd(sal_Int32 nEndPos) const;
158 SwTextAttr * GetSortedByEnd( size_t nPos ) const
159 {
160 assert( !(nPos != 0 && m_bEndMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" )(static_cast <bool> (!(nPos != 0 && m_bEndMapNeedsSorting
) && "going to trigger a resort in the middle of an iteration, that's bad"
) ? void (0) : __assert_fail ("!(nPos != 0 && m_bEndMapNeedsSorting) && \"going to trigger a resort in the middle of an iteration, that's bad\""
, "/home/maarten/src/libreoffice/core/sw/inc/ndhints.hxx", 160
, __extension__ __PRETTY_FUNCTION__))
;
161 if (m_bEndMapNeedsSorting)
162 ResortEndMap();
163 return m_HintsByEnd[nPos];
164 }
165
166 size_t GetFirstPosSortedByWhichAndStart(sal_uInt16 nWhich) const;
167 SwTextAttr * GetSortedByWhichAndStart( size_t nPos ) const
168 {
169 assert( !(nPos != 0 && m_bWhichMapNeedsSorting) && "going to trigger a resort in the middle of an iteration, that's bad" )(static_cast <bool> (!(nPos != 0 && m_bWhichMapNeedsSorting
) && "going to trigger a resort in the middle of an iteration, that's bad"
) ? void (0) : __assert_fail ("!(nPos != 0 && m_bWhichMapNeedsSorting) && \"going to trigger a resort in the middle of an iteration, that's bad\""
, "/home/maarten/src/libreoffice/core/sw/inc/ndhints.hxx", 169
, __extension__ __PRETTY_FUNCTION__))
;
170 if (m_bWhichMapNeedsSorting)
171 ResortWhichMap();
172 return m_HintsByWhichAndStart[nPos];
173 }
174
175 /// Trigger the sorting if necessary
176 void SortIfNeedBe() const
177 {
178 if (m_bStartMapNeedsSorting)
179 ResortStartMap();
180 if (m_bEndMapNeedsSorting)
181 ResortEndMap();
182 if (m_bWhichMapNeedsSorting)
183 ResortWhichMap();
184 }
185 SwTextAttr * Cut( const size_t nPosInStart )
186 {
187 SwTextAttr *pHt = m_HintsByStart[nPosInStart];
188 DeleteAtPos( nPosInStart );
189 return pHt;
190 }
191
192 bool CanBeDeleted() const { return m_HintsByStart.empty(); }
193
194 /// register a History, which receives all attribute changes (for Undo)
195 void Register( SwRegHistory* pHist ) { m_pHistory = pHist; }
196 /// deregister the currently registered History
197 void DeRegister() { Register(nullptr); }
198 SwRegHistory* GetHistory() const { return m_pHistory; }
199
200 /// try to insert the hint
201 /// @return true iff hint successfully inserted
202 bool TryInsertHint( SwTextAttr * const pHint, SwTextNode & rNode,
203 const SetAttrMode nMode = SetAttrMode::DEFAULT );
204
205 bool HasFootnote() const { return m_bFootnote; }
206 bool IsInSplitNode() const { return m_bInSplitNode; }
9
Returning the value 1, which participates in a condition later
207
208 // calc current value of m_bHiddenByParaField, returns true iff changed
209 bool CalcHiddenParaField() const; // changes mutable state
210
211 // Marks the hint-maps as needing sorting because the position of something has changed
212 void StartPosChanged() const { m_bStartMapNeedsSorting = true; m_bEndMapNeedsSorting = true; m_bWhichMapNeedsSorting = true; }
213 void EndPosChanged() const { m_bStartMapNeedsSorting = true; m_bEndMapNeedsSorting = true; m_bWhichMapNeedsSorting = true; }
214};
215
216#endif
217
218/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/svl/typedwhich.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9#ifndef INCLUDED_SVL_TYPEDWHICH_HXX
10#define INCLUDED_SVL_TYPEDWHICH_HXX
11
12#include <sal/config.h>
13#include <sal/types.h>
14
15/**
16 * A very thin wrapper around the sal_uInt16 WhichId whose purpose is mostly to carry type information,
17 * so that we Put() and Get() the right subclasses of SfxPoolItem for each WhichId.
18 */
19template <class T> class TypedWhichId final
20{
21public:
22 explicit constexpr TypedWhichId(sal_uInt16 nWhich)
23 : mnWhich(nWhich)
24 {
25 }
26 constexpr operator sal_uInt16() const { return mnWhich; }
27
28private:
29 sal_uInt16 const mnWhich;
30};
31
32template <class T> constexpr bool operator==(sal_uInt16 lhs, TypedWhichId<T> const& rhs)
33{
34 return lhs == sal_uInt16(rhs);
35}
36template <class T> constexpr bool operator!=(sal_uInt16 lhs, TypedWhichId<T> const& rhs)
37{
38 return lhs != sal_uInt16(rhs);
39}
40template <class T> constexpr bool operator==(TypedWhichId<T> const& lhs, sal_uInt16 rhs)
41{
42 return sal_uInt16(lhs) == rhs;
43}
44template <class T> constexpr bool operator!=(TypedWhichId<T> const& lhs, sal_uInt16 rhs)
45{
46 return sal_uInt16(lhs) != rhs;
12
Assuming the condition is false
13
Returning zero, which participates in a condition later
47}
48
49#endif // INCLUDED_SVL_TYPEDWHICH_HXX
50
51/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */