File: | home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx |
Warning: | line 549, column 30 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 <sot/exchange.hxx> | |||
22 | #include <svx/svdpage.hxx> | |||
23 | #include <editeng/keepitem.hxx> | |||
24 | #include <editeng/ulspitem.hxx> | |||
25 | #include <editeng/lrspitem.hxx> | |||
26 | #include <editeng/boxitem.hxx> | |||
27 | #include <editeng/shaditem.hxx> | |||
28 | #include <editeng/protitem.hxx> | |||
29 | #include <editeng/opaqitem.hxx> | |||
30 | #include <svx/svdouno.hxx> | |||
31 | #include <editeng/frmdiritem.hxx> | |||
32 | #include <swmodule.hxx> | |||
33 | #include <modcfg.hxx> | |||
34 | #include <com/sun/star/beans/XPropertySet.hpp> | |||
35 | #include <com/sun/star/embed/XEmbeddedObject.hpp> | |||
36 | #include <SwStyleNameMapper.hxx> | |||
37 | #include <drawdoc.hxx> | |||
38 | #include <fchrfmt.hxx> | |||
39 | #include <frmatr.hxx> | |||
40 | #include <txatbase.hxx> | |||
41 | #include <fmtfld.hxx> | |||
42 | #include <fmtornt.hxx> | |||
43 | #include <fmtcntnt.hxx> | |||
44 | #include <fmtanchr.hxx> | |||
45 | #include <fmtfsize.hxx> | |||
46 | #include <fmtsrnd.hxx> | |||
47 | #include <fmtflcnt.hxx> | |||
48 | #include <frmfmt.hxx> | |||
49 | #include <pam.hxx> | |||
50 | #include <ndtxt.hxx> | |||
51 | #include <ndnotxt.hxx> | |||
52 | #include <ndole.hxx> | |||
53 | #include <doc.hxx> | |||
54 | #include <IDocumentUndoRedo.hxx> | |||
55 | #include <IDocumentRedlineAccess.hxx> | |||
56 | #include <DocumentSettingManager.hxx> | |||
57 | #include <IDocumentDrawModelAccess.hxx> | |||
58 | #include <IDocumentFieldsAccess.hxx> | |||
59 | #include <IDocumentState.hxx> | |||
60 | #include <IDocumentLayoutAccess.hxx> | |||
61 | #include <IDocumentStylePoolAccess.hxx> | |||
62 | #include <rootfrm.hxx> | |||
63 | #include <pagefrm.hxx> | |||
64 | #include <cntfrm.hxx> | |||
65 | #include <txtfrm.hxx> | |||
66 | #include <notxtfrm.hxx> | |||
67 | #include <flyfrm.hxx> | |||
68 | #include <dflyobj.hxx> | |||
69 | #include <dcontact.hxx> | |||
70 | #include <swundo.hxx> | |||
71 | #include <flypos.hxx> | |||
72 | #include <UndoInsert.hxx> | |||
73 | #include <expfld.hxx> | |||
74 | #include <poolfmt.hxx> | |||
75 | #include <docary.hxx> | |||
76 | #include <swtable.hxx> | |||
77 | #include <tblsel.hxx> | |||
78 | #include <txtftn.hxx> | |||
79 | #include <ftnidx.hxx> | |||
80 | #include <ftninfo.hxx> | |||
81 | #include <pagedesc.hxx> | |||
82 | #include <strings.hrc> | |||
83 | #include <frameformats.hxx> | |||
84 | #include <tools/datetimeutils.hxx> | |||
85 | ||||
86 | #include <sortedobjs.hxx> | |||
87 | ||||
88 | #include <vector> | |||
89 | ||||
90 | using namespace ::com::sun::star; | |||
91 | ||||
92 | #define DEF_FLY_WIDTH2268 2268 // Default width for FlyFrames (2268 == 4cm) | |||
93 | ||||
94 | static bool lcl_IsItemSet(const SwContentNode & rNode, sal_uInt16 which) | |||
95 | { | |||
96 | bool bResult = false; | |||
97 | ||||
98 | if (SfxItemState::SET == rNode.GetSwAttrSet().GetItemState(which)) | |||
99 | bResult = true; | |||
100 | ||||
101 | return bResult; | |||
102 | } | |||
103 | ||||
104 | SdrObject* SwDoc::CloneSdrObj( const SdrObject& rObj, bool bMoveWithinDoc, | |||
105 | bool bInsInPage ) | |||
106 | { | |||
107 | // #i52858# - method name changed | |||
108 | SdrPage *pPg = getIDocumentDrawModelAccess().GetOrCreateDrawModel()->GetPage( 0 ); | |||
109 | if( !pPg ) | |||
110 | { | |||
111 | pPg = getIDocumentDrawModelAccess().GetDrawModel()->AllocPage( false ); | |||
112 | getIDocumentDrawModelAccess().GetDrawModel()->InsertPage( pPg ); | |||
113 | } | |||
114 | ||||
115 | // TTTT Clone directly to target SdrModel | |||
116 | SdrObject *pObj(rObj.CloneSdrObject(*getIDocumentDrawModelAccess().GetDrawModel())); | |||
117 | ||||
118 | if( bMoveWithinDoc && SdrInventor::FmForm == pObj->GetObjInventor() ) | |||
119 | { | |||
120 | // We need to preserve the Name for Controls | |||
121 | uno::Reference< awt::XControlModel > xModel = static_cast<SdrUnoObj*>(pObj)->GetUnoControlModel(); | |||
122 | uno::Any aVal; | |||
123 | uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY); | |||
124 | const OUString sName("Name"); | |||
125 | if( xSet.is() ) | |||
126 | aVal = xSet->getPropertyValue( sName ); | |||
127 | if( bInsInPage ) | |||
128 | pPg->InsertObjectThenMakeNameUnique( pObj ); | |||
129 | if( xSet.is() ) | |||
130 | xSet->setPropertyValue( sName, aVal ); | |||
131 | } | |||
132 | else if( bInsInPage ) | |||
133 | pPg->InsertObjectThenMakeNameUnique( pObj ); | |||
134 | ||||
135 | // For drawing objects: set layer of cloned object to invisible layer | |||
136 | SdrLayerID nLayerIdForClone = rObj.GetLayer(); | |||
137 | if ( dynamic_cast<const SwFlyDrawObj*>( pObj) == nullptr && | |||
138 | dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr && | |||
139 | typeid(SdrObject) != typeid(pObj) ) | |||
140 | { | |||
141 | if ( getIDocumentDrawModelAccess().IsVisibleLayerId( nLayerIdForClone ) ) | |||
142 | { | |||
143 | nLayerIdForClone = getIDocumentDrawModelAccess().GetInvisibleLayerIdByVisibleOne( nLayerIdForClone ); | |||
144 | } | |||
145 | } | |||
146 | pObj->SetLayer( nLayerIdForClone ); | |||
147 | ||||
148 | return pObj; | |||
149 | } | |||
150 | ||||
151 | SwFlyFrameFormat* SwDoc::MakeFlySection_( const SwPosition& rAnchPos, | |||
152 | const SwContentNode& rNode, | |||
153 | RndStdIds eRequestId, | |||
154 | const SfxItemSet* pFlySet, | |||
155 | SwFrameFormat* pFrameFormat ) | |||
156 | { | |||
157 | if( !pFrameFormat ) | |||
158 | pFrameFormat = getIDocumentStylePoolAccess().GetFrameFormatFromPool( RES_POOLFRM_FRAME ); | |||
159 | ||||
160 | OUString sName; | |||
161 | if( !mbInReading ) | |||
162 | switch( rNode.GetNodeType() ) | |||
163 | { | |||
164 | case SwNodeType::Grf: sName = GetUniqueGrfName(); break; | |||
165 | case SwNodeType::Ole: sName = GetUniqueOLEName(); break; | |||
166 | default: sName = GetUniqueFrameName(); break; | |||
167 | } | |||
168 | SwFlyFrameFormat* pFormat = MakeFlyFrameFormat( sName, pFrameFormat ); | |||
169 | ||||
170 | // Create content and connect to the format. | |||
171 | // Create ContentNode and put it into the autotext selection. | |||
172 | SwNodeRange aRange( GetNodes().GetEndOfAutotext(), -1, | |||
173 | GetNodes().GetEndOfAutotext() ); | |||
174 | GetNodes().SectionDown( &aRange, SwFlyStartNode ); | |||
175 | ||||
176 | pFormat->SetFormatAttr( SwFormatContent( rNode.StartOfSectionNode() )); | |||
177 | ||||
178 | const SwFormatAnchor* pAnchor = nullptr; | |||
179 | if( pFlySet ) | |||
180 | { | |||
181 | pFlySet->GetItemState( RES_ANCHOR, false, | |||
182 | reinterpret_cast<const SfxPoolItem**>(&pAnchor) ); | |||
183 | if( SfxItemState::SET == pFlySet->GetItemState( RES_CNTNT, false )) | |||
184 | { | |||
185 | SfxItemSet aTmpSet( *pFlySet ); | |||
186 | aTmpSet.ClearItem( RES_CNTNT ); | |||
187 | pFormat->SetFormatAttr( aTmpSet ); | |||
188 | } | |||
189 | else | |||
190 | pFormat->SetFormatAttr( *pFlySet ); | |||
191 | } | |||
192 | ||||
193 | // Anchor not yet set? | |||
194 | RndStdIds eAnchorId; | |||
195 | // #i107811# Assure that at-page anchored fly frames have a page num or a | |||
196 | // content anchor set. | |||
197 | if ( !pAnchor || | |||
198 | ( RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId() && | |||
199 | !pAnchor->GetContentAnchor() ) || | |||
200 | ( RndStdIds::FLY_AT_PAGE == pAnchor->GetAnchorId() && | |||
201 | !pAnchor->GetContentAnchor() && | |||
202 | pAnchor->GetPageNum() == 0 ) ) | |||
203 | { | |||
204 | // set it again, needed for Undo | |||
205 | SwFormatAnchor aAnch( pFormat->GetAnchor() ); | |||
206 | if (pAnchor && (RndStdIds::FLY_AT_FLY == pAnchor->GetAnchorId())) | |||
207 | { | |||
208 | SwPosition aPos( *rAnchPos.nNode.GetNode().FindFlyStartNode() ); | |||
209 | aAnch.SetAnchor( &aPos ); | |||
210 | eAnchorId = RndStdIds::FLY_AT_FLY; | |||
211 | } | |||
212 | else | |||
213 | { | |||
214 | if( eRequestId != aAnch.GetAnchorId() && | |||
215 | SfxItemState::SET != pFormat->GetItemState( RES_ANCHOR ) ) | |||
216 | { | |||
217 | aAnch.SetType( eRequestId ); | |||
218 | } | |||
219 | ||||
220 | eAnchorId = aAnch.GetAnchorId(); | |||
221 | if ( RndStdIds::FLY_AT_PAGE != eAnchorId || !pAnchor || aAnch.GetPageNum() == 0) | |||
222 | { | |||
223 | aAnch.SetAnchor( &rAnchPos ); | |||
224 | } | |||
225 | } | |||
226 | pFormat->SetFormatAttr( aAnch ); | |||
227 | } | |||
228 | else | |||
229 | eAnchorId = pFormat->GetAnchor().GetAnchorId(); | |||
230 | ||||
231 | if ( RndStdIds::FLY_AS_CHAR == eAnchorId ) | |||
232 | { | |||
233 | const sal_Int32 nStt = rAnchPos.nContent.GetIndex(); | |||
234 | SwTextNode * pTextNode = rAnchPos.nNode.GetNode().GetTextNode(); | |||
235 | ||||
236 | OSL_ENSURE(pTextNode!= nullptr, "There should be a SwTextNode!")do { if (true && (!(pTextNode!= nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "236" ": "), "%s", "There should be a SwTextNode!"); } } while (false); | |||
237 | ||||
238 | if (pTextNode != nullptr) | |||
239 | { | |||
240 | SwFormatFlyCnt aFormat( pFormat ); | |||
241 | // may fail if there's no space left or header/ftr | |||
242 | if (!pTextNode->InsertItem(aFormat, nStt, nStt)) | |||
243 | { // pFormat is dead now | |||
244 | return nullptr; | |||
245 | } | |||
246 | } | |||
247 | } | |||
248 | ||||
249 | if( SfxItemState::SET != pFormat->GetAttrSet().GetItemState( RES_FRM_SIZE )) | |||
250 | { | |||
251 | SwFormatFrameSize aFormatSize( SwFrameSize::Variable, 0, DEF_FLY_WIDTH2268 ); | |||
252 | const SwNoTextNode* pNoTextNode = rNode.GetNoTextNode(); | |||
253 | if( pNoTextNode ) | |||
254 | { | |||
255 | // Set size | |||
256 | Size aSize( pNoTextNode->GetTwipSize() ); | |||
257 | if( MINFLY23 > aSize.Width() ) | |||
258 | aSize.setWidth( DEF_FLY_WIDTH2268 ); | |||
259 | aFormatSize.SetWidth( aSize.Width() ); | |||
260 | if( aSize.Height() ) | |||
261 | { | |||
262 | aFormatSize.SetHeight( aSize.Height() ); | |||
263 | aFormatSize.SetHeightSizeType( SwFrameSize::Fixed ); | |||
264 | } | |||
265 | } | |||
266 | pFormat->SetFormatAttr( aFormatSize ); | |||
267 | } | |||
268 | ||||
269 | // Set up frames | |||
270 | if( getIDocumentLayoutAccess().GetCurrentViewShell() ) | |||
271 | pFormat->MakeFrames(); // ??? | |||
272 | ||||
273 | if (GetIDocumentUndoRedo().DoesUndo()) | |||
274 | { | |||
275 | sal_uLong nNodeIdx = rAnchPos.nNode.GetIndex(); | |||
276 | const sal_Int32 nCntIdx = rAnchPos.nContent.GetIndex(); | |||
277 | GetIDocumentUndoRedo().AppendUndo( | |||
278 | std::make_unique<SwUndoInsLayFormat>( pFormat, nNodeIdx, nCntIdx )); | |||
279 | } | |||
280 | ||||
281 | getIDocumentState().SetModified(); | |||
282 | return pFormat; | |||
283 | } | |||
284 | ||||
285 | SwFlyFrameFormat* SwDoc::MakeFlySection( RndStdIds eAnchorType, | |||
286 | const SwPosition* pAnchorPos, | |||
287 | const SfxItemSet* pFlySet, | |||
288 | SwFrameFormat* pFrameFormat, bool bCalledFromShell ) | |||
289 | { | |||
290 | SwFlyFrameFormat* pFormat = nullptr; | |||
291 | if ( !pAnchorPos && (RndStdIds::FLY_AT_PAGE != eAnchorType) ) | |||
292 | { | |||
293 | const SwFormatAnchor* pAnch; | |||
294 | if( (pFlySet && SfxItemState::SET == pFlySet->GetItemState( | |||
295 | RES_ANCHOR, false, reinterpret_cast<const SfxPoolItem**>(&pAnch) )) || | |||
296 | ( pFrameFormat && SfxItemState::SET == pFrameFormat->GetItemState( | |||
297 | RES_ANCHOR, true, reinterpret_cast<const SfxPoolItem**>(&pAnch) )) ) | |||
298 | { | |||
299 | if ( RndStdIds::FLY_AT_PAGE != pAnch->GetAnchorId() ) | |||
300 | { | |||
301 | pAnchorPos = pAnch->GetContentAnchor(); | |||
302 | } | |||
303 | } | |||
304 | } | |||
305 | ||||
306 | if (pAnchorPos) | |||
307 | { | |||
308 | if( !pFrameFormat ) | |||
309 | pFrameFormat = getIDocumentStylePoolAccess().GetFrameFormatFromPool( RES_POOLFRM_FRAME ); | |||
310 | ||||
311 | sal_uInt16 nCollId = static_cast<sal_uInt16>( | |||
312 | GetDocumentSettingManager().get(DocumentSettingId::HTML_MODE) ? RES_POOLCOLL_TEXT : RES_POOLCOLL_FRAME ); | |||
313 | ||||
314 | /* If there is no adjust item in the paragraph style for the content node of the new fly section | |||
315 | propagate an existing adjust item at the anchor to the new content node. */ | |||
316 | SwContentNode * pNewTextNd = GetNodes().MakeTextNode | |||
317 | (SwNodeIndex( GetNodes().GetEndOfAutotext()), | |||
318 | getIDocumentStylePoolAccess().GetTextCollFromPool( nCollId )); | |||
319 | SwContentNode * pAnchorNode = pAnchorPos->nNode.GetNode().GetContentNode(); | |||
320 | // pAnchorNode from cursor must be valid, unless a whole table is selected (in which | |||
321 | // case the node is not a content node, and pAnchorNode is nullptr). In the latter case, | |||
322 | // bCalledFromShell is false. | |||
323 | assert(!bCalledFromShell || pAnchorNode)(static_cast <bool> (!bCalledFromShell || pAnchorNode) ? void (0) : __assert_fail ("!bCalledFromShell || pAnchorNode" , "/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" , 323, __extension__ __PRETTY_FUNCTION__)); | |||
324 | ||||
325 | const SfxPoolItem * pItem = nullptr; | |||
326 | ||||
327 | if (bCalledFromShell && !lcl_IsItemSet(*pNewTextNd, RES_PARATR_ADJUST) && | |||
328 | SfxItemState::SET == pAnchorNode->GetSwAttrSet(). | |||
329 | GetItemState(RES_PARATR_ADJUST, true, &pItem)) | |||
330 | { | |||
331 | pNewTextNd->SetAttr(*pItem); | |||
332 | } | |||
333 | ||||
334 | pFormat = MakeFlySection_( *pAnchorPos, *pNewTextNd, | |||
335 | eAnchorType, pFlySet, pFrameFormat ); | |||
336 | } | |||
337 | return pFormat; | |||
338 | } | |||
339 | ||||
340 | SwFlyFrameFormat* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rSet, | |||
341 | const SwSelBoxes* pSelBoxes, | |||
342 | SwFrameFormat *pParent ) | |||
343 | { | |||
344 | const SwFormatAnchor& rAnch = rSet.Get( RES_ANCHOR ); | |||
345 | ||||
346 | GetIDocumentUndoRedo().StartUndo( SwUndoId::INSLAYFMT, nullptr ); | |||
347 | ||||
348 | SwFlyFrameFormat* pFormat = MakeFlySection( rAnch.GetAnchorId(), rPam.GetPoint(), | |||
349 | &rSet, pParent ); | |||
350 | ||||
351 | // If content is selected, it becomes the new frame's content. | |||
352 | // Namely, it is moved into the NodeArray's appropriate section. | |||
353 | ||||
354 | if( pFormat ) | |||
355 | { | |||
356 | do { // middle check loop | |||
357 | const SwFormatContent &rContent = pFormat->GetContent(); | |||
358 | OSL_ENSURE( rContent.GetContentIdx(), "No content prepared." )do { if (true && (!(rContent.GetContentIdx()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "358" ": "), "%s", "No content prepared."); } } while (false ); | |||
359 | SwNodeIndex aIndex( *(rContent.GetContentIdx()), 1 ); | |||
360 | SwContentNode *pNode = aIndex.GetNode().GetContentNode(); | |||
361 | ||||
362 | // Attention: Do not create an index on the stack, or we | |||
363 | // cannot delete ContentNode in the end! | |||
364 | SwPosition aPos( aIndex ); | |||
365 | aPos.nContent.Assign( pNode, 0 ); | |||
366 | ||||
367 | if( pSelBoxes && !pSelBoxes->empty() ) | |||
368 | { | |||
369 | // Table selection | |||
370 | // Copy parts of a table: create a table with the same width as the | |||
371 | // original one and move (copy and delete) the selected boxes. | |||
372 | // The size is corrected on a percentage basis. | |||
373 | ||||
374 | SwTableNode* pTableNd = const_cast<SwTableNode*>((*pSelBoxes)[0]-> | |||
375 | GetSttNd()->FindTableNode()); | |||
376 | if( !pTableNd ) | |||
377 | break; | |||
378 | ||||
379 | SwTable& rTable = pTableNd->GetTable(); | |||
380 | ||||
381 | // Did we select the whole table? | |||
382 | if( pSelBoxes->size() == rTable.GetTabSortBoxes().size() ) | |||
383 | { | |||
384 | // move the whole table | |||
385 | SwNodeRange aRg( *pTableNd, 0, *pTableNd->EndOfSectionNode(), 1 ); | |||
386 | ||||
387 | // If we move the whole table and it is located within a | |||
388 | // FlyFrame, the we create a TextNode after it. | |||
389 | // So that this FlyFrame is preserved. | |||
390 | if( aRg.aEnd.GetNode().IsEndNode() ) | |||
391 | GetNodes().MakeTextNode( aRg.aStart, | |||
392 | GetDfltTextFormatColl() ); | |||
393 | ||||
394 | getIDocumentContentOperations().MoveNodeRange( aRg, aPos.nNode, SwMoveFlags::DEFAULT ); | |||
395 | } | |||
396 | else | |||
397 | { | |||
398 | rTable.MakeCopy(*this, aPos, *pSelBoxes); | |||
399 | // Don't delete a part of a table with row span!! | |||
400 | // You could delete the content instead -> ToDo | |||
401 | //rTable.DeleteSel( this, *pSelBoxes, 0, 0, true, true ); | |||
402 | } | |||
403 | ||||
404 | // If the table is within the frame, then copy without the following TextNode | |||
405 | aIndex = rContent.GetContentIdx()->GetNode().EndOfSectionIndex() - 1; | |||
406 | OSL_ENSURE( aIndex.GetNode().GetTextNode(),do { if (true && (!(aIndex.GetNode().GetTextNode()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "407" ": "), "%s", "a TextNode should be here"); } } while (false) | |||
407 | "a TextNode should be here" )do { if (true && (!(aIndex.GetNode().GetTextNode()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "407" ": "), "%s", "a TextNode should be here"); } } while (false); | |||
408 | aPos.nContent.Assign( nullptr, 0 ); // Deregister index! | |||
409 | GetNodes().Delete( aIndex ); | |||
410 | ||||
411 | // This is a hack: whilst FlyFrames/Headers/Footers are not undoable we delete all Undo objects | |||
412 | if( GetIDocumentUndoRedo().DoesUndo() ) | |||
413 | { | |||
414 | GetIDocumentUndoRedo().DelAllUndoObj(); | |||
415 | } | |||
416 | } | |||
417 | else | |||
418 | { | |||
419 | // copy all Pams and then delete all | |||
420 | bool bOldFlag = mbCopyIsMove; | |||
421 | bool const bOldUndo = GetIDocumentUndoRedo().DoesUndo(); | |||
422 | bool const bOldRedlineMove(getIDocumentRedlineAccess().IsRedlineMove()); | |||
423 | mbCopyIsMove = true; | |||
424 | GetIDocumentUndoRedo().DoUndo(false); | |||
425 | getIDocumentRedlineAccess().SetRedlineMove(true); | |||
426 | for(const SwPaM& rTmp : rPam.GetRingContainer()) | |||
427 | { | |||
428 | if( rTmp.HasMark() && | |||
429 | *rTmp.GetPoint() != *rTmp.GetMark() ) | |||
430 | { | |||
431 | // aPos is the newly created fly section, so definitely outside rPam, it's pointless to check that again. | |||
432 | getIDocumentContentOperations().CopyRange(*const_cast<SwPaM*>(&rTmp), aPos, SwCopyFlags::IsMoveToFly); | |||
433 | } | |||
434 | } | |||
435 | getIDocumentRedlineAccess().SetRedlineMove(bOldRedlineMove); | |||
436 | mbCopyIsMove = bOldFlag; | |||
437 | GetIDocumentUndoRedo().DoUndo(bOldUndo); | |||
438 | ||||
439 | for(const SwPaM& rTmp : rPam.GetRingContainer()) | |||
440 | { | |||
441 | if( rTmp.HasMark() && | |||
442 | *rTmp.GetPoint() != *rTmp.GetMark() ) | |||
443 | { | |||
444 | getIDocumentContentOperations().DeleteAndJoin( *const_cast<SwPaM*>(&rTmp) ); | |||
445 | } | |||
446 | } | |||
447 | } | |||
448 | } while( false ); | |||
449 | } | |||
450 | ||||
451 | getIDocumentState().SetModified(); | |||
452 | ||||
453 | GetIDocumentUndoRedo().EndUndo( SwUndoId::INSLAYFMT, nullptr ); | |||
454 | ||||
455 | return pFormat; | |||
456 | } | |||
457 | ||||
458 | ||||
459 | /* | |||
460 | * paragraph frames - o.k. if the PaM includes the paragraph from the beginning | |||
461 | * to the beginning of the next paragraph at least | |||
462 | * frames at character - o.k. if the PaM starts at least at the same position | |||
463 | * as the frame | |||
464 | */ | |||
465 | static bool lcl_TstFlyRange( const SwPaM* pPam, const SwPosition* pFlyPos, | |||
466 | RndStdIds nAnchorId ) | |||
467 | { | |||
468 | bool bOk = false; | |||
469 | const SwPaM* pTmp = pPam; | |||
470 | do { | |||
471 | const sal_uInt32 nFlyIndex = pFlyPos->nNode.GetIndex(); | |||
472 | const SwPosition* pPaMStart = pTmp->Start(); | |||
473 | const SwPosition* pPaMEnd = pTmp->End(); | |||
474 | const sal_uInt32 nPamStartIndex = pPaMStart->nNode.GetIndex(); | |||
475 | const sal_uInt32 nPamEndIndex = pPaMEnd->nNode.GetIndex(); | |||
476 | if (RndStdIds::FLY_AT_PARA == nAnchorId) | |||
477 | bOk = (nPamStartIndex < nFlyIndex && nPamEndIndex > nFlyIndex) || | |||
478 | (((nPamStartIndex == nFlyIndex) && (pPaMStart->nContent.GetIndex() == 0)) && | |||
479 | (nPamEndIndex > nFlyIndex)); | |||
480 | else | |||
481 | { | |||
482 | const sal_Int32 nFlyContentIndex = pFlyPos->nContent.GetIndex(); | |||
483 | const sal_Int32 nPamEndContentIndex = pPaMEnd->nContent.GetIndex(); | |||
484 | bOk = (nPamStartIndex < nFlyIndex && | |||
485 | (( nPamEndIndex > nFlyIndex )|| | |||
486 | ((nPamEndIndex == nFlyIndex) && | |||
487 | (nPamEndContentIndex > nFlyContentIndex))) ) | |||
488 | || | |||
489 | (((nPamStartIndex == nFlyIndex) && | |||
490 | (pPaMStart->nContent.GetIndex() <= nFlyContentIndex)) && | |||
491 | ((nPamEndIndex > nFlyIndex) || | |||
492 | (nPamEndContentIndex > nFlyContentIndex ))); | |||
493 | } | |||
494 | ||||
495 | if( bOk ) | |||
496 | break; | |||
497 | pTmp = pTmp->GetNext(); | |||
498 | } while( pPam != pTmp ); | |||
499 | return bOk; | |||
500 | } | |||
501 | ||||
502 | SwPosFlyFrames SwDoc::GetAllFlyFormats( const SwPaM* pCmpRange, bool bDrawAlso, | |||
503 | bool bAsCharAlso ) const | |||
504 | { | |||
505 | SwPosFlyFrames aRetval; | |||
506 | ||||
507 | // collect all anchored somehow to paragraphs | |||
508 | for( auto pFly : *GetSpzFrameFormats() ) | |||
509 | { | |||
510 | bool bDrawFormat = bDrawAlso && RES_DRAWFRMFMT == pFly->Which(); | |||
511 | bool bFlyFormat = RES_FLYFRMFMT == pFly->Which(); | |||
512 | if( bFlyFormat || bDrawFormat ) | |||
513 | { | |||
514 | const SwFormatAnchor& rAnchor = pFly->GetAnchor(); | |||
515 | SwPosition const*const pAPos = rAnchor.GetContentAnchor(); | |||
516 | if (pAPos && | |||
517 | ((RndStdIds::FLY_AT_PARA == rAnchor.GetAnchorId()) || | |||
518 | (RndStdIds::FLY_AT_FLY == rAnchor.GetAnchorId()) || | |||
519 | (RndStdIds::FLY_AT_CHAR == rAnchor.GetAnchorId()) || | |||
520 | ((RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) && bAsCharAlso))) | |||
521 | { | |||
522 | if( pCmpRange && | |||
523 | !lcl_TstFlyRange( pCmpRange, pAPos, rAnchor.GetAnchorId() )) | |||
524 | continue; // not a valid FlyFrame | |||
525 | aRetval.insert(std::make_shared<SwPosFlyFrame>(pAPos->nNode, pFly, aRetval.size())); | |||
526 | } | |||
527 | } | |||
528 | } | |||
529 | ||||
530 | // If we don't have a layout we can't get page anchored FlyFrames. | |||
531 | // Also, page anchored FlyFrames are only returned if no range is specified. | |||
532 | if( !getIDocumentLayoutAccess().GetCurrentViewShell() || pCmpRange ) | |||
| ||||
533 | { | |||
534 | return aRetval; | |||
535 | } | |||
536 | ||||
537 | const SwPageFrame *pPage = static_cast<const SwPageFrame*>(getIDocumentLayoutAccess().GetCurrentLayout()->GetLower()); | |||
538 | while( pPage ) | |||
539 | { | |||
540 | if( pPage->GetSortedObjs() ) | |||
541 | { | |||
542 | const SwSortedObjs &rObjs = *pPage->GetSortedObjs(); | |||
543 | for(SwAnchoredObject* pAnchoredObj : rObjs) | |||
544 | { | |||
545 | SwFrameFormat *pFly; | |||
546 | if ( dynamic_cast<const SwFlyFrame*>( pAnchoredObj) != nullptr ) | |||
547 | pFly = &(pAnchoredObj->GetFrameFormat()); | |||
548 | else if ( bDrawAlso ) | |||
549 | pFly = &(pAnchoredObj->GetFrameFormat()); | |||
| ||||
550 | else | |||
551 | continue; | |||
552 | ||||
553 | const SwFormatAnchor& rAnchor = pFly->GetAnchor(); | |||
554 | if ((RndStdIds::FLY_AT_PARA != rAnchor.GetAnchorId()) && | |||
555 | (RndStdIds::FLY_AT_FLY != rAnchor.GetAnchorId()) && | |||
556 | (RndStdIds::FLY_AT_CHAR != rAnchor.GetAnchorId())) | |||
557 | { | |||
558 | const SwContentFrame * pContentFrame = pPage->FindFirstBodyContent(); | |||
559 | if ( !pContentFrame ) | |||
560 | { | |||
561 | // Oops! An empty page. | |||
562 | // In order not to lose the whole frame (RTF) we | |||
563 | // look for the last Content before the page. | |||
564 | const SwPageFrame *pPrv = static_cast<const SwPageFrame*>(pPage->GetPrev()); | |||
565 | while ( !pContentFrame && pPrv ) | |||
566 | { | |||
567 | pContentFrame = pPrv->FindFirstBodyContent(); | |||
568 | pPrv = static_cast<const SwPageFrame*>(pPrv->GetPrev()); | |||
569 | } | |||
570 | } | |||
571 | if ( pContentFrame ) | |||
572 | { | |||
573 | SwNodeIndex aIdx( pContentFrame->IsTextFrame() | |||
574 | ? *static_cast<SwTextFrame const*>(pContentFrame)->GetTextNodeFirst() | |||
575 | : *static_cast<SwNoTextFrame const*>(pContentFrame)->GetNode() ); | |||
576 | aRetval.insert(std::make_shared<SwPosFlyFrame>(aIdx, pFly, aRetval.size())); | |||
577 | } | |||
578 | } | |||
579 | } | |||
580 | } | |||
581 | pPage = static_cast<const SwPageFrame*>(pPage->GetNext()); | |||
582 | } | |||
583 | ||||
584 | return aRetval; | |||
585 | } | |||
586 | ||||
587 | /* #i6447# changed behaviour if lcl_CpyAttr: | |||
588 | ||||
589 | If the old item set contains the item to set (no inheritance) copy the item | |||
590 | into the new set. | |||
591 | ||||
592 | If the old item set contains the item by inheritance and the new set | |||
593 | contains the item, too: | |||
594 | If the two items differ copy the item from the old set to the new set. | |||
595 | ||||
596 | Otherwise the new set will not be changed. | |||
597 | */ | |||
598 | static void lcl_CpyAttr( SfxItemSet &rNewSet, const SfxItemSet &rOldSet, sal_uInt16 nWhich ) | |||
599 | { | |||
600 | const SfxPoolItem *pOldItem = nullptr; | |||
601 | ||||
602 | rOldSet.GetItemState( nWhich, false, &pOldItem); | |||
603 | if (pOldItem != nullptr) | |||
604 | rNewSet.Put( *pOldItem ); | |||
605 | else | |||
606 | { | |||
607 | pOldItem = rOldSet.GetItem( nWhich ); | |||
608 | if (pOldItem != nullptr) | |||
609 | { | |||
610 | const SfxPoolItem *pNewItem = rNewSet.GetItem( nWhich ); | |||
611 | if (pNewItem != nullptr) | |||
612 | { | |||
613 | if (*pOldItem != *pNewItem) | |||
614 | rNewSet.Put( *pOldItem ); | |||
615 | } | |||
616 | else { | |||
617 | OSL_FAIL("What am I doing here?")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "617" ": "), "%s", "What am I doing here?"); } } while ( false); | |||
618 | } | |||
619 | } | |||
620 | else { | |||
621 | OSL_FAIL("What am I doing here?")do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "621" ": "), "%s", "What am I doing here?"); } } while ( false); | |||
622 | } | |||
623 | } | |||
624 | ||||
625 | } | |||
626 | ||||
627 | static SwFlyFrameFormat * | |||
628 | lcl_InsertLabel(SwDoc & rDoc, SwTextFormatColls *const pTextFormatCollTable, | |||
629 | SwUndoInsertLabel *const pUndo, | |||
630 | SwLabelType const eType, OUString const& rText, OUString const& rSeparator, | |||
631 | const OUString& rNumberingSeparator, | |||
632 | const bool bBefore, const sal_uInt16 nId, const sal_uLong nNdIdx, | |||
633 | const OUString& rCharacterStyle, | |||
634 | const bool bCpyBrd ) | |||
635 | { | |||
636 | ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo()); | |||
637 | ||||
638 | bool bTable = false; // To save some code. | |||
639 | ||||
640 | // Get the field first, because we retrieve the TextColl via the field's name | |||
641 | OSL_ENSURE( nId == USHRT_MAX || nId < rDoc.getIDocumentFieldsAccess().GetFieldTypes()->size(),do { if (true && (!(nId == (32767 *2 +1) || nId < rDoc .getIDocumentFieldsAccess().GetFieldTypes()->size()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "642" ": "), "%s", "FieldType index out of bounds."); } } while (false) | |||
642 | "FieldType index out of bounds." )do { if (true && (!(nId == (32767 *2 +1) || nId < rDoc .getIDocumentFieldsAccess().GetFieldTypes()->size()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "642" ": "), "%s", "FieldType index out of bounds."); } } while (false); | |||
643 | SwFieldType *pType = (nId != USHRT_MAX(32767 *2 +1)) ? (*rDoc.getIDocumentFieldsAccess().GetFieldTypes())[nId].get() : nullptr; | |||
644 | OSL_ENSURE(!pType || pType->Which() == SwFieldIds::SetExp, "wrong Id for Label")do { if (true && (!(!pType || pType->Which() == SwFieldIds ::SetExp))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "644" ": "), "%s", "wrong Id for Label"); } } while (false ); | |||
645 | ||||
646 | SwTextFormatColl * pColl = nullptr; | |||
647 | if( pType ) | |||
648 | { | |||
649 | for( auto i = pTextFormatCollTable->size(); i; ) | |||
650 | { | |||
651 | if( (*pTextFormatCollTable)[ --i ]->GetName()==pType->GetName() ) | |||
652 | { | |||
653 | pColl = (*pTextFormatCollTable)[i]; | |||
654 | break; | |||
655 | } | |||
656 | } | |||
657 | OSL_ENSURE( pColl, "no text collection found" )do { if (true && (!(pColl))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "657" ": "), "%s", "no text collection found"); } } while (false); | |||
658 | } | |||
659 | ||||
660 | if( !pColl ) | |||
661 | { | |||
662 | pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_LABEL ); | |||
663 | } | |||
664 | ||||
665 | SwTextNode *pNew = nullptr; | |||
666 | SwFlyFrameFormat* pNewFormat = nullptr; | |||
667 | ||||
668 | switch ( eType ) | |||
669 | { | |||
670 | case SwLabelType::Table: | |||
671 | bTable = true; | |||
672 | [[fallthrough]]; | |||
673 | case SwLabelType::Fly: | |||
674 | // At the FlySection's Beginning/End insert the corresponding Node with its Field. | |||
675 | // The Frame is created automatically. | |||
676 | { | |||
677 | SwStartNode *pSttNd = rDoc.GetNodes()[nNdIdx]->GetStartNode(); | |||
678 | OSL_ENSURE( pSttNd, "No StartNode in InsertLabel." )do { if (true && (!(pSttNd))) { sal_detail_logFormat( (SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "678" ": "), "%s", "No StartNode in InsertLabel."); } } while (false); | |||
679 | sal_uLong nNode; | |||
680 | if( bBefore ) | |||
681 | { | |||
682 | nNode = pSttNd->GetIndex(); | |||
683 | if( !bTable ) | |||
684 | ++nNode; | |||
685 | } | |||
686 | else | |||
687 | { | |||
688 | nNode = pSttNd->EndOfSectionIndex(); | |||
689 | if( bTable ) | |||
690 | ++nNode; | |||
691 | } | |||
692 | ||||
693 | if( pUndo ) | |||
694 | pUndo->SetNodePos( nNode ); | |||
695 | ||||
696 | // Create Node for labeling paragraph. | |||
697 | SwNodeIndex aIdx( rDoc.GetNodes(), nNode ); | |||
698 | pNew = rDoc.GetNodes().MakeTextNode( aIdx, pColl ); | |||
699 | } | |||
700 | break; | |||
701 | ||||
702 | case SwLabelType::Object: | |||
703 | { | |||
704 | // Destroy Frame, | |||
705 | // insert new Frame, | |||
706 | // insert the corresponding Node with Field into the new Frame, | |||
707 | // insert the old Frame with the Object (Picture/OLE) paragraph-bound into the new Frame, | |||
708 | // create Frames. | |||
709 | ||||
710 | // Get the FlyFrame's Format and decouple the Layout. | |||
711 | SwFrameFormat *pOldFormat = rDoc.GetNodes()[nNdIdx]->GetFlyFormat(); | |||
712 | OSL_ENSURE( pOldFormat, "Couldn't find the Fly's Format." )do { if (true && (!(pOldFormat))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "712" ": "), "%s", "Couldn't find the Fly's Format."); } } while (false); | |||
713 | // #i115719# | |||
714 | // <title> and <description> attributes are lost when calling <DelFrames()>. | |||
715 | // Thus, keep them and restore them after the calling <MakeFrames()> | |||
716 | const bool bIsSwFlyFrameFormatInstance( dynamic_cast<SwFlyFrameFormat*>(pOldFormat) != nullptr ); | |||
717 | const OUString sTitle( bIsSwFlyFrameFormatInstance | |||
718 | ? static_cast<SwFlyFrameFormat*>(pOldFormat)->GetObjTitle() | |||
719 | : OUString() ); | |||
720 | const OUString sDescription( bIsSwFlyFrameFormatInstance | |||
721 | ? static_cast<SwFlyFrameFormat*>(pOldFormat)->GetObjDescription() | |||
722 | : OUString() ); | |||
723 | pOldFormat->DelFrames(); | |||
724 | ||||
725 | pNewFormat = rDoc.MakeFlyFrameFormat( rDoc.GetUniqueFrameName(), | |||
726 | rDoc.getIDocumentStylePoolAccess().GetFrameFormatFromPool(RES_POOLFRM_FRAME) ); | |||
727 | ||||
728 | /* #i6447#: Only the selected items are copied from the old | |||
729 | format. */ | |||
730 | std::unique_ptr<SfxItemSet> pNewSet = pNewFormat->GetAttrSet().Clone(); | |||
731 | ||||
732 | // Copy only the set attributes. | |||
733 | // The others should apply from the Templates. | |||
734 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_PRINT ); | |||
735 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_OPAQUE ); | |||
736 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_PROTECT ); | |||
737 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_SURROUND ); | |||
738 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_VERT_ORIENT ); | |||
739 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_HORI_ORIENT ); | |||
740 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_LR_SPACE ); | |||
741 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_UL_SPACE ); | |||
742 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_BACKGROUND ); | |||
743 | if( bCpyBrd ) | |||
744 | { | |||
745 | // If there's no BoxItem at graphic, but the new Format has one, then set the | |||
746 | // default item in the new Set. Because the graphic's size has never changed! | |||
747 | const SfxPoolItem *pItem; | |||
748 | if( SfxItemState::SET == pOldFormat->GetAttrSet(). | |||
749 | GetItemState( RES_BOX, true, &pItem )) | |||
750 | pNewSet->Put( *pItem ); | |||
751 | else if( SfxItemState::SET == pNewFormat->GetAttrSet(). | |||
752 | GetItemState( RES_BOX )) | |||
753 | pNewSet->Put( *GetDfltAttr( RES_BOX ) ); | |||
754 | ||||
755 | if( SfxItemState::SET == pOldFormat->GetAttrSet(). | |||
756 | GetItemState( RES_SHADOW, true, &pItem )) | |||
757 | pNewSet->Put( *pItem ); | |||
758 | else if( SfxItemState::SET == pNewFormat->GetAttrSet(). | |||
759 | GetItemState( RES_SHADOW )) | |||
760 | pNewSet->Put( *GetDfltAttr( RES_SHADOW ) ); | |||
761 | } | |||
762 | else | |||
763 | { | |||
764 | // Hard-set the attributes, because they could come from the Template | |||
765 | // and then size calculations could not be correct anymore. | |||
766 | pNewSet->Put( SvxBoxItem(RES_BOX) ); | |||
767 | pNewSet->Put( SvxShadowItem(RES_SHADOW) ); | |||
768 | } | |||
769 | ||||
770 | // Always transfer the anchor, which is a hard attribute anyways. | |||
771 | pNewSet->Put( pOldFormat->GetAnchor() ); | |||
772 | ||||
773 | // The new one should be changeable in its height. | |||
774 | std::unique_ptr<SwFormatFrameSize> aFrameSize(pOldFormat->GetFrameSize().Clone()); | |||
775 | aFrameSize->SetHeightSizeType( SwFrameSize::Minimum ); | |||
776 | pNewSet->Put( std::move(aFrameSize) ); | |||
777 | ||||
778 | SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection( | |||
779 | SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ), | |||
780 | SwFlyStartNode, pColl ); | |||
781 | pNewSet->Put( SwFormatContent( pSttNd )); | |||
782 | ||||
783 | pNewFormat->SetFormatAttr( *pNewSet ); | |||
784 | ||||
785 | // InContents need to be treated in a special way: | |||
786 | // The TextAttribute needs to be destroyed. | |||
787 | // Unfortunately, this also destroys the Format next to the Frames. | |||
788 | // To avoid this, we disconnect the attribute from the Format. | |||
789 | ||||
790 | const SwFormatAnchor& rAnchor = pNewFormat->GetAnchor(); | |||
791 | if ( RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId() ) | |||
792 | { | |||
793 | const SwPosition *pPos = rAnchor.GetContentAnchor(); | |||
794 | SwTextNode *pTextNode = pPos->nNode.GetNode().GetTextNode(); | |||
795 | OSL_ENSURE( pTextNode->HasHints(), "Missing FlyInCnt-Hint." )do { if (true && (!(pTextNode->HasHints()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "795" ": "), "%s", "Missing FlyInCnt-Hint."); } } while ( false); | |||
796 | const sal_Int32 nIdx = pPos->nContent.GetIndex(); | |||
797 | SwTextAttr * const pHint = | |||
798 | pTextNode->GetTextAttrForCharAt(nIdx, RES_TXTATR_FLYCNT); | |||
799 | ||||
800 | assert(pHint && "Missing Hint.")(static_cast <bool> (pHint && "Missing Hint.") ? void (0) : __assert_fail ("pHint && \"Missing Hint.\"" , "/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" , 800, __extension__ __PRETTY_FUNCTION__)); | |||
801 | ||||
802 | OSL_ENSURE( pHint->Which() == RES_TXTATR_FLYCNT,do { if (true && (!(pHint->Which() == RES_TXTATR_FLYCNT ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "803" ": "), "%s", "Missing FlyInCnt-Hint."); } } while ( false) | |||
803 | "Missing FlyInCnt-Hint." )do { if (true && (!(pHint->Which() == RES_TXTATR_FLYCNT ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "803" ": "), "%s", "Missing FlyInCnt-Hint."); } } while ( false); | |||
804 | OSL_ENSURE( pHint->GetFlyCnt().GetFrameFormat() == pOldFormat,do { if (true && (!(pHint->GetFlyCnt().GetFrameFormat () == pOldFormat))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "805" ": "), "%s", "Wrong TextFlyCnt-Hint."); } } while ( false) | |||
805 | "Wrong TextFlyCnt-Hint." )do { if (true && (!(pHint->GetFlyCnt().GetFrameFormat () == pOldFormat))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "805" ": "), "%s", "Wrong TextFlyCnt-Hint."); } } while ( false); | |||
806 | ||||
807 | const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt()).SetFlyFormat( | |||
808 | pNewFormat ); | |||
809 | } | |||
810 | ||||
811 | // The old one should not have a flow and it should be adjusted to above and | |||
812 | // middle. | |||
813 | // Also, the width should be 100% and it should also adjust the height, if changed. | |||
814 | pNewSet->ClearItem(); | |||
815 | ||||
816 | pNewSet->Put( SwFormatSurround( css::text::WrapTextMode_NONE ) ); | |||
817 | pNewSet->Put( SvxOpaqueItem( RES_OPAQUE, true ) ); | |||
818 | ||||
819 | sal_Int16 eVert = bBefore ? text::VertOrientation::BOTTOM : text::VertOrientation::TOP; | |||
820 | pNewSet->Put( SwFormatVertOrient( 0, eVert ) ); | |||
821 | pNewSet->Put( SwFormatHoriOrient( 0, text::HoriOrientation::CENTER ) ); | |||
822 | ||||
823 | aFrameSize.reset(pOldFormat->GetFrameSize().Clone()); | |||
824 | ||||
825 | SwOLENode* pOleNode = rDoc.GetNodes()[nNdIdx + 1]->GetOLENode(); | |||
826 | bool isMath = false; | |||
827 | if(pOleNode) | |||
828 | { | |||
829 | svt::EmbeddedObjectRef& xRef = pOleNode->GetOLEObj().GetObject(); | |||
830 | if(xRef.is()) | |||
831 | { | |||
832 | SvGlobalName aCLSID( xRef->getClassID() ); | |||
833 | isMath = ( SotExchange::IsMath( aCLSID ) != 0 ); | |||
834 | } | |||
835 | } | |||
836 | aFrameSize->SetWidthPercent(isMath ? 0 : 100); | |||
837 | aFrameSize->SetHeightPercent(SwFormatFrameSize::SYNCED); | |||
838 | pNewSet->Put( std::move(aFrameSize) ); | |||
839 | ||||
840 | // Hard-set the attributes, because they could come from the Template | |||
841 | // and then size calculations could not be correct anymore. | |||
842 | if( bCpyBrd ) | |||
843 | { | |||
844 | pNewSet->Put( SvxBoxItem(RES_BOX) ); | |||
845 | pNewSet->Put( SvxShadowItem(RES_SHADOW) ); | |||
846 | } | |||
847 | pNewSet->Put( SvxLRSpaceItem(RES_LR_SPACE) ); | |||
848 | pNewSet->Put( SvxULSpaceItem(RES_UL_SPACE) ); | |||
849 | ||||
850 | // The old one is paragraph-bound to the paragraph in the new one. | |||
851 | SwFormatAnchor aAnch( RndStdIds::FLY_AT_PARA ); | |||
852 | SwNodeIndex aAnchIdx( *pNewFormat->GetContent().GetContentIdx(), 1 ); | |||
853 | pNew = aAnchIdx.GetNode().GetTextNode(); | |||
854 | SwPosition aPos( aAnchIdx ); | |||
855 | aAnch.SetAnchor( &aPos ); | |||
856 | pNewSet->Put( aAnch ); | |||
857 | ||||
858 | if( pUndo ) | |||
859 | pUndo->SetFlys( *pOldFormat, *pNewSet, *pNewFormat ); | |||
860 | else | |||
861 | pOldFormat->SetFormatAttr( *pNewSet ); | |||
862 | ||||
863 | pNewSet.reset(); | |||
864 | ||||
865 | // Have only the FlyFrames created. | |||
866 | // We leave this to established methods (especially for InCntFlys). | |||
867 | pNewFormat->MakeFrames(); | |||
868 | // #i115719# | |||
869 | if ( bIsSwFlyFrameFormatInstance ) | |||
870 | { | |||
871 | static_cast<SwFlyFrameFormat*>(pOldFormat)->SetObjTitle( sTitle ); | |||
872 | static_cast<SwFlyFrameFormat*>(pOldFormat)->SetObjDescription( sDescription ); | |||
873 | } | |||
874 | } | |||
875 | break; | |||
876 | ||||
877 | default: | |||
878 | OSL_ENSURE(false, "unknown LabelType?")do { if (true && (!(false))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "878" ": "), "%s", "unknown LabelType?"); } } while (false ); | |||
879 | } | |||
880 | OSL_ENSURE( pNew, "No Label inserted" )do { if (true && (!(pNew))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "880" ": "), "%s", "No Label inserted"); } } while (false ); | |||
881 | if( pNew ) | |||
882 | { | |||
883 | // #i61007# order of captions | |||
884 | bool bOrderNumberingFirst = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetModuleConfig()->IsCaptionOrderNumberingFirst(); | |||
885 | // Work up OUString | |||
886 | OUString aText; | |||
887 | if( bOrderNumberingFirst ) | |||
888 | { | |||
889 | aText = rNumberingSeparator; | |||
890 | } | |||
891 | if( pType) | |||
892 | { | |||
893 | aText += pType->GetName(); | |||
894 | if( !bOrderNumberingFirst ) | |||
895 | aText += " "; | |||
896 | } | |||
897 | sal_Int32 nIdx = aText.getLength(); | |||
898 | if( !rText.isEmpty() ) | |||
899 | { | |||
900 | aText += rSeparator; | |||
901 | } | |||
902 | const sal_Int32 nSepIdx = aText.getLength(); | |||
903 | aText += rText; | |||
904 | ||||
905 | // Insert string | |||
906 | SwIndex aIdx( pNew, 0 ); | |||
907 | pNew->InsertText( aText, aIdx ); | |||
908 | ||||
909 | // Insert field | |||
910 | if(pType) | |||
911 | { | |||
912 | SwSetExpField aField( static_cast<SwSetExpFieldType*>(pType), OUString(), SVX_NUM_ARABIC); | |||
913 | if( bOrderNumberingFirst ) | |||
914 | nIdx = 0; | |||
915 | SwFormatField aFormat( aField ); | |||
916 | pNew->InsertItem( aFormat, nIdx, nIdx ); | |||
917 | if(!rCharacterStyle.isEmpty()) | |||
918 | { | |||
919 | SwCharFormat* pCharFormat = rDoc.FindCharFormatByName(rCharacterStyle); | |||
920 | if( !pCharFormat ) | |||
921 | { | |||
922 | const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName(rCharacterStyle, SwGetPoolIdFromName::ChrFmt); | |||
923 | pCharFormat = rDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool( nMyId ); | |||
924 | } | |||
925 | if (pCharFormat) | |||
926 | { | |||
927 | SwFormatCharFormat aCharFormat( pCharFormat ); | |||
928 | pNew->InsertItem( aCharFormat, 0, | |||
929 | nSepIdx + 1, SetAttrMode::DONTEXPAND ); | |||
930 | } | |||
931 | } | |||
932 | } | |||
933 | ||||
934 | if ( bTable ) | |||
935 | { | |||
936 | if ( bBefore ) | |||
937 | { | |||
938 | if ( !pNew->GetSwAttrSet().GetKeep().GetValue() ) | |||
939 | pNew->SetAttr( SvxFormatKeepItem( true, RES_KEEP ) ); | |||
940 | } | |||
941 | else | |||
942 | { | |||
943 | SwTableNode *const pNd = | |||
944 | rDoc.GetNodes()[nNdIdx]->GetStartNode()->GetTableNode(); | |||
945 | SwTable &rTable = pNd->GetTable(); | |||
946 | if ( !rTable.GetFrameFormat()->GetKeep().GetValue() ) | |||
947 | rTable.GetFrameFormat()->SetFormatAttr( SvxFormatKeepItem( true, RES_KEEP ) ); | |||
948 | if ( pUndo ) | |||
949 | pUndo->SetUndoKeep(); | |||
950 | } | |||
951 | } | |||
952 | rDoc.getIDocumentState().SetModified(); | |||
953 | } | |||
954 | ||||
955 | return pNewFormat; | |||
956 | } | |||
957 | ||||
958 | SwFlyFrameFormat * | |||
959 | SwDoc::InsertLabel( | |||
960 | SwLabelType const eType, OUString const& rText, OUString const& rSeparator, | |||
961 | OUString const& rNumberingSeparator, | |||
962 | bool const bBefore, sal_uInt16 const nId, sal_uLong const nNdIdx, | |||
963 | OUString const& rCharacterStyle, | |||
964 | bool const bCpyBrd ) | |||
965 | { | |||
966 | std::unique_ptr<SwUndoInsertLabel> pUndo; | |||
967 | if (GetIDocumentUndoRedo().DoesUndo()) | |||
968 | { | |||
969 | pUndo.reset(new SwUndoInsertLabel( | |||
970 | eType, rText, rSeparator, rNumberingSeparator, | |||
971 | bBefore, nId, rCharacterStyle, bCpyBrd, this )); | |||
972 | } | |||
973 | ||||
974 | SwFlyFrameFormat *const pNewFormat = lcl_InsertLabel(*this, mpTextFormatCollTable.get(), pUndo.get(), | |||
975 | eType, rText, rSeparator, rNumberingSeparator, bBefore, | |||
976 | nId, nNdIdx, rCharacterStyle, bCpyBrd); | |||
977 | ||||
978 | if (pUndo) | |||
979 | { | |||
980 | GetIDocumentUndoRedo().AppendUndo(std::move(pUndo)); | |||
981 | } | |||
982 | else | |||
983 | { | |||
984 | GetIDocumentUndoRedo().DelAllUndoObj(); | |||
985 | } | |||
986 | ||||
987 | return pNewFormat; | |||
988 | } | |||
989 | ||||
990 | static SwFlyFrameFormat * | |||
991 | lcl_InsertDrawLabel( SwDoc & rDoc, SwTextFormatColls *const pTextFormatCollTable, | |||
992 | SwUndoInsertLabel *const pUndo, SwDrawFrameFormat *const pOldFormat, | |||
993 | OUString const& rText, | |||
994 | const OUString& rSeparator, | |||
995 | const OUString& rNumberSeparator, | |||
996 | const sal_uInt16 nId, | |||
997 | const OUString& rCharacterStyle, | |||
998 | SdrObject& rSdrObj ) | |||
999 | { | |||
1000 | ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo()); | |||
1001 | ::sw::DrawUndoGuard const drawUndoGuard(rDoc.GetIDocumentUndoRedo()); | |||
1002 | ||||
1003 | // Because we get by the TextColl's name, we need to create the field first. | |||
1004 | OSL_ENSURE( nId == USHRT_MAX || nId < rDoc.getIDocumentFieldsAccess().GetFieldTypes()->size(),do { if (true && (!(nId == (32767 *2 +1) || nId < rDoc .getIDocumentFieldsAccess().GetFieldTypes()->size()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1005" ": "), "%s", "FieldType index out of bounds"); } } while (false) | |||
1005 | "FieldType index out of bounds" )do { if (true && (!(nId == (32767 *2 +1) || nId < rDoc .getIDocumentFieldsAccess().GetFieldTypes()->size()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1005" ": "), "%s", "FieldType index out of bounds"); } } while (false); | |||
1006 | SwFieldType *pType = nId != USHRT_MAX(32767 *2 +1) ? (*rDoc.getIDocumentFieldsAccess().GetFieldTypes())[nId].get() : nullptr; | |||
1007 | OSL_ENSURE( !pType || pType->Which() == SwFieldIds::SetExp, "Wrong label id" )do { if (true && (!(!pType || pType->Which() == SwFieldIds ::SetExp))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1007" ": "), "%s", "Wrong label id"); } } while (false); | |||
1008 | ||||
1009 | SwTextFormatColl *pColl = nullptr; | |||
1010 | if( pType ) | |||
1011 | { | |||
1012 | for( auto i = pTextFormatCollTable->size(); i; ) | |||
1013 | { | |||
1014 | if( (*pTextFormatCollTable)[ --i ]->GetName()==pType->GetName() ) | |||
1015 | { | |||
1016 | pColl = (*pTextFormatCollTable)[i]; | |||
1017 | break; | |||
1018 | } | |||
1019 | } | |||
1020 | OSL_ENSURE( pColl, "no text collection found" )do { if (true && (!(pColl))) { sal_detail_logFormat(( SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1020" ": "), "%s", "no text collection found"); } } while (false); | |||
1021 | } | |||
1022 | ||||
1023 | if( !pColl ) | |||
1024 | { | |||
1025 | pColl = rDoc.getIDocumentStylePoolAccess().GetTextCollFromPool( RES_POOLCOLL_LABEL ); | |||
1026 | } | |||
1027 | ||||
1028 | SwTextNode* pNew = nullptr; | |||
1029 | SwFlyFrameFormat* pNewFormat = nullptr; | |||
1030 | ||||
1031 | // Destroy Frame, | |||
1032 | // insert new Frame, | |||
1033 | // insert the corresponding Node with Field into the new Frame, | |||
1034 | // insert the old Frame with the Object (Picture/OLE) paragraph-bound into the new Frame, | |||
1035 | // create Frames. | |||
1036 | ||||
1037 | // Keep layer ID of drawing object before removing | |||
1038 | // its frames. | |||
1039 | // Note: The layer ID is passed to the undo and have to be the correct value. | |||
1040 | // Removing the frames of the drawing object changes its layer. | |||
1041 | const SdrLayerID nLayerId = rSdrObj.GetLayer(); | |||
1042 | ||||
1043 | pOldFormat->DelFrames(); | |||
1044 | ||||
1045 | // InContents need to be treated in a special way: | |||
1046 | // The TextAttribute needs to be destroyed. | |||
1047 | // Unfortunately, this also destroys the Format next to the Frames. | |||
1048 | // To avoid this, we disconnect the attribute from the Format. | |||
1049 | std::unique_ptr<SfxItemSet> pNewSet = pOldFormat->GetAttrSet().Clone( false ); | |||
1050 | ||||
1051 | // Protect the Frame's size and position | |||
1052 | if ( rSdrObj.IsMoveProtect() || rSdrObj.IsResizeProtect() ) | |||
1053 | { | |||
1054 | SvxProtectItem aProtect(RES_PROTECT); | |||
1055 | aProtect.SetContentProtect( false ); | |||
1056 | aProtect.SetPosProtect( rSdrObj.IsMoveProtect() ); | |||
1057 | aProtect.SetSizeProtect( rSdrObj.IsResizeProtect() ); | |||
1058 | pNewSet->Put( aProtect ); | |||
1059 | } | |||
1060 | ||||
1061 | // Take over the text wrap | |||
1062 | lcl_CpyAttr( *pNewSet, pOldFormat->GetAttrSet(), RES_SURROUND ); | |||
1063 | ||||
1064 | // Send the frame to the back, if needed. | |||
1065 | // Consider the 'invisible' hell layer. | |||
1066 | if ( rDoc.getIDocumentDrawModelAccess().GetHellId() != nLayerId && | |||
1067 | rDoc.getIDocumentDrawModelAccess().GetInvisibleHellId() != nLayerId ) | |||
1068 | { | |||
1069 | SvxOpaqueItem aOpaque( RES_OPAQUE ); | |||
1070 | aOpaque.SetValue( true ); | |||
1071 | pNewSet->Put( aOpaque ); | |||
1072 | } | |||
1073 | ||||
1074 | // Take over position | |||
1075 | // #i26791# - use directly drawing object's positioning attributes | |||
1076 | pNewSet->Put( pOldFormat->GetHoriOrient() ); | |||
1077 | pNewSet->Put( pOldFormat->GetVertOrient() ); | |||
1078 | ||||
1079 | pNewSet->Put( pOldFormat->GetAnchor() ); | |||
1080 | ||||
1081 | // The new one should be variable in its height! | |||
1082 | Size aSz( rSdrObj.GetCurrentBoundRect().GetSize() ); | |||
1083 | SwFormatFrameSize aFrameSize( SwFrameSize::Minimum, aSz.Width(), aSz.Height() ); | |||
1084 | pNewSet->Put( aFrameSize ); | |||
1085 | ||||
1086 | // Apply the margin to the new Frame. | |||
1087 | // Don't set a border, use the one from the Template. | |||
1088 | pNewSet->Put( pOldFormat->GetLRSpace() ); | |||
1089 | pNewSet->Put( pOldFormat->GetULSpace() ); | |||
1090 | ||||
1091 | SwStartNode* pSttNd = | |||
1092 | rDoc.GetNodes().MakeTextSection( | |||
1093 | SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ), | |||
1094 | SwFlyStartNode, pColl ); | |||
1095 | ||||
1096 | pNewFormat = rDoc.MakeFlyFrameFormat( rDoc.GetUniqueFrameName(), | |||
1097 | rDoc.getIDocumentStylePoolAccess().GetFrameFormatFromPool( RES_POOLFRM_FRAME ) ); | |||
1098 | ||||
1099 | // Set border and shadow to default if the template contains any. | |||
1100 | if( SfxItemState::SET == pNewFormat->GetAttrSet().GetItemState( RES_BOX )) | |||
1101 | pNewSet->Put( *GetDfltAttr( RES_BOX ) ); | |||
1102 | ||||
1103 | if( SfxItemState::SET == pNewFormat->GetAttrSet().GetItemState(RES_SHADOW)) | |||
1104 | pNewSet->Put( *GetDfltAttr( RES_SHADOW ) ); | |||
1105 | ||||
1106 | pNewFormat->SetFormatAttr( SwFormatContent( pSttNd )); | |||
1107 | pNewFormat->SetFormatAttr( *pNewSet ); | |||
1108 | ||||
1109 | const SwFormatAnchor& rAnchor = pNewFormat->GetAnchor(); | |||
1110 | if ( RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId() ) | |||
1111 | { | |||
1112 | const SwPosition *pPos = rAnchor.GetContentAnchor(); | |||
1113 | SwTextNode *pTextNode = pPos->nNode.GetNode().GetTextNode(); | |||
1114 | OSL_ENSURE( pTextNode->HasHints(), "Missing FlyInCnt-Hint." )do { if (true && (!(pTextNode->HasHints()))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1114" ": "), "%s", "Missing FlyInCnt-Hint."); } } while (false); | |||
1115 | const sal_Int32 nIdx = pPos->nContent.GetIndex(); | |||
1116 | SwTextAttr * const pHint = | |||
1117 | pTextNode->GetTextAttrForCharAt( nIdx, RES_TXTATR_FLYCNT ); | |||
1118 | ||||
1119 | assert(pHint && "Missing Hint.")(static_cast <bool> (pHint && "Missing Hint.") ? void (0) : __assert_fail ("pHint && \"Missing Hint.\"" , "/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" , 1119, __extension__ __PRETTY_FUNCTION__)); | |||
1120 | ||||
1121 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1122 | OSL_ENSURE( pHint->Which() == RES_TXTATR_FLYCNT,do { if (true && (!(pHint->Which() == RES_TXTATR_FLYCNT ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1123" ": "), "%s", "Missing FlyInCnt-Hint."); } } while (false) | |||
1123 | "Missing FlyInCnt-Hint." )do { if (true && (!(pHint->Which() == RES_TXTATR_FLYCNT ))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl" ), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1123" ": "), "%s", "Missing FlyInCnt-Hint."); } } while (false); | |||
1124 | OSL_ENSURE( pHint->GetFlyCnt().do { if (true && (!(pHint->GetFlyCnt(). GetFrameFormat () == static_cast<SwFrameFormat*>(pOldFormat)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1126" ": "), "%s", "Wrong TextFlyCnt-Hint."); } } while (false) | |||
1125 | GetFrameFormat() == static_cast<SwFrameFormat*>(pOldFormat),do { if (true && (!(pHint->GetFlyCnt(). GetFrameFormat () == static_cast<SwFrameFormat*>(pOldFormat)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1126" ": "), "%s", "Wrong TextFlyCnt-Hint."); } } while (false) | |||
1126 | "Wrong TextFlyCnt-Hint." )do { if (true && (!(pHint->GetFlyCnt(). GetFrameFormat () == static_cast<SwFrameFormat*>(pOldFormat)))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1126" ": "), "%s", "Wrong TextFlyCnt-Hint."); } } while (false); | |||
1127 | #endif | |||
1128 | const_cast<SwFormatFlyCnt&>(pHint->GetFlyCnt()).SetFlyFormat( pNewFormat ); | |||
1129 | } | |||
1130 | ||||
1131 | // The old one should not have a flow | |||
1132 | // and it should be adjusted to above and middle. | |||
1133 | pNewSet->ClearItem(); | |||
1134 | ||||
1135 | pNewSet->Put( SwFormatSurround( css::text::WrapTextMode_NONE ) ); | |||
1136 | if (nLayerId == rDoc.getIDocumentDrawModelAccess().GetHellId()) | |||
1137 | { | |||
1138 | // Consider drawing objects in the 'invisible' hell layer | |||
1139 | rSdrObj.SetLayer( rDoc.getIDocumentDrawModelAccess().GetHeavenId() ); | |||
1140 | } | |||
1141 | else if (nLayerId == rDoc.getIDocumentDrawModelAccess().GetInvisibleHellId()) | |||
1142 | { | |||
1143 | rSdrObj.SetLayer( rDoc.getIDocumentDrawModelAccess().GetInvisibleHeavenId() ); | |||
1144 | } | |||
1145 | pNewSet->Put( SvxLRSpaceItem( RES_LR_SPACE ) ); | |||
1146 | pNewSet->Put( SvxULSpaceItem( RES_UL_SPACE ) ); | |||
1147 | ||||
1148 | // #i26791# - set position of the drawing object, which is labeled. | |||
1149 | pNewSet->Put( SwFormatVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ) ); | |||
1150 | pNewSet->Put( SwFormatHoriOrient( 0, text::HoriOrientation::CENTER, text::RelOrientation::FRAME ) ); | |||
1151 | ||||
1152 | // The old one is paragraph-bound to the new one's paragraph. | |||
1153 | SwFormatAnchor aAnch( RndStdIds::FLY_AT_PARA ); | |||
1154 | SwNodeIndex aAnchIdx( *pNewFormat->GetContent().GetContentIdx(), 1 ); | |||
1155 | pNew = aAnchIdx.GetNode().GetTextNode(); | |||
1156 | SwPosition aPos( aAnchIdx ); | |||
1157 | aAnch.SetAnchor( &aPos ); | |||
1158 | pNewSet->Put( aAnch ); | |||
1159 | ||||
1160 | if( pUndo ) | |||
1161 | { | |||
1162 | pUndo->SetFlys( *pOldFormat, *pNewSet, *pNewFormat ); | |||
1163 | // #i26791# - position no longer needed | |||
1164 | pUndo->SetDrawObj( nLayerId ); | |||
1165 | } | |||
1166 | else | |||
1167 | pOldFormat->SetFormatAttr( *pNewSet ); | |||
1168 | ||||
1169 | pNewSet.reset(); | |||
1170 | ||||
1171 | // Have only the FlyFrames created. | |||
1172 | // We leave this to established methods (especially for InCntFlys). | |||
1173 | pNewFormat->MakeFrames(); | |||
1174 | ||||
1175 | OSL_ENSURE( pNew, "No Label inserted" )do { if (true && (!(pNew))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1175" ": "), "%s", "No Label inserted"); } } while (false ); | |||
1176 | ||||
1177 | if( pNew ) | |||
1178 | { | |||
1179 | //#i61007# order of captions | |||
1180 | bool bOrderNumberingFirst = SW_MOD()( static_cast<SwModule*>(SfxApplication::GetModule(SfxToolsModule ::Writer)))->GetModuleConfig()->IsCaptionOrderNumberingFirst(); | |||
1181 | ||||
1182 | // prepare string | |||
1183 | OUString aText; | |||
1184 | if( bOrderNumberingFirst ) | |||
1185 | { | |||
1186 | aText = rNumberSeparator; | |||
1187 | } | |||
1188 | if ( pType ) | |||
1189 | { | |||
1190 | aText += pType->GetName(); | |||
1191 | if( !bOrderNumberingFirst ) | |||
1192 | aText += " "; | |||
1193 | } | |||
1194 | sal_Int32 nIdx = aText.getLength(); | |||
1195 | aText += rSeparator; | |||
1196 | const sal_Int32 nSepIdx = aText.getLength(); | |||
1197 | aText += rText; | |||
1198 | ||||
1199 | // insert text | |||
1200 | SwIndex aIdx( pNew, 0 ); | |||
1201 | pNew->InsertText( aText, aIdx ); | |||
1202 | ||||
1203 | // insert field | |||
1204 | if ( pType ) | |||
1205 | { | |||
1206 | SwSetExpField aField( static_cast<SwSetExpFieldType*>(pType), OUString(), SVX_NUM_ARABIC ); | |||
1207 | if( bOrderNumberingFirst ) | |||
1208 | nIdx = 0; | |||
1209 | SwFormatField aFormat( aField ); | |||
1210 | pNew->InsertItem( aFormat, nIdx, nIdx ); | |||
1211 | if ( !rCharacterStyle.isEmpty() ) | |||
1212 | { | |||
1213 | SwCharFormat * pCharFormat = rDoc.FindCharFormatByName(rCharacterStyle); | |||
1214 | if ( !pCharFormat ) | |||
1215 | { | |||
1216 | const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName( rCharacterStyle, SwGetPoolIdFromName::ChrFmt ); | |||
1217 | pCharFormat = rDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool( nMyId ); | |||
1218 | } | |||
1219 | if ( pCharFormat ) | |||
1220 | { | |||
1221 | SwFormatCharFormat aCharFormat( pCharFormat ); | |||
1222 | pNew->InsertItem( aCharFormat, 0, nSepIdx + 1, | |||
1223 | SetAttrMode::DONTEXPAND ); | |||
1224 | } | |||
1225 | } | |||
1226 | } | |||
1227 | } | |||
1228 | ||||
1229 | return pNewFormat; | |||
1230 | } | |||
1231 | ||||
1232 | SwFlyFrameFormat* SwDoc::InsertDrawLabel( | |||
1233 | OUString const& rText, | |||
1234 | OUString const& rSeparator, | |||
1235 | OUString const& rNumberSeparator, | |||
1236 | sal_uInt16 const nId, | |||
1237 | OUString const& rCharacterStyle, | |||
1238 | SdrObject& rSdrObj ) | |||
1239 | { | |||
1240 | SwDrawContact *const pContact = | |||
1241 | static_cast<SwDrawContact*>(GetUserCall( &rSdrObj )); | |||
1242 | if (!pContact) | |||
1243 | return nullptr; | |||
1244 | OSL_ENSURE( RES_DRAWFRMFMT == pContact->GetFormat()->Which(),do { if (true && (!(RES_DRAWFRMFMT == pContact->GetFormat ()->Which()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1245" ": "), "%s", "InsertDrawLabel(): not a DrawFrameFormat" ); } } while (false) | |||
1245 | "InsertDrawLabel(): not a DrawFrameFormat" )do { if (true && (!(RES_DRAWFRMFMT == pContact->GetFormat ()->Which()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN ), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1245" ": "), "%s", "InsertDrawLabel(): not a DrawFrameFormat" ); } } while (false); | |||
1246 | ||||
1247 | SwDrawFrameFormat* pOldFormat = static_cast<SwDrawFrameFormat *>(pContact->GetFormat()); | |||
1248 | if (!pOldFormat) | |||
1249 | return nullptr; | |||
1250 | ||||
1251 | std::unique_ptr<SwUndoInsertLabel> pUndo; | |||
1252 | if (GetIDocumentUndoRedo().DoesUndo()) | |||
1253 | { | |||
1254 | GetIDocumentUndoRedo().ClearRedo(); | |||
1255 | pUndo.reset(new SwUndoInsertLabel( | |||
1256 | SwLabelType::Draw, rText, rSeparator, rNumberSeparator, false, | |||
1257 | nId, rCharacterStyle, false, this )); | |||
1258 | } | |||
1259 | ||||
1260 | SwFlyFrameFormat *const pNewFormat = lcl_InsertDrawLabel( | |||
1261 | *this, mpTextFormatCollTable.get(), pUndo.get(), pOldFormat, | |||
1262 | rText, rSeparator, rNumberSeparator, nId, rCharacterStyle, rSdrObj); | |||
1263 | ||||
1264 | if (pUndo) | |||
1265 | { | |||
1266 | GetIDocumentUndoRedo().AppendUndo( std::move(pUndo) ); | |||
1267 | } | |||
1268 | else | |||
1269 | { | |||
1270 | GetIDocumentUndoRedo().DelAllUndoObj(); | |||
1271 | } | |||
1272 | ||||
1273 | return pNewFormat; | |||
1274 | } | |||
1275 | ||||
1276 | static void lcl_collectUsedNums(std::vector<unsigned int>& rSetFlags, sal_Int32 nNmLen, const OUString& rName, const OUString& rCmpName) | |||
1277 | { | |||
1278 | if (rName.startsWith(rCmpName)) | |||
1279 | { | |||
1280 | // Only get and set the Flag | |||
1281 | const sal_Int32 nNum = rName.copy(nNmLen).toInt32() - 1; | |||
1282 | if (nNum >= 0) | |||
1283 | rSetFlags.push_back(nNum); | |||
1284 | } | |||
1285 | } | |||
1286 | ||||
1287 | static void lcl_collectUsedNums(std::vector<unsigned int>& rSetFlags, sal_Int32 nNmLen, const SdrObject& rObj, const OUString& rCmpName) | |||
1288 | { | |||
1289 | OUString sName = rObj.GetName(); | |||
1290 | lcl_collectUsedNums(rSetFlags, nNmLen, sName, rCmpName); | |||
1291 | // tdf#122487 take groups into account, iterate and recurse through their | |||
1292 | // contents for name collision check | |||
1293 | if (!rObj.IsGroupObject()) | |||
1294 | return; | |||
1295 | ||||
1296 | const SdrObjList* pSub(rObj.GetSubList()); | |||
1297 | assert(pSub && "IsGroupObject is implemented as GetSubList != nullptr")(static_cast <bool> (pSub && "IsGroupObject is implemented as GetSubList != nullptr" ) ? void (0) : __assert_fail ("pSub && \"IsGroupObject is implemented as GetSubList != nullptr\"" , "/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" , 1297, __extension__ __PRETTY_FUNCTION__)); | |||
1298 | const size_t nCount = pSub->GetObjCount(); | |||
1299 | for (size_t i = 0; i < nCount; ++i) | |||
1300 | { | |||
1301 | SdrObject* pObj = pSub->GetObj(i); | |||
1302 | if (!pObj) | |||
1303 | continue; | |||
1304 | lcl_collectUsedNums(rSetFlags, nNmLen, *pObj, rCmpName); | |||
1305 | } | |||
1306 | } | |||
1307 | ||||
1308 | namespace | |||
1309 | { | |||
1310 | int first_available_number(std::vector<unsigned int>& numbers) | |||
1311 | { | |||
1312 | std::sort(numbers.begin(), numbers.end()); | |||
1313 | auto last = std::unique(numbers.begin(), numbers.end()); | |||
1314 | numbers.erase(last, numbers.end()); | |||
1315 | ||||
1316 | for (size_t i = 0; i < numbers.size(); ++i) | |||
1317 | { | |||
1318 | if (numbers[i] != i) | |||
1319 | return i; | |||
1320 | } | |||
1321 | ||||
1322 | return numbers.size(); | |||
1323 | } | |||
1324 | } | |||
1325 | ||||
1326 | static OUString lcl_GetUniqueFlyName(const SwDoc& rDoc, const char* pDefStrId, sal_uInt16 eType) | |||
1327 | { | |||
1328 | assert(eType >= RES_FMT_BEGIN && eType < RES_FMT_END)(static_cast <bool> (eType >= RES_FMT_BEGIN && eType < RES_FMT_END) ? void (0) : __assert_fail ("eType >= RES_FMT_BEGIN && eType < RES_FMT_END" , "/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" , 1328, __extension__ __PRETTY_FUNCTION__)); | |||
1329 | if (rDoc.IsInMailMerge()) | |||
1330 | { | |||
1331 | OUString newName = "MailMergeFly" | |||
1332 | + OStringToOUString( DateTimeToOString( DateTime( DateTime::SYSTEM )), RTL_TEXTENCODING_ASCII_US(((rtl_TextEncoding) 11)) ) | |||
1333 | + OUString::number( rDoc.GetSpzFrameFormats()->size() + 1 ); | |||
1334 | return newName; | |||
1335 | } | |||
1336 | ||||
1337 | OUString aName(SwResId(pDefStrId)); | |||
1338 | sal_Int32 nNmLen = aName.getLength(); | |||
1339 | ||||
1340 | const SwFrameFormats& rFormats = *rDoc.GetSpzFrameFormats(); | |||
1341 | ||||
1342 | std::vector<unsigned int> aUsedNums; | |||
1343 | aUsedNums.reserve(rFormats.size()); | |||
1344 | ||||
1345 | for( SwFrameFormats::size_type n = 0; n < rFormats.size(); ++n ) | |||
1346 | { | |||
1347 | const SwFrameFormat* pFlyFormat = rFormats[ n ]; | |||
1348 | if (eType != pFlyFormat->Which()) | |||
1349 | continue; | |||
1350 | if (eType == RES_DRAWFRMFMT) | |||
1351 | { | |||
1352 | const SdrObject *pObj = pFlyFormat->FindSdrObject(); | |||
1353 | if (pObj) | |||
1354 | lcl_collectUsedNums(aUsedNums, nNmLen, *pObj, aName); | |||
1355 | } | |||
1356 | ||||
1357 | OUString sName = pFlyFormat->GetName(); | |||
1358 | lcl_collectUsedNums(aUsedNums, nNmLen, sName, aName); | |||
1359 | } | |||
1360 | ||||
1361 | // All numbers are flagged accordingly, so determine the right one | |||
1362 | SwFrameFormats::size_type nNum = first_available_number(aUsedNums) + 1; | |||
1363 | return aName + OUString::number(nNum); | |||
1364 | } | |||
1365 | ||||
1366 | OUString SwDoc::GetUniqueGrfName() const | |||
1367 | { | |||
1368 | return lcl_GetUniqueFlyName(*this, STR_GRAPHIC_DEFNAMEreinterpret_cast<char const *>("STR_GRAPHIC_DEFNAME" "\004" u8"Image"), RES_FLYFRMFMT); | |||
1369 | } | |||
1370 | ||||
1371 | OUString SwDoc::GetUniqueOLEName() const | |||
1372 | { | |||
1373 | return lcl_GetUniqueFlyName(*this, STR_OBJECT_DEFNAMEreinterpret_cast<char const *>("STR_OBJECT_DEFNAME" "\004" u8"Object"), RES_FLYFRMFMT); | |||
1374 | } | |||
1375 | ||||
1376 | OUString SwDoc::GetUniqueFrameName() const | |||
1377 | { | |||
1378 | return lcl_GetUniqueFlyName(*this, STR_FRAME_DEFNAMEreinterpret_cast<char const *>("STR_FRAME_DEFNAME" "\004" u8"Frame"), RES_FLYFRMFMT); | |||
1379 | } | |||
1380 | ||||
1381 | OUString SwDoc::GetUniqueShapeName() const | |||
1382 | { | |||
1383 | return lcl_GetUniqueFlyName(*this, STR_SHAPE_DEFNAMEreinterpret_cast<char const *>("STR_SHAPE_DEFNAME" "\004" u8"Shape"), RES_DRAWFRMFMT); | |||
1384 | } | |||
1385 | ||||
1386 | OUString SwDoc::GetUniqueDrawObjectName() const | |||
1387 | { | |||
1388 | return lcl_GetUniqueFlyName(*this, "DrawObject", RES_DRAWFRMFMT); | |||
1389 | } | |||
1390 | ||||
1391 | const SwFlyFrameFormat* SwDoc::FindFlyByName( const OUString& rName, SwNodeType nNdTyp ) const | |||
1392 | { | |||
1393 | auto range = GetSpzFrameFormats()->rangeFind( RES_FLYFRMFMT, rName ); | |||
1394 | for( auto it = range.first; it != range.second; it++ ) | |||
1395 | { | |||
1396 | const SwFrameFormat* pFlyFormat = *it; | |||
1397 | if( RES_FLYFRMFMT != pFlyFormat->Which() || pFlyFormat->GetName() != rName ) | |||
1398 | continue; | |||
1399 | const SwNodeIndex* pIdx = pFlyFormat->GetContent().GetContentIdx(); | |||
1400 | if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() ) | |||
1401 | { | |||
1402 | if( nNdTyp != SwNodeType::NONE ) | |||
1403 | { | |||
1404 | // query for the right NodeType | |||
1405 | const SwNode* pNd = GetNodes()[ pIdx->GetIndex()+1 ]; | |||
1406 | if( nNdTyp == SwNodeType::Text | |||
1407 | ? !pNd->IsNoTextNode() | |||
1408 | : nNdTyp == pNd->GetNodeType() ) | |||
1409 | return static_cast<const SwFlyFrameFormat*>(pFlyFormat); | |||
1410 | } | |||
1411 | else | |||
1412 | return static_cast<const SwFlyFrameFormat*>(pFlyFormat); | |||
1413 | } | |||
1414 | } | |||
1415 | return nullptr; | |||
1416 | } | |||
1417 | ||||
1418 | void SwDoc::SetFlyName( SwFlyFrameFormat& rFormat, const OUString& rName ) | |||
1419 | { | |||
1420 | OUString sName( rName ); | |||
1421 | if( sName.isEmpty() || FindFlyByName( sName ) ) | |||
1422 | { | |||
1423 | const char* pTyp = STR_FRAME_DEFNAMEreinterpret_cast<char const *>("STR_FRAME_DEFNAME" "\004" u8"Frame"); | |||
1424 | const SwNodeIndex* pIdx = rFormat.GetContent().GetContentIdx(); | |||
1425 | if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() ) | |||
1426 | { | |||
1427 | switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() ) | |||
1428 | { | |||
1429 | case SwNodeType::Grf: | |||
1430 | pTyp = STR_GRAPHIC_DEFNAMEreinterpret_cast<char const *>("STR_GRAPHIC_DEFNAME" "\004" u8"Image"); | |||
1431 | break; | |||
1432 | case SwNodeType::Ole: | |||
1433 | pTyp = STR_OBJECT_DEFNAMEreinterpret_cast<char const *>("STR_OBJECT_DEFNAME" "\004" u8"Object"); | |||
1434 | break; | |||
1435 | default: break; | |||
1436 | } | |||
1437 | } | |||
1438 | sName = lcl_GetUniqueFlyName(*this, pTyp, RES_FLYFRMFMT); | |||
1439 | } | |||
1440 | rFormat.SetName( sName, true ); | |||
1441 | getIDocumentState().SetModified(); | |||
1442 | } | |||
1443 | ||||
1444 | void SwDoc::SetAllUniqueFlyNames() | |||
1445 | { | |||
1446 | sal_Int32 n, nFlyNum = 0, nGrfNum = 0, nOLENum = 0; | |||
1447 | ||||
1448 | const OUString sFlyNm(SwResId(STR_FRAME_DEFNAMEreinterpret_cast<char const *>("STR_FRAME_DEFNAME" "\004" u8"Frame"))); | |||
1449 | const OUString sGrfNm(SwResId(STR_GRAPHIC_DEFNAMEreinterpret_cast<char const *>("STR_GRAPHIC_DEFNAME" "\004" u8"Image"))); | |||
1450 | const OUString sOLENm(SwResId(STR_OBJECT_DEFNAMEreinterpret_cast<char const *>("STR_OBJECT_DEFNAME" "\004" u8"Object"))); | |||
1451 | ||||
1452 | n = GetSpzFrameFormats()->size(); | |||
1453 | if( 255 < n ) | |||
1454 | n = 255; | |||
1455 | SwFrameFormatsV aArr; | |||
1456 | aArr.reserve( n ); | |||
1457 | SwFrameFormat* pFlyFormat; | |||
1458 | bool bContainsAtPageObjWithContentAnchor = false; | |||
1459 | ||||
1460 | for( n = GetSpzFrameFormats()->size(); n; ) | |||
1461 | { | |||
1462 | pFlyFormat = (*GetSpzFrameFormats())[ --n ]; | |||
1463 | if( RES_FLYFRMFMT == pFlyFormat->Which() ) | |||
1464 | { | |||
1465 | const OUString& aNm = pFlyFormat->GetName(); | |||
1466 | if ( !aNm.isEmpty() ) | |||
1467 | { | |||
1468 | sal_Int32 *pNum = nullptr; | |||
1469 | sal_Int32 nLen = 0; | |||
1470 | if ( aNm.startsWith(sGrfNm) ) | |||
1471 | { | |||
1472 | nLen = sGrfNm.getLength(); | |||
1473 | pNum = &nGrfNum; | |||
1474 | } | |||
1475 | else if( aNm.startsWith(sFlyNm) ) | |||
1476 | { | |||
1477 | nLen = sFlyNm.getLength(); | |||
1478 | pNum = &nFlyNum; | |||
1479 | } | |||
1480 | else if( aNm.startsWith(sOLENm) ) | |||
1481 | { | |||
1482 | nLen = sOLENm.getLength(); | |||
1483 | pNum = &nOLENum; | |||
1484 | } | |||
1485 | ||||
1486 | if ( pNum ) | |||
1487 | { | |||
1488 | const sal_Int32 nNewLen = aNm.copy( nLen ).toInt32(); | |||
1489 | if (*pNum < nNewLen) | |||
1490 | *pNum = nNewLen; | |||
1491 | } | |||
1492 | } | |||
1493 | else | |||
1494 | // we want to set that afterwards | |||
1495 | aArr.push_back( pFlyFormat ); | |||
1496 | ||||
1497 | } | |||
1498 | if ( !bContainsAtPageObjWithContentAnchor ) | |||
1499 | { | |||
1500 | const SwFormatAnchor& rAnchor = pFlyFormat->GetAnchor(); | |||
1501 | if ( (RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId()) && | |||
1502 | rAnchor.GetContentAnchor() ) | |||
1503 | { | |||
1504 | bContainsAtPageObjWithContentAnchor = true; | |||
1505 | } | |||
1506 | } | |||
1507 | } | |||
1508 | SetContainsAtPageObjWithContentAnchor( bContainsAtPageObjWithContentAnchor ); | |||
1509 | ||||
1510 | for( n = aArr.size(); n; ) | |||
1511 | { | |||
1512 | pFlyFormat = aArr[ --n ]; | |||
1513 | const SwNodeIndex* pIdx = pFlyFormat->GetContent().GetContentIdx(); | |||
1514 | if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() ) | |||
1515 | { | |||
1516 | switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() ) | |||
1517 | { | |||
1518 | case SwNodeType::Grf: | |||
1519 | pFlyFormat->SetName( sGrfNm + OUString::number( ++nGrfNum )); | |||
1520 | break; | |||
1521 | case SwNodeType::Ole: | |||
1522 | pFlyFormat->SetName( sOLENm + OUString::number( ++nOLENum )); | |||
1523 | break; | |||
1524 | default: | |||
1525 | pFlyFormat->SetName( sFlyNm + OUString::number( ++nFlyNum )); | |||
1526 | break; | |||
1527 | } | |||
1528 | } | |||
1529 | } | |||
1530 | aArr.clear(); | |||
1531 | ||||
1532 | if( GetFootnoteIdxs().empty() ) | |||
1533 | return; | |||
1534 | ||||
1535 | SwTextFootnote::SetUniqueSeqRefNo( *this ); | |||
1536 | // #i52775# Chapter footnotes did not get updated correctly. | |||
1537 | // Calling UpdateAllFootnote() instead of UpdateFootnote() solves this problem, | |||
1538 | // but I do not dare to call UpdateAllFootnote() in all cases: Safety first. | |||
1539 | if ( FTNNUM_CHAPTER == GetFootnoteInfo().m_eNum ) | |||
1540 | { | |||
1541 | GetFootnoteIdxs().UpdateAllFootnote(); | |||
1542 | } | |||
1543 | else | |||
1544 | { | |||
1545 | SwNodeIndex aTmp( GetNodes() ); | |||
1546 | GetFootnoteIdxs().UpdateFootnote( aTmp ); | |||
1547 | } | |||
1548 | } | |||
1549 | ||||
1550 | bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const | |||
1551 | { | |||
1552 | // That can also be a Fly in a Fly in the Header. | |||
1553 | // Is also used by sw3io, to determine if a Redline object is | |||
1554 | // in the Header or Footer. | |||
1555 | // Because Redlines are also attached to Start and EndNode, | |||
1556 | // the Index must not necessarily be from a ContentNode. | |||
1557 | SwNode* pNd = &rIdx.GetNode(); | |||
1558 | const SwNode* pFlyNd = pNd->FindFlyStartNode(); | |||
1559 | while( pFlyNd ) | |||
1560 | { | |||
1561 | // get up by using the Anchor | |||
1562 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1563 | std::vector<const SwFrameFormat*> checkFormats; | |||
1564 | for( auto pFormat : *GetSpzFrameFormats() ) | |||
1565 | { | |||
1566 | const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx(); | |||
1567 | if( pIdx && pFlyNd == &pIdx->GetNode() ) | |||
1568 | checkFormats.push_back( pFormat ); | |||
1569 | } | |||
1570 | #endif | |||
1571 | std::vector<SwFrameFormat*> const*const pFlys(pFlyNd->GetAnchoredFlys()); | |||
1572 | bool bFound(false); | |||
1573 | for (size_t i = 0; pFlys && i < pFlys->size(); ++i) | |||
1574 | { | |||
1575 | const SwFrameFormat *const pFormat = (*pFlys)[i]; | |||
1576 | const SwNodeIndex* pIdx = pFormat->GetContent().GetContentIdx(); | |||
1577 | if( pIdx && pFlyNd == &pIdx->GetNode() ) | |||
1578 | { | |||
1579 | #if OSL_DEBUG_LEVEL1 > 0 | |||
1580 | auto checkPos = std::find( | |||
1581 | checkFormats.begin(), checkFormats.end(), pFormat ); | |||
1582 | assert( checkPos != checkFormats.end())(static_cast <bool> (checkPos != checkFormats.end()) ? void (0) : __assert_fail ("checkPos != checkFormats.end()", "/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" , 1582, __extension__ __PRETTY_FUNCTION__)); | |||
1583 | checkFormats.erase( checkPos ); | |||
1584 | #endif | |||
1585 | const SwFormatAnchor& rAnchor = pFormat->GetAnchor(); | |||
1586 | if ((RndStdIds::FLY_AT_PAGE == rAnchor.GetAnchorId()) || | |||
1587 | !rAnchor.GetContentAnchor() ) | |||
1588 | { | |||
1589 | return false; | |||
1590 | } | |||
1591 | ||||
1592 | pNd = &rAnchor.GetContentAnchor()->nNode.GetNode(); | |||
1593 | pFlyNd = pNd->FindFlyStartNode(); | |||
1594 | bFound = true; | |||
1595 | break; | |||
1596 | } | |||
1597 | } | |||
1598 | if (!bFound) | |||
1599 | { | |||
1600 | OSL_ENSURE(mbInReading, "Found a FlySection but not a Format!")do { if (true && (!(mbInReading))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sw/source/core/doc/doclay.cxx" ":" "1600" ": "), "%s", "Found a FlySection but not a Format!" ); } } while (false); | |||
1601 | return false; | |||
1602 | } | |||
1603 | } | |||
1604 | ||||
1605 | return nullptr != pNd->FindHeaderStartNode() || | |||
1606 | nullptr != pNd->FindFooterStartNode(); | |||
1607 | } | |||
1608 | ||||
1609 | SvxFrameDirection SwDoc::GetTextDirection( const SwPosition& rPos, | |||
1610 | const Point* pPt ) const | |||
1611 | { | |||
1612 | SvxFrameDirection nRet = SvxFrameDirection::Unknown; | |||
1613 | ||||
1614 | SwContentNode *pNd = rPos.nNode.GetNode().GetContentNode(); | |||
1615 | ||||
1616 | // #i42921# - use new method <SwContentNode::GetTextDirection(..)> | |||
1617 | if ( pNd ) | |||
1618 | { | |||
1619 | nRet = pNd->GetTextDirection( rPos, pPt ); | |||
1620 | } | |||
1621 | if ( nRet == SvxFrameDirection::Unknown ) | |||
1622 | { | |||
1623 | const SvxFrameDirectionItem* pItem = nullptr; | |||
1624 | if( pNd ) | |||
1625 | { | |||
1626 | // Are we in a FlyFrame? Then look at that for the correct attribute | |||
1627 | const SwFrameFormat* pFlyFormat = pNd->GetFlyFormat(); | |||
1628 | while( pFlyFormat ) | |||
1629 | { | |||
1630 | pItem = &pFlyFormat->GetFrameDir(); | |||
1631 | if( SvxFrameDirection::Environment == pItem->GetValue() ) | |||
1632 | { | |||
1633 | pItem = nullptr; | |||
1634 | const SwFormatAnchor* pAnchor = &pFlyFormat->GetAnchor(); | |||
1635 | if ((RndStdIds::FLY_AT_PAGE != pAnchor->GetAnchorId()) && | |||
1636 | pAnchor->GetContentAnchor()) | |||
1637 | { | |||
1638 | pFlyFormat = pAnchor->GetContentAnchor()->nNode. | |||
1639 | GetNode().GetFlyFormat(); | |||
1640 | } | |||
1641 | else | |||
1642 | pFlyFormat = nullptr; | |||
1643 | } | |||
1644 | else | |||
1645 | pFlyFormat = nullptr; | |||
1646 | } | |||
1647 | ||||
1648 | if( !pItem ) | |||
1649 | { | |||
1650 | const SwPageDesc* pPgDsc = pNd->FindPageDesc(); | |||
1651 | if( pPgDsc ) | |||
1652 | pItem = &pPgDsc->GetMaster().GetFrameDir(); | |||
1653 | } | |||
1654 | } | |||
1655 | if( !pItem ) | |||
1656 | pItem = &GetAttrPool().GetDefaultItem( RES_FRAMEDIR ); | |||
1657 | nRet = pItem->GetValue(); | |||
1658 | } | |||
1659 | return nRet; | |||
1660 | } | |||
1661 | ||||
1662 | bool SwDoc::IsInVerticalText( const SwPosition& rPos ) const | |||
1663 | { | |||
1664 | const SvxFrameDirection nDir = GetTextDirection( rPos ); | |||
1665 | return SvxFrameDirection::Vertical_RL_TB == nDir || SvxFrameDirection::Vertical_LR_TB == nDir; | |||
1666 | } | |||
1667 | ||||
1668 | o3tl::sorted_vector<SwRootFrame*> SwDoc::GetAllLayouts() | |||
1669 | { | |||
1670 | o3tl::sorted_vector<SwRootFrame*> aAllLayouts; | |||
1671 | SwViewShell *pStart = getIDocumentLayoutAccess().GetCurrentViewShell(); | |||
1672 | if(pStart) | |||
1673 | { | |||
1674 | for(const SwViewShell& rShell : pStart->GetRingContainer()) | |||
1675 | { | |||
1676 | if(rShell.GetLayout()) | |||
1677 | aAllLayouts.insert(rShell.GetLayout()); | |||
1678 | } | |||
1679 | } | |||
1680 | return aAllLayouts; | |||
1681 | } | |||
1682 | ||||
1683 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |