xref: /aoo4110/main/sw/source/core/doc/doclay.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <unotools/linguprops.hxx>
28 #include <unotools/lingucfg.hxx>
29 #include <com/sun/star/embed/EmbedStates.hpp>
30 #include <hintids.hxx>
31 #include <com/sun/star/util/XCloseable.hpp>
32 #include <sfx2/progress.hxx>
33 #include <svx/svdmodel.hxx>
34 #include <svx/svdpage.hxx>
35 #include <editeng/keepitem.hxx>
36 #include <editeng/ulspitem.hxx>
37 #include <editeng/lrspitem.hxx>
38 #include <editeng/boxitem.hxx>
39 #include <editeng/shaditem.hxx>
40 #include <editeng/protitem.hxx>
41 #include <editeng/opaqitem.hxx>
42 #include <editeng/prntitem.hxx>
43 #include <svx/fmglob.hxx>
44 #include <svx/svdouno.hxx>
45 #include <svx/fmpage.hxx>
46 #include <editeng/frmdiritem.hxx>
47 
48 #include <swmodule.hxx>
49 #include <modcfg.hxx>
50 #include <com/sun/star/beans/XPropertySet.hpp>
51 #include <rtl/logfile.hxx>
52 #include <SwStyleNameMapper.hxx>
53 #include <fchrfmt.hxx>
54 #include <errhdl.hxx>
55 #include <frmatr.hxx>
56 #include <txatbase.hxx>
57 #include <fmtfld.hxx>
58 #include <fmtornt.hxx>
59 #include <fmtcntnt.hxx>
60 #include <fmtanchr.hxx>
61 #include <fmtfsize.hxx>
62 #include <fmtsrnd.hxx>
63 #include <fmtflcnt.hxx>
64 #include <fmtcnct.hxx>
65 #include <frmfmt.hxx>
66 #include <dcontact.hxx>
67 #include <txtflcnt.hxx>
68 #include <docfld.hxx>   // fuer Expression-Felder
69 #include <pam.hxx>
70 #include <ndtxt.hxx>
71 #include <ndnotxt.hxx>
72 #include <ndole.hxx>
73 #include <doc.hxx>
74 #include <IDocumentUndoRedo.hxx>
75 #include <rootfrm.hxx>
76 #include <pagefrm.hxx>
77 #include <cntfrm.hxx>
78 #include <flyfrm.hxx>
79 #include <fesh.hxx>
80 #include <docsh.hxx>
81 #include <dflyobj.hxx>
82 #include <dcontact.hxx>
83 #include <swundo.hxx>
84 #include <flypos.hxx>
85 #include <UndoInsert.hxx>
86 #include <expfld.hxx>		// InsertLabel
87 #include <poolfmt.hxx>		// PoolVorlagen-Id's
88 #include <docary.hxx>
89 #include <swtable.hxx>
90 #include <tblsel.hxx>
91 #include <viewopt.hxx>
92 #include <fldupde.hxx>
93 #include <txtftn.hxx>
94 #include <ftnidx.hxx>
95 #include <ftninfo.hxx>
96 #include <pagedesc.hxx>
97 #include <PostItMgr.hxx>
98 #include <comcore.hrc>		// STR-ResId's
99 
100 // #i11176#
101 #include <unoframe.hxx>
102 // OD 2004-05-24 #i28701#
103 #include <sortedobjs.hxx>
104 
105 // --> OD 2004-07-26 #i32089#
106 #include <vector>
107 // <--
108 
109 using namespace ::com::sun::star;
110 using ::rtl::OUString;
111 
112 #define DEF_FLY_WIDTH	 2268	//Defaultbreite fuer FlyFrms	(2268 == 4cm)
113 
114 /* #109161# */
lcl_IsItemSet(const SwCntntNode & rNode,sal_uInt16 which)115 static bool lcl_IsItemSet(const SwCntntNode & rNode, sal_uInt16 which)
116 {
117     bool bResult = false;
118 
119     if (SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState(which))
120         bResult = true;
121 
122     return bResult;
123 }
124 
125 /*************************************************************************
126 |*
127 |*	SwDoc::MakeLayoutFmt()
128 |*
129 |*	Beschreibung		Erzeugt ein neues Format das in seinen Einstellungen
130 |* 		Defaultmaessig zu dem Request passt. Das Format wird in das
131 |* 		entsprechende Formate-Array gestellt.
132 |* 		Wenn bereits ein passendes Format existiert, so wird dies
133 |* 		zurueckgeliefert.
134 |*	Ersterstellung		MA 22. Sep. 92
135 |*	Letzte Aenderung	JP 08.05.98
136 |*
137 |*************************************************************************/
138 
MakeLayoutFmt(RndStdIds eRequest,const SfxItemSet * pSet)139 SwFrmFmt *SwDoc::MakeLayoutFmt( RndStdIds eRequest, const SfxItemSet* pSet )
140 {
141 	SwFrmFmt *pFmt = 0;
142 	const sal_Bool bMod = IsModified();
143 	sal_Bool bHeader = sal_False;
144 
145 	switch ( eRequest )
146 	{
147 	case RND_STD_HEADER:
148 	case RND_STD_HEADERL:
149 	case RND_STD_HEADERR:
150 		{
151 			bHeader = sal_True;
152 			// kein break, es geht unten weiter
153 		}
154 	case RND_STD_FOOTER:
155 	case RND_STD_FOOTERL:
156 	case RND_STD_FOOTERR:
157 		{
158             pFmt = new SwFrmFmt( GetAttrPool(),
159                                  (bHeader ? "Header" : "Footer"),
160                                  GetDfltFrmFmt() );
161 
162 			SwNodeIndex aTmpIdx( GetNodes().GetEndOfAutotext() );
163 			SwStartNode* pSttNd =
164                 GetNodes().MakeTextSection
165                 ( aTmpIdx,
166                   bHeader ? SwHeaderStartNode : SwFooterStartNode,
167                   GetTxtCollFromPool(static_cast<sal_uInt16>( bHeader
168                                      ? ( eRequest == RND_STD_HEADERL
169                                          ? RES_POOLCOLL_HEADERL
170                                          : eRequest == RND_STD_HEADERR
171                                          ? RES_POOLCOLL_HEADERR
172                                          : RES_POOLCOLL_HEADER )
173                                      : ( eRequest == RND_STD_FOOTERL
174                                          ? RES_POOLCOLL_FOOTERL
175                                          : eRequest == RND_STD_FOOTERR
176                                          ? RES_POOLCOLL_FOOTERR
177                                          : RES_POOLCOLL_FOOTER )
178                                      ) ) );
179             pFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
180 
181 			if( pSet )		// noch ein paar Attribute setzen ?
182                 pFmt->SetFmtAttr( *pSet );
183 
184             // JP: warum zuruecksetzen ???	Doc. ist doch veraendert ???
185             // bei den Fly auf jedenfall verkehrt !!
186 			if ( !bMod )
187 				ResetModified();
188 		}
189 		break;
190 
191 	case RND_DRAW_OBJECT:
192 		{
193 			pFmt = MakeDrawFrmFmt( aEmptyStr, GetDfltFrmFmt() );
194 			if( pSet )		// noch ein paar Attribute setzen ?
195                 pFmt->SetFmtAttr( *pSet );
196 
197             if (GetIDocumentUndoRedo().DoesUndo())
198             {
199                 GetIDocumentUndoRedo().AppendUndo(
200                     new SwUndoInsLayFmt(pFmt, 0, 0));
201             }
202         }
203 		break;
204 
205 #ifdef DBG_UTIL
206     case FLY_AT_PAGE:
207     case FLY_AT_CHAR:
208     case FLY_AT_FLY:
209     case FLY_AT_PARA:
210     case FLY_AS_CHAR:
211         ASSERT( false, "use new interface instead: SwDoc::MakeFlySection!" );
212         break;
213 #endif
214 
215 	default:
216 		ASSERT( !this,
217 				"Layoutformat mit ungueltigem Request angefordert." );
218 
219 	}
220 	return pFmt;
221 }
222 /*************************************************************************
223 |*
224 |*	SwDoc::DelLayoutFmt()
225 |*
226 |*	Beschreibung		Loescht das angegebene Format, der Inhalt wird mit
227 |* 		geloescht.
228 |*	Ersterstellung		MA 23. Sep. 92
229 |*	Letzte Aenderung	MA 05. Feb. 93
230 |*
231 |*************************************************************************/
232 
DelLayoutFmt(SwFrmFmt * pFmt)233 void SwDoc::DelLayoutFmt( SwFrmFmt *pFmt )
234 {
235 	//Verkettung von Rahmen muss ggf. zusammengefuehrt werden.
236 	//Bevor die Frames vernichtet werden, damit die Inhalte der Rahmen
237 	//ggf. entsprechend gerichtet werden.
238 	const SwFmtChain &rChain = pFmt->GetChain();
239 	if ( rChain.GetPrev() )
240 	{
241 		SwFmtChain aChain( rChain.GetPrev()->GetChain() );
242 		aChain.SetNext( rChain.GetNext() );
243 		SetAttr( aChain, *rChain.GetPrev() );
244 	}
245 	if ( rChain.GetNext() )
246 	{
247 		SwFmtChain aChain( rChain.GetNext()->GetChain() );
248 		aChain.SetPrev( rChain.GetPrev() );
249 		SetAttr( aChain, *rChain.GetNext() );
250 	}
251 
252 	const SwNodeIndex* pCntIdx = pFmt->GetCntnt().GetCntntIdx();
253     if (pCntIdx && !GetIDocumentUndoRedo().DoesUndo())
254     {
255 		//Verbindung abbauen, falls es sich um ein OLE-Objekt handelt.
256 		SwOLENode* pOLENd = GetNodes()[ pCntIdx->GetIndex()+1 ]->GetOLENode();
257 		if( pOLENd && pOLENd->GetOLEObj().IsOleRef() )
258 		{
259             /*
260 			SwDoc* pDoc = (SwDoc*)pFmt->GetDoc();
261 			if( pDoc )
262 			{
263                 SfxObjectShell* p = pDoc->GetPersist();
264 				if( p )		// muss da sein
265 				{
266 					SvInfoObjectRef aRef( p->Find( pOLENd->GetOLEObj().GetName() ) );
267 					if( aRef.Is() )
268 						aRef->SetObj(0);
269 				}
270             } */
271 
272             // TODO/MBA: the old object closed the object, cleared all references to it, but didn't remove it from the container.
273             // I have no idea, why, nobody could explain it - so I do my very best to mimic this behavior
274             //uno::Reference < util::XCloseable > xClose( pOLENd->GetOLEObj().GetOleRef(), uno::UNO_QUERY );
275             //if ( xClose.is() )
276             {
277                 try
278                 {
279                     pOLENd->GetOLEObj().GetOleRef()->changeState( embed::EmbedStates::LOADED );
280                 }
281                 catch ( uno::Exception& )
282                 {
283                 }
284             }
285 
286             //pOLENd->GetOLEObj().GetOleRef() = 0;
287 		}
288 	}
289 
290 	//Frms vernichten.
291 	pFmt->DelFrms();
292 
293 	// erstmal sind nur Fly's Undofaehig
294 	const sal_uInt16 nWh = pFmt->Which();
295     if (GetIDocumentUndoRedo().DoesUndo() &&
296         (RES_FLYFRMFMT == nWh || RES_DRAWFRMFMT == nWh))
297     {
298         GetIDocumentUndoRedo().AppendUndo( new SwUndoDelLayFmt( pFmt ));
299     }
300     else
301     {
302         // --> OD 2004-07-26 #i32089# - delete at-frame anchored objects
303         if ( nWh == RES_FLYFRMFMT )
304         {
305             // determine frame formats of at-frame anchored objects
306             const SwNodeIndex* pCntntIdx = pFmt->GetCntnt().GetCntntIdx();
307             if ( pCntntIdx )
308             {
309                 const SwSpzFrmFmts* pTbl = pFmt->GetDoc()->GetSpzFrmFmts();
310                 if ( pTbl )
311                 {
312                     std::vector<SwFrmFmt*> aToDeleteFrmFmts;
313                     const sal_uLong nNodeIdxOfFlyFmt( pCntntIdx->GetIndex() );
314 
315                     for ( sal_uInt16 i = 0; i < pTbl->Count(); ++i )
316                     {
317                         SwFrmFmt* pTmpFmt = (*pTbl)[i];
318                         const SwFmtAnchor &rAnch = pTmpFmt->GetAnchor();
319                         if ( rAnch.GetAnchorId() == FLY_AT_FLY &&
320                              rAnch.GetCntntAnchor()->nNode.GetIndex() == nNodeIdxOfFlyFmt )
321                         {
322                             aToDeleteFrmFmts.push_back( pTmpFmt );
323                         }
324                     }
325 
326                     // delete found frame formats
327                     while ( !aToDeleteFrmFmts.empty() )
328                     {
329                         SwFrmFmt* pTmpFmt = aToDeleteFrmFmts.back();
330                         pFmt->GetDoc()->DelLayoutFmt( pTmpFmt );
331 
332                         aToDeleteFrmFmts.pop_back();
333                     }
334                 }
335             }
336         }
337         // <--
338 
339 		//Inhalt Loeschen.
340 		if( pCntIdx )
341 		{
342 			SwNode *pNode = &pCntIdx->GetNode();
343             ((SwFmtCntnt&)pFmt->GetFmtAttr( RES_CNTNT )).SetNewCntntIdx( 0 );
344 			DeleteSection( pNode );
345 		}
346 
347 		// ggfs. bei Zeichengebundenen Flys das Zeichen loeschen
348 		const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
349         if ((FLY_AS_CHAR == rAnchor.GetAnchorId()) && rAnchor.GetCntntAnchor())
350         {
351 			const SwPosition* pPos = rAnchor.GetCntntAnchor();
352 			SwTxtNode *pTxtNd = pPos->nNode.GetNode().GetTxtNode();
353 
354             // attribute is still in text node, delete it
355             if ( pTxtNd )
356             {
357                 SwTxtFlyCnt* const pAttr = static_cast<SwTxtFlyCnt*>(
358                     pTxtNd->GetTxtAttrForCharAt( pPos->nContent.GetIndex(),
359                         RES_TXTATR_FLYCNT ));
360                 if ( pAttr && (pAttr->GetFlyCnt().GetFrmFmt() == pFmt) )
361                 {
362                     // dont delete, set pointer to 0
363                     const_cast<SwFmtFlyCnt&>(pAttr->GetFlyCnt()).SetFlyFmt();
364                     SwIndex aIdx( pPos->nContent );
365                     pTxtNd->EraseText( aIdx, 1 );
366                 }
367             }
368         }
369 
370 		DelFrmFmt( pFmt );
371 	}
372 	SetModified();
373 }
374 
375 /*************************************************************************
376 |*
377 |*	SwDoc::CopyLayoutFmt()
378 |*
379 |*	Beschreibung		Kopiert das angegebene Format pSrc in pDest und
380 |*						returnt pDest. Wenn es noch kein pDest gibt, wird
381 |*						eins angelegt.
382 |*						JP: steht das Source Format in einem anderen
383 |*							Dokument, so kopiere auch dann noch richtig !!
384 |*							Vom chaos::Anchor-Attribut wird die Position immer
385 |*							auf 0 gesetzt !!!
386 |*
387 |*	Ersterstellung		BP 18.12.92
388 |*	Letzte Aenderung	MA 17. Jul. 96
389 |*
390 |*************************************************************************/
391 
CopyLayoutFmt(const SwFrmFmt & rSource,const SwFmtAnchor & rNewAnchor,bool bSetTxtFlyAtt,bool bMakeFrms)392 SwFrmFmt *SwDoc::CopyLayoutFmt(
393     const SwFrmFmt& rSource,
394     const SwFmtAnchor& rNewAnchor,
395     bool bSetTxtFlyAtt,
396     bool bMakeFrms )
397 {
398     const bool bFly = RES_FLYFRMFMT == rSource.Which();
399     const bool bDraw = RES_DRAWFRMFMT == rSource.Which();
400     ASSERT( bFly || bDraw, "this method only works for fly or draw" );
401 
402 	SwDoc* pSrcDoc = (SwDoc*)rSource.GetDoc();
403 
404     // #108784# may we copy this object?
405     // We may, unless it's 1) it's a control (and therfore a draw)
406     //                     2) anchored in a header/footer
407     //                     3) anchored (to paragraph?)
408     bool bMayNotCopy = false;
409     if( bDraw )
410     {
411         const SwDrawContact* pDrawContact =
412             static_cast<const SwDrawContact*>( rSource.FindContactObj() );
413 
414         bMayNotCopy =
415             ((FLY_AT_PARA == rNewAnchor.GetAnchorId()) ||
416              (FLY_AT_FLY  == rNewAnchor.GetAnchorId()) ||
417              (FLY_AT_CHAR == rNewAnchor.GetAnchorId())) &&
418             rNewAnchor.GetCntntAnchor() &&
419             IsInHeaderFooter( rNewAnchor.GetCntntAnchor()->nNode ) &&
420             pDrawContact != NULL  &&
421             pDrawContact->GetMaster() != NULL  &&
422             CheckControlLayer( pDrawContact->GetMaster() );
423     }
424 
425     // just return if we can't copy this
426     if( bMayNotCopy )
427         return NULL;
428 
429 	SwFrmFmt* pDest = GetDfltFrmFmt();
430 	if( rSource.GetRegisteredIn() != pSrcDoc->GetDfltFrmFmt() )
431 		pDest = CopyFrmFmt( *(SwFrmFmt*)rSource.GetRegisteredIn() );
432 	if( bFly )
433 	{
434 		// #i11176#
435 		// To do a correct cloning concerning the ZOrder for all objects
436 		// it is necessary to actually create a draw object for fly frames, too.
437 		// These are then added to the DrawingLayer (which needs to exist).
438 		// Together with correct sorting of all drawinglayer based objects
439 		// before cloning ZOrder transfer works correctly then.
440 		SwFlyFrmFmt *pFormat = MakeFlyFrmFmt( rSource.GetName(), pDest );
441 		pDest = pFormat;
442 
443 		SwXFrame::GetOrCreateSdrObject(pFormat);
444 	}
445 	else
446 		pDest = MakeDrawFrmFmt( aEmptyStr, pDest );
447 
448 	// alle anderen/neue Attribute kopieren.
449 	pDest->CopyAttrs( rSource );
450 
451 	//Chains werden nicht kopiert.
452     pDest->ResetFmtAttr( RES_CHAIN );
453 
454 	if( bFly )
455 	{
456 		//Der Inhalt wird dupliziert.
457 		const SwNode& rCSttNd = rSource.GetCntnt().GetCntntIdx()->GetNode();
458 		SwNodeRange aRg( rCSttNd, 1, *rCSttNd.EndOfSectionNode() );
459 
460 		SwNodeIndex aIdx( GetNodes().GetEndOfAutotext() );
461 		SwStartNode* pSttNd = GetNodes().MakeEmptySection( aIdx, SwFlyStartNode );
462 
463 		// erst den chaos::Anchor/CntntIndex setzen, innerhalb des Kopierens
464 		// auf die Werte zugegriffen werden kann (DrawFmt in Kopf-/Fusszeilen)
465 		aIdx = *pSttNd;
466 		SwFmtCntnt aAttr( rSource.GetCntnt() );
467 		aAttr.SetNewCntntIdx( &aIdx );
468         pDest->SetFmtAttr( aAttr );
469         pDest->SetFmtAttr( rNewAnchor );
470 
471 		if( !mbCopyIsMove || this != pSrcDoc )
472 		{
473 			if( mbInReading )
474 				pDest->SetName( aEmptyStr );
475 			else
476 			{
477 				// Teste erstmal ob der Name schon vergeben ist.
478 				// Wenn ja -> neuen generieren
479 				sal_Int8 nNdTyp = aRg.aStart.GetNode().GetNodeType();
480 
481 				String sOld( pDest->GetName() );
482 				pDest->SetName( aEmptyStr );
483 				if( FindFlyByName( sOld, nNdTyp ) )		// einen gefunden
484 					switch( nNdTyp )
485 					{
486 					case ND_GRFNODE:	sOld = GetUniqueGrfName();		break;
487 					case ND_OLENODE:	sOld = GetUniqueOLEName();		break;
488 					default:			sOld = GetUniqueFrameName();	break;
489 					}
490 
491 				pDest->SetName( sOld );
492 			}
493 		}
494 
495         if (GetIDocumentUndoRedo().DoesUndo())
496         {
497             GetIDocumentUndoRedo().AppendUndo(new SwUndoInsLayFmt(pDest,0,0));
498         }
499 
500 		// sorge dafuer das auch Fly's in Fly's kopiert werden
501 		aIdx = *pSttNd->EndOfSectionNode();
502         pSrcDoc->CopyWithFlyInFly( aRg, 0, aIdx, NULL, sal_False, sal_True, sal_True );
503 	}
504 	else
505 	{
506 		ASSERT( RES_DRAWFRMFMT == rSource.Which(), "Weder Fly noch Draw." );
507         // OD 2005-08-02 #i52780# - Note: moving object to visible layer not needed.
508         SwDrawContact* pSourceContact = (SwDrawContact *)rSource.FindContactObj();
509 
510         SwDrawContact* pContact = new SwDrawContact( (SwDrawFrmFmt*)pDest,
511                                 CloneSdrObj( *pSourceContact->GetMaster(),
512                                         mbCopyIsMove && this == pSrcDoc ) );
513         // --> OD 2005-05-23 #i49730# - notify draw frame format
514         // that position attributes are already set, if the position attributes
515         // are already set at the source draw frame format.
516         if ( pDest->ISA(SwDrawFrmFmt) &&
517              rSource.ISA(SwDrawFrmFmt) &&
518              static_cast<const SwDrawFrmFmt&>(rSource).IsPosAttrSet() )
519         {
520             static_cast<SwDrawFrmFmt*>(pDest)->PosAttrSet();
521         }
522         // <--
523 
524         if( pDest->GetAnchor() == rNewAnchor )
525         {
526             // OD 03.07.2003 #108784# - do *not* connect to layout, if
527             // a <MakeFrms> will not be called.
528             if ( bMakeFrms )
529             {
530                 pContact->ConnectToLayout( &rNewAnchor );
531             }
532         }
533 		else
534             pDest->SetFmtAttr( rNewAnchor );
535 
536         if (GetIDocumentUndoRedo().DoesUndo())
537         {
538             GetIDocumentUndoRedo().AppendUndo(new SwUndoInsLayFmt(pDest,0,0));
539         }
540     }
541 
542     if (bSetTxtFlyAtt && (FLY_AS_CHAR == rNewAnchor.GetAnchorId()))
543     {
544         const SwPosition* pPos = rNewAnchor.GetCntntAnchor();
545         SwFmtFlyCnt aFmt( pDest );
546         pPos->nNode.GetNode().GetTxtNode()->InsertItem(
547             aFmt, pPos->nContent.GetIndex(), 0 );
548 	}
549 
550 	if( bMakeFrms )
551 		pDest->MakeFrms();
552 
553 	return pDest;
554 }
555 
CloneSdrObj(const SdrObject & rObj,sal_Bool bMoveWithinDoc,sal_Bool bInsInPage)556 SdrObject* SwDoc::CloneSdrObj( const SdrObject& rObj, sal_Bool bMoveWithinDoc,
557 								sal_Bool bInsInPage )
558 {
559     // --> OD 2005-08-08 #i52858# - method name changed
560     SdrPage *pPg = GetOrCreateDrawModel()->GetPage( 0 );
561     // <--
562 	if( !pPg )
563 	{
564 		pPg = GetDrawModel()->AllocPage( sal_False );
565 		GetDrawModel()->InsertPage( pPg );
566 	}
567 
568 	SdrObject *pObj = rObj.Clone();
569 	if( bMoveWithinDoc && FmFormInventor == pObj->GetObjInventor() )
570 	{
571 		// bei Controls muss der Name erhalten bleiben
572 		uno::Reference< awt::XControlModel >  xModel = ((SdrUnoObj*)pObj)->GetUnoControlModel();
573 		uno::Any aVal;
574 		uno::Reference< beans::XPropertySet >  xSet(xModel, uno::UNO_QUERY);
575 		OUString sName( rtl::OUString::createFromAscii("Name") );
576 		if( xSet.is() )
577 			aVal = xSet->getPropertyValue( sName );
578 		if( bInsInPage )
579 			pPg->InsertObject( pObj );
580 		if( xSet.is() )
581 			xSet->setPropertyValue( sName, aVal );
582 	}
583 	else if( bInsInPage )
584 		pPg->InsertObject( pObj );
585 
586     // OD 02.07.2003 #108784# - for drawing objects: set layer of cloned object
587     // to invisible layer
588     SdrLayerID nLayerIdForClone = rObj.GetLayer();
589     if ( !pObj->ISA(SwFlyDrawObj) &&
590          !pObj->ISA(SwVirtFlyDrawObj) &&
591          !IS_TYPE(SdrObject,pObj) )
592     {
593         if ( IsVisibleLayerId( nLayerIdForClone ) )
594         {
595             nLayerIdForClone = GetInvisibleLayerIdByVisibleOne( nLayerIdForClone );
596         }
597     }
598     pObj->SetLayer( nLayerIdForClone );
599 
600 
601     return pObj;
602 }
603 
_MakeFlySection(const SwPosition & rAnchPos,const SwCntntNode & rNode,RndStdIds eRequestId,const SfxItemSet * pFlySet,SwFrmFmt * pFrmFmt)604 SwFlyFrmFmt* SwDoc::_MakeFlySection( const SwPosition& rAnchPos,
605 									const SwCntntNode& rNode,
606 									RndStdIds eRequestId,
607 									const SfxItemSet* pFlySet,
608 									SwFrmFmt* pFrmFmt )
609 {
610 	if( !pFrmFmt )
611 		pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME );
612 
613 	String sName;
614 	if( !mbInReading )
615 		switch( rNode.GetNodeType() )
616 		{
617 		case ND_GRFNODE:		sName = GetUniqueGrfName();		break;
618 		case ND_OLENODE:        sName = GetUniqueOLEName();		break;
619 		default:				sName = GetUniqueFrameName();		break;
620 		}
621 	SwFlyFrmFmt* pFmt = MakeFlyFrmFmt( sName, pFrmFmt );
622 
623 	//Inhalt erzeugen und mit dem Format verbinden.
624 	//CntntNode erzeugen und in die Autotextsection stellen
625 	SwNodeRange aRange( GetNodes().GetEndOfAutotext(), -1,
626 						GetNodes().GetEndOfAutotext() );
627 	GetNodes().SectionDown( &aRange, SwFlyStartNode );
628 
629     pFmt->SetFmtAttr( SwFmtCntnt( rNode.StartOfSectionNode() ));
630 
631 
632 	const SwFmtAnchor* pAnchor = 0;
633 	if( pFlySet )
634 	{
635 		pFlySet->GetItemState( RES_ANCHOR, sal_False,
636 								(const SfxPoolItem**)&pAnchor );
637 		if( SFX_ITEM_SET == pFlySet->GetItemState( RES_CNTNT, sal_False ))
638 		{
639 			SfxItemSet aTmpSet( *pFlySet );
640 			aTmpSet.ClearItem( RES_CNTNT );
641             pFmt->SetFmtAttr( aTmpSet );
642 		}
643 		else
644             pFmt->SetFmtAttr( *pFlySet );
645 	}
646 
647 	// Anker noch nicht gesetzt ?
648 	RndStdIds eAnchorId = pAnchor ? pAnchor->GetAnchorId()
649 								  : pFmt->GetAnchor().GetAnchorId();
650     // --> OD 2010-01-07 #i107811#
651     // Assure that at-page anchored fly frames have a page num or a content anchor set.
652     if ( !pAnchor ||
653          ( FLY_AT_PAGE != pAnchor->GetAnchorId() &&
654            !pAnchor->GetCntntAnchor() ) ||
655          ( FLY_AT_PAGE == pAnchor->GetAnchorId() &&
656            !pAnchor->GetCntntAnchor() &&
657            pAnchor->GetPageNum() == 0 ) )
658 	{
659 		// dann setze ihn, wird im Undo gebraucht
660 		SwFmtAnchor aAnch( pFmt->GetAnchor() );
661         if (pAnchor && (FLY_AT_FLY == pAnchor->GetAnchorId()))
662         {
663 			SwPosition aPos( *rAnchPos.nNode.GetNode().FindFlyStartNode() );
664 			aAnch.SetAnchor( &aPos );
665 			eAnchorId = FLY_AT_FLY;
666 		}
667 		else
668 		{
669 			if( eRequestId != aAnch.GetAnchorId() &&
670 				SFX_ITEM_SET != pFmt->GetItemState( RES_ANCHOR, sal_True ) )
671             {
672 				aAnch.SetType( eRequestId );
673             }
674 
675 			eAnchorId = aAnch.GetAnchorId();
676             if ( FLY_AT_PAGE != eAnchorId ||
677                  ( FLY_AT_PAGE == eAnchorId &&
678                    ( !pAnchor ||
679                      aAnch.GetPageNum() == 0 ) ) )
680             {
681 				aAnch.SetAnchor( &rAnchPos );
682             }
683 		}
684         // <--
685         pFmt->SetFmtAttr( aAnch );
686 	}
687 	else
688 		eAnchorId = pFmt->GetAnchor().GetAnchorId();
689 
690     if ( FLY_AS_CHAR == eAnchorId )
691     {
692 		xub_StrLen nStt = rAnchPos.nContent.GetIndex();
693         SwTxtNode * pTxtNode = rAnchPos.nNode.GetNode().GetTxtNode();
694 
695         ASSERT(pTxtNode!= 0, "There should be a SwTxtNode!");
696 
697         if (pTxtNode != NULL)
698         {
699             SwFmtFlyCnt aFmt( pFmt );
700             pTxtNode->InsertItem( aFmt, nStt, nStt );
701         }
702     }
703 
704 	if( SFX_ITEM_SET != pFmt->GetAttrSet().GetItemState( RES_FRM_SIZE ))
705 	{
706 		SwFmtFrmSize aFmtSize( ATT_VAR_SIZE, 0, DEF_FLY_WIDTH );
707 		const SwNoTxtNode* pNoTxtNode = rNode.GetNoTxtNode();
708 		if( pNoTxtNode )
709 		{
710 			//Groesse einstellen.
711 		 	Size aSize( pNoTxtNode->GetTwipSize() );
712 			if( MINFLY > aSize.Width() )
713 				aSize.Width() = DEF_FLY_WIDTH;
714 			aFmtSize.SetWidth( aSize.Width() );
715 			if( aSize.Height() )
716 			{
717 				aFmtSize.SetHeight( aSize.Height() );
718                 aFmtSize.SetHeightSizeType( ATT_FIX_SIZE );
719 			}
720 		}
721         pFmt->SetFmtAttr( aFmtSize );
722 	}
723 
724 	// Frames anlegen
725 	if( GetCurrentViewShell() )
726 		pFmt->MakeFrms();			// ???	//swmod 071108//swmod 071225
727 
728     if (GetIDocumentUndoRedo().DoesUndo())
729     {
730         sal_uLong nNodeIdx = rAnchPos.nNode.GetIndex();
731         xub_StrLen nCntIdx = rAnchPos.nContent.GetIndex();
732         GetIDocumentUndoRedo().AppendUndo(
733             new SwUndoInsLayFmt( pFmt, nNodeIdx, nCntIdx ));
734     }
735 
736 	SetModified();
737 	return pFmt;
738 }
739 
MakeFlySection(RndStdIds eAnchorType,const SwPosition * pAnchorPos,const SfxItemSet * pFlySet,SwFrmFmt * pFrmFmt,sal_Bool bCalledFromShell)740 SwFlyFrmFmt* SwDoc::MakeFlySection( RndStdIds eAnchorType,
741 									const SwPosition* pAnchorPos,
742 									const SfxItemSet* pFlySet,
743 									SwFrmFmt* pFrmFmt, sal_Bool bCalledFromShell )
744 {
745 	SwFlyFrmFmt* pFmt = 0;
746 	sal_Bool bCallMake = sal_True;
747     if ( !pAnchorPos && (FLY_AT_PAGE != eAnchorType) )
748     {
749 		const SwFmtAnchor* pAnch;
750 		if( (pFlySet && SFX_ITEM_SET == pFlySet->GetItemState(
751 				RES_ANCHOR, sal_False, (const SfxPoolItem**)&pAnch )) ||
752 			( pFrmFmt && SFX_ITEM_SET == pFrmFmt->GetItemState(
753 				RES_ANCHOR, sal_True, (const SfxPoolItem**)&pAnch )) )
754 		{
755             if ( (FLY_AT_PAGE != pAnch->GetAnchorId()) )
756             {
757                 pAnchorPos = pAnch->GetCntntAnchor();
758                 if (pAnchorPos)
759                 {
760                     bCallMake = sal_False;
761                 }
762             }
763         }
764     }
765 
766 	if( bCallMake )
767 	{
768 		if( !pFrmFmt )
769 			pFrmFmt = GetFrmFmtFromPool( RES_POOLFRM_FRAME );
770 
771 		sal_uInt16 nCollId = static_cast<sal_uInt16>(
772             get(IDocumentSettingAccess::HTML_MODE) ? RES_POOLCOLL_TEXT : RES_POOLCOLL_FRAME );
773 
774         /* #109161# If there exists no adjust item in the paragraph
775             style for the content node of the new fly section
776             propagate an existing adjust item at the anchor to the new
777             content node. */
778         SwCntntNode * pNewTxtNd = GetNodes().MakeTxtNode
779             (SwNodeIndex( GetNodes().GetEndOfAutotext()),
780              GetTxtCollFromPool( nCollId ));
781         SwCntntNode * pAnchorNode = pAnchorPos->nNode.GetNode().GetCntntNode();
782 
783         const SfxPoolItem * pItem = NULL;
784 
785         if (bCalledFromShell && !lcl_IsItemSet(*pNewTxtNd, RES_PARATR_ADJUST) &&
786             SFX_ITEM_SET == pAnchorNode->GetSwAttrSet().
787             GetItemState(RES_PARATR_ADJUST, sal_True, &pItem))
788             static_cast<SwCntntNode *>(pNewTxtNd)->SetAttr(*pItem);
789 
790  		pFmt = _MakeFlySection( *pAnchorPos, *pNewTxtNd,
791 								eAnchorType, pFlySet, pFrmFmt );
792 	}
793 	return pFmt;
794 }
795 
MakeFlyAndMove(const SwPaM & rPam,const SfxItemSet & rSet,const SwSelBoxes * pSelBoxes,SwFrmFmt * pParent)796 SwFlyFrmFmt* SwDoc::MakeFlyAndMove( const SwPaM& rPam, const SfxItemSet& rSet,
797 									const SwSelBoxes* pSelBoxes,
798 									SwFrmFmt *pParent )
799 {
800 	SwFmtAnchor& rAnch = (SwFmtAnchor&)rSet.Get( RES_ANCHOR );
801 
802     GetIDocumentUndoRedo().StartUndo( UNDO_INSLAYFMT, NULL );
803 
804 	SwFlyFrmFmt* pFmt = MakeFlySection( rAnch.GetAnchorId(), rPam.GetPoint(),
805 										&rSet, pParent );
806 
807 	// Wenn Inhalt selektiert ist, so wird dieser jetzt zum Inhalt des
808 	// neuen Rahmen. Sprich er wird in die entspr. Sektion des NodesArr
809 	//gemoved.
810 
811 	if( pFmt )
812 	{
813 		do {		// middle check loop
814 			const SwFmtCntnt &rCntnt = pFmt->GetCntnt();
815 			ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
816 			SwNodeIndex aIndex( *(rCntnt.GetCntntIdx()), 1 );
817 			SwCntntNode *pNode = aIndex.GetNode().GetCntntNode();
818 
819 			// ACHTUNG: nicht einen Index auf dem Stack erzeugen, sonst
820 			// 		   	kann der CntntnNode am Ende nicht geloscht werden !!
821 			SwPosition aPos( aIndex );
822 			aPos.nContent.Assign( pNode, 0 );
823 
824 			if( pSelBoxes && pSelBoxes->Count() )
825 			{
826 				// Tabellenselection
827 				// kopiere Teile aus einer Tabelle: lege eine Tabelle mit der
828 				// Breite der Originalen an und move (kopiere/loesche) die
829 				// selektierten Boxen. Die Groessen werden prozentual
830 				// korrigiert.
831 
832 				SwTableNode* pTblNd = (SwTableNode*)(*pSelBoxes)[0]->
833 												GetSttNd()->FindTableNode();
834 				if( !pTblNd )
835 					break;
836 
837 				SwTable& rTbl = pTblNd->GetTable();
838 
839 				// ist die gesamte Tabelle selektiert ?
840 				if( pSelBoxes->Count() == rTbl.GetTabSortBoxes().Count() )
841 				{
842 					// verschiebe die gesamte Tabelle
843 					SwNodeRange aRg( *pTblNd, 0, *pTblNd->EndOfSectionNode(), 1 );
844 
845 					// wird die gesamte Tabelle verschoben und steht diese
846 					// in einem FlyFrame, dann erzeuge dahinter einen neuen
847 					// TextNode. Dadurch bleibt dieser Fly erhalten !
848 					if( aRg.aEnd.GetNode().IsEndNode() )
849 						GetNodes().MakeTxtNode( aRg.aStart,
850 									(SwTxtFmtColl*)GetDfltTxtFmtColl() );
851 
852                     MoveNodeRange( aRg, aPos.nNode, DOC_MOVEDEFAULT );
853                 }
854 				else
855 				{
856 					rTbl.MakeCopy( this, aPos, *pSelBoxes );
857                     // Don't delete a part of a table with row span!!
858                     // You could delete the content instead -> ToDo
859 					//rTbl.DeleteSel( this, *pSelBoxes, 0, 0, sal_True, sal_True );
860 				}
861 
862 				// wenn Tabelle im Rahmen, dann ohne nachfolgenden TextNode
863 				aIndex = rCntnt.GetCntntIdx()->GetNode().EndOfSectionIndex() - 1;
864 				ASSERT( aIndex.GetNode().GetTxtNode(),
865 						"hier sollte ein TextNode stehen" );
866 				aPos.nContent.Assign( 0, 0 );		// Index abmelden !!
867 				GetNodes().Delete( aIndex, 1 );
868 
869 //JP erstmal ein Hack, solange keine Flys/Headers/Footers Undofaehig sind
870 // werden erstmal alle Undo - Objecte geloescht.
871 if( GetIDocumentUndoRedo().DoesUndo() )
872 {
873     GetIDocumentUndoRedo().DelAllUndoObj();
874 }
875 
876 			}
877 			else
878 			{
879 /*
880 				// alle Pams verschieben
881 				SwPaM* pTmp = (SwPaM*)&rPam;
882 				do {
883 					if( pTmp->HasMark() &&
884 						*pTmp->GetPoint() != *pTmp->GetMark() )
885 						MoveAndJoin( *pTmp, aPos );
886 				} while( &rPam != ( pTmp = (SwPaM*)pTmp->GetNext() ) );
887 */
888 				// copy all Pams and then delete all
889 				SwPaM* pTmp = (SwPaM*)&rPam;
890                 sal_Bool bOldFlag = mbCopyIsMove;
891                 bool const bOldUndo = GetIDocumentUndoRedo().DoesUndo();
892 				mbCopyIsMove = sal_True;
893                 GetIDocumentUndoRedo().DoUndo(false);
894 				do {
895 					if( pTmp->HasMark() &&
896 						*pTmp->GetPoint() != *pTmp->GetMark() )
897                     {
898                         CopyRange( *pTmp, aPos, false );
899                     }
900                     pTmp = static_cast<SwPaM*>(pTmp->GetNext());
901                 } while ( &rPam != pTmp );
902 				mbCopyIsMove = bOldFlag;
903                 GetIDocumentUndoRedo().DoUndo(bOldUndo);
904 
905 				pTmp = (SwPaM*)&rPam;
906 				do {
907 					if( pTmp->HasMark() &&
908 						*pTmp->GetPoint() != *pTmp->GetMark() )
909                     {
910 						DeleteAndJoin( *pTmp );
911                     }
912                     pTmp = static_cast<SwPaM*>(pTmp->GetNext());
913                 } while ( &rPam != pTmp );
914 			}
915 		} while( sal_False );
916 	}
917 
918 	SetModified();
919 
920     GetIDocumentUndoRedo().EndUndo( UNDO_INSLAYFMT, NULL );
921 
922 	return pFmt;
923 }
924 
925 
926 // Insert drawing object, which has to be already inserted in the DrawModel
InsertDrawObj(const SwPaM & rRg,SdrObject & rDrawObj,const SfxItemSet & rFlyAttrSet)927 SwDrawFrmFmt* SwDoc::InsertDrawObj(
928     const SwPaM &rRg,
929     SdrObject& rDrawObj,
930     const SfxItemSet& rFlyAttrSet )
931 {
932     SwDrawFrmFmt* pFmt = MakeDrawFrmFmt( aEmptyStr, GetDfltFrmFmt() );
933 
934     const SwFmtAnchor* pAnchor = 0;
935     rFlyAttrSet.GetItemState( RES_ANCHOR, sal_False, (const SfxPoolItem**) &pAnchor );
936     pFmt->SetFmtAttr( rFlyAttrSet );
937 
938     RndStdIds eAnchorId = pAnchor != NULL ? pAnchor->GetAnchorId() : pFmt->GetAnchor().GetAnchorId();
939     const bool bIsAtCntnt = (FLY_AT_PAGE != eAnchorId);
940 
941     const SwNodeIndex* pChkIdx = 0;
942     if ( pAnchor == NULL )
943     {
944         pChkIdx = &rRg.GetPoint()->nNode;
945     }
946     else if ( bIsAtCntnt )
947     {
948         pChkIdx =
949             pAnchor->GetCntntAnchor() ? &pAnchor->GetCntntAnchor()->nNode : &rRg.GetPoint()->nNode;
950     }
951 
952     // allow drawing objects in header/footer, but control objects aren't allowed in header/footer.
953     if( pChkIdx != NULL
954         && ::CheckControlLayer( &rDrawObj )
955         && IsInHeaderFooter( *pChkIdx ) )
956     {
957         // apply at-page anchor format
958         eAnchorId = FLY_AT_PAGE;
959         pFmt->SetFmtAttr( SwFmtAnchor( eAnchorId ) );
960     }
961     else if( pAnchor == NULL
962              || ( bIsAtCntnt
963                   && pAnchor->GetCntntAnchor() == NULL ) )
964     {
965         // apply anchor format
966         SwFmtAnchor aAnch( pAnchor != NULL ? *pAnchor : pFmt->GetAnchor() );
967         eAnchorId = aAnch.GetAnchorId();
968         if ( eAnchorId == FLY_AT_FLY )
969         {
970             SwPosition aPos( *rRg.GetNode()->FindFlyStartNode() );
971             aAnch.SetAnchor( &aPos );
972         }
973         else
974         {
975             aAnch.SetAnchor( rRg.GetPoint() );
976             if ( eAnchorId == FLY_AT_PAGE )
977             {
978                 eAnchorId = rDrawObj.ISA( SdrUnoObj ) ? FLY_AS_CHAR : FLY_AT_PARA;
979                 aAnch.SetType( eAnchorId );
980             }
981         }
982         pFmt->SetFmtAttr( aAnch );
983     }
984 
985     // insert text attribute for as-character anchored drawing object
986     if ( eAnchorId == FLY_AS_CHAR )
987     {
988         bool bAnchorAtPageAsFallback = true;
989         const SwFmtAnchor& rDrawObjAnchorFmt = pFmt->GetAnchor();
990         if ( rDrawObjAnchorFmt.GetCntntAnchor() != NULL )
991         {
992             SwTxtNode* pAnchorTxtNode =
993                     rDrawObjAnchorFmt.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
994             if ( pAnchorTxtNode != NULL )
995             {
996                 const xub_StrLen nStt = rDrawObjAnchorFmt.GetCntntAnchor()->nContent.GetIndex();
997                 SwFmtFlyCnt aFmt( pFmt );
998                 pAnchorTxtNode->InsertItem( aFmt, nStt, nStt );
999                 bAnchorAtPageAsFallback = false;
1000             }
1001         }
1002 
1003         if ( bAnchorAtPageAsFallback )
1004         {
1005             ASSERT( false, "SwDoc::InsertDrawObj(..) - missing content anchor for as-character anchored drawing object --> anchor at-page" );
1006             pFmt->SetFmtAttr( SwFmtAnchor( FLY_AT_PAGE ) );
1007         }
1008     }
1009 
1010     SwDrawContact* pContact = new SwDrawContact( pFmt, &rDrawObj );
1011 
1012     if ( GetCurrentViewShell() )
1013     {
1014         // create layout representation
1015         pFmt->MakeFrms();
1016         if ( pContact->GetAnchorFrm() )
1017         {
1018             pContact->MoveObjToVisibleLayer( &rDrawObj );
1019         }
1020     }
1021 
1022     if (GetIDocumentUndoRedo().DoesUndo())
1023     {
1024         GetIDocumentUndoRedo().AppendUndo( new SwUndoInsLayFmt(pFmt, 0, 0) );
1025     }
1026 
1027     SetModified();
1028     return pFmt;
1029 }
1030 
1031 /*************************************************************************
1032 |*
1033 |*	SwDoc::GetAllFlyFmts
1034 |*
1035 |*	Ersterstellung		MA 14. Jul. 93
1036 |*	Letzte Aenderung	MD 23. Feb. 95
1037 |*
1038 |*************************************************************************/
1039 
1040 /*sal_Bool TstFlyRange( const SwPaM* pPam, sal_uInt32 nFlyPos )
1041 {
1042 	sal_Bool bOk = sal_False;
1043 	const SwPaM* pTmp = pPam;
1044 	do {
1045 		bOk = pTmp->Start()->nNode.GetIndex() < nFlyPos &&
1046 				pTmp->End()->nNode.GetIndex() > nFlyPos;
1047 	} while( !bOk && pPam != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
1048 	return bOk;
1049 }
1050 */
1051 /* -----------------------------04.04.00 10:55--------------------------------
1052 	paragraph frames - o.k. if the PaM includes the paragraph from the beginning
1053 					   to the beginning of the next paragraph at least
1054 	frames at character - o.k. if the pam start at least at the same position
1055  						as the frame
1056  ---------------------------------------------------------------------------*/
TstFlyRange(const SwPaM * pPam,const SwPosition * pFlyPos,RndStdIds nAnchorId)1057 sal_Bool TstFlyRange( const SwPaM* pPam, const SwPosition* pFlyPos,
1058 						RndStdIds nAnchorId )
1059 {
1060 	sal_Bool bOk = sal_False;
1061 	const SwPaM* pTmp = pPam;
1062 	do {
1063 		const sal_uInt32 nFlyIndex = pFlyPos->nNode.GetIndex();
1064 		const SwPosition* pPaMStart = pTmp->Start();
1065 		const SwPosition* pPaMEnd = pTmp->End();
1066 		const sal_uInt32 nPamStartIndex = pPaMStart->nNode.GetIndex();
1067 		const sal_uInt32 nPamEndIndex = pPaMEnd->nNode.GetIndex();
1068         if (FLY_AT_PARA == nAnchorId)
1069 			bOk = (nPamStartIndex < nFlyIndex && nPamEndIndex > nFlyIndex) ||
1070 			   (((nPamStartIndex == nFlyIndex) && (pPaMStart->nContent.GetIndex() == 0)) &&
1071 			   (nPamEndIndex > nFlyIndex));
1072 		else
1073 		{
1074 			xub_StrLen nFlyContentIndex = pFlyPos->nContent.GetIndex();
1075 			xub_StrLen nPamEndContentIndex = pPaMEnd->nContent.GetIndex();
1076 			bOk = (nPamStartIndex < nFlyIndex &&
1077 				(( nPamEndIndex > nFlyIndex )||
1078 				 ((nPamEndIndex == nFlyIndex) &&
1079                   (nPamEndContentIndex > nFlyContentIndex))) )
1080 				||
1081 			   		(((nPamStartIndex == nFlyIndex) &&
1082 					  (pPaMStart->nContent.GetIndex() <= nFlyContentIndex)) &&
1083                      ((nPamEndIndex > nFlyIndex) ||
1084                      (nPamEndContentIndex > nFlyContentIndex )));
1085 		}
1086 
1087 	} while( !bOk && pPam != ( pTmp = (const SwPaM*)pTmp->GetNext() ));
1088 	return bOk;
1089 }
1090 
1091 
GetAllFlyFmts(const SwPaM * pCmpRange,sal_Bool bDrawAlso) const1092 SwPosFlyFrms SwDoc::GetAllFlyFmts( const SwPaM* pCmpRange, sal_Bool bDrawAlso ) const
1093 {
1094     SwPosFlyFrms aRetval;
1095 	SwFrmFmt *pFly;
1096 
1097 	// erstmal alle Absatzgebundenen einsammeln
1098 	for( sal_uInt16 n = 0; n < GetSpzFrmFmts()->Count(); ++n )
1099 	{
1100 		pFly = (*GetSpzFrmFmts())[ n ];
1101 		bool bDrawFmt = bDrawAlso ? RES_DRAWFRMFMT == pFly->Which() : false;
1102 		bool bFlyFmt = RES_FLYFRMFMT == pFly->Which();
1103 		if( bFlyFmt || bDrawFmt )
1104 		{
1105 			const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1106             SwPosition const*const pAPos = rAnchor.GetCntntAnchor();
1107             if (pAPos &&
1108                 ((FLY_AT_PARA == rAnchor.GetAnchorId()) ||
1109                  (FLY_AT_FLY  == rAnchor.GetAnchorId()) ||
1110                  (FLY_AT_CHAR == rAnchor.GetAnchorId())))
1111 			{
1112 				if( pCmpRange &&
1113 					!TstFlyRange( pCmpRange, pAPos, rAnchor.GetAnchorId() ))
1114 						continue;		// kein gueltiger FlyFrame
1115                 aRetval.insert(SwPosFlyFrmPtr(new SwPosFlyFrm(pAPos->nNode, pFly, aRetval.size())));
1116 			}
1117 		}
1118 	}
1119 
1120 	// kein Layout oder nur ein Teil, dann wars das
1121 	// Seitenbezogen Flys nur, wenn vollstaendig "gewuenscht" wird !
1122 	if( !GetCurrentViewShell() || pCmpRange )	//swmod 071108//swmod 071225
1123     {
1124 		return aRetval;
1125     }
1126 
1127 	SwPageFrm *pPage = (SwPageFrm*)GetCurrentLayout()->GetLower();	//swmod 080218
1128 	while( pPage )
1129 	{
1130 		if( pPage->GetSortedObjs() )
1131 		{
1132             SwSortedObjs &rObjs = *pPage->GetSortedObjs();
1133 			for( sal_uInt16 i = 0; i < rObjs.Count(); ++i)
1134 			{
1135                 SwAnchoredObject* pAnchoredObj = rObjs[i];
1136                 if ( pAnchoredObj->ISA(SwFlyFrm) )
1137                     pFly = &(pAnchoredObj->GetFrmFmt());
1138 				else if ( bDrawAlso )
1139                     pFly = &(pAnchoredObj->GetFrmFmt());
1140 				else
1141 					continue;
1142 
1143 				const SwFmtAnchor& rAnchor = pFly->GetAnchor();
1144                 if ((FLY_AT_PARA != rAnchor.GetAnchorId()) &&
1145                     (FLY_AT_FLY  != rAnchor.GetAnchorId()) &&
1146                     (FLY_AT_CHAR != rAnchor.GetAnchorId()))
1147 				{
1148 					const SwCntntFrm * pCntntFrm = pPage->FindFirstBodyCntnt();
1149 					if ( !pCntntFrm )
1150 					{
1151 						//Oops! Eine leere Seite. Damit der Rahmen nicht ganz
1152 						//verlorengeht (RTF) suchen wir schnell den letzen
1153 						//Cntnt der vor der Seite steht.
1154 						SwPageFrm *pPrv = (SwPageFrm*)pPage->GetPrev();
1155 						while ( !pCntntFrm && pPrv )
1156 						{
1157 							pCntntFrm = pPrv->FindFirstBodyCntnt();
1158 							pPrv = (SwPageFrm*)pPrv->GetPrev();
1159 						}
1160 					}
1161 					if ( pCntntFrm )
1162 					{
1163 						SwNodeIndex aIdx( *pCntntFrm->GetNode() );
1164                         aRetval.insert(SwPosFlyFrmPtr(new SwPosFlyFrm(aIdx, pFly, aRetval.size())));
1165 					}
1166 				}
1167 			}
1168 		}
1169 		pPage = (SwPageFrm*)pPage->GetNext();
1170 	}
1171 
1172     return aRetval;
1173 }
1174 
1175 /*************************************************************************
1176 |*
1177 |*	SwDoc::InsertLabel()
1178 |*
1179 |*	Ersterstellung		MA 11. Feb. 94
1180 |*	Letzte Aenderung	MA 12. Nov. 97
1181 |*
1182 |*************************************************************************/
1183 
1184 /* #i6447# changed behaviour if lcl_CpyAttr:
1185 
1186    If the old item set contains the item to set (no inheritance) copy the item
1187    into the new set.
1188 
1189    If the old item set contains the item by inheritance and the new set
1190    contains the item, too:
1191       If the two items differ copy the item from the old set to the new set.
1192 
1193    Otherwise the new set will not be changed.
1194 */
1195 
lcl_CpyAttr(SfxItemSet & rNewSet,const SfxItemSet & rOldSet,sal_uInt16 nWhich)1196 void lcl_CpyAttr( SfxItemSet &rNewSet, const SfxItemSet &rOldSet, sal_uInt16 nWhich )
1197 {
1198 	const SfxPoolItem *pOldItem = NULL, *pNewItem = NULL;
1199 
1200     rOldSet.GetItemState( nWhich, sal_False, &pOldItem);
1201 	if (pOldItem != NULL)
1202 		rNewSet.Put( *pOldItem );
1203     else
1204     {
1205         pOldItem = rOldSet.GetItem( nWhich, sal_True);
1206         if (pOldItem != NULL)
1207         {
1208             pNewItem = rNewSet.GetItem( nWhich, sal_True);
1209             if (pNewItem != NULL)
1210             {
1211                 if (*pOldItem != *pNewItem)
1212                     rNewSet.Put( *pOldItem );
1213             }
1214             else {
1215                 ASSERT(0, "What am I doing here?");
1216             }
1217         }
1218         else {
1219             ASSERT(0, "What am I doing here?");
1220         }
1221     }
1222 
1223 }
1224 
1225 
1226 static SwFlyFrmFmt *
lcl_InsertLabel(SwDoc & rDoc,SwTxtFmtColls * const pTxtFmtCollTbl,SwUndoInsertLabel * const pUndo,SwLabelType const eType,String const & rTxt,String const & rSeparator,const String & rNumberingSeparator,const sal_Bool bBefore,const sal_uInt16 nId,const sal_uLong nNdIdx,const String & rCharacterStyle,const sal_Bool bCpyBrd)1227 lcl_InsertLabel(SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1228         SwUndoInsertLabel *const pUndo,
1229         SwLabelType const eType, String const& rTxt, String const& rSeparator,
1230             const String& rNumberingSeparator,
1231 			const sal_Bool bBefore, const sal_uInt16 nId, const sal_uLong nNdIdx,
1232             const String& rCharacterStyle,
1233 			const sal_Bool bCpyBrd )
1234 {
1235     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1236 
1237     sal_Bool bTable = sal_False;    //Um etwas Code zu sparen.
1238 
1239 	//Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt werden
1240 	//muss
1241     OSL_ENSURE( nId == USHRT_MAX  || nId < rDoc.GetFldTypes()->Count(),
1242             "FldType index out of bounds." );
1243     SwFieldType *pType = (nId != USHRT_MAX) ? (*rDoc.GetFldTypes())[nId] : NULL;
1244     OSL_ENSURE(!pType || pType->Which() == RES_SETEXPFLD, "wrong Id for Label");
1245 
1246     SwTxtFmtColl * pColl = NULL;
1247     if( pType )
1248     {
1249 	    for( sal_uInt16 i = pTxtFmtCollTbl->Count(); i; )
1250 	    {
1251 		    if( (*pTxtFmtCollTbl)[ --i ]->GetName() == pType->GetName() )
1252 		    {
1253 			    pColl = (*pTxtFmtCollTbl)[i];
1254 			    break;
1255 		    }
1256 	    }
1257         DBG_ASSERT( pColl, "no text collection found" );
1258     }
1259 
1260     if( !pColl )
1261     {
1262         pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1263     }
1264 
1265     SwTxtNode *pNew = NULL;
1266     SwFlyFrmFmt* pNewFmt = NULL;
1267 
1268 	switch ( eType )
1269 	{
1270 		case LTYPE_TABLE:
1271 			bTable = sal_True;
1272 			/* Kein Break hier */
1273 		case LTYPE_FLY:
1274 			//Am Anfang/Ende der Fly-Section den entsprechenden Node mit Feld
1275 			//einfuegen (Frame wird automatisch erzeugt).
1276 			{
1277                 SwStartNode *pSttNd = rDoc.GetNodes()[nNdIdx]->GetStartNode();
1278 				ASSERT( pSttNd, "Kein StartNode in InsertLabel." );
1279 				sal_uLong nNode;
1280 				if( bBefore )
1281 				{
1282 					nNode = pSttNd->GetIndex();
1283 					if( !bTable )
1284 						++nNode;
1285 				}
1286 				else
1287 				{
1288 					nNode = pSttNd->EndOfSectionIndex();
1289 					if( bTable )
1290 						++nNode;
1291 				}
1292 
1293 				if( pUndo )
1294 					pUndo->SetNodePos( nNode );
1295 
1296 				//Node fuer Beschriftungsabsatz erzeugen.
1297                 SwNodeIndex aIdx( rDoc.GetNodes(), nNode );
1298                 pNew = rDoc.GetNodes().MakeTxtNode( aIdx, pColl );
1299 			}
1300 			break;
1301 
1302 		case LTYPE_OBJECT:
1303 			{
1304 				//Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden
1305 				// Node mit Feld in den neuen Rahmen, den alten Rahmen mit
1306 				// dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen,
1307 				// Frames erzeugen.
1308 
1309 				//Erstmal das Format zum Fly besorgen und das Layout entkoppeln.
1310                 SwFrmFmt *pOldFmt = rDoc.GetNodes()[nNdIdx]->GetFlyFmt();
1311 				ASSERT( pOldFmt, "Format des Fly nicht gefunden." );
1312                 // --> OD #i115719#
1313                 // <title> and <description> attributes are lost when calling <DelFrms()>.
1314                 // Thus, keep them and restore them after the calling <MakeFrms()>
1315                 const bool bIsSwFlyFrmFmtInstance( dynamic_cast<SwFlyFrmFmt*>(pOldFmt) != 0 );
1316                 const String sTitle( bIsSwFlyFrmFmtInstance
1317                                      ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjTitle()
1318                                      : String() );
1319                 const String sDescription( bIsSwFlyFrmFmtInstance
1320                                            ? static_cast<SwFlyFrmFmt*>(pOldFmt)->GetObjDescription()
1321                                            : String() );
1322                 // <--
1323 				pOldFmt->DelFrms();
1324 
1325                 pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1326                                 rDoc.GetFrmFmtFromPool(RES_POOLFRM_FRAME) );
1327 
1328                 /* #i6447#: Only the selected items are copied from the old
1329                    format. */
1330 				SfxItemSet* pNewSet = pNewFmt->GetAttrSet().Clone( sal_True );
1331 
1332 
1333 				//Diejenigen Attribute uebertragen die auch gesetzt sind,
1334 				//andere sollen weiterhin aus den Vorlagen gueltig werden.
1335 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PRINT );
1336 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_OPAQUE );
1337 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_PROTECT );
1338 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1339 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_VERT_ORIENT );
1340 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_HORI_ORIENT );
1341 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_LR_SPACE );
1342 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_UL_SPACE );
1343 				lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_BACKGROUND );
1344 				if( bCpyBrd )
1345 				{
1346 					// JP 07.07.99: Bug 67029 - if at Grafik no BoxItem but
1347 					// 				in the new Format is any, then set the
1348 					//				default item in the new Set. Because
1349 					// 				the Size of the Grafik have never been
1350 					//				changed!
1351 					const SfxPoolItem *pItem;
1352 					if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1353 							GetItemState( RES_BOX, sal_True, &pItem ))
1354 						pNewSet->Put( *pItem );
1355 					else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1356 							GetItemState( RES_BOX, sal_True ))
1357 						pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1358 
1359 					if( SFX_ITEM_SET == pOldFmt->GetAttrSet().
1360 							GetItemState( RES_SHADOW, sal_True, &pItem ))
1361 						pNewSet->Put( *pItem );
1362 					else if( SFX_ITEM_SET == pNewFmt->GetAttrSet().
1363 							GetItemState( RES_SHADOW, sal_True ))
1364 						pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1365 				}
1366 				else
1367 				{
1368 					//Die Attribute hart setzen, weil sie sonst aus der
1369 					// Vorlage kommen koenten und dann passt die
1370 					// Grossenberechnung nicht mehr.
1371                     pNewSet->Put( SvxBoxItem(RES_BOX) );
1372                     pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1373 
1374 				}
1375 
1376 				//Anker immer uebertragen, ist sowieso ein hartes Attribut.
1377 				pNewSet->Put( pOldFmt->GetAnchor() );
1378 
1379 				//In der Hoehe soll der neue Varabel sein!
1380 				SwFmtFrmSize aFrmSize( pOldFmt->GetFrmSize() );
1381                 aFrmSize.SetHeightSizeType( ATT_MIN_SIZE );
1382 				pNewSet->Put( aFrmSize );
1383 
1384                 SwStartNode* pSttNd = rDoc.GetNodes().MakeTextSection(
1385                             SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1386 							SwFlyStartNode, pColl );
1387 				pNewSet->Put( SwFmtCntnt( pSttNd ));
1388 
1389                 pNewFmt->SetFmtAttr( *pNewSet );
1390 
1391 				//Bei InCntnt's wird es spannend: Das TxtAttribut muss
1392 				//vernichtet werden. Leider reisst dies neben den Frms auch
1393 				//noch das Format mit in sein Grab. Um dass zu unterbinden
1394 				//loesen wir vorher die Verbindung zwischen Attribut und Format.
1395 
1396 				const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1397                 if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1398                 {
1399 					const SwPosition *pPos = rAnchor.GetCntntAnchor();
1400 					SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1401 					ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1402 					const xub_StrLen nIdx = pPos->nContent.GetIndex();
1403                     SwTxtAttr * const pHnt =
1404                         pTxtNode->GetTxtAttrForCharAt(nIdx, RES_TXTATR_FLYCNT);
1405 
1406 					ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1407 								"Missing FlyInCnt-Hint." );
1408                     ASSERT( pHnt && pHnt->GetFlyCnt().GetFrmFmt() == pOldFmt,
1409 								"Wrong TxtFlyCnt-Hint." );
1410 
1411                     const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt(
1412                             pNewFmt );
1413                 }
1414 
1415 
1416 				//Der Alte soll keinen Umlauf haben, und er soll oben/mittig
1417 				//ausgerichtet sein.
1418 				//Ausserdem soll die Breite 100% betragen und bei Aenderungen
1419 				//Die Hoehe mit anpassen.
1420 				pNewSet->ClearItem();
1421 
1422 				pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1423 				pNewSet->Put( SvxOpaqueItem( RES_OPAQUE, sal_True ) );
1424                 pNewSet->Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ) );
1425                 pNewSet->Put( SwFmtHoriOrient( 0, text::HoriOrientation::CENTER, text::RelOrientation::FRAME ) );
1426 
1427 				aFrmSize = pOldFmt->GetFrmSize();
1428 				aFrmSize.SetWidthPercent( 0 );
1429 				aFrmSize.SetHeightPercent( 255 );
1430 				pNewSet->Put( aFrmSize );
1431 
1432 				//Die Attribute setzen wir hart, weil sie sonst aus der Vorlage
1433 				//kommen koenten und dann passt die Grossenberechnung nicht mehr.
1434 				if( bCpyBrd )
1435 				{
1436                     pNewSet->Put( SvxBoxItem(RES_BOX) );
1437                     pNewSet->Put( SvxShadowItem(RES_SHADOW) );
1438 				}
1439                 pNewSet->Put( SvxLRSpaceItem(RES_LR_SPACE) );
1440                 pNewSet->Put( SvxULSpaceItem(RES_UL_SPACE) );
1441 
1442 				//Der Alte ist absatzgebunden, und zwar am Absatz im neuen.
1443                 SwFmtAnchor aAnch( FLY_AT_PARA );
1444 				SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1445 				pNew = aAnchIdx.GetNode().GetTxtNode();
1446 				SwPosition aPos( aAnchIdx );
1447 				aAnch.SetAnchor( &aPos );
1448 				pNewSet->Put( aAnch );
1449 
1450 				if( pUndo )
1451 					pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1452 				else
1453                     pOldFmt->SetFmtAttr( *pNewSet );
1454 
1455 				delete pNewSet;
1456 
1457 				//Nun nur noch die Flys erzeugen lassen. Das ueberlassen
1458 				//wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig).
1459 				pNewFmt->MakeFrms();
1460                 // --> OD #i115719#
1461                 if ( bIsSwFlyFrmFmtInstance )
1462                 {
1463                     static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjTitle( sTitle );
1464                     static_cast<SwFlyFrmFmt*>(pOldFmt)->SetObjDescription( sDescription );
1465                 }
1466                 // <--
1467 			}
1468 			break;
1469 
1470 		default:
1471             OSL_ENSURE(false, "unknown LabelType?");
1472 	}
1473 	ASSERT( pNew, "No Label inserted" );
1474 	if( pNew )
1475 	{
1476         //#i61007# order of captions
1477         sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1478 		//String aufbereiten
1479         String aTxt;
1480         if( bOrderNumberingFirst )
1481         {
1482             aTxt = rNumberingSeparator;
1483         }
1484         if( pType)
1485         {
1486             aTxt += pType->GetName();
1487             if( !bOrderNumberingFirst )
1488                 aTxt += ' ';
1489         }
1490 		xub_StrLen nIdx = aTxt.Len();
1491         if( rTxt.Len() > 0 )
1492         {
1493             aTxt += rSeparator;
1494         }
1495         xub_StrLen nSepIdx = aTxt.Len();
1496         aTxt += rTxt;
1497 
1498 		//String einfuegen
1499 		SwIndex aIdx( pNew, 0 );
1500         pNew->InsertText( aTxt, aIdx );
1501 
1502         //
1503 		//Feld einfuegen
1504         if(pType)
1505         {
1506             SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, SVX_NUM_ARABIC);
1507             if( bOrderNumberingFirst )
1508                 nIdx = 0;
1509             SwFmtFld aFmt( aFld );
1510             pNew->InsertItem( aFmt, nIdx, nIdx );
1511             if(rCharacterStyle.Len())
1512             {
1513                 SwCharFmt* pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1514                 if( !pCharFmt )
1515                 {
1516                     const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName(rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT);
1517                     pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1518                 }
1519                 if (pCharFmt)
1520                 {
1521                     SwFmtCharFmt aCharFmt( pCharFmt );
1522                     pNew->InsertItem( aCharFmt, 0,
1523                         nSepIdx + 1, nsSetAttrMode::SETATTR_DONTEXPAND );
1524                 }
1525             }
1526         }
1527 
1528 		if ( bTable )
1529 		{
1530 			if ( bBefore )
1531 			{
1532 				if ( !pNew->GetSwAttrSet().GetKeep().GetValue()  )
1533                     pNew->SetAttr( SvxFmtKeepItem( sal_True, RES_KEEP ) );
1534 			}
1535 			else
1536 			{
1537                 SwTableNode *const pNd =
1538                     rDoc.GetNodes()[nNdIdx]->GetStartNode()->GetTableNode();
1539 				SwTable &rTbl = pNd->GetTable();
1540 				if ( !rTbl.GetFrmFmt()->GetKeep().GetValue() )
1541                     rTbl.GetFrmFmt()->SetFmtAttr( SvxFmtKeepItem( sal_True, RES_KEEP ) );
1542 				if ( pUndo )
1543 					pUndo->SetUndoKeep();
1544 			}
1545 		}
1546 	    rDoc.SetModified();
1547 	}
1548 
1549 	return pNewFmt;
1550 }
1551 
1552 SwFlyFrmFmt *
InsertLabel(SwLabelType const eType,String const & rTxt,String const & rSeparator,String const & rNumberingSeparator,sal_Bool const bBefore,sal_uInt16 const nId,sal_uLong const nNdIdx,String const & rCharacterStyle,sal_Bool const bCpyBrd)1553 SwDoc::InsertLabel(
1554         SwLabelType const eType, String const& rTxt, String const& rSeparator,
1555         String const& rNumberingSeparator,
1556         sal_Bool const bBefore, sal_uInt16 const nId, sal_uLong const nNdIdx,
1557         String const& rCharacterStyle,
1558         sal_Bool const bCpyBrd )
1559 {
1560     SwUndoInsertLabel * pUndo(0);
1561     if (GetIDocumentUndoRedo().DoesUndo())
1562     {
1563         pUndo = new SwUndoInsertLabel(
1564                         eType, rTxt, rSeparator, rNumberingSeparator,
1565                         bBefore, nId, rCharacterStyle, bCpyBrd );
1566     }
1567 
1568     SwFlyFrmFmt *const pNewFmt = lcl_InsertLabel(*this, pTxtFmtCollTbl, pUndo,
1569             eType, rTxt, rSeparator, rNumberingSeparator, bBefore,
1570             nId, nNdIdx, rCharacterStyle, bCpyBrd);
1571 
1572     if (pUndo)
1573     {
1574         GetIDocumentUndoRedo().AppendUndo(pUndo);
1575     }
1576     else
1577     {
1578         GetIDocumentUndoRedo().DelAllUndoObj();
1579     }
1580 
1581     return pNewFmt;
1582 }
1583 
1584 
1585 /*************************************************************************
1586 |*
1587 |*	SwDoc::InsertDrawLabel()
1588 |*
1589 |*	Ersterstellung		MIB 7. Dez. 98
1590 |*	Letzte Aenderung	MIB 7. Dez. 98
1591 |*
1592 |*************************************************************************/
1593 
1594 static SwFlyFrmFmt *
lcl_InsertDrawLabel(SwDoc & rDoc,SwTxtFmtColls * const pTxtFmtCollTbl,SwUndoInsertLabel * const pUndo,SwDrawFrmFmt * const pOldFmt,String const & rTxt,const String & rSeparator,const String & rNumberSeparator,const sal_uInt16 nId,const String & rCharacterStyle,SdrObject & rSdrObj)1595 lcl_InsertDrawLabel( SwDoc & rDoc, SwTxtFmtColls *const pTxtFmtCollTbl,
1596         SwUndoInsertLabel *const pUndo, SwDrawFrmFmt *const pOldFmt,
1597         String const& rTxt,
1598                                      const String& rSeparator,
1599                                      const String& rNumberSeparator,
1600 									 const sal_uInt16 nId,
1601                                      const String& rCharacterStyle,
1602                                      SdrObject& rSdrObj )
1603 {
1604     ::sw::UndoGuard const undoGuard(rDoc.GetIDocumentUndoRedo());
1605     ::sw::DrawUndoGuard const drawUndoGuard(rDoc.GetIDocumentUndoRedo());
1606 
1607 	// Erstmal das Feld bauen, weil ueber den Namen die TxtColl besorgt
1608 	// werden muss
1609     OSL_ENSURE( nId == USHRT_MAX  || nId < rDoc.GetFldTypes()->Count(),
1610             "FldType index out of bounds" );
1611     SwFieldType *pType = nId != USHRT_MAX ? (*rDoc.GetFldTypes())[nId] : 0;
1612     OSL_ENSURE( !pType || pType->Which() == RES_SETEXPFLD, "Wrong label id" );
1613 
1614     SwTxtFmtColl *pColl = NULL;
1615     if( pType )
1616     {
1617         for( sal_uInt16 i = pTxtFmtCollTbl->Count(); i; )
1618         {
1619             if( (*pTxtFmtCollTbl)[ --i ]->GetName() == pType->GetName() )
1620             {
1621                 pColl = (*pTxtFmtCollTbl)[i];
1622                 break;
1623             }
1624         }
1625         DBG_ASSERT( pColl, "no text collection found" );
1626     }
1627 
1628     if( !pColl )
1629     {
1630         pColl = rDoc.GetTxtCollFromPool( RES_POOLCOLL_LABEL );
1631     }
1632 
1633     SwTxtNode* pNew = NULL;
1634     SwFlyFrmFmt* pNewFmt = NULL;
1635 
1636 	// Rahmen zerstoeren, neuen Rahmen einfuegen, entsprechenden
1637 	// Node mit Feld in den neuen Rahmen, den alten Rahmen mit
1638 	// dem Object (Grafik/Ole) absatzgebunden in den neuen Rahmen,
1639 	// Frames erzeugen.
1640 
1641     // OD 27.11.2003 #112045# - Keep layer ID of drawing object before removing
1642     // its frames.
1643     // Note: The layer ID is passed to the undo and have to be the correct value.
1644     //       Removing the frames of the drawing object changes its layer.
1645     const SdrLayerID nLayerId = rSdrObj.GetLayer();
1646 
1647 	pOldFmt->DelFrms();
1648 
1649 	//Bei InCntnt's wird es spannend: Das TxtAttribut muss
1650 	//vernichtet werden. Leider reisst dies neben den Frms auch
1651 	//noch das Format mit in sein Grab. Um dass zu unterbinden
1652 	//loesen wir vorher die Verbindung zwischen Attribut und Format.
1653 	SfxItemSet* pNewSet = pOldFmt->GetAttrSet().Clone( sal_False );
1654 
1655 	// Ggf. Groesse und Position des Rahmens schuetzen
1656 	if ( rSdrObj.IsMoveProtect() || rSdrObj.IsResizeProtect() )
1657 	{
1658         SvxProtectItem aProtect(RES_PROTECT);
1659 		aProtect.SetCntntProtect( sal_False );
1660 		aProtect.SetPosProtect( rSdrObj.IsMoveProtect() );
1661 		aProtect.SetSizeProtect( rSdrObj.IsResizeProtect() );
1662 		pNewSet->Put( aProtect );
1663 	}
1664 
1665 	// Umlauf uebernehmen
1666 	lcl_CpyAttr( *pNewSet, pOldFmt->GetAttrSet(), RES_SURROUND );
1667 
1668 	// Den Rahmen ggf. in den Hintergrund schicken.
1669     // OD 02.07.2003 #108784# - consider 'invisible' hell layer.
1670     if ( rDoc.GetHellId() != nLayerId &&
1671          rDoc.GetInvisibleHellId() != nLayerId )
1672 	{
1673         SvxOpaqueItem aOpaque( RES_OPAQUE );
1674 		aOpaque.SetValue( sal_True );
1675 		pNewSet->Put( aOpaque );
1676 	}
1677 
1678 	// Position uebernehmen
1679     // OD 2004-04-15 #i26791# - use directly the positioning attributes of
1680     // the drawing object.
1681     pNewSet->Put( pOldFmt->GetHoriOrient() );
1682     pNewSet->Put( pOldFmt->GetVertOrient() );
1683 
1684 	pNewSet->Put( pOldFmt->GetAnchor() );
1685 
1686 	//In der Hoehe soll der neue Varabel sein!
1687  	Size aSz( rSdrObj.GetCurrentBoundRect().GetSize() );
1688 	SwFmtFrmSize aFrmSize( ATT_MIN_SIZE, aSz.Width(), aSz.Height() );
1689 	pNewSet->Put( aFrmSize );
1690 
1691 	// Abstaende auf den neuen Rahmen uebertragen. Eine Umrandung
1692 	// gibt es beu Zeichen-Objekten nicht, also muss sie geloescht
1693 	// werden.
1694 	// MA: Falsch sie wird nicht gesetzt, denn die aus der Vorlage
1695 	// soll ruhig wirksam werden
1696 	pNewSet->Put( pOldFmt->GetLRSpace() );
1697 	pNewSet->Put( pOldFmt->GetULSpace() );
1698 
1699     SwStartNode* pSttNd =
1700         rDoc.GetNodes().MakeTextSection(
1701             SwNodeIndex( rDoc.GetNodes().GetEndOfAutotext() ),
1702                                     SwFlyStartNode, pColl );
1703 
1704     pNewFmt = rDoc.MakeFlyFrmFmt( rDoc.GetUniqueFrameName(),
1705                  rDoc.GetFrmFmtFromPool( RES_POOLFRM_FRAME ) );
1706 
1707 	// JP 28.10.99: Bug 69487 - set border and shadow to default if the
1708 	// 				template contains any.
1709 	if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState( RES_BOX, sal_True ))
1710 		pNewSet->Put( *GetDfltAttr( RES_BOX ) );
1711 
1712 	if( SFX_ITEM_SET == pNewFmt->GetAttrSet().GetItemState(RES_SHADOW,sal_True))
1713 		pNewSet->Put( *GetDfltAttr( RES_SHADOW ) );
1714 
1715     pNewFmt->SetFmtAttr( SwFmtCntnt( pSttNd ));
1716     pNewFmt->SetFmtAttr( *pNewSet );
1717 
1718 	const SwFmtAnchor& rAnchor = pNewFmt->GetAnchor();
1719     if ( FLY_AS_CHAR == rAnchor.GetAnchorId() )
1720 	{
1721 		const SwPosition *pPos = rAnchor.GetCntntAnchor();
1722 		SwTxtNode *pTxtNode = pPos->nNode.GetNode().GetTxtNode();
1723 		ASSERT( pTxtNode->HasHints(), "Missing FlyInCnt-Hint." );
1724 		const xub_StrLen nIdx = pPos->nContent.GetIndex();
1725         SwTxtAttr * const pHnt =
1726             pTxtNode->GetTxtAttrForCharAt( nIdx, RES_TXTATR_FLYCNT );
1727 
1728 #ifdef DBG_UTIL
1729 		ASSERT( pHnt && pHnt->Which() == RES_TXTATR_FLYCNT,
1730 					"Missing FlyInCnt-Hint." );
1731 		ASSERT( pHnt && ((SwFmtFlyCnt&)pHnt->GetFlyCnt()).
1732 					GetFrmFmt() == (SwFrmFmt*)pOldFmt,
1733 					"Wrong TxtFlyCnt-Hint." );
1734 #endif
1735         const_cast<SwFmtFlyCnt&>(pHnt->GetFlyCnt()).SetFlyFmt( pNewFmt );
1736     }
1737 
1738 
1739 	//Der Alte soll keinen Umlauf haben, und er soll oben/mittig
1740 	//ausgerichtet sein.
1741 	pNewSet->ClearItem();
1742 
1743 	pNewSet->Put( SwFmtSurround( SURROUND_NONE ) );
1744     if (nLayerId == rDoc.GetHellId())
1745     {
1746         rSdrObj.SetLayer( rDoc.GetHeavenId() );
1747     }
1748     // OD 02.07.2003 #108784# - consider drawing objects in 'invisible' hell layer
1749     else if (nLayerId == rDoc.GetInvisibleHellId())
1750     {
1751         rSdrObj.SetLayer( rDoc.GetInvisibleHeavenId() );
1752     }
1753     pNewSet->Put( SvxLRSpaceItem( RES_LR_SPACE ) );
1754     pNewSet->Put( SvxULSpaceItem( RES_UL_SPACE ) );
1755 
1756     // OD 2004-04-15 #i26791# - set position of the drawing object, which is labeled.
1757     pNewSet->Put( SwFmtVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME ) );
1758     pNewSet->Put( SwFmtHoriOrient( 0, text::HoriOrientation::CENTER, text::RelOrientation::FRAME ) );
1759 
1760 	//Der Alte ist absatzgebunden, und zwar am Absatz im neuen.
1761     SwFmtAnchor aAnch( FLY_AT_PARA );
1762 	SwNodeIndex aAnchIdx( *pNewFmt->GetCntnt().GetCntntIdx(), 1 );
1763 	pNew = aAnchIdx.GetNode().GetTxtNode();
1764 	SwPosition aPos( aAnchIdx );
1765 	aAnch.SetAnchor( &aPos );
1766 	pNewSet->Put( aAnch );
1767 
1768 	if( pUndo )
1769 	{
1770 		pUndo->SetFlys( *pOldFmt, *pNewSet, *pNewFmt );
1771         // OD 2004-04-15 #i26791# - position no longer needed
1772         pUndo->SetDrawObj( nLayerId );
1773 	}
1774 	else
1775         pOldFmt->SetFmtAttr( *pNewSet );
1776 
1777 	delete pNewSet;
1778 
1779 	//Nun nur noch die Flys erzeugen lassen. Das ueberlassen
1780 	//wir vorhanden Methoden (insb. fuer InCntFlys etwas aufwendig).
1781 	pNewFmt->MakeFrms();
1782 
1783 	ASSERT( pNew, "No Label inserted" );
1784 
1785 	if( pNew )
1786 	{
1787         //#i61007# order of captions
1788         sal_Bool bOrderNumberingFirst = SW_MOD()->GetModuleConfig()->IsCaptionOrderNumberingFirst();
1789 
1790         // prepare string
1791         String aTxt;
1792         if( bOrderNumberingFirst )
1793         {
1794             aTxt = rNumberSeparator;
1795         }
1796         if ( pType )
1797         {
1798             aTxt += pType->GetName();
1799             if( !bOrderNumberingFirst )
1800                 aTxt += ' ';
1801         }
1802 		xub_StrLen nIdx = aTxt.Len();
1803         aTxt += rSeparator;
1804         xub_StrLen nSepIdx = aTxt.Len();
1805         aTxt += rTxt;
1806 
1807         // insert text
1808 		SwIndex aIdx( pNew, 0 );
1809         pNew->InsertText( aTxt, aIdx );
1810 
1811         // insert field
1812         if ( pType )
1813         {
1814             SwSetExpField aFld( (SwSetExpFieldType*)pType, aEmptyStr, SVX_NUM_ARABIC );
1815             if( bOrderNumberingFirst )
1816                 nIdx = 0;
1817             SwFmtFld aFmt( aFld );
1818             pNew->InsertItem( aFmt, nIdx, nIdx );
1819             if ( rCharacterStyle.Len() )
1820             {
1821                 SwCharFmt * pCharFmt = rDoc.FindCharFmtByName(rCharacterStyle);
1822                 if ( !pCharFmt )
1823                 {
1824                     const sal_uInt16 nMyId = SwStyleNameMapper::GetPoolIdFromUIName( rCharacterStyle, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
1825                     pCharFmt = rDoc.GetCharFmtFromPool( nMyId );
1826                 }
1827                 if ( pCharFmt )
1828                 {
1829                     SwFmtCharFmt aCharFmt( pCharFmt );
1830                     pNew->InsertItem( aCharFmt, 0, nSepIdx + 1,
1831                             nsSetAttrMode::SETATTR_DONTEXPAND );
1832                 }
1833             }
1834         }
1835     }
1836 
1837 	return pNewFmt;
1838 }
1839 
InsertDrawLabel(String const & rTxt,String const & rSeparator,String const & rNumberSeparator,sal_uInt16 const nId,String const & rCharacterStyle,SdrObject & rSdrObj)1840 SwFlyFrmFmt* SwDoc::InsertDrawLabel(
1841         String const& rTxt,
1842         String const& rSeparator,
1843         String const& rNumberSeparator,
1844         sal_uInt16 const nId,
1845         String const& rCharacterStyle,
1846         SdrObject& rSdrObj )
1847 {
1848     SwDrawContact *const pContact =
1849         static_cast<SwDrawContact*>(GetUserCall( &rSdrObj ));
1850     OSL_ENSURE( RES_DRAWFRMFMT == pContact->GetFmt()->Which(),
1851             "InsertDrawLabel(): not a DrawFrmFmt" );
1852     if (!pContact)
1853         return 0;
1854 
1855     SwDrawFrmFmt* pOldFmt = (SwDrawFrmFmt *)pContact->GetFmt();
1856     if (!pOldFmt)
1857         return 0;
1858 
1859     SwUndoInsertLabel * pUndo = 0;
1860     if (GetIDocumentUndoRedo().DoesUndo())
1861     {
1862         GetIDocumentUndoRedo().ClearRedo();
1863         pUndo = new SwUndoInsertLabel(
1864             LTYPE_DRAW, rTxt, rSeparator, rNumberSeparator, sal_False,
1865             nId, rCharacterStyle, sal_False );
1866     }
1867 
1868     SwFlyFrmFmt *const pNewFmt = lcl_InsertDrawLabel(
1869         *this, pTxtFmtCollTbl, pUndo, pOldFmt,
1870         rTxt, rSeparator, rNumberSeparator, nId, rCharacterStyle, rSdrObj);
1871 
1872     if (pUndo)
1873     {
1874         GetIDocumentUndoRedo().AppendUndo( pUndo );
1875     }
1876     else
1877     {
1878         GetIDocumentUndoRedo().DelAllUndoObj();
1879     }
1880 
1881     return pNewFmt;
1882 }
1883 
1884 
1885 /*************************************************************************
1886 |*
1887 |*	IDocumentTimerAccess-methods
1888 |*
1889 |*************************************************************************/
1890 
StartIdling()1891 void SwDoc::StartIdling()
1892 {
1893     mbStartIdleTimer = sal_True;
1894     if( !mIdleBlockCount )
1895         aIdleTimer.Start();
1896 }
1897 
StopIdling()1898 void SwDoc::StopIdling()
1899 {
1900     mbStartIdleTimer = sal_False;
1901     aIdleTimer.Stop();
1902 }
1903 
BlockIdling()1904 void SwDoc::BlockIdling()
1905 {
1906     aIdleTimer.Stop();
1907     ++mIdleBlockCount;
1908 }
1909 
UnblockIdling()1910 void SwDoc::UnblockIdling()
1911 {
1912     --mIdleBlockCount;
1913     if( !mIdleBlockCount && mbStartIdleTimer && !aIdleTimer.IsActive() )
1914         aIdleTimer.Start();
1915 }
1916 
1917 
1918 /*************************************************************************
1919 |*
1920 |*	SwDoc::DoIdleJobs()
1921 |*
1922 |*	Ersterstellung		OK 30.03.94
1923 |*	Letzte Aenderung	MA 09. Jun. 95
1924 |*
1925 |*************************************************************************/
1926 
IMPL_LINK(SwDoc,DoIdleJobs,Timer *,pTimer)1927 IMPL_LINK( SwDoc, DoIdleJobs, Timer *, pTimer )
1928 {
1929 #ifdef TIMELOG
1930 	static ::rtl::Logfile* pModLogFile = 0;
1931 	if( !pModLogFile )
1932 		pModLogFile = new ::rtl::Logfile( "First DoIdleJobs" );
1933 #endif
1934 
1935 	SwRootFrm* pTmpRoot = GetCurrentLayout();//swmod 080219
1936 	if( pTmpRoot &&
1937         !SfxProgress::GetActiveProgress( pDocShell ) )
1938 	{
1939 		ViewShell *pSh, *pStartSh;
1940 		pSh = pStartSh = GetCurrentViewShell();
1941 		do {
1942 			if( pSh->ActionPend() )
1943             {
1944                 if( pTimer )
1945                     pTimer->Start();
1946 				return 0;
1947             }
1948 			pSh = (ViewShell*)pSh->GetNext();
1949 		} while( pSh != pStartSh );
1950 
1951         if( pTmpRoot->IsNeedGrammarCheck() )
1952         {
1953             sal_Bool bIsOnlineSpell = pSh->GetViewOptions()->IsOnlineSpell();
1954             sal_Bool bIsAutoGrammar = sal_False;
1955             SvtLinguConfig().GetProperty( ::rtl::OUString::createFromAscii(
1956                         UPN_IS_GRAMMAR_AUTO ) ) >>= bIsAutoGrammar;
1957 
1958             if (bIsOnlineSpell && bIsAutoGrammar)
1959                 StartGrammarChecking( *this );
1960         }
1961 		SwFldUpdateFlags nFldUpdFlag;
1962 		std::set<SwRootFrm*> aAllLayouts = GetAllLayouts();//swmod 080320
1963 		std::set<SwRootFrm*>::iterator pLayIter = aAllLayouts.begin();
1964 		for ( ;pLayIter != aAllLayouts.end();pLayIter++ )
1965 		{
1966 			if ((*pLayIter)->IsIdleFormat())
1967 			{
1968 				(*pLayIter)->GetCurrShell()->LayoutIdle();
1969 				break;
1970 			}
1971 		}
1972 	    bool bAllValid = pLayIter == aAllLayouts.end() ? 1 : 0;
1973         if( bAllValid && ( AUTOUPD_FIELD_ONLY ==
1974                  ( nFldUpdFlag = getFieldUpdateFlags(true) )
1975 					|| AUTOUPD_FIELD_AND_CHARTS == nFldUpdFlag ) &&
1976 				GetUpdtFlds().IsFieldsDirty() &&
1977 				!GetUpdtFlds().IsInUpdateFlds() &&
1978 				!IsExpFldsLocked()
1979 				// das umschalten der Feldname fuehrt zu keinem Update der
1980 				// Felder, also der "Hintergrund-Update" immer erfolgen
1981 				/* && !pStartSh->GetViewOptions()->IsFldName()*/ )
1982 		{
1983 			// chaos::Action-Klammerung!
1984 			GetUpdtFlds().SetInUpdateFlds( sal_True );
1985 
1986 			pTmpRoot->StartAllAction();
1987 
1988             // no jump on update of fields #i85168#
1989             const sal_Bool bOldLockView = pStartSh->IsViewLocked();
1990             pStartSh->LockView( sal_True );
1991 
1992 			GetSysFldType( RES_CHAPTERFLD )->ModifyNotification( 0, 0 );	// KapitelFld
1993 			UpdateExpFlds( 0, sal_False );		// Expression-Felder Updaten
1994 			UpdateTblFlds(NULL);				// Tabellen
1995 			UpdateRefFlds(NULL);				// Referenzen
1996 
1997 			pTmpRoot->EndAllAction();
1998 
1999             pStartSh->LockView( bOldLockView );
2000 
2001 			GetUpdtFlds().SetInUpdateFlds( sal_False );
2002 			GetUpdtFlds().SetFieldsDirty( sal_False );
2003 		}
2004 	}	//swmod 080219
2005 #ifdef TIMELOG
2006 	if( pModLogFile && 1 != (long)pModLogFile )
2007 		delete pModLogFile, ((long&)pModLogFile) = 1;
2008 #endif
2009     if( pTimer )
2010         pTimer->Start();
2011 	return 0;
2012 }
2013 
IMPL_STATIC_LINK(SwDoc,BackgroundDone,SvxBrushItem *,EMPTYARG)2014 IMPL_STATIC_LINK( SwDoc, BackgroundDone, SvxBrushItem*, EMPTYARG )
2015 {
2016 	ViewShell *pSh, *pStartSh;
2017 	pSh = pStartSh = pThis->GetCurrentViewShell();	//swmod 071108//swmod 071225
2018 	if( pStartSh )
2019 		do {
2020 			if( pSh->GetWin() )
2021 			{
2022 				//Fuer Repaint mir virtuellen Device sorgen.
2023 				pSh->LockPaint();
2024 				pSh->UnlockPaint( sal_True );
2025 			}
2026 			pSh = (ViewShell*)pSh->GetNext();
2027 		} while( pSh != pStartSh );
2028 	return 0;
2029 }
2030 
lcl_GetUniqueFlyName(const SwDoc * pDoc,sal_uInt16 nDefStrId)2031 static String lcl_GetUniqueFlyName( const SwDoc* pDoc, sal_uInt16 nDefStrId )
2032 {
2033 	ResId aId( nDefStrId, *pSwResMgr );
2034 	String aName( aId );
2035 	xub_StrLen nNmLen = aName.Len();
2036 
2037 	const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts();
2038 
2039 	sal_uInt16 nNum, nTmp, nFlagSize = ( rFmts.Count() / 8 ) +2;
2040 	sal_uInt8* pSetFlags = new sal_uInt8[ nFlagSize ];
2041 	sal_uInt16 n;
2042 
2043 	memset( pSetFlags, 0, nFlagSize );
2044 
2045 	for( n = 0; n < rFmts.Count(); ++n )
2046 	{
2047 		const SwFrmFmt* pFlyFmt = rFmts[ n ];
2048 		if( RES_FLYFRMFMT == pFlyFmt->Which() &&
2049 			pFlyFmt->GetName().Match( aName ) == nNmLen )
2050 		{
2051 			// Nummer bestimmen und das Flag setzen
2052             nNum = static_cast< sal_uInt16 >( pFlyFmt->GetName().Copy( nNmLen ).ToInt32() );
2053 			if( nNum-- && nNum < rFmts.Count() )
2054 				pSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 ));
2055 		}
2056 	}
2057 
2058 	// alle Nummern entsprechend geflag, also bestimme die richtige Nummer
2059 	nNum = rFmts.Count();
2060 	for( n = 0; n < nFlagSize; ++n )
2061 		if( 0xff != ( nTmp = pSetFlags[ n ] ))
2062 		{
2063 			// also die Nummer bestimmen
2064 			nNum = n * 8;
2065 			while( nTmp & 1 )
2066 				++nNum, nTmp >>= 1;
2067 			break;
2068 		}
2069 
2070 	delete [] pSetFlags;
2071 	return aName += String::CreateFromInt32( ++nNum );
2072 }
2073 
GetUniqueGrfName() const2074 String SwDoc::GetUniqueGrfName() const
2075 {
2076 	return lcl_GetUniqueFlyName( this, STR_GRAPHIC_DEFNAME );
2077 }
2078 
GetUniqueOLEName() const2079 String SwDoc::GetUniqueOLEName() const
2080 {
2081 	return lcl_GetUniqueFlyName( this, STR_OBJECT_DEFNAME );
2082 }
2083 
GetUniqueFrameName() const2084 String SwDoc::GetUniqueFrameName() const
2085 {
2086 	return lcl_GetUniqueFlyName( this, STR_FRAME_DEFNAME );
2087 }
2088 
FindFlyByName(const String & rName,sal_Int8 nNdTyp) const2089 const SwFlyFrmFmt* SwDoc::FindFlyByName( const String& rName, sal_Int8 nNdTyp ) const
2090 {
2091 	const SwSpzFrmFmts& rFmts = *GetSpzFrmFmts();
2092 	for( sal_uInt16 n = rFmts.Count(); n; )
2093 	{
2094 		const SwFrmFmt* pFlyFmt = rFmts[ --n ];
2095 		const SwNodeIndex* pIdx;
2096 		if( RES_FLYFRMFMT == pFlyFmt->Which() && pFlyFmt->GetName() == rName &&
2097 			0 != ( pIdx = pFlyFmt->GetCntnt().GetCntntIdx() ) &&
2098 			pIdx->GetNode().GetNodes().IsDocNodes() )
2099 		{
2100 			if( nNdTyp )
2101 			{
2102 				// dann noch auf den richtigen Node-Typ abfragen
2103 				const SwNode* pNd = GetNodes()[ pIdx->GetIndex()+1 ];
2104 				if( nNdTyp == ND_TEXTNODE
2105 						? !pNd->IsNoTxtNode()
2106 						: nNdTyp == pNd->GetNodeType() )
2107 					return (SwFlyFrmFmt*)pFlyFmt;
2108 			}
2109 			else
2110 				return (SwFlyFrmFmt*)pFlyFmt;
2111 		}
2112 	}
2113 	return 0;
2114 }
2115 
SetFlyName(SwFlyFrmFmt & rFmt,const String & rName)2116 void SwDoc::SetFlyName( SwFlyFrmFmt& rFmt, const String& rName )
2117 {
2118 	String sName( rName );
2119 	if( !rName.Len() || FindFlyByName( rName ) )
2120 	{
2121 		sal_uInt16 nTyp = STR_FRAME_DEFNAME;
2122 		const SwNodeIndex* pIdx = rFmt.GetCntnt().GetCntntIdx();
2123 		if( pIdx && pIdx->GetNode().GetNodes().IsDocNodes() )
2124 			switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2125 			{
2126 			case ND_GRFNODE:	nTyp = STR_GRAPHIC_DEFNAME;	break;
2127 			case ND_OLENODE:	nTyp = STR_OBJECT_DEFNAME;	break;
2128 			}
2129 		sName = lcl_GetUniqueFlyName( this, nTyp );
2130 	}
2131 	rFmt.SetName( sName, sal_True );
2132     SetModified();
2133 }
2134 
SetAllUniqueFlyNames()2135 void SwDoc::SetAllUniqueFlyNames()
2136 {
2137 	sal_uInt16 n, nFlyNum = 0, nGrfNum = 0, nOLENum = 0;
2138 
2139 	ResId nFrmId( STR_FRAME_DEFNAME, *pSwResMgr ),
2140 		  nGrfId( STR_GRAPHIC_DEFNAME, *pSwResMgr ),
2141 		  nOLEId( STR_OBJECT_DEFNAME, *pSwResMgr );
2142 	String sFlyNm( nFrmId );
2143 	String sGrfNm( nGrfId );
2144 	String sOLENm( nOLEId );
2145 
2146 	if( 255 < ( n = GetSpzFrmFmts()->Count() ))
2147 		n = 255;
2148 	SwSpzFrmFmts aArr( (sal_Int8)n, 10 );
2149 	SwFrmFmtPtr pFlyFmt;
2150 	bool bContainsAtPageObjWithContentAnchor = false;
2151 
2152 	for( n = GetSpzFrmFmts()->Count(); n; )
2153 	{
2154 		if( RES_FLYFRMFMT == (pFlyFmt = (*GetSpzFrmFmts())[ --n ])->Which() )
2155 		{
2156 			sal_uInt16 *pNum = 0;
2157 			xub_StrLen nLen;
2158 			const String& rNm = pFlyFmt->GetName();
2159 			if( rNm.Len() )
2160 			{
2161 				if( rNm.Match( sGrfNm ) == ( nLen = sGrfNm.Len() ))
2162 					pNum = &nGrfNum;
2163 				else if( rNm.Match( sFlyNm ) == ( nLen = sFlyNm.Len() ))
2164 					pNum = &nFlyNum;
2165 				else if( rNm.Match( sOLENm ) == ( nLen = sOLENm.Len() ))
2166 					pNum = &nOLENum;
2167 
2168                 if ( pNum && *pNum < ( nLen = static_cast< xub_StrLen >( rNm.Copy( nLen ).ToInt32() ) ) )
2169 					*pNum = nLen;
2170 			}
2171 			else
2172 				// das wollen wir nachher setzen
2173 				aArr.Insert( pFlyFmt, aArr.Count() );
2174 
2175 		}
2176 		if ( !bContainsAtPageObjWithContentAnchor )
2177 		{
2178 			const SwFmtAnchor& rAnchor = pFlyFmt->GetAnchor();
2179             if ( (FLY_AT_PAGE == rAnchor.GetAnchorId()) &&
2180                  rAnchor.GetCntntAnchor() )
2181             {
2182 				bContainsAtPageObjWithContentAnchor = true;
2183             }
2184 		}
2185 	}
2186     SetContainsAtPageObjWithContentAnchor( bContainsAtPageObjWithContentAnchor );
2187 
2188 	const SwNodeIndex* pIdx;
2189 
2190 	for( n = aArr.Count(); n; )
2191 		if( 0 != ( pIdx = ( pFlyFmt = aArr[ --n ])->GetCntnt().GetCntntIdx() )
2192 			&& pIdx->GetNode().GetNodes().IsDocNodes() )
2193 		{
2194 			sal_uInt16 nNum;
2195 			String sNm;
2196 			switch( GetNodes()[ pIdx->GetIndex() + 1 ]->GetNodeType() )
2197 			{
2198 			case ND_GRFNODE:
2199 				sNm = sGrfNm;
2200 				nNum = ++nGrfNum;
2201 				break;
2202 			case ND_OLENODE:
2203 				sNm = sOLENm;
2204 				nNum = ++nOLENum;
2205 				break;
2206 			default:
2207 				sNm = sFlyNm;
2208 				nNum = ++nFlyNum;
2209 				break;
2210 			}
2211 			pFlyFmt->SetName( sNm += String::CreateFromInt32( nNum ));
2212 		}
2213 	aArr.Remove( 0, aArr.Count() );
2214 
2215 	if( GetFtnIdxs().Count() )
2216 	{
2217 		SwTxtFtn::SetUniqueSeqRefNo( *this );
2218         // --> FME 2005-08-02 #i52775# Chapter footnotes did not
2219         // get updated correctly. Calling UpdateAllFtn() instead of
2220         // UpdateFtn() solves this problem, but I do not dare to
2221         // call UpdateAllFtn() in all cases: Safety first.
2222         if ( FTNNUM_CHAPTER == GetFtnInfo().eNum )
2223         {
2224             GetFtnIdxs().UpdateAllFtn();
2225         }
2226         // <--
2227         else
2228         {
2229             SwNodeIndex aTmp( GetNodes() );
2230             GetFtnIdxs().UpdateFtn( aTmp );
2231         }
2232     }
2233 }
2234 
IsInHeaderFooter(const SwNodeIndex & rIdx) const2235 sal_Bool SwDoc::IsInHeaderFooter( const SwNodeIndex& rIdx ) const
2236 {
2237 	// gibt es ein Layout, dann ueber das laufen!!
2238 	//	(Das kann dann auch Fly in Fly in Kopfzeile !)
2239 	// MIB 9.2.98: Wird auch vom sw3io benutzt, um festzustellen, ob sich
2240 	// ein Redline-Objekt in einer Kopf- oder Fusszeile befindet. Da
2241 	// Redlines auch an Start- und Endnodes haengen, muss der Index nicht
2242 	// unbedingt der eines Content-Nodes sein.
2243 	SwNode* pNd = &rIdx.GetNode();
2244 	if( pNd->IsCntntNode() && pCurrentView )//swmod 071029//swmod 071225
2245 	{
2246         const SwFrm *pFrm = pNd->GetCntntNode()->getLayoutFrm( GetCurrentLayout() );
2247 		if( pFrm )
2248 		{
2249             const SwFrm *pUp = pFrm->GetUpper();
2250 			while ( pUp && !pUp->IsHeaderFrm() && !pUp->IsFooterFrm() )
2251 			{
2252 				if ( pUp->IsFlyFrm() )
2253                     pUp = ((SwFlyFrm*)pUp)->GetAnchorFrm();
2254 				pUp = pUp->GetUpper();
2255 			}
2256 			if ( pUp )
2257 				return sal_True;
2258 
2259 			return sal_False;
2260 		}
2261 	}
2262 
2263 
2264 	const SwNode* pFlyNd = pNd->FindFlyStartNode();
2265 	while( pFlyNd )
2266 	{
2267 		// dann ueber den Anker nach oben "hangeln"
2268 		sal_uInt16 n;
2269 		for( n = 0; n < GetSpzFrmFmts()->Count(); ++n )
2270 		{
2271 			const SwFrmFmt* pFmt = (*GetSpzFrmFmts())[ n ];
2272 			const SwNodeIndex* pIdx = pFmt->GetCntnt().GetCntntIdx();
2273 			if( pIdx && pFlyNd == &pIdx->GetNode() )
2274 			{
2275 				const SwFmtAnchor& rAnchor = pFmt->GetAnchor();
2276                 if ((FLY_AT_PAGE == rAnchor.GetAnchorId()) ||
2277 					!rAnchor.GetCntntAnchor() )
2278                 {
2279 					return sal_False;
2280                 }
2281 
2282 				pNd = &rAnchor.GetCntntAnchor()->nNode.GetNode();
2283 				pFlyNd = pNd->FindFlyStartNode();
2284 				break;
2285 			}
2286 		}
2287 		if( n >= GetSpzFrmFmts()->Count() )
2288 		{
2289 			ASSERT( mbInReading, "Fly-Section aber kein Format gefunden" );
2290 			return sal_False;
2291 		}
2292 	}
2293 
2294 	return 0 != pNd->FindHeaderStartNode() ||
2295 			0 != pNd->FindFooterStartNode();
2296 }
2297 
GetTextDirection(const SwPosition & rPos,const Point * pPt) const2298 short SwDoc::GetTextDirection( const SwPosition& rPos,
2299                                const Point* pPt ) const
2300 {
2301     short nRet = -1;
2302 
2303 	SwCntntNode *pNd = rPos.nNode.GetNode().GetCntntNode();
2304 
2305     // --> OD 2005-02-21 #i42921# - use new method <SwCntntNode::GetTextDirection(..)>
2306     if ( pNd )
2307     {
2308         nRet = pNd->GetTextDirection( rPos, pPt );
2309     }
2310     if ( nRet == -1 )
2311     // <--
2312 	{
2313 		const SvxFrameDirectionItem* pItem = 0;
2314 		if( pNd )
2315 		{
2316 			// in a flyframe? Then look at that for the correct attribute
2317 			const SwFrmFmt* pFlyFmt = pNd->GetFlyFmt();
2318 			while( pFlyFmt )
2319 			{
2320 				pItem = &pFlyFmt->GetFrmDir();
2321 				if( FRMDIR_ENVIRONMENT == pItem->GetValue() )
2322 				{
2323 					pItem = 0;
2324 					const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
2325                     if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
2326                         pAnchor->GetCntntAnchor())
2327                     {
2328 						pFlyFmt = pAnchor->GetCntntAnchor()->nNode.
2329 											GetNode().GetFlyFmt();
2330                     }
2331 					else
2332 						pFlyFmt = 0;
2333 				}
2334 				else
2335 					pFlyFmt = 0;
2336 			}
2337 
2338 			if( !pItem )
2339 			{
2340 				const SwPageDesc* pPgDsc = pNd->FindPageDesc( sal_False );
2341 				if( pPgDsc )
2342 					pItem = &pPgDsc->GetMaster().GetFrmDir();
2343 			}
2344 		}
2345 		if( !pItem )
2346 			pItem = (SvxFrameDirectionItem*)&GetAttrPool().GetDefaultItem(
2347 															RES_FRAMEDIR );
2348         nRet = pItem->GetValue();
2349 	}
2350     return nRet;
2351 }
2352 
IsInVerticalText(const SwPosition & rPos,const Point * pPt) const2353 sal_Bool SwDoc::IsInVerticalText( const SwPosition& rPos, const Point* pPt ) const
2354 {
2355     const short nDir = GetTextDirection( rPos, pPt );
2356     return FRMDIR_VERT_TOP_RIGHT == nDir || FRMDIR_VERT_TOP_LEFT == nDir;
2357 }
2358 
SetCurrentViewShell(ViewShell * pNew)2359 void SwDoc::SetCurrentViewShell( ViewShell* pNew )
2360 {
2361     pCurrentView = pNew;
2362 }
2363 
GetLayouter()2364 SwLayouter* SwDoc::GetLayouter()
2365 {
2366     return pLayouter;
2367 }
2368 
GetLayouter() const2369 const SwLayouter* SwDoc::GetLayouter() const
2370 {
2371     return pLayouter;
2372 }
2373 
SetLayouter(SwLayouter * pNew)2374 void SwDoc::SetLayouter( SwLayouter* pNew )
2375 {
2376     pLayouter = pNew;
2377 }
2378 
GetCurrentViewShell() const2379 const ViewShell *SwDoc::GetCurrentViewShell() const
2380 {
2381     return pCurrentView;
2382 }
2383 
GetCurrentViewShell()2384 ViewShell *SwDoc::GetCurrentViewShell()
2385 {
2386     return pCurrentView;
2387 }	//swmod 080219 It must be able to communicate to a ViewShell.This is going to be removedd later.
2388 
GetCurrentLayout() const2389 const SwRootFrm *SwDoc::GetCurrentLayout() const
2390 {
2391 	if(GetCurrentViewShell())
2392 		return GetCurrentViewShell()->GetLayout();
2393 	return 0;
2394 }
2395 
GetCurrentLayout()2396 SwRootFrm *SwDoc::GetCurrentLayout()
2397 {
2398 	if(GetCurrentViewShell())
2399 		return GetCurrentViewShell()->GetLayout();
2400 	return 0;
2401 }
2402 
HasLayout() const2403 bool SwDoc::HasLayout() const
2404 {
2405     // if there is a view, there is always a layout
2406     return (pCurrentView != 0);
2407 }
2408 
GetAllLayouts()2409 std::set<SwRootFrm*> SwDoc::GetAllLayouts()
2410 {
2411     std::set<SwRootFrm*> aAllLayouts;
2412     ViewShell *pStart = GetCurrentViewShell();
2413     ViewShell *pTemp = pStart;
2414     if ( pTemp )
2415     {
2416         do
2417         {
2418             if (pTemp->GetLayout())
2419             {
2420                 aAllLayouts.insert(pTemp->GetLayout());
2421                 pTemp = (ViewShell*)pTemp->GetNext();
2422             }
2423         } while(pTemp!=pStart);
2424     }
2425 
2426     return aAllLayouts;
2427 }//swmod 070825
2428 
2429 
ShareLayout(boost::shared_ptr<SwRootFrm> & rPtr)2430 void SwDoc::ShareLayout(boost::shared_ptr<SwRootFrm>& rPtr)
2431 {
2432     pLayoutPtr = rPtr;
2433 }
2434 
2435