LibreOffice Module sw (master) 1
atrflyin.cxx
Go to the documentation of this file.
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>
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#include <osl/diagnose.h>
38
41 m_pTextAttr( nullptr ),
42 m_pFormat( pFrameFormat )
43{
44}
45
46bool SwFormatFlyCnt::operator==( const SfxPoolItem& rAttr ) const
47{
48 assert(SfxPoolItem::operator==(rAttr));
49 return( m_pTextAttr && static_cast<const SwFormatFlyCnt&>(rAttr).m_pTextAttr &&
50 m_pTextAttr->GetStart() == static_cast<const SwFormatFlyCnt&>(rAttr).m_pTextAttr->GetStart() &&
51 m_pFormat == static_cast<const SwFormatFlyCnt&>(rAttr).GetFrameFormat() );
52}
53
55{
56 return new SwFormatFlyCnt( m_pFormat );
57}
58
59SwTextFlyCnt::SwTextFlyCnt( SwFormatFlyCnt& rAttr, sal_Int32 nStartPos )
60 : SwTextAttr( rAttr, nStartPos )
61{
62 rAttr.m_pTextAttr = this;
63 SetHasDummyChar(true);
64}
65
93{
95 assert(pFormat);
96 // The FlyFrameFormat must be copied - CopyLayoutFormat
97 // (DocumentLayoutManager.cxx) creates the FlyFrameFormat and copies the
98 // content.
99
100 // disable undo while copying attribute
101 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
102 SwFormatAnchor aAnchor( pFormat->GetAnchor() );
103 if ((RndStdIds::FLY_AT_PAGE != aAnchor.GetAnchorId()) &&
104 (&rDoc != pFormat->GetDoc())) // different documents?
105 {
106 // JP 03.06.96: ensure that the copied anchor points to valid content!
107 // setting it to the correct position is done later.
108 SwNodeIndex aIdx( rDoc.GetNodes().GetEndOfExtras(), +2 );
109 SwContentNode* pCNd = aIdx.GetNode().GetContentNode();
110 if( !pCNd )
111 pCNd = rDoc.GetNodes().GoNext( &aIdx );
112
113 SwPosition pos(aIdx.GetNode());
114 aAnchor.SetAnchor( &pos );
115 }
116
117 SwFrameFormat* pNew = rDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, false, false );
118 const_cast<SwFormatFlyCnt&>(GetFlyCnt()).SetFlyFormat( pNew );
119}
120
127{
128 // for Undo, the new anchor must be known already!
129
130 SwDoc& rDoc = const_cast<SwDoc&>(pNode->GetDoc());
131
133 SwFormatAnchor aAnchor( pFormat->GetAnchor() );
134 SwNode *const pOldNode(aAnchor.GetContentAnchor()
135 ? &aAnchor.GetContentAnchor()->GetNode()
136 : nullptr);
137
138 std::optional<SwPosition> oPos;
139 if (!pOldNode || !pOldNode->GetNodes().IsDocNodes() ||
140 pOldNode != static_cast<SwNode const *>(pNode))
141 {
142 oPos.emplace( *pNode, GetStart() );
143 }
144 else
145 {
146 oPos.emplace( *pOldNode, pOldNode->GetContentNode(), GetStart() );
147 }
148
149 aAnchor.SetType( RndStdIds::FLY_AS_CHAR ); // default!
150 aAnchor.SetAnchor( &*oPos );
151
152 // in case of anchor change, delete all FlyFrames
153 // JP 25.04.95: if the Frames can be moved within SplitNode, they don't
154 // need to be deleted
155 if( ( !pNode->GetpSwpHints() || !pNode->GetpSwpHints()->IsInSplitNode() )
156 && RES_DRAWFRMFMT != pFormat->Which() )
157 pFormat->DelFrames();
158
159 // copy into a different document?
160 if( &rDoc != pFormat->GetDoc() )
161 {
162 // disable undo while copying attribute
163 ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
164 SwFrameFormat* pNew = rDoc.getIDocumentLayoutAccess().CopyLayoutFormat( *pFormat, aAnchor, false, false );
165
166 ::sw::UndoGuard const undoGuardFormat(
167 pFormat->GetDoc()->GetIDocumentUndoRedo());
168 pFormat->GetDoc()->getIDocumentLayoutAccess().DelLayoutFormat( pFormat );
169 const_cast<SwFormatFlyCnt&>(GetFlyCnt()).SetFlyFormat( pNew );
170 }
171 else if( pNode->GetpSwpHints() &&
172 pNode->GetpSwpHints()->IsInSplitNode() &&
173 RES_DRAWFRMFMT != pFormat->Which() )
174 {
175 pFormat->LockModify();
176 pFormat->SetFormatAttr( aAnchor ); // only set the anchor
177 // tdf#91228 must notify the anchor nodes despite LockModify
178 assert(pOldNode);
179 pOldNode->RemoveAnchoredFly(pFormat);
180 oPos->GetNode().AddAnchoredFly(pFormat);
181 pFormat->UnlockModify();
182 }
183 else
184 {
185 assert(!pFormat->IsModifyLocked()); // need to notify anchor node
186 if (RES_DRAWFRMFMT == pFormat->Which())
187 {
188 if (SdrObject const*const pObj = pFormat->FindSdrObject())
189 { // tdf#123259 disconnect with *old* anchor position
190 static_cast<SwDrawContact*>(::GetUserCall(pObj))->DisconnectFromLayout(false);
191 }
192 }
193 pFormat->SetFormatAttr( aAnchor ); // only set the anchor
194
195 // If the draw format has a TextBox, then set its anchor as well.
196 if (SwFrameFormat* pTextBox
198 {
199 SwFormatAnchor aTextBoxAnchor(pTextBox->GetAnchor());
200 aTextBoxAnchor.SetAnchor(aAnchor.GetContentAnchor());
201
202 // SwFlyAtContentFrame::SwClientNotify() assumes the anchor has a matching layout frame, which
203 // may not be the case when we're in the process of a node split, so block
204 // notifications.
205 bool bIsInSplitNode = pNode->GetpSwpHints() && pNode->GetpSwpHints()->IsInSplitNode();
206 if (bIsInSplitNode)
207 {
208 pTextBox->LockModify();
209 }
210 else
211 {
212 // Otherwise delete fly frames on anchor change.
213 pTextBox->DelFrames();
214 }
215
216 pTextBox->SetFormatAttr(aTextBoxAnchor);
217
218 if (bIsInSplitNode)
219 {
220 pOldNode->RemoveAnchoredFly(pTextBox);
221 oPos->GetNode().AddAnchoredFly(pTextBox);
222 pTextBox->UnlockModify();
223 }
224 else
225 {
226 pTextBox->MakeFrames();
227 }
228 }
229 }
230
231 // The node may have several SwTextFrames - for every SwTextFrame a
232 // SwFlyInContentFrame is created.
233}
234
235
241{
242 SwFrameFormat* pFrameFormat = GetFlyCnt().GetFrameFormat();
243 if( RES_DRAWFRMFMT == pFrameFormat->Which() )
244 {
245 OSL_ENSURE( false, "SwTextFlyCnt::GetFlyFrame_: DrawInCnt-under construction!" );
246 return nullptr;
247 }
248
249 SwIterator<SwFlyFrame,SwFormat> aIter( *GetFlyCnt().m_pFormat );
250 assert(pCurrFrame->IsTextFrame());
251 SwFrame* pFrame = aIter.First();
252 if ( pFrame )
253 {
254 SwTextFrame *pFirst = const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pCurrFrame));
255 while ( pFirst->IsFollow() )
256 pFirst = pFirst->FindMaster();
257 do
258 {
259 SwTextFrame *pTmp = pFirst;
260 do
261 { if( static_cast<SwFlyFrame*>(pFrame)->GetAnchorFrame() == static_cast<SwFrame*>(pTmp) )
262 {
263 if ( pTmp != pCurrFrame )
264 {
265 pTmp->RemoveFly( static_cast<SwFlyFrame*>(pFrame) );
266 const_cast<SwTextFrame*>(static_cast<const SwTextFrame*>(pCurrFrame))->AppendFly( static_cast<SwFlyFrame*>(pFrame) );
267 }
268 return static_cast<SwFlyInContentFrame*>(pFrame);
269 }
270 pTmp = pTmp->GetFollow();
271 } while ( pTmp );
272
273 pFrame = aIter.Next();
274
275 } while( pFrame );
276 }
277
278 // We did not find a matching FlyFrame, so create a new one.
279 // AppendFly() triggers a reformat of pCurrentFrame. However, the
280 // recursion is blocked by the lock mechanism in SwTextFrame::Format().
281 SwFrame* pCurrentFrame = const_cast<SwFrame*>(pCurrFrame);
282 SwFlyInContentFrame *pFly = new SwFlyInContentFrame(static_cast<SwFlyFrameFormat*>(pFrameFormat), pCurrentFrame, pCurrentFrame);
283 pCurrentFrame->AppendFly(pFly);
284 pFly->RegistFlys();
285
286 // We must ensure that the content of the FlyInCnt is fully formatted
287 // right after construction.
288 // #i26945# - Use new object formatter to format Writer
289 // fly frame and its content.
290 SwObjectFormatter::FormatObj( *pFly, const_cast<SwFrame*>(pCurrFrame),
291 pCurrFrame->FindPageFrame() );
292
293 return pFly;
294}
295
296/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual SwFrameFormat * CopyLayoutFormat(const SwFrameFormat &rSrc, const SwFormatAnchor &rNewAnchor, bool bSetTextFlyAtt, bool bMakeFrames)=0
virtual void DelLayoutFormat(SwFrameFormat *pFormat)=0
const SwFrame * GetAnchorFrame() const
SwTextFrame * FindMaster() const
Definition: flowfrm.cxx:737
Definition: doc.hxx:192
IDocumentUndoRedo & GetIDocumentUndoRedo()
Definition: doc.cxx:145
SwNodes & GetNodes()
Definition: doc.hxx:413
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:406
ContactObject for connection of formats as representatives of draw objects in SwClient and the object...
Definition: dcontact.hxx:304
bool IsFollow() const
Definition: flowfrm.hxx:167
general base class for all free-flowing frames
Definition: flyfrm.hxx:79
FlyAnchors.
Definition: fmtanchr.hxx:37
void SetAnchor(const SwPosition *pPos)
Definition: atrfrm.cxx:1586
RndStdIds GetAnchorId() const
Definition: fmtanchr.hxx:67
void SetType(RndStdIds nRndId)
Definition: fmtanchr.hxx:73
const SwPosition * GetContentAnchor() const
Definition: fmtanchr.hxx:69
Format of a fly content.
Definition: fmtflcnt.hxx:33
virtual SwFormatFlyCnt * Clone(SfxItemPool *pPool=nullptr) const override
Definition: atrflyin.cxx:54
SwTextFlyCnt * m_pTextAttr
Definition: fmtflcnt.hxx:35
SwFrameFormat * m_pFormat
My Fly/DrawFrame-format.
Definition: fmtflcnt.hxx:36
SwFormatFlyCnt(SwFrameFormat *pFrameFormat)
Definition: atrflyin.cxx:39
virtual bool operator==(const SfxPoolItem &) const override
"Pure virtual methods" of SfxPoolItem.
Definition: atrflyin.cxx:46
SwFrameFormat * GetFrameFormat() const
Definition: fmtflcnt.hxx:45
const SwDoc * GetDoc() const
The document is set in SwAttrPool now, therefore you always can access it.
Definition: format.hxx:139
sal_uInt16 Which() const
for Querying of Writer-functions.
Definition: format.hxx:82
const SwFormatAnchor & GetAnchor(bool=true) const
Definition: fmtanchr.hxx:83
virtual bool SetFormatAttr(const SfxPoolItem &rAttr)
Definition: format.cxx:447
Style of a layout element.
Definition: frmfmt.hxx:62
virtual void DelFrames()
Destroys all Frames in aDepend (Frames are identified via dynamic_cast).
Definition: atrfrm.cxx:2701
SdrObject * FindSdrObject()
Definition: frmfmt.hxx:141
Base class of the Writer layout elements.
Definition: frame.hxx:315
void RemoveFly(SwFlyFrame *pToRemove)
Definition: fly.cxx:2212
bool IsTextFrame() const
Definition: frame.hxx:1234
void AppendFly(SwFlyFrame *pNew)
Definition: fly.cxx:2194
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
TElementType * Next()
Definition: calbck.hxx:364
TElementType * First()
Definition: calbck.hxx:356
void LockModify()
Definition: calbck.hxx:208
bool IsModifyLocked() const
Definition: calbck.hxx:210
void UnlockModify()
Definition: calbck.hxx:209
Marks a node in the document model.
Definition: ndindex.hxx:31
SwNode & GetNode() const
Definition: ndindex.hxx:136
Base class of the Writer document model elements.
Definition: node.hxx:84
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:722
void RemoveAnchoredFly(SwFrameFormat *)
Definition: node.cxx:2180
SwDoc & GetDoc()
Definition: node.hxx:217
SwContentNode * GetContentNode()
Definition: node.hxx:644
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:163
bool IsDocNodes() const
Is the NodesArray the regular one of Doc? (and not the UndoNds, ...) Implementation in doc....
Definition: nodes.cxx:2531
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1300
static bool FormatObj(SwAnchoredObject &_rAnchoredObj, SwFrame *_pAnchorFrame=nullptr, const SwPageFrame *_pPageFrame=nullptr)
method to format a given floating screen object
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const SwFormatFlyCnt & GetFlyCnt() const
Definition: txatbase.hxx:226
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
void SetHasDummyChar(const bool bFlag)
Definition: txatbase.hxx:78
static SwFrameFormat * getOtherTextBoxFormat(const SwFrameFormat *pFormat, sal_uInt16 nType, const SdrObject *pObject=nullptr)
If we have an associated TextFrame, then return that.
void SetAnchor(const SwTextNode *pNode)
SetAnchor() is called by SwTextNode::InsertHint() and sets the anchor position in the SwFlyFrameForma...
Definition: atrflyin.cxx:126
void CopyFlyFormat(SwDoc &rDoc)
An overview of how a new SwTextFlyCnt is created: MakeTextAttr() is called e.g.
Definition: atrflyin.cxx:92
SwFlyInContentFrame * GetFlyFrame_(const SwFrame *pCurrFrame)
GetFlyFrame_() is called during text formatting by SwTextFormatter and searches for the SwFlyFrame fo...
Definition: atrflyin.cxx:240
SwTextFlyCnt(SwFormatFlyCnt &rAttr, sal_Int32 nStart)
Definition: atrflyin.cxx:59
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:165
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:861
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:89
SwpHints * GetpSwpHints()
Definition: ndtxt.hxx:235
bool IsInSplitNode() const
Definition: ndhints.hxx:206
SwContact * GetUserCall(const SdrObject *pObj)
Returns the UserCall if applicable from the group object.
Definition: dcontact.cxx:172
constexpr TypedWhichId< SwDrawFrameFormat > RES_DRAWFRMFMT(159)
constexpr TypedWhichId< SwFormatFlyCnt > RES_TXTATR_FLYCNT(58)
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
size_t pos