Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "hintids.hxx"
21 : #include <svx/svdtrans.hxx>
22 : #include <editeng/protitem.hxx>
23 : #include <editeng/opaqitem.hxx>
24 : #include <svx/svdpage.hxx>
25 :
26 : #include <fmtclds.hxx>
27 : #include <fmtornt.hxx>
28 : #include <fmtfsize.hxx>
29 : #include <fmturl.hxx>
30 : #include "viewsh.hxx"
31 : #include "viewimp.hxx"
32 : #include "cntfrm.hxx"
33 : #include "frmatr.hxx"
34 : #include "doc.hxx"
35 : #include <IDocumentUndoRedo.hxx>
36 : #include "dview.hxx"
37 : #include "dflyobj.hxx"
38 : #include "flyfrm.hxx"
39 : #include "frmfmt.hxx"
40 : #include "viewopt.hxx"
41 : #include "frmtool.hxx"
42 : #include "flyfrms.hxx"
43 : #include "ndnotxt.hxx"
44 : #include "grfatr.hxx"
45 : #include "pagefrm.hxx"
46 : #include "rootfrm.hxx"
47 :
48 : #include <svx/sdr/properties/defaultproperties.hxx>
49 : #include <basegfx/range/b2drange.hxx>
50 : #include <basegfx/polygon/b2dpolygontools.hxx>
51 : #include <basegfx/polygon/b2dpolygon.hxx>
52 :
53 : // AW: For VCOfDrawVirtObj and stuff
54 : #include <svx/sdr/contact/viewcontactofvirtobj.hxx>
55 : #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
56 : #include <sw_primitivetypes2d.hxx>
57 : #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
58 :
59 : using namespace ::com::sun::star;
60 :
61 : static bool bInResize = false;
62 :
63 5087 : TYPEINIT1( SwFlyDrawObj, SdrObject )
64 48356 : TYPEINIT1( SwVirtFlyDrawObj, SdrVirtObj )
65 :
66 : namespace sdr
67 : {
68 : namespace contact
69 : {
70 : /**
71 : * @see #i95264#
72 : *
73 : * currently needed since createViewIndependentPrimitive2DSequence() is called when
74 : * RecalcBoundRect() is used. There should currently no VOCs being constructed since it
75 : * gets not visualized (instead the corresponding SwVirtFlyDrawObj's referencing this one
76 : * are visualized).
77 : */
78 : class VCOfSwFlyDrawObj : public ViewContactOfSdrObj
79 : {
80 : protected:
81 : /** This method is responsible for creating the graphical visualisation data
82 : *
83 : * @note ONLY based on model data
84 : */
85 : virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const;
86 :
87 : public:
88 : /// basic constructor, used from SdrObject.
89 145 : VCOfSwFlyDrawObj(SwFlyDrawObj& rObj)
90 145 : : ViewContactOfSdrObj(rObj)
91 : {
92 145 : }
93 : virtual ~VCOfSwFlyDrawObj();
94 : };
95 :
96 80 : drawinglayer::primitive2d::Primitive2DSequence VCOfSwFlyDrawObj::createViewIndependentPrimitive2DSequence() const
97 : {
98 : // currently gets not visualized, return empty sequence
99 80 : return drawinglayer::primitive2d::Primitive2DSequence();
100 : }
101 :
102 290 : VCOfSwFlyDrawObj::~VCOfSwFlyDrawObj()
103 : {
104 290 : }
105 : } // end of namespace contact
106 : } // end of namespace sdr
107 :
108 :
109 0 : sdr::properties::BaseProperties* SwFlyDrawObj::CreateObjectSpecificProperties()
110 : {
111 : // create default properties
112 0 : return new sdr::properties::DefaultProperties(*this);
113 : }
114 :
115 145 : sdr::contact::ViewContact* SwFlyDrawObj::CreateObjectSpecificViewContact()
116 : {
117 : // needs an own VC since createViewIndependentPrimitive2DSequence()
118 : // is called when RecalcBoundRect() is used
119 145 : return new sdr::contact::VCOfSwFlyDrawObj(*this);
120 : }
121 :
122 355 : SwFlyDrawObj::SwFlyDrawObj()
123 : {
124 355 : }
125 :
126 710 : SwFlyDrawObj::~SwFlyDrawObj()
127 : {
128 710 : }
129 :
130 : // SwFlyDrawObj - Factory-Methods
131 :
132 1037 : sal_uInt32 SwFlyDrawObj::GetObjInventor() const
133 : {
134 1037 : return SWGInventor;
135 : }
136 :
137 0 : sal_uInt16 SwFlyDrawObj::GetObjIdentifier() const
138 : {
139 0 : return SwFlyDrawObjIdentifier;
140 : }
141 :
142 : // TODO: Need own primitive to get the FlyFrame paint working
143 :
144 : namespace drawinglayer
145 : {
146 : namespace primitive2d
147 : {
148 852 : class SwVirtFlyDrawObjPrimitive : public BufferedDecompositionPrimitive2D
149 : {
150 : private:
151 : const SwVirtFlyDrawObj& mrSwVirtFlyDrawObj;
152 : const basegfx::B2DRange maOuterRange;
153 :
154 : protected:
155 : /// method which is to be used to implement the local decomposition of a 2D primitive
156 : virtual Primitive2DSequence create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
157 :
158 : public:
159 426 : SwVirtFlyDrawObjPrimitive(
160 : const SwVirtFlyDrawObj& rSwVirtFlyDrawObj,
161 : const basegfx::B2DRange &rOuterRange)
162 : : BufferedDecompositionPrimitive2D(),
163 : mrSwVirtFlyDrawObj(rSwVirtFlyDrawObj),
164 426 : maOuterRange(rOuterRange)
165 : {
166 426 : }
167 :
168 : virtual bool operator==(const BasePrimitive2D& rPrimitive) const;
169 :
170 : virtual basegfx::B2DRange getB2DRange(const geometry::ViewInformation2D& rViewInformation) const;
171 :
172 : // overloaded to allow callbacks to wrap_DoPaintObject
173 : virtual Primitive2DSequence get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const;
174 :
175 : // data read access
176 1604 : const SwVirtFlyDrawObj& getSwVirtFlyDrawObj() const { return mrSwVirtFlyDrawObj; }
177 2633 : const basegfx::B2DRange& getOuterRange() const { return maOuterRange; }
178 :
179 : /// provide unique ID
180 : DeclPrimitive2DIDBlock()
181 : };
182 : } // end of namespace primitive2d
183 : } // end of namespace drawinglayer
184 :
185 : namespace drawinglayer
186 : {
187 : namespace primitive2d
188 : {
189 102 : Primitive2DSequence SwVirtFlyDrawObjPrimitive::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
190 : {
191 102 : Primitive2DSequence aRetval;
192 :
193 102 : if(!getOuterRange().isEmpty())
194 : {
195 : // currently this SW object has no primitive representation. As long as this is the case,
196 : // create invisible geometry to allow corfect HitTest and BoundRect calculations for the
197 : // object. Use a filled primitive to get 'inside' as default object hit. The special cases from
198 : // the old SwVirtFlyDrawObj::CheckHit implementation are handled now in SwDrawView::PickObj;
199 : // this removed the 'hack' to get a view from inside model data or to react on null-tolerance
200 : // as it was done in the old implementation
201 : const Primitive2DReference aHitTestReference(
202 : createHiddenGeometryPrimitives2D(
203 : true,
204 102 : getOuterRange()));
205 :
206 102 : aRetval = Primitive2DSequence(&aHitTestReference, 1);
207 : }
208 :
209 102 : return aRetval;
210 : }
211 :
212 695 : bool SwVirtFlyDrawObjPrimitive::operator==(const BasePrimitive2D& rPrimitive) const
213 : {
214 695 : if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
215 : {
216 695 : const SwVirtFlyDrawObjPrimitive& rCompare = (SwVirtFlyDrawObjPrimitive&)rPrimitive;
217 :
218 695 : return (&getSwVirtFlyDrawObj() == &rCompare.getSwVirtFlyDrawObj()
219 695 : && getOuterRange() == rCompare.getOuterRange());
220 : }
221 :
222 0 : return false;
223 : }
224 :
225 1039 : basegfx::B2DRange SwVirtFlyDrawObjPrimitive::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
226 : {
227 1039 : return getOuterRange();
228 : }
229 :
230 214 : Primitive2DSequence SwVirtFlyDrawObjPrimitive::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
231 : {
232 : // This is the callback to keep the FlyFrame painting in SW alive as long as it
233 : // is not changed to primitives. This is the method which will be called by the processors
234 : // when they do not know this primitive (and they do not). Inside wrap_DoPaintObject
235 : // there needs to be a test that paint is only done during SW repaints (see there).
236 : // Using this mechanism guarantees the correct Z-Order of the VirtualObject-based FlyFrames.
237 214 : getSwVirtFlyDrawObj().wrap_DoPaintObject();
238 :
239 : // call parent
240 214 : return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation);
241 : }
242 :
243 : // provide unique ID
244 1792 : ImplPrimitive2DIDBlock(SwVirtFlyDrawObjPrimitive, PRIMITIVE2D_ID_SWVIRTFLYDRAWOBJPRIMITIVE2D)
245 :
246 : } // end of namespace primitive2d
247 : } // end of namespace drawinglayer
248 :
249 : // AW: own sdr::contact::ViewContact (VC) sdr::contact::ViewObjectContact (VOC) needed
250 : // since offset is defined different from SdrVirtObj's sdr::contact::ViewContactOfVirtObj.
251 : // For paint, that offset is used by setting at the OutputDevice; for primitives this is
252 : // not possible since we have no OutputDevice, but define the geometry itself.
253 :
254 : namespace sdr
255 : {
256 : namespace contact
257 : {
258 : class VCOfSwVirtFlyDrawObj : public ViewContactOfVirtObj
259 : {
260 : protected:
261 : /** This method is responsible for creating the graphical visualisation data
262 : *
263 : * @note ONLY based on model data
264 : */
265 : virtual drawinglayer::primitive2d::Primitive2DSequence createViewIndependentPrimitive2DSequence() const;
266 :
267 : public:
268 : /// basic constructor, used from SdrObject.
269 328 : VCOfSwVirtFlyDrawObj(SwVirtFlyDrawObj& rObj)
270 328 : : ViewContactOfVirtObj(rObj)
271 : {
272 328 : }
273 : virtual ~VCOfSwVirtFlyDrawObj();
274 :
275 : /// access to SwVirtFlyDrawObj
276 1278 : SwVirtFlyDrawObj& GetSwVirtFlyDrawObj() const
277 : {
278 1278 : return (SwVirtFlyDrawObj&)mrObject;
279 : }
280 : };
281 : } // end of namespace contact
282 : } // end of namespace sdr
283 :
284 : namespace sdr
285 : {
286 : namespace contact
287 : {
288 426 : drawinglayer::primitive2d::Primitive2DSequence VCOfSwVirtFlyDrawObj::createViewIndependentPrimitive2DSequence() const
289 : {
290 426 : drawinglayer::primitive2d::Primitive2DSequence xRetval;
291 426 : const SdrObject& rReferencedObject = GetSwVirtFlyDrawObj().GetReferencedObj();
292 :
293 426 : if(rReferencedObject.ISA(SwFlyDrawObj))
294 : {
295 : // create an own specialized primitive which is used as repaint callpoint and HitTest
296 : // for HitTest processor (see primitive implementation above)
297 426 : const basegfx::B2DRange aOuterRange(GetSwVirtFlyDrawObj().getOuterBound());
298 :
299 426 : if(!aOuterRange.isEmpty())
300 : {
301 : const drawinglayer::primitive2d::Primitive2DReference xPrimitive(
302 : new drawinglayer::primitive2d::SwVirtFlyDrawObjPrimitive(
303 : GetSwVirtFlyDrawObj(),
304 426 : aOuterRange));
305 :
306 426 : xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xPrimitive, 1);
307 : }
308 : }
309 :
310 426 : return xRetval;
311 : }
312 :
313 656 : VCOfSwVirtFlyDrawObj::~VCOfSwVirtFlyDrawObj()
314 : {
315 656 : }
316 : } // end of namespace contact
317 : } // end of namespace sdr
318 :
319 426 : basegfx::B2DRange SwVirtFlyDrawObj::getOuterBound() const
320 : {
321 426 : basegfx::B2DRange aOuterRange;
322 426 : const SdrObject& rReferencedObject = GetReferencedObj();
323 :
324 426 : if(rReferencedObject.ISA(SwFlyDrawObj))
325 : {
326 426 : const SwFlyFrm* pFlyFrame = GetFlyFrm();
327 :
328 426 : if(pFlyFrame)
329 : {
330 426 : const Rectangle aOuterRectangle(pFlyFrame->Frm().Pos(), pFlyFrame->Frm().SSize());
331 :
332 852 : if(!aOuterRectangle.IsEmpty()
333 426 : && RECT_EMPTY != aOuterRectangle.Right()
334 852 : && RECT_EMPTY != aOuterRectangle.Bottom())
335 : {
336 426 : aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Left(), aOuterRectangle.Top()));
337 426 : aOuterRange.expand(basegfx::B2DTuple(aOuterRectangle.Right(), aOuterRectangle.Bottom()));
338 : }
339 : }
340 : }
341 :
342 426 : return aOuterRange;
343 : }
344 :
345 0 : basegfx::B2DRange SwVirtFlyDrawObj::getInnerBound() const
346 : {
347 0 : basegfx::B2DRange aInnerRange;
348 0 : const SdrObject& rReferencedObject = GetReferencedObj();
349 :
350 0 : if(rReferencedObject.ISA(SwFlyDrawObj))
351 : {
352 0 : const SwFlyFrm* pFlyFrame = GetFlyFrm();
353 :
354 0 : if(pFlyFrame)
355 : {
356 0 : const Rectangle aInnerRectangle(pFlyFrame->Frm().Pos() + pFlyFrame->Prt().Pos(), pFlyFrame->Prt().SSize());
357 :
358 0 : if(!aInnerRectangle.IsEmpty()
359 0 : && RECT_EMPTY != aInnerRectangle.Right()
360 0 : && RECT_EMPTY != aInnerRectangle.Bottom())
361 : {
362 0 : aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Left(), aInnerRectangle.Top()));
363 0 : aInnerRange.expand(basegfx::B2DTuple(aInnerRectangle.Right(), aInnerRectangle.Bottom()));
364 : }
365 : }
366 : }
367 :
368 0 : return aInnerRange;
369 : }
370 :
371 328 : sdr::contact::ViewContact* SwVirtFlyDrawObj::CreateObjectSpecificViewContact()
372 : {
373 : // need an own ViewContact (VC) to allow creation of a specialized primitive
374 : // for being able to visualize the FlyFrames in primitive renderers
375 328 : return new sdr::contact::VCOfSwVirtFlyDrawObj(*this);
376 : }
377 :
378 328 : SwVirtFlyDrawObj::SwVirtFlyDrawObj(SdrObject& rNew, SwFlyFrm* pFly) :
379 : SdrVirtObj( rNew ),
380 328 : pFlyFrm( pFly )
381 : {
382 : //#110094#-1
383 : // bNotPersistent = bNeedColorRestore = bWriterFlyFrame = sal_True;
384 328 : const SvxProtectItem &rP = pFlyFrm->GetFmt()->GetProtect();
385 328 : bMovProt = rP.IsPosProtected();
386 328 : bSizProt = rP.IsSizeProtected();
387 328 : }
388 :
389 :
390 984 : SwVirtFlyDrawObj::~SwVirtFlyDrawObj()
391 : {
392 328 : if ( GetPage() ) //Withdraw SdrPage the responsibility.
393 312 : GetPage()->RemoveObject( GetOrdNum() );
394 656 : }
395 :
396 0 : const SwFrmFmt *SwVirtFlyDrawObj::GetFmt() const
397 : {
398 0 : return GetFlyFrm()->GetFmt();
399 : }
400 2 : SwFrmFmt *SwVirtFlyDrawObj::GetFmt()
401 : {
402 2 : return GetFlyFrm()->GetFmt();
403 : }
404 :
405 : // --> OD #i102707#
406 : namespace
407 : {
408 : class RestoreMapMode
409 : {
410 : public:
411 172 : explicit RestoreMapMode( ViewShell* pViewShell )
412 : : mbMapModeRestored( false )
413 172 : , mpOutDev( pViewShell->GetOut() )
414 : {
415 172 : if ( pViewShell->getPrePostMapMode() != mpOutDev->GetMapMode() )
416 : {
417 170 : mpOutDev->Push(PUSH_MAPMODE);
418 :
419 170 : GDIMetaFile* pMetaFile = mpOutDev->GetConnectMetaFile();
420 170 : if ( pMetaFile &&
421 170 : pMetaFile->IsRecord() && !pMetaFile->IsPause() )
422 : {
423 : OSL_FAIL( "MapMode restoration during meta file creation is somehow suspect - using <SetRelativeMapMode(..)>, but not sure, if correct." );
424 0 : mpOutDev->SetRelativeMapMode( pViewShell->getPrePostMapMode() );
425 : }
426 : else
427 : {
428 170 : mpOutDev->SetMapMode( pViewShell->getPrePostMapMode() );
429 : }
430 :
431 170 : mbMapModeRestored = true;
432 : }
433 172 : };
434 :
435 172 : ~RestoreMapMode()
436 : {
437 172 : if ( mbMapModeRestored )
438 : {
439 170 : mpOutDev->Pop();
440 : }
441 172 : };
442 :
443 : private:
444 : bool mbMapModeRestored;
445 : OutputDevice* mpOutDev;
446 : };
447 : }
448 : // <--
449 :
450 214 : void SwVirtFlyDrawObj::wrap_DoPaintObject() const
451 : {
452 214 : ViewShell* pShell = pFlyFrm->getRootFrm()->GetCurrShell();
453 :
454 : // Only paint when we have a current shell and a DrawingLayer paint is in progress.
455 : // This avcoids evtl. problems with renderers which do processing stuff,
456 : // but no paints. IsPaintInProgress() depends on SW repaint, so, as long
457 : // as SW paints self and calls DrawLayer() for Heaven and Hell, this will
458 : // be correct
459 214 : if ( pShell && pShell->IsDrawingLayerPaintInProgress() )
460 : {
461 213 : bool bDrawObject(true);
462 :
463 213 : if ( !SwFlyFrm::IsPaint( (SdrObject*)this, pShell ) )
464 : {
465 0 : bDrawObject = false;
466 : }
467 :
468 213 : if ( bDrawObject )
469 : {
470 213 : if ( !pFlyFrm->IsFlyInCntFrm() )
471 : {
472 : // it is also necessary to restore the VCL MapMode from ViewInformation since e.g.
473 : // the VCL PixelRenderer resets it at the used OutputDevice. Unfortunately, this
474 : // excludes shears and rotates which are not expressable in MapMode.
475 : // OD #i102707#
476 : // new helper class to restore MapMode - restoration, only if
477 : // needed and consideration of paint for meta file creation .
478 172 : RestoreMapMode aRestoreMapModeIfNeeded( pShell );
479 :
480 : // paint the FlyFrame (use standard VCL-Paint)
481 172 : pFlyFrm->Paint( GetFlyFrm()->Frm() );
482 : }
483 : }
484 : }
485 214 : }
486 :
487 0 : void SwVirtFlyDrawObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const
488 : {
489 : rInfo.bSelectAllowed = rInfo.bMoveAllowed =
490 0 : rInfo.bResizeFreeAllowed = rInfo.bResizePropAllowed = sal_True;
491 :
492 : rInfo.bRotateFreeAllowed = rInfo.bRotate90Allowed =
493 : rInfo.bMirrorFreeAllowed = rInfo.bMirror45Allowed =
494 : rInfo.bMirror90Allowed = rInfo.bShearAllowed =
495 : rInfo.bCanConvToPath = rInfo.bCanConvToPoly =
496 0 : rInfo.bCanConvToPathLineToArea = rInfo.bCanConvToPolyLineToArea = sal_False;
497 0 : }
498 :
499 : // SwVirtFlyDrawObj - Size Determination
500 :
501 6093 : void SwVirtFlyDrawObj::SetRect() const
502 : {
503 6093 : if ( GetFlyFrm()->Frm().HasArea() )
504 6093 : ((SwVirtFlyDrawObj*)this)->aOutRect = GetFlyFrm()->Frm().SVRect();
505 : else
506 0 : ((SwVirtFlyDrawObj*)this)->aOutRect = Rectangle();
507 6093 : }
508 :
509 4803 : const Rectangle& SwVirtFlyDrawObj::GetCurrentBoundRect() const
510 : {
511 4803 : SetRect();
512 4803 : return aOutRect;
513 : }
514 :
515 3640 : const Rectangle& SwVirtFlyDrawObj::GetLastBoundRect() const
516 : {
517 3640 : return GetCurrentBoundRect();
518 : }
519 :
520 0 : void SwVirtFlyDrawObj::RecalcBoundRect()
521 : {
522 0 : SetRect();
523 0 : }
524 :
525 0 : void SwVirtFlyDrawObj::RecalcSnapRect()
526 : {
527 0 : SetRect();
528 0 : }
529 :
530 523 : const Rectangle& SwVirtFlyDrawObj::GetSnapRect() const
531 : {
532 523 : SetRect();
533 523 : return aOutRect;
534 : }
535 :
536 0 : void SwVirtFlyDrawObj::SetSnapRect(const Rectangle& )
537 : {
538 0 : Rectangle aTmp( GetLastBoundRect() );
539 0 : SetRect();
540 0 : SetChanged();
541 0 : BroadcastObjectChange();
542 0 : if (pUserCall!=NULL)
543 0 : pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp);
544 0 : }
545 :
546 0 : void SwVirtFlyDrawObj::NbcSetSnapRect(const Rectangle& )
547 : {
548 0 : SetRect();
549 0 : }
550 :
551 0 : const Rectangle& SwVirtFlyDrawObj::GetLogicRect() const
552 : {
553 0 : SetRect();
554 0 : return aOutRect;
555 : }
556 :
557 0 : void SwVirtFlyDrawObj::SetLogicRect(const Rectangle& )
558 : {
559 0 : Rectangle aTmp( GetLastBoundRect() );
560 0 : SetRect();
561 0 : SetChanged();
562 0 : BroadcastObjectChange();
563 0 : if (pUserCall!=NULL)
564 0 : pUserCall->Changed(*this, SDRUSERCALL_RESIZE, aTmp);
565 0 : }
566 :
567 0 : void SwVirtFlyDrawObj::NbcSetLogicRect(const Rectangle& )
568 : {
569 0 : SetRect();
570 0 : }
571 :
572 0 : ::basegfx::B2DPolyPolygon SwVirtFlyDrawObj::TakeXorPoly() const
573 : {
574 0 : const Rectangle aSourceRectangle(GetFlyFrm()->Frm().SVRect());
575 0 : const ::basegfx::B2DRange aSourceRange(aSourceRectangle.Left(), aSourceRectangle.Top(), aSourceRectangle.Right(), aSourceRectangle.Bottom());
576 0 : ::basegfx::B2DPolyPolygon aRetval;
577 :
578 0 : aRetval.append(::basegfx::tools::createPolygonFromRect(aSourceRange));
579 :
580 0 : return aRetval;
581 : }
582 :
583 : // SwVirtFlyDrawObj::Move() und Resize()
584 :
585 0 : void SwVirtFlyDrawObj::NbcMove(const Size& rSiz)
586 : {
587 0 : MoveRect( aOutRect, rSiz );
588 0 : const Point aOldPos( GetFlyFrm()->Frm().Pos() );
589 0 : const Point aNewPos( aOutRect.TopLeft() );
590 0 : const SwRect aFlyRect( aOutRect );
591 :
592 : //If the Fly has a automatic align (right or top),
593 : //so preserve the automatic.
594 0 : SwFrmFmt *pFmt = GetFlyFrm()->GetFmt();
595 0 : const sal_Int16 eHori = pFmt->GetHoriOrient().GetHoriOrient();
596 0 : const sal_Int16 eVert = pFmt->GetVertOrient().GetVertOrient();
597 0 : const sal_Int16 eRelHori = pFmt->GetHoriOrient().GetRelationOrient();
598 0 : const sal_Int16 eRelVert = pFmt->GetVertOrient().GetRelationOrient();
599 : //On paragraph bound Flys starting from the new position a new
600 : //anchor must be set. Anchor and the new RelPos is calculated and
601 : //placed by the Fly itself.
602 0 : if( GetFlyFrm()->IsFlyAtCntFrm() )
603 0 : ((SwFlyAtCntFrm*)GetFlyFrm())->SetAbsPos( aNewPos );
604 : else
605 : {
606 0 : const SwFrmFmt *pTmpFmt = GetFmt();
607 0 : const SwFmtVertOrient &rVert = pTmpFmt->GetVertOrient();
608 0 : const SwFmtHoriOrient &rHori = pTmpFmt->GetHoriOrient();
609 0 : long lXDiff = aNewPos.X() - aOldPos.X();
610 0 : if( rHori.IsPosToggle() && text::HoriOrientation::NONE == eHori &&
611 0 : !GetFlyFrm()->FindPageFrm()->OnRightPage() )
612 0 : lXDiff = -lXDiff;
613 :
614 0 : if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() &&
615 : text::HoriOrientation::NONE == eHori )
616 0 : lXDiff = -lXDiff;
617 :
618 0 : long lYDiff = aNewPos.Y() - aOldPos.Y();
619 0 : if( GetFlyFrm()->GetAnchorFrm()->IsVertical() )
620 : {
621 : //lXDiff -= rVert.GetPos();
622 : //lYDiff += rHori.GetPos();
623 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
624 0 : if ( GetFlyFrm()->GetAnchorFrm()->IsVertLR() )
625 : {
626 0 : lXDiff += rVert.GetPos();
627 0 : lXDiff = -lXDiff;
628 : }
629 : else
630 : {
631 0 : lXDiff -= rVert.GetPos();
632 0 : lYDiff += rHori.GetPos();
633 : }
634 : }
635 : else
636 : {
637 0 : lXDiff += rHori.GetPos();
638 0 : lYDiff += rVert.GetPos();
639 : }
640 :
641 0 : if( GetFlyFrm()->GetAnchorFrm()->IsRightToLeft() &&
642 : text::HoriOrientation::NONE != eHori )
643 0 : lXDiff = GetFlyFrm()->GetAnchorFrm()->Frm().Width() -
644 0 : aFlyRect.Width() - lXDiff;
645 :
646 0 : const Point aTmp( lXDiff, lYDiff );
647 0 : GetFlyFrm()->ChgRelPos( aTmp );
648 : }
649 :
650 0 : SwAttrSet aSet( pFmt->GetDoc()->GetAttrPool(),
651 0 : RES_VERT_ORIENT, RES_HORI_ORIENT );
652 0 : SwFmtHoriOrient aHori( pFmt->GetHoriOrient() );
653 0 : SwFmtVertOrient aVert( pFmt->GetVertOrient() );
654 0 : bool bPut = false;
655 :
656 0 : if( !GetFlyFrm()->IsFlyLayFrm() &&
657 0 : ::GetHtmlMode(pFmt->GetDoc()->GetDocShell()) )
658 : {
659 : //In HTML-Mode only automatic aligns are allowed.
660 : //Only we can try a snap to left/right respectively left-/right border
661 0 : const SwFrm* pAnch = GetFlyFrm()->GetAnchorFrm();
662 0 : bool bNextLine = false;
663 :
664 0 : if( !GetFlyFrm()->IsAutoPos() || text::RelOrientation::PAGE_FRAME != aHori.GetRelationOrient() )
665 : {
666 0 : if( text::RelOrientation::CHAR == eRelHori )
667 : {
668 0 : aHori.SetHoriOrient( text::HoriOrientation::LEFT );
669 0 : aHori.SetRelationOrient( text::RelOrientation::CHAR );
670 : }
671 : else
672 : {
673 0 : bNextLine = true;
674 : //Horizontal Align:
675 : const bool bLeftFrm =
676 0 : aFlyRect.Left() < pAnch->Frm().Left() + pAnch->Prt().Left(),
677 0 : bLeftPrt = aFlyRect.Left() + aFlyRect.Width() <
678 0 : pAnch->Frm().Left() + pAnch->Prt().Width()/2;
679 0 : if ( bLeftFrm || bLeftPrt )
680 : {
681 0 : aHori.SetHoriOrient( text::HoriOrientation::LEFT );
682 0 : aHori.SetRelationOrient( bLeftFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
683 : }
684 : else
685 : {
686 0 : const bool bRightFrm = aFlyRect.Left() >
687 0 : pAnch->Frm().Left() + pAnch->Prt().Width();
688 0 : aHori.SetHoriOrient( text::HoriOrientation::RIGHT );
689 0 : aHori.SetRelationOrient( bRightFrm ? text::RelOrientation::FRAME : text::RelOrientation::PRINT_AREA );
690 : }
691 : }
692 0 : aSet.Put( aHori );
693 : }
694 : //Vertical alignment simply is retained principally,
695 : //only on manual align will be switched over.
696 0 : bool bRelChar = text::RelOrientation::CHAR == eRelVert;
697 : aVert.SetVertOrient( eVert != text::VertOrientation::NONE ? eVert :
698 0 : GetFlyFrm()->IsFlyInCntFrm() ? text::VertOrientation::CHAR_CENTER :
699 0 : bRelChar && bNextLine ? text::VertOrientation::CHAR_TOP : text::VertOrientation::TOP );
700 0 : if( bRelChar )
701 0 : aVert.SetRelationOrient( text::RelOrientation::CHAR );
702 : else
703 0 : aVert.SetRelationOrient( text::RelOrientation::PRINT_AREA );
704 0 : aSet.Put( aVert );
705 0 : bPut = true;
706 : }
707 :
708 : //We want preferably not to lose the automatic alignments.
709 0 : if ( !bPut && bInResize )
710 : {
711 0 : if ( text::HoriOrientation::NONE != eHori )
712 : {
713 0 : aHori.SetHoriOrient( eHori );
714 0 : aHori.SetRelationOrient( eRelHori );
715 0 : aSet.Put( aHori );
716 0 : bPut = true;
717 : }
718 0 : if ( text::VertOrientation::NONE != eVert )
719 : {
720 0 : aVert.SetVertOrient( eVert );
721 0 : aVert.SetRelationOrient( eRelVert );
722 0 : aSet.Put( aVert );
723 0 : bPut = true;
724 : }
725 : }
726 0 : if ( bPut )
727 0 : pFmt->SetFmtAttr( aSet );
728 0 : }
729 :
730 0 : void SwVirtFlyDrawObj::NbcResize(const Point& rRef,
731 : const Fraction& xFact, const Fraction& yFact)
732 : {
733 0 : ResizeRect( aOutRect, rRef, xFact, yFact );
734 :
735 0 : const SwFrm* pTmpFrm = GetFlyFrm()->GetAnchorFrm();
736 0 : if( !pTmpFrm )
737 0 : pTmpFrm = GetFlyFrm();
738 0 : const bool bVertX = pTmpFrm->IsVertical();
739 :
740 0 : const sal_Bool bRTL = pTmpFrm->IsRightToLeft();
741 :
742 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
743 0 : const bool bVertL2RX = pTmpFrm->IsVertLR();
744 0 : const Point aNewPos( ( bVertX && !bVertL2RX ) || bRTL ?
745 0 : aOutRect.Right() + 1 :
746 0 : aOutRect.Left(),
747 0 : aOutRect.Top() );
748 :
749 0 : Size aSz( aOutRect.Right() - aOutRect.Left() + 1,
750 0 : aOutRect.Bottom()- aOutRect.Top() + 1 );
751 0 : if( aSz != GetFlyFrm()->Frm().SSize() )
752 : {
753 : //The width of the columns should not be too narrow
754 0 : if ( GetFlyFrm()->Lower() && GetFlyFrm()->Lower()->IsColumnFrm() )
755 : {
756 0 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), GetFlyFrm() );
757 0 : const SwBorderAttrs &rAttrs = *aAccess.Get();
758 0 : long nMin = rAttrs.CalcLeftLine()+rAttrs.CalcRightLine();
759 0 : const SwFmtCol& rCol = rAttrs.GetAttrSet().GetCol();
760 0 : if ( rCol.GetColumns().size() > 1 )
761 : {
762 0 : for ( sal_uInt16 i = 0; i < rCol.GetColumns().size(); ++i )
763 : {
764 0 : nMin += rCol.GetColumns()[i].GetLeft() +
765 0 : rCol.GetColumns()[i].GetRight() +
766 0 : MINFLY;
767 : }
768 0 : nMin -= MINFLY;
769 : }
770 0 : aSz.Width() = std::max( aSz.Width(), nMin );
771 : }
772 :
773 0 : SwFrmFmt *pFmt = GetFmt();
774 0 : const SwFmtFrmSize aOldFrmSz( pFmt->GetFrmSize() );
775 0 : GetFlyFrm()->ChgSize( aSz );
776 0 : SwFmtFrmSize aFrmSz( pFmt->GetFrmSize() );
777 0 : if ( aFrmSz.GetWidthPercent() || aFrmSz.GetHeightPercent() )
778 : {
779 : long nRelWidth, nRelHeight;
780 0 : const SwFrm *pRel = GetFlyFrm()->IsFlyLayFrm() ?
781 0 : GetFlyFrm()->GetAnchorFrm() :
782 0 : GetFlyFrm()->GetAnchorFrm()->GetUpper();
783 0 : const ViewShell *pSh = GetFlyFrm()->getRootFrm()->GetCurrShell();
784 0 : if ( pSh && pRel->IsBodyFrm() &&
785 0 : pSh->GetViewOptions()->getBrowseMode() &&
786 0 : pSh->VisArea().HasArea() )
787 : {
788 0 : nRelWidth = pSh->GetBrowseWidth();
789 0 : nRelHeight = pSh->VisArea().Height();
790 0 : const Size aBorder = pSh->GetOut()->PixelToLogic( pSh->GetBrowseBorder() );
791 0 : nRelHeight -= 2*aBorder.Height();
792 : }
793 : else
794 : {
795 0 : nRelWidth = pRel->Prt().Width();
796 0 : nRelHeight = pRel->Prt().Height();
797 : }
798 0 : if ( aFrmSz.GetWidthPercent() && aFrmSz.GetWidthPercent() != 0xFF &&
799 0 : aOldFrmSz.GetWidth() != aFrmSz.GetWidth() )
800 0 : aFrmSz.SetWidthPercent( sal_uInt8(aSz.Width() * 100L / nRelWidth + 0.5) );
801 0 : if ( aFrmSz.GetHeightPercent() && aFrmSz.GetHeightPercent() != 0xFF &&
802 0 : aOldFrmSz.GetHeight() != aFrmSz.GetHeight() )
803 0 : aFrmSz.SetHeightPercent( sal_uInt8(aSz.Height() * 100L / nRelHeight + 0.5) );
804 0 : pFmt->GetDoc()->SetAttr( aFrmSz, *pFmt );
805 0 : }
806 : }
807 :
808 : //Position can also be changed!
809 0 : const Point aOldPos( ( bVertX && !bVertL2RX ) || bRTL ?
810 0 : GetFlyFrm()->Frm().TopRight() :
811 0 : GetFlyFrm()->Frm().Pos() );
812 0 : if ( aNewPos != aOldPos )
813 : {
814 : //May have been altered by the ChgSize!
815 0 : if( bVertX || bRTL )
816 : {
817 0 : if( aOutRect.TopRight() != aNewPos )
818 : {
819 : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
820 : SwTwips nDeltaX;
821 0 : if ( bVertL2RX )
822 0 : nDeltaX = aNewPos.X() - aOutRect.Left();
823 : else
824 0 : nDeltaX = aNewPos.X() - aOutRect.Right();
825 0 : SwTwips nDeltaY = aNewPos.Y() - aOutRect.Top();
826 0 : MoveRect( aOutRect, Size( nDeltaX, nDeltaY ) );
827 0 : }
828 : }
829 0 : else if ( aOutRect.TopLeft() != aNewPos )
830 0 : aOutRect.SetPos( aNewPos );
831 0 : bInResize = true;
832 0 : NbcMove( Size( 0, 0 ) );
833 0 : bInResize = false;
834 : }
835 0 : }
836 :
837 0 : void SwVirtFlyDrawObj::Move(const Size& rSiz)
838 : {
839 0 : NbcMove( rSiz );
840 0 : SetChanged();
841 0 : GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
842 0 : }
843 :
844 0 : void SwVirtFlyDrawObj::Resize(const Point& rRef,
845 : const Fraction& xFact, const Fraction& yFact, bool /*bUnsetRelative*/)
846 : {
847 0 : NbcResize( rRef, xFact, yFact );
848 0 : SetChanged();
849 0 : GetFmt()->GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(false);
850 0 : }
851 :
852 : // Macro
853 :
854 0 : Pointer SwVirtFlyDrawObj::GetMacroPointer(
855 : const SdrObjMacroHitRec& ) const
856 : {
857 0 : return Pointer( POINTER_REFHAND );
858 : }
859 :
860 0 : bool SwVirtFlyDrawObj::HasMacro() const
861 : {
862 0 : const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL();
863 0 : return rURL.GetMap() || rURL.GetURL().Len();
864 : }
865 :
866 0 : SdrObject* SwVirtFlyDrawObj::CheckMacroHit( const SdrObjMacroHitRec& rRec ) const
867 : {
868 0 : const SwFmtURL &rURL = pFlyFrm->GetFmt()->GetURL();
869 0 : if( rURL.GetMap() || rURL.GetURL().Len() )
870 : {
871 0 : SwRect aRect;
872 0 : if ( pFlyFrm->Lower() && pFlyFrm->Lower()->IsNoTxtFrm() )
873 : {
874 0 : aRect = pFlyFrm->Prt();
875 0 : aRect += pFlyFrm->Frm().Pos();
876 : }
877 : else
878 0 : aRect = pFlyFrm->Frm();
879 :
880 0 : if( aRect.IsInside( rRec.aPos ) )
881 : {
882 0 : aRect.Pos().setX(aRect.Pos().getX() + rRec.nTol);
883 0 : aRect.Pos().setY(aRect.Pos().getY() + rRec.nTol);
884 0 : aRect.SSize().Height()-= 2 * rRec.nTol;
885 0 : aRect.SSize().Width() -= 2 * rRec.nTol;
886 :
887 0 : if( aRect.IsInside( rRec.aPos ) )
888 : {
889 0 : if( !rURL.GetMap() ||
890 0 : pFlyFrm->GetFmt()->GetIMapObject( rRec.aPos, pFlyFrm ))
891 0 : return (SdrObject*)this;
892 :
893 0 : return 0;
894 : }
895 : }
896 : }
897 0 : return SdrObject::CheckMacroHit( rRec );
898 : }
899 :
900 : // Dragging
901 :
902 0 : bool SwVirtFlyDrawObj::supportsFullDrag() const
903 : {
904 : // call parent
905 0 : return SdrVirtObj::supportsFullDrag();
906 : }
907 :
908 0 : SdrObject* SwVirtFlyDrawObj::getFullDragClone() const
909 : {
910 : // call parent
911 0 : return SdrVirtObj::getFullDragClone();
912 99 : }
913 :
914 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|