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