update credits
[LibreOffice.git] / include / svx / svdoedge.hxx
blob180369f81743c24d2b84771d1034d4b8ad0c7776
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 _SVDOEDGE_HXX
21 #define _SVDOEDGE_HXX
23 #include <svx/svdotext.hxx>
24 #include <svx/svdglue.hxx>
25 #include "svx/svxdllapi.h"
27 //************************************************************
28 // Vorausdeklarationen
29 //************************************************************
31 class SdrDragMethod;
32 class SdrPageView;
34 namespace sdr { namespace properties {
35 class ConnectorProperties;
38 //************************************************************
39 // Hilfsklasse SdrObjConnection
40 //************************************************************
42 class SdrObjConnection
44 friend class SdrEdgeObj;
45 friend class ImpEdgeHdl;
46 friend class SdrCreateView;
48 protected:
49 Point aObjOfs; // Wird beim Draggen eines Knotens gesetzt
50 SdrObject* pObj; // Referenziertes Objekt
51 long nXDist; // Hor. Objektabstand wenn bXDistOvr=TRUE
52 long nYDist; // Vert. Objektabstand wenn bYDistOvr=TRUE
53 sal_uInt16 nConId; // Konnektornummer
55 // bitfield
56 unsigned bBestConn : 1; // sal_True= es wird der guenstigste Konnektor gesucht
57 unsigned bBestVertex : 1; // sal_True= es wird der guenstigste Scheitelpunkt zum konnekten gesucht
58 unsigned bXDistOvr : 1; // sal_True= Hor. Objektabstand wurde gedragt (Overwrite)
59 unsigned bYDistOvr : 1; // sal_True= Vert. Objektabstand wurde gedragt (Overwrite)
60 unsigned bAutoVertex : 1; // AutoConnector am Scheitelpunkt nCon
61 unsigned bAutoCorner : 1; // AutoConnector am Eckpunkt nCon
63 public:
64 SdrObjConnection() { ResetVars(); }
65 SVX_DLLPUBLIC ~SdrObjConnection();
67 void ResetVars();
68 bool TakeGluePoint(SdrGluePoint& rGP, bool bSetAbsolutePos) const;
70 inline void SetBestConnection( sal_Bool rB ) { bBestConn = rB; };
71 inline void SetBestVertex( sal_Bool rB ) { bBestVertex = rB; };
72 inline void SetAutoVertex( sal_Bool rB ) { bAutoVertex = rB; };
73 inline void SetConnectorId( sal_uInt16 nId ) { nConId = nId; };
75 inline sal_Bool IsBestConnection() const { return bBestConn; };
76 inline sal_Bool IsBestVertex() const { return bBestVertex; };
77 inline sal_Bool IsAutoVertex() const { return bAutoVertex; };
78 inline sal_uInt16 GetConnectorId() const { return nConId; };
79 inline SdrObject* GetObject() const { return pObj; }
82 //************************************************************
83 // Hilfsklasse SdrEdgeInfoRec
84 //************************************************************
86 enum SdrEdgeLineCode {OBJ1LINE2,OBJ1LINE3,OBJ2LINE2,OBJ2LINE3,MIDDLELINE};
88 class SdrEdgeInfoRec
90 public:
91 // Die 5 Distanzen werden beim draggen bzw. per SetAttr gesetzt und von
92 // ImpCalcEdgeTrack ausgewertet. Per Get/SetAttr/Get/SetStyleSh werden
93 // jedoch nur 0-3 longs transportiert.
94 Point aObj1Line2;
95 Point aObj1Line3;
96 Point aObj2Line2;
97 Point aObj2Line3;
98 Point aMiddleLine;
100 // Nachfolgende Werte werden von ImpCalcEdgeTrack gesetzt
101 long nAngle1; // Austrittswinkel am Obj1
102 long nAngle2; // Austrittswinkel am Obj2
103 sal_uInt16 nObj1Lines; // 1..3
104 sal_uInt16 nObj2Lines; // 1..3
105 sal_uInt16 nMiddleLine; // 0xFFFF=keine, sonst Punktnummer des Linienbeginns
106 char cOrthoForm; // Form des Ortho-Verbindes, z.B. 'Z','U',I','L','S',...
108 public:
109 SdrEdgeInfoRec()
110 : nAngle1(0),
111 nAngle2(0),
112 nObj1Lines(0),
113 nObj2Lines(0),
114 nMiddleLine(0xFFFF),
115 cOrthoForm(0)
118 Point& ImpGetLineVersatzPoint(SdrEdgeLineCode eLineCode);
119 const Point& ImpGetLineVersatzPoint(SdrEdgeLineCode eLineCode) const { return ((SdrEdgeInfoRec*)this)->ImpGetLineVersatzPoint(eLineCode); }
120 sal_uInt16 ImpGetPolyIdx(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const;
121 bool ImpIsHorzLine(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const;
122 void ImpSetLineVersatz(SdrEdgeLineCode eLineCode, const XPolygon& rXP, long nVal);
123 long ImpGetLineVersatz(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const;
126 //************************************************************
127 // Hilfsklasse SdrEdgeObjGeoData
128 //************************************************************
130 class SdrEdgeObjGeoData : public SdrTextObjGeoData
132 public:
133 SdrObjConnection aCon1; // Verbindungszustand des Linienanfangs
134 SdrObjConnection aCon2; // Verbindungszustand des Linienendes
135 XPolygon* pEdgeTrack;
136 sal_Bool bEdgeTrackDirty;// sal_True=Verbindungsverlauf muss neu berechnet werden.
137 sal_Bool bEdgeTrackUserDefined;
138 SdrEdgeInfoRec aEdgeInfo;
140 public:
141 SdrEdgeObjGeoData();
142 virtual ~SdrEdgeObjGeoData();
145 //************************************************************
146 // Hilfsklasse SdrEdgeObj
147 //************************************************************
149 class SVX_DLLPUBLIC SdrEdgeObj : public SdrTextObj
151 private:
152 // to allow sdr::properties::ConnectorProperties access to ImpSetAttrToEdgeInfo()
153 friend class sdr::properties::ConnectorProperties;
155 friend class SdrCreateView;
156 friend class ImpEdgeHdl;
158 protected:
159 virtual sdr::contact::ViewContact* CreateObjectSpecificViewContact();
160 virtual sdr::properties::BaseProperties* CreateObjectSpecificProperties();
162 SdrObjConnection aCon1; // Verbindungszustand des Linienanfangs
163 SdrObjConnection aCon2; // Verbindungszustand des Linienendes
165 XPolygon* pEdgeTrack;
166 sal_uInt16 nNotifyingCount; // Verrieglung
167 SdrEdgeInfoRec aEdgeInfo;
169 // bitfield
170 unsigned bEdgeTrackDirty : 1; // sal_True=Verbindungsverlauf muss neu berechnet werden.
171 unsigned bEdgeTrackUserDefined : 1;
173 // #109007#
174 // Bool to allow supporession of default connects at object
175 // inside test (HitTest) and object center test (see ImpFindConnector())
176 unsigned mbSuppressDefaultConnect : 1;
178 // #110649#
179 // Flag value for avoiding death loops when calculating BoundRects
180 // from circularly connected connectors. A coloring algorythm is used
181 // here. When the GetCurrentBoundRect() calculation of a SdrEdgeObj
182 // is running, the flag is set, else it is always sal_False.
183 unsigned mbBoundRectCalculationRunning : 1;
185 // #i123048# need to remember if layouting was suppressed before to get
186 // to a correct state for first real layouting
187 unsigned mbSuppressed : 1;
189 public:
190 // #109007#
191 // Interface to default connect suppression
192 void SetSuppressDefaultConnect(sal_Bool bNew) { mbSuppressDefaultConnect = bNew; }
193 sal_Bool GetSuppressDefaultConnect() const { return mbSuppressDefaultConnect; }
195 // #110649#
196 sal_Bool IsBoundRectCalculationRunning() const { return mbBoundRectCalculationRunning; }
198 protected:
199 virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint);
201 XPolygon ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, const Rectangle& rRect, const Point& rCenter) const;
202 void ImpRecalcEdgeTrack(); // Neuberechnung des Verbindungsverlaufs
203 XPolygon ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection& rCon1, SdrObjConnection& rCon2, SdrEdgeInfoRec* pInfo) const;
204 XPolygon ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rectangle& rBoundRect1, const Rectangle& rBewareRect1,
205 const Point& rPt2, long nAngle2, const Rectangle& rBoundRect2, const Rectangle& rBewareRect2,
206 sal_uIntPtr* pnQuality, SdrEdgeInfoRec* pInfo) const;
207 static bool ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrObjConnection& rCon, const SdrEdgeObj* pThis, OutputDevice* pOut=NULL);
208 sal_uInt16 ImpCalcEscAngle(SdrObject* pObj, const Point& aPt2) const;
209 void ImpSetTailPoint(bool bTail1, const Point& rPt);
210 void ImpUndirtyEdgeTrack(); // eventuelle Neuberechnung des Verbindungsverlaufs
211 void ImpDirtyEdgeTrack(); // invalidate connector path, so it will be recalculated next time
212 void ImpSetAttrToEdgeInfo(); // Werte vom Pool nach aEdgeInfo kopieren
213 void ImpSetEdgeInfoToAttr(); // Werte vom aEdgeInfo in den Pool kopieren
215 public:
216 TYPEINFO();
218 SdrEdgeObj();
219 virtual ~SdrEdgeObj();
221 SdrObjConnection& GetConnection(bool bTail1) { return *(bTail1 ? &aCon1 : &aCon2); }
222 virtual void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const;
223 virtual sal_uInt16 GetObjIdentifier() const;
224 virtual const Rectangle& GetCurrentBoundRect() const;
225 virtual const Rectangle& GetSnapRect() const;
226 virtual bool IsNode() const;
227 virtual SdrGluePoint GetVertexGluePoint(sal_uInt16 nNum) const;
228 virtual SdrGluePoint GetCornerGluePoint(sal_uInt16 nNum) const;
229 virtual const SdrGluePointList* GetGluePointList() const;
230 virtual SdrGluePointList* ForceGluePointList();
231 virtual bool IsEdge() const;
233 // bTail1=TRUE: Linienanfang, sonst LinienEnde
234 // pObj=NULL: Disconnect
235 void SetEdgeTrackDirty() { bEdgeTrackDirty=sal_True; }
236 void ConnectToNode(bool bTail1, SdrObject* pObj);
237 void DisconnectFromNode(bool bTail1);
238 SdrObject* GetConnectedNode(bool bTail1) const;
239 const SdrObjConnection& GetConnection(bool bTail1) const { return *(bTail1 ? &aCon1 : &aCon2); }
240 bool CheckNodeConnection(bool bTail1) const;
242 virtual void RecalcSnapRect();
243 virtual void TakeUnrotatedSnapRect(Rectangle& rRect) const;
244 virtual SdrEdgeObj* Clone() const;
245 SdrEdgeObj& operator=(const SdrEdgeObj& rObj);
246 virtual void TakeObjNameSingul(String& rName) const;
247 virtual void TakeObjNamePlural(String& rName) const;
249 void SetEdgeTrackPath( const basegfx::B2DPolyPolygon& rPoly );
250 basegfx::B2DPolyPolygon GetEdgeTrackPath() const;
252 virtual basegfx::B2DPolyPolygon TakeXorPoly() const;
253 virtual sal_uInt32 GetHdlCount() const;
254 virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const;
256 // special drag methods
257 virtual bool hasSpecialDrag() const;
258 virtual bool beginSpecialDrag(SdrDragStat& rDrag) const;
259 virtual bool applySpecialDrag(SdrDragStat& rDrag);
260 virtual String getSpecialDragComment(const SdrDragStat& rDrag) const;
262 // FullDrag support
263 virtual SdrObject* getFullDragClone() const;
265 virtual void NbcSetSnapRect(const Rectangle& rRect);
266 virtual void NbcMove(const Size& aSize);
267 virtual void NbcResize(const Point& rRefPnt, const Fraction& aXFact, const Fraction& aYFact);
269 // #i54102# added rotate, mirrorn and shear support
270 virtual void NbcRotate(const Point& rRef, long nWink, double sn, double cs);
271 virtual void NbcMirror(const Point& rRef1, const Point& rRef2);
272 virtual void NbcShear(const Point& rRef, long nWink, double tn, bool bVShear);
274 // #102344# Added missing implementation
275 virtual void NbcSetAnchorPos(const Point& rPnt);
277 virtual bool BegCreate(SdrDragStat& rStat);
278 virtual bool MovCreate(SdrDragStat& rStat);
279 virtual bool EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd);
280 virtual bool BckCreate(SdrDragStat& rStat);
281 virtual void BrkCreate(SdrDragStat& rStat);
282 virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat& rDrag) const;
283 virtual Pointer GetCreatePointer() const;
284 virtual SdrObject* DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const;
286 virtual sal_uInt32 GetSnapPointCount() const;
287 virtual Point GetSnapPoint(sal_uInt32 i) const;
288 virtual sal_Bool IsPolyObj() const;
289 virtual sal_uInt32 GetPointCount() const;
290 virtual Point GetPoint(sal_uInt32 i) const;
291 virtual void NbcSetPoint(const Point& rPnt, sal_uInt32 i);
293 virtual SdrObjGeoData* NewGeoData() const;
294 virtual void SaveGeoData(SdrObjGeoData& rGeo) const;
295 virtual void RestGeoData(const SdrObjGeoData& rGeo);
297 /** updates edges that are connected to the edges of this object
298 as if the connected objects send a repaint broadcast
299 #103122#
301 void Reformat();
303 // helper methods for the StarOffice api
304 Point GetTailPoint( sal_Bool bTail ) const;
305 void SetTailPoint( sal_Bool bTail, const Point& rPt );
306 void setGluePointIndex( sal_Bool bTail, sal_Int32 nId = -1 );
307 sal_Int32 getGluePointIndex( sal_Bool bTail );
309 virtual sal_Bool TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const;
310 virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon);
312 // for geometry access
313 ::basegfx::B2DPolygon getEdgeTrack() const;
315 // helper method for SdrDragMethod::AddConnectorOverlays. Adds a overlay polygon for
316 // this connector to rResult.
317 basegfx::B2DPolygon ImplAddConnectorOverlay(SdrDragMethod& rDragMethod, bool bTail1, bool bTail2, bool bDetail) const;
320 ////////////////////////////////////////////////////////////////////////////////////////////////////
322 // Zur Bestimmung der Verlaufslinie werden folgende Item-Parameter des SdrItemPool verwendet:
324 // sal_uInt16 EdgeFlowAngle Default 9000 (=90.00 Deg), min 0, max 9000
325 // Verlauffreiheitswinkel.
326 // Der Winkel, in dem die Verbindungslinie verlaufen darf.
328 // sal_uInt16 EdgeEscAngle Default 9000 (=90.00 Deg), min 0, max 9000
329 // Objektaustrittswinkel.
330 // Der Winkel, in dem die Verbindungslinie aus dem Objekt austreten darf.
332 // sal_Bool EdgeEscAsRay Default FALSE
333 // sal_True= die Verbindungslinie tritt aus dem Obj Strahlenfoermig aus.
334 // Also Winkelvorgabe durch die Strecke ObjMitte/Konnektor.
336 // sal_Bool EdgeEscUseObjAngle Default FALSE
337 // Objektdrehwinkelberuecksichtigung.
338 // sal_True= Bei der Bestimmung des Objektaustrittswinkels wird der
339 // Drehwinkel des Objekts als Offset beruecksichtigt.
341 // sal_uIntPtr EdgeFlowDefDist Default 0, min 0, max ?
342 // Das ist der Default-Mindestabstand der bei der Berechnung der
343 // Verbindungslinie zu den angedockten Objekten in logischen Einheiten.
344 // Dieser Abstand wird innerhalb des Objektes "ueberschrieben", sobald
345 // der User an den Linien draggd. Beim Andocken an ein neues Objekt wird
346 // dann jedoch wieder dieser Default verwendet.
349 // Allgemeines zu Konnektoren:
351 // Es gibt Knoten und Kantenobjekte. Zwei Knoten koennen durch eine Kante
352 // miteinander verbunden werden. Ist eine Kante nur an einem Ende an einen
353 // Knoten geklebt, ist das andere Ende auf einer absoluten Position im Doc
354 // fixiert. Ebenso ist es natuerlich auch moeglich, dass eine Kante an beiden
355 // Enden "frei", also nicht mit einem Knotenobjekt verbunden ist.
357 // Ein Kantenobjekt kann theoretisch auch gleichzeitig Knotenobjekt sein. In
358 // der ersten Version wird das jedoch noch nicht realisiert werden.
360 // Eine Verbindung zwischen Knoten und Kante kann hergestellt werden durch:
361 // - Interaktives erzeugen eines neuen Kantenobjekts an der SdrView wobei
362 // Anfangs- bzw. Endpunkt der Kante auf ein Konnektor (Klebestelle) eines
363 // bereits vorhandenen Knotenobjekts gelegt wird.
364 // - Interaktives draggen des Anfangs- bzw. Endpunkts eines bestehenden
365 // Kantenobjekts an der SdrView auf ein Konnektor (Klebestelle) eines
366 // bereits vorhandenen Knotenobjekts.
367 // - Undo/Redo
368 // Verschieben von Knotenobjekten stellt keine Verbindungen her. Ebenso auch
369 // nicht das direkte Verschieben von Kantenendpunkten am SdrModel...
370 // Verbindungen koennen auch hergestellt werden, wenn die Konnektoren an der
371 // View nicht sichtbar geschaltet sind.
373 // Eine vorhandene Verbindung zwischen Knoten und Kante bleibt erhalten bei:
374 // - Draggen (Move/Resize/Rotate/...) des Knotenobjekts
375 // - Verschieben einer Konnektorposition im Knotemobjekt
376 // - gleichzeitiges Draggen (Move/Resize/Rotate/...) von Knoten und Kante
378 // Eine Verbindung zwischen Knoten und Kante kann geloesst werden durch:
379 // - Loeschen eines der Objekte
380 // - Draggen des Kantenobjekts ohne gleichzeitiges Draggen des Knotens
381 // - Loeschen des Konnektors am Knotenobjekt
382 // - Undo/Redo/Repeat
383 // Beim Draggen muss die Aufforderung zum loesen der Verbindung von ausserhalb
384 // des Models befohlen werden (z.B. von der SdrView). SdrEdgeObj::Move() loesst
385 // die Verbindung nicht selbsttaetig.
387 // Jedes Knotenobjekt kann Konnektoren, sog. Klebestellen besitzen. Das sind die
388 // geometrischen Punkte, an denen das verbindende Kantenobjekt bei hergestellter
389 // Verbindung endet. Defaultmaessig hat jedes Objekt keine Konnektoren. Trotzdem
390 // kann man bei bestimmten View-Einstellungen eine Kante andocken, da dann z.B.
391 // an den 4 Scheitelpunkten des Knotenobjekts bei Bedarf automatisch Konnektoren
392 // generiert werden. Jedes Objekt liefert dafuer 2x4 sog. Default-Konnektorposi-
393 // tionen, 4 an den Scheitelpunkten und 4 an den Eckpositionen. Im Normalfall
394 // liegen diese an den 8 Handlepositionen; Ausnahmen bilden hier Ellipsen,
395 // Parallelogramme, ... . Darueberhinaus koennen auch an jedem Knotenobjekt
396 // anwenderspeziefische Konnektoren gesetzt werden.
398 // Dann gibt es noch die Moeglichkeit, ein Kante an einem Objekt mit dem
399 // Attribut "bUseBestConnector" anzudocken. Es wird dann aus dem Angebot der
400 // Konnektoren des Objekts oder/und der Scheitelpunkte, jeweils die fuer den
401 // Verlauf der Verbindungslinie guenstigste Konnektorposition verwendet. Der
402 // Anwender vergibt dieses Attribut, indem er den Knoten in seiner Mitte
403 // andockt (siehe z.B. Visio).
404 // 09-06-1996: bUseBestConnector verwendet nur Scheitelpunktklebepunkte.
406 // Und hier noch etwas Begriffsdefinition:
407 // Verbinder : Eben das Verbinderobjekt (Kantenobjekt)
408 // Knoten : Ein beliebiges Objekt, an dem ein Verbinder drangeklebt
409 // werden kann, z.B. ein Rechteck, ...
410 // Klebepunkt: Der Punkt, an dem der Verbinder an das Knotenobjekt
411 // geklebt wird. Hierbei gibt es:
412 // Scheitelpunktklebepunkte: Jedes Knotenobjekt hat diese
413 // Klebepunkte von Natur aus. Moeglicherweise gibt es
414 // im Draw bereits die Option "Automatisch ankleben an
415 // Objektscheitelpunkte" (default an)
416 // Eckpunktklebepunkte: Auch diese Klebepunkte sind den
417 // Objekten von mir bereits mitgegeben. Wie die oben
418 // erwaehnten gibt es fuer diese moeglicherweise
419 // bereits auch eine Option im Draw. (default aus)
420 // Scheitelpunktklebepunkte und Eckpunktklebepunkte sind
421 // im Gegensatz zu Visio nicht optisch sichtbar; sie
422 // sind eben einfach da (wenn Option eingeschaltet).
423 // Benutzerdefinierte Klebepunkte: Gibt es an jedem
424 // Knotenobjekt beliebig viele. Per Option koennen sie
425 // sichtbar geschaltet werden (beim editieren immer
426 // sichtbar). Zur Zeit sind die jedoch noch nicht ganz
427 // fertigimplementiert.
428 // Automatische Klebepunktwahl: Wird der Verbinder so an
429 // das Knotenobjekt gedockt, dass der schwarke Rahmen
430 // das gesamte Objekt umfasst, so versucht der
431 // Verbinder von den 4 Scheitelpunktklebepunkten (und
432 // zwar nur von denen) den guenstigsten herauszufinden.
434 //////////////////////////////////////////////////////////////////////////////////////////////////
436 #endif //_SVDOEDGE_HXX
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */