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 :
41 : #include <swmodule.hxx>
42 : #include <modcfg.hxx>
43 : #include <com/sun/star/beans/XPropertySet.hpp>
44 : #include <SwStyleNameMapper.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 <rootfrm.hxx>
66 : #include <pagefrm.hxx>
67 : #include <cntfrm.hxx>
68 : #include <flyfrm.hxx>
69 : #include <fesh.hxx>
70 : #include <docsh.hxx>
71 : #include <dflyobj.hxx>
72 : #include <dcontact.hxx>
73 : #include <swundo.hxx>
74 : #include <flypos.hxx>
75 : #include <UndoInsert.hxx>
76 : #include <expfld.hxx>
77 : #include <poolfmt.hxx>
78 : #include <docary.hxx>
79 : #include <swtable.hxx>
80 : #include <tblsel.hxx>
81 : #include <viewopt.hxx>
82 : #include <fldupde.hxx>
83 : #include <txtftn.hxx>
84 : #include <ftnidx.hxx>
85 : #include <ftninfo.hxx>
86 : #include <pagedesc.hxx>
87 : #include <PostItMgr.hxx>
88 : #include <comcore.hrc>
89 :
90 : #include <unoframe.hxx>
91 :
92 : #include <sortedobjs.hxx>
93 :
94 : #include <vector>
95 :
96 : using namespace ::com::sun::star;
97 :
98 : #define DEF_FLY_WIDTH 2268 // Default width for FlyFrms (2268 == 4cm)
99 :
100 0 : static bool lcl_IsItemSet(const SwCntntNode & rNode, sal_uInt16 which)
101 : {
102 0 : bool bResult = false;
103 :
104 0 : if (SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState(which))
105 0 : bResult = true;
106 :
107 0 : return bResult;
108 : }
109 :
110 : /** Create a new format whose settings fit to the Request by default.
111 :
112 : The format is put into the respective format array.
113 : If there already is a fitting format, it is returned instead. */
114 0 : SwFrmFmt *SwDoc::MakeLayoutFmt( RndStdIds eRequest, const SfxItemSet* pSet )
115 : {
116 0 : SwFrmFmt *pFmt = 0;
117 0 : const sal_Bool bMod = IsModified();
118 0 : bool bHeader = false;
119 :
120 0 : switch ( eRequest )
121 : {
122 : case RND_STD_HEADER:
123 : case RND_STD_HEADERL:
124 : case RND_STD_HEADERR:
125 : {
126 0 : bHeader = true;
127 : // no break, we continue further down
128 : }
129 : case RND_STD_FOOTER:
130 : case RND_STD_FOOTERL:
131 : case RND_STD_FOOTERR:
132 : {
133 : pFmt = new SwFrmFmt( GetAttrPool(),
134 : (bHeader ? "Right header" : "Right footer"),
135 0 : GetDfltFrmFmt() );
136 :
137 0 : SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() );
138 : SwStartNode* pSttNd =
139 0 : GetNodes().MakeTextSection
140 : ( aTmpIdx,
141 : bHeader ? SwHeaderStartNode : SwFooterStartNode,
142 : GetTxtCollFromPool(static_cast<sal_uInt16>( bHeader
143 : ? ( eRequest == RND_STD_HEADERL
144 : ? RES_POOLCOLL_HEADERL
145 : : eRequest == RND_STD_HEADERR
146 : ? RES_POOLCOLL_HEADERR
147 : : RES_POOLCOLL_HEADER )
148 : : ( eRequest == RND_STD_FOOTERL
149 : ? RES_POOLCOLL_FOOTERL
150 : : eRequest == RND_STD_FOOTERR
151 : ? RES_POOLCOLL_FOOTERR
152 : : RES_POOLCOLL_FOOTER )
153 0 : ) ) );
154 0 : pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
155 :
156 0 : if( pSet ) // Set a few more attributes
157 0 : pFmt->SetFmtAttr( *pSet );
158 :
159 : // Why set it back? Doc has changed, or not?
160 : // In any case, wrong for the FlyFrames!
161 0 : if ( !bMod )
162 0 : ResetModified();
163 : }
164 0 : break;
165 :
166 : case RND_DRAW_OBJECT:
167 : {
168 0 : pFmt = MakeDrawFrmFmt( OUString(), GetDfltFrmFmt() );
169 0 : if( pSet ) // Set a few more attributes
170 0 : pFmt->SetFmtAttr( *pSet );
171 :
172 0 : if (GetIDocumentUndoRedo().DoesUndo())
173 : {
174 0 : GetIDocumentUndoRedo().AppendUndo(
175 0 : new SwUndoInsLayFmt(pFmt, 0, 0));
176 : }
177 : }
178 0 : break;
179 :
180 : #if OSL_DEBUG_LEVEL > 0
181 : case FLY_AT_PAGE:
182 : case FLY_AT_CHAR:
183 : case FLY_AT_FLY:
184 : case FLY_AT_PARA:
185 : case FLY_AS_CHAR:
186 : OSL_FAIL( "use new interface instead: SwDoc::MakeFlySection!" );
187 : break;
188 : #endif
189 :
190 : default:
191 : OSL_ENSURE( !this,
192 : "LayoutFormat was requested with an invalid Request." );
193 :
194 : }
195 0 : return pFmt;
196 : }
197 :
198 : /// Deletes the denoted format and its content.
199 0 : void SwDoc::DelLayoutFmt( SwFrmFmt *pFmt )
200 : {
201 : // A chain of frames needs to be merged, if necessary,
202 : // so that the Frame's contents are adjusted accordingly before we destroy the Frames.
203 0 : const SwFmtChain &rChain = pFmt->GetChain();
204 0 : if ( rChain.GetPrev() )
205 : {
206 0 : SwFmtChain aChain( rChain.GetPrev()->GetChain() );
207 0 : aChain.SetNext( rChain.GetNext() );
208 0 : SetAttr( aChain, *rChain.GetPrev() );
209 : }
210 0 : if ( rChain.GetNext() )
211 : {
212 0 : SwFmtChain aChain( rChain.GetNext()->GetChain() );
213 0 : aChain.SetPrev( rChain.GetPrev() );
214 0 : SetAttr( aChain, *rChain.GetNext() );
215 : }
216 :
217 0 : const SwNodeIndex* pCntIdx = pFmt->GetCntnt().GetCntntIdx();
218 0 : if (pCntIdx && !GetIDocumentUndoRedo().DoesUndo())
219 : {
220 : // Disconnect if it's an OLE object
221 0 : SwOLENode* pOLENd = GetNodes()[ pCntIdx->GetIndex()+1 ]->GetOLENode();
222 0 : if( pOLENd && pOLENd->GetOLEObj().IsOleRef() )
223 : {
224 :
225 : // TODO: the old object closed the object and cleared all references to it, but didn't remove it from the container.
226 : // I have no idea, why, nobody could explain it - so I do my very best to mimic this behavior
227 : //uno::Reference < util::XCloseable > xClose( pOLENd->GetOLEObj().GetOleRef(), uno::UNO_QUERY );
228 : //if ( xClose.is() )
229 : {
230 : try
231 : {
232 0 : pOLENd->GetOLEObj().GetOleRef()->changeState( embed::EmbedStates::LOADED );
233 : }
234 0 : catch ( uno::Exception& )
235 : {
236 : }
237 : }
238 :
239 : }
240 : }
241 :
242 : // Destroy Frames
243 0 : pFmt->DelFrms();
244 :
245 : // Only FlyFrames are undoable at first
246 0 : const sal_uInt16 nWh = pFmt->Which();
247 0 : if (GetIDocumentUndoRedo().DoesUndo() &&
248 0 : (RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh))
249 : {
250 0 : GetIDocumentUndoRedo().AppendUndo( new SwUndoDelLayFmt( pFmt ));
251 : }
252 : else
253 : {
254 : // #i32089# - delete at-frame anchored objects
255 0 : if ( nWh == RES_FLYFRMFMT )
256 : {
257 : // determine frame formats of at-frame anchored objects
258 0 : const SwNodeIndex* pCntntIdx = pFmt->GetCntnt().GetCntntIdx();
259 0 : if ( pCntntIdx )
260 : {
261 0 : const SwFrmFmts* pTbl = pFmt->GetDoc()->GetSpzFrmFmts();
262 0 : if ( pTbl )
263 : {
264 0 : std::vector<SwFrmFmt*> aToDeleteFrmFmts;
265 0 : const sal_uLong nNodeIdxOfFlyFmt( pCntntIdx->GetIndex() );
266 :
267 0 : for ( sal_uInt16 i = 0; i < pTbl->size(); ++i )
268 : {
269 0 : SwFrmFmt* pTmpFmt = (*pTbl)[i];
270 0 : const SwFmtAnchor &rAnch = pTmpFmt->GetAnchor();
271 0 : if ( rAnch.GetAnchorId() == FLY_AT_FLY &&
272 0 : rAnch.GetCntntAnchor()->nNode.GetIndex() == nNodeIdxOfFlyFmt )
273 : {
274 0 : aToDeleteFrmFmts.push_back( pTmpFmt );
275 : }
276 : }
277 :
278 : // delete found frame formats
279 0 : while ( !aToDeleteFrmFmts.empty() )
280 : {
281 0 : SwFrmFmt* pTmpFmt = aToDeleteFrmFmts.back();
282 0 : pFmt->GetDoc()->DelLayoutFmt( pTmpFmt );
283 :
284 0 : aToDeleteFrmFmts.pop_back();
285 0 : }
286 : }
287 : }
288 : }
289 :
290 : // Delete content
291 0 : if( pCntIdx )
292 : {
293 0 : SwNode *pNode = &pCntIdx->GetNode();
294 0 : ((SwFmtCntnt&)pFmt->GetFmtAttr( RES_CNTNT )).SetNewCntntIdx( 0 );
295 0 : DeleteSection( pNode );
296 : }
297 :
298 : // Delete the character for FlyFrames anchored as char (if necessary)
299 0 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
300 0 : if ((FLY_AS_CHAR == rAnchor.GetAnchorId()) && rAnchor.GetCntntAnchor())
301 : {
302 0 : const SwPosition* pPos = rAnchor.GetCntntAnchor();
303 0 : SwTxtNode *pTxtNd = pPos->nNode.GetNode().GetTxtNode();
304 :
305 : // attribute is still in text node, delete it
306 0 : if ( pTxtNd )
307 : {
308 : SwTxtFlyCnt* const pAttr = static_cast<SwTxtFlyCnt*>(
309 : pTxtNd->GetTxtAttrForCharAt( pPos->nContent.GetIndex(),
310 0 : RES_TXTATR_FLYCNT ));
311 0 : if ( pAttr && (pAttr->GetFlyCnt().GetFrmFmt() == pFmt) )
312 : {
313 : // dont delete, set pointer to 0
314 0 : const_cast<SwFmtFlyCnt&>(pAttr->GetFlyCnt()).SetFlyFmt();
315 0 : SwIndex aIdx( pPos->nContent );
316 0 : pTxtNd->EraseText( aIdx, 1 );
317 : }
318 : }
319 : }
320 :
321 0 : DelFrmFmt( pFmt );
322 : }
323 0 : SetModified();
324 0 : }
325 :
326 : /** Copies the stated format (pSrc) to pDest and returns pDest.
327 :
328 : If there's no pDest, it is created.
329 : If the source format is located in another document, also copy correctly
330 : in this case.
331 : The Anchor attribute's position is always set to 0! */
332 0 : SwFrmFmt *SwDoc::CopyLayoutFmt(
333 : const SwFrmFmt& rSource,
334 : const SwFmtAnchor& rNewAnchor,
335 : bool bSetTxtFlyAtt,
336 : bool bMakeFrms )
337 : {
338 0 : const bool bFly = RES_FLYFRMFMT == rSource.Which();
339 0 : const bool bDraw = RES_DRAWFRMFMT == rSource.Which();
340 : OSL_ENSURE( bFly || bDraw, "this method only works for fly or draw" );
341 :
342 0 : SwDoc* pSrcDoc = (SwDoc*)rSource.GetDoc();
343 :
344 : // May we copy this object?
345 : // We may, unless it's 1) it's a control (and therfore a draw)
346 : // 2) anchored in a header/footer
347 : // 3) anchored (to paragraph?)
348 0 : bool bMayNotCopy = false;
349 0 : if( bDraw )
350 : {
351 : const SwDrawContact* pDrawContact =
352 0 : static_cast<const SwDrawContact*>( rSource.FindContactObj() );
353 :
354 : bMayNotCopy =
355 0 : ((FLY_AT_PARA == rNewAnchor.GetAnchorId()) ||
356 0 : (FLY_AT_FLY == rNewAnchor.GetAnchorId()) ||
357 0 : (FLY_AT_CHAR == rNewAnchor.GetAnchorId())) &&
358 0 : rNewAnchor.GetCntntAnchor() &&
359 0 : IsInHeaderFooter( rNewAnchor.GetCntntAnchor()->nNode ) &&
360 0 : pDrawContact != NULL &&
361 0 : pDrawContact->GetMaster() != NULL &&
362 0 : CheckControlLayer( pDrawContact->GetMaster() );
363 : }
364 :
365 : // just return if we can't copy this
366 0 : if( bMayNotCopy )
367 0 : return NULL;
368 :
369 0 : SwFrmFmt* pDest = GetDfltFrmFmt();
370 0 : if( rSource.GetRegisteredIn() != pSrcDoc->GetDfltFrmFmt() )
371 0 : pDest = CopyFrmFmt( *(SwFrmFmt*)rSource.GetRegisteredIn() );
372 0 : if( bFly )
373 : {
374 : // #i11176#
375 : // To do a correct cloning concerning the ZOrder for all objects
376 : // it is necessary to actually create a draw object for fly frames, too.
377 : // These are then added to the DrawingLayer (which needs to exist).
378 : // Together with correct sorting of all drawinglayer based objects
379 : // before cloning ZOrder transfer works correctly then.
380 0 : SwFlyFrmFmt *pFormat = MakeFlyFrmFmt( rSource.GetName(), pDest );
381 0 : pDest = pFormat;
382 :
383 0 : SwXFrame::GetOrCreateSdrObject(pFormat);
384 : }
385 : else
386 0 : pDest = MakeDrawFrmFmt( OUString(), pDest );
387 :
388 : // Copy all other or new attributes
389 0 : pDest->CopyAttrs( rSource );
390 :
391 : // Do not copy chains
392 0 : pDest->ResetFmtAttr( RES_CHAIN );
393 :
394 0 : if( bFly )
395 : {
396 : // Duplicate the content.
397 0 : const SwNode& rCSttNd = rSource.GetCntnt().GetCntntIdx()->GetNode();
398 0 : SwNodeRange aRg( rCSttNd, 1, *rCSttNd.EndOfSectionNode() );
399 :
400 0 : SwNodeIndex aIdx( GetNodes().GetEndOfAutotext() );
401 0 : SwStartNode* pSttNd = GetNodes().MakeEmptySection( aIdx, SwFlyStartNode );
402 :
403 : // Set the Anchor/CntntIndex first.
404 : // Within the copying part, we can access the values (DrawFmt in Headers and Footers)
405 0 : aIdx = *pSttNd;
406 0 : SwFmtCntnt aAttr( rSource.GetCntnt() );
407 0 : aAttr.SetNewCntntIdx( &aIdx );
408 0 : pDest->SetFmtAttr( aAttr );
409 0 : pDest->SetFmtAttr( rNewAnchor );
410 :
411 0 : if( !mbCopyIsMove || this != pSrcDoc )
412 : {
413 0 : if( mbInReading )
414 0 : pDest->SetName( OUString() );
415 : else
416 : {
417 : // Test first if the name is already taken, if so generate a new one.
418 0 : sal_Int8 nNdTyp = aRg.aStart.GetNode().GetNodeType();
419 :
420 0 : OUString sOld( pDest->GetName() );
421 0 : pDest->SetName( OUString() );
422 0 : if( FindFlyByName( sOld, nNdTyp ) ) // found one
423 0 : switch( nNdTyp )
424 : {
425 0 : case ND_GRFNODE: sOld = GetUniqueGrfName(); break;
426 0 : case ND_OLENODE: sOld = GetUniqueOLEName(); break;
427 0 : default: sOld = GetUniqueFrameName(); break;
428 : }
429 :
430 0 : pDest->SetName( sOld );
431 : }
432 : }
433 :
434 0 : if (GetIDocumentUndoRedo().DoesUndo())
435 : {
436 0 : GetIDocumentUndoRedo().AppendUndo(new SwUndoInsLayFmt(pDest,0,0));
437 : }
438 :
439 : // Make sure that FlyFrames in FlyFrames are copied
440 0 : aIdx = *pSttNd->EndOfSectionNode();
441 :
442 : //fdo#36631 disable (scoped) any undo operations associated with the
443 : //contact object itself. They should be managed by SwUndoInsLayFmt.
444 0 : const ::sw::DrawUndoGuard drawUndoGuard(GetIDocumentUndoRedo());
445 :
446 0 : pSrcDoc->CopyWithFlyInFly( aRg, 0, aIdx, NULL, sal_False, sal_True, sal_True );
447 : }
448 : else
449 : {
450 : OSL_ENSURE( RES_DRAWFRMFMT == rSource.Which(), "Neither Fly nor Draw." );
451 : // #i52780# - Note: moving object to visible layer not needed.
452 0 : SwDrawContact* pSourceContact = (SwDrawContact *)rSource.FindContactObj();
453 :
454 : SwDrawContact* pContact = new SwDrawContact( (SwDrawFrmFmt*)pDest,
455 0 : CloneSdrObj( *pSourceContact->GetMaster(),
456 0 : mbCopyIsMove && this == pSrcDoc ) );
457 : // #i49730# - notify draw frame format that position attributes are
458 : // already set, if the position attributes are already set at the
459 : // source draw frame format.
460 0 : if ( pDest->ISA(SwDrawFrmFmt) &&
461 0 : rSource.ISA(SwDrawFrmFmt) &&
462 0 : static_cast<const SwDrawFrmFmt&>(rSource).IsPosAttrSet() )
463 : {
464 0 : static_cast<SwDrawFrmFmt*>(pDest)->PosAttrSet();
465 : }
466 :
467 0 : if( pDest->GetAnchor() == rNewAnchor )
468 : {
469 : // Do *not* connect to layout, if a <MakeFrms> will not be called.
470 0 : if ( bMakeFrms )
471 : {
472 0 : pContact->ConnectToLayout( &rNewAnchor );
473 : }
474 : }
475 : else
476 0 : pDest->SetFmtAttr( rNewAnchor );
477 :
478 0 : if (GetIDocumentUndoRedo().DoesUndo())
479 : {
480 0 : GetIDocumentUndoRedo().AppendUndo(new SwUndoInsLayFmt(pDest,0,0));
481 : }
482 : }
483 :
484 0 : if (bSetTxtFlyAtt && (FLY_AS_CHAR == rNewAnchor.GetAnchorId()))
485 : {
486 0 : const SwPosition* pPos = rNewAnchor.GetCntntAnchor();
487 0 : SwFmtFlyCnt aFmt( pDest );
488 0 : pPos->nNode.GetNode().GetTxtNode()->InsertItem(
489 0 : aFmt, pPos->nContent.GetIndex(), 0 );
490 : }
491 :
492 0 : if( bMakeFrms )
493 0 : pDest->MakeFrms();
494 :
495 0 : return pDest;
496 : }
497 :
498 0 : SdrObject* SwDoc::CloneSdrObj( const SdrObject& rObj, bool bMoveWithinDoc,
499 : bool bInsInPage )
500 : {
501 : // #i52858# - method name changed
502 0 : SdrPage *pPg = GetOrCreateDrawModel()->GetPage( 0 );
503 0 : if( !pPg )
504 : {
505 0 : pPg = GetDrawModel()->AllocPage( false );
506 0 : GetDrawModel()->InsertPage( pPg );
507 : }
508 :
509 0 : SdrObject *pObj = rObj.Clone();
510 0 : if( bMoveWithinDoc && FmFormInventor == pObj->GetObjInventor() )
511 : {
512 : // We need to preserve the Name for Controls
513 0 : uno::Reference< awt::XControlModel > xModel = ((SdrUnoObj*)pObj)->GetUnoControlModel();
514 0 : uno::Any aVal;
515 0 : uno::Reference< beans::XPropertySet > xSet(xModel, uno::UNO_QUERY);
516 0 : OUString sName("Name");
517 0 : if( xSet.is() )
518 0 : aVal = xSet->getPropertyValue( sName );
519 0 : if( bInsInPage )
520 0 : pPg->InsertObject( pObj );
521 0 : if( xSet.is() )
522 0 : xSet->setPropertyValue( sName, aVal );
523 : }
524 0 : else if( bInsInPage )
525 0 : pPg->InsertObject( pObj );
526 :
527 : // For drawing objects: set layer of cloned object to invisible layer
528 0 : SdrLayerID nLayerIdForClone = rObj.GetLayer();
529 0 : if ( !pObj->ISA(SwFlyDrawObj) &&
530 0 : !pObj->ISA(SwVirtFlyDrawObj) &&
531 0 : !IS_TYPE(SdrObject,pObj) )
532 : {
533 0 : if ( IsVisibleLayerId( nLayerIdForClone ) )
534 : {
535 0 : nLayerIdForClone = GetInvisibleLayerIdByVisibleOne( nLayerIdForClone );
536 : }
537 : }
538 0 : pObj->SetLayer( nLayerIdForClone );
539 :
540 0 : return pObj;
541 : }
542 :
543 0 : SwFlyFrmFmt* SwDoc::_MakeFlySection( const SwPosition& rAnchPos,
544 : const SwCntntNode& rNode,
545 : RndStdIds eRequestId,
546 : const SfxItemSet* pFlySet,
547 : SwFrmFmt* pFrmFmt )
548 : {
549 0 : if( !pFrmFmt )
550 0 : pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME );
551 :
552 0 : OUString sName;
553 0 : if( !mbInReading )
554 0 : switch( rNode.GetNodeType() )
555 : {
556 0 : case ND_GRFNODE: sName = GetUniqueGrfName(); break;
557 0 : case ND_OLENODE: sName = GetUniqueOLEName(); break;
558 0 : default: sName = GetUniqueFrameName(); break;
559 : }
560 0 : SwFlyFrmFmt* pFmt = MakeFlyFrmFmt( sName, pFrmFmt );
561 :
562 : // Create content and connect to the format.
563 : // Create CntntNode and put it into the autotext selection.
564 0 : SwNodeRange aRange( GetNodes().GetEndOfAutotext(), -1,
565 0 : GetNodes().GetEndOfAutotext() );
566 0 : GetNodes().SectionDown( &aRange, SwFlyStartNode );
567 :
568 0 : pFmt->SetFmtAttr( SwFmtCntnt( rNode.StartOfSectionNode() ));
569 :
570 0 : const SwFmtAnchor* pAnchor = 0;
571 0 : if( pFlySet )
572 : {
573 : pFlySet->GetItemState( RES_ANCHOR, false,
574 0 : (const SfxPoolItem**)&pAnchor );
575 0 : if( SFX_ITEM_SET == pFlySet->GetItemState( RES_CNTNT, false ))
576 : {
577 0 : SfxItemSet aTmpSet( *pFlySet );
578 0 : aTmpSet.ClearItem( RES_CNTNT );
579 0 : pFmt->SetFmtAttr( aTmpSet );
580 : }
581 : else
582 0 : pFmt->SetFmtAttr( *pFlySet );
583 : }
584 :
585 : // Anchor not yet set?
586 0 : RndStdIds eAnchorId = pAnchor ? pAnchor->GetAnchorId()
587 0 : : pFmt->GetAnchor().GetAnchorId();
588 : // #i107811# Assure that at-page anchored fly frames have a page num or a
589 : // content anchor set.
590 0 : if ( !pAnchor ||
591 0 : ( FLY_AT_PAGE != pAnchor->GetAnchorId() &&
592 0 : !pAnchor->GetCntntAnchor() ) ||
593 0 : ( FLY_AT_PAGE == pAnchor->GetAnchorId() &&
594 0 : !pAnchor->GetCntntAnchor() &&
595 0 : pAnchor->GetPageNum() == 0 ) )
596 : {
597 : // set it again, needed for Undo
598 0 : SwFmtAnchor aAnch( pFmt->GetAnchor() );
599 0 : if (pAnchor && (FLY_AT_FLY == pAnchor->GetAnchorId()))
600 : {
601 0 : SwPosition aPos( *rAnchPos.nNode.GetNode().FindFlyStartNode() );
602 0 : aAnch.SetAnchor( &aPos );
603 0 : eAnchorId = FLY_AT_FLY;
604 : }
605 : else
606 : {
607 0 : if( eRequestId != aAnch.GetAnchorId() &&
608 0 : SFX_ITEM_SET != pFmt->GetItemState( RES_ANCHOR, sal_True ) )
609 : {
610 0 : aAnch.SetType( eRequestId );
611 : }
612 :
613 0 : eAnchorId = aAnch.GetAnchorId();
614 0 : if ( FLY_AT_PAGE != eAnchorId ||
615 0 : ( FLY_AT_PAGE == eAnchorId &&
616 0 : ( !pAnchor ||
617 0 : aAnch.GetPageNum() == 0 ) ) )
618 : {
619 0 : aAnch.SetAnchor( &rAnchPos );
620 : }
621 : }
622 0 : pFmt->SetFmtAttr( aAnch );
623 : }
624 : else
625 0 : eAnchorId = pFmt->GetAnchor().GetAnchorId();
626 :
627 0 : if ( FLY_AS_CHAR == eAnchorId )
628 : {
629 0 : const sal_Int32 nStt = rAnchPos.nContent.GetIndex();
630 0 : SwTxtNode * pTxtNode = rAnchPos.nNode.GetNode().GetTxtNode();
631 :
632 : OSL_ENSURE(pTxtNode!= 0, "There should be a SwTxtNode!");
633 :
634 0 : if (pTxtNode != NULL)
635 : {
636 0 : SwFmtFlyCnt aFmt( pFmt );
637 : // may fail if there's no space left or header/ftr
638 0 : if (!pTxtNode->InsertItem(aFmt, nStt, nStt))
639 : { // pFmt is dead now
640 0 : return 0;
641 0 : }
642 : }
643 : }
644 :
645 0 : if( SFX_ITEM_SET != pFmt->GetAttrSet().GetItemState( RES_FRM_SIZE ))
646 : {
647 0 : SwFmtFrmSize aFmtSize( ATT_VAR_SIZE, 0, DEF_FLY_WIDTH );
648 0 : const SwNoTxtNode* pNoTxtNode = rNode.GetNoTxtNode();
649 0 : if( pNoTxtNode )
650 : {
651 : // Set size
652 0 : Size aSize( pNoTxtNode->GetTwipSize() );
653 0 : if( MINFLY > aSize.Width() )
654 0 : aSize.Width() = DEF_FLY_WIDTH;
655 0 : aFmtSize.SetWidth( aSize.Width() );
656 0 : if( aSize.Height() )
657 : {
658 0 : aFmtSize.SetHeight( aSize.Height() );
659 0 : aFmtSize.SetHeightSizeType( ATT_FIX_SIZE );
660 : }
661 : }
662 0 : pFmt->SetFmtAttr( aFmtSize );
663 : }
664 :
665 : // Set up frames
666 0 : if( GetCurrentViewShell() )
667 0 : pFmt->MakeFrms(); // ???
668 :
669 0 : if (GetIDocumentUndoRedo().DoesUndo())
670 : {
671 0 : sal_uLong nNodeIdx = rAnchPos.nNode.GetIndex();
672 0 : const sal_Int32 nCntIdx = rAnchPos.nContent.GetIndex();
673 0 : GetIDocumentUndoRedo().AppendUndo(
674 0 : new SwUndoInsLayFmt( pFmt, nNodeIdx, nCntIdx ));
675 : }
676 :
677 0 : SetModified();
678 0 : return pFmt;
679 : }
680 :
681 0 : SwFlyFrmFmt* SwDoc::MakeFlySection( RndStdIds eAnchorType,
682 : const SwPosition* pAnchorPos,
683 : const SfxItemSet* pFlySet,
684 : SwFrmFmt* pFrmFmt, bool bCalledFromShell )
685 : {
686 0 : SwFlyFrmFmt* pFmt = 0;
687 0 : bool bCallMake = true;
688 0 : if ( !pAnchorPos && (FLY_AT_PAGE != eAnchorType) )
689 : {
690 : const SwFmtAnchor* pAnch;
691 0 : if( (pFlySet && SFX_ITEM_SET == pFlySet->GetItemState(
692 0 : RES_ANCHOR, false, (const SfxPoolItem**)&pAnch )) ||
693 0 : ( pFrmFmt && SFX_ITEM_SET == pFrmFmt->GetItemState(
694 0 : RES_ANCHOR, sal_True, (const SfxPoolItem**)&pAnch )) )
695 : {
696 0 : if ( (FLY_AT_PAGE != pAnch->GetAnchorId()) )
697 : {
698 0 : pAnchorPos = pAnch->GetCntntAnchor();
699 0 : if (pAnchorPos)
700 : {
701 0 : bCallMake = false;
702 : }
703 : }
704 : }
705 : }
706 :
707 0 : if( bCallMake )
708 : {
709 0 : if( !pFrmFmt )
710 0 : pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME );
711 :
712 : sal_uInt16 nCollId = static_cast<sal_uInt16>(
713 0 : get(IDocumentSettingAccess::HTML_MODE) ? RES_POOLCOLL_TEXT : RES_POOLCOLL_FRAME );
714 :
715 : /* If there is no adjust item in the paragraph style for the content node of the new fly section
716 : propagate an existing adjust item at the anchor to the new content node. */
717 0 : SwCntntNode * pNewTxtNd = GetNodes().MakeTxtNode
718 0 : (SwNodeIndex( GetNodes().GetEndOfAutotext()),
719 0 : GetTxtCollFromPool( nCollId ));
720 0 : SwCntntNode * pAnchorNode = pAnchorPos->nNode.GetNode().GetCntntNode();
721 :
722 0 : const SfxPoolItem * pItem = NULL;
723 :
724 0 : if (bCalledFromShell && !lcl_IsItemSet(*pNewTxtNd, RES_PARATR_ADJUST) &&
725 0 : SFX_ITEM_SET == pAnchorNode->GetSwAttrSet().
726 0 : GetItemState(RES_PARATR_ADJUST, true, &pItem))
727 : {
728 0 : static_cast<SwCntntNode *>(pNewTxtNd)->SetAttr(*pItem);
729 : }
730 :
731 : pFmt = _MakeFlySection( *pAnchorPos, *pNewTxtNd,
732 0 : eAnchorType, pFlySet, pFrmFmt );
733 : }
734 0 : return pFmt;
735 : }
736 :
737 0 : SwFlyFrmFmt* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rSet,
738 : const SwSelBoxes* pSelBoxes,
739 : SwFrmFmt *pParent )
740 : {
741 0 : SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR );
742 :
743 0 : GetIDocumentUndoRedo().StartUndo( UNDO_INSLAYFMT, NULL );
744 :
745 : SwFlyFrmFmt* pFmt = MakeFlySection( rAnch.GetAnchorId(), rPam.GetPoint(),
746 0 : &rSet, pParent );
747 :
748 : // If content is selected, it becomes the new frame's content.
749 : // Namely, it is moved into the NodeArray's appropriate section.
750 :
751 0 : if( pFmt )
752 : {
753 : do { // middle check loop
754 0 : const SwFmtCntnt &rCntnt = pFmt->GetCntnt();
755 : OSL_ENSURE( rCntnt.GetCntntIdx(), "No content prepared." );
756 0 : SwNodeIndex aIndex( *(rCntnt.GetCntntIdx()), 1 );
757 0 : SwCntntNode *pNode = aIndex.GetNode().GetCntntNode();
758 :
759 : // Attention: Do not create an index on the stack, or we
760 : // cannot delete CntntNode in the end!
761 0 : SwPosition aPos( aIndex );
762 0 : aPos.nContent.Assign( pNode, 0 );
763 :
764 0 : if( pSelBoxes && !pSelBoxes->empty() )
765 : {
766 : // Table selection
767 : // Copy parts of a table: create a table with the same width as the
768 : // original one and move (copy and delete) the selected boxes.
769 : // The size is corrected on a percentage basis.
770 :
771 0 : SwTableNode* pTblNd = (SwTableNode*)(*pSelBoxes)[0]->
772 0 : GetSttNd()->FindTableNode();
773 0 : if( !pTblNd )
774 0 : break;
775 :
776 0 : SwTable& rTbl = pTblNd->GetTable();
777 :
778 : // Did we select the whole table?
779 0 : if( pSelBoxes->size() == rTbl.GetTabSortBoxes().size() )
780 : {
781 : // move the whole table
782 0 : SwNodeRange aRg( *pTblNd, 0, *pTblNd->EndOfSectionNode(), 1 );
783 :
784 : // If we move the whole table and it is located within a
785 : // FlyFrame, the we create a TextNode after it.
786 : // So that this FlyFrame is preserved.
787 0 : if( aRg.aEnd.GetNode().IsEndNode() )
788 0 : GetNodes().MakeTxtNode( aRg.aStart,
789 0 : (SwTxtFmtColl*)GetDfltTxtFmtColl() );
790 :
791 0 : MoveNodeRange( aRg, aPos.nNode, DOC_MOVEDEFAULT );
792 : }
793 : else
794 : {
795 0 : rTbl.MakeCopy( this, aPos, *pSelBoxes );
796 : // Don't delete a part of a table with row span!!
797 : // You could delete the content instead -> ToDo
798 : //rTbl.DeleteSel( this, *pSelBoxes, 0, 0, true, true );
799 : }
800 :
801 : // If the table is within the frame, then copy without the following TextNode
802 0 : aIndex = rCntnt.GetCntntIdx()->GetNode().EndOfSectionIndex() - 1;
803 : OSL_ENSURE( aIndex.GetNode().GetTxtNode(),
804 : "a TextNode should be here" );
805 0 : aPos.nContent.Assign( 0, 0 ); // Deregister index!
806 0 : GetNodes().Delete( aIndex, 1 );
807 :
808 : // This is a hack: whilst FlyFrames/Headers/Footers are not undoable we delete all Undo objects
809 0 : if( GetIDocumentUndoRedo().DoesUndo() )
810 : {
811 0 : GetIDocumentUndoRedo().DelAllUndoObj();
812 : }
813 : }
814 : else
815 : {
816 : // copy all Pams and then delete all
817 0 : SwPaM* pTmp = (SwPaM*)&rPam;
818 0 : bool bOldFlag = mbCopyIsMove;
819 0 : bool const bOldUndo = GetIDocumentUndoRedo().DoesUndo();
820 0 : bool const bOldRedlineMove(IsRedlineMove());
821 0 : mbCopyIsMove = true;
822 0 : GetIDocumentUndoRedo().DoUndo(false);
823 0 : SetRedlineMove(true);
824 0 : do {
825 0 : if( pTmp->HasMark() &&
826 0 : *pTmp->GetPoint() != *pTmp->GetMark() )
827 : {
828 0 : CopyRange( *pTmp, aPos, false );
829 : }
830 0 : pTmp = static_cast<SwPaM*>(pTmp->GetNext());
831 : } while ( &rPam != pTmp );
832 0 : SetRedlineMove(bOldRedlineMove);
833 0 : mbCopyIsMove = bOldFlag;
834 0 : GetIDocumentUndoRedo().DoUndo(bOldUndo);
835 :
836 0 : pTmp = (SwPaM*)&rPam;
837 0 : do {
838 0 : if( pTmp->HasMark() &&
839 0 : *pTmp->GetPoint() != *pTmp->GetMark() )
840 : {
841 0 : DeleteAndJoin( *pTmp );
842 : }
843 0 : pTmp = static_cast<SwPaM*>(pTmp->GetNext());
844 : } while ( &rPam != pTmp );
845 0 : }
846 : } while( false );
847 : }
848 :
849 0 : SetModified();
850 :
851 0 : GetIDocumentUndoRedo().EndUndo( UNDO_INSLAYFMT, NULL );
852 :
853 0 : return pFmt;
854 : }
855 :
856 : // Insert drawing object, which has to be already inserted in the DrawModel
857 0 : SwDrawFrmFmt* SwDoc::InsertDrawObj(
858 : const SwPaM &rRg,
859 : SdrObject& rDrawObj,
860 : const SfxItemSet& rFlyAttrSet )
861 : {
862 0 : SwDrawFrmFmt* pFmt = MakeDrawFrmFmt( OUString(), GetDfltFrmFmt() );
863 :
864 0 : const SwFmtAnchor* pAnchor = 0;
865 0 : rFlyAttrSet.GetItemState( RES_ANCHOR, false, (const SfxPoolItem**) &pAnchor );
866 0 : pFmt->SetFmtAttr( rFlyAttrSet );
867 :
868 : // Didn't set the Anchor yet?
869 : // DrawObjecte must never end up in the Header/Footer!
870 0 : RndStdIds eAnchorId = pAnchor != NULL ? pAnchor->GetAnchorId() : pFmt->GetAnchor().GetAnchorId();
871 0 : const bool bIsAtCntnt = (FLY_AT_PAGE != eAnchorId);
872 :
873 0 : const SwNodeIndex* pChkIdx = 0;
874 0 : if ( pAnchor == NULL )
875 : {
876 0 : pChkIdx = &rRg.GetPoint()->nNode;
877 : }
878 0 : else if ( bIsAtCntnt )
879 : {
880 : pChkIdx =
881 0 : pAnchor->GetCntntAnchor() ? &pAnchor->GetCntntAnchor()->nNode : &rRg.GetPoint()->nNode;
882 : }
883 :
884 : // allow drawing objects in header/footer, but control objects aren't allowed in header/footer.
885 0 : if( pChkIdx != NULL
886 0 : && ::CheckControlLayer( &rDrawObj )
887 0 : && IsInHeaderFooter( *pChkIdx ) )
888 : {
889 : // apply at-page anchor format
890 0 : eAnchorId = FLY_AT_PAGE;
891 0 : pFmt->SetFmtAttr( SwFmtAnchor( eAnchorId ) );
892 : }
893 0 : else if( pAnchor == NULL
894 0 : || ( bIsAtCntnt
895 0 : && pAnchor->GetCntntAnchor() == NULL ) )
896 : {
897 : // apply anchor format
898 0 : SwFmtAnchor aAnch( pAnchor != NULL ? *pAnchor : pFmt->GetAnchor() );
899 0 : eAnchorId = aAnch.GetAnchorId();
900 0 : if ( eAnchorId == FLY_AT_FLY )
901 : {
902 0 : SwPosition aPos( *rRg.GetNode()->FindFlyStartNode() );
903 0 : aAnch.SetAnchor( &aPos );
904 : }
905 : else
906 : {
907 0 : aAnch.SetAnchor( rRg.GetPoint() );
908 0 : if ( eAnchorId == FLY_AT_PAGE )
909 : {
910 0 : eAnchorId = rDrawObj.ISA( SdrUnoObj ) ? FLY_AS_CHAR : FLY_AT_PARA;
911 0 : aAnch.SetType( eAnchorId );
912 : }
913 : }
914 0 : pFmt->SetFmtAttr( aAnch );
915 : }
916 :
917 : // insert text attribute for as-character anchored drawing object
918 0 : if ( eAnchorId == FLY_AS_CHAR )
919 : {
920 0 : bool bAnchorAtPageAsFallback = true;
921 0 : const SwFmtAnchor& rDrawObjAnchorFmt = pFmt->GetAnchor();
922 0 : if ( rDrawObjAnchorFmt.GetCntntAnchor() != NULL )
923 : {
924 : SwTxtNode* pAnchorTxtNode =
925 0 : rDrawObjAnchorFmt.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
926 0 : if ( pAnchorTxtNode != NULL )
927 : {
928 0 : const sal_Int32 nStt = rDrawObjAnchorFmt.GetCntntAnchor()->nContent.GetIndex();
929 0 : SwFmtFlyCnt aFmt( pFmt );
930 0 : pAnchorTxtNode->InsertItem( aFmt, nStt, nStt );
931 0 : bAnchorAtPageAsFallback = false;
932 : }
933 : }
934 :
935 0 : if ( bAnchorAtPageAsFallback )
936 : {
937 : OSL_ENSURE( false, "SwDoc::InsertDrawObj(..) - missing content anchor for as-character anchored drawing object --> anchor at-page" );
938 0 : pFmt->SetFmtAttr( SwFmtAnchor( FLY_AT_PAGE ) );
939 : }
940 : }
941 :
942 0 : SwDrawContact* pContact = new SwDrawContact( pFmt, &rDrawObj );
943 :
944 : // Create Frames if necessary
945 0 : if( GetCurrentViewShell() )
946 : {
947 : // create layout representation
948 0 : pFmt->MakeFrms();
949 : // #i42319# - follow-up of #i35635#
950 : // move object to visible layer
951 : // #i79391#
952 0 : if ( pContact->GetAnchorFrm() )
953 : {
954 0 : pContact->MoveObjToVisibleLayer( &rDrawObj );
955 : }
956 : }
957 :
958 0 : if (GetIDocumentUndoRedo().DoesUndo())
959 : {
960 0 : GetIDocumentUndoRedo().AppendUndo( new SwUndoInsLayFmt(pFmt, 0, 0) );
961 : }
962 :
963 0 : SetModified();
964 0 : return pFmt;
965 : }
966 :
967 : /* ---------------------------------------------------------------------------
968 : paragraph frames - o.k. if the PaM includes the paragraph from the beginning
969 : to the beginning of the next paragraph at least
970 : frames at character - o.k. if the PaM starts at least at the same position
971 : as the frame
972 : ---------------------------------------------------------------------------*/
973 0 : static bool lcl_TstFlyRange( const SwPaM* pPam, const SwPosition* pFlyPos,
974 : RndStdIds nAnchorId )
975 : {
976 0 : bool bOk = false;
977 0 : const SwPaM* pTmp = pPam;
978 0 : do {
979 0 : const sal_uInt32 nFlyIndex = pFlyPos->nNode.GetIndex();
980 0 : const SwPosition* pPaMStart = pTmp->Start();
981 0 : const SwPosition* pPaMEnd = pTmp->End();
982 0 : const sal_uInt32 nPamStartIndex = pPaMStart->nNode.GetIndex();
983 0 : const sal_uInt32 nPamEndIndex = pPaMEnd->nNode.GetIndex();
984 0 : if (FLY_AT_PARA == nAnchorId)
985 0 : bOk = (nPamStartIndex < nFlyIndex && nPamEndIndex > nFlyIndex) ||
986 0 : (((nPamStartIndex == nFlyIndex) && (pPaMStart->nContent.GetIndex() == 0)) &&
987 0 : (nPamEndIndex > nFlyIndex));
988 : else
989 : {
990 0 : const sal_Int32 nFlyContentIndex = pFlyPos->nContent.GetIndex();
991 0 : const sal_Int32 nPamEndContentIndex = pPaMEnd->nContent.GetIndex();
992 0 : bOk = (nPamStartIndex < nFlyIndex &&
993 0 : (( nPamEndIndex > nFlyIndex )||
994 0 : ((nPamEndIndex == nFlyIndex) &&
995 : (nPamEndContentIndex > nFlyContentIndex))) )
996 0 : ||
997 0 : (((nPamStartIndex == nFlyIndex) &&
998 0 : (pPaMStart->nContent.GetIndex() <= nFlyContentIndex)) &&
999 0 : ((nPamEndIndex > nFlyIndex) ||
1000 0 : (nPamEndContentIndex > nFlyContentIndex )));
1001 : }
1002 :
1003 0 : } while( !bOk && pPam != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
1004 0 : return bOk;
1005 : }
1006 :
1007 0 : SwPosFlyFrms SwDoc::GetAllFlyFmts( const SwPaM* pCmpRange, bool bDrawAlso,
1008 : bool bAsCharAlso ) const
1009 : {
1010 0 : SwPosFlyFrms aRetval;
1011 : SwFrmFmt *pFly;
1012 :
1013 : // collect all anchored somehow to paragraphs
1014 0 : for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->size(); ++n )
1015 : {
1016 0 : pFly = (*GetSpzFrmFmts())[ n ];
1017 0 : bool bDrawFmt = bDrawAlso ? RES_DRAWFRMFMT == pFly->Which() : false;
1018 0 : bool bFlyFmt = RES_FLYFRMFMT == pFly->Which();
1019 0 : if( bFlyFmt || bDrawFmt )
1020 : {
1021 0 : const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1022 0 : SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
1023 0 : if (pAPos &&
1024 0 : ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
1025 0 : (FLY_AT_FLY == rAnchor.GetAnchorId()) ||
1026 0 : (FLY_AT_CHAR == rAnchor.GetAnchorId()) ||
1027 0 : ((FLY_AS_CHAR == rAnchor.GetAnchorId()) && bAsCharAlso)))
1028 : {
1029 0 : if( pCmpRange &&
1030 0 : !lcl_TstFlyRange( pCmpRange, pAPos, rAnchor.GetAnchorId() ))
1031 0 : continue; // not a valid FlyFrame
1032 0 : aRetval.insert(SwPosFlyFrmPtr(new SwPosFlyFrm(pAPos->nNode, pFly, aRetval.size())));
1033 : }
1034 : }
1035 : }
1036 :
1037 : // If we don't have a layout we can't get page anchored FlyFrames.
1038 : // Also, page anchored FlyFrames are only returned if no range is specified.
1039 0 : if( !GetCurrentViewShell() || pCmpRange )
1040 : {
1041 0 : return aRetval;
1042 : }
1043 :
1044 0 : SwPageFrm *pPage = (SwPageFrm*)GetCurrentLayout()->GetLower();
1045 0 : while( pPage )
1046 : {
1047 0 : if( pPage->GetSortedObjs() )
1048 : {
1049 0 : SwSortedObjs &rObjs = *pPage->GetSortedObjs();
1050 0 : for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
1051 : {
1052 0 : SwAnchoredObject* pAnchoredObj = rObjs[i];
1053 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
1054 0 : pFly = &(pAnchoredObj->GetFrmFmt());
1055 0 : else if ( bDrawAlso )
1056 0 : pFly = &(pAnchoredObj->GetFrmFmt());
1057 : else
1058 0 : continue;
1059 :
1060 0 : const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1061 0 : if ((FLY_AT_PARA != rAnchor.GetAnchorId()) &&
1062 0 : (FLY_AT_FLY != rAnchor.GetAnchorId()) &&
1063 0 : (FLY_AT_CHAR != rAnchor.GetAnchorId()))
1064 : {
1065 0 : const SwCntntFrm * pCntntFrm = pPage->FindFirstBodyCntnt();
1066 0 : if ( !pCntntFrm )
1067 : {
1068 : // Oops! An empty page.
1069 : // In order not to loose the whole frame (RTF) we
1070 : // look for the last Cntnt before the page.
1071 0 : SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev();
1072 0 : while ( !pCntntFrm && pPrv )
1073 : {
1074 0 : pCntntFrm = pPrv->FindFirstBodyCntnt();
1075 0 : pPrv = (SwPageFrm*)pPrv->GetPrev();
1076 : }
1077 : }
1078 0 : if ( pCntntFrm )
1079 : {
1080 0 : SwNodeIndex aIdx( *pCntntFrm->GetNode() );
1081 0 : aRetval.insert(SwPosFlyFrmPtr(new SwPosFlyFrm(aIdx, pFly, aRetval.size())));
1082 : }
1083 : }
1084 : }
1085 : }
1086 0 : pPage = (SwPageFrm*)pPage->GetNext();
1087 : }
1088 :
1089 0 : return aRetval;
1090 : }
1091 :
1092 : /* #i6447# changed behaviour if lcl_CpyAttr:
1093 :
1094 : If the old item set contains the item to set (no inheritance) copy the item
1095 : into the new set.
1096 :
1097 : If the old item set contains the item by inheritance and the new set
1098 : contains the item, too:
1099 : If the two items differ copy the item from the old set to the new set.
1100 :
1101 : Otherwise the new set will not be changed.
1102 : */
1103 0 : static void lcl_CpyAttr( SfxItemSet &rNewSet, const SfxItemSet &rOldSet, sal_uInt16 nWhich )
1104 : {
1105 0 : const SfxPoolItem *pOldItem = NULL, *pNewItem = NULL;
1106 :
1107 0 : rOldSet.GetItemState( nWhich, false, &pOldItem);
1108 0 : if (pOldItem != NULL)
1109 0 : rNewSet.Put( *pOldItem );
1110 : else
1111 : {
1112 0 : pOldItem = rOldSet.GetItem( nWhich, true);
1113 0 : if (pOldItem != NULL)
1114 : {
1115 0 : pNewItem = rNewSet.GetItem( nWhich, true);
1116 0 : if (pNewItem != NULL)
1117 : {
1118 0 : if (*pOldItem != *pNewItem)
1119 0 : rNewSet.Put( *pOldItem );
1120 : }
1121 : else {
1122 : OSL_FAIL("What am I doing here?");
1123 : }
1124 : }
1125 : else {
1126 : OSL_FAIL("What am I doing here?");
1127 : }
1128 : }
1129 :
1130 0 : }
1131 :
1132 : static SwFlyFrmFmt *
1133 0 : lcl_InsertLabel(SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1134 : SwUndoInsertLabel *const pUndo,
1135 : SwLabelType const eType, OUString const& rTxt, OUString const& rSeparator,
1136 : const OUString& rNumberingSeparator,
1137 : const sal_Bool bBefore, const sal_uInt16 nId, const sal_uLong nNdIdx,
1138 : const OUString& rCharacterStyle,
1139 : const sal_Bool bCpyBrd )
1140 : {
1141 0 : ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1142 :
1143 0 : bool bTable = false; // To save some code.
1144 :
1145 : // Get the field first, beause we retrieve the TxtColl via the field's name
1146 : OSL_ENSURE( nId == USHRT_MAX || nId < rDoc.GetFldTypes()->size(),
1147 : "FldType index out of bounds." );
1148 0 : SwFieldType *pType = (nId != USHRT_MAX) ? (*rDoc.GetFldTypes())[nId] : NULL;
1149 : OSL_ENSURE(!pType || pType->Which() == RES_SETEXPFLD, "wrong Id for Label");
1150 :
1151 0 : SwTxtFmtColl * pColl = NULL;
1152 0 : if( pType )
1153 : {
1154 0 : for( sal_uInt16 i = pTxtFmtCollTbl->size(); i; )
1155 : {
1156 0 : if( (*pTxtFmtCollTbl)[ --i ]->GetName()==pType->GetName() )
1157 : {
1158 0 : pColl = (*pTxtFmtCollTbl)[i];
1159 0 : break;
1160 : }
1161 : }
1162 : OSL_ENSURE( pColl, "no text collection found" );
1163 : }
1164 :
1165 0 : if( !pColl )
1166 : {
1167 0 : pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1168 : }
1169 :
1170 0 : SwTxtNode *pNew = NULL;
1171 0 : SwFlyFrmFmt* pNewFmt = NULL;
1172 :
1173 0 : switch ( eType )
1174 : {
1175 : case LTYPE_TABLE:
1176 0 : bTable = true;
1177 : // no break here
1178 : case LTYPE_FLY:
1179 : // At the FlySection's Beginning/End insert the corresponding Node with it's Field.
1180 : // The Frame is created automatically.
1181 : {
1182 0 : SwStartNode *pSttNd = rDoc.GetNodes()[nNdIdx]->GetStartNode();
1183 : OSL_ENSURE( pSttNd, "No StartNode in InsertLabel." );
1184 : sal_uLong nNode;
1185 0 : if( bBefore )
1186 : {
1187 0 : nNode = pSttNd->GetIndex();
1188 0 : if( !bTable )
1189 0 : ++nNode;
1190 : }
1191 : else
1192 : {
1193 0 : nNode = pSttNd->EndOfSectionIndex();
1194 0 : if( bTable )
1195 0 : ++nNode;
1196 : }
1197 :
1198 0 : if( pUndo )
1199 0 : pUndo->SetNodePos( nNode );
1200 :
1201 : // Create Node for labeling paragraph.
1202 0 : SwNodeIndex aIdx( rDoc.GetNodes(), nNode );
1203 0 : pNew = rDoc.GetNodes().MakeTxtNode( aIdx, pColl );
1204 : }
1205 0 : break;
1206 :
1207 : case LTYPE_OBJECT:
1208 : {
1209 : // Destroy Frame,
1210 : // insert new Frame,
1211 : // insert the corresponding Node with Field into the new Frame,
1212 : // insert the old Frame with the Object (Picture/OLE) paragraph-bound into the new Frame,
1213 : // create Frames.
1214 :
1215 : // Get the FlyFrame's Format and decouple the Layout.
1216 0 : SwFrmFmt *pOldFmt = rDoc.GetNodes()[nNdIdx]->GetFlyFmt();
1217 : OSL_ENSURE( pOldFmt, "Couldn't find the Fly's Format." );
1218 : // #i115719#
1219 : // <title> and <description> attributes are lost when calling <DelFrms()>.
1220 : // Thus, keep them and restore them after the calling <MakeFrms()>
1221 0 : const bool bIsSwFlyFrmFmtInstance( dynamic_cast<SwFlyFrmFmt*>(pOldFmt) != 0 );
1222 : const OUString sTitle( bIsSwFlyFrmFmtInstance
1223 : ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjTitle()
1224 0 : : OUString() );
1225 : const OUString sDescription( bIsSwFlyFrmFmtInstance
1226 : ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjDescription()
1227 0 : : OUString() );
1228 0 : pOldFmt->DelFrms();
1229 :
1230 : pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1231 0 : rDoc.GetFrmFmtFromPool(RES_POOLFRM_FRAME) );
1232 :
1233 : /* #i6447#: Only the selected items are copied from the old
1234 : format. */
1235 0 : SfxItemSet* pNewSet = pNewFmt->GetAttrSet().Clone( true );
1236 :
1237 : // Copy only the set attributes.
1238 : // The others should apply from the Templates.
1239 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PRINT );
1240 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_OPAQUE );
1241 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PROTECT );
1242 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1243 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_VERT_ORIENT );
1244 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_HORI_ORIENT );
1245 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_LR_SPACE );
1246 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_UL_SPACE );
1247 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_BACKGROUND );
1248 0 : if( bCpyBrd )
1249 : {
1250 : // If there's no BoxItem at graphic, but the new Format has one, then set the
1251 : // default item in the new Set. Because the graphic's size has never changed!
1252 : const SfxPoolItem *pItem;
1253 0 : if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1254 0 : GetItemState( RES_BOX, true, &pItem ))
1255 0 : pNewSet->Put( *pItem );
1256 0 : else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1257 0 : GetItemState( RES_BOX, true ))
1258 0 : pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1259 :
1260 0 : if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1261 0 : GetItemState( RES_SHADOW, true, &pItem ))
1262 0 : pNewSet->Put( *pItem );
1263 0 : else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1264 0 : GetItemState( RES_SHADOW, true ))
1265 0 : pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1266 : }
1267 : else
1268 : {
1269 : // Hard-set the attributes, because they could come from the Template
1270 : // and then size calculations could not be correct anymore.
1271 0 : pNewSet->Put( SvxBoxItem(RES_BOX) );
1272 0 : pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1273 : }
1274 :
1275 : // Always transfer the anchor, which is a hard attribute anyways.
1276 0 : pNewSet->Put( pOldFmt->GetAnchor() );
1277 :
1278 : // The new one should be changeable in its height.
1279 0 : SwFmtFrmSize aFrmSize( pOldFmt->GetFrmSize() );
1280 0 : aFrmSize.SetHeightSizeType( ATT_MIN_SIZE );
1281 0 : pNewSet->Put( aFrmSize );
1282 :
1283 0 : SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection(
1284 0 : SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1285 0 : SwFlyStartNode, pColl );
1286 0 : pNewSet->Put( SwFmtCntnt( pSttNd ));
1287 :
1288 0 : pNewFmt->SetFmtAttr( *pNewSet );
1289 :
1290 : // InCntnts need to be treated in a special way:
1291 : // The TxtAttribute needs to be destroyed.
1292 : // Unfortunately, this also destroys the Format next to the Frames.
1293 : // To avoid this, we disconnect the attribute from the Format.
1294 :
1295 0 : const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1296 0 : if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1297 : {
1298 0 : const SwPosition *pPos = rAnchor.GetCntntAnchor();
1299 0 : SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1300 : OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1301 0 : const sal_Int32 nIdx = pPos->nContent.GetIndex();
1302 : SwTxtAttr * const pHnt =
1303 0 : pTxtNode->GetTxtAttrForCharAt(nIdx, RES_TXTATR_FLYCNT);
1304 :
1305 : OSL_ENSURE( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1306 : "Missing FlyInCnt-Hint." );
1307 : OSL_ENSURE( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pOldFmt,
1308 : "Wrong TxtFlyCnt-Hint." );
1309 :
1310 0 : const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt(
1311 0 : pNewFmt );
1312 : }
1313 :
1314 : // The old one should not have a flow and it should be adjusted to above and
1315 : // middle.
1316 : // Also, the width should be 100% and it should also adjust the hight, if changed.
1317 0 : pNewSet->ClearItem();
1318 :
1319 0 : pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1320 0 : pNewSet->Put( SvxOpaqueItem( RES_OPAQUE, true ) );
1321 :
1322 0 : sal_Int16 eVert = bBefore ? text::VertOrientation::BOTTOM : text::VertOrientation::TOP;
1323 0 : pNewSet->Put( SwFmtVertOrient( 0, eVert ) );
1324 0 : pNewSet->Put( SwFmtHoriOrient( 0, text::HoriOrientation::CENTER ) );
1325 :
1326 0 : aFrmSize = pOldFmt->GetFrmSize();
1327 0 : aFrmSize.SetWidthPercent( 0 );
1328 0 : aFrmSize.SetHeightPercent( 255 );
1329 0 : pNewSet->Put( aFrmSize );
1330 :
1331 : // Hard-set the attributes, because they could come from the Template
1332 : // and then size calculations could not be correct anymore.
1333 0 : if( bCpyBrd )
1334 : {
1335 0 : pNewSet->Put( SvxBoxItem(RES_BOX) );
1336 0 : pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1337 : }
1338 0 : pNewSet->Put( SvxLRSpaceItem(RES_LR_SPACE) );
1339 0 : pNewSet->Put( SvxULSpaceItem(RES_UL_SPACE) );
1340 :
1341 : // The old one is paragraph-bound to the paragraph in the new one.
1342 0 : SwFmtAnchor aAnch( FLY_AT_PARA );
1343 0 : SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1344 0 : pNew = aAnchIdx.GetNode().GetTxtNode();
1345 0 : SwPosition aPos( aAnchIdx );
1346 0 : aAnch.SetAnchor( &aPos );
1347 0 : pNewSet->Put( aAnch );
1348 :
1349 0 : if( pUndo )
1350 0 : pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1351 : else
1352 0 : pOldFmt->SetFmtAttr( *pNewSet );
1353 :
1354 0 : delete pNewSet;
1355 :
1356 : // Have only the FlyFrames created.
1357 : // We leave this to established methods (especially for InCntFlys).
1358 0 : pNewFmt->MakeFrms();
1359 : // #i115719#
1360 0 : if ( bIsSwFlyFrmFmtInstance )
1361 : {
1362 0 : static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjTitle( sTitle );
1363 0 : static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjDescription( sDescription );
1364 0 : }
1365 : }
1366 0 : break;
1367 :
1368 : default:
1369 : OSL_ENSURE(false, "unknown LabelType?");
1370 : }
1371 : OSL_ENSURE( pNew, "No Label inserted" );
1372 0 : if( pNew )
1373 : {
1374 : // #i61007# order of captions
1375 0 : sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1376 : // Work up OUString
1377 0 : OUString aTxt;
1378 0 : if( bOrderNumberingFirst )
1379 : {
1380 0 : aTxt = rNumberingSeparator;
1381 : }
1382 0 : if( pType)
1383 : {
1384 0 : aTxt += pType->GetName();
1385 0 : if( !bOrderNumberingFirst )
1386 0 : aTxt += " ";
1387 : }
1388 0 : sal_Int32 nIdx = aTxt.getLength();
1389 0 : if( !rTxt.isEmpty() )
1390 : {
1391 0 : aTxt += rSeparator;
1392 : }
1393 0 : const sal_Int32 nSepIdx = aTxt.getLength();
1394 0 : aTxt += rTxt;
1395 :
1396 : // Insert string
1397 0 : SwIndex aIdx( pNew, 0 );
1398 0 : pNew->InsertText( aTxt, aIdx );
1399 :
1400 : // Insert field
1401 0 : if(pType)
1402 : {
1403 0 : SwSetExpField aFld( (SwSetExpFieldType*)pType, OUString(), SVX_NUM_ARABIC);
1404 0 : if( bOrderNumberingFirst )
1405 0 : nIdx = 0;
1406 0 : SwFmtFld aFmt( aFld );
1407 0 : pNew->InsertItem( aFmt, nIdx, nIdx );
1408 0 : if(!rCharacterStyle.isEmpty())
1409 : {
1410 0 : SwCharFmt* pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1411 0 : if( !pCharFmt )
1412 : {
1413 0 : const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName(rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
1414 0 : pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1415 : }
1416 0 : if (pCharFmt)
1417 : {
1418 0 : SwFmtCharFmt aCharFmt( pCharFmt );
1419 : pNew->InsertItem( aCharFmt, 0,
1420 0 : nSepIdx + 1, nsSetAttrMode::SETATTR_DONTEXPAND );
1421 : }
1422 0 : }
1423 : }
1424 :
1425 0 : if ( bTable )
1426 : {
1427 0 : if ( bBefore )
1428 : {
1429 0 : if ( !pNew->GetSwAttrSet().GetKeep().GetValue() )
1430 0 : pNew->SetAttr( SvxFmtKeepItem( true, RES_KEEP ) );
1431 : }
1432 : else
1433 : {
1434 : SwTableNode *const pNd =
1435 0 : rDoc.GetNodes()[nNdIdx]->GetStartNode()->GetTableNode();
1436 0 : SwTable &rTbl = pNd->GetTable();
1437 0 : if ( !rTbl.GetFrmFmt()->GetKeep().GetValue() )
1438 0 : rTbl.GetFrmFmt()->SetFmtAttr( SvxFmtKeepItem( true, RES_KEEP ) );
1439 0 : if ( pUndo )
1440 0 : pUndo->SetUndoKeep();
1441 : }
1442 : }
1443 0 : rDoc.SetModified();
1444 : }
1445 :
1446 0 : return pNewFmt;
1447 : }
1448 :
1449 : SwFlyFrmFmt *
1450 0 : SwDoc::InsertLabel(
1451 : SwLabelType const eType, OUString const& rTxt, OUString const& rSeparator,
1452 : OUString const& rNumberingSeparator,
1453 : sal_Bool const bBefore, sal_uInt16 const nId, sal_uLong const nNdIdx,
1454 : OUString const& rCharacterStyle,
1455 : sal_Bool const bCpyBrd )
1456 : {
1457 0 : SwUndoInsertLabel * pUndo(0);
1458 0 : if (GetIDocumentUndoRedo().DoesUndo())
1459 : {
1460 : pUndo = new SwUndoInsertLabel(
1461 : eType, rTxt, rSeparator, rNumberingSeparator,
1462 0 : bBefore, nId, rCharacterStyle, bCpyBrd );
1463 : }
1464 :
1465 : SwFlyFrmFmt *const pNewFmt = lcl_InsertLabel(*this, mpTxtFmtCollTbl, pUndo,
1466 : eType, rTxt, rSeparator, rNumberingSeparator, bBefore,
1467 0 : nId, nNdIdx, rCharacterStyle, bCpyBrd);
1468 :
1469 0 : if (pUndo)
1470 : {
1471 0 : GetIDocumentUndoRedo().AppendUndo(pUndo);
1472 : }
1473 : else
1474 : {
1475 0 : GetIDocumentUndoRedo().DelAllUndoObj();
1476 : }
1477 :
1478 0 : return pNewFmt;
1479 : }
1480 :
1481 : static SwFlyFrmFmt *
1482 0 : lcl_InsertDrawLabel( SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1483 : SwUndoInsertLabel *const pUndo, SwDrawFrmFmt *const pOldFmt,
1484 : OUString const& rTxt,
1485 : const OUString& rSeparator,
1486 : const OUString& rNumberSeparator,
1487 : const sal_uInt16 nId,
1488 : const OUString& rCharacterStyle,
1489 : SdrObject& rSdrObj )
1490 : {
1491 0 : ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1492 0 : ::sw::DrawUndoGuard const drawUndoGuard(rDoc.GetIDocumentUndoRedo());
1493 :
1494 : // Because we get by the TxtColl's name, we need to create the field first.
1495 : OSL_ENSURE( nId == USHRT_MAX || nId < rDoc.GetFldTypes()->size(),
1496 : "FldType index out of bounds" );
1497 0 : SwFieldType *pType = nId != USHRT_MAX ? (*rDoc.GetFldTypes())[nId] : 0;
1498 : OSL_ENSURE( !pType || pType->Which() == RES_SETEXPFLD, "Wrong label id" );
1499 :
1500 0 : SwTxtFmtColl *pColl = NULL;
1501 0 : if( pType )
1502 : {
1503 0 : for( sal_uInt16 i = pTxtFmtCollTbl->size(); i; )
1504 : {
1505 0 : if( (*pTxtFmtCollTbl)[ --i ]->GetName()==pType->GetName() )
1506 : {
1507 0 : pColl = (*pTxtFmtCollTbl)[i];
1508 0 : break;
1509 : }
1510 : }
1511 : OSL_ENSURE( pColl, "no text collection found" );
1512 : }
1513 :
1514 0 : if( !pColl )
1515 : {
1516 0 : pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1517 : }
1518 :
1519 0 : SwTxtNode* pNew = NULL;
1520 0 : SwFlyFrmFmt* pNewFmt = NULL;
1521 :
1522 : // Destroy Frame,
1523 : // insert new Frame,
1524 : // insert the corresponding Node with Field into the new Frame,
1525 : // insert the old Frame with the Object (Picture/OLE) paragraph-bound into the new Frame,
1526 : // create Frames.
1527 :
1528 : // Keep layer ID of drawing object before removing
1529 : // its frames.
1530 : // Note: The layer ID is passed to the undo and have to be the correct value.
1531 : // Removing the frames of the drawing object changes its layer.
1532 0 : const SdrLayerID nLayerId = rSdrObj.GetLayer();
1533 :
1534 0 : pOldFmt->DelFrms();
1535 :
1536 : // InCntnts need to be treated in a special way:
1537 : // The TxtAttribute needs to be destroyed.
1538 : // Unfortunately, this also destroys the Format next to the Frames.
1539 : // To avoid this, we disconnect the attribute from the Format.
1540 0 : SfxItemSet* pNewSet = pOldFmt->GetAttrSet().Clone( false );
1541 :
1542 : // Protect the Frame's size and position
1543 0 : if ( rSdrObj.IsMoveProtect() || rSdrObj.IsResizeProtect() )
1544 : {
1545 0 : SvxProtectItem aProtect(RES_PROTECT);
1546 0 : aProtect.SetCntntProtect( false );
1547 0 : aProtect.SetPosProtect( rSdrObj.IsMoveProtect() );
1548 0 : aProtect.SetSizeProtect( rSdrObj.IsResizeProtect() );
1549 0 : pNewSet->Put( aProtect );
1550 : }
1551 :
1552 : // Take over the text wrap
1553 0 : lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1554 :
1555 : // Send the frame to the back, if needed.
1556 : // Consider the 'invisible' hell layer.
1557 0 : if ( rDoc.GetHellId() != nLayerId &&
1558 0 : rDoc.GetInvisibleHellId() != nLayerId )
1559 : {
1560 0 : SvxOpaqueItem aOpaque( RES_OPAQUE );
1561 0 : aOpaque.SetValue( true );
1562 0 : pNewSet->Put( aOpaque );
1563 : }
1564 :
1565 : // Take over position
1566 : // #i26791# - use directly drawing object's positioning attributes
1567 0 : pNewSet->Put( pOldFmt->GetHoriOrient() );
1568 0 : pNewSet->Put( pOldFmt->GetVertOrient() );
1569 :
1570 0 : pNewSet->Put( pOldFmt->GetAnchor() );
1571 :
1572 : // The new one should be variable in its height!
1573 0 : Size aSz( rSdrObj.GetCurrentBoundRect().GetSize() );
1574 0 : SwFmtFrmSize aFrmSize( ATT_MIN_SIZE, aSz.Width(), aSz.Height() );
1575 0 : pNewSet->Put( aFrmSize );
1576 :
1577 : // Apply the margin to the new Frame.
1578 : // Don't set a border, use the one from the Template.
1579 0 : pNewSet->Put( pOldFmt->GetLRSpace() );
1580 0 : pNewSet->Put( pOldFmt->GetULSpace() );
1581 :
1582 : SwStartNode* pSttNd =
1583 0 : rDoc.GetNodes().MakeTextSection(
1584 0 : SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1585 0 : SwFlyStartNode, pColl );
1586 :
1587 : pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1588 0 : rDoc.GetFrmFmtFromPool( RES_POOLFRM_FRAME ) );
1589 :
1590 : // Set border and shadow to default if the template contains any.
1591 0 : if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState( RES_BOX, true ))
1592 0 : pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1593 :
1594 0 : if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState(RES_SHADOW,true))
1595 0 : pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1596 :
1597 0 : pNewFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
1598 0 : pNewFmt->SetFmtAttr( *pNewSet );
1599 :
1600 0 : const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1601 0 : if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1602 : {
1603 0 : const SwPosition *pPos = rAnchor.GetCntntAnchor();
1604 0 : SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1605 : OSL_ENSURE( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1606 0 : const sal_Int32 nIdx = pPos->nContent.GetIndex();
1607 : SwTxtAttr * const pHnt =
1608 0 : pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
1609 :
1610 : #if OSL_DEBUG_LEVEL > 0
1611 : OSL_ENSURE( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1612 : "Missing FlyInCnt-Hint." );
1613 : OSL_ENSURE( pHnt && ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).
1614 : GetFrmFmt() == (SwFrmFmt*)pOldFmt,
1615 : "Wrong TxtFlyCnt-Hint." );
1616 : #endif
1617 0 : const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt( pNewFmt );
1618 : }
1619 :
1620 : // The old one should not have a flow
1621 : // and it should be adjusted to above and middle.
1622 0 : pNewSet->ClearItem();
1623 :
1624 0 : pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1625 0 : if (nLayerId == rDoc.GetHellId())
1626 : {
1627 : // Consider drawing objects in the 'invisible' hell layer
1628 0 : rSdrObj.SetLayer( rDoc.GetHeavenId() );
1629 : }
1630 0 : else if (nLayerId == rDoc.GetInvisibleHellId())
1631 : {
1632 0 : rSdrObj.SetLayer( rDoc.GetInvisibleHeavenId() );
1633 : }
1634 0 : pNewSet->Put( SvxLRSpaceItem( RES_LR_SPACE ) );
1635 0 : pNewSet->Put( SvxULSpaceItem( RES_UL_SPACE ) );
1636 :
1637 : // #i26791# - set position of the drawing object, which is labeled.
1638 0 : pNewSet->Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ) );
1639 0 : pNewSet->Put( SwFmtHoriOrient( 0, text::HoriOrientation::CENTER, text::RelOrientation::FRAME ) );
1640 :
1641 : // The old one is paragraph-bound to the new one's paragraph.
1642 0 : SwFmtAnchor aAnch( FLY_AT_PARA );
1643 0 : SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1644 0 : pNew = aAnchIdx.GetNode().GetTxtNode();
1645 0 : SwPosition aPos( aAnchIdx );
1646 0 : aAnch.SetAnchor( &aPos );
1647 0 : pNewSet->Put( aAnch );
1648 :
1649 0 : if( pUndo )
1650 : {
1651 0 : pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1652 : // #i26791# - position no longer needed
1653 0 : pUndo->SetDrawObj( nLayerId );
1654 : }
1655 : else
1656 0 : pOldFmt->SetFmtAttr( *pNewSet );
1657 :
1658 0 : delete pNewSet;
1659 :
1660 : // Have only the FlyFrames created.
1661 : // We leave this to established methods (especially for InCntFlys).
1662 0 : pNewFmt->MakeFrms();
1663 :
1664 : OSL_ENSURE( pNew, "No Label inserted" );
1665 :
1666 0 : if( pNew )
1667 : {
1668 : //#i61007# order of captions
1669 0 : sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1670 :
1671 : // prepare string
1672 0 : OUString aTxt;
1673 0 : if( bOrderNumberingFirst )
1674 : {
1675 0 : aTxt = rNumberSeparator;
1676 : }
1677 0 : if ( pType )
1678 : {
1679 0 : aTxt += pType->GetName();
1680 0 : if( !bOrderNumberingFirst )
1681 0 : aTxt += " ";
1682 : }
1683 0 : sal_Int32 nIdx = aTxt.getLength();
1684 0 : aTxt += rSeparator;
1685 0 : const sal_Int32 nSepIdx = aTxt.getLength();
1686 0 : aTxt += rTxt;
1687 :
1688 : // insert text
1689 0 : SwIndex aIdx( pNew, 0 );
1690 0 : pNew->InsertText( aTxt, aIdx );
1691 :
1692 : // insert field
1693 0 : if ( pType )
1694 : {
1695 0 : SwSetExpField aFld( (SwSetExpFieldType*)pType, OUString(), SVX_NUM_ARABIC );
1696 0 : if( bOrderNumberingFirst )
1697 0 : nIdx = 0;
1698 0 : SwFmtFld aFmt( aFld );
1699 0 : pNew->InsertItem( aFmt, nIdx, nIdx );
1700 0 : if ( !rCharacterStyle.isEmpty() )
1701 : {
1702 0 : SwCharFmt * pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1703 0 : if ( !pCharFmt )
1704 : {
1705 0 : const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName( rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
1706 0 : pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1707 : }
1708 0 : if ( pCharFmt )
1709 : {
1710 0 : SwFmtCharFmt aCharFmt( pCharFmt );
1711 : pNew->InsertItem( aCharFmt, 0, nSepIdx + 1,
1712 0 : nsSetAttrMode::SETATTR_DONTEXPAND );
1713 : }
1714 0 : }
1715 0 : }
1716 : }
1717 :
1718 0 : return pNewFmt;
1719 : }
1720 :
1721 0 : SwFlyFrmFmt* SwDoc::InsertDrawLabel(
1722 : OUString const& rTxt,
1723 : OUString const& rSeparator,
1724 : OUString const& rNumberSeparator,
1725 : sal_uInt16 const nId,
1726 : OUString const& rCharacterStyle,
1727 : SdrObject& rSdrObj )
1728 : {
1729 : SwDrawContact *const pContact =
1730 0 : static_cast<SwDrawContact*>(GetUserCall( &rSdrObj ));
1731 : OSL_ENSURE( RES_DRAWFRMFMT == pContact->GetFmt()->Which(),
1732 : "InsertDrawLabel(): not a DrawFrmFmt" );
1733 0 : if (!pContact)
1734 0 : return 0;
1735 :
1736 0 : SwDrawFrmFmt* pOldFmt = (SwDrawFrmFmt *)pContact->GetFmt();
1737 0 : if (!pOldFmt)
1738 0 : return 0;
1739 :
1740 0 : SwUndoInsertLabel * pUndo = 0;
1741 0 : if (GetIDocumentUndoRedo().DoesUndo())
1742 : {
1743 0 : GetIDocumentUndoRedo().ClearRedo();
1744 : pUndo = new SwUndoInsertLabel(
1745 : LTYPE_DRAW, rTxt, rSeparator, rNumberSeparator, sal_False,
1746 0 : nId, rCharacterStyle, sal_False );
1747 : }
1748 :
1749 : SwFlyFrmFmt *const pNewFmt = lcl_InsertDrawLabel(
1750 : *this, mpTxtFmtCollTbl, pUndo, pOldFmt,
1751 0 : rTxt, rSeparator, rNumberSeparator, nId, rCharacterStyle, rSdrObj);
1752 :
1753 0 : if (pUndo)
1754 : {
1755 0 : GetIDocumentUndoRedo().AppendUndo( pUndo );
1756 : }
1757 : else
1758 : {
1759 0 : GetIDocumentUndoRedo().DelAllUndoObj();
1760 : }
1761 :
1762 0 : return pNewFmt;
1763 : }
1764 :
1765 : // IDocumentTimerAccess methods ------------------------------------------
1766 :
1767 0 : void SwDoc::StartIdling()
1768 : {
1769 0 : mbStartIdleTimer = true;
1770 0 : if( !mIdleBlockCount )
1771 0 : maIdleTimer.Start();
1772 0 : }
1773 :
1774 0 : void SwDoc::StopIdling()
1775 : {
1776 0 : mbStartIdleTimer = false;
1777 0 : maIdleTimer.Stop();
1778 0 : }
1779 :
1780 0 : void SwDoc::BlockIdling()
1781 : {
1782 0 : maIdleTimer.Stop();
1783 0 : ++mIdleBlockCount;
1784 0 : }
1785 :
1786 0 : void SwDoc::UnblockIdling()
1787 : {
1788 0 : --mIdleBlockCount;
1789 0 : if( !mIdleBlockCount && mbStartIdleTimer && !maIdleTimer.IsActive() )
1790 0 : maIdleTimer.Start();
1791 0 : }
1792 :
1793 0 : void SwDoc::StartBackgroundJobs() {
1794 : // Trigger DoIdleJobs(), asynchronously.
1795 0 : maIdleTimer.Start();
1796 0 : }
1797 :
1798 0 : IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer )
1799 : {
1800 : #ifdef TIMELOG
1801 : static ::rtl::Logfile* pModLogFile = 0;
1802 : if( !pModLogFile )
1803 : pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
1804 : #endif
1805 :
1806 0 : SwRootFrm* pTmpRoot = GetCurrentLayout();
1807 0 : if( pTmpRoot &&
1808 0 : !SfxProgress::GetActiveProgress( mpDocShell ) )
1809 : {
1810 : SwViewShell *pSh, *pStartSh;
1811 0 : pSh = pStartSh = GetCurrentViewShell();
1812 0 : do {
1813 0 : if( pSh->ActionPend() )
1814 : {
1815 0 : pTimer->Start();
1816 0 : return 0;
1817 : }
1818 0 : pSh = (SwViewShell*)pSh->GetNext();
1819 : } while( pSh != pStartSh );
1820 :
1821 0 : if( pTmpRoot->IsNeedGrammarCheck() )
1822 : {
1823 0 : sal_Bool bIsOnlineSpell = pSh->GetViewOptions()->IsOnlineSpell();
1824 0 : sal_Bool bIsAutoGrammar = sal_False;
1825 : SvtLinguConfig().GetProperty( OUString(
1826 0 : UPN_IS_GRAMMAR_AUTO ) ) >>= bIsAutoGrammar;
1827 :
1828 0 : if (bIsOnlineSpell && bIsAutoGrammar)
1829 0 : StartGrammarChecking( *this );
1830 : }
1831 0 : std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();
1832 0 : std::set<SwRootFrm*>::iterator pLayIter = aAllLayouts.begin();
1833 0 : for ( ;pLayIter != aAllLayouts.end();++pLayIter )
1834 : {
1835 0 : if ((*pLayIter)->IsIdleFormat())
1836 : {
1837 0 : (*pLayIter)->GetCurrShell()->LayoutIdle();
1838 :
1839 : // Defer the remaining work.
1840 0 : pTimer->Start();
1841 0 : return 0;
1842 : }
1843 : }
1844 :
1845 0 : SwFldUpdateFlags nFldUpdFlag = getFieldUpdateFlags(true);
1846 0 : if( ( AUTOUPD_FIELD_ONLY == nFldUpdFlag
1847 0 : || AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) &&
1848 0 : GetUpdtFlds().IsFieldsDirty()
1849 : // If we switch the field name the Fields are not updated.
1850 : // So the "backgorund update" should always be carried out
1851 : /* && !pStartSh->GetViewOptions()->IsFldName()*/ )
1852 : {
1853 0 : if ( GetUpdtFlds().IsInUpdateFlds() ||
1854 0 : IsExpFldsLocked() )
1855 : {
1856 0 : pTimer->Start();
1857 0 : return 0;
1858 : }
1859 :
1860 : // Action brackets!
1861 0 : GetUpdtFlds().SetInUpdateFlds( true );
1862 :
1863 0 : pTmpRoot->StartAllAction();
1864 :
1865 : // no jump on update of fields #i85168#
1866 0 : const sal_Bool bOldLockView = pStartSh->IsViewLocked();
1867 0 : pStartSh->LockView( sal_True );
1868 :
1869 0 : GetSysFldType( RES_CHAPTERFLD )->ModifyNotification( 0, 0 ); // ChapterField
1870 0 : UpdateExpFlds( 0, false ); // Updates ExpressionFields
1871 0 : UpdateTblFlds(NULL); // Tables
1872 0 : UpdateRefFlds(NULL); // References
1873 :
1874 0 : pTmpRoot->EndAllAction();
1875 :
1876 0 : pStartSh->LockView( bOldLockView );
1877 :
1878 0 : GetUpdtFlds().SetInUpdateFlds( false );
1879 0 : GetUpdtFlds().SetFieldsDirty( false );
1880 0 : }
1881 : }
1882 : #ifdef TIMELOG
1883 : if( pModLogFile && 1 != (long)pModLogFile )
1884 : delete pModLogFile, ((long&)pModLogFile) = 1;
1885 : #endif
1886 0 : return 0;
1887 : }
1888 :
1889 0 : IMPL_STATIC_LINK( SwDoc, BackgroundDone, SvxBrushItem*, EMPTYARG )
1890 : {
1891 : SwViewShell *pSh, *pStartSh;
1892 0 : pSh = pStartSh = pThis->GetCurrentViewShell();
1893 0 : if( pStartSh )
1894 0 : do {
1895 0 : if( pSh->GetWin() )
1896 : {
1897 : // Make sure to repaint with virtual device
1898 0 : pSh->LockPaint();
1899 0 : pSh->UnlockPaint( sal_True );
1900 : }
1901 0 : pSh = (SwViewShell*)pSh->GetNext();
1902 : } while( pSh != pStartSh );
1903 0 : return 0;
1904 : }
1905 :
1906 0 : static OUString lcl_GetUniqueFlyName( const SwDoc* pDoc, sal_uInt16 nDefStrId )
1907 : {
1908 0 : ResId aId( nDefStrId, *pSwResMgr );
1909 0 : OUString aName( aId );
1910 0 : sal_Int32 nNmLen = aName.getLength();
1911 :
1912 0 : const SwFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
1913 :
1914 0 : sal_uInt16 nNum, nTmp, nFlagSize = ( rFmts.size() / 8 ) +2;
1915 0 : sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
1916 : sal_uInt16 n;
1917 :
1918 0 : memset( pSetFlags, 0, nFlagSize );
1919 :
1920 0 : for( n = 0; n < rFmts.size(); ++n )
1921 : {
1922 0 : const SwFrmFmt* pFlyFmt = rFmts[ n ];
1923 0 : if( RES_FLYFRMFMT == pFlyFmt->Which() &&
1924 0 : pFlyFmt->GetName().startsWith( aName ) )
1925 : {
1926 : // Only get and set the Flag
1927 0 : nNum = static_cast< sal_uInt16 >( pFlyFmt->GetName().copy( nNmLen ).toInt32() );
1928 0 : if( nNum-- && nNum < rFmts.size() )
1929 0 : pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
1930 : }
1931 : }
1932 :
1933 : // All numbers are flagged accordingly, so determine the right one
1934 0 : nNum = rFmts.size();
1935 0 : for( n = 0; n < nFlagSize; ++n )
1936 0 : if( 0xff != ( nTmp = pSetFlags[ n ] ))
1937 : {
1938 : // so determine the number
1939 0 : nNum = n * 8;
1940 0 : while( nTmp & 1 )
1941 0 : ++nNum, nTmp >>= 1;
1942 0 : break;
1943 : }
1944 :
1945 0 : delete [] pSetFlags;
1946 0 : return aName += OUString::number( ++nNum );
1947 : }
1948 :
1949 0 : OUString SwDoc::GetUniqueGrfName() const
1950 : {
1951 0 : return lcl_GetUniqueFlyName( this, STR_GRAPHIC_DEFNAME );
1952 : }
1953 :
1954 0 : OUString SwDoc::GetUniqueOLEName() const
1955 : {
1956 0 : return lcl_GetUniqueFlyName( this, STR_OBJECT_DEFNAME );
1957 : }
1958 :
1959 0 : OUString SwDoc::GetUniqueFrameName() const
1960 : {
1961 0 : return lcl_GetUniqueFlyName( this, STR_FRAME_DEFNAME );
1962 : }
1963 :
1964 0 : const SwFlyFrmFmt* SwDoc::FindFlyByName( const OUString& rName, sal_Int8 nNdTyp ) const
1965 : {
1966 0 : const SwFrmFmts& rFmts = *GetSpzFrmFmts();
1967 0 : for( sal_uInt16 n = rFmts.size(); n; )
1968 : {
1969 0 : const SwFrmFmt* pFlyFmt = rFmts[ --n ];
1970 0 : const SwNodeIndex* pIdx = 0;
1971 0 : if( RES_FLYFRMFMT == pFlyFmt->Which() && pFlyFmt->GetName() == rName &&
1972 0 : 0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) &&
1973 0 : pIdx->GetNode().GetNodes().IsDocNodes() )
1974 : {
1975 0 : if( nNdTyp )
1976 : {
1977 : // query for the right NodeType
1978 0 : const SwNode* pNd = GetNodes()[ pIdx->GetIndex()+1 ];
1979 0 : if( nNdTyp == ND_TEXTNODE
1980 0 : ? !pNd->IsNoTxtNode()
1981 0 : : nNdTyp == pNd->GetNodeType() )
1982 0 : return (SwFlyFrmFmt*)pFlyFmt;
1983 : }
1984 : else
1985 0 : return (SwFlyFrmFmt*)pFlyFmt;
1986 : }
1987 : }
1988 0 : return 0;
1989 : }
1990 :
1991 0 : void SwDoc::SetFlyName( SwFlyFrmFmt& rFmt, const OUString& rName )
1992 : {
1993 0 : OUString sName( rName );
1994 0 : if( sName.isEmpty() || FindFlyByName( sName ) )
1995 : {
1996 0 : sal_uInt16 nTyp = STR_FRAME_DEFNAME;
1997 0 : const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx();
1998 0 : if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() )
1999 0 : switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2000 : {
2001 0 : case ND_GRFNODE: nTyp = STR_GRAPHIC_DEFNAME; break;
2002 0 : case ND_OLENODE: nTyp = STR_OBJECT_DEFNAME; break;
2003 : }
2004 0 : sName = lcl_GetUniqueFlyName( this, nTyp );
2005 : }
2006 0 : rFmt.SetName( sName, sal_True );
2007 0 : SetModified();
2008 0 : }
2009 :
2010 0 : void SwDoc::SetAllUniqueFlyNames()
2011 : {
2012 0 : sal_Int32 n, nFlyNum = 0, nGrfNum = 0, nOLENum = 0;
2013 :
2014 0 : ResId nFrmId( STR_FRAME_DEFNAME, *pSwResMgr ),
2015 0 : nGrfId( STR_GRAPHIC_DEFNAME, *pSwResMgr ),
2016 0 : nOLEId( STR_OBJECT_DEFNAME, *pSwResMgr );
2017 0 : OUString sFlyNm( nFrmId );
2018 0 : OUString sGrfNm( nGrfId );
2019 0 : OUString sOLENm( nOLEId );
2020 :
2021 0 : if( 255 < ( n = GetSpzFrmFmts()->size() ))
2022 0 : n = 255;
2023 0 : SwFrmFmts aArr;
2024 0 : aArr.reserve( n );
2025 : SwFrmFmt* pFlyFmt;
2026 0 : bool bContainsAtPageObjWithContentAnchor = false;
2027 :
2028 0 : for( n = GetSpzFrmFmts()->size(); n; )
2029 : {
2030 0 : if( RES_FLYFRMFMT == (pFlyFmt = (*GetSpzFrmFmts())[ --n ])->Which() )
2031 : {
2032 0 : sal_Int32 *pNum = 0;
2033 0 : const OUString aNm = pFlyFmt->GetName();
2034 0 : if ( !aNm.isEmpty() )
2035 : {
2036 0 : sal_Int32 nLen = 0;
2037 0 : if ( aNm.startsWith(sGrfNm) )
2038 : {
2039 0 : nLen = sGrfNm.getLength();
2040 0 : pNum = &nGrfNum;
2041 : }
2042 0 : else if( aNm.startsWith(sFlyNm) )
2043 : {
2044 0 : nLen = sFlyNm.getLength();
2045 0 : pNum = &nFlyNum;
2046 : }
2047 0 : else if( aNm.startsWith(sOLENm) )
2048 : {
2049 0 : nLen = sOLENm.getLength();
2050 0 : pNum = &nOLENum;
2051 : }
2052 :
2053 0 : if ( pNum )
2054 : {
2055 0 : const sal_Int32 nNewLen = aNm.copy( nLen ).toInt32();
2056 0 : if (*pNum < nNewLen)
2057 0 : *pNum = nNewLen;
2058 : }
2059 : }
2060 : else
2061 : // we want to set that afterwards
2062 0 : aArr.push_back( pFlyFmt );
2063 :
2064 : }
2065 0 : if ( !bContainsAtPageObjWithContentAnchor )
2066 : {
2067 0 : const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
2068 0 : if ( (FLY_AT_PAGE == rAnchor.GetAnchorId()) &&
2069 0 : rAnchor.GetCntntAnchor() )
2070 : {
2071 0 : bContainsAtPageObjWithContentAnchor = true;
2072 : }
2073 : }
2074 : }
2075 0 : SetContainsAtPageObjWithContentAnchor( bContainsAtPageObjWithContentAnchor );
2076 :
2077 : const SwNodeIndex* pIdx;
2078 :
2079 0 : for( n = aArr.size(); n; )
2080 0 : if( 0 != ( pIdx = ( pFlyFmt = aArr[ --n ])->GetCntnt().GetCntntIdx() )
2081 0 : && pIdx->GetNode().GetNodes().IsDocNodes() )
2082 : {
2083 : sal_uInt16 nNum;
2084 0 : OUString sNm;
2085 0 : switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2086 : {
2087 : case ND_GRFNODE:
2088 0 : sNm = sGrfNm;
2089 0 : nNum = ++nGrfNum;
2090 0 : break;
2091 : case ND_OLENODE:
2092 0 : sNm = sOLENm;
2093 0 : nNum = ++nOLENum;
2094 0 : break;
2095 : default:
2096 0 : sNm = sFlyNm;
2097 0 : nNum = ++nFlyNum;
2098 0 : break;
2099 : }
2100 0 : pFlyFmt->SetName( sNm + OUString::number( nNum ));
2101 : }
2102 0 : aArr.clear();
2103 :
2104 0 : if( !GetFtnIdxs().empty() )
2105 : {
2106 0 : SwTxtFtn::SetUniqueSeqRefNo( *this );
2107 : // #i52775# Chapter footnotes did not get updated correctly.
2108 : // Calling UpdateAllFtn() instead of UpdateFtn() solves this problem,
2109 : // but I do not dare to call UpdateAllFtn() in all cases: Safety first.
2110 0 : if ( FTNNUM_CHAPTER == GetFtnInfo().eNum )
2111 : {
2112 0 : GetFtnIdxs().UpdateAllFtn();
2113 : }
2114 : else
2115 : {
2116 0 : SwNodeIndex aTmp( GetNodes() );
2117 0 : GetFtnIdxs().UpdateFtn( aTmp );
2118 : }
2119 0 : }
2120 0 : }
2121 :
2122 0 : bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const
2123 : {
2124 : // If there's a Layout, use it!
2125 : // That can also be a Fly in a Fly in the Header.
2126 : // Is also used by sw3io, to determine if a Redline object is
2127 : // in the Header or Footer.
2128 : // Because Redlines are also attached to Start and EndNoden,
2129 : // the Index must not necessarily be from a ContentNode.
2130 0 : SwNode* pNd = &rIdx.GetNode();
2131 0 : if( pNd->IsCntntNode() && mpCurrentView )
2132 : {
2133 0 : const SwFrm *pFrm = pNd->GetCntntNode()->getLayoutFrm( GetCurrentLayout() );
2134 0 : if( pFrm )
2135 : {
2136 0 : const SwFrm *pUp = pFrm->GetUpper();
2137 0 : while ( pUp && !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
2138 : {
2139 0 : if ( pUp->IsFlyFrm() )
2140 0 : pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
2141 0 : pUp = pUp->GetUpper();
2142 : }
2143 0 : if ( pUp )
2144 0 : return true;
2145 :
2146 0 : return false;
2147 : }
2148 : }
2149 :
2150 0 : const SwNode* pFlyNd = pNd->FindFlyStartNode();
2151 0 : while( pFlyNd )
2152 : {
2153 : // get up by using the Anchor
2154 : sal_uInt16 n;
2155 0 : for( n = 0; n < GetSpzFrmFmts()->size(); ++n )
2156 : {
2157 0 : const SwFrmFmt* pFmt = (*GetSpzFrmFmts())[ n ];
2158 0 : const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
2159 0 : if( pIdx && pFlyNd == &pIdx->GetNode() )
2160 : {
2161 0 : const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
2162 0 : if ((FLY_AT_PAGE == rAnchor.GetAnchorId()) ||
2163 0 : !rAnchor.GetCntntAnchor() )
2164 : {
2165 0 : return false;
2166 : }
2167 :
2168 0 : pNd = &rAnchor.GetCntntAnchor()->nNode.GetNode();
2169 0 : pFlyNd = pNd->FindFlyStartNode();
2170 0 : break;
2171 : }
2172 : }
2173 0 : if( n >= GetSpzFrmFmts()->size() )
2174 : {
2175 : OSL_ENSURE( mbInReading, "Found a FlySection but not a Format!" );
2176 0 : return false;
2177 : }
2178 : }
2179 :
2180 0 : return 0 != pNd->FindHeaderStartNode() ||
2181 0 : 0 != pNd->FindFooterStartNode();
2182 : }
2183 :
2184 0 : short SwDoc::GetTextDirection( const SwPosition& rPos,
2185 : const Point* pPt ) const
2186 : {
2187 0 : short nRet = -1;
2188 :
2189 0 : SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
2190 :
2191 : // #i42921# - use new method <SwCntntNode::GetTextDirection(..)>
2192 0 : if ( pNd )
2193 : {
2194 0 : nRet = pNd->GetTextDirection( rPos, pPt );
2195 : }
2196 0 : if ( nRet == -1 )
2197 : {
2198 0 : const SvxFrameDirectionItem* pItem = 0;
2199 0 : if( pNd )
2200 : {
2201 : // Are we in a FlyFrame? Then look at that for the correct attribute
2202 0 : const SwFrmFmt* pFlyFmt = pNd->GetFlyFmt();
2203 0 : while( pFlyFmt )
2204 : {
2205 0 : pItem = &pFlyFmt->GetFrmDir();
2206 0 : if( FRMDIR_ENVIRONMENT == pItem->GetValue() )
2207 : {
2208 0 : pItem = 0;
2209 0 : const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
2210 0 : if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
2211 0 : pAnchor->GetCntntAnchor())
2212 : {
2213 0 : pFlyFmt = pAnchor->GetCntntAnchor()->nNode.
2214 0 : GetNode().GetFlyFmt();
2215 : }
2216 : else
2217 0 : pFlyFmt = 0;
2218 : }
2219 : else
2220 0 : pFlyFmt = 0;
2221 : }
2222 :
2223 0 : if( !pItem )
2224 : {
2225 0 : const SwPageDesc* pPgDsc = pNd->FindPageDesc( sal_False );
2226 0 : if( pPgDsc )
2227 0 : pItem = &pPgDsc->GetMaster().GetFrmDir();
2228 : }
2229 : }
2230 0 : if( !pItem )
2231 0 : pItem = (SvxFrameDirectionItem*)&GetAttrPool().GetDefaultItem(
2232 0 : RES_FRAMEDIR );
2233 0 : nRet = pItem->GetValue();
2234 : }
2235 0 : return nRet;
2236 : }
2237 :
2238 0 : bool SwDoc::IsInVerticalText( const SwPosition& rPos, const Point* pPt ) const
2239 : {
2240 0 : const short nDir = GetTextDirection( rPos, pPt );
2241 0 : return FRMDIR_VERT_TOP_RIGHT == nDir || FRMDIR_VERT_TOP_LEFT == nDir;
2242 : }
2243 :
2244 0 : void SwDoc::SetCurrentViewShell( SwViewShell* pNew )
2245 : {
2246 0 : mpCurrentView = pNew;
2247 0 : }
2248 :
2249 0 : SwLayouter* SwDoc::GetLayouter()
2250 : {
2251 0 : return mpLayouter;
2252 : }
2253 :
2254 0 : const SwLayouter* SwDoc::GetLayouter() const
2255 : {
2256 0 : return mpLayouter;
2257 : }
2258 :
2259 0 : void SwDoc::SetLayouter( SwLayouter* pNew )
2260 : {
2261 0 : mpLayouter = pNew;
2262 0 : }
2263 :
2264 0 : const SwViewShell *SwDoc::GetCurrentViewShell() const
2265 : {
2266 0 : return mpCurrentView;
2267 : }
2268 :
2269 0 : SwViewShell *SwDoc::GetCurrentViewShell()
2270 : {
2271 0 : return mpCurrentView;
2272 : }
2273 :
2274 : // It must be able to communicate to a SwViewShell. This is going to be removed later.
2275 0 : const SwRootFrm *SwDoc::GetCurrentLayout() const
2276 : {
2277 0 : if(GetCurrentViewShell())
2278 0 : return GetCurrentViewShell()->GetLayout();
2279 0 : return 0;
2280 : }
2281 :
2282 0 : SwRootFrm *SwDoc::GetCurrentLayout()
2283 : {
2284 0 : if(GetCurrentViewShell())
2285 0 : return GetCurrentViewShell()->GetLayout();
2286 0 : return 0;
2287 : }
2288 :
2289 0 : bool SwDoc::HasLayout() const
2290 : {
2291 : // if there is a view, there is always a layout
2292 0 : return (mpCurrentView != 0);
2293 : }
2294 :
2295 0 : std::set<SwRootFrm*> SwDoc::GetAllLayouts()
2296 : {
2297 0 : std::set<SwRootFrm*> aAllLayouts;
2298 0 : SwViewShell *pStart = GetCurrentViewShell();
2299 0 : SwViewShell *pTemp = pStart;
2300 0 : if ( pTemp )
2301 : {
2302 0 : do
2303 : {
2304 0 : if (pTemp->GetLayout())
2305 : {
2306 0 : aAllLayouts.insert(pTemp->GetLayout());
2307 0 : pTemp = (SwViewShell*)pTemp->GetNext();
2308 : }
2309 : } while(pTemp!=pStart);
2310 : }
2311 :
2312 0 : return aAllLayouts;
2313 : }
2314 :
2315 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|