xref: /trunk/main/sw/source/core/draw/dflyobj.cxx (revision efeef26f)
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