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