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