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