make ValueTransfer easier to understand
[LibreOffice.git] / include / svx / svdobj.hxx
blobfe050c0d01574a245c73cb7f3fc4f0181fe8e02f
1 /*
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 .
19 #pragma once
21 #include <memory>
22 #include <com/sun/star/uno/Any.hxx>
23 #include <cppuhelper/weakref.hxx>
24 #include <rtl/ustring.hxx>
25 #include <vcl/outdev.hxx>
26 #include <svl/lstner.hxx>
27 #include <svl/poolitem.hxx>
28 #include <svl/typedwhich.hxx>
29 #include <tools/degree.hxx>
30 #include <svx/DiagramDataInterface.hxx>
31 #include <svx/svdtypes.hxx>
32 #include <svx/svdobjkind.hxx>
33 #include <svx/svxdllapi.h>
34 #include <svx/shapeproperty.hxx>
35 #include <tools/link.hxx>
36 #include <tools/weakbase.h>
37 #include <tools/gen.hxx>
38 #include <unotools/resmgr.hxx>
40 #include <unordered_set>
42 class SfxBroadcaster;
43 class AutoTimer;
44 class OutlinerParaObject;
45 class Outliner;
46 class SdrOutliner;
47 class SdrDragStat;
48 class SdrHdl;
49 class SdrHdlList;
50 class SdrItemPool;
51 class SdrModel;
52 class SdrObjList;
53 class SdrObject;
54 class SdrPage;
55 class SdrPageView;
56 class SdrView;
57 class SfxItemSet;
58 class SfxGrabBagItem;
59 class SfxSetItem;
60 class SfxStyleSheet;
61 class SfxUndoAction;
62 class XFillAttrSetItem;
63 class XLineAttrSetItem;
64 class SfxItemPool;
65 namespace tools { class PolyPolygon; }
66 class SfxPoolItem;
67 class SdrVirtObj;
68 class SdrDragView;
69 class SdrObjUserDataList;
70 class SdrObjPlusData;
71 class SdrGluePoint;
72 class SdrGluePointList;
73 class SdrLayerIDSet;
74 class Fraction;
75 enum class PointerStyle;
76 class Graphic;
77 class SvxShape;
79 namespace basegfx
81 class B2DPoint;
82 class B2DPolyPolygon;
83 class B2DHomMatrix;
86 namespace sdr { class ObjectUser; }
87 namespace sdr::properties { class BaseProperties; }
88 namespace sdr::contact { class ViewContact; }
90 namespace svx { class PropertyChangeNotifier; }
91 namespace com::sun::star::drawing { class XShape; }
94 struct SVXCORE_DLLPUBLIC SdrObjectFreeOp;
96 // helper for constructing std::unique_ptr for SdrObjects where a
97 // deleter is needed - here, SdrObject::Free needs to be used.
98 typedef std::unique_ptr< SdrObject, SdrObjectFreeOp > SdrObjectUniquePtr;
100 enum class SdrInventor : sal_uInt32 {
101 Unknown = 0,
102 BasicDialog = sal_uInt32( 'D' | ('L' << 8) | ('G' << 16) | ('1' << 24) ),
103 Default = sal_uInt32( 'S' | ('V' << 8) | ('D' << 16) | ('r' << 24) ),
104 E3d = sal_uInt32( 'E' | ('3' << 8) | ('D' << 16) | ('1' << 24) ),
105 FmForm = sal_uInt32( 'F' | ('M' << 8) | ('0' << 16) | ('1' << 24) ),
106 IMap = sal_uInt32( 'I' | ('M' << 8) | ('A' << 16) | ('P' << 24) ),
107 ReportDesign = sal_uInt32( 'R' | ('P' << 8) | ('T' << 16) | ('1' << 24) ),
108 ScOrSwDraw = sal_uInt32( 'S' | ('C' << 8) | ('3' << 16) | ('0' << 24) ), // Used in sc/ and sw/
109 SgaImap = sal_uInt32( 'S' | ('D' << 8) | ('U' << 16) | ('D' << 24) ),
110 StarDrawUserData = sal_uInt32( 'S' | ('D' << 8) | ('U' << 16) | ('D' << 24) ),
111 Swg = sal_uInt32( 'S' | ('W' << 8) | ('G' << 16) ),
114 enum class SdrUserCallType {
115 MoveOnly, // only moved, size unchanged
116 Resize, // size and maybe position changed
117 ChangeAttr, // attribute changed. Eventually new size, because of line width
118 Delete, // object is going to be deleted soon, no attributes anymore
119 Inserted, // inserted into an object list (e.g. Page)
120 Removed, // removed from an object list
121 ChildMoveOnly, // a child within a group has changed
122 ChildResize, // a child within a group has changed
123 ChildChangeAttr, // a child within a group has changed
124 ChildDelete, // a child within a group has changed
125 ChildInserted, // a child within a group has changed
126 ChildRemoved // a child within a group has changed
129 class SVXCORE_DLLPUBLIC SdrObjUserCall
131 public:
132 virtual ~SdrObjUserCall();
133 virtual void Changed(const SdrObject& rObj, SdrUserCallType eType, const tools::Rectangle& rOldBoundRect);
136 class SVXCORE_DLLPUBLIC SdrObjMacroHitRec
138 public:
139 Point aPos;
140 const SdrLayerIDSet* pVisiLayer;
141 const SdrPageView* pPageView;
142 sal_uInt16 nTol;
144 SdrObjMacroHitRec();
148 * User data of a drawing object, e.g. application specific data.
149 * Every drawing object can have an arbitrary amount of such records (SV list).
150 * Whoever wants to save data here, must inherit from this and set a corresponding link in the factory.
152 class SVXCORE_DLLPUBLIC SdrObjUserData
154 SdrInventor nInventor;
155 sal_uInt16 nIdentifier;
157 void operator=(const SdrObjUserData& rData) = delete;
158 bool operator==(const SdrObjUserData& rData) const = delete;
159 bool operator!=(const SdrObjUserData& rData) const = delete;
161 public:
162 SdrObjUserData(SdrInventor nInv, sal_uInt16 nId);
163 SdrObjUserData(const SdrObjUserData& rData);
164 virtual ~SdrObjUserData();
166 virtual std::unique_ptr<SdrObjUserData> Clone(SdrObject* pObj1) const = 0; // #i71039# NULL -> 0
167 SdrInventor GetInventor() const { return nInventor;}
168 sal_uInt16 GetId() const { return nIdentifier;}
172 * All geometrical data of an arbitrary object for use in undo/redo
174 class SVXCORE_DLLPUBLIC SdrObjGeoData
176 public:
177 tools::Rectangle aBoundRect;
178 Point aAnchor;
179 std::unique_ptr<SdrGluePointList>
180 pGPL;
181 bool bMovProt;
182 bool bSizProt;
183 bool bNoPrint;
184 bool bClosedObj;
185 bool mbVisible;
186 SdrLayerID mnLayerID;
188 public:
189 SdrObjGeoData();
190 virtual ~SdrObjGeoData();
194 * Provides information about various ZObject properties
196 class SVXCORE_DLLPUBLIC SdrObjTransformInfoRec
198 public:
199 bool bMoveAllowed : 1; // if false, object cannot be moved
200 bool bResizeFreeAllowed : 1; // if false, object cannot be resized freely
201 bool bResizePropAllowed : 1; // if false, object cannot even be resized proportionally
202 bool bRotateFreeAllowed : 1; // if false, object cannot be rotated freely
203 bool bRotate90Allowed : 1; // if false, object cannot even be rotated in 90 degree steps
204 bool bMirrorFreeAllowed : 1; // if false, object cannot be mirrored freely
205 bool bMirror45Allowed : 1; // if false, object cannot even be mirrored over axes in a 45 degree raster
206 bool bMirror90Allowed : 1; // if false, object cannot even be mirrored over axes in a 90 degree raster
207 bool bTransparenceAllowed : 1; // if false, object does not have an interactive transparence control
208 bool bShearAllowed : 1; // if false, object cannot be sheared
209 bool bEdgeRadiusAllowed : 1;
210 bool bNoOrthoDesired : 1; // is true for Rect; is false for BMP, MTF
211 bool bNoContortion : 1; // if false, contortion not possible (for crook, only true for PathObj and grouped PathObjs)
212 bool bCanConvToPath : 1; // if false, no conversion into PathObj possible
213 bool bCanConvToPoly : 1; // if false, no conversion into PolyObj possible
214 bool bCanConvToContour : 1; // if false, no conversion down to whole contour possible
215 bool bCanConvToPathLineToArea : 1; // if false, no conversion into PathObj with transformation from LineToArea possible
216 bool bCanConvToPolyLineToArea : 1; // if false, no conversion into PolyObj with transformation from LineToArea possible
218 SdrObjTransformInfoRec();
221 ////////////////////////////////////////////////////////////////////////////////////////////////////
223 // SdrObject
224 // SdrAttrObj
225 // E3dObject
226 // E3dCompoundObject
227 // E3dCubeObj
228 // E3dExtrudeObj
229 // E3dLatheObj
230 // E3dPolygonObj
231 // E3dSphereObj
232 // E3dScene
233 // SdrTextObj
234 // SdrObjCustomShape
235 // OCustomShape
236 // SdrEdgeObj
237 // SdrMeasureObj
238 // SdrPathObj
239 // SdrRectObj
240 // SdrCaptionObj
241 // SdrCircObj
242 // SdrGrafObj
243 // SdrMediaObj
244 // SdrOle2Obj
245 // OOle2Obj
246 // SdrUnoObj
247 // DlgEdObj
248 // DlgEdForm
249 // OUnoObject
250 // FmFormObj
251 // SdrTableObj
252 // SdrObjGroup
253 // SdrPageObj
254 // SdrVirtObj
255 // SwDrawVirtObj
256 // SwVirtFlyDrawObj
257 // SwFlyDrawObj
259 /// Abstract DrawObject
260 class SVXCORE_DLLPUBLIC SdrObject : public SfxListener, public tools::WeakBase
262 private:
263 friend class SdrObjListIter;
264 friend class SdrObjList;
265 friend class SdrVirtObj;
266 friend class SdrRectObj;
268 // OperationSmiley: Allow at each SdrObject to set a FillGeometryDefiningShape,
269 // so that for SdrObjects where this is set, the definition of a defined FillStyle
270 // will use this, but the local geometry will be filled. This allows to fill
271 // multiple shapes with a unified fill, e.g think about CustomShapes.
272 // Currently this is *only* used for CustomShapes, but may be developed to get a
273 // common mechanism - usages for it are easy to be found. The current limitation
274 // to CustomShapes allows to think about these SdrObjects to 'vanish' during the
275 // lifetime of 'this' - the SdrObjects without SdrPage and SdrModel are used as helper
276 // objects for SdrObjCustomShape and thus their lifetime is limited to the lifetime
277 // of this local object. For unifying this mechanism, some weak reference of
278 // SdrObjects would have to be thought about (not easy with the current implementation).
279 // So - allow *only* EnhancedCustomShape2d (which creates the visualizations for
280 // SdrObjCustomShape) to set this. Already allow unified read to use it - thus already
281 // allowing to implement as standard case for all kinds of SdrObjects.
282 friend class EnhancedCustomShape2d;
283 const SdrObject* mpFillGeometryDefiningShape;
284 void setFillGeometryDefiningShape(const SdrObject* pNew) { mpFillGeometryDefiningShape = pNew; }
285 public:
286 const SdrObject* getFillGeometryDefiningShape() const { return mpFillGeometryDefiningShape; }
288 private:
289 // the SdrModel this objects was created with, unchanged during SdrObject lifetime
290 SdrModel& mrSdrModelFromSdrObject;
292 public:
293 // A SdrObject always needs a SdrModel for lifetime (Pool, ...)
294 SdrObject(SdrModel& rSdrModel);
295 // Copy constructor
296 SdrObject(SdrModel& rSdrModel, SdrObject const & rSource);
298 // SdrModel/SdrPage access on SdrObject level
299 SdrPage* getSdrPageFromSdrObject() const;
300 SdrModel& getSdrModelFromSdrObject() const;
302 // access to possible children (SdrObjGroup/E3dScene)
303 virtual SdrObjList* getChildrenOfSdrObject() const;
305 // access to parent
306 SdrObjList* getParentSdrObjListFromSdrObject() const;
307 SdrObject* getParentSdrObjectFromSdrObject() const;
309 private:
310 SVX_DLLPRIVATE void setParentOfSdrObject(SdrObjList* pNew);
312 public:
313 // react on model/page change
314 virtual void handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage);
316 void AddObjectUser(sdr::ObjectUser& rNewUser);
317 void RemoveObjectUser(sdr::ObjectUser& rOldUser);
319 sdr::contact::ViewContact& GetViewContact() const;
321 virtual sdr::properties::BaseProperties& GetProperties() const;
323 // DrawContact support: Methods for handling Object changes
324 void ActionChanged() const;
326 static SdrItemPool& GetGlobalDrawObjectItemPool();
327 void SetRelativeWidth( double nValue );
328 void SetRelativeWidthRelation( sal_Int16 eValue );
329 void SetRelativeHeight( double nValue );
330 void SetRelativeHeightRelation( sal_Int16 eValue );
331 const double* GetRelativeWidth() const;
332 sal_Int16 GetRelativeWidthRelation() const;
333 const double* GetRelativeHeight() const;
334 sal_Int16 GetRelativeHeightRelation() const;
336 void SetDiagramData(std::shared_ptr<DiagramDataInterface> pDiagramData);
337 const std::shared_ptr<DiagramDataInterface> & GetDiagramData() const;
339 /// @param bNotMyself = true: set only ObjList to dirty, don't mark this object as dirty.
341 /// This is needed for instance for NbcMove, because usually one moves SnapRect and aOutRect
342 /// at the same time to avoid recomputation.
343 virtual void SetBoundAndSnapRectsDirty(bool bNotMyself = false, bool bRecursive = true);
345 // frees the SdrObject pointed to by the argument
346 // In case the object has an SvxShape, which has the ownership of the object, it
347 // is actually *not* deleted.
348 static void Free( SdrObject*& _rpObject );
350 // this method is only for access from Property objects
351 virtual void SetBoundRectDirty();
353 SfxItemPool & GetObjectItemPool() const;
355 void AddListener(SfxListener& rListener);
356 void RemoveListener(SfxListener& rListener);
358 void AddReference(SdrVirtObj& rVrtObj);
359 void DelReference(SdrVirtObj& rVrtObj);
360 virtual SdrInventor GetObjInventor() const;
361 virtual SdrObjKind GetObjIdentifier() const;
362 virtual void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const;
364 // Layer interface
365 virtual SdrLayerID GetLayer() const;
366 virtual void NbcSetLayer(SdrLayerID nLayer);
367 virtual void SetLayer(SdrLayerID nLayer);
368 // renaming GetSdrLayerIDSet -> getMergedHierarchySdrLayerIDSet to make clear what happens here. rSet needs to be empty.
369 void getMergedHierarchySdrLayerIDSet(SdrLayerIDSet& rSet) const;
371 void SendUserCall(SdrUserCallType eUserCall, const tools::Rectangle& rBoundRect) const;
373 // #i68101#
374 // An object may have a user-set Name (Get/SetName()), e.g SdrGrafObj, SdrObjGroup
375 // or SdrOle2Obj.
376 // It may also have a Title and a Description for accessibility purposes.
377 void SetName(const OUString& rStr, const bool bSetChanged = true);
378 OUString GetName() const;
379 void MakeNameUnique();
380 void MakeNameUnique(std::unordered_set<OUString>& rNameSet);
381 void SetTitle(const OUString& rStr);
382 OUString GetTitle() const;
383 void SetDescription(const OUString& rStr);
384 OUString GetDescription() const;
386 // for group objects
387 bool IsGroupObject() const;
388 virtual SdrObjList* GetSubList() const;
390 /// The order number (aka ZOrder, aka z-index) determines whether a
391 /// SdrObject is located above or below another. Objects are painted from
392 /// lowest to highest order number. If the order of SdrObjects in the
393 /// SdrObjList is changed, the bObjOrdNumsDirty flag is set on the SdrPage
394 /// and the next GetOrdNum() call recalculates the order number of all
395 /// SdrObjects in the SdrObjList.
396 sal_uInt32 GetOrdNum() const;
398 // setting the order number should only happen from the model or from the page
399 void SetOrdNum(sal_uInt32 nNum);
401 // GrabBagItem for interim interop purposes
402 void GetGrabBagItem(css::uno::Any& rVal) const;
404 void SetGrabBagItem(const css::uno::Any& rVal);
406 // Return the position in the navigation order for the called object.
407 // Note that this method may update the navigation position of the
408 // called and of other SdrObjects. Therefore this method can not be
409 // const.
410 // @return
411 // If no navigation position has been explicitly defined then the
412 // result of GetOrdNum() is returned.
413 sal_uInt32 GetNavigationPosition() const;
415 // To make clearer that this method may trigger RecalcBoundRect and thus may be
416 // expensive and sometimes problematic (inside a bigger object change You will get
417 // non-useful BoundRects sometimes) i rename that method from GetBoundRect() to
418 // GetCurrentBoundRect().
419 virtual const tools::Rectangle& GetCurrentBoundRect() const;
421 // To have a possibility to get the last calculated BoundRect e.g for producing
422 // the first rectangle for repaints (old and new need to be used) without forcing
423 // a RecalcBoundRect (which may be problematical and expensive sometimes) i add here
424 // a new method for accessing the last BoundRect.
425 virtual const tools::Rectangle& GetLastBoundRect() const;
427 virtual void RecalcBoundRect();
429 void BroadcastObjectChange() const;
431 const SfxBroadcaster* GetBroadcaster() const;
433 // set modified-flag in the model
434 virtual void SetChanged();
436 // Tooling for painting a single object to an OutputDevice. This will be needed as long
437 // as not all painting is changed to use DrawContact objects.
438 void SingleObjectPainter(OutputDevice& rOut) const;
439 bool LineGeometryUsageIsNecessary() const;
441 // RotGrfFlyFrame: If true, this SdrObject supports only limited rotation, that
442 // means no change of the rotation point (only centered) and no shear allowed
443 virtual bool HasLimitedRotation() const;
445 // Returns a copy of the object. Every inherited class must reimplement this.
446 virtual SdrObject* CloneSdrObject(SdrModel& rTargetModel) const;
448 // Overwriting this object makes no sense, it is too complicated for that
449 SdrObject& operator=(const SdrObject& rObj) = delete;
450 SdrObject& operator=(SdrObject&& rObj) = delete;
452 // TakeObjName...() is for the display in the UI, e.g. "3 frames selected"
453 virtual OUString TakeObjNameSingul() const;
454 virtual OUString TakeObjNamePlural() const;
456 /// The Xor-Polygon is required by the View to drag the object.
457 /// All polygons within the PolyPolygon are interpreted as PolyLine.
458 /// To get a closed Polygon, close it explicitly.
459 virtual basegfx::B2DPolyPolygon TakeXorPoly() const;
461 /// contour for TextToContour
462 virtual basegfx::B2DPolyPolygon TakeContour() const;
464 /// Via GetHdlCount the number of Handles can be retrieved.
465 /// Normally 8, if it's a line 2.
466 /// For Polygon objects (Polygon/Spline/Bezier) the number may be much
467 /// larger. Polygon objects are also allowed to select a point of a
468 /// selected object. The handle of that point will then be replaced by
469 /// a new set of handles (PlusHdl). For a Polygon this would be a simple
470 /// selection Handle, for a Bezier curve this may be up to 3 Handles
471 /// (including Weights).
472 /// GetHdl() and GetPlusHdl() must create Handle instances with new!
473 /// An object that returns true from HasSpacialDrag() must provide these
474 /// methods (incl. FillHdlList()).
475 virtual sal_uInt32 GetHdlCount() const;
476 virtual void AddToPlusHdlList(SdrHdlList& rHdlList, SdrHdl& rHdl) const;
477 virtual void AddToHdlList(SdrHdlList& rHdlList) const;
478 virtual void addCropHandles(SdrHdlList& rTarget) const;
480 /// The standard transformations (Move,Resize,Rotate,Mirror,Shear) are
481 /// taken over by the View (TakeXorPoly(),...).
482 /// Object type specific dragging like corner radius of Rectangle,
483 /// control points of Splines, weights of Bezier curves, pointer of
484 /// Label objects must be handled by the object itself.
485 /// To keep the Model free of state, the state is kept in the View
486 /// and then passed to the object. EndDrag usually returns true for success,
487 /// false may be returned if the dragging did not modify the object,
488 /// where the View already handles the case that the pointer was not
489 /// moved at all.
490 virtual bool hasSpecialDrag() const;
491 virtual bool beginSpecialDrag(SdrDragStat& rDrag) const;
492 virtual bool applySpecialDrag(SdrDragStat& rDrag);
493 virtual OUString getSpecialDragComment(const SdrDragStat& rDrag) const;
494 virtual basegfx::B2DPolyPolygon getSpecialDragPoly(const SdrDragStat& rDrag) const;
496 // FullDrag support. This is for standard interactions and for SdrObjOwn
497 // support. If supportsFullDrag() returns true, getFullDragClone has to
498 // return a cloned SdrObject (who's ownership it loses) at which modifications
499 // like Move(), Scale(), etc or applySpecialDrag() will be executed. That
500 // object will be visualized on overlay for full drag, but should not be
501 // part of the model, thus not changing anything since it's only a temporary
502 // helper object for interaction
503 virtual bool supportsFullDrag() const;
504 virtual SdrObjectUniquePtr getFullDragClone() const;
506 /// Every object must be able to create itself interactively.
507 /// On MouseDown first an object is created, and its BegCreate() method
508 /// is called. On every MouseMove, MovCreate() is called. BrkCreate()
509 /// is called if the user cancels the interactive object creation.
510 /// EndCreate() is called on the MouseUp event. If EndCreate() returns
511 /// true, the creation is finished; the object is inserted into the
512 /// corresponding list. Otherwise it is assumed that further points
513 /// are necessary to create the object (Polygon, ...). The parameter
514 /// eCmd contains the number of mouse clicks (if the application
515 /// provides it).
516 /// BckCreate() will undo the previous EndCreate(), e.g. to delete the
517 /// last point of the Polygon. If BckCreate() returns false, creation
518 /// is cancelled.
519 virtual bool BegCreate(SdrDragStat& rStat);
520 virtual bool MovCreate(SdrDragStat& rStat); // if true, Xor needs to be repainted
521 virtual bool EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd);
522 virtual bool BckCreate(SdrDragStat& rStat);
523 virtual void BrkCreate(SdrDragStat& rStat);
525 /// get the cursor/pointer that signals creating this object
526 virtual PointerStyle GetCreatePointer() const;
528 /// Polygon dragged by the user when creating the object
529 virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat& rDrag) const;
531 /// The methods Move, Resize, Rotate, Mirror, Shear, SetSnapRect and
532 /// SetLogicRect call the corresponding Nbc-methods, send a Repaint
533 /// broadcast and set the Modified state on the Model.
534 /// Derived classes should usually only override the Nbc methods.
535 /// Nbc means "no broadcast".
536 virtual void NbcMove (const Size& rSiz);
537 virtual void NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact);
538 virtual void NbcCrop (const basegfx::B2DPoint& rRef, double fxFact, double fyFact);
539 virtual void NbcRotate(const Point& rRef, Degree100 nAngle, double sn, double cs);
540 // Utility for call sites that don't have sin and cos handy
541 void NbcRotate(const Point& rRef, Degree100 nAngle);
542 virtual void NbcMirror(const Point& rRef1, const Point& rRef2);
543 virtual void NbcShear (const Point& rRef, Degree100 nAngle, double tn, bool bVShear);
545 virtual void Move (const Size& rSiz);
546 virtual void Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative = true);
547 virtual void Crop (const basegfx::B2DPoint& rRef, double fxFact, double fyFact);
548 virtual void Rotate(const Point& rRef, Degree100 nAngle, double sn, double cs);
549 virtual void Mirror(const Point& rRef1, const Point& rRef2);
550 virtual void Shear (const Point& rRef, Degree100 nAngle, double tn, bool bVShear);
552 /// The relative position of a SdrObject is the distance of the upper
553 /// left corner of the logic bounding rectangle (SnapRect) to the anchor.
554 virtual void NbcSetRelativePos(const Point& rPnt);
555 virtual void SetRelativePos(const Point& rPnt);
556 virtual Point GetRelativePos() const;
557 void ImpSetAnchorPos(const Point& rPnt);
558 virtual void NbcSetAnchorPos(const Point& rPnt);
559 virtual void SetAnchorPos(const Point& rPnt);
561 /// Snap is not done on the BoundRect but if possible on logic coordinates
562 /// (i.e. without considering stroke width, ...)
563 /// SetSnapRect() tries to size the Object so that it fits into the
564 /// passed Rect (without stroke width, ...)
565 virtual void RecalcSnapRect();
566 virtual const tools::Rectangle& GetSnapRect() const;
567 virtual void SetSnapRect(const tools::Rectangle& rRect);
568 virtual void NbcSetSnapRect(const tools::Rectangle& rRect);
570 // Logic Rect: for the Rect for instance without regard to rotation angle, shear, ...
571 virtual const tools::Rectangle& GetLogicRect() const;
572 virtual void SetLogicRect(const tools::Rectangle& rRect);
573 virtual void NbcSetLogicRect(const tools::Rectangle& rRect);
575 // the default is to set the logic rect to the given rectangle rMaxRect. If the shape
576 // has an intrinsic aspect ratio it may set the logic rect so the aspect
577 // ratio is kept but still inside the rectangle rMaxRect.
578 // If bShrinkOnly is set to true, the size of the current logic rect will not
579 // be changed if it is smaller than the given rectangle rMaxRect.
580 virtual void AdjustToMaxRect( const tools::Rectangle& rMaxRect, bool bShrinkOnly = false );
582 // rotation and shear angle
583 virtual Degree100 GetRotateAngle() const;
584 virtual Degree100 GetShearAngle(bool bVertical = false) const;
586 /// snap to special points of an Object (polygon points, center of circle)
587 virtual sal_uInt32 GetSnapPointCount() const;
588 virtual Point GetSnapPoint(sal_uInt32 i) const;
590 // For objects, whose points can be moved individually.
591 // (e.g. polygons, polylines, lines)
592 // The points of those objects are selected (if necessary multiselection),
593 // deleted, inserted, or as a multiselection moved or rotated...
594 // Only such objects can have PlusHandles (e.g. the weights of a Bezier curve).
595 virtual bool IsPolyObj() const;
596 virtual sal_uInt32 GetPointCount() const;
597 virtual Point GetPoint(sal_uInt32 i) const;
598 void SetPoint(const Point& rPnt, sal_uInt32 i);
599 virtual void NbcSetPoint(const Point& rPnt, sal_uInt32 i);
601 // get all geometrical data for undo/redo
602 virtual std::unique_ptr<SdrObjGeoData> GetGeoData() const;
603 virtual void SetGeoData(const SdrObjGeoData& rGeo);
605 // ItemSet access
606 const SfxItemSet& GetMergedItemSet() const;
607 void SetMergedItem(const SfxPoolItem& rItem);
608 void ClearMergedItem(const sal_uInt16 nWhich = 0);
609 void SetMergedItemSet(const SfxItemSet& rSet, bool bClearAllItems = false);
610 const SfxPoolItem& GetMergedItem(const sal_uInt16 nWhich) const;
611 template<class T>
612 const T& GetMergedItem( TypedWhichId<T> nWhich ) const
614 return static_cast<const T&>(GetMergedItem(sal_uInt16(nWhich)));
617 // syntactical sugar for ItemSet accesses
618 void SetMergedItemSetAndBroadcast(const SfxItemSet& rSet, bool bClearAllItems = false);
620 // NotPersistAttr for Layer, ObjName, geometrical transformations etc.
621 void TakeNotPersistAttr(SfxItemSet& rAttr) const;
622 void ApplyNotPersistAttr(const SfxItemSet& rAttr);
623 void NbcApplyNotPersistAttr(const SfxItemSet& rAttr);
625 // if bDontRemoveHardAttr is false, set all attributes, which were set in the style sheet, to their default value
626 // if true, all hard attributes keep their values
627 void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr);
628 virtual void NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr);
629 SfxStyleSheet* GetStyleSheet() const;
631 virtual bool HasTextEdit() const;
633 // keep text in outliner's format
634 // SetOutlinerParaObject: transfer ownership of *pTextObject!
635 void SetOutlinerParaObject(std::optional<OutlinerParaObject> pTextObject);
636 virtual void NbcSetOutlinerParaObject(std::optional<OutlinerParaObject> pTextObject);
637 virtual OutlinerParaObject* GetOutlinerParaObject() const;
638 virtual void NbcReformatText();
640 void BurnInStyleSheetAttributes();
642 // macro abilities, e.g. a rectangle as PushButton.
643 virtual bool HasMacro() const;
644 virtual SdrObject* CheckMacroHit (const SdrObjMacroHitRec& rRec) const;
645 virtual PointerStyle GetMacroPointer (const SdrObjMacroHitRec& rRec) const;
646 virtual void PaintMacro (OutputDevice& rOut, const tools::Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const;
647 virtual bool DoMacro (const SdrObjMacroHitRec& rRec);
648 bool IsMacroHit(const SdrObjMacroHitRec& rRec) const;
650 // Connectors
651 // (see also documentation in SvdoEdge.hxx, SdrEdgeObj, as well as SvdGlue.hxx and SvdGlEV.hxx)
653 // There are nodes and edges. In theory an edge can also be a node, but this isn't implemented yet.
654 // A node has a number of gluepoints, onto which edges can glued to
655 // An edge can be either
656 // - without any connection to any node,
657 // - or connected on one end to a node, while the other end is not connected,
658 // - or connected on both ends with exactly one node each.
659 // The edge is listener for its up to two nodes.
660 // Whenever a node is moved or resized, all its connected edges follow.
661 // This is also true for SetGluePoint()... on the node.
662 // On the other hand, moving/resizing an edge breaks the connection.
664 // automatic gluepoints:
665 // a node object must provide four vertex and corner positions
666 // usually 0: top, 1: right, 2: bottom, 3: left
667 virtual SdrGluePoint GetVertexGluePoint(sal_uInt16 nNum) const;
669 // usually:
670 // 0: top-left, 1: top-right, 2: bottom-right, 3: bottom-left
671 virtual SdrGluePoint GetCornerGluePoint(sal_uInt16 nNum) const;
673 // list of all gluepoints, can be NULL
674 virtual const SdrGluePointList* GetGluePointList() const;
676 // after changing the GluePointList, one has to call the object's SendRepaintBroadcast!
677 virtual SdrGluePointList* ForceGluePointList();
679 // to be set temporarily when transforming related object(?)
680 void SetGlueReallyAbsolute(bool bOn);
681 void NbcRotateGluePoints(const Point& rRef, Degree100 nAngle, double sn, double cs);
682 void NbcMirrorGluePoints(const Point& rRef1, const Point& rRef2);
683 void NbcShearGluePoints (const Point& rRef, double tn, bool bVShear);
685 // if bTail1 is true, line start, otherwise line end
686 // if pObj is null disconnect
687 virtual void ConnectToNode(bool bTail1, SdrObject* pObj);
688 virtual void DisconnectFromNode(bool bTail1);
689 virtual SdrObject* GetConnectedNode(bool bTail1) const;
691 // sets the writing mode of the object's context
692 // Objects which itself do not support different writing modes will ignore this call.
693 // Objects which support different writing modes, but have an own, explicit writing mode set,
694 // will also ignore this call.
695 // Objects which support different writing modes, and whose own mode is set to css.text.WritingMode2.CONTEXT,
696 // will use the given writing mode to calculate their "effective writing mode".
697 // The behaviour of this method is undefined if you pass css.text.WritingMode2.CONTEXT.
698 // @param _nContextWritingMode
699 // the effective writing mode of the context of the object
700 virtual void SetContextWritingMode( const sal_Int16 _nContextWritingMode );
702 // If an object is able to convert itself into a polygon or into a Bezier curve (or into both),
703 // then the following methods should be overridden.
704 // E.g., convert a RectObj with line width 10, SOLID_PEN into a polygon:
705 // In the bLineToArea=false mode a PolyObj with four supporting points,
706 // line width 10 and SOLID_PEN shall be created.
707 // On the contrary in the bLineToArea=true mode the generated object should
708 // still have a line attribute NULL_PEN, and the line (also line pattern)
709 // itself should be emulated by the polygon area, which thereby can be
710 // manipulated by the user afterwards.
711 // The RectObj therefore can only convert correctly if it has an area attribute NULL_BRUSH.
712 // In this case it would have to:
713 // - set SOLID_BRUSH with the color of the given pen,
714 // - set NULL_PEN, and
715 // - generate tools::PolyPolygon with two polygons with four supporting points each.
716 // In each case the return value is a SdrObject*, because it is also
717 // allowed to return group objects (e.g. for SdrTextObj).
718 // In the case of the conversion from TextObj to PathObj,
719 // both modi (bLineToArea=true/false) would be identical.
720 // The methods' default implementations report "I'm unable to do this" (false/null).
721 virtual SdrObjectUniquePtr DoConvertToPolyObj(bool bBezier, bool bAddText) const;
722 SdrObjectUniquePtr ConvertToPolyObj(bool bBezier, bool bLineToArea) const;
724 // convert this path object to contour object; bForceLineDash converts even
725 // when there is no filled new polygon created from line-to-polygon conversion,
726 // specially used for XLINE_DASH and 3D conversion
727 SdrObject* ConvertToContourObj(SdrObject* pRet, bool bForceLineDash = false) const;
728 private:
729 SdrObject* ImpConvertToContourObj(bool bForceLineDash);
730 public:
732 // if true, reference onto an object
733 bool IsVirtualObj() const { return m_bVirtObj;}
735 // is true, if object can probably be filled
736 // is false, if object has probably line ends
737 // is invalid, if this is a group object
738 bool IsClosedObj() const { return m_bClosedObj;}
740 // tdf#118662 reorganize inserted state, no local bool needed anymore,
741 // it depends on being a member of a SdrObjList
742 void InsertedStateChange();
743 bool IsInserted() const { return nullptr != getParentSdrObjListFromSdrObject(); }
745 bool IsEdgeObj() const { return m_bIsEdge;}
746 bool Is3DObj() const { return m_bIs3DObj;}
747 bool IsUnoObj() const { return m_bIsUnoObj;}
748 void SetMoveProtect(bool bProt);
749 bool IsMoveProtect() const { return m_bMovProt;}
750 void SetResizeProtect(bool bProt);
751 bool IsResizeProtect() const { return m_bSizProt;}
752 void SetPrintable(bool bPrn);
753 bool IsPrintable() const { return !m_bNoPrint;}
754 void SetVisible(bool bVisible);
755 bool IsVisible() const { return mbVisible;}
756 void SetMarkProtect(bool bProt);
757 bool IsMarkProtect() const { return m_bMarkProt;}
759 /// Whether the aspect ratio should be kept by default when resizing.
760 virtual bool shouldKeepAspectRatio() const { return false; }
762 // application specific data
763 sal_uInt16 GetUserDataCount() const;
764 SdrObjUserData* GetUserData(sal_uInt16 nNum) const;
766 void AppendUserData(std::unique_ptr<SdrObjUserData> pData);
768 // removes the record from the list and performs delete (FreeMem+Dtor).
769 void DeleteUserData(sal_uInt16 nNum);
771 // access to the UNO representation of the shape
772 virtual css::uno::Reference< css::drawing::XShape > getUnoShape();
774 static SdrObject* getSdrObjectFromXShape( const css::uno::Reference< css::uno::XInterface >& xInt );
776 // retrieves the instance responsible for notifying changes in the properties of the shape associated with
777 // the SdrObject
779 // @precond
780 // There already exists an SvxShape instance associated with the SdrObject
781 // @throws css::uno::RuntimeException
782 // if there does nt yet exists an SvxShape instance associated with the SdrObject.
783 svx::PropertyChangeNotifier& getShapePropertyChangeNotifier();
785 // notifies a change in the given property, to all applicable listeners registered at the associated SvxShape
787 // This method is equivalent to calling getShapePropertyChangeNotifier().notifyPropertyChange( _eProperty ),
788 // exception that it is allowed to be called when there does not yet exist an associated SvxShape - in which
789 // case the method will silently return without doing anything.
790 void notifyShapePropertyChange( const svx::ShapeProperty _eProperty ) const;
792 // transformation interface for StarOfficeAPI. This implements support for
793 // homogen 3x3 matrices containing the transformation of the SdrObject. At the
794 // moment it contains a shearX, rotation and translation, but for setting all linear
795 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
797 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
798 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
799 virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const;
801 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
802 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
803 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
804 virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon);
806 // give info if object is in destruction
807 bool IsInDestruction() const;
809 // return if fill is != XFILL_NONE
810 bool HasFillStyle() const;
811 bool HasLineStyle() const;
813 // on import of OLE object from MS documents the BLIP size might be retrieved,
814 // the following methods are used to control it;
815 // usually this data makes no sense after the import is finished, since the object
816 // might be resized
817 const tools::Rectangle& GetBLIPSizeRectangle() const { return maBLIPSizeRectangle;}
818 void SetBLIPSizeRectangle( const tools::Rectangle& aRect );
820 // #i121917#
821 virtual bool HasText() const;
823 bool Equals(const SdrObject&) const;
825 virtual void dumpAsXml(xmlTextWriterPtr pWriter) const;
827 /// Is this a textbox of a drawinglayer shape?
828 virtual bool IsTextBox() const;
830 void SetEmptyPresObj(bool bEpt);
831 bool IsEmptyPresObj() const { return m_bEmptyPresObj;}
832 void SetNotVisibleAsMaster(bool bFlg);
833 bool IsNotVisibleAsMaster() const { return m_bNotVisibleAsMaster;}
834 void SetUserCall(SdrObjUserCall* pUser);
835 SdrObjUserCall* GetUserCall() const { return m_pUserCall;}
836 /// @see mbDoNotInsertIntoPageAutomatically
837 void SetDoNotInsertIntoPageAutomatically(bool bSet);
838 /// @see mbDoNotInsertIntoPageAutomatically
839 bool IsDoNotInsertIntoPageAutomatically() const { return mbDoNotInsertIntoPageAutomatically;}
841 // Warning: this method should only be used if you really know what you're doing
842 sal_uInt32 GetOrdNumDirect() const { return m_nOrdNum;}
844 // #i25616#
845 bool DoesSupportTextIndentingOnLineWidthChange() const { return mbSupportTextIndentingOnLineWidthChange;}
847 const Point& GetAnchorPos() const;
849 // #i25616#
850 bool LineIsOutsideGeometry() const { return mbLineIsOutsideGeometry;}
852 // Set the position in the navigation position to the given value.
853 // This method is typically used only by the model after a change to
854 // the navigation order.
855 // This method does not change the navigation position of other
856 // objects.
857 // Use SdrObjList::SetObjectNavigationPosition() instead.
858 void SetNavigationPosition (const sal_uInt32 nPosition);
860 // sets a new UNO representation of the shape
861 // This is only a public interface function. The actual work is
862 // done by impl_setUnoShape().
863 // Calling this function is only allowed for the UNO representation
864 // itself!
865 void setUnoShape( const css::uno::Reference<css::drawing::XShape>& _rxUnoShape);
867 const css::uno::WeakReference< css::drawing::XShape >& getWeakUnoShape() const { return maWeakUnoShape; }
869 void setSuitableOutlinerBg(Outliner& rOutliner) const;
870 // If fillstyle is drawing::FillStyle_BITMAP, returns the graphic.
871 const Graphic* getFillGraphic() const;
873 const OUString& getHyperlink() const { return msHyperlink; }
874 void setHyperlink(const OUString& sHyperlink) { msHyperlink = sHyperlink; }
876 protected:
877 mutable tools::Rectangle m_aOutRect; // surrounding rectangle for Paint (incl. LineWidth, ...)
878 Point m_aAnchor; // anchor position (Writer)
879 SdrObjUserCall* m_pUserCall;
880 std::unique_ptr<SdrObjPlusData>
881 m_pPlusData; // Broadcaster, UserData, connectors, ... (this is the Bitsack)
882 // object is only pointing to another one
883 bool m_bVirtObj : 1;
884 bool m_bSnapRectDirty : 1;
885 // the following flags will be streamed
886 bool m_bMovProt : 1; // if true, the position is protected
887 bool m_bSizProt : 1; // if true, the size is protected
888 // If bEmptyPresObj is true, it is a presentation object that has no content yet.
889 // The flag's default value is false.
890 // The management is done by the application.
891 // Neither assign operator nor cloning copies the flag!
892 // The flag is persistent.
893 bool m_bEmptyPresObj : 1; // empty presentation object (Draw)
894 // if true, object is invisible as object of the MasterPage
895 bool m_bNotVisibleAsMaster : 1;
896 // if true, the object is closed, i.e. no line, arc...
897 bool m_bClosedObj : 1;
898 bool m_bIsEdge : 1;
899 bool m_bIs3DObj : 1;
900 bool m_bIsUnoObj : 1;
901 // #i25616#
902 bool mbLineIsOutsideGeometry : 1;
903 // #i25616#
904 bool mbSupportTextIndentingOnLineWidthChange : 1;
906 virtual ~SdrObject() override;
908 virtual std::unique_ptr<sdr::properties::BaseProperties> CreateObjectSpecificProperties();
910 virtual std::unique_ptr<sdr::contact::ViewContact> CreateObjectSpecificViewContact();
912 tools::Rectangle ImpDragCalcRect(const SdrDragStat& rDrag) const;
914 // for GetDragComment
915 OUString ImpGetDescriptionStr(TranslateId pStrCacheID) const;
917 void ImpForcePlusData();
919 OUString GetMetrStr(tools::Long nVal) const;
921 /// A derived class must override these 3 methods if it has own geometric
922 /// data that must be saved for Undo.
923 /// NewGeoData() creates an empty instance of a class derived from
924 /// SdrObjGeoData.
925 virtual std::unique_ptr<SdrObjGeoData> NewGeoData() const;
926 virtual void SaveGeoData(SdrObjGeoData& rGeo) const;
927 virtual void RestoreGeoData(const SdrObjGeoData& rGeo);
929 // internal versions
930 const SfxItemSet& GetObjectItemSet() const;
931 void SetObjectItem(const SfxPoolItem& rItem);
932 void SetObjectItemSet(const SfxItemSet& rSet);
933 const SfxPoolItem& GetObjectItem(const sal_uInt16 nWhich) const;
934 template<class T> const T& GetObjectItem( TypedWhichId<T> nWhich ) const
936 return static_cast<const T&>(GetObjectItem(sal_uInt16(nWhich)));
939 /// Sets a new UNO shape
941 /// The default implementation of this function sets the new UNO
942 /// shape. Derived classes should override the function to handle
943 /// any other actions that are needed when the shape is being
944 /// changed.
946 /// The implementation _must_ call the same method of its parent
947 /// class (preferably as the first step)!
948 virtual void impl_setUnoShape( const css::uno::Reference< css::drawing::XShape >& _rxUnoShape );
950 const SfxItemSet* getBackgroundFillSet() const;
952 private:
953 struct Impl;
954 std::unique_ptr<Impl> mpImpl;
955 SdrObjList* mpParentOfSdrObject; // list that includes this object
956 sal_uInt32 m_nOrdNum; // order number of the object in the list
957 std::unique_ptr<SfxGrabBagItem> m_pGrabBagItem; // holds the GrabBagItem property
958 // Position in the navigation order. SAL_MAX_UINT32 when not used.
959 sal_uInt32 mnNavigationPosition;
960 SdrLayerID mnLayerID;
961 bool m_bNoPrint : 1; // if true, the object is not printed.
962 bool mbVisible : 1; // if false, the object is not visible on screen (but maybe on printer, depending on bNoprint
963 bool m_bMarkProt : 1; // marking forbidden, persistent
964 // on import of OLE object from MS documents the BLIP size might be retrieved,
965 // in this case the following member is initialized as nonempty rectangle
966 tools::Rectangle maBLIPSizeRectangle;
967 std::unique_ptr<sdr::properties::BaseProperties>
968 mpProperties;
969 std::unique_ptr<sdr::contact::ViewContact>
970 mpViewContact;
972 // do not use directly, always use getSvxShape() if you have to!
973 SvxShape* mpSvxShape;
974 css::uno::WeakReference< css::drawing::XShape >
975 maWeakUnoShape;
976 // HACK: Do not automatically insert newly created object into a page.
977 // The user needs to do it manually later.
978 bool mbDoNotInsertIntoPageAutomatically;
979 // Hyperlink for the whole shape
980 OUString msHyperlink;
982 // only for internal use!
983 SvxShape* getSvxShape();
985 SdrObject( const SdrObject& ) = delete;
988 struct SVXCORE_DLLPUBLIC SdrObjectFreeOp
990 void operator()(SdrObject* obj)
992 SdrObject::Free(obj);
996 struct SdrObjCreatorParams
998 SdrInventor nInventor;
999 SdrObjKind nObjIdentifier;
1000 SdrModel& rSdrModel;
1004 * Whoever creates his own objects must set a link in the SdrObjFactory class.
1005 * The handler must have the following signature:
1006 * void Hdl(SdrObjFactory*)
1007 * He must take a look at the referenced instance's nInventor and nIdentifier values,
1008 * and must create a new drawing object instance accordingly.
1009 * He must also make the pNewObj pointer reference to this instance.
1011 class SVXCORE_DLLPUBLIC SdrObjFactory
1013 public:
1014 static SdrObject* MakeNewObject(
1015 SdrModel& rSdrModel,
1016 SdrInventor nInventor,
1017 SdrObjKind nObjIdentifier,
1018 const tools::Rectangle* pSnapRect = nullptr);
1020 static void InsertMakeObjectHdl(Link<SdrObjCreatorParams, SdrObject*> const & rLink);
1021 static void RemoveMakeObjectHdl(Link<SdrObjCreatorParams, SdrObject*> const & rLink);
1023 private:
1024 static SVX_DLLPRIVATE SdrObject* CreateObjectFromFactory(
1025 SdrModel& rSdrModel,
1026 SdrInventor nInventor,
1027 SdrObjKind nIdentifier);
1029 SdrObjFactory() = delete;
1032 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */