2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <com/sun/star/uno/Any.hxx>
23 #include <cppuhelper/weak.hxx>
24 #include <cppuhelper/weakref.hxx>
25 #include <rtl/ustring.hxx>
26 #include <vcl/outdev.hxx>
27 #include <svl/lstner.hxx>
28 #include <svl/poolitem.hxx>
29 #include <svl/typedwhich.hxx>
30 #include <tools/degree.hxx>
31 #include <svx/svdtypes.hxx>
32 #include <svx/svdobjkind.hxx>
33 #include <svx/svxdllapi.h>
34 #include <tools/link.hxx>
35 #include <tools/gen.hxx>
36 #include <unotools/resmgr.hxx>
38 #include <unordered_set>
44 class OutlinerParaObject
;
63 class XFillAttrSetItem
;
64 class XLineAttrSetItem
;
66 namespace tools
{ class PolyPolygon
; }
70 class SdrObjUserDataList
;
73 class SdrGluePointList
;
76 enum class PointerStyle
;
87 namespace sdr
{ class ObjectUser
; }
88 namespace sdr::properties
{ class BaseProperties
; }
89 namespace sdr::contact
{ class ViewContact
; }
91 namespace com::sun::star::drawing
{ class XShape
; }
92 namespace svx::diagram
{ class IDiagramHelper
; }
95 enum class SdrInventor
: sal_uInt32
{
97 BasicDialog
= sal_uInt32( 'D' | ('L' << 8) | ('G' << 16) | ('1' << 24) ),
98 Default
= sal_uInt32( 'S' | ('V' << 8) | ('D' << 16) | ('r' << 24) ),
99 E3d
= sal_uInt32( 'E' | ('3' << 8) | ('D' << 16) | ('1' << 24) ),
100 FmForm
= sal_uInt32( 'F' | ('M' << 8) | ('0' << 16) | ('1' << 24) ),
101 IMap
= sal_uInt32( 'I' | ('M' << 8) | ('A' << 16) | ('P' << 24) ),
102 ReportDesign
= sal_uInt32( 'R' | ('P' << 8) | ('T' << 16) | ('1' << 24) ),
103 ScOrSwDraw
= sal_uInt32( 'S' | ('C' << 8) | ('3' << 16) | ('0' << 24) ), // Used in sc/ and sw/
104 SgaImap
= sal_uInt32( 'S' | ('D' << 8) | ('U' << 16) | ('D' << 24) ),
105 StarDrawUserData
= sal_uInt32( 'S' | ('D' << 8) | ('U' << 16) | ('D' << 24) ),
106 Swg
= sal_uInt32( 'S' | ('W' << 8) | ('G' << 16) ),
109 enum class SdrUserCallType
{
110 MoveOnly
, // only moved, size unchanged
111 Resize
, // size and maybe position changed
112 ChangeAttr
, // attribute changed. Eventually new size, because of line width
113 Delete
, // object is going to be deleted soon, no attributes anymore
114 Inserted
, // inserted into an object list (e.g. Page)
115 Removed
, // removed from an object list
116 ChildMoveOnly
, // a child within a group has changed
117 ChildResize
, // a child within a group has changed
118 ChildChangeAttr
, // a child within a group has changed
119 ChildDelete
, // a child within a group has changed
120 ChildInserted
, // a child within a group has changed
121 ChildRemoved
// a child within a group has changed
124 class SVXCORE_DLLPUBLIC SdrObjUserCall
127 virtual ~SdrObjUserCall();
128 virtual void Changed(const SdrObject
& rObj
, SdrUserCallType eType
, const tools::Rectangle
& rOldBoundRect
);
129 virtual void const* GetPDFAnchorStructureElementKey(SdrObject
const& rObj
);
132 class SVXCORE_DLLPUBLIC SdrObjMacroHitRec
136 const SdrLayerIDSet
* pVisiLayer
;
137 const SdrPageView
* pPageView
;
144 * User data of a drawing object, e.g. application specific data.
145 * Every drawing object can have an arbitrary amount of such records (SV list).
146 * Whoever wants to save data here, must inherit from this and set a corresponding link in the factory.
148 class SVXCORE_DLLPUBLIC SdrObjUserData
150 SdrInventor m_nInventor
;
151 sal_uInt16 m_nIdentifier
;
153 void operator=(const SdrObjUserData
& rData
) = delete;
154 bool operator==(const SdrObjUserData
& rData
) const = delete;
155 bool operator!=(const SdrObjUserData
& rData
) const = delete;
158 SdrObjUserData(SdrInventor nInv
, sal_uInt16 nId
);
159 SdrObjUserData(const SdrObjUserData
& rData
);
160 virtual ~SdrObjUserData();
162 virtual std::unique_ptr
<SdrObjUserData
> Clone(SdrObject
* pObj1
) const = 0; // #i71039# NULL -> 0
163 SdrInventor
GetInventor() const { return m_nInventor
;}
164 sal_uInt16
GetId() const { return m_nIdentifier
;}
169 * Provides information about various ZObject properties
171 class SVXCORE_DLLPUBLIC SdrObjTransformInfoRec
174 bool bMoveAllowed
: 1; // if false, object cannot be moved
175 bool bResizeFreeAllowed
: 1; // if false, object cannot be resized freely
176 bool bResizePropAllowed
: 1; // if false, object cannot even be resized proportionally
177 bool bRotateFreeAllowed
: 1; // if false, object cannot be rotated freely
178 bool bRotate90Allowed
: 1; // if false, object cannot even be rotated in 90 degree steps
179 bool bMirrorFreeAllowed
: 1; // if false, object cannot be mirrored freely
180 bool bMirror45Allowed
: 1; // if false, object cannot even be mirrored over axes in a 45 degree raster
181 bool bMirror90Allowed
: 1; // if false, object cannot even be mirrored over axes in a 90 degree raster
182 bool bTransparenceAllowed
: 1; // if false, object does not have an interactive transparence control
183 bool bShearAllowed
: 1; // if false, object cannot be sheared
184 bool bEdgeRadiusAllowed
: 1;
185 bool bNoOrthoDesired
: 1; // is true for Rect; is false for BMP, MTF
186 bool bNoContortion
: 1; // if false, contortion not possible (for crook, only true for PathObj and grouped PathObjs)
187 bool bCanConvToPath
: 1; // if false, no conversion into PathObj possible
188 bool bCanConvToPoly
: 1; // if false, no conversion into PolyObj possible
189 bool bCanConvToContour
: 1; // if false, no conversion down to whole contour possible
190 bool bCanConvToPathLineToArea
: 1; // if false, no conversion into PathObj with transformation from LineToArea possible
191 bool bCanConvToPolyLineToArea
: 1; // if false, no conversion into PolyObj with transformation from LineToArea possible
193 SdrObjTransformInfoRec();
196 ////////////////////////////////////////////////////////////////////////////////////////////////////
234 /// Abstract DrawObject
235 class SVXCORE_DLLPUBLIC SdrObject
: public SfxListener
, public cppu::OWeakObject
238 // Basic DiagramHelper support
239 virtual const std::shared_ptr
< svx::diagram::IDiagramHelper
>& getDiagramHelper() const;
240 bool isDiagram() const { return bool(getDiagramHelper()); }
243 friend class SdrObjListIter
;
244 friend class SdrObjList
;
245 friend class SdrVirtObj
;
246 friend class SdrRectObj
;
248 // OperationSmiley: Allow at each SdrObject to set a FillGeometryDefiningShape,
249 // so that for SdrObjects where this is set, the definition of a defined FillStyle
250 // will use this, but the local geometry will be filled. This allows to fill
251 // multiple shapes with a unified fill, e.g think about CustomShapes.
252 // Currently this is *only* used for CustomShapes, but may be developed to get a
253 // common mechanism - usages for it are easy to be found. The current limitation
254 // to CustomShapes allows to think about these SdrObjects to 'vanish' during the
255 // lifetime of 'this' - the SdrObjects without SdrPage and SdrModel are used as helper
256 // objects for SdrObjCustomShape and thus their lifetime is limited to the lifetime
257 // of this local object. For unifying this mechanism, some weak reference of
258 // SdrObjects would have to be thought about (not easy with the current implementation).
259 // So - allow *only* EnhancedCustomShape2d (which creates the visualizations for
260 // SdrObjCustomShape) to set this. Already allow unified read to use it - thus already
261 // allowing to implement as standard case for all kinds of SdrObjects.
262 friend class EnhancedCustomShape2d
;
263 const SdrObject
* mpFillGeometryDefiningShape
;
264 void setFillGeometryDefiningShape(const SdrObject
* pNew
) { mpFillGeometryDefiningShape
= pNew
; }
266 const SdrObject
* getFillGeometryDefiningShape() const { return mpFillGeometryDefiningShape
; }
269 // the SdrModel this objects was created with, unchanged during SdrObject lifetime
270 SdrModel
& mrSdrModelFromSdrObject
;
273 // A SdrObject always needs a SdrModel for lifetime (Pool, ...)
274 SdrObject(SdrModel
& rSdrModel
);
276 SdrObject(SdrModel
& rSdrModel
, SdrObject
const & rSource
);
278 virtual void SAL_CALL
acquire() noexcept override final
;
279 virtual void SAL_CALL
release() noexcept override final
;
281 // SdrModel/SdrPage access on SdrObject level
282 SdrPage
* getSdrPageFromSdrObject() const;
283 SdrModel
& getSdrModelFromSdrObject() const;
285 // access to possible children (SdrObjGroup/E3dScene)
286 virtual SdrObjList
* getChildrenOfSdrObject() const;
289 SdrObjList
* getParentSdrObjListFromSdrObject() const;
290 SdrObject
* getParentSdrObjectFromSdrObject() const;
293 SVX_DLLPRIVATE
void setParentOfSdrObject(SdrObjList
* pNew
);
296 // react on model/page change
297 virtual void handlePageChange(SdrPage
* pOldPage
, SdrPage
* pNewPage
);
299 void AddObjectUser(sdr::ObjectUser
& rNewUser
);
300 void RemoveObjectUser(sdr::ObjectUser
& rOldUser
);
302 sdr::contact::ViewContact
& GetViewContact() const;
304 virtual sdr::properties::BaseProperties
& GetProperties() const;
306 // DrawContact support: Methods for handling Object changes
307 void ActionChanged() const;
309 static SdrItemPool
& GetGlobalDrawObjectItemPool();
310 void SetRelativeWidth( double nValue
);
311 void SetRelativeWidthRelation( sal_Int16 eValue
);
312 void SetRelativeHeight( double nValue
);
313 void SetRelativeHeightRelation( sal_Int16 eValue
);
314 const double* GetRelativeWidth() const;
315 sal_Int16
GetRelativeWidthRelation() const;
316 const double* GetRelativeHeight() const;
317 sal_Int16
GetRelativeHeightRelation() const;
319 /// @param bNotMyself = true: set only ObjList to dirty, don't mark this object as dirty.
321 /// This is needed for instance for NbcMove, because usually one moves SnapRect and aOutRect
322 /// at the same time to avoid recomputation.
323 virtual void SetBoundAndSnapRectsDirty(bool bNotMyself
= false, bool bRecursive
= true);
325 // this method is only for access from Property objects
326 virtual void SetBoundRectDirty();
328 SfxItemPool
& GetObjectItemPool() const;
330 void AddListener(SfxListener
& rListener
);
331 void RemoveListener(SfxListener
& rListener
);
333 void AddReference(SdrVirtObj
& rVrtObj
);
334 void DelReference(SdrVirtObj
& rVrtObj
);
335 virtual SdrInventor
GetObjInventor() const;
336 virtual SdrObjKind
GetObjIdentifier() const;
337 virtual void TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const;
340 virtual SdrLayerID
GetLayer() const;
341 virtual void NbcSetLayer(SdrLayerID nLayer
);
342 virtual void SetLayer(SdrLayerID nLayer
);
343 bool isVisibleOnAnyOfTheseLayers(const SdrLayerIDSet
& rSet
) const;
345 void SendUserCall(SdrUserCallType eUserCall
, const tools::Rectangle
& rBoundRect
) const;
348 // An object may have a user-set Name (Get/SetName()), e.g SdrGrafObj, SdrObjGroup
350 // It may also have a Title and a Description for accessibility purposes.
351 virtual void SetName(const OUString
& rStr
, const bool bSetChanged
= true);
352 virtual const OUString
& GetName() const;
353 void MakeNameUnique();
354 void MakeNameUnique(std::unordered_set
<OUString
>& rNameSet
);
355 virtual void SetTitle(const OUString
& rStr
);
356 virtual OUString
GetTitle() const;
357 virtual void SetDescription(const OUString
& rStr
);
358 virtual OUString
GetDescription() const;
359 virtual void SetDecorative(bool isDecorative
);
360 virtual bool IsDecorative() const;
363 bool IsGroupObject() const;
364 virtual SdrObjList
* GetSubList() const;
366 /// The order number (aka ZOrder, aka z-index) determines whether a
367 /// SdrObject is located above or below another. Objects are painted from
368 /// lowest to highest order number. If the order of SdrObjects in the
369 /// SdrObjList is changed, the bObjOrdNumsDirty flag is set on the SdrPage
370 /// and the next GetOrdNum() call recalculates the order number of all
371 /// SdrObjects in the SdrObjList.
372 sal_uInt32
GetOrdNum() const;
374 // setting the order number should only happen from the model or from the page
375 void SetOrdNum(sal_uInt32 nNum
);
377 // GrabBagItem for interim interop purposes
378 void GetGrabBagItem(css::uno::Any
& rVal
) const;
380 virtual void SetGrabBagItem(const css::uno::Any
& rVal
);
382 // Return the position in the navigation order for the called object.
383 // Note that this method may update the navigation position of the
384 // called and of other SdrObjects. Therefore this method can not be
387 // If no navigation position has been explicitly defined then the
388 // result of GetOrdNum() is returned.
389 sal_uInt32
GetNavigationPosition() const;
391 // To make clearer that this method may trigger RecalcBoundRect and thus may be
392 // expensive and sometimes problematic (inside a bigger object change You will get
393 // non-useful BoundRects sometimes) i rename that method from GetBoundRect() to
394 // GetCurrentBoundRect().
395 virtual const tools::Rectangle
& GetCurrentBoundRect() const;
397 // To have a possibility to get the last calculated BoundRect e.g for producing
398 // the first rectangle for repaints (old and new need to be used) without forcing
399 // a RecalcBoundRect (which may be problematical and expensive sometimes) i add here
400 // a new method for accessing the last BoundRect.
401 virtual const tools::Rectangle
& GetLastBoundRect() const;
403 virtual void RecalcBoundRect();
405 void BroadcastObjectChange() const;
407 const SfxBroadcaster
* GetBroadcaster() const;
409 // set modified-flag in the model
410 virtual void SetChanged();
412 // Tooling for painting a single object to an OutputDevice. This will be needed as long
413 // as not all painting is changed to use DrawContact objects.
414 void SingleObjectPainter(OutputDevice
& rOut
) const;
415 bool LineGeometryUsageIsNecessary() const;
417 // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation, that
418 // means no change of the rotation point (only centered) and no shear allowed
419 virtual bool HasLimitedRotation() const;
421 // Returns a copy of the object. Every inherited class must reimplement this.
422 virtual rtl::Reference
<SdrObject
> CloneSdrObject(SdrModel
& rTargetModel
) const = 0;
423 // helper, since Clone always return the type of the current subclass
425 static rtl::Reference
<T
> Clone(T
const & rObj
, SdrModel
& rTargetModel
)
427 rtl::Reference
<SdrObject
> newObj
= rObj
.CloneSdrObject(rTargetModel
);
428 return static_cast<T
*>(newObj
.get());
431 // Overwriting this object makes no sense, it is too complicated for that
432 SdrObject
& operator=(const SdrObject
& rObj
) = delete;
433 SdrObject
& operator=(SdrObject
&& rObj
) = delete;
435 // TakeObjName...() is for the display in the UI, e.g. "3 frames selected"
436 virtual OUString
TakeObjNameSingul() const;
437 virtual OUString
TakeObjNamePlural() const;
439 /// The Xor-Polygon is required by the View to drag the object.
440 /// All polygons within the PolyPolygon are interpreted as PolyLine.
441 /// To get a closed Polygon, close it explicitly.
442 virtual basegfx::B2DPolyPolygon
TakeXorPoly() const;
444 /// contour for TextToContour
445 virtual basegfx::B2DPolyPolygon
TakeContour() const;
447 /// Via GetHdlCount the number of Handles can be retrieved.
448 /// Normally 8, if it's a line 2.
449 /// For Polygon objects (Polygon/Spline/Bezier) the number may be much
450 /// larger. Polygon objects are also allowed to select a point of a
451 /// selected object. The handle of that point will then be replaced by
452 /// a new set of handles (PlusHdl). For a Polygon this would be a simple
453 /// selection Handle, for a Bezier curve this may be up to 3 Handles
454 /// (including Weights).
455 /// GetHdl() and GetPlusHdl() must create Handle instances with new!
456 /// An object that returns true from HasSpacialDrag() must provide these
457 /// methods (incl. FillHdlList()).
458 virtual sal_uInt32
GetHdlCount() const;
459 virtual void AddToPlusHdlList(SdrHdlList
& rHdlList
, SdrHdl
& rHdl
) const;
460 virtual void AddToHdlList(SdrHdlList
& rHdlList
) const;
461 virtual void addCropHandles(SdrHdlList
& rTarget
) const;
463 /// The standard transformations (Move,Resize,Rotate,Mirror,Shear) are
464 /// taken over by the View (TakeXorPoly(),...).
465 /// Object type specific dragging like corner radius of Rectangle,
466 /// control points of Splines, weights of Bezier curves, pointer of
467 /// Label objects must be handled by the object itself.
468 /// To keep the Model free of state, the state is kept in the View
469 /// and then passed to the object. EndDrag usually returns true for success,
470 /// false may be returned if the dragging did not modify the object,
471 /// where the View already handles the case that the pointer was not
473 virtual bool hasSpecialDrag() const;
474 virtual bool beginSpecialDrag(SdrDragStat
& rDrag
) const;
475 virtual bool applySpecialDrag(SdrDragStat
& rDrag
);
476 virtual OUString
getSpecialDragComment(const SdrDragStat
& rDrag
) const;
477 virtual basegfx::B2DPolyPolygon
getSpecialDragPoly(const SdrDragStat
& rDrag
) const;
479 // FullDrag support. This is for standard interactions and for SdrObjOwn
480 // support. If supportsFullDrag() returns true, getFullDragClone has to
481 // return a cloned SdrObject (who's ownership it loses) at which modifications
482 // like Move(), Scale(), etc or applySpecialDrag() will be executed. That
483 // object will be visualized on overlay for full drag, but should not be
484 // part of the model, thus not changing anything since it's only a temporary
485 // helper object for interaction
486 virtual bool supportsFullDrag() const;
487 virtual rtl::Reference
<SdrObject
> getFullDragClone() const;
489 /// Every object must be able to create itself interactively.
490 /// On MouseDown first an object is created, and its BegCreate() method
491 /// is called. On every MouseMove, MovCreate() is called. BrkCreate()
492 /// is called if the user cancels the interactive object creation.
493 /// EndCreate() is called on the MouseUp event. If EndCreate() returns
494 /// true, the creation is finished; the object is inserted into the
495 /// corresponding list. Otherwise it is assumed that further points
496 /// are necessary to create the object (Polygon, ...). The parameter
497 /// eCmd contains the number of mouse clicks (if the application
499 /// BckCreate() will undo the previous EndCreate(), e.g. to delete the
500 /// last point of the Polygon. If BckCreate() returns false, creation
502 virtual bool BegCreate(SdrDragStat
& rStat
);
503 virtual bool MovCreate(SdrDragStat
& rStat
); // if true, Xor needs to be repainted
504 virtual bool EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
);
505 virtual bool BckCreate(SdrDragStat
& rStat
);
506 virtual void BrkCreate(SdrDragStat
& rStat
);
508 /// get the cursor/pointer that signals creating this object
509 virtual PointerStyle
GetCreatePointer() const;
511 /// Polygon dragged by the user when creating the object
512 virtual basegfx::B2DPolyPolygon
TakeCreatePoly(const SdrDragStat
& rDrag
) const;
514 /// The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and
515 /// SetLogicRect call the corresponding Nbc-methods, send a Repaint
516 /// broadcast and set the Modified state on the Model.
517 /// Derived classes should usually only override the Nbc methods.
518 /// Nbc means "no broadcast".
519 virtual void NbcMove (const Size
& rSiz
);
520 virtual void NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
);
521 virtual void NbcCrop (const basegfx::B2DPoint
& rRef
, double fxFact
, double fyFact
);
522 virtual void NbcRotate(const Point
& rRef
, Degree100 nAngle
, double sn
, double cs
) = 0;
523 // Utility for call sites that don't have sin and cos handy
524 void NbcRotate(const Point
& rRef
, Degree100 nAngle
);
525 virtual void NbcMirror(const Point
& rRef1
, const Point
& rRef2
);
526 virtual void NbcShear (const Point
& rRef
, Degree100 nAngle
, double tn
, bool bVShear
);
528 virtual void Move (const Size
& rSiz
);
529 virtual void Resize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
, bool bUnsetRelative
= true);
530 virtual void Crop (const basegfx::B2DPoint
& rRef
, double fxFact
, double fyFact
);
531 virtual void Rotate(const Point
& rRef
, Degree100 nAngle
, double sn
, double cs
);
532 virtual void Mirror(const Point
& rRef1
, const Point
& rRef2
);
533 virtual void Shear (const Point
& rRef
, Degree100 nAngle
, double tn
, bool bVShear
);
535 /// The relative position of a SdrObject is the distance of the upper
536 /// left corner of the logic bounding rectangle (SnapRect) to the anchor.
537 virtual void NbcSetRelativePos(const Point
& rPnt
);
538 virtual void SetRelativePos(const Point
& rPnt
);
539 virtual Point
GetRelativePos() const;
540 void ImpSetAnchorPos(const Point
& rPnt
);
541 virtual void NbcSetAnchorPos(const Point
& rPnt
);
542 virtual void SetAnchorPos(const Point
& rPnt
);
544 /// Snap is not done on the BoundRect but if possible on logic coordinates
545 /// (i.e. without considering stroke width, ...)
546 /// SetSnapRect() tries to size the Object so that it fits into the
547 /// passed Rect (without stroke width, ...)
548 virtual void RecalcSnapRect();
549 virtual const tools::Rectangle
& GetSnapRect() const;
550 virtual void SetSnapRect(const tools::Rectangle
& rRect
);
551 virtual void NbcSetSnapRect(const tools::Rectangle
& rRect
);
553 // Logic Rect: for the Rect for instance without regard to rotation angle, shear, ...
554 virtual const tools::Rectangle
& GetLogicRect() const;
555 virtual void SetLogicRect(const tools::Rectangle
& rRect
);
556 virtual void NbcSetLogicRect(const tools::Rectangle
& rRect
);
558 // the default is to set the logic rect to the given rectangle rMaxRect. If the shape
559 // has an intrinsic aspect ratio it may set the logic rect so the aspect
560 // ratio is kept but still inside the rectangle rMaxRect.
561 // If bShrinkOnly is set to true, the size of the current logic rect will not
562 // be changed if it is smaller than the given rectangle rMaxRect.
563 virtual void AdjustToMaxRect( const tools::Rectangle
& rMaxRect
, bool bShrinkOnly
= false );
565 // rotation and shear angle
566 virtual Degree100
GetRotateAngle() const;
567 virtual Degree100
GetShearAngle(bool bVertical
= false) const;
569 /// snap to special points of an Object (polygon points, center of circle)
570 virtual sal_uInt32
GetSnapPointCount() const;
571 virtual Point
GetSnapPoint(sal_uInt32 i
) const;
573 // For objects, whose points can be moved individually.
574 // (e.g. polygons, polylines, lines)
575 // The points of those objects are selected (if necessary multiselection),
576 // deleted, inserted, or as a multiselection moved or rotated...
577 // Only such objects can have PlusHandles (e.g. the weights of a Bezier curve).
578 virtual bool IsPolyObj() const;
579 virtual sal_uInt32
GetPointCount() const;
580 virtual Point
GetPoint(sal_uInt32 i
) const;
581 void SetPoint(const Point
& rPnt
, sal_uInt32 i
);
582 virtual void NbcSetPoint(const Point
& rPnt
, sal_uInt32 i
);
584 // get all geometrical data for undo/redo
585 virtual std::unique_ptr
<SdrObjGeoData
> GetGeoData() const;
586 virtual void SetGeoData(const SdrObjGeoData
& rGeo
);
589 const SfxItemSet
& GetMergedItemSet() const;
590 void SetMergedItem(const SfxPoolItem
& rItem
);
591 void ClearMergedItem(const sal_uInt16 nWhich
= 0);
592 void SetMergedItemSet(const SfxItemSet
& rSet
, bool bClearAllItems
= false);
593 const SfxPoolItem
& GetMergedItem(const sal_uInt16 nWhich
) const;
595 const T
& GetMergedItem( TypedWhichId
<T
> nWhich
) const
597 return static_cast<const T
&>(GetMergedItem(sal_uInt16(nWhich
)));
600 // syntactical sugar for ItemSet accesses
601 void SetMergedItemSetAndBroadcast(const SfxItemSet
& rSet
, bool bClearAllItems
= false);
603 // NotPersistAttr for Layer, ObjName, geometrical transformations etc.
604 void TakeNotPersistAttr(SfxItemSet
& rAttr
) const;
605 void ApplyNotPersistAttr(const SfxItemSet
& rAttr
);
606 void NbcApplyNotPersistAttr(const SfxItemSet
& rAttr
);
608 // if bDontRemoveHardAttr is false, set all attributes, which were set in the style sheet, to their default value
609 // if true, all hard attributes keep their values
610 void SetStyleSheet(SfxStyleSheet
* pNewStyleSheet
, bool bDontRemoveHardAttr
);
611 void NbcSetStyleSheet(SfxStyleSheet
* pNewStyleSheet
, bool bDontRemoveHardAttr
);
612 SfxStyleSheet
* GetStyleSheet() const;
614 virtual bool HasTextEdit() const;
616 // keep text in outliner's format
617 // SetOutlinerParaObject: transfer ownership of *pTextObject!
618 void SetOutlinerParaObject(std::optional
<OutlinerParaObject
> pTextObject
);
619 virtual void NbcSetOutlinerParaObject(std::optional
<OutlinerParaObject
> pTextObject
);
620 virtual OutlinerParaObject
* GetOutlinerParaObject() const;
621 virtual void NbcReformatText();
623 void BurnInStyleSheetAttributes();
625 // macro abilities, e.g. a rectangle as PushButton.
626 virtual bool HasMacro() const;
627 virtual SdrObject
* CheckMacroHit (const SdrObjMacroHitRec
& rRec
) const;
628 virtual PointerStyle
GetMacroPointer (const SdrObjMacroHitRec
& rRec
) const;
629 virtual void PaintMacro (OutputDevice
& rOut
, const tools::Rectangle
& rDirtyRect
, const SdrObjMacroHitRec
& rRec
) const;
630 virtual bool DoMacro (const SdrObjMacroHitRec
& rRec
);
631 bool IsMacroHit(const SdrObjMacroHitRec
& rRec
) const;
634 // (see also documentation in SvdoEdge.hxx, SdrEdgeObj, as well as SvdGlue.hxx and SvdGlEV.hxx)
636 // There are nodes and edges. In theory an edge can also be a node, but this isn't implemented yet.
637 // A node has a number of gluepoints, onto which edges can glued to
638 // An edge can be either
639 // - without any connection to any node,
640 // - or connected on one end to a node, while the other end is not connected,
641 // - or connected on both ends with exactly one node each.
642 // The edge is listener for its up to two nodes.
643 // Whenever a node is moved or resized, all its connected edges follow.
644 // This is also true for SetGluePoint()... on the node.
645 // On the other hand, moving/resizing an edge breaks the connection.
647 // automatic gluepoints:
648 // a node object must provide four vertex and corner positions
649 // usually 0: top, 1: right, 2: bottom, 3: left
650 virtual SdrGluePoint
GetVertexGluePoint(sal_uInt16 nNum
) const;
653 // 0: top-left, 1: top-right, 2: bottom-right, 3: bottom-left
654 virtual SdrGluePoint
GetCornerGluePoint(sal_uInt16 nNum
) const;
656 // list of all gluepoints, can be NULL
657 virtual const SdrGluePointList
* GetGluePointList() const;
659 // after changing the GluePointList, one has to call the object's SendRepaintBroadcast!
660 virtual SdrGluePointList
* ForceGluePointList();
662 // to be set temporarily when transforming related object(?)
663 void SetGlueReallyAbsolute(bool bOn
);
664 void NbcRotateGluePoints(const Point
& rRef
, Degree100 nAngle
, double sn
, double cs
);
665 void NbcMirrorGluePoints(const Point
& rRef1
, const Point
& rRef2
);
666 void NbcShearGluePoints (const Point
& rRef
, double tn
, bool bVShear
);
668 // if bTail1 is true, line start, otherwise line end
669 // if pObj is null disconnect
670 virtual void ConnectToNode(bool bTail1
, SdrObject
* pObj
);
671 virtual void DisconnectFromNode(bool bTail1
);
672 virtual SdrObject
* GetConnectedNode(bool bTail1
) const;
674 // sets the writing mode of the object's context
675 // Objects which itself do not support different writing modes will ignore this call.
676 // Objects which support different writing modes, but have an own, explicit writing mode set,
677 // will also ignore this call.
678 // Objects which support different writing modes, and whose own mode is set to css.text.WritingMode2.CONTEXT,
679 // will use the given writing mode to calculate their "effective writing mode".
680 // The behaviour of this method is undefined if you pass css.text.WritingMode2.CONTEXT.
681 // @param _nContextWritingMode
682 // the effective writing mode of the context of the object
683 virtual void SetContextWritingMode( const sal_Int16 _nContextWritingMode
);
685 // If an object is able to convert itself into a polygon or into a Bezier curve (or into both),
686 // then the following methods should be overridden.
687 // E.g., convert a RectObj with line width 10, SOLID_PEN into a polygon:
688 // In the bLineToArea=false mode a PolyObj with four supporting points,
689 // line width 10 and SOLID_PEN shall be created.
690 // On the contrary in the bLineToArea=true mode the generated object should
691 // still have a line attribute NULL_PEN, and the line (also line pattern)
692 // itself should be emulated by the polygon area, which thereby can be
693 // manipulated by the user afterwards.
694 // The RectObj therefore can only convert correctly if it has an area attribute NULL_BRUSH.
695 // In this case it would have to:
696 // - set SOLID_BRUSH with the color of the given pen,
697 // - set NULL_PEN, and
698 // - generate tools::PolyPolygon with two polygons with four supporting points each.
699 // In each case the return value is a SdrObject*, because it is also
700 // allowed to return group objects (e.g. for SdrTextObj).
701 // In the case of the conversion from TextObj to PathObj,
702 // both modi (bLineToArea=true/false) would be identical.
703 // The methods' default implementations report "I'm unable to do this" (false/null).
704 virtual rtl::Reference
<SdrObject
> DoConvertToPolyObj(bool bBezier
, bool bAddText
) const;
705 rtl::Reference
<SdrObject
> ConvertToPolyObj(bool bBezier
, bool bLineToArea
) const;
707 // convert this path object to contour object; bForceLineDash converts even
708 // when there is no filled new polygon created from line-to-polygon conversion,
709 // specially used for XLINE_DASH and 3D conversion
710 rtl::Reference
<SdrObject
> ConvertToContourObj(SdrObject
* pRet
, bool bForceLineDash
= false) const;
712 rtl::Reference
<SdrObject
> ImpConvertToContourObj(bool bForceLineDash
);
715 // if true, reference onto an object
716 bool IsVirtualObj() const { return m_bVirtObj
;}
718 // is true, if object can probably be filled
719 // is false, if object has probably line ends
720 // is invalid, if this is a group object
721 bool IsClosedObj() const { return m_bClosedObj
;}
723 // tdf#118662 reorganize inserted state, no local bool needed anymore,
724 // it depends on being a member of a SdrObjList
725 void InsertedStateChange();
726 bool IsInserted() const { return nullptr != getParentSdrObjListFromSdrObject(); }
728 bool IsEdgeObj() const { return m_bIsEdge
;}
729 bool Is3DObj() const { return m_bIs3DObj
;}
730 bool IsUnoObj() const { return m_bIsUnoObj
;}
731 void SetMoveProtect(bool bProt
);
732 bool IsMoveProtect() const { return m_bMovProt
;}
733 void SetResizeProtect(bool bProt
);
734 bool IsResizeProtect() const { return m_bSizProt
;}
735 void SetPrintable(bool bPrn
);
736 bool IsPrintable() const { return !m_bNoPrint
;}
737 void SetVisible(bool bVisible
);
738 bool IsVisible() const { return mbVisible
;}
739 void SetMarkProtect(bool bProt
);
740 bool IsMarkProtect() const { return m_bMarkProt
;}
741 virtual bool IsSdrTextObj() const { return false; }
742 virtual bool IsTextPath() const { return false ; }
744 /// Whether the aspect ratio should be kept by default when resizing.
745 virtual bool shouldKeepAspectRatio() const { return false; }
747 // application specific data
748 sal_uInt16
GetUserDataCount() const;
749 SdrObjUserData
* GetUserData(sal_uInt16 nNum
) const;
751 void AppendUserData(std::unique_ptr
<SdrObjUserData
> pData
);
753 // removes the record from the list and performs delete (FreeMem+Dtor).
754 void DeleteUserData(sal_uInt16 nNum
);
756 // access to the UNO representation of the shape
757 virtual css::uno::Reference
< css::drawing::XShape
> getUnoShape();
759 static SdrObject
* getSdrObjectFromXShape( const css::uno::Reference
< css::uno::XInterface
>& xInt
);
761 // notifies a change in the given property, to all applicable listeners registered at the associated SvxShape
763 // This method is equivalent to calling getShapePropertyChangeNotifier().notifyPropertyChange( _eProperty ),
764 // exception that it is allowed to be called when there does not yet exist an associated SvxShape - in which
765 // case the method will silently return without doing anything.
766 void notifyShapePropertyChange( const OUString
& rPropName
) const;
768 // transformation interface for StarOfficeAPI. This implements support for
769 // homogen 3x3 matrices containing the transformation of the SdrObject. At the
770 // moment it contains a shearX, rotation and translation, but for setting all linear
771 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
773 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
774 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
775 virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix
& rMatrix
, basegfx::B2DPolyPolygon
& rPolyPolygon
) const;
777 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
778 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
779 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
780 virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix
& rMatrix
, const basegfx::B2DPolyPolygon
& rPolyPolygon
);
782 // give info if object is in destruction
783 bool IsInDestruction() const;
785 // return if fill is != XFILL_NONE
786 bool HasFillStyle() const;
787 bool HasLineStyle() const;
789 // on import of OLE object from MS documents the BLIP size might be retrieved,
790 // the following methods are used to control it;
791 // usually this data makes no sense after the import is finished, since the object
793 const tools::Rectangle
& GetBLIPSizeRectangle() const { return maBLIPSizeRectangle
;}
794 void SetBLIPSizeRectangle( const tools::Rectangle
& aRect
);
797 virtual bool HasText() const;
799 bool Equals(const SdrObject
&) const;
801 virtual void dumpAsXml(xmlTextWriterPtr pWriter
) const;
803 /// Is this a textbox of a drawinglayer shape?
804 virtual bool IsTextBox() const;
806 void SetEmptyPresObj(bool bEpt
);
807 bool IsEmptyPresObj() const { return m_bEmptyPresObj
;}
808 void SetNotVisibleAsMaster(bool bFlg
);
809 bool IsNotVisibleAsMaster() const { return m_bNotVisibleAsMaster
;}
810 void SetUserCall(SdrObjUserCall
* pUser
);
811 SdrObjUserCall
* GetUserCall() const { return m_pUserCall
;}
812 /// @see mbDoNotInsertIntoPageAutomatically
813 void SetDoNotInsertIntoPageAutomatically(bool bSet
);
814 /// @see mbDoNotInsertIntoPageAutomatically
815 bool IsDoNotInsertIntoPageAutomatically() const { return mbDoNotInsertIntoPageAutomatically
;}
817 // Warning: this method should only be used if you really know what you're doing
818 sal_uInt32
GetOrdNumDirect() const { return m_nOrdNum
;}
821 bool DoesSupportTextIndentingOnLineWidthChange() const { return mbSupportTextIndentingOnLineWidthChange
;}
823 const Point
& GetAnchorPos() const;
826 bool LineIsOutsideGeometry() const { return mbLineIsOutsideGeometry
;}
828 // Set the position in the navigation position to the given value.
829 // This method is typically used only by the model after a change to
830 // the navigation order.
831 // This method does not change the navigation position of other
833 // Use SdrObjList::SetObjectNavigationPosition() instead.
834 void SetNavigationPosition (const sal_uInt32 nPosition
);
836 /// Sets a new UNO representation of the shape
838 /// Calling this function is only allowed for the UNO representation
841 /// The default implementation of this function sets the new UNO
842 /// shape. Derived classes should override the function to handle
843 /// any other actions that are needed when the shape is being
846 /// The implementation _must_ call the same method of its parent
847 /// class (preferably as the first step)!
848 virtual void setUnoShape( const css::uno::Reference
< css::drawing::XShape
>& _rxUnoShape
);
850 const css::uno::WeakReference
< css::drawing::XShape
>& getWeakUnoShape() const { return maWeakUnoShape
; }
852 // return true if a bg was set, false otherwise
853 bool setSuitableOutlinerBg(Outliner
& rOutliner
) const;
854 // If fillstyle is drawing::FillStyle_BITMAP, returns the graphic.
855 const Graphic
* getFillGraphic() const;
857 const OUString
& getHyperlink() const { return msHyperlink
; }
858 void setHyperlink(const OUString
& sHyperlink
) { msHyperlink
= sHyperlink
; }
860 void ForceMetricToItemPoolMetric(basegfx::B2DPolyPolygon
& rPolyPolygon
) const noexcept
;
863 const tools::Rectangle
& getOutRectangle() const;
864 void setOutRectangleConst(tools::Rectangle
const& rRectangle
) const; // need to do something about this
865 void setOutRectangle(tools::Rectangle
const& rRectangle
);
866 void resetOutRectangle();
867 void moveOutRectangle(sal_Int32 nXDelta
, sal_Int32 nYDelta
);
869 mutable tools::Rectangle m_aOutRect
; // surrounding rectangle for Paint (incl. LineWidth, ...)
870 Point m_aAnchor
; // anchor position (Writer)
871 SdrObjUserCall
* m_pUserCall
;
872 std::unique_ptr
<SdrObjPlusData
>
873 m_pPlusData
; // Broadcaster, UserData, connectors, ... (this is the Bitsack)
874 // object is only pointing to another one
876 bool m_bSnapRectDirty
: 1;
877 // the following flags will be streamed
878 bool m_bMovProt
: 1; // if true, the position is protected
879 bool m_bSizProt
: 1; // if true, the size is protected
880 // If bEmptyPresObj is true, it is a presentation object that has no content yet.
881 // The flag's default value is false.
882 // The management is done by the application.
883 // Neither assign operator nor cloning copies the flag!
884 // The flag is persistent.
885 bool m_bEmptyPresObj
: 1; // empty presentation object (Draw)
886 // if true, object is invisible as object of the MasterPage
887 bool m_bNotVisibleAsMaster
: 1;
888 // if true, the object is closed, i.e. no line, arc...
889 bool m_bClosedObj
: 1;
892 bool m_bIsUnoObj
: 1;
894 bool mbLineIsOutsideGeometry
: 1;
896 bool mbSupportTextIndentingOnLineWidthChange
: 1;
898 virtual ~SdrObject() override
;
900 virtual std::unique_ptr
<sdr::properties::BaseProperties
> CreateObjectSpecificProperties() = 0;
902 virtual std::unique_ptr
<sdr::contact::ViewContact
> CreateObjectSpecificViewContact();
904 tools::Rectangle
ImpDragCalcRect(const SdrDragStat
& rDrag
) const;
906 // for GetDragComment
907 OUString
ImpGetDescriptionStr(TranslateId pStrCacheID
) const;
909 void ImpForcePlusData();
911 OUString
GetMetrStr(tools::Long nVal
) const;
913 /// A derived class must override these 3 methods if it has own geometric
914 /// data that must be saved for Undo.
915 /// NewGeoData() creates an empty instance of a class derived from
917 virtual std::unique_ptr
<SdrObjGeoData
> NewGeoData() const;
918 virtual void SaveGeoData(SdrObjGeoData
& rGeo
) const;
919 virtual void RestoreGeoData(const SdrObjGeoData
& rGeo
);
922 const SfxItemSet
& GetObjectItemSet() const;
923 void SetObjectItem(const SfxPoolItem
& rItem
);
924 void SetObjectItemSet(const SfxItemSet
& rSet
);
925 const SfxPoolItem
& GetObjectItem(const sal_uInt16 nWhich
) const;
926 template<class T
> const T
& GetObjectItem( TypedWhichId
<T
> nWhich
) const
928 return static_cast<const T
&>(GetObjectItem(sal_uInt16(nWhich
)));
931 const SfxItemSet
* getBackgroundFillSet() const;
933 virtual void InternalSetStyleSheet(SfxStyleSheet
* pNewStyleSheet
, bool bDontRemoveHardAttr
, bool bBroadcast
);
937 std::unique_ptr
<Impl
> mpImpl
;
938 SdrObjList
* mpParentOfSdrObject
; // list that includes this object
939 sal_uInt32 m_nOrdNum
; // order number of the object in the list
940 std::unique_ptr
<SfxGrabBagItem
> m_pGrabBagItem
; // holds the GrabBagItem property
941 // Position in the navigation order. SAL_MAX_UINT32 when not used.
942 sal_uInt32 mnNavigationPosition
;
943 SdrLayerID mnLayerID
;
944 bool m_bNoPrint
: 1; // if true, the object is not printed.
945 bool mbVisible
: 1; // if false, the object is not visible on screen (but maybe on printer, depending on bNoprint
946 bool m_bMarkProt
: 1; // marking forbidden, persistent
947 // on import of OLE object from MS documents the BLIP size might be retrieved,
948 // in this case the following member is initialized as nonempty rectangle
949 tools::Rectangle maBLIPSizeRectangle
;
950 std::unique_ptr
<sdr::properties::BaseProperties
>
952 std::unique_ptr
<sdr::contact::ViewContact
>
955 // do not use directly, always use getSvxShape() if you have to, because not all
956 // SdrObjects have an associated SvxShape subclass (e.g. reportdesign)
957 SvxShape
* mpSvxShape
;
958 css::uno::WeakReference
< css::drawing::XShape
>
961 // HACK: Do not automatically insert newly created object into a page.
962 // The user needs to do it manually later.
963 bool mbDoNotInsertIntoPageAutomatically
;
964 // Hyperlink for the whole shape
965 OUString msHyperlink
;
967 // only for internal use!
968 SvxShape
* getSvxShape();
970 SdrObject( const SdrObject
& ) = delete;
973 SVXCORE_DLLPUBLIC E3dScene
* DynCastE3dScene(SdrObject
*);
974 inline const E3dScene
* DynCastE3dScene(const SdrObject
* p
) { return DynCastE3dScene(const_cast<SdrObject
*>(p
)); }
975 SVXCORE_DLLPUBLIC E3dObject
* DynCastE3dObject(SdrObject
*);
976 inline const E3dObject
* DynCastE3dObject(const SdrObject
* p
) { return DynCastE3dObject(const_cast<SdrObject
*>(p
)); }
977 SVXCORE_DLLPUBLIC SdrTextObj
* DynCastSdrTextObj(SdrObject
*);
978 inline const SdrTextObj
* DynCastSdrTextObj(const SdrObject
* p
) { return DynCastSdrTextObj(const_cast<SdrObject
*>(p
)); }
981 struct SdrObjCreatorParams
983 SdrInventor nInventor
;
984 SdrObjKind nObjIdentifier
;
989 * Whoever creates his own objects must set a link in the SdrObjFactory class.
990 * The handler must have the following signature:
991 * void Hdl(SdrObjFactory*)
992 * He must take a look at the referenced instance's nInventor and nIdentifier values,
993 * and must create a new drawing object instance accordingly.
994 * He must also make the pNewObj pointer reference to this instance.
996 class SVXCORE_DLLPUBLIC SdrObjFactory
999 static rtl::Reference
<SdrObject
> MakeNewObject(
1000 SdrModel
& rSdrModel
,
1001 SdrInventor nInventor
,
1002 SdrObjKind nObjIdentifier
,
1003 const tools::Rectangle
* pSnapRect
= nullptr);
1005 static void InsertMakeObjectHdl(Link
<SdrObjCreatorParams
, rtl::Reference
<SdrObject
>> const & rLink
);
1006 static void RemoveMakeObjectHdl(Link
<SdrObjCreatorParams
, rtl::Reference
<SdrObject
>> const & rLink
);
1009 static SVX_DLLPRIVATE
rtl::Reference
<SdrObject
> CreateObjectFromFactory(
1010 SdrModel
& rSdrModel
,
1011 SdrInventor nInventor
,
1012 SdrObjKind nIdentifier
);
1014 SdrObjFactory() = delete;
1017 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */