xref: /trunk/main/sw/source/core/layout/flyincnt.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include "cntfrm.hxx"
32 #include "doc.hxx"
33 #include "flyfrm.hxx"
34 #include "frmtool.hxx"
35 #include "frmfmt.hxx"
36 #include "hints.hxx"
37 #include <fmtornt.hxx>
38 #include <fmtfsize.hxx>
39 #include "txtfrm.hxx"       //fuer IsLocked()
40 #include "flyfrms.hxx"
41 // OD 2004-01-19 #110582#
42 #include <dflyobj.hxx>
43 
44 //aus FlyCnt.cxx
45 void DeepCalc( const SwFrm *pFrm );
46 
47 /*************************************************************************
48 |*
49 |*  SwFlyInCntFrm::SwFlyInCntFrm(), ~SwFlyInCntFrm()
50 |*
51 |*  Ersterstellung      MA 01. Dec. 92
52 |*  Letzte Aenderung    MA 09. Apr. 99
53 |*
54 |*************************************************************************/
55 SwFlyInCntFrm::SwFlyInCntFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
56     SwFlyFrm( pFmt, pSib, pAnch )
57 {
58     bInCnt = bInvalidLayout = bInvalidCntnt = sal_True;
59     SwTwips nRel = pFmt->GetVertOrient().GetPos();
60     // OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
61     Point aRelPos;
62     if( pAnch && pAnch->IsVertical() )
63         aRelPos.X() = pAnch->IsReverse() ? nRel : -nRel;
64     else
65         aRelPos.Y() = nRel;
66     SetCurrRelPos( aRelPos );
67 }
68 
69 SwFlyInCntFrm::~SwFlyInCntFrm()
70 {
71     //und Tschuess.
72     if ( !GetFmt()->GetDoc()->IsInDtor() && GetAnchorFrm() )
73     {
74         SwRect aTmp( GetObjRectWithSpaces() );
75         SwFlyInCntFrm::NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_LEAVE );
76     }
77 }
78 
79 // --> OD 2004-06-29 #i28701#
80 TYPEINIT1(SwFlyInCntFrm,SwFlyFrm);
81 // <--
82 /*************************************************************************
83 |*
84 |*  SwFlyInCntFrm::SetRefPoint(),
85 |*
86 |*  Ersterstellung      MA 01. Dec. 92
87 |*  Letzte Aenderung    MA 06. Aug. 95
88 |*
89 |*************************************************************************/
90 void SwFlyInCntFrm::SetRefPoint( const Point& rPoint,
91                                  const Point& rRelAttr,
92                                  const Point& rRelPos )
93 {
94     // OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
95     ASSERT( rPoint != aRef || rRelAttr != GetCurrRelPos(), "SetRefPoint: no change" );
96     SwFlyNotify *pNotify = NULL;
97     // No notify at a locked fly frame, if a fly frame is locked, there's
98     // already a SwFlyNotify object on the stack (MakeAll).
99     if( !IsLocked() )
100         pNotify = new SwFlyNotify( this );
101     aRef = rPoint;
102     SetCurrRelPos( rRelAttr );
103     SWRECTFN( GetAnchorFrm() )
104     (Frm().*fnRect->fnSetPos)( rPoint + rRelPos );
105     // --> OD 2006-08-25 #i68520#
106     InvalidateObjRectWithSpaces();
107     // <--
108     if( pNotify )
109     {
110         InvalidatePage();
111         bValidPos = sal_False;
112         bInvalid  = sal_True;
113         Calc();
114         delete pNotify;
115     }
116 }
117 
118 /*************************************************************************
119 |*
120 |*  SwFlyInCntFrm::Modify()
121 |*
122 |*  Ersterstellung      MA 16. Dec. 92
123 |*  Letzte Aenderung    MA 02. Sep. 93
124 |*
125 |*************************************************************************/
126 void SwFlyInCntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
127 {
128     sal_Bool bCallPrepare = sal_False;
129     sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
130     if( RES_ATTRSET_CHG == nWhich )
131     {
132         if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
133             GetItemState( RES_SURROUND, sal_False ) ||
134             SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
135             GetItemState( RES_FRMMACRO, sal_False ) )
136         {
137             SwAttrSetChg aOld( *(SwAttrSetChg*)pOld );
138             SwAttrSetChg aNew( *(SwAttrSetChg*)pNew );
139 
140             aOld.ClearItem( RES_SURROUND );
141             aNew.ClearItem( RES_SURROUND );
142             aOld.ClearItem( RES_FRMMACRO );
143             aNew.ClearItem( RES_FRMMACRO );
144             if( aNew.Count() )
145             {
146                 SwFlyFrm::Modify( &aOld, &aNew );
147                 bCallPrepare = sal_True;
148             }
149         }
150         else if( ((SwAttrSetChg*)pNew)->GetChgSet()->Count())
151         {
152             SwFlyFrm::Modify( pOld, pNew );
153             bCallPrepare = sal_True;
154         }
155     }
156     else if( nWhich != RES_SURROUND && RES_FRMMACRO != nWhich )
157     {
158         SwFlyFrm::Modify( pOld, pNew );
159         bCallPrepare = sal_True;
160     }
161 
162     if ( bCallPrepare && GetAnchorFrm() )
163         AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
164 }
165 /*************************************************************************
166 |*
167 |*  SwFlyInCntFrm::Format()
168 |*
169 |*  Beschreibung:       Hier wird der Inhalt initial mit Formatiert.
170 |*  Ersterstellung      MA 16. Dec. 92
171 |*  Letzte Aenderung    MA 19. May. 93
172 |*
173 |*************************************************************************/
174 void SwFlyInCntFrm::Format( const SwBorderAttrs *pAttrs )
175 {
176     if ( !Frm().Height() )
177     {
178         Lock(); //nicht hintenherum den Anker formatieren.
179         SwCntntFrm *pCntnt = ContainsCntnt();
180         while ( pCntnt )
181         {   pCntnt->Calc();
182             pCntnt = pCntnt->GetNextCntntFrm();
183         }
184         Unlock();
185     }
186     SwFlyFrm::Format( pAttrs );
187 }
188 /*************************************************************************
189 |*
190 |*  SwFlyInCntFrm::MakeFlyPos()
191 |*
192 |*  Beschreibung        Im Unterschied zu anderen Frms wird hier nur die
193 |*      die RelPos berechnet. Die absolute Position wird ausschliesslich
194 |*      per SetAbsPos errechnet.
195 |*  Ersterstellung      MA 03. Dec. 92
196 |*  Letzte Aenderung    MA 12. Apr. 96
197 |*
198 |*************************************************************************/
199 // OD 2004-03-23 #i26791#
200 //void SwFlyInCntFrm::MakeFlyPos()
201 void SwFlyInCntFrm::MakeObjPos()
202 {
203     if ( !bValidPos )
204     {
205         bValidPos = sal_True;
206         SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
207         const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
208         //Und ggf. noch die aktuellen Werte im Format updaten, dabei darf
209         //zu diesem Zeitpunkt natuerlich kein Modify verschickt werden.
210         const bool bVert = GetAnchorFrm()->IsVertical();
211         const bool bRev = GetAnchorFrm()->IsReverse();
212         SwTwips nOld = rVert.GetPos();
213         SwTwips nAct = bVert ? -GetCurrRelPos().X() : GetCurrRelPos().Y();
214         if( bRev )
215             nAct = -nAct;
216         if( nAct != nOld )
217         {
218             SwFmtVertOrient aVert( rVert );
219             aVert.SetPos( nAct );
220             pFmt->LockModify();
221             pFmt->SetFmtAttr( aVert );
222             pFmt->UnlockModify();
223         }
224     }
225 }
226 
227 // --> OD 2004-12-02 #115759#
228 void SwFlyInCntFrm::_ActionOnInvalidation( const InvalidationType _nInvalid )
229 {
230     if ( INVALID_POS == _nInvalid || INVALID_ALL == _nInvalid )
231         AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, &GetFrmFmt() );
232 }
233 // <--
234 /*************************************************************************
235 |*
236 |*  SwFlyInCntFrm::NotifyBackground()
237 |*
238 |*  Ersterstellung      MA 03. Dec. 92
239 |*  Letzte Aenderung    MA 26. Aug. 93
240 |*
241 |*************************************************************************/
242 void SwFlyInCntFrm::NotifyBackground( SwPageFrm *, const SwRect& rRect,
243                                        PrepareHint eHint)
244 {
245     if ( eHint == PREP_FLY_ATTR_CHG )
246         AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG );
247     else
248         AnchorFrm()->Prepare( eHint, (void*)&rRect );
249 }
250 
251 /*************************************************************************
252 |*
253 |*  SwFlyInCntFrm::GetRelPos()
254 |*
255 |*  Ersterstellung      MA 04. Dec. 92
256 |*  Letzte Aenderung    MA 04. Dec. 92
257 |*
258 |*************************************************************************/
259 const Point SwFlyInCntFrm::GetRelPos() const
260 {
261     Calc();
262     return GetCurrRelPos();
263 }
264 
265 /*************************************************************************
266 |*
267 |*  SwFlyInCntFrm::RegistFlys()
268 |*
269 |*  Ersterstellung      MA 26. Nov. 93
270 |*  Letzte Aenderung    MA 26. Nov. 93
271 |*
272 |*************************************************************************/
273 void SwFlyInCntFrm::RegistFlys()
274 {
275     // vgl. SwRowFrm::RegistFlys()
276     SwPageFrm *pPage = FindPageFrm();
277     ASSERT( pPage, "Flys ohne Seite anmelden?" );
278     ::RegistFlys( pPage, this );
279 }
280 
281 /*************************************************************************
282 |*
283 |*  SwFlyInCntFrm::MakeAll()
284 |*
285 |*  Ersterstellung      MA 18. Feb. 94
286 |*  Letzte Aenderung    MA 13. Jun. 96
287 |*
288 |*************************************************************************/
289 void SwFlyInCntFrm::MakeAll()
290 {
291     // OD 2004-01-19 #110582#
292     if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
293     {
294         return;
295     }
296 
297     if ( !GetAnchorFrm() || IsLocked() || IsColLocked() || !FindPageFrm() )
298         return;
299 
300     Lock(); //Der Vorhang faellt
301 
302         //uebernimmt im DTor die Benachrichtigung
303     const SwFlyNotify aNotify( this );
304     SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
305     const SwBorderAttrs &rAttrs = *aAccess.Get();
306 
307     if ( IsClipped() )
308         bValidSize = bHeightClipped = bWidthClipped = sal_False;
309 
310     while ( !bValidPos || !bValidSize || !bValidPrtArea )
311     {
312         //Nur einstellen wenn das Flag gesetzt ist!!
313         if ( !bValidSize )
314         {
315             bValidPrtArea = sal_False;
316 /*
317             // This is also done in the Format function, so I think
318             // this code is not necessary anymore:
319             long nOldWidth = aFrm.Width();
320             const Size aRelSize( CalcRel( rFrmSz ) );
321             aFrm.Width( aRelSize.Width() );
322 
323             if ( aFrm.Width() > nOldWidth )
324                 //Damit sich der Inhalt anpasst
325                 aFrm.Height( aRelSize.Height() );
326 */
327         }
328 
329         if ( !bValidPrtArea )
330             MakePrtArea( rAttrs );
331 
332         if ( !bValidSize )
333             Format( &rAttrs );
334 
335         if ( !bValidPos )
336         {
337             // OD 2004-03-23 #i26791#
338             //MakeFlyPos();
339             MakeObjPos();
340         }
341 
342         // --> OD 2006-04-13 #b6402800#
343         // re-activate clipping of as-character anchored Writer fly frames
344         // depending on compatibility option <ClipAsCharacterAnchoredWriterFlyFrames>
345         if ( bValidPos && bValidSize &&
346              GetFmt()->getIDocumentSettingAccess()->get( IDocumentSettingAccess::CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME ) )
347         {
348             SwFrm* pFrm = AnchorFrm();
349             if ( Frm().Left() == (pFrm->Frm().Left()+pFrm->Prt().Left()) &&
350                  Frm().Width() > pFrm->Prt().Width() )
351             {
352                 Frm().Width( pFrm->Prt().Width() );
353                 bValidPrtArea = sal_False;
354                 bWidthClipped = sal_True;
355             }
356         }
357         // <--
358     }
359     Unlock();
360 }
361 
362