Bump version to 6.4-15
[LibreOffice.git] / include / svx / svdoedge.hxx
blobe6399da73bda12d333aafb12b7ddb1f28bb1a97a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_SVX_SVDOEDGE_HXX
21 #define INCLUDED_SVX_SVDOEDGE_HXX
23 #include <memory>
24 #include <svx/svdotext.hxx>
25 #include <svx/svdglue.hxx>
26 #include <svx/svxdllapi.h>
29 class SdrDragMethod;
30 class SdrPageView;
32 namespace sdr { namespace properties {
33 class ConnectorProperties;
37 /// Utility class SdrObjConnection
38 class SdrObjConnection final
40 friend class SdrEdgeObj;
41 friend class ImpEdgeHdl;
42 friend class SdrCreateView;
44 Point aObjOfs; // set during dragging of a node
45 SdrObject* pObj; // referenced object
46 sal_uInt16 nConId; // connector number
48 bool bBestConn : 1; // true -> the best-matching connector is searched for
49 bool bBestVertex : 1; // true -> the best-matching vertex to connect is searched for
50 bool bAutoVertex : 1; // autoConnector at apex nCon
51 bool bAutoCorner : 1; // autoConnector at corner nCon
53 public:
54 SdrObjConnection() { ResetVars(); }
56 void ResetVars();
57 bool TakeGluePoint(SdrGluePoint& rGP) const;
59 void SetBestConnection( bool rB ) { bBestConn = rB; };
60 void SetBestVertex( bool rB ) { bBestVertex = rB; };
61 void SetAutoVertex( bool rB ) { bAutoVertex = rB; };
62 void SetConnectorId( sal_uInt16 nId ) { nConId = nId; };
64 bool IsBestConnection() const { return bBestConn; };
65 bool IsAutoVertex() const { return bAutoVertex; };
66 sal_uInt16 GetConnectorId() const { return nConId; };
67 SdrObject* GetObject() const { return pObj; }
71 enum class SdrEdgeLineCode { Obj1Line2, Obj1Line3, Obj2Line2, Obj2Line3, MiddleLine };
73 /// Utility class SdrEdgeInfoRec
74 class SdrEdgeInfoRec
76 public:
77 // The 5 distances are set on dragging or via SetAttr and are
78 // evaluated by ImpCalcEdgeTrack. Only 0-3 longs are transported
79 // via Get/SetAttr/Get/SetStyleSh though.
80 Point aObj1Line2;
81 Point aObj1Line3;
82 Point aObj2Line2;
83 Point aObj2Line3;
84 Point aMiddleLine;
86 // Following values are set by ImpCalcEdgeTrack
87 long nAngle1; // exit angle at Obj1
88 long nAngle2; // exit angle at Obj2
89 sal_uInt16 nObj1Lines; // 1..3
90 sal_uInt16 nObj2Lines; // 1..3
91 sal_uInt16 nMiddleLine; // 0xFFFF=none, otherwise point number of the beginning of the line
93 public:
94 SdrEdgeInfoRec()
95 : nAngle1(0),
96 nAngle2(0),
97 nObj1Lines(0),
98 nObj2Lines(0),
99 nMiddleLine(0xFFFF)
102 Point& ImpGetLineOffsetPoint(SdrEdgeLineCode eLineCode);
103 sal_uInt16 ImpGetPolyIdx(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const;
104 bool ImpIsHorzLine(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const;
105 void ImpSetLineOffset(SdrEdgeLineCode eLineCode, const XPolygon& rXP, long nVal);
106 long ImpGetLineOffset(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const;
110 /// Utility class SdrEdgeObjGeoData
111 class SdrEdgeObjGeoData final : public SdrTextObjGeoData
113 public:
114 SdrObjConnection aCon1; // connection status of the beginning of the line
115 SdrObjConnection aCon2; // connection status of the end of the line
116 std::unique_ptr<XPolygon> pEdgeTrack;
117 bool bEdgeTrackDirty; // true -> connector track needs to be recalculated
118 bool bEdgeTrackUserDefined;
119 SdrEdgeInfoRec aEdgeInfo;
121 public:
122 SdrEdgeObjGeoData();
123 virtual ~SdrEdgeObjGeoData() override;
127 /// Utility class SdrEdgeObj
128 class SVX_DLLPUBLIC SdrEdgeObj : public SdrTextObj
130 private:
131 // to allow sdr::properties::ConnectorProperties access to ImpSetAttrToEdgeInfo()
132 friend class sdr::properties::ConnectorProperties;
134 friend class SdrCreateView;
135 friend class ImpEdgeHdl;
137 protected:
138 virtual std::unique_ptr<sdr::contact::ViewContact> CreateObjectSpecificViewContact() override;
139 virtual std::unique_ptr<sdr::properties::BaseProperties> CreateObjectSpecificProperties() override;
141 SdrObjConnection aCon1; // Connection status of the beginning of the line
142 SdrObjConnection aCon2; // Connection status of the end of the line
144 std::unique_ptr<XPolygon> pEdgeTrack;
145 sal_uInt16 nNotifyingCount; // Locking
146 SdrEdgeInfoRec aEdgeInfo;
148 bool bEdgeTrackDirty : 1; // true -> Connection track needs to be recalculated
149 bool bEdgeTrackUserDefined : 1;
151 // Bool to allow suppression of default connects at object
152 // inside test (HitTest) and object center test (see ImpFindConnector())
153 bool mbSuppressDefaultConnect : 1;
155 // Flag value for avoiding infinite loops when calculating
156 // BoundRects from ring-connected connectors. A coloring algorithm
157 // is used here. When the GetCurrentBoundRect() calculation of a
158 // SdrEdgeObj is running, the flag is set, else it is always
159 // false.
160 bool mbBoundRectCalculationRunning : 1;
162 // #i123048# need to remember if layouting was suppressed before to get
163 // to a correct state for first real layouting
164 bool mbSuppressed : 1;
166 public:
167 // Interface to default connect suppression
168 void SetSuppressDefaultConnect(bool bNew) { mbSuppressDefaultConnect = bNew; }
169 bool GetSuppressDefaultConnect() const { return mbSuppressDefaultConnect; }
171 protected:
172 virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
174 static XPolygon ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, const tools::Rectangle& rRect, const Point& rCenter);
175 void ImpRecalcEdgeTrack(); // recalculation of the connection track
176 XPolygon ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection& rCon1, SdrObjConnection& rCon2, SdrEdgeInfoRec* pInfo) const;
177 XPolygon ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const tools::Rectangle& rBoundRect1, const tools::Rectangle& rBewareRect1,
178 const Point& rPt2, long nAngle2, const tools::Rectangle& rBoundRect2, const tools::Rectangle& rBewareRect2,
179 sal_uIntPtr* pnQuality, SdrEdgeInfoRec* pInfo) const;
180 static bool ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrObjConnection& rCon, const SdrEdgeObj* pThis, OutputDevice* pOut=nullptr);
181 static SdrEscapeDirection ImpCalcEscAngle(SdrObject const * pObj, const Point& aPt2);
182 void ImpSetTailPoint(bool bTail1, const Point& rPt);
183 void ImpUndirtyEdgeTrack(); // potential recalculation of the connection track
184 void ImpDirtyEdgeTrack(); // invalidate connector path, so it will be recalculated next time
185 void ImpSetAttrToEdgeInfo(); // copying values from the pool to aEdgeInfo
186 void ImpSetEdgeInfoToAttr(); // copying values from the aEdgeInfo to the pool
188 // protected destructor
189 virtual ~SdrEdgeObj() override;
191 public:
192 SdrEdgeObj(SdrModel& rSdrModel);
194 // react on model/page change
195 virtual void handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage) override;
197 SdrObjConnection& GetConnection(bool bTail1) { return *(bTail1 ? &aCon1 : &aCon2); }
198 virtual void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const override;
199 virtual sal_uInt16 GetObjIdentifier() const override;
200 virtual const tools::Rectangle& GetCurrentBoundRect() const override;
201 virtual const tools::Rectangle& GetSnapRect() const override;
202 virtual SdrGluePoint GetVertexGluePoint(sal_uInt16 nNum) const override;
203 virtual SdrGluePoint GetCornerGluePoint(sal_uInt16 nNum) const override;
204 virtual const SdrGluePointList* GetGluePointList() const override;
205 virtual SdrGluePointList* ForceGluePointList() override;
207 // * for all of the below: bTail1=true: beginning of the line,
208 // otherwise end of the line
209 // * pObj=NULL: disconnect connector
210 void SetEdgeTrackDirty() { bEdgeTrackDirty=true; }
211 void ConnectToNode(bool bTail1, SdrObject* pObj) override;
212 void DisconnectFromNode(bool bTail1) override;
213 SdrObject* GetConnectedNode(bool bTail1) const override;
214 const SdrObjConnection& GetConnection(bool bTail1) const { return *(bTail1 ? &aCon1 : &aCon2); }
215 bool CheckNodeConnection(bool bTail1) const;
217 virtual void RecalcSnapRect() override;
218 virtual void TakeUnrotatedSnapRect(tools::Rectangle& rRect) const override;
219 virtual SdrEdgeObj* CloneSdrObject(SdrModel& rTargetModel) const override;
220 SdrEdgeObj& operator=(const SdrEdgeObj& rObj);
221 virtual OUString TakeObjNameSingul() const override;
222 virtual OUString TakeObjNamePlural() const override;
224 void SetEdgeTrackPath( const basegfx::B2DPolyPolygon& rPoly );
225 basegfx::B2DPolyPolygon GetEdgeTrackPath() const;
227 virtual basegfx::B2DPolyPolygon TakeXorPoly() const override;
228 virtual sal_uInt32 GetHdlCount() const override;
229 virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
231 // special drag methods
232 virtual bool hasSpecialDrag() const override;
233 virtual bool beginSpecialDrag(SdrDragStat& rDrag) const override;
234 virtual bool applySpecialDrag(SdrDragStat& rDrag) override;
235 virtual OUString getSpecialDragComment(const SdrDragStat& rDrag) const override;
237 // FullDrag support
238 virtual SdrObjectUniquePtr getFullDragClone() const override;
240 virtual void NbcSetSnapRect(const tools::Rectangle& rRect) override;
241 virtual void NbcMove(const Size& aSize) override;
242 virtual void NbcResize(const Point& rRefPnt, const Fraction& aXFact, const Fraction& aYFact) override;
244 // #i54102# added rotate, mirror and shear support
245 virtual void NbcRotate(const Point& rRef, long nAngle, double sn, double cs) override;
246 virtual void NbcMirror(const Point& rRef1, const Point& rRef2) override;
247 virtual void NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear) override;
249 // #102344# Added missing implementation
250 virtual void NbcSetAnchorPos(const Point& rPnt) override;
252 virtual bool BegCreate(SdrDragStat& rStat) override;
253 virtual bool MovCreate(SdrDragStat& rStat) override;
254 virtual bool EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) override;
255 virtual bool BckCreate(SdrDragStat& rStat) override;
256 virtual void BrkCreate(SdrDragStat& rStat) override;
257 virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat& rDrag) const override;
258 virtual PointerStyle GetCreatePointer() const override;
259 virtual SdrObjectUniquePtr DoConvertToPolyObj(bool bBezier, bool bAddText) const override;
261 virtual sal_uInt32 GetSnapPointCount() const override;
262 virtual Point GetSnapPoint(sal_uInt32 i) const override;
263 virtual bool IsPolyObj() const override;
264 virtual sal_uInt32 GetPointCount() const override;
265 virtual Point GetPoint(sal_uInt32 i) const override;
266 virtual void NbcSetPoint(const Point& rPnt, sal_uInt32 i) override;
268 virtual SdrObjGeoData* NewGeoData() const override;
269 virtual void SaveGeoData(SdrObjGeoData& rGeo) const override;
270 virtual void RestGeoData(const SdrObjGeoData& rGeo) override;
272 /** updates edges that are connected to the edges of this object
273 as if the connected objects send a repaint broadcast
274 #103122#
276 void Reformat();
278 // helper methods for the StarOffice api
279 Point GetTailPoint( bool bTail ) const;
280 void SetTailPoint( bool bTail, const Point& rPt );
281 void setGluePointIndex( bool bTail, sal_Int32 nId = -1 );
282 sal_Int32 getGluePointIndex( bool bTail );
284 virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const override;
285 virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon) override;
287 // for geometry access
288 ::basegfx::B2DPolygon getEdgeTrack() const;
290 // helper method for SdrDragMethod::AddConnectorOverlays. Adds an overlay polygon for
291 // this connector to rResult.
292 basegfx::B2DPolygon ImplAddConnectorOverlay(SdrDragMethod& rDragMethod, bool bTail1, bool bTail2, bool bDetail) const;
295 // The following item parameters of the SdrItemPool are used to
296 // determine the actual connector line routing:
298 // sal_uInt16 EdgeFlowAngle default 9000 (= 90.00 deg), min 0, max 9000
299 // Clearance angle.
300 // The angle at which the connecting line may run.
302 // sal_uInt16 EdgeEscAngle default 9000 (= 90.00 Deg), min 0, max 9000
303 // Object exit angle.
304 // The angle at which the connection line may exit from the object.
306 // bool EdgeEscAsRay default false
307 // true -> the connecting line emerges from the object radially.
308 // Thus, angle specification by the line ObjCenter / connector.
310 // bool EdgeEscUseObjAngle default false
311 // Object rotation angle is considered
312 // true -> when determining the connector exit angle, angle for
313 // object rotation is taken as an offset.
315 // sal_uIntPtr EdgeFlowDefDist default 0, min 0, max ?
316 // This is the default minimum distance on calculation of the
317 // connection Line to the docked objects is in logical units.
318 // This distance is overridden within the object, as soon as the
319 // user drags on the lines. When docking onto a new object,
320 // however, this default is used again.
323 // General Information About Connectors:
325 // There are nodes and edge objects. Two nodes can be joined by an
326 // edge. If a connector is connected to a node only at one end, the
327 // other end is fixed to an absolute position in the document. It is
328 // of course also possible for a connector to be "free" at both ends,
329 // i.e. not connected to a node object on each side.
331 // A connector object can also theoretically be a node object at the
332 // same time. In the first version, however, this will not yet be
333 // realized.
335 // A connection between node and connector edge can be established by:
336 // - Interactive creation of a new edge object at the SdrView where
337 // the beginning or end point of the edge is placed on a connector
338 // (glueing point) of an already existing node object.
339 // - Interactive dragging of the beginning or end point of an
340 // existing connector edge object on the SdrView to a connector
341 // (glueing point) of an already existing node object.
342 // - Undo/Redo
343 // Moving node objects does not make any connections. Also not the
344 // direct shifting of edge endpoints on the SdrModel... Connections
345 // can also be established, if the connectors are not configured to
346 // be visible in the view.
348 // An existing connection between node and edge is retained for:
349 // - Dragging (Move/Resize/Rotate/...) of the node object
350 // - Moving a connector position in the node object
351 // - Simultaneous dragging (Move/Resize/Rotate/...) of the node and the
352 // edge
354 // A connection between node and edge can be removed by:
355 // - Deleting one of the objects
356 // - Dragging the edge object without simultaneously dragging the node
357 // - Deleting the connector at the node object
358 // - Undo/Redo/Repeat
359 // When dragging, the request to remove the connection must be
360 // requested from outside of the model (for example, from the
361 // SdrView). SdrEdgeObj::Move() itself does not remove the
362 // connection.
364 // Each node object can have connectors, so-called glue points. These
365 // are the geometric points at which the connecting edge object ends
366 // when the connection is established. By default, each object has no
367 // connectors. Nevertheless, one can dock an edge in certain view
368 // settings since then, e.g., connectors can be automatically
369 // generated at the 4 vertices of the node object when needed. Each
370 // object provides 2x4 so-called default connector positions, 4 at
371 // the vertices and 4 at the corner positions. In the normal case,
372 // these are located at the 8 handle positions; exceptions here are
373 // ellipses, parallelograms, ... . In addition, user-specific
374 // connectors can be set for each node object.
376 // Then there is also the possibility to dock an edge on an object
377 // with the attribute "bUseBestConnector". The best-matching
378 // connector position for the routing of the connection line is then
379 // used from the offering of connectors of the object or/and of the
380 // vertices. The user assigns this attribute by docking the node in
381 // its center (see, e.g., Visio).
382 // 09-06-1996: bUseBestConnector uses vertex glue points only.
384 // And here is some terminology:
385 // Connector : The connector object (edge object)
386 // Node : Any object to which a connector can be glued to, e.g., a rectangle,
387 // etc.
388 // Glue point: The point at which the connector is glued to the node object.
389 // There are:
390 // Vertex glue points: Each node object presents these glue
391 // points inherently. Perhaps there is already the option
392 // "automatically glue to object vertex" in Draw (default is
393 // on).
394 // Corner glue points: These glue points, too, are already
395 // auto-enabled on objects. Similar to the ones above,
396 // there may already be an option for them in Draw (default is
397 // off).
398 // In contrast to Visio, vertex glue points and corner glue
399 // points are not displayed in the UI; they are simply there (if
400 // the option is activated).
401 // Custom glue points: Any number of them are present on each
402 // node object. They can be made visible using the option
403 // (always visible when editing). At the moment, however, they
404 // are not yet fully implemented.
405 // Automatic glue point selection: If the connector is docked
406 // to the node object so that the black frame encompasses the
407 // entire object, then the connector tries to find the most
408 // convenient of the 4 vertex glue points (and only of those).
410 #endif // INCLUDED_SVX_SVDOEDGE_HXX
412 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */