1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 #include <anchoreddrawobject.hxx>
27 #include <svx/svdobj.hxx>
28 #include <dcontact.hxx>
29 #include <rootfrm.hxx>
30 #include <pagefrm.hxx>
31 #include <cntfrm.hxx>
32 #include <doc.hxx>
33 #include <tocntntanchoredobjectposition.hxx>
34 #include <tolayoutanchoredobjectposition.hxx>
35 #include <frmtool.hxx>
36 #include <fmtornt.hxx>
37 // --> OD 2004-08-12 #i32795#
38 #include <txtfrm.hxx>
39 // <--
40 // --> OD 2004-08-12 #i32795#
41 // template class <std::vector>
42 #include <vector>
43 // <--
44
45 // --> OD 2004-08-10 #i28749#
46 #include <com/sun/star/text/PositionLayoutDir.hpp>
47 // <--
48 // --> OD 2005-03-09 #i44559#
49 #include <ndtxt.hxx>
50 // <--
51
52 using namespace ::com::sun::star;
53
54 // ============================================================================
55 // helper class for correct notification due to the positioning of
56 // the anchored drawing object
57 // ============================================================================
58 class SwPosNotify
59 {
60 private:
61 SwAnchoredDrawObject* mpAnchoredDrawObj;
62 SwRect maOldObjRect;
63 SwPageFrm* mpOldPageFrm;
64
65 public:
66 SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj );
67 ~SwPosNotify();
68 // --> OD 2004-08-12 #i32795#
69 Point LastObjPos() const;
70 // <--
71 };
72
SwPosNotify(SwAnchoredDrawObject * _pAnchoredDrawObj)73 SwPosNotify::SwPosNotify( SwAnchoredDrawObject* _pAnchoredDrawObj ) :
74 mpAnchoredDrawObj( _pAnchoredDrawObj )
75 {
76 maOldObjRect = mpAnchoredDrawObj->GetObjRect();
77 // --> OD 2004-10-20 #i35640# - determine correct page frame
78 mpOldPageFrm = mpAnchoredDrawObj->GetPageFrm();
79 // <--
80 }
81
~SwPosNotify()82 SwPosNotify::~SwPosNotify()
83 {
84 if ( maOldObjRect != mpAnchoredDrawObj->GetObjRect() )
85 {
86 if( maOldObjRect.HasArea() && mpOldPageFrm )
87 {
88 mpAnchoredDrawObj->NotifyBackground( mpOldPageFrm, maOldObjRect,
89 PREP_FLY_LEAVE );
90 }
91 SwRect aNewObjRect( mpAnchoredDrawObj->GetObjRect() );
92 if( aNewObjRect.HasArea() )
93 {
94 // --> OD 2004-10-20 #i35640# - determine correct page frame
95 SwPageFrm* pNewPageFrm = mpAnchoredDrawObj->GetPageFrm();
96 // <--
97 if( pNewPageFrm )
98 mpAnchoredDrawObj->NotifyBackground( pNewPageFrm, aNewObjRect,
99 PREP_FLY_ARRIVE );
100 }
101
102 ::ClrContourCache( mpAnchoredDrawObj->GetDrawObj() );
103
104 // --> OD 2004-10-20 #i35640# - additional notify anchor text frame
105 // Needed for negative positioned drawing objects
106 // --> OD 2005-03-01 #i43255# - refine condition to avoid unneeded
107 // invalidations: anchored object had to be on the page of its anchor
108 // text frame.
109 if ( mpAnchoredDrawObj->GetAnchorFrm()->IsTxtFrm() &&
110 mpOldPageFrm == mpAnchoredDrawObj->GetAnchorFrm()->FindPageFrm() )
111 {
112 mpAnchoredDrawObj->AnchorFrm()->Prepare( PREP_FLY_LEAVE );
113 }
114 // <--
115
116 // indicate a restart of the layout process
117 mpAnchoredDrawObj->SetRestartLayoutProcess( true );
118 }
119 else
120 {
121 // lock position
122 mpAnchoredDrawObj->LockPosition();
123
124 if ( !mpAnchoredDrawObj->ConsiderForTextWrap() )
125 {
126 // indicate that object has to be considered for text wrap
127 mpAnchoredDrawObj->SetConsiderForTextWrap( true );
128 // invalidate 'background' in order to allow its 'background'
129 // to wrap around it.
130 mpAnchoredDrawObj->NotifyBackground( mpAnchoredDrawObj->GetPageFrm(),
131 mpAnchoredDrawObj->GetObjRectWithSpaces(),
132 PREP_FLY_ARRIVE );
133 // invalidate position of anchor frame in order to force
134 // a re-format of the anchor frame, which also causes a
135 // re-format of the invalid previous frames of the anchor frame.
136 mpAnchoredDrawObj->AnchorFrm()->InvalidatePos();
137 }
138 }
139 }
140
141 // --> OD 2004-08-12 #i32795#
LastObjPos() const142 Point SwPosNotify::LastObjPos() const
143 {
144 return maOldObjRect.Pos();
145 }
146 //<--
147
148 // ============================================================================
149 // OD 2004-08-12 #i32795#
150 // helper class for oscillation control on object positioning
151 // ============================================================================
152 class SwObjPosOscillationControl
153 {
154 private:
155 sal_uInt8 mnPosStackSize;
156
157 const SwAnchoredDrawObject* mpAnchoredDrawObj;
158
159 std::vector<Point*> maObjPositions;
160
161 public:
162 SwObjPosOscillationControl( const SwAnchoredDrawObject& _rAnchoredDrawObj );
163 ~SwObjPosOscillationControl();
164
165 bool OscillationDetected();
166 };
167
SwObjPosOscillationControl(const SwAnchoredDrawObject & _rAnchoredDrawObj)168 SwObjPosOscillationControl::SwObjPosOscillationControl(
169 const SwAnchoredDrawObject& _rAnchoredDrawObj )
170 : mnPosStackSize( 20 ),
171 mpAnchoredDrawObj( &_rAnchoredDrawObj )
172 {
173 }
174
~SwObjPosOscillationControl()175 SwObjPosOscillationControl::~SwObjPosOscillationControl()
176 {
177 while ( !maObjPositions.empty() )
178 {
179 Point* pPos = maObjPositions.back();
180 delete pPos;
181
182 maObjPositions.pop_back();
183 }
184 }
185
OscillationDetected()186 bool SwObjPosOscillationControl::OscillationDetected()
187 {
188 bool bOscillationDetected = false;
189
190 if ( maObjPositions.size() == mnPosStackSize )
191 {
192 // position stack is full -> oscillation
193 bOscillationDetected = true;
194 }
195 else
196 {
197 Point* pNewObjPos = new Point( mpAnchoredDrawObj->GetObjRect().Pos() );
198 for ( std::vector<Point*>::iterator aObjPosIter = maObjPositions.begin();
199 aObjPosIter != maObjPositions.end();
200 ++aObjPosIter )
201 {
202 if ( *(pNewObjPos) == *(*aObjPosIter) )
203 {
204 // position already occured -> oscillation
205 bOscillationDetected = true;
206 delete pNewObjPos;
207 break;
208 }
209 }
210 if ( !bOscillationDetected )
211 {
212 maObjPositions.push_back( pNewObjPos );
213 }
214 }
215
216 return bOscillationDetected;
217 }
218
219 // ============================================================================
220 // implementation of class <SwAnchoredDrawObject>
221 // ============================================================================
222 TYPEINIT1(SwAnchoredDrawObject,SwAnchoredObject);
223
SwAnchoredDrawObject()224 SwAnchoredDrawObject::SwAnchoredDrawObject() :
225 SwAnchoredObject(),
226 mbValidPos( false ),
227 // --> OD 2004-09-29 #i34748#
228 mpLastObjRect( 0L ),
229 // <--
230 mbNotYetAttachedToAnchorFrame( true ),
231 // --> OD 2004-08-09 #i28749#
232 mbNotYetPositioned( true ),
233 // <--
234 // --> OD 2006-03-17 #i62875#
235 mbCaptureAfterLayoutDirChange( false )
236 // <--
237 {
238 }
239
~SwAnchoredDrawObject()240 SwAnchoredDrawObject::~SwAnchoredDrawObject()
241 {
242 // --> OD 2004-11-03 - follow-up of #i34748#
243 delete mpLastObjRect;
244 // <--
245 }
246
247 // --> OD 2006-03-17 #i62875#
UpdateLayoutDir()248 void SwAnchoredDrawObject::UpdateLayoutDir()
249 {
250 SwFrmFmt::tLayoutDir nOldLayoutDir( GetFrmFmt().GetLayoutDir() );
251
252 SwAnchoredObject::UpdateLayoutDir();
253
254 if ( !NotYetPositioned() &&
255 GetFrmFmt().GetLayoutDir() != nOldLayoutDir &&
256 GetFrmFmt().GetDoc()->get(IDocumentSettingAccess::DO_NOT_CAPTURE_DRAW_OBJS_ON_PAGE) &&
257 !IsOutsidePage() )
258 {
259 mbCaptureAfterLayoutDirChange = true;
260 }
261 }
262 // <--
263
264 // --> OD 2006-03-17 #i62875#
IsOutsidePage() const265 bool SwAnchoredDrawObject::IsOutsidePage() const
266 {
267 bool bOutsidePage( false );
268
269 if ( !NotYetPositioned() && GetPageFrm() )
270 {
271 SwRect aTmpRect( GetObjRect() );
272 bOutsidePage =
273 ( aTmpRect.Intersection( GetPageFrm()->Frm() ) != GetObjRect() );
274 }
275
276 return bOutsidePage;
277 }
278 // <--
279
280 // =============================================================================
281 // OD 2004-03-25 #i26791# - implementation of pure virtual method declared in
282 // base class <SwAnchoredObject>
283 // =============================================================================
MakeObjPos()284 void SwAnchoredDrawObject::MakeObjPos()
285 {
286 if ( IsPositioningInProgress() )
287 {
288 // nothind to do - positioning already in progress
289 return;
290 }
291
292 if ( mbValidPos )
293 {
294 // nothing to do - position is valid
295 return;
296 }
297
298 // --> OD 2004-08-09 #i28749# - anchored drawing object has to be attached
299 // to anchor frame
300 if ( mbNotYetAttachedToAnchorFrame )
301 {
302 ASSERT( false,
303 "<SwAnchoredDrawObject::MakeObjPos() - drawing object not yet attached to anchor frame -> no positioning" );
304 return;
305 }
306
307 SwDrawContact* pDrawContact =
308 static_cast<SwDrawContact*>(::GetUserCall( GetDrawObj() ));
309
310 // --> OD 2004-08-09 #i28749# - if anchored drawing object hasn't been yet
311 // positioned, convert its positioning attributes, if its positioning
312 // attributes are given in horizontal left-to-right layout.
313 // --> OD 2004-10-25 #i36010# - Note: horizontal left-to-right layout is made
314 // the default layout direction for <SwDrawFrmFmt> instances. Thus, it has
315 // to be adjusted manually, if no adjustment of the positioning attributes
316 // have to be performed here.
317 // --> OD 2004-11-17 #i35635# - additionally move drawing object to the
318 // visible layer.
319 if ( mbNotYetPositioned )
320 {
321 // --> OD 2004-11-17 #i35635#
322 pDrawContact->MoveObjToVisibleLayer( DrawObj() );
323 // <--
324 // --> OD 2004-09-29 #117975# - perform conversion of positioning
325 // attributes only for 'master' drawing objects
326 // --> OD 2005-03-11 #i44334#, #i44681# - check, if positioning
327 // attributes already have been set.
328 if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
329 !static_cast<SwDrawFrmFmt&>(GetFrmFmt()).IsPosAttrSet() )
330 {
331 _SetPositioningAttr();
332 }
333 // <--
334 // --> OD 2006-05-24 #b6418964#
335 // - reset internal flag after all needed actions are performed to
336 // avoid callbacks from drawing layer
337 mbNotYetPositioned = false;
338 // <--
339 }
340 // <--
341
342 // indicate that positioning is in progress
343 {
344 SwObjPositioningInProgress aObjPosInProgress( *this );
345
346 // determine relative position of drawing object and set it
347 switch ( pDrawContact->GetAnchorId() )
348 {
349 case FLY_AS_CHAR:
350 {
351 // indicate that position will be valid after positioning is performed
352 mbValidPos = true;
353 // nothing to do, because as-character anchored objects are positioned
354 // during the format of its anchor frame - see <SwFlyCntPortion::SetBase(..)>
355 }
356 break;
357 case FLY_AT_PARA:
358 case FLY_AT_CHAR:
359 {
360 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
361 // helper method <_MakeObjPosAnchoredAtPara()>
362 _MakeObjPosAnchoredAtPara();
363 }
364 break;
365 case FLY_AT_PAGE:
366 case FLY_AT_FLY:
367 {
368 // --> OD 2004-08-12 #i32795# - move intrinsic positioning to
369 // helper method <_MakeObjPosAnchoredAtLayout()>
370 _MakeObjPosAnchoredAtLayout();
371 }
372 break;
373 default:
374 {
375 ASSERT( false, "<SwAnchoredDrawObject::MakeObjPos()> - unknown anchor type - please inform OD." );
376 }
377 }
378
379 // keep, current object rectangle
380 // --> OD 2004-09-29 #i34748# - use new method <SetLastObjRect(..)>
381 SetLastObjRect( GetObjRect().SVRect() );
382 // <--
383
384 // Assure for 'master' drawing object, that it's registered at the correct page.
385 // Perform check not for as-character anchored drawing objects and only if
386 // the anchor frame is valid.
387 if ( !GetDrawObj()->ISA(SwDrawVirtObj) &&
388 !pDrawContact->ObjAnchoredAsChar() &&
389 GetAnchorFrm()->IsValid() )
390 {
391 pDrawContact->ChkPage();
392 }
393 }
394
395 // --> OD 2006-03-17 #i62875#
396 if ( mbCaptureAfterLayoutDirChange &&
397 GetPageFrm() )
398 {
399 SwRect aPageRect( GetPageFrm()->Frm() );
400 SwRect aObjRect( GetObjRect() );
401 if ( aObjRect.Right() >= aPageRect.Right() + 10 )
402 {
403 Size aSize( aPageRect.Right() - aObjRect.Right(), 0 );
404 DrawObj()->Move( aSize );
405 aObjRect = GetObjRect();
406 }
407
408 if ( aObjRect.Left() + 10 <= aPageRect.Left() )
409 {
410 Size aSize( aPageRect.Left() - aObjRect.Left(), 0 );
411 DrawObj()->Move( aSize );
412 }
413
414 mbCaptureAfterLayoutDirChange = false;
415 }
416 // <--
417 }
418
419 /** method for the intrinsic positioning of a at-paragraph|at-character
420 anchored drawing object
421
422 OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>
423
424 @author OD
425 */
_MakeObjPosAnchoredAtPara()426 void SwAnchoredDrawObject::_MakeObjPosAnchoredAtPara()
427 {
428 // --> OD 2004-08-12 #i32795# - adopt positioning algorithm from Writer
429 // fly frames, which are anchored at paragraph|at character
430
431 // Determine, if anchor frame can/has to be formatted.
432 // If yes, after each object positioning the anchor frame is formatted.
433 // If after the anchor frame format the object position isn't valid, the
434 // object is positioned again.
435 // --> OD 2005-02-22 #i43255# - refine condition: anchor frame format not
436 // allowed, if another anchored object, has to be consider its wrap influence
437 // --> OD 2005-06-07 #i50356# - format anchor frame containing the anchor
438 // position. E.g., for at-character anchored object this can be the follow
439 // frame of the anchor frame, which contains the anchor character.
440 const bool bFormatAnchor =
441 !static_cast<const SwTxtFrm*>( GetAnchorFrmContainingAnchPos() )->IsAnyJoinLocked() &&
442 !ConsiderObjWrapInfluenceOnObjPos() &&
443 !ConsiderObjWrapInfluenceOfOtherObjs();
444 // <--
445
446 if ( bFormatAnchor )
447 {
448 // --> OD 2005-06-07 #i50356#
449 GetAnchorFrmContainingAnchPos()->Calc();
450 // <--
451 }
452
453 bool bOscillationDetected = false;
454 SwObjPosOscillationControl aObjPosOscCtrl( *this );
455 // --> OD 2004-08-25 #i3317# - boolean, to apply temporarly the
456 // 'straightforward positioning process' for the frame due to its
457 // overlapping with a previous column.
458 bool bConsiderWrapInfluenceDueToOverlapPrevCol( false );
459 // <--
460 do {
461 // indicate that position will be valid after positioning is performed
462 mbValidPos = true;
463
464 // --> OD 2004-10-20 #i35640# - correct scope for <SwPosNotify> instance
465 {
466 // create instance of <SwPosNotify> for correct notification
467 SwPosNotify aPosNotify( this );
468
469 // determine and set position
470 objectpositioning::SwToCntntAnchoredObjectPosition
471 aObjPositioning( *DrawObj() );
472 aObjPositioning.CalcPosition();
473
474 // get further needed results of the positioning algorithm
475 SetVertPosOrientFrm ( aObjPositioning.GetVertPosOrientFrm() );
476 _SetDrawObjAnchor();
477
478 // check for object position oscillation, if position has changed.
479 if ( GetObjRect().Pos() != aPosNotify.LastObjPos() )
480 {
481 bOscillationDetected = aObjPosOscCtrl.OscillationDetected();
482 }
483 }
484 // <--
485 // format anchor frame, if requested.
486 // Note: the format of the anchor frame can cause the object position
487 // to be invalid.
488 if ( bFormatAnchor )
489 {
490 // --> OD 2005-06-07 #i50356#
491 GetAnchorFrmContainingAnchPos()->Calc();
492 // <--
493 }
494
495 // --> OD 2004-08-25 #i3317#
496 if ( !ConsiderObjWrapInfluenceOnObjPos() &&
497 OverlapsPrevColumn() )
498 {
499 bConsiderWrapInfluenceDueToOverlapPrevCol = true;
500 }
501 // <--
502 } while ( !mbValidPos && !bOscillationDetected &&
503 !bConsiderWrapInfluenceDueToOverlapPrevCol );
504
505 // --> OD 2004-08-25 #i3317# - consider a detected oscillation and overlapping
506 // with previous column.
507 // temporarly consider the anchored objects wrapping style influence
508 if ( bOscillationDetected || bConsiderWrapInfluenceDueToOverlapPrevCol )
509 {
510 SetTmpConsiderWrapInfluence( true );
511 SetRestartLayoutProcess( true );
512 }
513 // <--
514 }
515
516 /** method for the intrinsic positioning of a at-page|at-frame anchored
517 drawing object
518
519 OD 2004-08-12 #i32795# - helper method for method <MakeObjPos>
520
521 @author OD
522 */
_MakeObjPosAnchoredAtLayout()523 void SwAnchoredDrawObject::_MakeObjPosAnchoredAtLayout()
524 {
525 // indicate that position will be valid after positioning is performed
526 mbValidPos = true;
527
528 // create instance of <SwPosNotify> for correct notification
529 SwPosNotify aPosNotify( this );
530
531 // determine position
532 objectpositioning::SwToLayoutAnchoredObjectPosition
533 aObjPositioning( *DrawObj() );
534 aObjPositioning.CalcPosition();
535
536 // set position
537
538 // --> OD 2004-07-29 #i31698#
539 // --> OD 2004-10-18 #i34995# - setting anchor position needed for filters,
540 // especially for the xml-filter to the OpenOffice.org file format
541 {
542 const Point aNewAnchorPos =
543 GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
544 DrawObj()->SetAnchorPos( aNewAnchorPos );
545 // --> OD 2006-10-05 #i70122# - missing invalidation
546 InvalidateObjRectWithSpaces();
547 // <--
548 }
549 // <--
550 SetCurrRelPos( aObjPositioning.GetRelPos() );
551 const SwFrm* pAnchorFrm = GetAnchorFrm();
552 SWRECTFN( pAnchorFrm );
553 const Point aAnchPos( (pAnchorFrm->Frm().*fnRect->fnGetPos)() );
554 SetObjLeft( aAnchPos.X() + GetCurrRelPos().X() );
555 SetObjTop( aAnchPos.Y() + GetCurrRelPos().Y() );
556 // <--
557 }
558
_SetDrawObjAnchor()559 void SwAnchoredDrawObject::_SetDrawObjAnchor()
560 {
561 // new anchor position
562 // --> OD 2004-07-29 #i31698# -
563 Point aNewAnchorPos =
564 GetAnchorFrm()->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
565 Point aCurrAnchorPos = GetDrawObj()->GetAnchorPos();
566 if ( aNewAnchorPos != aCurrAnchorPos )
567 {
568 // determine movement to be applied after setting the new anchor position
569 Size aMove( aCurrAnchorPos.X() - aNewAnchorPos.X(),
570 aCurrAnchorPos.Y() - aNewAnchorPos.Y() );
571 // set new anchor position
572 DrawObj()->SetAnchorPos( aNewAnchorPos );
573 // correct object position, caused by setting new anchor position
574 DrawObj()->Move( aMove );
575 // --> OD 2006-10-05 #i70122# - missing invalidation
576 InvalidateObjRectWithSpaces();
577 // <--
578 }
579 }
580
581 /** method to invalidate the given page frame
582
583 OD 2004-07-02 #i28701#
584
585 @author OD
586 */
_InvalidatePage(SwPageFrm * _pPageFrm)587 void SwAnchoredDrawObject::_InvalidatePage( SwPageFrm* _pPageFrm )
588 {
589 if ( _pPageFrm && !_pPageFrm->GetFmt()->GetDoc()->IsInDtor() )
590 {
591 if ( _pPageFrm->GetUpper() )
592 {
593 // --> OD 2004-11-11 #i35007# - correct invalidation for as-character
594 // anchored objects.
595 if ( GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR )
596 {
597 _pPageFrm->InvalidateFlyInCnt();
598 }
599 else
600 {
601 _pPageFrm->InvalidateFlyLayout();
602 }
603 // <--
604
605 SwRootFrm* pRootFrm = static_cast<SwRootFrm*>(_pPageFrm->GetUpper());
606 pRootFrm->DisallowTurbo();
607 if ( pRootFrm->GetTurbo() )
608 {
609 const SwCntntFrm* pTmpFrm = pRootFrm->GetTurbo();
610 pRootFrm->ResetTurbo();
611 pTmpFrm->InvalidatePage();
612 }
613 pRootFrm->SetIdleFlags();
614 }
615 }
616 }
617
InvalidateObjPos()618 void SwAnchoredDrawObject::InvalidateObjPos()
619 {
620 // --> OD 2004-07-01 #i28701# - check, if invalidation is allowed
621 if ( mbValidPos &&
622 InvalidationOfPosAllowed() )
623 {
624 mbValidPos = false;
625 // --> OD 2006-08-10 #i68520#
626 InvalidateObjRectWithSpaces();
627 // <--
628
629 // --> OD 2005-03-08 #i44339# - check, if anchor frame exists.
630 if ( GetAnchorFrm() )
631 {
632 // --> OD 2004-11-22 #118547# - notify anchor frame of as-character
633 // anchored object, because its positioned by the format of its anchor frame.
634 // --> OD 2005-03-09 #i44559# - assure, that text hint is already
635 // existing in the text frame
636 if ( GetAnchorFrm()->ISA(SwTxtFrm) &&
637 (GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AS_CHAR) )
638 {
639 SwTxtFrm* pAnchorTxtFrm( static_cast<SwTxtFrm*>(AnchorFrm()) );
640 if ( pAnchorTxtFrm->GetTxtNode()->GetpSwpHints() &&
641 pAnchorTxtFrm->CalcFlyPos( &GetFrmFmt() ) != STRING_LEN )
642 {
643 AnchorFrm()->Prepare( PREP_FLY_ATTR_CHG, &GetFrmFmt() );
644 }
645 }
646 // <--
647
648 SwPageFrm* pPageFrm = AnchorFrm()->FindPageFrm();
649 _InvalidatePage( pPageFrm );
650
651 // --> OD 2004-08-12 #i32270# - also invalidate page frame, at which the
652 // drawing object is registered at.
653 SwPageFrm* pPageFrmRegisteredAt = GetPageFrm();
654 if ( pPageFrmRegisteredAt &&
655 pPageFrmRegisteredAt != pPageFrm )
656 {
657 _InvalidatePage( pPageFrmRegisteredAt );
658 }
659 // <--
660 // --> OD 2004-09-23 #i33751#, #i34060# - method <GetPageFrmOfAnchor()>
661 // is replaced by method <FindPageFrmOfAnchor()>. It's return value
662 // have to be checked.
663 SwPageFrm* pPageFrmOfAnchor = FindPageFrmOfAnchor();
664 if ( pPageFrmOfAnchor &&
665 pPageFrmOfAnchor != pPageFrm &&
666 pPageFrmOfAnchor != pPageFrmRegisteredAt )
667 // <--
668 {
669 _InvalidatePage( pPageFrmOfAnchor );
670 }
671 }
672 // <--
673 }
674 }
675
GetFrmFmt()676 SwFrmFmt& SwAnchoredDrawObject::GetFrmFmt()
677 {
678 ASSERT( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt(),
679 "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
680 return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt());
681 }
GetFrmFmt() const682 const SwFrmFmt& SwAnchoredDrawObject::GetFrmFmt() const
683 {
684 ASSERT( static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt(),
685 "<SwAnchoredDrawObject::GetFrmFmt()> - missing frame format -> crash." );
686 return *(static_cast<SwDrawContact*>(GetUserCall(GetDrawObj()))->GetFmt());
687 }
688
GetObjRect() const689 const SwRect SwAnchoredDrawObject::GetObjRect() const
690 {
691 // use geometry of drawing object
692 //return GetDrawObj()->GetCurrentBoundRect();
693 return GetDrawObj()->GetSnapRect();
694 }
695
696 // --> OD 2006-10-05 #i70122#
GetObjBoundRect() const697 const SwRect SwAnchoredDrawObject::GetObjBoundRect() const
698 {
699 return GetDrawObj()->GetCurrentBoundRect();
700 }
701 // <--
702
703 // --> OD 2006-08-10 #i68520#
_SetObjTop(const SwTwips _nTop)704 bool SwAnchoredDrawObject::_SetObjTop( const SwTwips _nTop )
705 {
706 SwTwips nDiff = _nTop - GetObjRect().Top();
707 DrawObj()->Move( Size( 0, nDiff ) );
708
709 return nDiff != 0;
710 }
_SetObjLeft(const SwTwips _nLeft)711 bool SwAnchoredDrawObject::_SetObjLeft( const SwTwips _nLeft )
712 {
713 SwTwips nDiff = _nLeft - GetObjRect().Left();
714 DrawObj()->Move( Size( nDiff, 0 ) );
715
716 return nDiff != 0;
717 }
718 // <--
719
720 /** adjust positioning and alignment attributes for new anchor frame
721
722 OD 2004-08-24 #i33313# - add second optional parameter <_pNewObjRect>
723
724 @author OD
725 */
AdjustPositioningAttr(const SwFrm * _pNewAnchorFrm,const SwRect * _pNewObjRect)726 void SwAnchoredDrawObject::AdjustPositioningAttr( const SwFrm* _pNewAnchorFrm,
727 const SwRect* _pNewObjRect )
728 {
729 SwTwips nHoriRelPos = 0;
730 SwTwips nVertRelPos = 0;
731 const Point aAnchorPos = _pNewAnchorFrm->GetFrmAnchorPos( ::HasWrap( GetDrawObj() ) );
732 // --> OD 2004-08-24 #i33313#
733 const SwRect aObjRect( _pNewObjRect ? *_pNewObjRect : GetObjRect() );
734 // <--
735 const bool bVert = _pNewAnchorFrm->IsVertical();
736 const bool bR2L = _pNewAnchorFrm->IsRightToLeft();
737 if ( bVert )
738 {
739 nHoriRelPos = aObjRect.Top() - aAnchorPos.Y();
740 nVertRelPos = aAnchorPos.X() - aObjRect.Right();
741 }
742 else if ( bR2L )
743 {
744 nHoriRelPos = aAnchorPos.X() - aObjRect.Right();
745 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
746 }
747 else
748 {
749 nHoriRelPos = aObjRect.Left() - aAnchorPos.X();
750 nVertRelPos = aObjRect.Top() - aAnchorPos.Y();
751 }
752
753 GetFrmFmt().SetFmtAttr( SwFmtHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
754 GetFrmFmt().SetFmtAttr( SwFmtVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
755 }
756
757 // --> OD 2004-09-29 #i34748# - change return type
GetLastObjRect() const758 const Rectangle* SwAnchoredDrawObject::GetLastObjRect() const
759 {
760 return mpLastObjRect;
761 }
762 // <--
763
764 // --> OD 2004-09-29 #i34748# - change return type.
765 // If member <mpLastObjRect> is NULL, create one.
SetLastObjRect(const Rectangle & _rNewLastRect)766 void SwAnchoredDrawObject::SetLastObjRect( const Rectangle& _rNewLastRect )
767 {
768 if ( !mpLastObjRect )
769 {
770 mpLastObjRect = new Rectangle;
771 }
772 *(mpLastObjRect) = _rNewLastRect;
773 }
774 // <--
775
ObjectAttachedToAnchorFrame()776 void SwAnchoredDrawObject::ObjectAttachedToAnchorFrame()
777 {
778 // --> OD 2004-07-27 #i31698#
779 SwAnchoredObject::ObjectAttachedToAnchorFrame();
780 // <--
781
782 if ( mbNotYetAttachedToAnchorFrame )
783 {
784 mbNotYetAttachedToAnchorFrame = false;
785 }
786 }
787
788 /** method to set positioning attributes
789
790 OD 2004-10-20 #i35798#
791 During load the positioning attributes aren't set.
792 Thus, the positioning attributes are set by the current object geometry.
793 This method is also used for the conversion for drawing objects
794 (not anchored as-character) imported from OpenOffice.org file format
795 once and directly before the first positioning.
796
797 @author OD
798 */
_SetPositioningAttr()799 void SwAnchoredDrawObject::_SetPositioningAttr()
800 {
801 SwDrawContact* pDrawContact =
802 static_cast<SwDrawContact*>(GetUserCall( GetDrawObj() ));
803
804 if ( !pDrawContact->ObjAnchoredAsChar() )
805 {
806 SwRect aObjRect( GetObjRect() );
807
808 SwTwips nHoriPos = aObjRect.Left();
809 SwTwips nVertPos = aObjRect.Top();
810 // --> OD 2005-03-10 #i44334#, #i44681#
811 // perform conversion only if position is in horizontal-left-to-right-layout.
812 if ( GetFrmFmt().GetPositionLayoutDir() ==
813 text::PositionLayoutDir::PositionInHoriL2R )
814 {
815 SwFrmFmt::tLayoutDir eLayoutDir = GetFrmFmt().GetLayoutDir();
816 switch ( eLayoutDir )
817 {
818 case SwFrmFmt::HORI_L2R:
819 {
820 // nothing to do
821 }
822 break;
823 case SwFrmFmt::HORI_R2L:
824 {
825 nHoriPos = -aObjRect.Left() - aObjRect.Width();
826 }
827 break;
828 case SwFrmFmt::VERT_R2L:
829 {
830 nHoriPos = aObjRect.Top();
831 nVertPos = -aObjRect.Left() - aObjRect.Width();
832 }
833 break;
834 default:
835 {
836 ASSERT( false,
837 "<SwAnchoredDrawObject::_SetPositioningAttr()> - unsupported layout direction" );
838 }
839 }
840 }
841 // <--
842
843 // --> OD 2006-11-10 #i71182#
844 // only change position - do not lose other attributes
845 SwFmtHoriOrient aHori( GetFrmFmt().GetHoriOrient() );
846 aHori.SetPos( nHoriPos );
847 GetFrmFmt().SetFmtAttr( aHori );
848
849 SwFmtVertOrient aVert( GetFrmFmt().GetVertOrient() );
850 // --> OD 2007-01-03 #i73079# - vertical position already correct
851 // if ( aVert.GetRelationOrient() == text::RelOrientation::CHAR ||
852 // aVert.GetRelationOrient() == text::RelOrientation::TEXT_LINE )
853 // {
854 // nVertPos = -nVertPos;
855 // }
856 // <--
857 aVert.SetPos( nVertPos );
858 GetFrmFmt().SetFmtAttr( aVert );
859 // <--
860
861 // --> OD 2004-10-25 #i36010# - set layout direction of the position
862 GetFrmFmt().SetPositionLayoutDir(
863 text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
864 // <--
865 }
866 // --> OD 2007-11-29 #i65798# - also for as-character anchored objects
867 // --> OD 2005-05-10 #i45952# - indicate that position
868 // attributes are set now.
869 static_cast<SwDrawFrmFmt&>(GetFrmFmt()).PosAttrSet();
870 // <--
871 }
872
NotifyBackground(SwPageFrm * _pPageFrm,const SwRect & _rRect,PrepareHint _eHint)873 void SwAnchoredDrawObject::NotifyBackground( SwPageFrm* _pPageFrm,
874 const SwRect& _rRect,
875 PrepareHint _eHint )
876 {
877 ::Notify_Background( GetDrawObj(), _pPageFrm, _rRect, _eHint, sal_True );
878 }
879
880 /** method to assure that anchored object is registered at the correct
881 page frame
882
883 OD 2004-07-02 #i28701#
884
885 @author OD
886 */
RegisterAtCorrectPage()887 void SwAnchoredDrawObject::RegisterAtCorrectPage()
888 {
889 SwPageFrm* pPageFrm( 0L );
890 if ( GetVertPosOrientFrm() )
891 {
892 pPageFrm = const_cast<SwPageFrm*>(GetVertPosOrientFrm()->FindPageFrm());
893 }
894 if ( pPageFrm && GetPageFrm() != pPageFrm )
895 {
896 if ( GetPageFrm() )
897 GetPageFrm()->RemoveDrawObjFromPage( *this );
898 pPageFrm->AppendDrawObjToPage( *this );
899 }
900 }
901
902 // =============================================================================
903