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 "hintids.hxx"
27 #include <svx/svdtrans.hxx>
28 #include <editeng/protitem.hxx>
29 #include <editeng/opaqitem.hxx>
30 #include <svx/svdpage.hxx>
31
32
33 #include <fmtclds.hxx>
34 #include <fmtornt.hxx>
35 #include <fmtfsize.hxx>
36 #include <fmturl.hxx>
37 #include "viewsh.hxx"
38 #include "viewimp.hxx"
39 #include "cntfrm.hxx"
40 #include "frmatr.hxx"
41 #include "doc.hxx"
42 #include <IDocumentUndoRedo.hxx>
43 #include "dview.hxx"
44 #include "dflyobj.hxx"
45 #include "flyfrm.hxx"
46 #include "frmfmt.hxx"
47 #include "viewopt.hxx"
48 #include "frmtool.hxx"
49 #include "flyfrms.hxx"
50 #include "ndnotxt.hxx"
51 #include "grfatr.hxx"
52 #include "pagefrm.hxx"
53 #include "rootfrm.hxx"
54
55
56 using namespace ::com::sun::star;
57
58
59 // --> OD 2004-11-22 #117958#
60 #include <svx/sdr/properties/defaultproperties.hxx>
61 // <--
62 #include <basegfx/range/b2drange.hxx>
63 #include <basegfx/polygon/b2dpolygontools.hxx>
64 #include <basegfx/polygon/b2dpolygon.hxx>
65
66 // AW: For VCOfDrawVirtObj and stuff
67 #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
68 #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
69 #include <sw_primitivetypes2d.hxx>
70 #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
71
72 using namespace ::com::sun::star;
73
74 static sal_Bool bInResize = sal_False;
75
76 TYPEINIT1( SwFlyDrawObj, SdrObject )
77 TYPEINIT1( SwVirtFlyDrawObj, SdrVirtObj )
78
79 /*************************************************************************
80 |*
81 |* SwFlyDrawObj::Ctor
82 |*
83 |* Ersterstellung MA 18. Apr. 95
84 |* Letzte Aenderung MA 28. May. 96
85 |*
86 *************************************************************************/
87
88 ////////////////////////////////////////////////////////////////////////////////////////////////////
89
90 namespace sdr
91 {
92 namespace contact
93 {
94 // #i95264# currently needed since createViewIndependentPrimitive2DSequence()
95 // is called when RecalcBoundRect() is used. There should currently no VOCs being
96 // constructed since it gets not visualized (instead the corresponding SwVirtFlyDrawObj's
97 // referencing this one are visualized).
98 class VCOfSwFlyDrawObj : public ViewContactOfSdrObj
99 {
100 protected:
101 // This method is responsible for creating the graphical visualisation data
102 // ONLY based on model data
103 virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const;
104
105 public:
106 // basic constructor, used from SdrObject.
VCOfSwFlyDrawObj(SwFlyDrawObj & rObj)107 VCOfSwFlyDrawObj(SwFlyDrawObj& rObj)
108 : ViewContactOfSdrObj(rObj)
109 {
110 }
111 virtual ~VCOfSwFlyDrawObj();
112 };
113
createViewIndependentPrimitive2DSequence() const114 drawinglayer::primitive2d::Primitive2DSequence VCOfSwFlyDrawObj::createViewIndependentPrimitive2DSequence() const
115 {
116 // currently gets not visualized, return empty sequence
117 return drawinglayer::primitive2d::Primitive2DSequence();
118 }
119
~VCOfSwFlyDrawObj()120 VCOfSwFlyDrawObj::~VCOfSwFlyDrawObj()
121 {
122 }
123 } // end of namespace contact
124 } // end of namespace sdr
125
126 ////////////////////////////////////////////////////////////////////////////////////////////////////
127
CreateObjectSpecificProperties()128 sdr::properties::BaseProperties* SwFlyDrawObj::CreateObjectSpecificProperties()
129 {
130 // --> OD 2004-11-22 #117958# - create default properties
131 return new sdr::properties::DefaultProperties(*this);
132 // <--
133 }
134
CreateObjectSpecificViewContact()135 sdr::contact::ViewContact* SwFlyDrawObj::CreateObjectSpecificViewContact()
136 {
137 // #i95264# needs an own VC since createViewIndependentPrimitive2DSequence()
138 // is called when RecalcBoundRect() is used
139 return new sdr::contact::VCOfSwFlyDrawObj(*this);
140 }
141
SwFlyDrawObj()142 SwFlyDrawObj::SwFlyDrawObj()
143 {
144 }
145
~SwFlyDrawObj()146 SwFlyDrawObj::~SwFlyDrawObj()
147 {
148 }
149
150 /*************************************************************************
151 |*
152 |* SwFlyDrawObj::Factory-Methoden
153 |*
154 |* Ersterstellung MA 23. Feb. 95
155 |* Letzte Aenderung MA 23. Feb. 95
156 |*
157 *************************************************************************/
158
GetObjInventor() const159 sal_uInt32 __EXPORT SwFlyDrawObj::GetObjInventor() const
160 {
161 return SWGInventor;
162 }
163
164
GetObjIdentifier() const165 sal_uInt16 __EXPORT SwFlyDrawObj::GetObjIdentifier() const
166 {
167 return SwFlyDrawObjIdentifier;
168 }
169
170
GetObjVersion() const171 sal_uInt16 __EXPORT SwFlyDrawObj::GetObjVersion() const
172 {
173 return SwDrawFirst;
174 }
175
176 /*************************************************************************
177 |*
178 |* SwVirtFlyDrawObj::CToren, Dtor
179 |*
180 |* Ersterstellung MA 08. Dec. 94
181 |* Letzte Aenderung MA 28. May. 96
182 |*
183 *************************************************************************/
184
185 //////////////////////////////////////////////////////////////////////////////////////
186 // AW: Need own primitive to get the FlyFrame paint working
187
188 namespace drawinglayer
189 {
190 namespace primitive2d
191 {
192 class SwVirtFlyDrawObjPrimitive : public BufferedDecompositionPrimitive2D
193 {
194 private:
195 const SwVirtFlyDrawObj& mrSwVirtFlyDrawObj;
196 const basegfx::B2DRange maOuterRange;
197
198 protected:
199 // method which is to be used to implement the local decomposition of a 2D primitive
200 virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
201
202 public:
SwVirtFlyDrawObjPrimitive(const SwVirtFlyDrawObj & rSwVirtFlyDrawObj,const basegfx::B2DRange & rOuterRange)203 SwVirtFlyDrawObjPrimitive(
204 const SwVirtFlyDrawObj& rSwVirtFlyDrawObj,
205 const basegfx::B2DRange &rOuterRange)
206 : BufferedDecompositionPrimitive2D(),
207 mrSwVirtFlyDrawObj(rSwVirtFlyDrawObj),
208 maOuterRange(rOuterRange)
209 {
210 }
211
212 // compare operator
213 virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
214
215 // get range
216 virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
217
218 // overloaded to allow callbacks to wrap_DoPaintObject
219 virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
220
221 // data read access
getSwVirtFlyDrawObj() const222 const SwVirtFlyDrawObj& getSwVirtFlyDrawObj() const { return mrSwVirtFlyDrawObj; }
getOuterRange() const223 const basegfx::B2DRange& getOuterRange() const { return maOuterRange; }
224
225 // provide unique ID
226 DeclPrimitrive2DIDBlock()
227 };
228 } // end of namespace primitive2d
229 } // end of namespace drawinglayer
230
231 namespace drawinglayer
232 {
233 namespace primitive2d
234 {
create2DDecomposition(const geometry::ViewInformation2D &) const235 Primitive2DSequence SwVirtFlyDrawObjPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
236 {
237 Primitive2DSequence aRetval;
238
239 if(!getOuterRange().isEmpty())
240 {
241 // currently this SW object has no primitive representation. As long as this is the case,
242 // create invisible geometry to allow corfect HitTest and BoundRect calculations for the
243 // object. Use a filled primitive to get 'inside' as default object hit. The special cases from
244 // the old SwVirtFlyDrawObj::CheckHit implementation are handled now in SwDrawView::PickObj;
245 // this removed the 'hack' to get a view from inside model data or to react on null-tolerance
246 // as it was done in the old implementation
247 const Primitive2DReference aHitTestReference(
248 createHiddenGeometryPrimitives2D(
249 true,
250 getOuterRange()));
251
252 aRetval = Primitive2DSequence(&aHitTestReference, 1);
253 }
254
255 return aRetval;
256 }
257
operator ==(const BasePrimitive2D & rPrimitive) const258 bool SwVirtFlyDrawObjPrimitive::operator==(const BasePrimitive2D& rPrimitive) const
259 {
260 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
261 {
262 const SwVirtFlyDrawObjPrimitive& rCompare = (SwVirtFlyDrawObjPrimitive&)rPrimitive;
263
264 return (&getSwVirtFlyDrawObj() == &rCompare.getSwVirtFlyDrawObj()
265 && getOuterRange() == rCompare.getOuterRange());
266 }
267
268 return false;
269 }
270
getB2DRange(const geometry::ViewInformation2D &) const271 basegfx::B2DRange SwVirtFlyDrawObjPrimitive::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
272 {
273 return getOuterRange();
274 }
275
get2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const276 Primitive2DSequence SwVirtFlyDrawObjPrimitive::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
277 {
278 // This is the callback to keep the FlyFrame painting in SW alive as long as it
279 // is not changed to primitives. This is the method which will be called by the processors
280 // when they do not know this primitive (and they do not). Inside wrap_DoPaintObject
281 // there needs to be a test that paint is only done during SW repaints (see there).
282 // Using this mechanism guarantees the correct Z-Order of the VirtualObject-based FlyFrames.
283 getSwVirtFlyDrawObj().wrap_DoPaintObject();
284
285 // call parent
286 return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
287 }
288
289 // provide unique ID
290 ImplPrimitrive2DIDBlock(SwVirtFlyDrawObjPrimitive, PRIMITIVE2D_ID_SWVIRTFLYDRAWOBJPRIMITIVE2D)
291
292 } // end of namespace primitive2d
293 } // end of namespace drawinglayer
294
295 //////////////////////////////////////////////////////////////////////////////////////
296 // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
297 // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
298 // For paint, that offset is used by setting at the OutputDevice; for primitives this is
299 // not possible since we have no OutputDevice, but define the geometry itself.
300
301 namespace sdr
302 {
303 namespace contact
304 {
305 class VCOfSwVirtFlyDrawObj : public ViewContactOfVirtObj
306 {
307 protected:
308 // This method is responsible for creating the graphical visualisation data
309 // ONLY based on model data
310 virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const;
311
312 public:
313 // basic constructor, used from SdrObject.
VCOfSwVirtFlyDrawObj(SwVirtFlyDrawObj & rObj)314 VCOfSwVirtFlyDrawObj(SwVirtFlyDrawObj& rObj)
315 : ViewContactOfVirtObj(rObj)
316 {
317 }
318 virtual ~VCOfSwVirtFlyDrawObj();
319
320 // access to SwVirtFlyDrawObj
GetSwVirtFlyDrawObj() const321 SwVirtFlyDrawObj& GetSwVirtFlyDrawObj() const
322 {
323 return (SwVirtFlyDrawObj&)mrObject;
324 }
325 };
326 } // end of namespace contact
327 } // end of namespace sdr
328
329 namespace sdr
330 {
331 namespace contact
332 {
createViewIndependentPrimitive2DSequence() const333 drawinglayer::primitive2d::Primitive2DSequence VCOfSwVirtFlyDrawObj::createViewIndependentPrimitive2DSequence() const
334 {
335 drawinglayer::primitive2d::Primitive2DSequence xRetval;
336 const SdrObject& rReferencedObject = GetSwVirtFlyDrawObj().GetReferencedObj();
337
338 if(rReferencedObject.ISA(SwFlyDrawObj))
339 {
340 // create an own specialized primitive which is used as repaint callpoint and HitTest
341 // for HitTest processor (see primitive implementation above)
342 const basegfx::B2DRange aOuterRange(GetSwVirtFlyDrawObj().getOuterBound());
343
344 if(!aOuterRange.isEmpty())
345 {
346 const drawinglayer::primitive2d::Primitive2DReference xPrimitive(
347 new drawinglayer::primitive2d::SwVirtFlyDrawObjPrimitive(
348 GetSwVirtFlyDrawObj(),
349 aOuterRange));
350
351 xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xPrimitive, 1);
352 }
353 }
354
355 return xRetval;
356 }
357
~VCOfSwVirtFlyDrawObj()358 VCOfSwVirtFlyDrawObj::~VCOfSwVirtFlyDrawObj()
359 {
360 }
361 } // end of namespace contact
362 } // end of namespace sdr
363
364 //////////////////////////////////////////////////////////////////////////////////////
365
getOuterBound() const366 basegfx::B2DRange SwVirtFlyDrawObj::getOuterBound() const
367 {
368 basegfx::B2DRange aOuterRange;
369 const SdrObject& rReferencedObject = GetReferencedObj();
370
371 if(rReferencedObject.ISA(SwFlyDrawObj))
372 {
373 const SwFlyFrm* pFlyFrame = GetFlyFrm();
374
375 if(pFlyFrame)
376 {
377 const Rectangle aOuterRectangle(pFlyFrame->Frm().Pos(), pFlyFrame->Frm().SSize());
378
379 if(!aOuterRectangle.IsEmpty()
380 && RECT_EMPTY != aOuterRectangle.Right()
381 && RECT_EMPTY != aOuterRectangle.Bottom())
382 {
383 aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Left(), aOuterRectangle.Top()));
384 aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Right(), aOuterRectangle.Bottom()));
385 }
386 }
387 }
388
389 return aOuterRange;
390 }
391
getInnerBound() const392 basegfx::B2DRange SwVirtFlyDrawObj::getInnerBound() const
393 {
394 basegfx::B2DRange aInnerRange;
395 const SdrObject& rReferencedObject = GetReferencedObj();
396
397 if(rReferencedObject.ISA(SwFlyDrawObj))
398 {
399 const SwFlyFrm* pFlyFrame = GetFlyFrm();
400
401 if(pFlyFrame)
402 {
403 const Rectangle aInnerRectangle(pFlyFrame->Frm().Pos() + pFlyFrame->Prt().Pos(), pFlyFrame->Prt().SSize());
404
405 if(!aInnerRectangle.IsEmpty()
406 && RECT_EMPTY != aInnerRectangle.Right()
407 && RECT_EMPTY != aInnerRectangle.Bottom())
408 {
409 aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Left(), aInnerRectangle.Top()));
410 aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Right(), aInnerRectangle.Bottom()));
411 }
412 }
413 }
414
415 return aInnerRange;
416 }
417
CreateObjectSpecificViewContact()418 sdr::contact::ViewContact* SwVirtFlyDrawObj::CreateObjectSpecificViewContact()
419 {
420 // need an own ViewContact (VC) to allow creation of a specialized primitive
421 // for being able to visualize the FlyFrames in primitive renderers
422 return new sdr::contact::VCOfSwVirtFlyDrawObj(*this);
423 }
424
SwVirtFlyDrawObj(SdrObject & rNew,SwFlyFrm * pFly)425 SwVirtFlyDrawObj::SwVirtFlyDrawObj(SdrObject& rNew, SwFlyFrm* pFly) :
426 SdrVirtObj( rNew ),
427 pFlyFrm( pFly )
428 {
429 //#110094#-1
430 // bNotPersistent = bNeedColorRestore = bWriterFlyFrame = sal_True;
431 const SvxProtectItem &rP = pFlyFrm->GetFmt()->GetProtect();
432 bMovProt = rP.IsPosProtected();
433 bSizProt = rP.IsSizeProtected();
434 }
435
436
~SwVirtFlyDrawObj()437 __EXPORT SwVirtFlyDrawObj::~SwVirtFlyDrawObj()
438 {
439 if ( GetPage() ) //Der SdrPage die Verantwortung entziehen.
440 GetPage()->RemoveObject( GetOrdNum() );
441 }
442
443 /*************************************************************************
444 |*
445 |* SwVirtFlyDrawObj::GetFmt()
446 |*
447 |* Ersterstellung MA 08. Dec. 94
448 |* Letzte Aenderung MA 08. Dec. 94
449 |*
450 *************************************************************************/
451
GetFmt() const452 const SwFrmFmt *SwVirtFlyDrawObj::GetFmt() const
453 {
454 return GetFlyFrm()->GetFmt();
455 }
456
457
GetFmt()458 SwFrmFmt *SwVirtFlyDrawObj::GetFmt()
459 {
460 return GetFlyFrm()->GetFmt();
461 }
462
463 /*************************************************************************
464 |*
465 |* SwVirtFlyDrawObj::Paint()
466 |*
467 |* Ersterstellung MA 20. Dec. 94
468 |* Letzte Aenderung MA 18. Dec. 95
469 |*
470 *************************************************************************/
471
472 // --> OD #i102707#
473 namespace
474 {
475 class RestoreMapMode
476 {
477 public:
RestoreMapMode(ViewShell * pViewShell)478 explicit RestoreMapMode( ViewShell* pViewShell )
479 : mbMapModeRestored( false )
480 , mpOutDev( pViewShell->GetOut() )
481 {
482 if ( pViewShell->getPrePostMapMode() != mpOutDev->GetMapMode() )
483 {
484 mpOutDev->Push(PUSH_MAPMODE);
485
486 GDIMetaFile* pMetaFile = mpOutDev->GetConnectMetaFile();
487 if ( pMetaFile &&
488 pMetaFile->IsRecord() && !pMetaFile->IsPause() )
489 {
490 ASSERT( false,
491 "MapMode restoration during meta file creation is somehow suspect - using <SetRelativeMapMode(..)>, but not sure, if correct." )
492 mpOutDev->SetRelativeMapMode( pViewShell->getPrePostMapMode() );
493 }
494 else
495 {
496 mpOutDev->SetMapMode( pViewShell->getPrePostMapMode() );
497 }
498
499 mbMapModeRestored = true;
500 }
501 };
502
~RestoreMapMode()503 ~RestoreMapMode()
504 {
505 if ( mbMapModeRestored )
506 {
507 mpOutDev->Pop();
508 }
509 };
510
511 private:
512 bool mbMapModeRestored;
513 OutputDevice* mpOutDev;
514 };
515 }
516 // <--
517
wrap_DoPaintObject() const518 void SwVirtFlyDrawObj::wrap_DoPaintObject() const
519 {
520 ViewShell* pShell = pFlyFrm->getRootFrm()->GetCurrShell();
521
522 // Only paint when we have a current shell and a DrawingLayer paint is in progress.
523 // This avcoids evtl. problems with renderers which do processing stuff,
524 // but no paints. IsPaintInProgress() depends on SW repaint, so, as long
525 // as SW paints self and calls DrawLayer() for Heaven and Hell, this will
526 // be correct
527 if ( pShell && pShell->IsDrawingLayerPaintInProgress() )
528 {
529 sal_Bool bDrawObject(sal_True);
530
531 if ( !SwFlyFrm::IsPaint( (SdrObject*)this, pShell ) )
532 {
533 bDrawObject = sal_False;
534 }
535
536 if ( bDrawObject )
537 {
538 if ( !pFlyFrm->IsFlyInCntFrm() )
539 {
540 // it is also necessary to restore the VCL MapMode from ViewInformation since e.g.
541 // the VCL PixelRenderer resets it at the used OutputDevice. Unfortunately, this
542 // excludes shears and rotates which are not expressable in MapMode.
543 // OD #i102707#
544 // new helper class to restore MapMode - restoration, only if
545 // needed and consideration of paint for meta file creation .
546 RestoreMapMode aRestoreMapModeIfNeeded( pShell );
547
548 // paint the FlyFrame (use standard VCL-Paint)
549 pFlyFrm->Paint( GetFlyFrm()->Frm() );
550 }
551 }
552 }
553 }
554
555 /*************************************************************************
556 |*
557 |* SwVirtFlyDrawObj::TakeObjInfo()
558 |*
559 |* Ersterstellung MA 03. May. 95
560 |* Letzte Aenderung MA 03. May. 95
561 |*
562 *************************************************************************/
563
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const564 void __EXPORT SwVirtFlyDrawObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const
565 {
566 rInfo.bSelectAllowed = rInfo.bMoveAllowed =
567 rInfo.bResizeFreeAllowed = rInfo.bResizePropAllowed = sal_True;
568
569 rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed =
570 rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed =
571 rInfo.bMirror90Allowed = rInfo.bShearAllowed =
572 rInfo.bCanConvToPath = rInfo.bCanConvToPoly =
573 rInfo.bCanConvToPathLineToArea = rInfo.bCanConvToPolyLineToArea = sal_False;
574 }
575
576
577 /*************************************************************************
578 |*
579 |* SwVirtFlyDrawObj::Groessenermittlung
580 |*
581 |* Ersterstellung MA 12. Jan. 95
582 |* Letzte Aenderung MA 10. Nov. 95
583 |*
584 *************************************************************************/
585
SetRect() const586 void SwVirtFlyDrawObj::SetRect() const
587 {
588 if ( GetFlyFrm()->Frm().HasArea() )
589 ((SwVirtFlyDrawObj*)this)->aOutRect = GetFlyFrm()->Frm().SVRect();
590 else
591 ((SwVirtFlyDrawObj*)this)->aOutRect = Rectangle();
592 }
593
594
GetCurrentBoundRect() const595 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetCurrentBoundRect() const
596 {
597 SetRect();
598 return aOutRect;
599 }
600
GetLastBoundRect() const601 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetLastBoundRect() const
602 {
603 return GetCurrentBoundRect();
604 }
605
606
RecalcBoundRect()607 void __EXPORT SwVirtFlyDrawObj::RecalcBoundRect()
608 {
609 SetRect();
610 }
611
612
RecalcSnapRect()613 void __EXPORT SwVirtFlyDrawObj::RecalcSnapRect()
614 {
615 SetRect();
616 }
617
618
GetSnapRect() const619 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetSnapRect() const
620 {
621 SetRect();
622 return aOutRect;
623 }
624
625
SetSnapRect(const Rectangle &)626 void __EXPORT SwVirtFlyDrawObj::SetSnapRect(const Rectangle& )
627 {
628 Rectangle aTmp( GetLastBoundRect() );
629 SetRect();
630 SetChanged();
631 BroadcastObjectChange();
632 if (pUserCall!=NULL)
633 pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp);
634 }
635
636
NbcSetSnapRect(const Rectangle &)637 void __EXPORT SwVirtFlyDrawObj::NbcSetSnapRect(const Rectangle& )
638 {
639 SetRect();
640 }
641
642
GetLogicRect() const643 const Rectangle& __EXPORT SwVirtFlyDrawObj::GetLogicRect() const
644 {
645 SetRect();
646 return aOutRect;
647 }
648
649
SetLogicRect(const Rectangle &)650 void __EXPORT SwVirtFlyDrawObj::SetLogicRect(const Rectangle& )
651 {
652 Rectangle aTmp( GetLastBoundRect() );
653 SetRect();
654 SetChanged();
655 BroadcastObjectChange();
656 if (pUserCall!=NULL)
657 pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp);
658 }
659
660
NbcSetLogicRect(const Rectangle &)661 void __EXPORT SwVirtFlyDrawObj::NbcSetLogicRect(const Rectangle& )
662 {
663 SetRect();
664 }
665
666
TakeXorPoly() const667 ::basegfx::B2DPolyPolygon SwVirtFlyDrawObj::TakeXorPoly() const
668 {
669 const Rectangle aSourceRectangle(GetFlyFrm()->Frm().SVRect());
670 const ::basegfx::B2DRange aSourceRange(aSourceRectangle.Left(), aSourceRectangle.Top(), aSourceRectangle.Right(), aSourceRectangle.Bottom());
671 ::basegfx::B2DPolyPolygon aRetval;
672
673 aRetval.append(::basegfx::tools::createPolygonFromRect(aSourceRange));
674
675 return aRetval;
676 }
677
678 /*************************************************************************
679 |*
680 |* SwVirtFlyDrawObj::Move() und Resize()
681 |*
682 |* Ersterstellung MA 12. Jan. 95
683 |* Letzte Aenderung MA 26. Jul. 96
684 |*
685 *************************************************************************/
686
NbcMove(const Size & rSiz)687 void __EXPORT SwVirtFlyDrawObj::NbcMove(const Size& rSiz)
688 {
689 MoveRect( aOutRect, rSiz );
690 const Point aOldPos( GetFlyFrm()->Frm().Pos() );
691 const Point aNewPos( aOutRect.TopLeft() );
692 const SwRect aFlyRect( aOutRect );
693
694 //Wenn der Fly eine automatische Ausrichtung hat (rechts oder oben),
695 //so soll die Automatik erhalten bleiben
696 SwFrmFmt *pFmt = GetFlyFrm()->GetFmt();
697 const sal_Int16 eHori = pFmt->GetHoriOrient().GetHoriOrient();
698 const sal_Int16 eVert = pFmt->GetVertOrient().GetVertOrient();
699 const sal_Int16 eRelHori = pFmt->GetHoriOrient().GetRelationOrient();
700 const sal_Int16 eRelVert = pFmt->GetVertOrient().GetRelationOrient();
701 //Bei Absatzgebundenen Flys muss ausgehend von der neuen Position ein
702 //neuer Anker gesetzt werden. Anker und neue RelPos werden vom Fly selbst
703 //berechnet und gesetzt.
704 if( GetFlyFrm()->IsFlyAtCntFrm() )
705 ((SwFlyAtCntFrm*)GetFlyFrm())->SetAbsPos( aNewPos );
706 else
707 {
708 const SwFrmFmt *pTmpFmt = GetFmt();
709 const SwFmtVertOrient &rVert = pTmpFmt->GetVertOrient();
710 const SwFmtHoriOrient &rHori = pTmpFmt->GetHoriOrient();
711 long lXDiff = aNewPos.X() - aOldPos.X();
712 if( rHori.IsPosToggle() && text::HoriOrientation::NONE == eHori &&
713 !GetFlyFrm()->FindPageFrm()->OnRightPage() )
714 lXDiff = -lXDiff;
715
716 if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() &&
717 text::HoriOrientation::NONE == eHori )
718 lXDiff = -lXDiff;
719
720 long lYDiff = aNewPos.Y() - aOldPos.Y();
721 if( GetFlyFrm()->GetAnchorFrm()->IsVertical() )
722 {
723 //lXDiff -= rVert.GetPos();
724 //lYDiff += rHori.GetPos();
725 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
726 if ( GetFlyFrm()->GetAnchorFrm()->IsVertLR() )
727 {
728 lXDiff += rVert.GetPos();
729 lXDiff = -lXDiff;
730 }
731 else
732 {
733 lXDiff -= rVert.GetPos();
734 lYDiff += rHori.GetPos();
735 }
736 }
737 else
738 {
739 lXDiff += rHori.GetPos();
740 lYDiff += rVert.GetPos();
741 }
742
743 if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() &&
744 text::HoriOrientation::NONE != eHori )
745 lXDiff = GetFlyFrm()->GetAnchorFrm()->Frm().Width() -
746 aFlyRect.Width() - lXDiff;
747
748 const Point aTmp( lXDiff, lYDiff );
749 GetFlyFrm()->ChgRelPos( aTmp );
750 }
751
752 SwAttrSet aSet( pFmt->GetDoc()->GetAttrPool(),
753 RES_VERT_ORIENT, RES_HORI_ORIENT );
754 SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
755 SwFmtVertOrient aVert( pFmt->GetVertOrient() );
756 sal_Bool bPut = sal_False;
757
758 if( !GetFlyFrm()->IsFlyLayFrm() &&
759 ::GetHtmlMode(pFmt->GetDoc()->GetDocShell()) )
760 {
761 //Im HTML-Modus sind nur automatische Ausrichtungen erlaubt.
762 //Einzig einen Snap auf Links/Rechts bzw. Linker-/Rechter-Rand koennen
763 //wir versuchen.
764 const SwFrm* pAnch = GetFlyFrm()->GetAnchorFrm();
765 sal_Bool bNextLine = sal_False;
766
767 if( !GetFlyFrm()->IsAutoPos() || text::RelOrientation::PAGE_FRAME != aHori.GetRelationOrient() )
768 {
769 if( text::RelOrientation::CHAR == eRelHori )
770 {
771 aHori.SetHoriOrient( text::HoriOrientation::LEFT );
772 aHori.SetRelationOrient( text::RelOrientation::CHAR );
773 }
774 else
775 {
776 bNextLine = sal_True;
777 //Horizontale Ausrichtung:
778 const sal_Bool bLeftFrm =
779 aFlyRect.Left() < pAnch->Frm().Left() + pAnch->Prt().Left(),
780 bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
781 pAnch->Frm().Left() + pAnch->Prt().Width()/2;
782 if ( bLeftFrm || bLeftPrt )
783 {
784 aHori.SetHoriOrient( text::HoriOrientation::LEFT );
785 aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
786 }
787 else
788 {
789 const sal_Bool bRightFrm = aFlyRect.Left() >
790 pAnch->Frm().Left() + pAnch->Prt().Width();
791 aHori.SetHoriOrient( text::HoriOrientation::RIGHT );
792 aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
793 }
794 }
795 aSet.Put( aHori );
796 }
797 //Vertikale Ausrichtung bleibt grundsaetzlich schlicht erhalten,
798 //nur bei nicht automatischer Ausrichtung wird umgeschaltet.
799 sal_Bool bRelChar = text::RelOrientation::CHAR == eRelVert;
800 aVert.SetVertOrient( eVert != text::VertOrientation::NONE ? eVert :
801 GetFlyFrm()->IsFlyInCntFrm() ? text::VertOrientation::CHAR_CENTER :
802 bRelChar && bNextLine ? text::VertOrientation::CHAR_TOP : text::VertOrientation::TOP );
803 if( bRelChar )
804 aVert.SetRelationOrient( text::RelOrientation::CHAR );
805 else
806 aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA );
807 aSet.Put( aVert );
808 bPut = sal_True;
809 }
810
811 //Automatische Ausrichtungen wollen wir moeglichst nicht verlieren.
812 if ( !bPut && bInResize )
813 {
814 if ( text::HoriOrientation::NONE != eHori )
815 {
816 aHori.SetHoriOrient( eHori );
817 aHori.SetRelationOrient( eRelHori );
818 aSet.Put( aHori );
819 bPut = sal_True;
820 }
821 if ( text::VertOrientation::NONE != eVert )
822 {
823 aVert.SetVertOrient( eVert );
824 aVert.SetRelationOrient( eRelVert );
825 aSet.Put( aVert );
826 bPut = sal_True;
827 }
828 }
829 if ( bPut )
830 pFmt->SetFmtAttr( aSet );
831 }
832
833
NbcResize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)834 void __EXPORT SwVirtFlyDrawObj::NbcResize(const Point& rRef,
835 const Fraction& xFact, const Fraction& yFact)
836 {
837 ResizeRect( aOutRect, rRef, xFact, yFact );
838
839 const SwFrm* pTmpFrm = GetFlyFrm()->GetAnchorFrm();
840 if( !pTmpFrm )
841 pTmpFrm = GetFlyFrm();
842 const bool bVertX = pTmpFrm->IsVertical();
843
844 const sal_Bool bRTL = pTmpFrm->IsRightToLeft();
845
846 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
847 const bool bVertL2RX = pTmpFrm->IsVertLR();
848 const Point aNewPos( ( bVertX && !bVertL2RX ) || bRTL ?
849 aOutRect.Right() + 1 :
850 aOutRect.Left(),
851 aOutRect.Top() );
852
853 Size aSz( aOutRect.Right() - aOutRect.Left() + 1,
854 aOutRect.Bottom()- aOutRect.Top() + 1 );
855 if( aSz != GetFlyFrm()->Frm().SSize() )
856 {
857 //Die Breite darf bei Spalten nicht zu schmal werden
858 if ( GetFlyFrm()->Lower() && GetFlyFrm()->Lower()->IsColumnFrm() )
859 {
860 SwBorderAttrAccess aAccess( SwFrm::GetCache(), GetFlyFrm() );
861 const SwBorderAttrs &rAttrs = *aAccess.Get();
862 long nMin = rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
863 const SwFmtCol& rCol = rAttrs.GetAttrSet().GetCol();
864 if ( rCol.GetColumns().Count() > 1 )
865 {
866 for ( sal_uInt16 i = 0; i < rCol.GetColumns().Count(); ++i )
867 {
868 nMin += rCol.GetColumns()[i]->GetLeft() +
869 rCol.GetColumns()[i]->GetRight() +
870 MINFLY;
871 }
872 nMin -= MINFLY;
873 }
874 aSz.Width() = Max( aSz.Width(), nMin );
875 }
876
877 SwFrmFmt *pFmt = GetFmt();
878 const SwFmtFrmSize aOldFrmSz( pFmt->GetFrmSize() );
879 GetFlyFrm()->ChgSize( aSz );
880 SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() );
881 if ( aFrmSz.GetWidthPercent() || aFrmSz.GetHeightPercent() )
882 {
883 long nRelWidth, nRelHeight;
884 const SwFrm *pRel = GetFlyFrm()->IsFlyLayFrm() ?
885 GetFlyFrm()->GetAnchorFrm() :
886 GetFlyFrm()->GetAnchorFrm()->GetUpper();
887 const ViewShell *pSh = GetFlyFrm()->getRootFrm()->GetCurrShell();
888 if ( pSh && pRel->IsBodyFrm() &&
889 pSh->GetViewOptions()->getBrowseMode() &&
890 pSh->VisArea().HasArea() )
891 {
892 nRelWidth = pSh->GetBrowseWidth();
893 nRelHeight = pSh->VisArea().Height();
894 const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
895 nRelHeight -= 2*aBorder.Height();
896 }
897 else
898 {
899 nRelWidth = pRel->Prt().Width();
900 nRelHeight = pRel->Prt().Height();
901 }
902 if ( aFrmSz.GetWidthPercent() && aFrmSz.GetWidthPercent() != 0xFF &&
903 aOldFrmSz.GetWidth() != aFrmSz.GetWidth() )
904 aFrmSz.SetWidthPercent( sal_uInt8(aSz.Width() * 100L / nRelWidth + 0.5) );
905 if ( aFrmSz.GetHeightPercent() && aFrmSz.GetHeightPercent() != 0xFF &&
906 aOldFrmSz.GetHeight() != aFrmSz.GetHeight() )
907 aFrmSz.SetHeightPercent( sal_uInt8(aSz.Height() * 100L / nRelHeight + 0.5) );
908 pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt );
909 }
910 }
911
912 //Position kann auch veraendert sein!
913 const Point aOldPos( ( bVertX && !bVertL2RX ) || bRTL ?
914 GetFlyFrm()->Frm().TopRight() :
915 GetFlyFrm()->Frm().Pos() );
916 if ( aNewPos != aOldPos )
917 {
918 //Kann sich durch das ChgSize veraendert haben!
919 if( bVertX || bRTL )
920 {
921 if( aOutRect.TopRight() != aNewPos )
922 {
923 //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
924 SwTwips nDeltaX;
925 if ( bVertL2RX )
926 nDeltaX = aNewPos.X() - aOutRect.Left();
927 else
928 nDeltaX = aNewPos.X() - aOutRect.Right();
929 SwTwips nDeltaY = aNewPos.Y() - aOutRect.Top();
930 MoveRect( aOutRect, Size( nDeltaX, nDeltaY ) );
931 }
932 }
933 else if ( aOutRect.TopLeft() != aNewPos )
934 aOutRect.SetPos( aNewPos );
935 bInResize = sal_True;
936 NbcMove( Size( 0, 0 ) );
937 bInResize = sal_False;
938 }
939 }
940
941
Move(const Size & rSiz)942 void __EXPORT SwVirtFlyDrawObj::Move(const Size& rSiz)
943 {
944 NbcMove( rSiz );
945 SetChanged();
946 GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
947 }
948
949
Resize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)950 void __EXPORT SwVirtFlyDrawObj::Resize(const Point& rRef,
951 const Fraction& xFact, const Fraction& yFact)
952 {
953 NbcResize( rRef, xFact, yFact );
954 SetChanged();
955 GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
956 }
957
958
GetMacroPointer(const SdrObjMacroHitRec &) const959 Pointer __EXPORT SwVirtFlyDrawObj::GetMacroPointer(
960 const SdrObjMacroHitRec& ) const
961 {
962 return Pointer( POINTER_REFHAND );
963 }
964
965
HasMacro() const966 FASTBOOL __EXPORT SwVirtFlyDrawObj::HasMacro() const
967 {
968 const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL();
969 return rURL.GetMap() || rURL.GetURL().Len();
970 }
971
972
CheckMacroHit(const SdrObjMacroHitRec & rRec) const973 SdrObject* SwVirtFlyDrawObj::CheckMacroHit( const SdrObjMacroHitRec& rRec ) const
974 {
975 const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL();
976 if( rURL.GetMap() || rURL.GetURL().Len() )
977 {
978 SwRect aRect;
979 if ( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() )
980 {
981 aRect = pFlyFrm->Prt();
982 aRect += pFlyFrm->Frm().Pos();
983 }
984 else
985 aRect = pFlyFrm->Frm();
986
987 if( aRect.IsInside( rRec.aPos ) )
988 {
989 SwRect aActRect( aRect );
990 Size aActSz( aRect.SSize() );
991 aRect.Pos().X() += rRec.nTol;
992 aRect.Pos().Y() += rRec.nTol;
993 aRect.SSize().Height()-= 2 * rRec.nTol;
994 aRect.SSize().Width() -= 2 * rRec.nTol;
995
996 if( aRect.IsInside( rRec.aPos ) )
997 {
998 if( !rURL.GetMap() ||
999 pFlyFrm->GetFmt()->GetIMapObject( rRec.aPos, pFlyFrm ))
1000 return (SdrObject*)this;
1001
1002 return 0;
1003 }
1004 }
1005 }
1006 return SdrObject::CheckMacroHit( rRec );
1007 }
1008
supportsFullDrag() const1009 bool SwVirtFlyDrawObj::supportsFullDrag() const
1010 {
1011 // call parent
1012 return SdrVirtObj::supportsFullDrag();
1013 }
1014
getFullDragClone() const1015 SdrObject* SwVirtFlyDrawObj::getFullDragClone() const
1016 {
1017 // call parent
1018 return SdrVirtObj::getFullDragClone();
1019 }
1020
1021 // eof
1022