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