Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "hintids.hxx"
21 : #include <svl/itemiter.hxx>
22 : #include <svtools/imap.hxx>
23 : #include <vcl/graph.hxx>
24 : #include <tools/poly.hxx>
25 : #include <tools/helpers.hxx>
26 : #include <svx/contdlg.hxx>
27 : #include <editeng/protitem.hxx>
28 : #include <editeng/opaqitem.hxx>
29 : #include <editeng/ulspitem.hxx>
30 : #include <editeng/lrspitem.hxx>
31 : #include <editeng/frmdiritem.hxx>
32 : #include <editeng/keepitem.hxx>
33 : #include <fmtanchr.hxx>
34 : #include <fmtfsize.hxx>
35 : #include <fmtclds.hxx>
36 : #include <fmtcntnt.hxx>
37 : #include <fmturl.hxx>
38 : #include <fmtsrnd.hxx>
39 : #include <fmtornt.hxx>
40 : #include <fmtpdsc.hxx>
41 : #include <fmtcnct.hxx>
42 : #include <layhelp.hxx>
43 : #include <ndtxt.hxx>
44 : #include <svx/svdogrp.hxx>
45 : #include <ndgrf.hxx>
46 : #include <tolayoutanchoredobjectposition.hxx>
47 : #include <fmtfollowtextflow.hxx>
48 : #include <sortedobjs.hxx>
49 : #include <objectformatter.hxx>
50 : #include <anchoredobject.hxx>
51 : #include <ndole.hxx>
52 : #include <swtable.hxx>
53 : #include <svx/svdpage.hxx>
54 : #include "doc.hxx"
55 : #include "viewsh.hxx"
56 : #include "layouter.hxx"
57 : #include "pagefrm.hxx"
58 : #include "rootfrm.hxx"
59 : #include "cntfrm.hxx"
60 : #include "pam.hxx"
61 : #include "frmatr.hxx"
62 : #include "viewimp.hxx"
63 : #include "viewopt.hxx"
64 : #include "dcontact.hxx"
65 : #include "dflyobj.hxx"
66 : #include "dview.hxx"
67 : #include "flyfrm.hxx"
68 : #include "frmtool.hxx"
69 : #include "frmfmt.hxx"
70 : #include "hints.hxx"
71 : #include "swregion.hxx"
72 : #include "tabfrm.hxx"
73 : #include "txtfrm.hxx"
74 : #include "ndnotxt.hxx"
75 : #include "notxtfrm.hxx" // GetGrfArea
76 : #include "flyfrms.hxx"
77 : #include "ndindex.hxx" // GetGrfArea
78 : #include "sectfrm.hxx"
79 : #include <vcl/svapp.hxx>
80 : #include "switerator.hxx"
81 :
82 : using namespace ::com::sun::star;
83 :
84 :
85 32596 : TYPEINIT2(SwFlyFrm,SwLayoutFrm,SwAnchoredObject);
86 :
87 : /*************************************************************************
88 : |*
89 : |* SwFlyFrm::SwFlyFrm()
90 : |*
91 : |*************************************************************************/
92 :
93 384 : SwFlyFrm::SwFlyFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
94 : SwLayoutFrm( pFmt, pSib ),
95 : SwAnchoredObject(), // #i26791#
96 : pPrevLink( 0 ),
97 : pNextLink( 0 ),
98 : bInCnt( sal_False ),
99 : bAtCnt( sal_False ),
100 : bLayout( sal_False ),
101 : bAutoPosition( sal_False ),
102 : bNoShrink( sal_False ),
103 384 : bLockDeleteContent( sal_False )
104 : {
105 384 : nType = FRMC_FLY;
106 :
107 384 : bInvalid = bNotifyBack = sal_True;
108 : bLocked = bMinHeight =
109 384 : bHeightClipped = bWidthClipped = bFormatHeightOnly = sal_False;
110 :
111 : //Grosseneinstellung, Fixe groesse ist immer die Breite
112 384 : const SwFmtFrmSize &rFrmSize = pFmt->GetFrmSize();
113 : sal_uInt16 nDir =
114 384 : ((SvxFrameDirectionItem&)pFmt->GetFmtAttr( RES_FRAMEDIR )).GetValue();
115 384 : if( FRMDIR_ENVIRONMENT == nDir )
116 : {
117 384 : bDerivedVert = 1;
118 384 : bDerivedR2L = 1;
119 : }
120 : else
121 : {
122 0 : bInvalidVert = 0;
123 0 : bDerivedVert = 0;
124 0 : bDerivedR2L = 0;
125 0 : if( FRMDIR_HORI_LEFT_TOP == nDir || FRMDIR_HORI_RIGHT_TOP == nDir )
126 : {
127 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
128 0 : bVertLR = 0;
129 0 : bVertical = 0;
130 : }
131 : else
132 : {
133 0 : const ViewShell *pSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
134 0 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
135 : {
136 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
137 0 : bVertLR = 0;
138 0 : bVertical = 0;
139 : }
140 : else
141 : {
142 0 : bVertical = 1;
143 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
144 0 : if ( FRMDIR_VERT_TOP_LEFT == nDir )
145 0 : bVertLR = 1;
146 : else
147 0 : bVertLR = 0;
148 : }
149 : }
150 :
151 0 : bInvalidR2L = 0;
152 0 : if( FRMDIR_HORI_RIGHT_TOP == nDir )
153 0 : bRightToLeft = 1;
154 : else
155 0 : bRightToLeft = 0;
156 : }
157 :
158 384 : Frm().Width( rFrmSize.GetWidth() );
159 384 : Frm().Height( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE ? MINFLY : rFrmSize.GetHeight() );
160 :
161 : // Fixed or variable Height?
162 384 : if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
163 14 : bMinHeight = sal_True;
164 370 : else if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
165 42 : bFixSize = sal_True;
166 :
167 : // insert columns, if necessary
168 384 : InsertColumns();
169 :
170 : //Erst das Init, dann den Inhalt, denn zum Inhalt koennen widerum
171 : //Objekte/Rahmen gehoeren die dann angemeldet werden.
172 384 : InitDrawObj( sal_False );
173 :
174 384 : Chain( pAnch );
175 :
176 384 : InsertCnt();
177 :
178 : //Und erstmal in den Wald stellen die Kiste, damit bei neuen Dokument nicht
179 : //unnoetig viel formatiert wird.
180 384 : Frm().Pos().X() = Frm().Pos().Y() = FAR_AWAY;
181 384 : }
182 :
183 384 : void SwFlyFrm::Chain( SwFrm* _pAnch )
184 : {
185 : // Connect to chain neighboors.
186 : // No problem, if a neighboor doesn't exist - the construction of the
187 : // neighboor will make the connection
188 384 : const SwFmtChain& rChain = GetFmt()->GetChain();
189 384 : if ( rChain.GetPrev() || rChain.GetNext() )
190 : {
191 0 : if ( rChain.GetNext() )
192 : {
193 0 : SwFlyFrm* pFollow = FindChainNeighbour( *rChain.GetNext(), _pAnch );
194 0 : if ( pFollow )
195 : {
196 : OSL_ENSURE( !pFollow->GetPrevLink(), "wrong chain detected" );
197 0 : if ( !pFollow->GetPrevLink() )
198 0 : SwFlyFrm::ChainFrames( this, pFollow );
199 : }
200 : }
201 0 : if ( rChain.GetPrev() )
202 : {
203 0 : SwFlyFrm *pMaster = FindChainNeighbour( *rChain.GetPrev(), _pAnch );
204 0 : if ( pMaster )
205 : {
206 : OSL_ENSURE( !pMaster->GetNextLink(), "wrong chain detected" );
207 0 : if ( !pMaster->GetNextLink() )
208 0 : SwFlyFrm::ChainFrames( pMaster, this );
209 : }
210 : }
211 : }
212 384 : }
213 :
214 384 : void SwFlyFrm::InsertCnt()
215 : {
216 384 : if ( !GetPrevLink() )
217 : {
218 384 : const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
219 : OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( no content prepared." );
220 384 : sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
221 : // Lower() bedeutet SwColumnFrm, eingefuegt werden muss der Inhalt dann in den (Column)BodyFrm
222 384 : ::_InsertCnt( Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)Lower())->Lower() : (SwLayoutFrm*)this,
223 768 : GetFmt()->GetDoc(), nIndex );
224 :
225 : // NoTxt always have a fixed height.
226 384 : if ( Lower() && Lower()->IsNoTxtFrm() )
227 : {
228 328 : bFixSize = sal_True;
229 328 : bMinHeight = sal_False;
230 : }
231 : }
232 384 : }
233 :
234 384 : void SwFlyFrm::InsertColumns()
235 : {
236 : // #i97379#
237 : // Check, if column are allowed.
238 : // Columns are not allowed for fly frames, which represent graphics or embedded objects.
239 384 : const SwFmtCntnt& rCntnt = GetFmt()->GetCntnt();
240 : OSL_ENSURE( rCntnt.GetCntntIdx(), "<SwFlyFrm::InsertColumns()> - no content prepared." );
241 384 : SwNodeIndex aFirstCntnt( *(rCntnt.GetCntntIdx()), 1 );
242 384 : if ( aFirstCntnt.GetNode().IsNoTxtNode() )
243 : {
244 384 : return;
245 : }
246 :
247 56 : const SwFmtCol &rCol = GetFmt()->GetCol();
248 56 : if ( rCol.GetNumCols() > 1 )
249 : {
250 : //PrtArea ersteinmal so gross wie der Frm, damit die Spalten
251 : //vernuenftig eingesetzt werden koennen; das schaukelt sich dann
252 : //schon zurecht.
253 0 : Prt().Width( Frm().Width() );
254 0 : Prt().Height( Frm().Height() );
255 0 : const SwFmtCol aOld; //ChgColumns() verlaesst sich darauf, dass auch ein
256 : //Old-Wert hereingereicht wird.
257 0 : ChgColumns( aOld, rCol );
258 384 : }
259 : }
260 :
261 : /*************************************************************************
262 : |*
263 : |* SwFlyFrm::~SwFlyFrm()
264 : |*
265 : |*************************************************************************/
266 :
267 184 : SwFlyFrm::~SwFlyFrm()
268 : {
269 : // Accessible objects for fly frames will be destroyed in this destructor.
270 : // For frames bound as char or frames that don't have an anchor we have
271 : // to do that ourselves. For any other frame the call RemoveFly at the
272 : // anchor will do that.
273 92 : if( IsAccessibleFrm() && GetFmt() && (IsFlyInCntFrm() || !GetAnchorFrm()) )
274 : {
275 84 : SwRootFrm *pRootFrm = getRootFrm();
276 84 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
277 : {
278 0 : ViewShell *pVSh = pRootFrm->GetCurrShell();
279 0 : if( pVSh && pVSh->Imp() )
280 : {
281 : // Lowers aren't disposed already, so we have to do a recursive
282 : // dispose
283 0 : pVSh->Imp()->DisposeAccessibleFrm( this, sal_True );
284 : }
285 : }
286 : }
287 :
288 92 : if( GetFmt() && !GetFmt()->GetDoc()->IsInDtor() )
289 : {
290 : // OD 2004-01-19 #110582#
291 0 : Unchain();
292 :
293 : // OD 2004-01-19 #110582#
294 0 : DeleteCnt();
295 :
296 : //Tschuess sagen.
297 0 : if ( GetAnchorFrm() )
298 0 : AnchorFrm()->RemoveFly( this );
299 : }
300 :
301 92 : FinitDrawObj();
302 92 : }
303 :
304 0 : const IDocumentDrawModelAccess* SwFlyFrm::getIDocumentDrawModelAccess()
305 : {
306 0 : return GetFmt()->getIDocumentDrawModelAccess();
307 : }
308 :
309 : // OD 2004-01-19 #110582#
310 0 : void SwFlyFrm::Unchain()
311 : {
312 0 : if ( GetPrevLink() )
313 0 : UnchainFrames( GetPrevLink(), this );
314 0 : if ( GetNextLink() )
315 0 : UnchainFrames( this, GetNextLink() );
316 0 : }
317 :
318 : // OD 2004-01-19 #110582#
319 0 : void SwFlyFrm::DeleteCnt()
320 : {
321 : // #110582#-2
322 0 : if ( IsLockDeleteContent() )
323 0 : return;
324 :
325 0 : SwFrm* pFrm = pLower;
326 0 : while ( pFrm )
327 : {
328 0 : while ( pFrm->GetDrawObjs() && pFrm->GetDrawObjs()->Count() )
329 : {
330 0 : SwAnchoredObject *pAnchoredObj = (*pFrm->GetDrawObjs())[0];
331 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
332 0 : delete pAnchoredObj;
333 0 : else if ( pAnchoredObj->ISA(SwAnchoredDrawObject) )
334 : {
335 : // OD 23.06.2003 #108784# - consider 'virtual' drawing objects
336 0 : SdrObject* pObj = pAnchoredObj->DrawObj();
337 0 : if ( pObj->ISA(SwDrawVirtObj) )
338 : {
339 0 : SwDrawVirtObj* pDrawVirtObj = static_cast<SwDrawVirtObj*>(pObj);
340 0 : pDrawVirtObj->RemoveFromWriterLayout();
341 0 : pDrawVirtObj->RemoveFromDrawingPage();
342 : }
343 : else
344 : {
345 : SwDrawContact* pContact =
346 0 : static_cast<SwDrawContact*>(::GetUserCall( pObj ));
347 0 : if ( pContact )
348 : {
349 0 : pContact->DisconnectFromLayout();
350 : }
351 : }
352 : }
353 : }
354 :
355 0 : pFrm->Remove();
356 0 : delete pFrm;
357 0 : pFrm = pLower;
358 : }
359 :
360 0 : InvalidatePage();
361 : }
362 :
363 : /*************************************************************************
364 : |*
365 : |* SwFlyFrm::InitDrawObj()
366 : |*
367 : |*************************************************************************/
368 :
369 310 : sal_uInt32 SwFlyFrm::_GetOrdNumForNewRef( const SwFlyDrawContact* pContact )
370 : {
371 310 : sal_uInt32 nOrdNum( 0L );
372 :
373 : // search for another Writer fly frame registered at same frame format
374 310 : SwIterator<SwFlyFrm,SwFmt> aIter( *pContact->GetFmt() );
375 310 : const SwFlyFrm* pFlyFrm( 0L );
376 620 : for ( pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
377 : {
378 310 : if ( pFlyFrm != this )
379 : {
380 0 : break;
381 : }
382 : }
383 :
384 310 : if ( pFlyFrm )
385 : {
386 : // another Writer fly frame found. Take its order number
387 0 : nOrdNum = pFlyFrm->GetVirtDrawObj()->GetOrdNum();
388 : }
389 : else
390 : {
391 : // no other Writer fly frame found. Take order number of 'master' object
392 : // #i35748# - use method <GetOrdNumDirect()> instead
393 : // of method <GetOrdNum()> to avoid a recalculation of the order number,
394 : // which isn't intended.
395 310 : nOrdNum = pContact->GetMaster()->GetOrdNumDirect();
396 : }
397 :
398 310 : return nOrdNum;
399 : }
400 :
401 384 : SwVirtFlyDrawObj* SwFlyFrm::CreateNewRef( SwFlyDrawContact *pContact )
402 : {
403 384 : SwVirtFlyDrawObj *pDrawObj = new SwVirtFlyDrawObj( *pContact->GetMaster(), this );
404 384 : pDrawObj->SetModel( pContact->GetMaster()->GetModel() );
405 384 : pDrawObj->SetUserCall( pContact );
406 :
407 : //Der Reader erzeugt die Master und setzt diese, um die Z-Order zu
408 : //transportieren, in die Page ein. Beim erzeugen der ersten Referenz werden
409 : //die Master aus der Liste entfernt und fuehren von da an ein
410 : //Schattendasein.
411 384 : SdrPage* pPg( 0L );
412 384 : if ( 0 != ( pPg = pContact->GetMaster()->GetPage() ) )
413 : {
414 74 : const sal_uInt32 nOrdNum = pContact->GetMaster()->GetOrdNum();
415 74 : pPg->ReplaceObject( pDrawObj, nOrdNum );
416 : }
417 : // #i27030# - insert new <SwVirtFlyDrawObj> instance
418 : // into drawing page with correct order number
419 : else
420 : {
421 310 : pContact->GetFmt()->getIDocumentDrawModelAccess()->GetDrawModel()->GetPage( 0 )->
422 310 : InsertObject( pDrawObj, _GetOrdNumForNewRef( pContact ) );
423 : }
424 : // #i38889# - assure, that new <SwVirtFlyDrawObj> instance
425 : // is in a visible layer.
426 384 : pContact->MoveObjToVisibleLayer( pDrawObj );
427 384 : return pDrawObj;
428 : }
429 :
430 :
431 :
432 384 : void SwFlyFrm::InitDrawObj( sal_Bool bNotify )
433 : {
434 : //ContactObject aus dem Format suchen. Wenn bereits eines existiert, so
435 : //braucht nur eine neue Ref erzeugt werden, anderfalls ist es jetzt an
436 : //der Zeit das Contact zu erzeugen.
437 :
438 384 : IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
439 384 : SwFlyDrawContact *pContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
440 384 : if ( !pContact )
441 : {
442 : // #i52858# - method name changed
443 286 : pContact = new SwFlyDrawContact( (SwFlyFrmFmt*)GetFmt(),
444 286 : pIDDMA->GetOrCreateDrawModel() );
445 : }
446 : OSL_ENSURE( pContact, "InitDrawObj failed" );
447 : // OD 2004-03-22 #i26791#
448 384 : SetDrawObj( *(CreateNewRef( pContact )) );
449 :
450 : //Den richtigen Layer setzen.
451 : // OD 2004-01-19 #110582#
452 384 : SdrLayerID nHeavenId = pIDDMA->GetHeavenId();
453 384 : SdrLayerID nHellId = pIDDMA->GetHellId();
454 : // OD 2004-03-22 #i26791#
455 768 : GetVirtDrawObj()->SetLayer( GetFmt()->GetOpaque().GetValue()
456 : ? nHeavenId
457 768 : : nHellId );
458 384 : if ( bNotify )
459 0 : NotifyDrawObj();
460 384 : }
461 :
462 : /*************************************************************************
463 : |*
464 : |* SwFlyFrm::FinitDrawObj()
465 : |*
466 : |*************************************************************************/
467 :
468 92 : void SwFlyFrm::FinitDrawObj()
469 : {
470 92 : if ( !GetVirtDrawObj() )
471 92 : return;
472 :
473 : //Bei den SdrPageViews abmelden falls das Objekt dort noch selektiert ist.
474 92 : if ( !GetFmt()->GetDoc()->IsInDtor() )
475 : {
476 0 : ViewShell *p1St = getRootFrm()->GetCurrShell();
477 0 : if ( p1St )
478 : {
479 0 : ViewShell *pSh = p1St;
480 0 : do
481 : { //z.Zt. kann das Drawing nur ein Unmark auf alles, weil das
482 : //Objekt bereits Removed wurde.
483 0 : if( pSh->HasDrawView() )
484 0 : pSh->Imp()->GetDrawView()->UnmarkAll();
485 0 : pSh = (ViewShell*)pSh->GetNext();
486 :
487 : } while ( pSh != p1St );
488 : }
489 : }
490 :
491 : //VirtObject mit in das Grab nehmen. Wenn das letzte VirObject
492 : //zerstoert wird, mussen das DrawObject und DrawContact ebenfalls
493 : //zerstoert werden.
494 92 : SwFlyDrawContact *pMyContact = 0;
495 92 : if ( GetFmt() )
496 : {
497 92 : bool bContinue = true;
498 92 : SwIterator<SwFrm,SwFmt> aFrmIter( *GetFmt() );
499 184 : for ( SwFrm* pFrm = aFrmIter.First(); pFrm; pFrm = aFrmIter.Next() )
500 92 : if ( pFrm != this )
501 : {
502 : // don't delete Contact if there is still a Frm
503 0 : bContinue = false;
504 0 : break;
505 : }
506 :
507 92 : if ( bContinue )
508 : // no Frm left, find Contact object to destroy
509 92 : pMyContact = SwIterator<SwFlyDrawContact,SwFmt>::FirstElement( *GetFmt() );
510 : }
511 :
512 : // OD, OS 2004-03-31 #116203# - clear user call of Writer fly frame 'master'
513 : // <SdrObject> to assure, that a <SwXFrame::dispose()> doesn't delete the
514 : // Writer fly frame again.
515 92 : if ( pMyContact )
516 : {
517 92 : pMyContact->GetMaster()->SetUserCall( 0 );
518 : }
519 92 : GetVirtDrawObj()->SetUserCall( 0 ); //Ruft sonst Delete des ContactObj
520 92 : delete GetVirtDrawObj(); //Meldet sich selbst beim Master ab.
521 92 : delete pMyContact; //zerstoert den Master selbst.
522 : }
523 :
524 : /*************************************************************************
525 : |*
526 : |* SwFlyFrm::ChainFrames()
527 : |*
528 : |*************************************************************************/
529 :
530 0 : void SwFlyFrm::ChainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
531 : {
532 : OSL_ENSURE( pMaster && pFollow, "uncomplete chain" );
533 : OSL_ENSURE( !pMaster->GetNextLink(), "link can not be changed" );
534 : OSL_ENSURE( !pFollow->GetPrevLink(), "link can not be changed" );
535 :
536 0 : pMaster->pNextLink = pFollow;
537 0 : pFollow->pPrevLink = pMaster;
538 :
539 0 : if ( pMaster->ContainsCntnt() )
540 : {
541 : //Damit ggf. ein Textfluss zustande kommt muss invalidiert werden.
542 0 : SwFrm *pInva = pMaster->FindLastLower();
543 0 : SWRECTFN( pMaster )
544 0 : const long nBottom = (pMaster->*fnRect->fnGetPrtBottom)();
545 0 : while ( pInva )
546 : {
547 0 : if( (pInva->Frm().*fnRect->fnBottomDist)( nBottom ) <= 0 )
548 : {
549 0 : pInva->InvalidateSize();
550 0 : pInva->Prepare( PREP_CLEAR );
551 0 : pInva = pInva->FindPrev();
552 : }
553 : else
554 0 : pInva = 0;
555 : }
556 : }
557 :
558 0 : if ( pFollow->ContainsCntnt() )
559 : {
560 : //Es gibt nur noch den Inhalt des Masters, der Inhalt vom Follow
561 : //hat keine Frames mehr (sollte immer nur genau ein leerer TxtNode sein).
562 0 : SwFrm *pFrm = pFollow->ContainsCntnt();
563 : OSL_ENSURE( !pFrm->IsTabFrm() && !pFrm->FindNext(), "follow in chain contains content" );
564 0 : pFrm->Cut();
565 0 : delete pFrm;
566 : }
567 :
568 : // invalidate accessible relation set (accessibility wrapper)
569 0 : ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
570 0 : if( pSh )
571 : {
572 0 : SwRootFrm* pLayout = pMaster->getRootFrm();
573 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
574 0 : pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
575 : }
576 0 : }
577 :
578 0 : void SwFlyFrm::UnchainFrames( SwFlyFrm *pMaster, SwFlyFrm *pFollow )
579 : {
580 0 : pMaster->pNextLink = 0;
581 0 : pFollow->pPrevLink = 0;
582 :
583 0 : if ( pFollow->ContainsCntnt() )
584 : {
585 : //Der Master saugt den Inhalt vom Follow auf
586 0 : SwLayoutFrm *pUpper = pMaster;
587 0 : if ( pUpper->Lower()->IsColumnFrm() )
588 : {
589 0 : pUpper = static_cast<SwLayoutFrm*>(pUpper->GetLastLower());
590 0 : pUpper = static_cast<SwLayoutFrm*>(pUpper->Lower()); // der (Column)BodyFrm
591 : OSL_ENSURE( pUpper && pUpper->IsColBodyFrm(), "Missing ColumnBody" );
592 : }
593 0 : SwFlyFrm *pFoll = pFollow;
594 0 : while ( pFoll )
595 : {
596 0 : SwFrm *pTmp = ::SaveCntnt( pFoll );
597 0 : if ( pTmp )
598 0 : ::RestoreCntnt( pTmp, pUpper, pMaster->FindLastLower(), true );
599 0 : pFoll->SetCompletePaint();
600 0 : pFoll->InvalidateSize();
601 0 : pFoll = pFoll->GetNextLink();
602 : }
603 : }
604 :
605 : //Der Follow muss mit seinem eigenen Inhalt versorgt werden.
606 0 : const SwFmtCntnt &rCntnt = pFollow->GetFmt()->GetCntnt();
607 : OSL_ENSURE( rCntnt.GetCntntIdx(), ":-( Kein Inhalt vorbereitet." );
608 0 : sal_uLong nIndex = rCntnt.GetCntntIdx()->GetIndex();
609 : // Lower() bedeutet SwColumnFrm, dieser beinhaltet wieder einen SwBodyFrm
610 0 : ::_InsertCnt( pFollow->Lower() ? (SwLayoutFrm*)((SwLayoutFrm*)pFollow->Lower())->Lower()
611 : : (SwLayoutFrm*)pFollow,
612 0 : pFollow->GetFmt()->GetDoc(), ++nIndex );
613 :
614 : // invalidate accessible relation set (accessibility wrapper)
615 0 : ViewShell* pSh = pMaster->getRootFrm()->GetCurrShell();
616 0 : if( pSh )
617 : {
618 0 : SwRootFrm* pLayout = pMaster->getRootFrm();
619 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
620 0 : pSh->Imp()->InvalidateAccessibleRelationSet( pMaster, pFollow );
621 : }
622 0 : }
623 :
624 : /*************************************************************************
625 : |*
626 : |* SwFlyFrm::FindChainNeighbour()
627 : |*
628 : |*************************************************************************/
629 :
630 0 : SwFlyFrm *SwFlyFrm::FindChainNeighbour( SwFrmFmt &rChain, SwFrm *pAnch )
631 : {
632 : //Wir suchen denjenigen Fly, der in dem selben Bereich steht.
633 : //Bereiche koennen zunaechst nur Kopf-/Fusszeilen oder Flys sein.
634 :
635 0 : if ( !pAnch ) //Wenn ein Anchor uebergeben Wurde zaehlt dieser: Ctor!
636 0 : pAnch = AnchorFrm();
637 :
638 : SwLayoutFrm *pLay;
639 0 : if ( pAnch->IsInFly() )
640 0 : pLay = pAnch->FindFlyFrm();
641 : else
642 : {
643 : //FindFooterOrHeader taugt hier nicht, weil evtl. noch keine Verbindung
644 : //zum Anker besteht.
645 0 : pLay = pAnch->GetUpper();
646 0 : while ( pLay && !(pLay->GetType() & (FRM_HEADER|FRM_FOOTER)) )
647 0 : pLay = pLay->GetUpper();
648 : }
649 :
650 0 : SwIterator<SwFlyFrm,SwFmt> aIter( rChain );
651 0 : SwFlyFrm *pFly = aIter.First();
652 0 : if ( pLay )
653 : {
654 0 : while ( pFly )
655 : {
656 0 : if ( pFly->GetAnchorFrm() )
657 : {
658 0 : if ( pFly->GetAnchorFrm()->IsInFly() )
659 : {
660 0 : if ( pFly->AnchorFrm()->FindFlyFrm() == pLay )
661 0 : break;
662 : }
663 0 : else if ( pLay == pFly->FindFooterOrHeader() )
664 0 : break;
665 : }
666 0 : pFly = aIter.Next();
667 : }
668 : }
669 : else if ( pFly )
670 : {
671 : OSL_ENSURE( !aIter.Next(), "chain with more than one inkarnation" );
672 : }
673 0 : return pFly;
674 : }
675 :
676 :
677 : /*************************************************************************
678 : |*
679 : |* SwFlyFrm::FindLastLower()
680 : |*
681 : |*************************************************************************/
682 :
683 0 : SwFrm *SwFlyFrm::FindLastLower()
684 : {
685 0 : SwFrm *pRet = ContainsAny();
686 0 : if ( pRet && pRet->IsInTab() )
687 0 : pRet = pRet->FindTabFrm();
688 0 : SwFrm *pNxt = pRet;
689 0 : while ( pNxt && IsAnLower( pNxt ) )
690 0 : { pRet = pNxt;
691 0 : pNxt = pNxt->FindNext();
692 : }
693 0 : return pRet;
694 : }
695 :
696 :
697 : /*************************************************************************
698 : |*
699 : |* SwFlyFrm::FrmSizeChg()
700 : |*
701 : |*************************************************************************/
702 :
703 0 : sal_Bool SwFlyFrm::FrmSizeChg( const SwFmtFrmSize &rFrmSize )
704 : {
705 0 : sal_Bool bRet = sal_False;
706 0 : SwTwips nDiffHeight = Frm().Height();
707 0 : if ( rFrmSize.GetHeightSizeType() == ATT_VAR_SIZE )
708 0 : bFixSize = bMinHeight = sal_False;
709 : else
710 : {
711 0 : if ( rFrmSize.GetHeightSizeType() == ATT_FIX_SIZE )
712 : {
713 0 : bFixSize = sal_True;
714 0 : bMinHeight = sal_False;
715 : }
716 0 : else if ( rFrmSize.GetHeightSizeType() == ATT_MIN_SIZE )
717 : {
718 0 : bFixSize = sal_False;
719 0 : bMinHeight = sal_True;
720 : }
721 0 : nDiffHeight -= rFrmSize.GetHeight();
722 : }
723 : //Wenn der Fly Spalten enthaehlt muessen der Fly und
724 : //die Spalten schon einmal auf die Wunschwerte gebracht
725 : //werden, sonst haben wir ein kleines Problem.
726 0 : if ( Lower() )
727 : {
728 0 : if ( Lower()->IsColumnFrm() )
729 : {
730 0 : const SwRect aOld( GetObjRectWithSpaces() );
731 0 : const Size aOldSz( Prt().SSize() );
732 0 : const SwTwips nDiffWidth = Frm().Width() - rFrmSize.GetWidth();
733 0 : aFrm.Height( aFrm.Height() - nDiffHeight );
734 0 : aFrm.Width ( aFrm.Width() - nDiffWidth );
735 : // #i68520#
736 0 : InvalidateObjRectWithSpaces();
737 0 : aPrt.Height( aPrt.Height() - nDiffHeight );
738 0 : aPrt.Width ( aPrt.Width() - nDiffWidth );
739 0 : ChgLowersProp( aOldSz );
740 0 : ::Notify( this, FindPageFrm(), aOld );
741 0 : bValidPos = sal_False;
742 0 : bRet = sal_True;
743 : }
744 0 : else if ( Lower()->IsNoTxtFrm() )
745 : {
746 0 : bFixSize = sal_True;
747 0 : bMinHeight = sal_False;
748 : }
749 : }
750 0 : return bRet;
751 : }
752 :
753 : /*************************************************************************
754 : |*
755 : |* SwFlyFrm::Modify()
756 : |*
757 : |*************************************************************************/
758 :
759 0 : void SwFlyFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem * pNew )
760 : {
761 0 : sal_uInt8 nInvFlags = 0;
762 :
763 0 : if( pNew && RES_ATTRSET_CHG == pNew->Which() )
764 : {
765 0 : SfxItemIter aNIter( *((SwAttrSetChg*)pNew)->GetChgSet() );
766 0 : SfxItemIter aOIter( *((SwAttrSetChg*)pOld)->GetChgSet() );
767 0 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
768 0 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
769 0 : while( true )
770 : {
771 : _UpdateAttr( (SfxPoolItem*)aOIter.GetCurItem(),
772 : (SfxPoolItem*)aNIter.GetCurItem(), nInvFlags,
773 0 : &aOldSet, &aNewSet );
774 0 : if( aNIter.IsAtEnd() )
775 0 : break;
776 0 : aNIter.NextItem();
777 0 : aOIter.NextItem();
778 : }
779 0 : if ( aOldSet.Count() || aNewSet.Count() )
780 0 : SwLayoutFrm::Modify( &aOldSet, &aNewSet );
781 : }
782 : else
783 0 : _UpdateAttr( pOld, pNew, nInvFlags );
784 :
785 0 : if ( nInvFlags != 0 )
786 : {
787 0 : _Invalidate();
788 0 : if ( nInvFlags & 0x01 )
789 : {
790 0 : _InvalidatePos();
791 : // #i68520#
792 0 : InvalidateObjRectWithSpaces();
793 : }
794 0 : if ( nInvFlags & 0x02 )
795 : {
796 0 : _InvalidateSize();
797 : // #i68520#
798 0 : InvalidateObjRectWithSpaces();
799 : }
800 0 : if ( nInvFlags & 0x04 )
801 0 : _InvalidatePrt();
802 0 : if ( nInvFlags & 0x08 )
803 0 : SetNotifyBack();
804 0 : if ( nInvFlags & 0x10 )
805 0 : SetCompletePaint();
806 0 : if ( ( nInvFlags & 0x40 ) && Lower() && Lower()->IsNoTxtFrm() )
807 0 : ClrContourCache( GetVirtDrawObj() );
808 : SwRootFrm *pRoot;
809 0 : if ( nInvFlags & 0x20 && 0 != (pRoot = getRootFrm()) )
810 0 : pRoot->InvalidateBrowseWidth();
811 : // #i28701#
812 0 : if ( nInvFlags & 0x80 )
813 : {
814 : // update sorted object lists, the Writer fly frame is registered at.
815 0 : UpdateObjInSortedList();
816 : }
817 :
818 : // #i87645# - reset flags for the layout process (only if something has been invalidated)
819 0 : ResetLayoutProcessBools();
820 : }
821 0 : }
822 :
823 0 : void SwFlyFrm::_UpdateAttr( const SfxPoolItem *pOld, const SfxPoolItem *pNew,
824 : sal_uInt8 &rInvFlags,
825 : SwAttrSetChg *pOldSet, SwAttrSetChg *pNewSet )
826 : {
827 0 : bool bClear = true;
828 0 : const sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
829 0 : ViewShell *pSh = getRootFrm()->GetCurrShell();
830 0 : switch( nWhich )
831 : {
832 : case RES_VERT_ORIENT:
833 : case RES_HORI_ORIENT:
834 : // OD 22.09.2003 #i18732# - consider new option 'follow text flow'
835 : case RES_FOLLOW_TEXT_FLOW:
836 : {
837 : //Achtung! _immer_ Aktion in ChgRePos() mitpflegen.
838 0 : rInvFlags |= 0x09;
839 : }
840 0 : break;
841 : // OD 2004-07-01 #i28701# - consider new option 'wrap influence on position'
842 : case RES_WRAP_INFLUENCE_ON_OBJPOS:
843 : {
844 0 : rInvFlags |= 0x89;
845 : }
846 0 : break;
847 : case RES_SURROUND:
848 : {
849 : // OD 2004-05-13 #i28701# - invalidate position on change of
850 : // wrapping style.
851 : //rInvFlags |= 0x40;
852 0 : rInvFlags |= 0x41;
853 : //Der Hintergrund muss benachrichtigt und Invalidiert werden.
854 0 : const SwRect aTmp( GetObjRectWithSpaces() );
855 0 : NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_ATTR_CHG );
856 :
857 : // Durch eine Umlaufaenderung von rahmengebundenen Rahmen kann eine
858 : // vertikale Ausrichtung aktiviert/deaktiviert werden => MakeFlyPos
859 0 : if( FLY_AT_FLY == GetFmt()->GetAnchor().GetAnchorId() )
860 0 : rInvFlags |= 0x09;
861 :
862 : //Ggf. die Kontur am Node loeschen.
863 0 : if ( Lower() && Lower()->IsNoTxtFrm() &&
864 0 : !GetFmt()->GetSurround().IsContour() )
865 : {
866 0 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
867 0 : if ( pNd->HasContour() )
868 0 : pNd->SetContour( 0 );
869 : }
870 : // #i28701# - perform reorder of object lists
871 : // at anchor frame and at page frame.
872 0 : rInvFlags |= 0x80;
873 : }
874 0 : break;
875 :
876 : case RES_PROTECT:
877 : {
878 0 : const SvxProtectItem *pP = (SvxProtectItem*)pNew;
879 0 : GetVirtDrawObj()->SetMoveProtect( pP->IsPosProtected() );
880 0 : GetVirtDrawObj()->SetResizeProtect( pP->IsSizeProtected() );
881 0 : if( pSh )
882 : {
883 0 : SwRootFrm* pLayout = getRootFrm();
884 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
885 0 : pSh->Imp()->InvalidateAccessibleEditableState( sal_True, this );
886 : }
887 0 : break;
888 : }
889 :
890 : case RES_COL:
891 : {
892 0 : ChgColumns( *(const SwFmtCol*)pOld, *(const SwFmtCol*)pNew );
893 0 : const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
894 0 : if ( FrmSizeChg( rNew ) )
895 0 : NotifyDrawObj();
896 0 : rInvFlags |= 0x1A;
897 0 : break;
898 : }
899 :
900 : case RES_FRM_SIZE:
901 : case RES_FMT_CHG:
902 : {
903 0 : const SwFmtFrmSize &rNew = GetFmt()->GetFrmSize();
904 0 : if ( FrmSizeChg( rNew ) )
905 0 : NotifyDrawObj();
906 0 : rInvFlags |= 0x7F;
907 0 : if ( RES_FMT_CHG == nWhich )
908 : {
909 0 : SwRect aNew( GetObjRectWithSpaces() );
910 0 : SwRect aOld( aFrm );
911 0 : const SvxULSpaceItem &rUL = ((SwFmtChg*)pOld)->pChangedFmt->GetULSpace();
912 0 : aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
913 0 : aOld.SSize().Height()+= rUL.GetLower();
914 0 : const SvxLRSpaceItem &rLR = ((SwFmtChg*)pOld)->pChangedFmt->GetLRSpace();
915 0 : aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
916 0 : aOld.SSize().Width() += rLR.GetRight();
917 0 : aNew.Union( aOld );
918 0 : NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
919 :
920 : //Dummer Fall. Bei der Zusweisung einer Vorlage k?nnen wir uns
921 : //nicht auf das alte Spaltenattribut verlassen. Da diese
922 : //wenigstens anzahlgemass fuer ChgColumns vorliegen muessen,
923 : //bleibt uns nur einen temporaeres Attribut zu basteln.
924 0 : SwFmtCol aCol;
925 0 : if ( Lower() && Lower()->IsColumnFrm() )
926 : {
927 0 : sal_uInt16 nCol = 0;
928 0 : SwFrm *pTmp = Lower();
929 0 : do
930 0 : { ++nCol;
931 0 : pTmp = pTmp->GetNext();
932 : } while ( pTmp );
933 0 : aCol.Init( nCol, 0, 1000 );
934 : }
935 0 : ChgColumns( aCol, GetFmt()->GetCol() );
936 : }
937 :
938 0 : SwFmtURL aURL( GetFmt()->GetURL() );
939 0 : if ( aURL.GetMap() )
940 : {
941 : const SwFmtFrmSize &rOld = nWhich == RES_FRM_SIZE ?
942 : *(SwFmtFrmSize*)pNew :
943 0 : ((SwFmtChg*)pOld)->pChangedFmt->GetFrmSize();
944 : //#35091# Kann beim Laden von Vorlagen mal 0 sein
945 0 : if ( rOld.GetWidth() && rOld.GetHeight() )
946 : {
947 :
948 0 : Fraction aScaleX( rOld.GetWidth(), rNew.GetWidth() );
949 0 : Fraction aScaleY( rOld.GetHeight(), rOld.GetHeight() );
950 0 : aURL.GetMap()->Scale( aScaleX, aScaleY );
951 0 : SwFrmFmt *pFmt = GetFmt();
952 0 : pFmt->LockModify();
953 0 : pFmt->SetFmtAttr( aURL );
954 0 : pFmt->UnlockModify();
955 : }
956 : }
957 0 : const SvxProtectItem &rP = GetFmt()->GetProtect();
958 0 : GetVirtDrawObj()->SetMoveProtect( rP.IsPosProtected() );
959 0 : GetVirtDrawObj()->SetResizeProtect( rP.IsSizeProtected() );
960 :
961 0 : if ( pSh )
962 0 : pSh->InvalidateWindows( Frm() );
963 0 : const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
964 0 : const sal_uInt8 nId = GetFmt()->GetOpaque().GetValue() ?
965 0 : pIDDMA->GetHeavenId() :
966 0 : pIDDMA->GetHellId();
967 0 : GetVirtDrawObj()->SetLayer( nId );
968 :
969 0 : if ( Lower() )
970 : {
971 : //Ggf. die Kontur am Node loeschen.
972 0 : if( Lower()->IsNoTxtFrm() &&
973 0 : !GetFmt()->GetSurround().IsContour() )
974 : {
975 0 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
976 0 : if ( pNd->HasContour() )
977 0 : pNd->SetContour( 0 );
978 : }
979 0 : else if( !Lower()->IsColumnFrm() )
980 : {
981 0 : SwFrm* pFrm = GetLastLower();
982 0 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
983 0 : pFrm->Prepare( PREP_ADJUST_FRM );
984 : }
985 : }
986 :
987 : // #i28701# - perform reorder of object lists
988 : // at anchor frame and at page frame.
989 0 : rInvFlags |= 0x80;
990 :
991 0 : break;
992 : }
993 : case RES_UL_SPACE:
994 : case RES_LR_SPACE:
995 : {
996 0 : rInvFlags |= 0x41;
997 0 : if( pSh && pSh->GetViewOptions()->getBrowseMode() )
998 0 : getRootFrm()->InvalidateBrowseWidth();
999 0 : SwRect aNew( GetObjRectWithSpaces() );
1000 0 : SwRect aOld( aFrm );
1001 0 : if ( RES_UL_SPACE == nWhich )
1002 : {
1003 0 : const SvxULSpaceItem &rUL = *(SvxULSpaceItem*)pNew;
1004 0 : aOld.Top( Max( aOld.Top() - long(rUL.GetUpper()), 0L ) );
1005 0 : aOld.SSize().Height()+= rUL.GetLower();
1006 : }
1007 : else
1008 : {
1009 0 : const SvxLRSpaceItem &rLR = *(SvxLRSpaceItem*)pNew;
1010 0 : aOld.Left ( Max( aOld.Left() - long(rLR.GetLeft()), 0L ) );
1011 0 : aOld.SSize().Width() += rLR.GetRight();
1012 : }
1013 0 : aNew.Union( aOld );
1014 0 : NotifyBackground( FindPageFrm(), aNew, PREP_CLEAR );
1015 : }
1016 0 : break;
1017 :
1018 : case RES_BOX:
1019 : case RES_SHADOW:
1020 0 : rInvFlags |= 0x17;
1021 0 : break;
1022 :
1023 : case RES_FRAMEDIR :
1024 0 : SetDerivedVert( sal_False );
1025 0 : SetDerivedR2L( sal_False );
1026 0 : CheckDirChange();
1027 0 : break;
1028 :
1029 : case RES_OPAQUE:
1030 : {
1031 0 : if ( pSh )
1032 0 : pSh->InvalidateWindows( Frm() );
1033 :
1034 0 : const IDocumentDrawModelAccess* pIDDMA = GetFmt()->getIDocumentDrawModelAccess();
1035 0 : const sal_uInt8 nId = ((SvxOpaqueItem*)pNew)->GetValue() ?
1036 0 : pIDDMA->GetHeavenId() :
1037 0 : pIDDMA->GetHellId();
1038 0 : GetVirtDrawObj()->SetLayer( nId );
1039 0 : if( pSh )
1040 : {
1041 0 : SwRootFrm* pLayout = getRootFrm();
1042 0 : if( pLayout && pLayout->IsAnyShellAccessible() )
1043 : {
1044 0 : pSh->Imp()->DisposeAccessibleFrm( this );
1045 0 : pSh->Imp()->AddAccessibleFrm( this );
1046 : }
1047 : }
1048 : // #i28701# - perform reorder of object lists
1049 : // at anchor frame and at page frame.
1050 0 : rInvFlags |= 0x80;
1051 : }
1052 0 : break;
1053 :
1054 : case RES_URL:
1055 : //Das Interface arbeitet bei Textrahmen auf der Rahmengroesse,
1056 : //die Map muss sich aber auf die FrmSize beziehen
1057 0 : if ( (!Lower() || !Lower()->IsNoTxtFrm()) &&
1058 0 : ((SwFmtURL*)pNew)->GetMap() && ((SwFmtURL*)pOld)->GetMap() )
1059 : {
1060 0 : const SwFmtFrmSize &rSz = GetFmt()->GetFrmSize();
1061 0 : if ( rSz.GetHeight() != Frm().Height() ||
1062 0 : rSz.GetWidth() != Frm().Width() )
1063 : {
1064 0 : SwFmtURL aURL( GetFmt()->GetURL() );
1065 0 : Fraction aScaleX( Frm().Width(), rSz.GetWidth() );
1066 0 : Fraction aScaleY( Frm().Height(), rSz.GetHeight() );
1067 0 : aURL.GetMap()->Scale( aScaleX, aScaleY );
1068 0 : SwFrmFmt *pFmt = GetFmt();
1069 0 : pFmt->LockModify();
1070 0 : pFmt->SetFmtAttr( aURL );
1071 0 : pFmt->UnlockModify();
1072 : }
1073 : }
1074 : /* Keine Invalidierung notwendig */
1075 0 : break;
1076 :
1077 : case RES_CHAIN:
1078 : {
1079 0 : SwFmtChain *pChain = (SwFmtChain*)pNew;
1080 0 : if ( pChain->GetNext() )
1081 : {
1082 0 : SwFlyFrm *pFollow = FindChainNeighbour( *pChain->GetNext() );
1083 0 : if ( GetNextLink() && pFollow != GetNextLink() )
1084 0 : SwFlyFrm::UnchainFrames( this, GetNextLink());
1085 0 : if ( pFollow )
1086 : {
1087 0 : if ( pFollow->GetPrevLink() &&
1088 0 : pFollow->GetPrevLink() != this )
1089 : SwFlyFrm::UnchainFrames( pFollow->GetPrevLink(),
1090 0 : pFollow );
1091 0 : if ( !GetNextLink() )
1092 0 : SwFlyFrm::ChainFrames( this, pFollow );
1093 : }
1094 : }
1095 0 : else if ( GetNextLink() )
1096 0 : SwFlyFrm::UnchainFrames( this, GetNextLink() );
1097 0 : if ( pChain->GetPrev() )
1098 : {
1099 0 : SwFlyFrm *pMaster = FindChainNeighbour( *pChain->GetPrev() );
1100 0 : if ( GetPrevLink() && pMaster != GetPrevLink() )
1101 0 : SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1102 0 : if ( pMaster )
1103 : {
1104 0 : if ( pMaster->GetNextLink() &&
1105 0 : pMaster->GetNextLink() != this )
1106 : SwFlyFrm::UnchainFrames( pMaster,
1107 0 : pMaster->GetNextLink() );
1108 0 : if ( !GetPrevLink() )
1109 0 : SwFlyFrm::ChainFrames( pMaster, this );
1110 : }
1111 : }
1112 0 : else if ( GetPrevLink() )
1113 0 : SwFlyFrm::UnchainFrames( GetPrevLink(), this );
1114 : }
1115 :
1116 : default:
1117 0 : bClear = false;
1118 : }
1119 0 : if ( bClear )
1120 : {
1121 0 : if ( pOldSet || pNewSet )
1122 : {
1123 0 : if ( pOldSet )
1124 0 : pOldSet->ClearItem( nWhich );
1125 0 : if ( pNewSet )
1126 0 : pNewSet->ClearItem( nWhich );
1127 : }
1128 : else
1129 0 : SwLayoutFrm::Modify( pOld, pNew );
1130 : }
1131 0 : }
1132 :
1133 : /*************************************************************************
1134 : |*
1135 : |* SwFlyFrm::GetInfo()
1136 : |*
1137 : |* Beschreibung erfragt Informationen
1138 : |*
1139 : *************************************************************************/
1140 :
1141 : // erfrage vom Modify Informationen
1142 0 : bool SwFlyFrm::GetInfo( SfxPoolItem & rInfo ) const
1143 : {
1144 0 : if( RES_AUTOFMT_DOCNODE == rInfo.Which() )
1145 0 : return false; // es gibt einen FlyFrm also wird er benutzt
1146 0 : return true; // weiter suchen
1147 : }
1148 :
1149 : /*************************************************************************
1150 : |*
1151 : |* SwFlyFrm::_Invalidate()
1152 : |*
1153 : |*************************************************************************/
1154 :
1155 492 : void SwFlyFrm::_Invalidate( SwPageFrm *pPage )
1156 : {
1157 492 : InvalidatePage( pPage );
1158 492 : bNotifyBack = bInvalid = sal_True;
1159 :
1160 : SwFlyFrm *pFrm;
1161 492 : if ( GetAnchorFrm() && 0 != (pFrm = AnchorFrm()->FindFlyFrm()) )
1162 : {
1163 : //Gaanz dumm: Wenn der Fly innerhalb eines Fly gebunden ist, der
1164 : //Spalten enthaehlt, sollte das Format von diesem ausgehen.
1165 0 : if ( !pFrm->IsLocked() && !pFrm->IsColLocked() &&
1166 0 : pFrm->Lower() && pFrm->Lower()->IsColumnFrm() )
1167 0 : pFrm->InvalidateSize();
1168 : }
1169 :
1170 : // #i85216#
1171 : // if vertical position is oriented at a layout frame inside a ghost section,
1172 : // assure that the position is invalidated and that the information about
1173 : // the vertical position oriented frame is cleared
1174 492 : if ( GetVertPosOrientFrm() && GetVertPosOrientFrm()->IsLayoutFrm() )
1175 : {
1176 46 : const SwSectionFrm* pSectFrm( GetVertPosOrientFrm()->FindSctFrm() );
1177 46 : if ( pSectFrm && pSectFrm->GetSection() == 0 )
1178 : {
1179 0 : InvalidatePos();
1180 0 : ClearVertPosOrientFrm();
1181 : }
1182 : }
1183 492 : }
1184 :
1185 : /*************************************************************************
1186 : |*
1187 : |* SwFlyFrm::ChgRelPos()
1188 : |*
1189 : |* Beschreibung Aenderung der relativen Position, die Position wird
1190 : |* damit automatisch Fix, das Attribut wird entprechend angepasst.
1191 : |*
1192 : |*************************************************************************/
1193 :
1194 0 : void SwFlyFrm::ChgRelPos( const Point &rNewPos )
1195 : {
1196 0 : if ( GetCurrRelPos() != rNewPos )
1197 : {
1198 0 : SwFrmFmt *pFmt = GetFmt();
1199 0 : const bool bVert = GetAnchorFrm()->IsVertical();
1200 0 : const SwTwips nNewY = bVert ? rNewPos.X() : rNewPos.Y();
1201 0 : SwTwips nTmpY = nNewY == LONG_MAX ? 0 : nNewY;
1202 0 : if( bVert )
1203 0 : nTmpY = -nTmpY;
1204 0 : SfxItemSet aSet( pFmt->GetDoc()->GetAttrPool(),
1205 0 : RES_VERT_ORIENT, RES_HORI_ORIENT);
1206 :
1207 0 : SwFmtVertOrient aVert( pFmt->GetVertOrient() );
1208 0 : SwTxtFrm *pAutoFrm = NULL;
1209 : // #i34948# - handle also at-page and at-fly anchored
1210 : // Writer fly frames
1211 0 : const RndStdIds eAnchorType = GetFrmFmt().GetAnchor().GetAnchorId();
1212 0 : if ( eAnchorType == FLY_AT_PAGE )
1213 : {
1214 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1215 0 : aVert.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1216 : }
1217 0 : else if ( eAnchorType == FLY_AT_FLY )
1218 : {
1219 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1220 0 : aVert.SetRelationOrient( text::RelOrientation::FRAME );
1221 : }
1222 0 : else if ( IsFlyAtCntFrm() || text::VertOrientation::NONE != aVert.GetVertOrient() )
1223 : {
1224 0 : if( text::RelOrientation::CHAR == aVert.GetRelationOrient() && IsAutoPos() )
1225 : {
1226 0 : if( LONG_MAX != nNewY )
1227 : {
1228 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1229 : xub_StrLen nOfs =
1230 0 : pFmt->GetAnchor().GetCntntAnchor()->nContent.GetIndex();
1231 : OSL_ENSURE( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected" );
1232 0 : pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1233 0 : while( pAutoFrm->GetFollow() &&
1234 0 : pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1235 : {
1236 0 : if( pAutoFrm == GetAnchorFrm() )
1237 0 : nTmpY += pAutoFrm->GetRelPos().Y();
1238 0 : nTmpY -= pAutoFrm->GetUpper()->Prt().Height();
1239 0 : pAutoFrm = pAutoFrm->GetFollow();
1240 : }
1241 0 : nTmpY = ((SwFlyAtCntFrm*)this)->GetRelCharY(pAutoFrm)-nTmpY;
1242 : }
1243 : else
1244 0 : aVert.SetVertOrient( text::VertOrientation::CHAR_BOTTOM );
1245 : }
1246 : else
1247 : {
1248 0 : aVert.SetVertOrient( text::VertOrientation::NONE );
1249 0 : aVert.SetRelationOrient( text::RelOrientation::FRAME );
1250 : }
1251 : }
1252 0 : aVert.SetPos( nTmpY );
1253 0 : aSet.Put( aVert );
1254 :
1255 : //Fuer Flys im Cnt ist die horizontale Ausrichtung uninteressant,
1256 : //den sie ist stets 0.
1257 0 : if ( !IsFlyInCntFrm() )
1258 : {
1259 0 : const SwTwips nNewX = bVert ? rNewPos.Y() : rNewPos.X();
1260 0 : SwTwips nTmpX = nNewX == LONG_MAX ? 0 : nNewX;
1261 0 : SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
1262 : // #i34948# - handle also at-page and at-fly anchored
1263 : // Writer fly frames
1264 0 : if ( eAnchorType == FLY_AT_PAGE )
1265 : {
1266 0 : aHori.SetHoriOrient( text::HoriOrientation::NONE );
1267 0 : aHori.SetRelationOrient( text::RelOrientation::PAGE_FRAME );
1268 0 : aHori.SetPosToggle( sal_False );
1269 : }
1270 0 : else if ( eAnchorType == FLY_AT_FLY )
1271 : {
1272 0 : aHori.SetHoriOrient( text::HoriOrientation::NONE );
1273 0 : aHori.SetRelationOrient( text::RelOrientation::FRAME );
1274 0 : aHori.SetPosToggle( sal_False );
1275 : }
1276 0 : else if ( IsFlyAtCntFrm() || text::HoriOrientation::NONE != aHori.GetHoriOrient() )
1277 : {
1278 0 : aHori.SetHoriOrient( text::HoriOrientation::NONE );
1279 0 : if( text::RelOrientation::CHAR == aHori.GetRelationOrient() && IsAutoPos() )
1280 : {
1281 0 : if( LONG_MAX != nNewX )
1282 : {
1283 0 : if( !pAutoFrm )
1284 : {
1285 0 : xub_StrLen nOfs = pFmt->GetAnchor().GetCntntAnchor()
1286 0 : ->nContent.GetIndex();
1287 : OSL_ENSURE( GetAnchorFrm()->IsTxtFrm(), "TxtFrm expected");
1288 0 : pAutoFrm = (SwTxtFrm*)GetAnchorFrm();
1289 0 : while( pAutoFrm->GetFollow() &&
1290 0 : pAutoFrm->GetFollow()->GetOfst() <= nOfs )
1291 0 : pAutoFrm = pAutoFrm->GetFollow();
1292 : }
1293 0 : nTmpX -= ((SwFlyAtCntFrm*)this)->GetRelCharX(pAutoFrm);
1294 : }
1295 : }
1296 : else
1297 0 : aHori.SetRelationOrient( text::RelOrientation::FRAME );
1298 0 : aHori.SetPosToggle( sal_False );
1299 : }
1300 0 : aHori.SetPos( nTmpX );
1301 0 : aSet.Put( aHori );
1302 : }
1303 0 : SetCurrRelPos( rNewPos );
1304 0 : pFmt->GetDoc()->SetAttr( aSet, *pFmt );
1305 : }
1306 0 : }
1307 : /*************************************************************************
1308 : |*
1309 : |* SwFlyFrm::Format()
1310 : |*
1311 : |* Beschreibung: "Formatiert" den Frame; Frm und PrtArea.
1312 : |* Die Fixsize wird hier nicht eingestellt.
1313 : |*
1314 : |*************************************************************************/
1315 :
1316 742 : void SwFlyFrm::Format( const SwBorderAttrs *pAttrs )
1317 : {
1318 : OSL_ENSURE( pAttrs, "FlyFrm::Format, pAttrs ist 0." );
1319 :
1320 742 : ColLock();
1321 :
1322 742 : if ( !bValidSize )
1323 : {
1324 742 : if ( Frm().Top() == FAR_AWAY && Frm().Left() == FAR_AWAY )
1325 : {
1326 : //Sicherheitsschaltung wegnehmen (siehe SwFrm::CTor)
1327 364 : Frm().Pos().X() = Frm().Pos().Y() = 0;
1328 : // #i68520#
1329 364 : InvalidateObjRectWithSpaces();
1330 : }
1331 :
1332 : //Breite der Spalten pruefen und ggf. einstellen.
1333 742 : if ( Lower() && Lower()->IsColumnFrm() )
1334 0 : AdjustColumns( 0, sal_False );
1335 :
1336 742 : bValidSize = sal_True;
1337 :
1338 742 : const SwTwips nUL = pAttrs->CalcTopLine() + pAttrs->CalcBottomLine();
1339 742 : const SwTwips nLR = pAttrs->CalcLeftLine() + pAttrs->CalcRightLine();
1340 742 : const SwFmtFrmSize &rFrmSz = GetFmt()->GetFrmSize();
1341 742 : Size aRelSize( CalcRel( rFrmSz ) );
1342 :
1343 : OSL_ENSURE( pAttrs->GetSize().Height() != 0 || rFrmSz.GetHeightPercent(), "Hoehe des RahmenAttr ist 0." );
1344 : OSL_ENSURE( pAttrs->GetSize().Width() != 0 || rFrmSz.GetWidthPercent(), "Breite des RahmenAttr ist 0." );
1345 :
1346 742 : SWRECTFN( this )
1347 742 : if( !HasFixSize() )
1348 : {
1349 60 : SwTwips nRemaining = 0;
1350 :
1351 60 : long nMinHeight = 0;
1352 60 : if( IsMinHeight() )
1353 44 : nMinHeight = bVert ? aRelSize.Width() : aRelSize.Height();
1354 :
1355 60 : if ( Lower() )
1356 : {
1357 60 : if ( Lower()->IsColumnFrm() )
1358 : {
1359 0 : FormatWidthCols( *pAttrs, nUL, nMinHeight );
1360 0 : nRemaining = (Lower()->Frm().*fnRect->fnGetHeight)();
1361 : }
1362 : else
1363 : {
1364 60 : SwFrm *pFrm = Lower();
1365 204 : while ( pFrm )
1366 : {
1367 84 : nRemaining += (pFrm->Frm().*fnRect->fnGetHeight)();
1368 84 : if( pFrm->IsTxtFrm() && ((SwTxtFrm*)pFrm)->IsUndersized() )
1369 : // Dieser TxtFrm waere gern ein bisschen groesser
1370 0 : nRemaining += ((SwTxtFrm*)pFrm)->GetParHeight()
1371 0 : - (pFrm->Prt().*fnRect->fnGetHeight)();
1372 84 : else if( pFrm->IsSctFrm() && ((SwSectionFrm*)pFrm)->IsUndersized() )
1373 0 : nRemaining += ((SwSectionFrm*)pFrm)->Undersize();
1374 84 : pFrm = pFrm->GetNext();
1375 : }
1376 : // #130878#
1377 : // Do not keep old height, if content has no height.
1378 : // The old height could be wrong due to wrong layout cache
1379 : // and isn't corrected in the further formatting, because
1380 : // the fly frame doesn't become invalid anymore.
1381 : // if( !nRemaining )
1382 : // nRemaining = nOldHeight - nUL;
1383 : }
1384 60 : if ( GetDrawObjs() )
1385 : {
1386 0 : sal_uInt32 nCnt = GetDrawObjs()->Count();
1387 0 : SwTwips nTop = (Frm().*fnRect->fnGetTop)();
1388 0 : SwTwips nBorder = (Frm().*fnRect->fnGetHeight)() -
1389 0 : (Prt().*fnRect->fnGetHeight)();
1390 0 : for ( sal_uInt16 i = 0; i < nCnt; ++i )
1391 : {
1392 0 : SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
1393 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
1394 : {
1395 0 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1396 : // OD 06.11.2003 #i22305# - consider
1397 : // only Writer fly frames, which follow the text flow.
1398 0 : if ( pFly->IsFlyLayFrm() &&
1399 0 : pFly->Frm().Top() != FAR_AWAY &&
1400 0 : pFly->GetFmt()->GetFollowTextFlow().GetValue() )
1401 : {
1402 0 : SwTwips nDist = -(pFly->Frm().*fnRect->
1403 0 : fnBottomDist)( nTop );
1404 0 : if( nDist > nBorder + nRemaining )
1405 0 : nRemaining = nDist - nBorder;
1406 : }
1407 : }
1408 : }
1409 : }
1410 : }
1411 :
1412 60 : if( IsMinHeight() && (nRemaining + nUL) < nMinHeight )
1413 26 : nRemaining = nMinHeight - nUL;
1414 : //Weil das Grow/Shrink der Flys die Groessen nicht direkt
1415 : //einstellt, sondern indirekt per Invalidate ein Format
1416 : //ausloesst, muessen die Groessen hier direkt eingestellt
1417 : //werden. Benachrichtung laeuft bereits mit.
1418 : //Weil bereits haeufiger 0en per Attribut hereinkamen wehre
1419 : //ich mich ab sofort dagegen.
1420 60 : if ( nRemaining < MINFLY )
1421 8 : nRemaining = MINFLY;
1422 60 : (Prt().*fnRect->fnSetHeight)( nRemaining );
1423 60 : nRemaining -= (Frm().*fnRect->fnGetHeight)();
1424 60 : (Frm().*fnRect->fnAddBottom)( nRemaining + nUL );
1425 : // #i68520#
1426 60 : if ( nRemaining + nUL != 0 )
1427 : {
1428 16 : InvalidateObjRectWithSpaces();
1429 : }
1430 60 : bValidSize = sal_True;
1431 : }
1432 : else
1433 : {
1434 682 : bValidSize = sal_True; //Fixe Frms formatieren sich nicht.
1435 : //Flys stellen ihre Groesse anhand des Attr ein.
1436 682 : SwTwips nNewSize = bVert ? aRelSize.Width() : aRelSize.Height();
1437 682 : nNewSize -= nUL;
1438 682 : if( nNewSize < MINFLY )
1439 0 : nNewSize = MINFLY;
1440 682 : (Prt().*fnRect->fnSetHeight)( nNewSize );
1441 682 : nNewSize += nUL - (Frm().*fnRect->fnGetHeight)();
1442 682 : (Frm().*fnRect->fnAddBottom)( nNewSize );
1443 : // #i68520#
1444 682 : if ( nNewSize != 0 )
1445 : {
1446 314 : InvalidateObjRectWithSpaces();
1447 : }
1448 : }
1449 :
1450 742 : if ( !bFormatHeightOnly )
1451 : {
1452 : OSL_ENSURE( aRelSize == CalcRel( rFrmSz ), "SwFlyFrm::Format CalcRel problem" );
1453 742 : SwTwips nNewSize = bVert ? aRelSize.Height() : aRelSize.Width();
1454 :
1455 742 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1456 : {
1457 : // #i9046# Autowidth for fly frames
1458 0 : const SwTwips nAutoWidth = CalcAutoWidth();
1459 0 : if ( nAutoWidth )
1460 : {
1461 0 : if( ATT_MIN_SIZE == rFrmSz.GetWidthSizeType() )
1462 0 : nNewSize = Max( nNewSize - nLR, nAutoWidth );
1463 : else
1464 0 : nNewSize = nAutoWidth;
1465 : }
1466 : }
1467 : else
1468 742 : nNewSize -= nLR;
1469 :
1470 742 : if( nNewSize < MINFLY )
1471 0 : nNewSize = MINFLY;
1472 742 : (Prt().*fnRect->fnSetWidth)( nNewSize );
1473 742 : nNewSize += nLR - (Frm().*fnRect->fnGetWidth)();
1474 742 : (Frm().*fnRect->fnAddRight)( nNewSize );
1475 : // #i68520#
1476 742 : if ( nNewSize != 0 )
1477 : {
1478 0 : InvalidateObjRectWithSpaces();
1479 : }
1480 : }
1481 : }
1482 742 : ColUnlock();
1483 742 : }
1484 :
1485 : // OD 14.03.2003 #i11760# - change parameter <bNoColl>: type <bool>;
1486 : // default value = false.
1487 : // OD 14.03.2003 #i11760# - add new parameter <bNoCalcFollow> with
1488 : // default value = false.
1489 : // OD 11.04.2003 #108824# - new parameter <bNoCalcFollow> was used by method
1490 : // <FormatWidthCols(..)> to avoid follow formatting
1491 : // for text frames. But, unformatted follows causes
1492 : // problems in method <SwCntntFrm::_WouldFit(..)>,
1493 : // which assumes that the follows are formatted.
1494 : // Thus, <bNoCalcFollow> no longer used by <FormatWidthCols(..)>.
1495 : //void CalcCntnt( SwLayoutFrm *pLay, sal_Bool bNoColl )
1496 0 : void CalcCntnt( SwLayoutFrm *pLay,
1497 : bool bNoColl,
1498 : bool bNoCalcFollow )
1499 : {
1500 : SwSectionFrm* pSect;
1501 0 : bool bCollect = false;
1502 0 : if( pLay->IsSctFrm() )
1503 : {
1504 0 : pSect = (SwSectionFrm*)pLay;
1505 0 : if( pSect->IsEndnAtEnd() && !bNoColl )
1506 : {
1507 0 : bCollect = true;
1508 0 : SwLayouter::CollectEndnotes( pLay->GetFmt()->GetDoc(), pSect );
1509 : }
1510 0 : pSect->CalcFtnCntnt();
1511 : }
1512 : else
1513 0 : pSect = NULL;
1514 0 : SwFrm *pFrm = pLay->ContainsAny();
1515 0 : if ( !pFrm )
1516 : {
1517 0 : if( pSect )
1518 : {
1519 0 : if( pSect->HasFollow() )
1520 0 : pFrm = pSect->GetFollow()->ContainsAny();
1521 0 : if( !pFrm )
1522 : {
1523 0 : if( pSect->IsEndnAtEnd() )
1524 : {
1525 0 : if( bCollect )
1526 0 : pLay->GetFmt()->GetDoc()->GetLayouter()->
1527 0 : InsertEndnotes( pSect );
1528 0 : sal_Bool bLock = pSect->IsFtnLock();
1529 0 : pSect->SetFtnLock( sal_True );
1530 0 : pSect->CalcFtnCntnt();
1531 0 : pSect->CalcFtnCntnt();
1532 0 : pSect->SetFtnLock( bLock );
1533 : }
1534 0 : return;
1535 : }
1536 0 : pFrm->_InvalidatePos();
1537 : }
1538 : else
1539 0 : return;
1540 : }
1541 0 : pFrm->InvalidatePage();
1542 :
1543 0 : do
1544 : {
1545 : // local variables to avoid loops caused by anchored object positioning
1546 0 : SwAnchoredObject* pAgainObj1 = 0;
1547 0 : SwAnchoredObject* pAgainObj2 = 0;
1548 :
1549 : // FME 2007-08-30 #i81146# new loop control
1550 0 : sal_uInt16 nLoopControlRuns = 0;
1551 0 : const sal_uInt16 nLoopControlMax = 20;
1552 0 : const SwFrm* pLoopControlCond = 0;
1553 :
1554 : SwFrm* pLast;
1555 0 : do
1556 : {
1557 0 : pLast = pFrm;
1558 0 : if( pFrm->IsVertical() ?
1559 0 : ( pFrm->GetUpper()->Prt().Height() != pFrm->Frm().Height() )
1560 0 : : ( pFrm->GetUpper()->Prt().Width() != pFrm->Frm().Width() ) )
1561 : {
1562 0 : pFrm->Prepare( PREP_FIXSIZE_CHG );
1563 0 : pFrm->_InvalidateSize();
1564 : }
1565 :
1566 0 : if ( pFrm->IsTabFrm() )
1567 : {
1568 0 : ((SwTabFrm*)pFrm)->bCalcLowers = sal_True;
1569 : // OD 26.08.2003 #i18103# - lock move backward of follow table,
1570 : // if no section content is formatted or follow table belongs
1571 : // to the section, which content is formatted.
1572 0 : if ( ((SwTabFrm*)pFrm)->IsFollow() &&
1573 0 : ( !pSect || pSect == pFrm->FindSctFrm() ) )
1574 : {
1575 0 : ((SwTabFrm*)pFrm)->bLockBackMove = sal_True;
1576 : }
1577 : }
1578 :
1579 : // OD 14.03.2003 #i11760# - forbid format of follow, if requested.
1580 0 : if ( bNoCalcFollow && pFrm->IsTxtFrm() )
1581 0 : static_cast<SwTxtFrm*>(pFrm)->ForbidFollowFormat();
1582 :
1583 0 : pFrm->Calc();
1584 :
1585 : // OD 14.03.2003 #i11760# - reset control flag for follow format.
1586 0 : if ( pFrm->IsTxtFrm() )
1587 : {
1588 0 : static_cast<SwTxtFrm*>(pFrm)->AllowFollowFormat();
1589 : }
1590 :
1591 : // #111937# The keep-attribute can cause the position
1592 : // of the prev to be invalid:
1593 : // OD 2004-03-15 #116560# - Do not consider invalid previous frame
1594 : // due to its keep-attribute, if current frame is a follow or is locked.
1595 : // #i44049# - do not consider invalid previous
1596 : // frame due to its keep-attribute, if it can't move forward.
1597 : // #i57765# - do not consider invalid previous
1598 : // frame, if current frame has a column/page break before attribute.
1599 0 : SwFrm* pTmpPrev = pFrm->FindPrev();
1600 0 : SwFlowFrm* pTmpPrevFlowFrm = pTmpPrev && pTmpPrev->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pTmpPrev) : 0;
1601 0 : SwFlowFrm* pTmpFlowFrm = pFrm->IsFlowFrm() ? SwFlowFrm::CastFlowFrm(pFrm) : 0;
1602 :
1603 : bool bPrevInvalid = pTmpPrevFlowFrm && pTmpFlowFrm &&
1604 0 : !pTmpFlowFrm->IsFollow() &&
1605 0 : !StackHack::IsLocked() && // #i76382#
1606 0 : !pTmpFlowFrm->IsJoinLocked() &&
1607 0 : !pTmpPrev->GetValidPosFlag() &&
1608 0 : pLay->IsAnLower( pTmpPrev ) &&
1609 0 : pTmpPrevFlowFrm->IsKeep( *pTmpPrev->GetAttrSet() ) &&
1610 0 : pTmpPrevFlowFrm->IsKeepFwdMoveAllowed();
1611 :
1612 : // format floating screen objects anchored to the frame.
1613 0 : bool bRestartLayoutProcess = false;
1614 0 : if ( !bPrevInvalid && pFrm->GetDrawObjs() && pLay->IsAnLower( pFrm ) )
1615 : {
1616 0 : bool bAgain = false;
1617 0 : SwPageFrm* pPageFrm = pFrm->FindPageFrm();
1618 0 : sal_uInt32 nCnt = pFrm->GetDrawObjs()->Count();
1619 0 : for ( sal_uInt16 i = 0; i < nCnt; ++i )
1620 : {
1621 : // #i28701#
1622 0 : SwAnchoredObject* pAnchoredObj = (*pFrm->GetDrawObjs())[i];
1623 : // determine, if anchored object has to be formatted.
1624 0 : if ( pAnchoredObj->PositionLocked() )
1625 : {
1626 0 : continue;
1627 : }
1628 :
1629 : // format anchored object
1630 0 : if ( pAnchoredObj->IsFormatPossible() )
1631 : {
1632 : // #i43737# - no invalidation of
1633 : // anchored object needed - causes loops for as-character
1634 : // anchored objects.
1635 : //pAnchoredObj->InvalidateObjPos();
1636 0 : SwRect aRect( pAnchoredObj->GetObjRect() );
1637 0 : if ( !SwObjectFormatter::FormatObj( *pAnchoredObj, pFrm, pPageFrm ) )
1638 : {
1639 0 : bRestartLayoutProcess = true;
1640 : break;
1641 : }
1642 : // #i3317# - restart layout process,
1643 : // if the position of the anchored object is locked now.
1644 0 : if ( pAnchoredObj->PositionLocked() )
1645 : {
1646 0 : bRestartLayoutProcess = true;
1647 : break;
1648 : }
1649 :
1650 0 : if ( aRect != pAnchoredObj->GetObjRect() )
1651 : {
1652 0 : bAgain = true;
1653 0 : if ( pAgainObj2 == pAnchoredObj )
1654 : {
1655 : OSL_FAIL( "::CalcCntnt(..) - loop detected, perform attribute changes to avoid the loop" );
1656 : //Oszillation unterbinden.
1657 0 : SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt();
1658 0 : SwFmtSurround aAttr( rFmt.GetSurround() );
1659 0 : if( SURROUND_THROUGHT != aAttr.GetSurround() )
1660 : {
1661 : // Bei autopositionierten hilft manchmal nur
1662 : // noch, auf Durchlauf zu schalten
1663 0 : if ((rFmt.GetAnchor().GetAnchorId() ==
1664 : FLY_AT_CHAR) &&
1665 : (SURROUND_PARALLEL ==
1666 0 : aAttr.GetSurround()))
1667 : {
1668 0 : aAttr.SetSurround( SURROUND_THROUGHT );
1669 : }
1670 : else
1671 : {
1672 0 : aAttr.SetSurround( SURROUND_PARALLEL );
1673 : }
1674 0 : rFmt.LockModify();
1675 0 : rFmt.SetFmtAttr( aAttr );
1676 0 : rFmt.UnlockModify();
1677 0 : }
1678 : }
1679 : else
1680 : {
1681 0 : if ( pAgainObj1 == pAnchoredObj )
1682 0 : pAgainObj2 = pAnchoredObj;
1683 0 : pAgainObj1 = pAnchoredObj;
1684 : }
1685 : }
1686 :
1687 0 : if ( !pFrm->GetDrawObjs() )
1688 : break;
1689 0 : if ( pFrm->GetDrawObjs()->Count() < nCnt )
1690 : {
1691 0 : --i;
1692 0 : --nCnt;
1693 : }
1694 : }
1695 : }
1696 :
1697 : // #i28701# - restart layout process, if
1698 : // requested by floating screen object formatting
1699 0 : if ( bRestartLayoutProcess )
1700 : {
1701 0 : pFrm = pLay->ContainsAny();
1702 0 : pAgainObj1 = 0L;
1703 0 : pAgainObj2 = 0L;
1704 0 : continue;
1705 : }
1706 :
1707 : // OD 2004-05-17 #i28701# - format anchor frame after its objects
1708 : // are formatted, if the wrapping style influence has to be considered.
1709 0 : if ( pLay->GetFmt()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) )
1710 : {
1711 0 : pFrm->Calc();
1712 : }
1713 :
1714 0 : if ( bAgain )
1715 : {
1716 0 : pFrm = pLay->ContainsCntnt();
1717 0 : if ( pFrm && pFrm->IsInTab() )
1718 0 : pFrm = pFrm->FindTabFrm();
1719 0 : if( pFrm && pFrm->IsInSct() )
1720 : {
1721 0 : SwSectionFrm* pTmp = pFrm->FindSctFrm();
1722 0 : if( pTmp != pLay && pLay->IsAnLower( pTmp ) )
1723 0 : pFrm = pTmp;
1724 : }
1725 :
1726 0 : if ( pFrm == pLoopControlCond )
1727 0 : ++nLoopControlRuns;
1728 : else
1729 : {
1730 0 : nLoopControlRuns = 0;
1731 0 : pLoopControlCond = pFrm;
1732 : }
1733 :
1734 0 : if ( nLoopControlRuns < nLoopControlMax )
1735 0 : continue;
1736 :
1737 : OSL_FAIL( "LoopControl in CalcCntnt" );
1738 : }
1739 : }
1740 0 : if ( pFrm->IsTabFrm() )
1741 : {
1742 0 : if ( ((SwTabFrm*)pFrm)->IsFollow() )
1743 0 : ((SwTabFrm*)pFrm)->bLockBackMove = sal_False;
1744 : }
1745 :
1746 0 : pFrm = bPrevInvalid ? pTmpPrev : pFrm->FindNext();
1747 0 : if( !bPrevInvalid && pFrm && pFrm->IsSctFrm() && pSect )
1748 : {
1749 : // Es koennen hier leere SectionFrms herumspuken
1750 0 : while( pFrm && pFrm->IsSctFrm() && !((SwSectionFrm*)pFrm)->GetSection() )
1751 0 : pFrm = pFrm->FindNext();
1752 : // Wenn FindNext den Follow des urspruenglichen Bereichs liefert,
1753 : // wollen wir mit dessen Inhalt weitermachen, solange dieser
1754 : // zurueckfliesst.
1755 0 : if( pFrm && pFrm->IsSctFrm() && ( pFrm == pSect->GetFollow() ||
1756 0 : ((SwSectionFrm*)pFrm)->IsAnFollow( pSect ) ) )
1757 : {
1758 0 : pFrm = ((SwSectionFrm*)pFrm)->ContainsAny();
1759 0 : if( pFrm )
1760 0 : pFrm->_InvalidatePos();
1761 : }
1762 : }
1763 : // Im pLay bleiben, Ausnahme, bei SectionFrms mit Follow wird der erste
1764 : // CntntFrm des Follows anformatiert, damit er die Chance erhaelt, in
1765 : // pLay zu landen. Solange diese Frames in pLay landen, geht's weiter.
1766 : } while ( pFrm &&
1767 0 : ( pLay->IsAnLower( pFrm ) ||
1768 : ( pSect &&
1769 0 : ( ( pSect->HasFollow() &&
1770 0 : ( pLay->IsAnLower( pLast ) ||
1771 0 : ( pLast->IsInSct() &&
1772 0 : pLast->FindSctFrm()->IsAnFollow(pSect) ) ) &&
1773 0 : pSect->GetFollow()->IsAnLower( pFrm ) ) ||
1774 0 : ( pFrm->IsInSct() &&
1775 0 : pFrm->FindSctFrm()->IsAnFollow( pSect ) ) ) ) ) );
1776 0 : if( pSect )
1777 : {
1778 0 : if( bCollect )
1779 : {
1780 0 : pLay->GetFmt()->GetDoc()->GetLayouter()->InsertEndnotes(pSect);
1781 0 : pSect->CalcFtnCntnt();
1782 : }
1783 0 : if( pSect->HasFollow() )
1784 : {
1785 0 : SwSectionFrm* pNxt = pSect->GetFollow();
1786 0 : while( pNxt && !pNxt->ContainsCntnt() )
1787 0 : pNxt = pNxt->GetFollow();
1788 0 : if( pNxt )
1789 0 : pNxt->CalcFtnCntnt();
1790 : }
1791 0 : if( bCollect )
1792 : {
1793 0 : pFrm = pLay->ContainsAny();
1794 0 : bCollect = false;
1795 0 : if( pFrm )
1796 0 : continue;
1797 : }
1798 : }
1799 0 : break;
1800 : }
1801 : while( true );
1802 : }
1803 :
1804 : /*************************************************************************
1805 : |*
1806 : |* SwFlyFrm::MakeFlyPos()
1807 : |*
1808 : |*************************************************************************/
1809 : // OD 2004-03-23 #i26791#
1810 : //void SwFlyFrm::MakeFlyPos()
1811 0 : void SwFlyFrm::MakeObjPos()
1812 : {
1813 0 : if ( !bValidPos )
1814 : {
1815 0 : bValidPos = sal_True;
1816 :
1817 : // OD 29.10.2003 #113049# - use new class to position object
1818 0 : GetAnchorFrm()->Calc();
1819 : objectpositioning::SwToLayoutAnchoredObjectPosition
1820 0 : aObjPositioning( *GetVirtDrawObj() );
1821 0 : aObjPositioning.CalcPosition();
1822 :
1823 : // #i58280#
1824 : // update relative position
1825 0 : SetCurrRelPos( aObjPositioning.GetRelPos() );
1826 :
1827 0 : SWRECTFN( GetAnchorFrm() );
1828 0 : aFrm.Pos( aObjPositioning.GetRelPos() );
1829 0 : aFrm.Pos() += (GetAnchorFrm()->Frm().*fnRect->fnGetPos)();
1830 : // #i69335#
1831 0 : InvalidateObjRectWithSpaces();
1832 : }
1833 0 : }
1834 :
1835 : /*************************************************************************
1836 : |*
1837 : |* SwFlyFrm::MakePrtArea()
1838 : |*
1839 : |*************************************************************************/
1840 742 : void SwFlyFrm::MakePrtArea( const SwBorderAttrs &rAttrs )
1841 : {
1842 :
1843 742 : if ( !bValidPrtArea )
1844 : {
1845 742 : bValidPrtArea = sal_True;
1846 :
1847 : // OD 31.07.2003 #110978# - consider vertical layout
1848 742 : SWRECTFN( this )
1849 742 : (this->*fnRect->fnSetXMargins)( rAttrs.CalcLeftLine(),
1850 1484 : rAttrs.CalcRightLine() );
1851 742 : (this->*fnRect->fnSetYMargins)( rAttrs.CalcTopLine(),
1852 1484 : rAttrs.CalcBottomLine() );
1853 : }
1854 742 : }
1855 :
1856 : /*************************************************************************
1857 : |*
1858 : |* SwFlyFrm::_Grow(), _Shrink()
1859 : |*
1860 : |*************************************************************************/
1861 :
1862 18 : SwTwips SwFlyFrm::_Grow( SwTwips nDist, sal_Bool bTst )
1863 : {
1864 18 : SWRECTFN( this )
1865 18 : if ( Lower() && !IsColLocked() && !HasFixSize() )
1866 : {
1867 16 : SwTwips nSize = (Frm().*fnRect->fnGetHeight)();
1868 16 : if( nSize > 0 && nDist > ( LONG_MAX - nSize ) )
1869 0 : nDist = LONG_MAX - nSize;
1870 :
1871 16 : if ( nDist <= 0L )
1872 0 : return 0L;
1873 :
1874 16 : if ( Lower()->IsColumnFrm() )
1875 : { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
1876 : //das Wachstum (wg. des Ausgleichs).
1877 0 : if ( !bTst )
1878 : {
1879 : // #i28701# - unlock position of Writer fly frame
1880 0 : UnlockPosition();
1881 0 : _InvalidatePos();
1882 0 : InvalidateSize();
1883 : }
1884 0 : return 0L;
1885 : }
1886 :
1887 16 : if ( !bTst )
1888 : {
1889 16 : const SwRect aOld( GetObjRectWithSpaces() );
1890 16 : _InvalidateSize();
1891 16 : const sal_Bool bOldLock = bLocked;
1892 16 : Unlock();
1893 16 : if ( IsFlyFreeFrm() )
1894 : {
1895 : // #i37068# - no format of position here
1896 : // and prevent move in method <CheckClip(..)>.
1897 : // This is needed to prevent layout loop caused by nested
1898 : // Writer fly frames - inner Writer fly frames format its
1899 : // anchor, which grows/shrinks the outer Writer fly frame.
1900 : // Note: position will be invalidated below.
1901 16 : bValidPos = sal_True;
1902 : // #i55416#
1903 : // Suppress format of width for autowidth frame, because the
1904 : // format of the width would call <SwTxtFrm::CalcFitToContent()>
1905 : // for the lower frame, which initiated this grow.
1906 16 : const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
1907 16 : const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
1908 16 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1909 : {
1910 0 : bFormatHeightOnly = sal_True;
1911 : }
1912 16 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
1913 16 : ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
1914 16 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
1915 : // #i55416#
1916 16 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
1917 : {
1918 0 : bFormatHeightOnly = bOldFormatHeightOnly;
1919 : }
1920 : }
1921 : else
1922 0 : MakeAll();
1923 16 : _InvalidateSize();
1924 16 : InvalidatePos();
1925 16 : if ( bOldLock )
1926 0 : Lock();
1927 16 : const SwRect aNew( GetObjRectWithSpaces() );
1928 16 : if ( aOld != aNew )
1929 16 : ::Notify( this, FindPageFrm(), aOld );
1930 16 : return (aNew.*fnRect->fnGetHeight)()-(aOld.*fnRect->fnGetHeight)();
1931 : }
1932 0 : return nDist;
1933 : }
1934 2 : return 0L;
1935 : }
1936 :
1937 0 : SwTwips SwFlyFrm::_Shrink( SwTwips nDist, sal_Bool bTst )
1938 : {
1939 0 : if( Lower() && !IsColLocked() && !HasFixSize() && !IsNoShrink() )
1940 : {
1941 0 : SWRECTFN( this )
1942 0 : SwTwips nHeight = (Frm().*fnRect->fnGetHeight)();
1943 0 : if ( nDist > nHeight )
1944 0 : nDist = nHeight;
1945 :
1946 0 : SwTwips nVal = nDist;
1947 0 : if ( IsMinHeight() )
1948 : {
1949 0 : const SwFmtFrmSize& rFmtSize = GetFmt()->GetFrmSize();
1950 0 : SwTwips nFmtHeight = bVert ? rFmtSize.GetWidth() : rFmtSize.GetHeight();
1951 :
1952 0 : nVal = Min( nDist, nHeight - nFmtHeight );
1953 : }
1954 :
1955 0 : if ( nVal <= 0L )
1956 0 : return 0L;
1957 :
1958 0 : if ( Lower()->IsColumnFrm() )
1959 : { //Bei Spaltigkeit ubernimmt das Format die Kontrolle ueber
1960 : //das Wachstum (wg. des Ausgleichs).
1961 0 : if ( !bTst )
1962 : {
1963 0 : SwRect aOld( GetObjRectWithSpaces() );
1964 0 : (Frm().*fnRect->fnSetHeight)( nHeight - nVal );
1965 : // #i68520#
1966 0 : if ( nHeight - nVal != 0 )
1967 : {
1968 0 : InvalidateObjRectWithSpaces();
1969 : }
1970 0 : nHeight = (Prt().*fnRect->fnGetHeight)();
1971 0 : (Prt().*fnRect->fnSetHeight)( nHeight - nVal );
1972 0 : _InvalidatePos();
1973 0 : InvalidateSize();
1974 0 : ::Notify( this, FindPageFrm(), aOld );
1975 0 : NotifyDrawObj();
1976 0 : if ( GetAnchorFrm()->IsInFly() )
1977 0 : AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
1978 : }
1979 0 : return 0L;
1980 : }
1981 :
1982 0 : if ( !bTst )
1983 : {
1984 0 : const SwRect aOld( GetObjRectWithSpaces() );
1985 0 : _InvalidateSize();
1986 0 : const sal_Bool bOldLocked = bLocked;
1987 0 : Unlock();
1988 0 : if ( IsFlyFreeFrm() )
1989 : {
1990 : // #i37068# - no format of position here
1991 : // and prevent move in method <CheckClip(..)>.
1992 : // This is needed to prevent layout loop caused by nested
1993 : // Writer fly frames - inner Writer fly frames format its
1994 : // anchor, which grows/shrinks the outer Writer fly frame.
1995 : // Note: position will be invalidated below.
1996 0 : bValidPos = sal_True;
1997 : // #i55416#
1998 : // Suppress format of width for autowidth frame, because the
1999 : // format of the width would call <SwTxtFrm::CalcFitToContent()>
2000 : // for the lower frame, which initiated this shrink.
2001 0 : const sal_Bool bOldFormatHeightOnly = bFormatHeightOnly;
2002 0 : const SwFmtFrmSize& rFrmSz = GetFmt()->GetFrmSize();
2003 0 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2004 : {
2005 0 : bFormatHeightOnly = sal_True;
2006 : }
2007 0 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( true );
2008 0 : ((SwFlyFreeFrm*)this)->SwFlyFreeFrm::MakeAll();
2009 0 : static_cast<SwFlyFreeFrm*>(this)->SetNoMoveOnCheckClip( false );
2010 : // #i55416#
2011 0 : if ( rFrmSz.GetWidthSizeType() != ATT_FIX_SIZE )
2012 : {
2013 0 : bFormatHeightOnly = bOldFormatHeightOnly;
2014 : }
2015 : }
2016 : else
2017 0 : MakeAll();
2018 0 : _InvalidateSize();
2019 0 : InvalidatePos();
2020 0 : if ( bOldLocked )
2021 0 : Lock();
2022 0 : const SwRect aNew( GetObjRectWithSpaces() );
2023 0 : if ( aOld != aNew )
2024 : {
2025 0 : ::Notify( this, FindPageFrm(), aOld );
2026 0 : if ( GetAnchorFrm()->IsInFly() )
2027 0 : AnchorFrm()->FindFlyFrm()->Shrink( nDist, bTst );
2028 : }
2029 0 : return (aOld.*fnRect->fnGetHeight)() -
2030 0 : (aNew.*fnRect->fnGetHeight)();
2031 : }
2032 0 : return nVal;
2033 : }
2034 0 : return 0L;
2035 : }
2036 :
2037 : /*************************************************************************
2038 : |*
2039 : |* SwFlyFrm::ChgSize()
2040 : |*
2041 : |*************************************************************************/
2042 :
2043 0 : Size SwFlyFrm::ChgSize( const Size& aNewSize )
2044 : {
2045 : // #i53298#
2046 : // If the fly frame anchored at-paragraph or at-character contains an OLE
2047 : // object, assure that the new size fits into the current clipping area
2048 : // of the fly frame
2049 0 : Size aAdjustedNewSize( aNewSize );
2050 : {
2051 0 : if ( dynamic_cast<SwFlyAtCntFrm*>(this) &&
2052 0 : Lower() && dynamic_cast<SwNoTxtFrm*>(Lower()) &&
2053 0 : static_cast<SwNoTxtFrm*>(Lower())->GetNode()->GetOLENode() )
2054 : {
2055 0 : SwRect aClipRect;
2056 0 : ::CalcClipRect( GetVirtDrawObj(), aClipRect, sal_False );
2057 0 : if ( aAdjustedNewSize.Width() > aClipRect.Width() )
2058 : {
2059 0 : aAdjustedNewSize.setWidth( aClipRect.Width() );
2060 : }
2061 0 : if ( aAdjustedNewSize.Height() > aClipRect.Height() )
2062 : {
2063 0 : aAdjustedNewSize.setWidth( aClipRect.Height() );
2064 : }
2065 : }
2066 : }
2067 0 : if ( aAdjustedNewSize != Frm().SSize() )
2068 : {
2069 0 : SwFrmFmt *pFmt = GetFmt();
2070 0 : SwFmtFrmSize aSz( pFmt->GetFrmSize() );
2071 0 : aSz.SetWidth( aAdjustedNewSize.Width() );
2072 : // #i53298# - no tolerance any more.
2073 : // If it reveals that the tolerance is still needed, then suppress a
2074 : // <SetAttr> call, if <aSz> equals the current <SwFmtFrmSize> attribute.
2075 : // if ( Abs(aAdjustedNewSize.Height() - aSz.GetHeight()) > 1 )
2076 0 : aSz.SetHeight( aAdjustedNewSize.Height() );
2077 : // uebers Doc fuers Undo!
2078 0 : pFmt->GetDoc()->SetAttr( aSz, *pFmt );
2079 0 : return aSz.GetSize();
2080 : }
2081 : else
2082 0 : return Frm().SSize();
2083 : }
2084 :
2085 : /*************************************************************************
2086 : |*
2087 : |* SwFlyFrm::IsLowerOf()
2088 : |*
2089 : |*************************************************************************/
2090 :
2091 66 : sal_Bool SwFlyFrm::IsLowerOf( const SwLayoutFrm* pUpperFrm ) const
2092 : {
2093 : OSL_ENSURE( GetAnchorFrm(), "8-( Fly is lost in Space." );
2094 66 : const SwFrm* pFrm = GetAnchorFrm();
2095 308 : do
2096 : {
2097 308 : if ( pFrm == pUpperFrm )
2098 0 : return sal_True;
2099 308 : pFrm = pFrm->IsFlyFrm()
2100 0 : ? ((const SwFlyFrm*)pFrm)->GetAnchorFrm()
2101 308 : : pFrm->GetUpper();
2102 : } while ( pFrm );
2103 66 : return sal_False;
2104 : }
2105 :
2106 : /*************************************************************************
2107 : |*
2108 : |* SwFlyFrm::Cut()
2109 : |*
2110 : |*************************************************************************/
2111 :
2112 0 : void SwFlyFrm::Cut()
2113 : {
2114 0 : }
2115 :
2116 : /*************************************************************************
2117 : |*
2118 : |* SwFrm::AppendFly(), RemoveFly()
2119 : |*
2120 : |*************************************************************************/
2121 :
2122 384 : void SwFrm::AppendFly( SwFlyFrm *pNew )
2123 : {
2124 384 : if ( !pDrawObjs )
2125 298 : pDrawObjs = new SwSortedObjs();
2126 384 : pDrawObjs->Insert( *pNew );
2127 384 : pNew->ChgAnchorFrm( this );
2128 :
2129 : //Bei der Seite anmelden; kann sein, dass noch keine da ist - die
2130 : //Anmeldung wird dann in SwPageFrm::PreparePage durch gefuehrt.
2131 384 : SwPageFrm *pPage = FindPageFrm();
2132 384 : if ( pPage )
2133 : {
2134 374 : if ( pNew->IsFlyAtCntFrm() && pNew->Frm().Top() == FAR_AWAY )
2135 : {
2136 : //Versuch die Seitenformatierung von neuen Dokumenten etwas
2137 : //guenstiger zu gestalten.
2138 : //Wir haengen die Flys erstenmal nach hinten damit sie bei heftigem
2139 : //Fluss der Anker nicht unoetig oft formatiert werden.
2140 : //Damit man noch brauchbar an das Ende des Dokumentes springen
2141 : //kann werden die Flys nicht ganz an das Ende gehaengt.
2142 64 : SwRootFrm *pRoot = (SwRootFrm*)pPage->GetUpper();
2143 64 : if( !SwLayHelper::CheckPageFlyCache( pPage, pNew ) )
2144 : {
2145 64 : SwPageFrm *pTmp = pRoot->GetLastPage();
2146 64 : if ( pTmp->GetPhyPageNum() > 30 )
2147 : {
2148 0 : for ( sal_uInt16 i = 0; i < 10; ++i )
2149 : {
2150 0 : pTmp = (SwPageFrm*)pTmp->GetPrev();
2151 0 : if( pTmp->GetPhyPageNum() <= pPage->GetPhyPageNum() )
2152 0 : break; // damit wir nicht vor unserem Anker landen
2153 : }
2154 0 : if ( pTmp->IsEmptyPage() )
2155 0 : pTmp = (SwPageFrm*)pTmp->GetPrev();
2156 0 : pPage = pTmp;
2157 : }
2158 : }
2159 64 : pPage->AppendFlyToPage( pNew );
2160 : }
2161 : else
2162 310 : pPage->AppendFlyToPage( pNew );
2163 : }
2164 384 : }
2165 :
2166 0 : void SwFrm::RemoveFly( SwFlyFrm *pToRemove )
2167 : {
2168 : //Bei der Seite Abmelden - kann schon passiert sein weil die Seite
2169 : //bereits destruiert wurde.
2170 0 : SwPageFrm *pPage = pToRemove->FindPageFrm();
2171 0 : if ( pPage && pPage->GetSortedObjs() )
2172 : {
2173 0 : pPage->RemoveFlyFromPage( pToRemove );
2174 : }
2175 : // #i73201#
2176 : else
2177 : {
2178 0 : if ( pToRemove->IsAccessibleFrm() &&
2179 0 : pToRemove->GetFmt() &&
2180 0 : !pToRemove->IsFlyInCntFrm() )
2181 : {
2182 0 : SwRootFrm *pRootFrm = getRootFrm();
2183 0 : if( pRootFrm && pRootFrm->IsAnyShellAccessible() )
2184 : {
2185 0 : ViewShell *pVSh = pRootFrm->GetCurrShell();
2186 0 : if( pVSh && pVSh->Imp() )
2187 : {
2188 0 : pVSh->Imp()->DisposeAccessibleFrm( pToRemove );
2189 : }
2190 : }
2191 : }
2192 : }
2193 :
2194 0 : pDrawObjs->Remove( *pToRemove );
2195 0 : if ( !pDrawObjs->Count() )
2196 0 : DELETEZ( pDrawObjs );
2197 :
2198 0 : pToRemove->ChgAnchorFrm( 0 );
2199 :
2200 0 : if ( !pToRemove->IsFlyInCntFrm() && GetUpper() && IsInTab() )//MA_FLY_HEIGHT
2201 0 : GetUpper()->InvalidateSize();
2202 0 : }
2203 :
2204 : /*************************************************************************
2205 : |*
2206 : |* SwFrm::AppendDrawObj(), RemoveDrawObj()
2207 : |*
2208 : |* --> OD 2004-07-06 #i28701# - new methods
2209 : |*
2210 : |*************************************************************************/
2211 90 : void SwFrm::AppendDrawObj( SwAnchoredObject& _rNewObj )
2212 : {
2213 90 : if ( !_rNewObj.ISA(SwAnchoredDrawObject) )
2214 : {
2215 : OSL_FAIL( "SwFrm::AppendDrawObj(..) - anchored object of unexcepted type -> object not appended" );
2216 90 : return;
2217 : }
2218 :
2219 180 : if ( !_rNewObj.GetDrawObj()->ISA(SwDrawVirtObj) &&
2220 90 : _rNewObj.GetAnchorFrm() && _rNewObj.GetAnchorFrm() != this )
2221 : {
2222 : // perform disconnect from layout, if 'master' drawing object is appended
2223 : // to a new frame.
2224 0 : static_cast<SwDrawContact*>(::GetUserCall( _rNewObj.GetDrawObj() ))->
2225 0 : DisconnectFromLayout( false );
2226 : }
2227 :
2228 90 : if ( _rNewObj.GetAnchorFrm() != this )
2229 : {
2230 90 : if ( !pDrawObjs )
2231 61 : pDrawObjs = new SwSortedObjs();
2232 90 : pDrawObjs->Insert( _rNewObj );
2233 90 : _rNewObj.ChgAnchorFrm( this );
2234 : }
2235 :
2236 : // #i113730#
2237 : // Assure the control objects and group objects containing controls are on the control layer
2238 90 : if ( ::CheckControlLayer( _rNewObj.DrawObj() ) )
2239 : {
2240 8 : const IDocumentDrawModelAccess* pIDDMA = getIDocumentDrawModelAccess();
2241 8 : const SdrLayerID aCurrentLayer(_rNewObj.DrawObj()->GetLayer());
2242 8 : const SdrLayerID aControlLayerID(pIDDMA->GetControlsId());
2243 8 : const SdrLayerID aInvisibleControlLayerID(pIDDMA->GetInvisibleControlsId());
2244 :
2245 8 : if(aCurrentLayer != aControlLayerID && aCurrentLayer != aInvisibleControlLayerID)
2246 : {
2247 0 : if ( aCurrentLayer == pIDDMA->GetInvisibleHellId() ||
2248 0 : aCurrentLayer == pIDDMA->GetInvisibleHeavenId() )
2249 : {
2250 0 : _rNewObj.DrawObj()->SetLayer(aInvisibleControlLayerID);
2251 : }
2252 : else
2253 : {
2254 0 : _rNewObj.DrawObj()->SetLayer(aControlLayerID);
2255 : }
2256 : }
2257 : }
2258 :
2259 : // no direct positioning needed, but invalidate the drawing object position
2260 90 : _rNewObj.InvalidateObjPos();
2261 :
2262 : // register at page frame
2263 90 : SwPageFrm* pPage = FindPageFrm();
2264 90 : if ( pPage )
2265 : {
2266 84 : pPage->AppendDrawObjToPage( _rNewObj );
2267 : }
2268 :
2269 : // Notify accessible layout.
2270 90 : ViewShell* pSh = getRootFrm()->GetCurrShell();
2271 90 : if( pSh )
2272 : {
2273 90 : SwRootFrm* pLayout = getRootFrm();
2274 90 : if( pLayout && pLayout->IsAnyShellAccessible() )
2275 0 : pSh->Imp()->AddAccessibleObj( _rNewObj.GetDrawObj() );
2276 : }
2277 : }
2278 :
2279 10 : void SwFrm::RemoveDrawObj( SwAnchoredObject& _rToRemoveObj )
2280 : {
2281 : // Notify accessible layout.
2282 10 : ViewShell* pSh = getRootFrm()->GetCurrShell();
2283 10 : if( pSh )
2284 : {
2285 6 : SwRootFrm* pLayout = getRootFrm();
2286 6 : if( pLayout && pLayout->IsAnyShellAccessible() )
2287 0 : pSh->Imp()->DisposeAccessibleObj( _rToRemoveObj.GetDrawObj() );
2288 : }
2289 :
2290 : // deregister from page frame
2291 10 : SwPageFrm* pPage = _rToRemoveObj.GetPageFrm();
2292 10 : if ( pPage && pPage->GetSortedObjs() )
2293 6 : pPage->RemoveDrawObjFromPage( _rToRemoveObj );
2294 :
2295 10 : pDrawObjs->Remove( _rToRemoveObj );
2296 10 : if ( !pDrawObjs->Count() )
2297 5 : DELETEZ( pDrawObjs );
2298 :
2299 10 : _rToRemoveObj.ChgAnchorFrm( 0 );
2300 10 : }
2301 :
2302 : /*************************************************************************
2303 : |*
2304 : |* SwFrm::InvalidateObjs()
2305 : |*
2306 : |*************************************************************************/
2307 : // #i28701# - change purpose of method and adjust its name
2308 1971 : void SwFrm::InvalidateObjs( const bool _bInvaPosOnly,
2309 : const bool _bNoInvaOfAsCharAnchoredObjs )
2310 : {
2311 1971 : if ( GetDrawObjs() )
2312 : {
2313 : // #i26945# - determine page the frame is on,
2314 : // in order to check, if anchored object is registered at the same
2315 : // page.
2316 350 : const SwPageFrm* pPageFrm = FindPageFrm();
2317 : // #i28701# - re-factoring
2318 350 : sal_uInt32 i = 0;
2319 814 : for ( ; i < GetDrawObjs()->Count(); ++i )
2320 : {
2321 464 : SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
2322 928 : if ( _bNoInvaOfAsCharAnchoredObjs &&
2323 464 : (pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
2324 : == FLY_AS_CHAR) )
2325 : {
2326 326 : continue;
2327 : }
2328 : // #i26945# - no invalidation, if anchored object
2329 : // isn't registered at the same page and instead is registered at
2330 : // the page, where its anchor character text frame is on.
2331 276 : if ( pAnchoredObj->GetPageFrm() &&
2332 138 : pAnchoredObj->GetPageFrm() != pPageFrm )
2333 : {
2334 0 : SwTxtFrm* pAnchorCharFrm = pAnchoredObj->FindAnchorCharFrm();
2335 0 : if ( pAnchorCharFrm &&
2336 0 : pAnchoredObj->GetPageFrm() == pAnchorCharFrm->FindPageFrm() )
2337 : {
2338 0 : continue;
2339 : }
2340 : // #115759# - unlock its position, if anchored
2341 : // object isn't registered at the page, where its anchor
2342 : // character text frame is on, respectively if it has no
2343 : // anchor character text frame.
2344 : else
2345 : {
2346 0 : pAnchoredObj->UnlockPosition();
2347 : }
2348 : }
2349 : // #i51474# - reset flag, that anchored object
2350 : // has cleared environment, and unlock its position, if the anchored
2351 : // object is registered at the same page as the anchor frame is on.
2352 138 : if ( pAnchoredObj->ClearedEnvironment() &&
2353 0 : pAnchoredObj->GetPageFrm() &&
2354 0 : pAnchoredObj->GetPageFrm() == pPageFrm )
2355 : {
2356 0 : pAnchoredObj->UnlockPosition();
2357 0 : pAnchoredObj->SetClearedEnvironment( false );
2358 : }
2359 : // distinguish between writer fly frames and drawing objects
2360 138 : if ( pAnchoredObj->ISA(SwFlyFrm) )
2361 : {
2362 72 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
2363 72 : pFly->_Invalidate();
2364 72 : pFly->_InvalidatePos();
2365 72 : if ( !_bInvaPosOnly )
2366 0 : pFly->_InvalidateSize();
2367 : }
2368 : else
2369 : {
2370 66 : pAnchoredObj->InvalidateObjPos();
2371 : } // end of distinction between writer fly frames and drawing objects
2372 :
2373 : } // end of loop on objects, which are connected to the frame
2374 : }
2375 1971 : }
2376 :
2377 : /*************************************************************************
2378 : |*
2379 : |* SwLayoutFrm::NotifyLowerObjs()
2380 : |*
2381 : |*************************************************************************/
2382 : // #i28701# - change purpose of method and its name
2383 : // #i26945# - correct check, if anchored object is a lower
2384 : // of the layout frame. E.g., anchor character text frame can be a follow text
2385 : // frame.
2386 : // #i44016# - add parameter <_bUnlockPosOfObjs> to
2387 : // force an unlockposition call for the lower objects.
2388 2936 : void SwLayoutFrm::NotifyLowerObjs( const bool _bUnlockPosOfObjs )
2389 : {
2390 : // invalidate lower floating screen objects
2391 2936 : SwPageFrm* pPageFrm = FindPageFrm();
2392 2936 : if ( pPageFrm && pPageFrm->GetSortedObjs() )
2393 : {
2394 154 : SwSortedObjs& rObjs = *(pPageFrm->GetSortedObjs());
2395 434 : for ( sal_uInt32 i = 0; i < rObjs.Count(); ++i )
2396 : {
2397 280 : SwAnchoredObject* pObj = rObjs[i];
2398 : // #i26945# - check, if anchored object is a lower
2399 : // of the layout frame is changed to check, if its anchor frame
2400 : // is a lower of the layout frame.
2401 : // determine the anchor frame - usually it's the anchor frame,
2402 : // for at-character/as-character anchored objects the anchor character
2403 : // text frame is taken.
2404 280 : const SwFrm* pAnchorFrm = pObj->GetAnchorFrmContainingAnchPos();
2405 280 : if ( pObj->ISA(SwFlyFrm) )
2406 : {
2407 224 : SwFlyFrm* pFly = static_cast<SwFlyFrm*>(pObj);
2408 :
2409 224 : if ( pFly->Frm().Left() == FAR_AWAY )
2410 62 : continue;
2411 :
2412 162 : if ( pFly->IsAnLower( this ) )
2413 72 : continue;
2414 :
2415 : // #i26945# - use <pAnchorFrm> to check, if
2416 : // fly frame is lower of layout frame resp. if fly frame is
2417 : // at a different page registered as its anchor frame is on.
2418 90 : const bool bLow = IsAnLower( pAnchorFrm );
2419 90 : if ( bLow || pAnchorFrm->FindPageFrm() != pPageFrm )
2420 : {
2421 16 : pFly->_Invalidate( pPageFrm );
2422 16 : if ( !bLow || pFly->IsFlyAtCntFrm() )
2423 : {
2424 : // #i44016#
2425 16 : if ( _bUnlockPosOfObjs )
2426 : {
2427 10 : pFly->UnlockPosition();
2428 : }
2429 16 : pFly->_InvalidatePos();
2430 : }
2431 : else
2432 0 : pFly->_InvalidatePrt();
2433 : }
2434 : }
2435 : else
2436 : {
2437 : OSL_ENSURE( pObj->ISA(SwAnchoredDrawObject),
2438 : "<SwLayoutFrm::NotifyFlys() - anchored object of unexcepted type" );
2439 : // #i26945# - use <pAnchorFrm> to check, if
2440 : // fly frame is lower of layout frame resp. if fly frame is
2441 : // at a different page registered as its anchor frame is on.
2442 86 : if ( IsAnLower( pAnchorFrm ) ||
2443 30 : pAnchorFrm->FindPageFrm() != pPageFrm )
2444 : {
2445 : // #i44016#
2446 26 : if ( _bUnlockPosOfObjs )
2447 : {
2448 6 : pObj->UnlockPosition();
2449 : }
2450 26 : pObj->InvalidateObjPos();
2451 : }
2452 : }
2453 : }
2454 : }
2455 2936 : }
2456 :
2457 : /*************************************************************************
2458 : |*
2459 : |* SwFlyFrm::NotifyDrawObj()
2460 : |*
2461 : |*************************************************************************/
2462 :
2463 828 : void SwFlyFrm::NotifyDrawObj()
2464 : {
2465 828 : SwVirtFlyDrawObj* pObj = GetVirtDrawObj();
2466 828 : pObj->SetRect();
2467 828 : pObj->SetRectsDirty();
2468 828 : pObj->SetChanged();
2469 828 : pObj->BroadcastObjectChange();
2470 828 : if ( GetFmt()->GetSurround().IsContour() )
2471 0 : ClrContourCache( pObj );
2472 828 : }
2473 :
2474 : /*************************************************************************
2475 : |*
2476 : |* SwFlyFrm::CalcRel()
2477 : |*
2478 : |*************************************************************************/
2479 :
2480 742 : Size SwFlyFrm::CalcRel( const SwFmtFrmSize &rSz ) const
2481 : {
2482 742 : Size aRet( rSz.GetSize() );
2483 :
2484 742 : const SwFrm *pRel = IsFlyLayFrm() ? GetAnchorFrm() : GetAnchorFrm()->GetUpper();
2485 742 : if( pRel ) // LAYER_IMPL
2486 : {
2487 742 : long nRelWidth = LONG_MAX, nRelHeight = LONG_MAX;
2488 742 : const ViewShell *pSh = getRootFrm()->GetCurrShell();
2489 1292 : if ( ( pRel->IsBodyFrm() || pRel->IsPageFrm() ) &&
2490 550 : pSh && pSh->GetViewOptions()->getBrowseMode() &&
2491 0 : pSh->VisArea().HasArea() )
2492 : {
2493 0 : nRelWidth = pSh->GetBrowseWidth();
2494 0 : nRelHeight = pSh->VisArea().Height();
2495 0 : Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
2496 0 : long nDiff = nRelWidth - pRel->Prt().Width();
2497 0 : if ( nDiff > 0 )
2498 0 : nRelWidth -= nDiff;
2499 0 : nRelHeight -= 2*aBorder.Height();
2500 0 : nDiff = nRelHeight - pRel->Prt().Height();
2501 0 : if ( nDiff > 0 )
2502 0 : nRelHeight -= nDiff;
2503 : }
2504 742 : nRelWidth = Min( nRelWidth, pRel->Prt().Width() );
2505 742 : nRelHeight = Min( nRelHeight, pRel->Prt().Height() );
2506 742 : if( !pRel->IsPageFrm() )
2507 : {
2508 742 : const SwPageFrm* pPage = FindPageFrm();
2509 742 : if( pPage )
2510 : {
2511 742 : nRelWidth = Min( nRelWidth, pPage->Prt().Width() );
2512 742 : nRelHeight = Min( nRelHeight, pPage->Prt().Height() );
2513 : }
2514 : }
2515 :
2516 742 : if ( rSz.GetWidthPercent() && rSz.GetWidthPercent() != 0xFF )
2517 0 : aRet.Width() = nRelWidth * rSz.GetWidthPercent() / 100;
2518 742 : if ( rSz.GetHeightPercent() && rSz.GetHeightPercent() != 0xFF )
2519 0 : aRet.Height() = nRelHeight * rSz.GetHeightPercent() / 100;
2520 :
2521 742 : if ( rSz.GetWidthPercent() == 0xFF )
2522 : {
2523 0 : aRet.Width() *= aRet.Height();
2524 0 : aRet.Width() /= rSz.GetHeight();
2525 : }
2526 742 : else if ( rSz.GetHeightPercent() == 0xFF )
2527 : {
2528 0 : aRet.Height() *= aRet.Width();
2529 0 : aRet.Height() /= rSz.GetWidth();
2530 : }
2531 : }
2532 742 : return aRet;
2533 : }
2534 :
2535 : /*************************************************************************
2536 : |*
2537 : |* SwFlyFrm::CalcAutoWidth()
2538 : |*
2539 : |*************************************************************************/
2540 :
2541 0 : static SwTwips lcl_CalcAutoWidth( const SwLayoutFrm& rFrm )
2542 : {
2543 0 : SwTwips nRet = 0;
2544 0 : SwTwips nMin = 0;
2545 0 : const SwFrm* pFrm = rFrm.Lower();
2546 :
2547 : // No autowidth defined for columned frames
2548 0 : if ( !pFrm || pFrm->IsColumnFrm() )
2549 0 : return nRet;
2550 :
2551 0 : while ( pFrm )
2552 : {
2553 0 : if ( pFrm->IsSctFrm() )
2554 : {
2555 0 : nMin = lcl_CalcAutoWidth( *(SwSectionFrm*)pFrm );
2556 : }
2557 0 : if ( pFrm->IsTxtFrm() )
2558 : {
2559 0 : nMin = ((SwTxtFrm*)pFrm)->CalcFitToContent();
2560 : const SvxLRSpaceItem &rSpace =
2561 0 : ((SwTxtFrm*)pFrm)->GetTxtNode()->GetSwAttrSet().GetLRSpace();
2562 0 : nMin += rSpace.GetRight() + rSpace.GetTxtLeft() + rSpace.GetTxtFirstLineOfst();
2563 : }
2564 0 : else if ( pFrm->IsTabFrm() )
2565 : {
2566 0 : const SwFmtFrmSize& rTblFmtSz = ((SwTabFrm*)pFrm)->GetTable()->GetFrmFmt()->GetFrmSize();
2567 0 : if ( USHRT_MAX == rTblFmtSz.GetSize().Width() ||
2568 0 : text::HoriOrientation::NONE == ((SwTabFrm*)pFrm)->GetFmt()->GetHoriOrient().GetHoriOrient() )
2569 : {
2570 0 : const SwPageFrm* pPage = rFrm.FindPageFrm();
2571 : // auto width table
2572 0 : nMin = pFrm->GetUpper()->IsVertical() ?
2573 0 : pPage->Prt().Height() :
2574 0 : pPage->Prt().Width();
2575 : }
2576 : else
2577 : {
2578 0 : nMin = rTblFmtSz.GetSize().Width();
2579 : }
2580 : }
2581 :
2582 0 : if ( nMin > nRet )
2583 0 : nRet = nMin;
2584 :
2585 0 : pFrm = pFrm->GetNext();
2586 : }
2587 :
2588 0 : return nRet;
2589 : }
2590 :
2591 0 : SwTwips SwFlyFrm::CalcAutoWidth() const
2592 : {
2593 0 : return lcl_CalcAutoWidth( *this );
2594 : }
2595 :
2596 : /*************************************************************************
2597 : |*
2598 : |* SwFlyFrm::GetContour()
2599 : |*
2600 : |*************************************************************************/
2601 : /// OD 16.04.2003 #i13147# - If called for paint and the <SwNoTxtFrm> contains
2602 : /// a graphic, load of intrinsic graphic has to be avoided.
2603 426 : sal_Bool SwFlyFrm::GetContour( PolyPolygon& rContour,
2604 : const sal_Bool _bForPaint ) const
2605 : {
2606 426 : sal_Bool bRet = sal_False;
2607 426 : if( GetFmt()->GetSurround().IsContour() && Lower() &&
2608 0 : Lower()->IsNoTxtFrm() )
2609 : {
2610 0 : SwNoTxtNode *pNd = (SwNoTxtNode*)((SwCntntFrm*)Lower())->GetNode();
2611 : // OD 16.04.2003 #i13147# - determine <GraphicObject> instead of <Graphic>
2612 : // in order to avoid load of graphic, if <SwNoTxtNode> contains a graphic
2613 : // node and method is called for paint.
2614 0 : const GraphicObject* pGrfObj = NULL;
2615 0 : bool bGrfObjCreated = false;
2616 0 : const SwGrfNode* pGrfNd = pNd->GetGrfNode();
2617 0 : if ( pGrfNd && _bForPaint )
2618 : {
2619 0 : pGrfObj = &(pGrfNd->GetGrfObj());
2620 : }
2621 : else
2622 : {
2623 0 : pGrfObj = new GraphicObject( pNd->GetGraphic() );
2624 0 : bGrfObjCreated = true;
2625 : }
2626 : OSL_ENSURE( pGrfObj, "SwFlyFrm::GetContour() - No Graphic/GraphicObject found at <SwNoTxtNode>." );
2627 0 : if ( pGrfObj && pGrfObj->GetType() != GRAPHIC_NONE )
2628 : {
2629 0 : if( !pNd->HasContour() )
2630 : {
2631 : // OD 16.04.2003 #i13147# - no <CreateContour> for a graphic
2632 : // during paint. Thus, return (value of <bRet> should be <sal_False>).
2633 0 : if ( pGrfNd && _bForPaint )
2634 : {
2635 : OSL_FAIL( "SwFlyFrm::GetContour() - No Contour found at <SwNoTxtNode> during paint." );
2636 0 : return bRet;
2637 : }
2638 0 : pNd->CreateContour();
2639 : }
2640 0 : pNd->GetContour( rContour );
2641 : //Der Node haelt das Polygon passend zur Originalgroesse der Grafik
2642 : //hier muss die Skalierung einkalkuliert werden.
2643 0 : SwRect aClip;
2644 0 : SwRect aOrig;
2645 0 : Lower()->Calc();
2646 0 : ((SwNoTxtFrm*)Lower())->GetGrfArea( aClip, &aOrig, false );
2647 : // OD 16.04.2003 #i13147# - copy method code <SvxContourDlg::ScaleContour(..)>
2648 : // in order to avoid that graphic has to be loaded for contour scale.
2649 : //SvxContourDlg::ScaleContour( rContour, aGrf, MAP_TWIP, aOrig.SSize() );
2650 : {
2651 0 : OutputDevice* pOutDev = Application::GetDefaultDevice();
2652 0 : const MapMode aDispMap( MAP_TWIP );
2653 0 : const MapMode aGrfMap( pGrfObj->GetPrefMapMode() );
2654 0 : const Size aGrfSize( pGrfObj->GetPrefSize() );
2655 0 : Size aOrgSize;
2656 0 : Point aNewPoint;
2657 0 : bool bPixelMap = aGrfMap.GetMapUnit() == MAP_PIXEL;
2658 :
2659 0 : if ( bPixelMap )
2660 0 : aOrgSize = pOutDev->PixelToLogic( aGrfSize, aDispMap );
2661 : else
2662 0 : aOrgSize = pOutDev->LogicToLogic( aGrfSize, aGrfMap, aDispMap );
2663 :
2664 0 : if ( aOrgSize.Width() && aOrgSize.Height() )
2665 : {
2666 0 : double fScaleX = (double) aOrig.Width() / aOrgSize.Width();
2667 0 : double fScaleY = (double) aOrig.Height() / aOrgSize.Height();
2668 :
2669 0 : for ( sal_uInt16 j = 0, nPolyCount = rContour.Count(); j < nPolyCount; j++ )
2670 : {
2671 0 : Polygon& rPoly = rContour[ j ];
2672 :
2673 0 : for ( sal_uInt16 i = 0, nCount = rPoly.GetSize(); i < nCount; i++ )
2674 : {
2675 0 : if ( bPixelMap )
2676 0 : aNewPoint = pOutDev->PixelToLogic( rPoly[ i ], aDispMap );
2677 : else
2678 0 : aNewPoint = pOutDev->LogicToLogic( rPoly[ i ], aGrfMap, aDispMap );
2679 :
2680 0 : rPoly[ i ] = Point( FRound( aNewPoint.X() * fScaleX ), FRound( aNewPoint.Y() * fScaleY ) );
2681 : }
2682 : }
2683 0 : }
2684 : }
2685 : // OD 17.04.2003 #i13147# - destroy created <GraphicObject>.
2686 0 : if ( bGrfObjCreated )
2687 : {
2688 0 : delete pGrfObj;
2689 : }
2690 0 : rContour.Move( aOrig.Left(), aOrig.Top() );
2691 0 : if( !aClip.Width() )
2692 0 : aClip.Width( 1 );
2693 0 : if( !aClip.Height() )
2694 0 : aClip.Height( 1 );
2695 0 : rContour.Clip( aClip.SVRect() );
2696 0 : rContour.Optimize(POLY_OPTIMIZE_CLOSE);
2697 0 : bRet = sal_True;
2698 : }
2699 : }
2700 426 : return bRet;
2701 : }
2702 :
2703 : // OD 2004-03-25 #i26791#
2704 1114 : const SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj() const
2705 : {
2706 1114 : return static_cast<const SwVirtFlyDrawObj*>(GetDrawObj());
2707 : }
2708 5330 : SwVirtFlyDrawObj* SwFlyFrm::GetVirtDrawObj()
2709 : {
2710 5330 : return static_cast<SwVirtFlyDrawObj*>(DrawObj());
2711 : }
2712 :
2713 : // =============================================================================
2714 : // OD 2004-03-24 #i26791# - implementation of pure virtual method declared in
2715 : // base class <SwAnchoredObject>
2716 : // =============================================================================
2717 48 : void SwFlyFrm::InvalidateObjPos()
2718 : {
2719 48 : InvalidatePos();
2720 : // #i68520#
2721 48 : InvalidateObjRectWithSpaces();
2722 48 : }
2723 :
2724 8250 : SwFrmFmt& SwFlyFrm::GetFrmFmt()
2725 : {
2726 : OSL_ENSURE( GetFmt(),
2727 : "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2728 8250 : return *GetFmt();
2729 : }
2730 8546 : const SwFrmFmt& SwFlyFrm::GetFrmFmt() const
2731 : {
2732 : OSL_ENSURE( GetFmt(),
2733 : "<SwFlyFrm::GetFrmFmt()> - missing frame format -> crash." );
2734 8546 : return *GetFmt();
2735 : }
2736 :
2737 7876 : const SwRect SwFlyFrm::GetObjRect() const
2738 : {
2739 7876 : return Frm();
2740 : }
2741 :
2742 : // #i70122#
2743 : // for Writer fly frames the bounding rectangle equals the object rectangles
2744 1274 : const SwRect SwFlyFrm::GetObjBoundRect() const
2745 : {
2746 1274 : return GetObjRect();
2747 : }
2748 :
2749 : // #i68520#
2750 246 : bool SwFlyFrm::_SetObjTop( const SwTwips _nTop )
2751 : {
2752 246 : const bool bChanged( Frm().Pos().Y() != _nTop );
2753 :
2754 246 : Frm().Pos().Y() = _nTop;
2755 :
2756 246 : return bChanged;
2757 : }
2758 82 : bool SwFlyFrm::_SetObjLeft( const SwTwips _nLeft )
2759 : {
2760 82 : const bool bChanged( Frm().Pos().X() != _nLeft );
2761 :
2762 82 : Frm().Pos().X() = _nLeft;
2763 :
2764 82 : return bChanged;
2765 : }
2766 :
2767 : /** method to assure that anchored object is registered at the correct
2768 : page frame
2769 :
2770 : OD 2004-07-02 #i28701#
2771 :
2772 : @author OD
2773 : */
2774 0 : void SwFlyFrm::RegisterAtCorrectPage()
2775 : {
2776 : // default behaviour is to do nothing.
2777 0 : }
2778 :
2779 : /** method to determine, if a <MakeAll()> on the Writer fly frame is possible
2780 :
2781 : OD 2004-05-11 #i28701#
2782 :
2783 : @author OD
2784 : */
2785 836 : bool SwFlyFrm::IsFormatPossible() const
2786 : {
2787 836 : return SwAnchoredObject::IsFormatPossible() &&
2788 836 : !IsLocked() && !IsColLocked();
2789 : }
2790 :
2791 4 : void SwFlyFrm::GetAnchoredObjects( std::list<SwAnchoredObject*>& aList, const SwFmt& rFmt )
2792 : {
2793 4 : SwIterator<SwFlyFrm,SwFmt> aIter( rFmt );
2794 8 : for( SwFlyFrm* pFlyFrm = aIter.First(); pFlyFrm; pFlyFrm = aIter.Next() )
2795 8 : aList.push_back( pFlyFrm );
2796 4 : }
2797 :
2798 13014 : const SwFlyFrmFmt * SwFlyFrm::GetFmt() const
2799 : {
2800 13014 : return static_cast< const SwFlyFrmFmt * >( GetDep() );
2801 : }
2802 :
2803 22592 : SwFlyFrmFmt * SwFlyFrm::GetFmt()
2804 : {
2805 22592 : return static_cast< SwFlyFrmFmt * >( GetDep() );
2806 : }
2807 :
2808 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|