diff options
Diffstat (limited to 'include/svx/svdoedge.hxx')
-rw-r--r-- | include/svx/svdoedge.hxx | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/include/svx/svdoedge.hxx b/include/svx/svdoedge.hxx new file mode 100644 index 000000000000..ea0968cd9487 --- /dev/null +++ b/include/svx/svdoedge.hxx @@ -0,0 +1,434 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef _SVDOEDGE_HXX +#define _SVDOEDGE_HXX + +#include <svx/svdotext.hxx> +#include <svx/svdglue.hxx> +#include "svx/svxdllapi.h" + +//************************************************************ +// Vorausdeklarationen +//************************************************************ + +class SdrDragMethod; +class SdrPageView; + +namespace sdr { namespace properties { + class ConnectorProperties; +}} + +//************************************************************ +// Hilfsklasse SdrObjConnection +//************************************************************ + +class SdrObjConnection +{ + friend class SdrEdgeObj; + friend class ImpEdgeHdl; + friend class SdrCreateView; + +protected: + Point aObjOfs; // Wird beim Draggen eines Knotens gesetzt + SdrObject* pObj; // Referenziertes Objekt + long nXDist; // Hor. Objektabstand wenn bXDistOvr=TRUE + long nYDist; // Vert. Objektabstand wenn bYDistOvr=TRUE + sal_uInt16 nConId; // Konnektornummer + + // bitfield + unsigned bBestConn : 1; // sal_True= es wird der guenstigste Konnektor gesucht + unsigned bBestVertex : 1; // sal_True= es wird der guenstigste Scheitelpunkt zum konnekten gesucht + unsigned bXDistOvr : 1; // sal_True= Hor. Objektabstand wurde gedragt (Overwrite) + unsigned bYDistOvr : 1; // sal_True= Vert. Objektabstand wurde gedragt (Overwrite) + unsigned bAutoVertex : 1; // AutoConnector am Scheitelpunkt nCon + unsigned bAutoCorner : 1; // AutoConnector am Eckpunkt nCon + +public: + SdrObjConnection() { ResetVars(); } + SVX_DLLPUBLIC ~SdrObjConnection(); + + void ResetVars(); + bool TakeGluePoint(SdrGluePoint& rGP, bool bSetAbsolutePos) const; + + inline void SetBestConnection( sal_Bool rB ) { bBestConn = rB; }; + inline void SetBestVertex( sal_Bool rB ) { bBestVertex = rB; }; + inline void SetAutoVertex( sal_Bool rB ) { bAutoVertex = rB; }; + inline void SetConnectorId( sal_uInt16 nId ) { nConId = nId; }; + + inline sal_Bool IsBestConnection() const { return bBestConn; }; + inline sal_Bool IsBestVertex() const { return bBestVertex; }; + inline sal_Bool IsAutoVertex() const { return bAutoVertex; }; + inline sal_uInt16 GetConnectorId() const { return nConId; }; + inline SdrObject* GetObject() const { return pObj; } +}; + +//************************************************************ +// Hilfsklasse SdrEdgeInfoRec +//************************************************************ + +enum SdrEdgeLineCode {OBJ1LINE2,OBJ1LINE3,OBJ2LINE2,OBJ2LINE3,MIDDLELINE}; + +class SdrEdgeInfoRec +{ +public: + // Die 5 Distanzen werden beim draggen bzw. per SetAttr gesetzt und von + // ImpCalcEdgeTrack ausgewertet. Per Get/SetAttr/Get/SetStyleSh werden + // jedoch nur 0-3 longs transportiert. + Point aObj1Line2; + Point aObj1Line3; + Point aObj2Line2; + Point aObj2Line3; + Point aMiddleLine; + + // Nachfolgende Werte werden von ImpCalcEdgeTrack gesetzt + long nAngle1; // Austrittswinkel am Obj1 + long nAngle2; // Austrittswinkel am Obj2 + sal_uInt16 nObj1Lines; // 1..3 + sal_uInt16 nObj2Lines; // 1..3 + sal_uInt16 nMiddleLine; // 0xFFFF=keine, sonst Punktnummer des Linienbeginns + char cOrthoForm; // Form des Ortho-Verbindes, z.B. 'Z','U',I','L','S',... + +public: + SdrEdgeInfoRec() + : nAngle1(0), + nAngle2(0), + nObj1Lines(0), + nObj2Lines(0), + nMiddleLine(0xFFFF), + cOrthoForm(0) + {} + + Point& ImpGetLineVersatzPoint(SdrEdgeLineCode eLineCode); + const Point& ImpGetLineVersatzPoint(SdrEdgeLineCode eLineCode) const { return ((SdrEdgeInfoRec*)this)->ImpGetLineVersatzPoint(eLineCode); } + sal_uInt16 ImpGetPolyIdx(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const; + bool ImpIsHorzLine(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const; + void ImpSetLineVersatz(SdrEdgeLineCode eLineCode, const XPolygon& rXP, long nVal); + long ImpGetLineVersatz(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const; +}; + +//************************************************************ +// Hilfsklasse SdrEdgeObjGeoData +//************************************************************ + +class SdrEdgeObjGeoData : public SdrTextObjGeoData +{ +public: + SdrObjConnection aCon1; // Verbindungszustand des Linienanfangs + SdrObjConnection aCon2; // Verbindungszustand des Linienendes + XPolygon* pEdgeTrack; + sal_Bool bEdgeTrackDirty;// sal_True=Verbindungsverlauf muss neu berechnet werden. + sal_Bool bEdgeTrackUserDefined; + SdrEdgeInfoRec aEdgeInfo; + +public: + SdrEdgeObjGeoData(); + virtual ~SdrEdgeObjGeoData(); +}; + +//************************************************************ +// Hilfsklasse SdrEdgeObj +//************************************************************ + +class SVX_DLLPUBLIC SdrEdgeObj : public SdrTextObj +{ +private: + // to allow sdr::properties::ConnectorProperties access to ImpSetAttrToEdgeInfo() + friend class sdr::properties::ConnectorProperties; + + friend class SdrCreateView; + friend class ImpEdgeHdl; + +protected: + virtual sdr::contact::ViewContact* CreateObjectSpecificViewContact(); + virtual sdr::properties::BaseProperties* CreateObjectSpecificProperties(); + + SdrObjConnection aCon1; // Verbindungszustand des Linienanfangs + SdrObjConnection aCon2; // Verbindungszustand des Linienendes + + XPolygon* pEdgeTrack; + sal_uInt16 nNotifyingCount; // Verrieglung + SdrEdgeInfoRec aEdgeInfo; + + // bitfield + unsigned bEdgeTrackDirty : 1; // sal_True=Verbindungsverlauf muss neu berechnet werden. + unsigned bEdgeTrackUserDefined : 1; + + // #109007# + // Bool to allow supporession of default connects at object + // inside test (HitTest) and object center test (see ImpFindConnector()) + unsigned mbSuppressDefaultConnect : 1; + + // #110649# + // Flag value for avoiding death loops when calculating BoundRects + // from circularly connected connectors. A coloring algorythm is used + // here. When the GetCurrentBoundRect() calculation of a SdrEdgeObj + // is running, the flag is set, else it is always sal_False. + unsigned mbBoundRectCalculationRunning : 1; + +public: + // #109007# + // Interface to default connect suppression + void SetSuppressDefaultConnect(sal_Bool bNew) { mbSuppressDefaultConnect = bNew; } + sal_Bool GetSuppressDefaultConnect() const { return mbSuppressDefaultConnect; } + + // #110649# + sal_Bool IsBoundRectCalculationRunning() const { return mbBoundRectCalculationRunning; } + +protected: + virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint); + + XPolygon ImpCalcObjToCenter(const Point& rStPt, long nEscAngle, const Rectangle& rRect, const Point& rCenter) const; + void ImpRecalcEdgeTrack(); // Neuberechnung des Verbindungsverlaufs + XPolygon ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection& rCon1, SdrObjConnection& rCon2, SdrEdgeInfoRec* pInfo) const; + XPolygon ImpCalcEdgeTrack(const Point& rPt1, long nAngle1, const Rectangle& rBoundRect1, const Rectangle& rBewareRect1, + const Point& rPt2, long nAngle2, const Rectangle& rBoundRect2, const Rectangle& rBewareRect2, + sal_uIntPtr* pnQuality, SdrEdgeInfoRec* pInfo) const; + static bool ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrObjConnection& rCon, const SdrEdgeObj* pThis, OutputDevice* pOut=NULL); + sal_uInt16 ImpCalcEscAngle(SdrObject* pObj, const Point& aPt2) const; + void ImpSetTailPoint(bool bTail1, const Point& rPt); + void ImpUndirtyEdgeTrack(); // eventuelle Neuberechnung des Verbindungsverlaufs + void ImpDirtyEdgeTrack(); // invalidate connector path, so it will be recalculated next time + void ImpSetAttrToEdgeInfo(); // Werte vom Pool nach aEdgeInfo kopieren + void ImpSetEdgeInfoToAttr(); // Werte vom aEdgeInfo in den Pool kopieren + +public: + TYPEINFO(); + + SdrEdgeObj(); + virtual ~SdrEdgeObj(); + + SdrObjConnection& GetConnection(bool bTail1) { return *(bTail1 ? &aCon1 : &aCon2); } + virtual void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const; + virtual sal_uInt16 GetObjIdentifier() const; + virtual const Rectangle& GetCurrentBoundRect() const; + virtual const Rectangle& GetSnapRect() const; + virtual bool IsNode() const; + virtual SdrGluePoint GetVertexGluePoint(sal_uInt16 nNum) const; + virtual SdrGluePoint GetCornerGluePoint(sal_uInt16 nNum) const; + virtual const SdrGluePointList* GetGluePointList() const; + virtual SdrGluePointList* ForceGluePointList(); + virtual bool IsEdge() const; + + // bTail1=TRUE: Linienanfang, sonst LinienEnde + // pObj=NULL: Disconnect + void SetEdgeTrackDirty() { bEdgeTrackDirty=sal_True; } + void ConnectToNode(bool bTail1, SdrObject* pObj); + void DisconnectFromNode(bool bTail1); + SdrObject* GetConnectedNode(bool bTail1) const; + const SdrObjConnection& GetConnection(bool bTail1) const { return *(bTail1 ? &aCon1 : &aCon2); } + bool CheckNodeConnection(bool bTail1) const; + + virtual void RecalcSnapRect(); + virtual void TakeUnrotatedSnapRect(Rectangle& rRect) const; + virtual SdrEdgeObj* Clone() const; + SdrEdgeObj& operator=(const SdrEdgeObj& rObj); + virtual void TakeObjNameSingul(String& rName) const; + virtual void TakeObjNamePlural(String& rName) const; + + void SetEdgeTrackPath( const basegfx::B2DPolyPolygon& rPoly ); + basegfx::B2DPolyPolygon GetEdgeTrackPath() const; + + virtual basegfx::B2DPolyPolygon TakeXorPoly() const; + virtual sal_uInt32 GetHdlCount() const; + virtual SdrHdl* GetHdl(sal_uInt32 nHdlNum) const; + + // special drag methods + virtual bool hasSpecialDrag() const; + virtual bool beginSpecialDrag(SdrDragStat& rDrag) const; + virtual bool applySpecialDrag(SdrDragStat& rDrag); + virtual String getSpecialDragComment(const SdrDragStat& rDrag) const; + + // FullDrag support + virtual SdrObject* getFullDragClone() const; + + virtual void NbcSetSnapRect(const Rectangle& rRect); + virtual void NbcMove(const Size& aSize); + virtual void NbcResize(const Point& rRefPnt, const Fraction& aXFact, const Fraction& aYFact); + + // #i54102# added rotate, mirrorn and shear support + virtual void NbcRotate(const Point& rRef, long nWink, double sn, double cs); + virtual void NbcMirror(const Point& rRef1, const Point& rRef2); + virtual void NbcShear(const Point& rRef, long nWink, double tn, bool bVShear); + + // #102344# Added missing implementation + virtual void NbcSetAnchorPos(const Point& rPnt); + + virtual bool BegCreate(SdrDragStat& rStat); + virtual bool MovCreate(SdrDragStat& rStat); + virtual bool EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd); + virtual bool BckCreate(SdrDragStat& rStat); + virtual void BrkCreate(SdrDragStat& rStat); + virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat& rDrag) const; + virtual Pointer GetCreatePointer() const; + virtual SdrObject* DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const; + + virtual sal_uInt32 GetSnapPointCount() const; + virtual Point GetSnapPoint(sal_uInt32 i) const; + virtual sal_Bool IsPolyObj() const; + virtual sal_uInt32 GetPointCount() const; + virtual Point GetPoint(sal_uInt32 i) const; + virtual void NbcSetPoint(const Point& rPnt, sal_uInt32 i); + + virtual SdrObjGeoData* NewGeoData() const; + virtual void SaveGeoData(SdrObjGeoData& rGeo) const; + virtual void RestGeoData(const SdrObjGeoData& rGeo); + + /** updates edges that are connected to the edges of this object + as if the connected objects send a repaint broadcast + #103122# + */ + void Reformat(); + + // helper methods for the StarOffice api + Point GetTailPoint( sal_Bool bTail ) const; + void SetTailPoint( sal_Bool bTail, const Point& rPt ); + void setGluePointIndex( sal_Bool bTail, sal_Int32 nId = -1 ); + sal_Int32 getGluePointIndex( sal_Bool bTail ); + + virtual sal_Bool TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const; + virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon); + + // for geometry access + ::basegfx::B2DPolygon getEdgeTrack() const; + + // helper method for SdrDragMethod::AddConnectorOverlays. Adds a overlay polygon for + // this connector to rResult. + basegfx::B2DPolygon ImplAddConnectorOverlay(SdrDragMethod& rDragMethod, bool bTail1, bool bTail2, bool bDetail) const; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Zur Bestimmung der Verlaufslinie werden folgende Item-Parameter des SdrItemPool verwendet: +// +// sal_uInt16 EdgeFlowAngle Default 9000 (=90.00 Deg), min 0, max 9000 +// Verlauffreiheitswinkel. +// Der Winkel, in dem die Verbindungslinie verlaufen darf. +// +// sal_uInt16 EdgeEscAngle Default 9000 (=90.00 Deg), min 0, max 9000 +// Objektaustrittswinkel. +// Der Winkel, in dem die Verbindungslinie aus dem Objekt austreten darf. +// +// sal_Bool EdgeEscAsRay Default FALSE +// sal_True= die Verbindungslinie tritt aus dem Obj Strahlenfoermig aus. +// Also Winkelvorgabe durch die Strecke ObjMitte/Konnektor. +// +// sal_Bool EdgeEscUseObjAngle Default FALSE +// Objektdrehwinkelberuecksichtigung. +// sal_True= Bei der Bestimmung des Objektaustrittswinkels wird der +// Drehwinkel des Objekts als Offset beruecksichtigt. +// +// sal_uIntPtr EdgeFlowDefDist Default 0, min 0, max ? +// Das ist der Default-Mindestabstand der bei der Berechnung der +// Verbindungslinie zu den angedockten Objekten in logischen Einheiten. +// Dieser Abstand wird innerhalb des Objektes "ueberschrieben", sobald +// der User an den Linien draggd. Beim Andocken an ein neues Objekt wird +// dann jedoch wieder dieser Default verwendet. +// +// +// Allgemeines zu Konnektoren: +// +// Es gibt Knoten und Kantenobjekte. Zwei Knoten koennen durch eine Kante +// miteinander verbunden werden. Ist eine Kante nur an einem Ende an einen +// Knoten geklebt, ist das andere Ende auf einer absoluten Position im Doc +// fixiert. Ebenso ist es natuerlich auch moeglich, dass eine Kante an beiden +// Enden "frei", also nicht mit einem Knotenobjekt verbunden ist. +// +// Ein Kantenobjekt kann theoretisch auch gleichzeitig Knotenobjekt sein. In +// der ersten Version wird das jedoch noch nicht realisiert werden. +// +// Eine Verbindung zwischen Knoten und Kante kann hergestellt werden durch: +// - Interaktives erzeugen eines neuen Kantenobjekts an der SdrView wobei +// Anfangs- bzw. Endpunkt der Kante auf ein Konnektor (Klebestelle) eines +// bereits vorhandenen Knotenobjekts gelegt wird. +// - Interaktives draggen des Anfangs- bzw. Endpunkts eines bestehenden +// Kantenobjekts an der SdrView auf ein Konnektor (Klebestelle) eines +// bereits vorhandenen Knotenobjekts. +// - Undo/Redo +// Verschieben von Knotenobjekten stellt keine Verbindungen her. Ebenso auch +// nicht das direkte Verschieben von Kantenendpunkten am SdrModel... +// Verbindungen koennen auch hergestellt werden, wenn die Konnektoren an der +// View nicht sichtbar geschaltet sind. +// +// Eine vorhandene Verbindung zwischen Knoten und Kante bleibt erhalten bei: +// - Draggen (Move/Resize/Rotate/...) des Knotenobjekts +// - Verschieben einer Konnektorposition im Knotemobjekt +// - gleichzeitiges Draggen (Move/Resize/Rotate/...) von Knoten und Kante +// +// Eine Verbindung zwischen Knoten und Kante kann geloesst werden durch: +// - Loeschen eines der Objekte +// - Draggen des Kantenobjekts ohne gleichzeitiges Draggen des Knotens +// - Loeschen des Konnektors am Knotenobjekt +// - Undo/Redo/Repeat +// Beim Draggen muss die Aufforderung zum loesen der Verbindung von ausserhalb +// des Models befohlen werden (z.B. von der SdrView). SdrEdgeObj::Move() loesst +// die Verbindung nicht selbsttaetig. +// +// Jedes Knotenobjekt kann Konnektoren, sog. Klebestellen besitzen. Das sind die +// geometrischen Punkte, an denen das verbindende Kantenobjekt bei hergestellter +// Verbindung endet. Defaultmaessig hat jedes Objekt keine Konnektoren. Trotzdem +// kann man bei bestimmten View-Einstellungen eine Kante andocken, da dann z.B. +// an den 4 Scheitelpunkten des Knotenobjekts bei Bedarf automatisch Konnektoren +// generiert werden. Jedes Objekt liefert dafuer 2x4 sog. Default-Konnektorposi- +// tionen, 4 an den Scheitelpunkten und 4 an den Eckpositionen. Im Normalfall +// liegen diese an den 8 Handlepositionen; Ausnahmen bilden hier Ellipsen, +// Parallelogramme, ... . Darueberhinaus koennen auch an jedem Knotenobjekt +// anwenderspeziefische Konnektoren gesetzt werden. +// +// Dann gibt es noch die Moeglichkeit, ein Kante an einem Objekt mit dem +// Attribut "bUseBestConnector" anzudocken. Es wird dann aus dem Angebot der +// Konnektoren des Objekts oder/und der Scheitelpunkte, jeweils die fuer den +// Verlauf der Verbindungslinie guenstigste Konnektorposition verwendet. Der +// Anwender vergibt dieses Attribut, indem er den Knoten in seiner Mitte +// andockt (siehe z.B. Visio). +// 09-06-1996: bUseBestConnector verwendet nur Scheitelpunktklebepunkte. +// +// Und hier noch etwas Begriffsdefinition: +// Verbinder : Eben das Verbinderobjekt (Kantenobjekt) +// Knoten : Ein beliebiges Objekt, an dem ein Verbinder drangeklebt +// werden kann, z.B. ein Rechteck, ... +// Klebepunkt: Der Punkt, an dem der Verbinder an das Knotenobjekt +// geklebt wird. Hierbei gibt es: +// Scheitelpunktklebepunkte: Jedes Knotenobjekt hat diese +// Klebepunkte von Natur aus. Moeglicherweise gibt es +// im Draw bereits die Option "Automatisch ankleben an +// Objektscheitelpunkte" (default an) +// Eckpunktklebepunkte: Auch diese Klebepunkte sind den +// Objekten von mir bereits mitgegeben. Wie die oben +// erwaehnten gibt es fuer diese moeglicherweise +// bereits auch eine Option im Draw. (default aus) +// Scheitelpunktklebepunkte und Eckpunktklebepunkte sind +// im Gegensatz zu Visio nicht optisch sichtbar; sie +// sind eben einfach da (wenn Option eingeschaltet). +// Benutzerdefinierte Klebepunkte: Gibt es an jedem +// Knotenobjekt beliebig viele. Per Option koennen sie +// sichtbar geschaltet werden (beim editieren immer +// sichtbar). Zur Zeit sind die jedoch noch nicht ganz +// fertigimplementiert. +// Automatische Klebepunktwahl: Wird der Verbinder so an +// das Knotenobjekt gedockt, dass der schwarke Rahmen +// das gesamte Objekt umfasst, so versucht der +// Verbinder von den 4 Scheitelpunktklebepunkten (und +// zwar nur von denen) den guenstigsten herauszufinden. +// +////////////////////////////////////////////////////////////////////////////////////////////////// + +#endif //_SVDOEDGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |