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 "doc.hxx"
21 : #include "frmtool.hxx"
22 : #include "hints.hxx"
23 : #include <fmtornt.hxx>
24 : #include "txtfrm.hxx"
25 : #include "flyfrms.hxx"
26 : // OD 2004-01-19 #110582#
27 : #include <dflyobj.hxx>
28 :
29 : //from FlyCnt.cxx
30 : void DeepCalc( const SwFrm *pFrm );
31 :
32 557 : SwFlyInCntFrm::SwFlyInCntFrm( SwFlyFrmFmt *pFmt, SwFrm* pSib, SwFrm *pAnch ) :
33 557 : SwFlyFrm( pFmt, pSib, pAnch )
34 : {
35 557 : bInCnt = bInvalidLayout = bInvalidCntnt = sal_True;
36 557 : SwTwips nRel = pFmt->GetVertOrient().GetPos();
37 : // OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
38 557 : Point aRelPos;
39 557 : if( pAnch && pAnch->IsVertical() )
40 0 : aRelPos.setX(pAnch->IsReverse() ? nRel : -nRel);
41 : else
42 557 : aRelPos.setY(nRel);
43 557 : SetCurrRelPos( aRelPos );
44 557 : }
45 :
46 1671 : SwFlyInCntFrm::~SwFlyInCntFrm()
47 : {
48 557 : if ( !GetFmt()->GetDoc()->IsInDtor() && GetAnchorFrm() )
49 : {
50 557 : SwRect aTmp( GetObjRectWithSpaces() );
51 557 : SwFlyInCntFrm::NotifyBackground( FindPageFrm(), aTmp, PREP_FLY_LEAVE );
52 : }
53 1114 : }
54 :
55 : // #i28701#
56 28087 : TYPEINIT1(SwFlyInCntFrm,SwFlyFrm);
57 :
58 1110 : void SwFlyInCntFrm::SetRefPoint( const Point& rPoint,
59 : const Point& rRelAttr,
60 : const Point& rRelPos )
61 : {
62 : // OD 2004-05-27 #i26791# - member <aRelPos> moved to <SwAnchoredObject>
63 : OSL_ENSURE( rPoint != aRef || rRelAttr != GetCurrRelPos(), "SetRefPoint: no change" );
64 1110 : SwFlyNotify *pNotify = NULL;
65 : // No notify at a locked fly frame, if a fly frame is locked, there's
66 : // already a SwFlyNotify object on the stack (MakeAll).
67 1110 : if( !IsLocked() )
68 1110 : pNotify = new SwFlyNotify( this );
69 1110 : aRef = rPoint;
70 1110 : SetCurrRelPos( rRelAttr );
71 1110 : SWRECTFN( GetAnchorFrm() )
72 1110 : (Frm().*fnRect->fnSetPos)( rPoint + rRelPos );
73 : // #i68520#
74 1110 : InvalidateObjRectWithSpaces();
75 1110 : if( pNotify )
76 : {
77 1110 : InvalidatePage();
78 1110 : mbValidPos = sal_False;
79 1110 : bInvalid = sal_True;
80 1110 : Calc();
81 1110 : delete pNotify;
82 : }
83 1110 : }
84 :
85 107 : void SwFlyInCntFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
86 : {
87 107 : bool bCallPrepare = false;
88 107 : sal_uInt16 nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
89 107 : if( RES_ATTRSET_CHG == nWhich )
90 : {
91 92 : if( SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
92 90 : GetItemState( RES_SURROUND, false ) ||
93 44 : SFX_ITEM_SET == ((SwAttrSetChg*)pNew)->GetChgSet()->
94 44 : GetItemState( RES_FRMMACRO, false ) )
95 : {
96 2 : SwAttrSetChg aOld( *(SwAttrSetChg*)pOld );
97 4 : SwAttrSetChg aNew( *(SwAttrSetChg*)pNew );
98 :
99 2 : aOld.ClearItem( RES_SURROUND );
100 2 : aNew.ClearItem( RES_SURROUND );
101 2 : aOld.ClearItem( RES_FRMMACRO );
102 2 : aNew.ClearItem( RES_FRMMACRO );
103 2 : if( aNew.Count() )
104 : {
105 0 : SwFlyFrm::Modify( &aOld, &aNew );
106 0 : bCallPrepare = true;
107 2 : }
108 : }
109 44 : else if( ((SwAttrSetChg*)pNew)->GetChgSet()->Count())
110 : {
111 44 : SwFlyFrm::Modify( pOld, pNew );
112 44 : bCallPrepare = true;
113 : }
114 : }
115 61 : else if( nWhich != RES_SURROUND && RES_FRMMACRO != nWhich )
116 : {
117 61 : SwFlyFrm::Modify( pOld, pNew );
118 61 : bCallPrepare = true;
119 : }
120 :
121 107 : if ( bCallPrepare && GetAnchorFrm() )
122 105 : AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, GetFmt() );
123 107 : }
124 :
125 : /// Here the content gets formatted initially.
126 1132 : void SwFlyInCntFrm::Format( const SwBorderAttrs *pAttrs )
127 : {
128 1132 : if ( !Frm().Height() )
129 : {
130 0 : Lock(); //don't format the anchor on the crook.
131 0 : SwCntntFrm *pCntnt = ContainsCntnt();
132 0 : while ( pCntnt )
133 0 : { pCntnt->Calc();
134 0 : pCntnt = pCntnt->GetNextCntntFrm();
135 : }
136 0 : Unlock();
137 : }
138 1132 : SwFlyFrm::Format( pAttrs );
139 1132 : }
140 :
141 : /** Calculate object position
142 : *
143 : * @note: In contrast to other Frames, we only calculate the relative position
144 : * here. The absolute position is only calculated using SetAbsPos.
145 : **/
146 1626 : void SwFlyInCntFrm::MakeObjPos()
147 : {
148 1626 : if ( !mbValidPos )
149 : {
150 1626 : mbValidPos = sal_True;
151 1626 : SwFlyFrmFmt *pFmt = (SwFlyFrmFmt*)GetFmt();
152 1626 : const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
153 : //Update the current values in the format if needed, during this we of
154 : //course must not send any Modify.
155 1626 : const bool bVert = GetAnchorFrm()->IsVertical();
156 1626 : const bool bRev = GetAnchorFrm()->IsReverse();
157 1626 : SwTwips nOld = rVert.GetPos();
158 1626 : SwTwips nAct = bVert ? -GetCurrRelPos().X() : GetCurrRelPos().Y();
159 1626 : if( bRev )
160 0 : nAct = -nAct;
161 1626 : if( nAct != nOld )
162 : {
163 664 : SwFmtVertOrient aVert( rVert );
164 664 : aVert.SetPos( nAct );
165 664 : pFmt->LockModify();
166 664 : pFmt->SetFmtAttr( aVert );
167 664 : pFmt->UnlockModify();
168 : }
169 : }
170 1626 : }
171 :
172 : // #115759#
173 614 : void SwFlyInCntFrm::_ActionOnInvalidation( const InvalidationType _nInvalid )
174 : {
175 614 : if ( INVALID_POS == _nInvalid || INVALID_ALL == _nInvalid )
176 32 : AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, &GetFrmFmt() );
177 614 : }
178 :
179 1122 : void SwFlyInCntFrm::NotifyBackground( SwPageFrm *, const SwRect& rRect,
180 : PrepareHint eHint)
181 : {
182 1122 : if ( eHint == PREP_FLY_ATTR_CHG )
183 0 : AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG );
184 : else
185 1122 : AnchorFrm()->Prepare( eHint, (void*)&rRect );
186 1122 : }
187 :
188 200 : const Point SwFlyInCntFrm::GetRelPos() const
189 : {
190 200 : Calc();
191 200 : return GetCurrRelPos();
192 : }
193 :
194 : /// @see SwRowFrm::RegistFlys()
195 491 : void SwFlyInCntFrm::RegistFlys()
196 : {
197 491 : SwPageFrm *pPage = FindPageFrm();
198 : OSL_ENSURE( pPage, "Register Flys without pages?" );
199 491 : ::RegistFlys( pPage, this );
200 491 : }
201 :
202 2179 : void SwFlyInCntFrm::MakeAll()
203 : {
204 : // OD 2004-01-19 #110582#
205 2179 : if ( !GetFmt()->GetDoc()->IsVisibleLayerId( GetVirtDrawObj()->GetLayer() ) )
206 : {
207 0 : return;
208 : }
209 :
210 2179 : if ( !GetAnchorFrm() || IsLocked() || IsColLocked() || !FindPageFrm() )
211 0 : return;
212 :
213 2179 : Lock(); // The curtain falls
214 :
215 : //does the notification in the DTor
216 2179 : const SwFlyNotify aNotify( this );
217 4358 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), this );
218 2179 : const SwBorderAttrs &rAttrs = *aAccess.Get();
219 :
220 2179 : if ( IsClipped() )
221 0 : mbValidSize = bHeightClipped = bWidthClipped = sal_False;
222 :
223 6537 : while ( !mbValidPos || !mbValidSize || !mbValidPrtArea || !m_bValidContentPos )
224 : {
225 : //Only stop, if the flag is set!!
226 2179 : if ( !mbValidSize )
227 : {
228 1132 : mbValidPrtArea = sal_False;
229 : }
230 :
231 2179 : if ( !mbValidPrtArea )
232 : {
233 1132 : MakePrtArea( rAttrs );
234 1132 : m_bValidContentPos = false;
235 : }
236 :
237 2179 : if ( !mbValidSize )
238 1132 : Format( &rAttrs );
239 :
240 2179 : if ( !mbValidPos )
241 : {
242 1626 : MakeObjPos();
243 : }
244 :
245 2179 : if ( !m_bValidContentPos )
246 1132 : MakeContentPos( rAttrs );
247 :
248 : // re-activate clipping of as-character anchored Writer fly frames
249 : // depending on compatibility option <ClipAsCharacterAnchoredWriterFlyFrames>
250 4358 : if ( mbValidPos && mbValidSize &&
251 2179 : GetFmt()->getIDocumentSettingAccess()->get( IDocumentSettingAccess::CLIP_AS_CHARACTER_ANCHORED_WRITER_FLY_FRAME ) )
252 : {
253 0 : SwFrm* pFrm = AnchorFrm();
254 0 : if ( Frm().Left() == (pFrm->Frm().Left()+pFrm->Prt().Left()) &&
255 0 : Frm().Width() > pFrm->Prt().Width() )
256 : {
257 0 : Frm().Width( pFrm->Prt().Width() );
258 0 : mbValidPrtArea = sal_False;
259 0 : bWidthClipped = sal_True;
260 : }
261 : }
262 : }
263 4358 : Unlock();
264 : }
265 :
266 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|