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