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