/*************************************************************************
 *
 *  $RCSfile: svdobj.hxx,v $
 *
 *  $Revision: 1.18.2.1 $
 *
 *  last change: $Author: mh $ $Date: 2002/05/31 12:57:14 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _SVDOBJ_HXX
#define _SVDOBJ_HXX

#ifndef _CPPUHELPER_WEAKREF_HXX_
#include <cppuhelper/weakref.hxx>
#endif

#ifndef _MAPMOD_HXX //autogen
#include <vcl/mapmod.hxx>
#endif

#ifndef _SFXLSTNER_HXX //autogen
#include <svtools/lstner.hxx>
#endif

#ifndef _SV_TIMER_HXX
#include <vcl/timer.hxx>
#endif

#ifndef _SVDSOB_HXX //autogen
#include <svx/svdsob.hxx>
#endif

#ifndef _SVDTYPES_HXX
#include <svx/svdtypes.hxx> // fuer SdrLayerID
#endif

#ifndef _SVDGLUE_HXX
#include <svx/svdglue.hxx> // Klebepunkte
#endif

#ifndef _SVX_XDASH_HXX
#include <svx/xdash.hxx>
#endif

#ifndef _XPOLY_HXX
#include <svx/xpoly.hxx>
#endif

#ifndef _POLY3D_HXX
#include <svx/poly3d.hxx>
#endif

#ifndef _XENUM_HXX
#include <svx/xenum.hxx>
#endif

//************************************************************
//   Vorausdeklarationen
//************************************************************

class SfxBroadcaster;
class Pointer;
class AutoTimer;
class ExtOutputDevice;
class ImpSdrMtfAnimator;
class OutlinerParaObject;
class SdrOutliner;
class SdrDragStat;
class SdrHdl;
class SdrHdlList;
class SdrItemPool;
class SdrMiscSetItem;
class SdrModel;
class SdrObjIOHeader;
class SdrObjList;
class SdrObject;
class SdrOutlinerSetItem;
class SdrPage;
class SdrPageView;
class SdrShadowSetItem;
class SdrView;
class SfxItemSet;
class SfxSetItem;
class SfxStyleSheet;
class SfxUndoAction;
class XFillAttrSetItem;
class XLineAttrSetItem;
class XPolyPolygon;
class XPolygon;
class XTextAttrSetItem;
class SfxItemPool;
class PolyPolygon;
class SfxPoolItem;

//************************************************************
//   Defines
//************************************************************

enum SdrObjKind {OBJ_NONE       = 0,  // Abstraktes Objekt (SdrObject)
				 OBJ_GRUP       = 1,  // Objektgruppe
				 OBJ_LINE       = 2,  // Strecke
				 OBJ_RECT       = 3,  // Rechteck ww. mit runden Ecken
				 OBJ_CIRC       = 4,  // Kreis, Ellipse
				 OBJ_SECT       = 5,  // Kreissektor
				 OBJ_CARC       = 6,  // Kreisbogen
				 OBJ_CCUT       = 7,  // Kreisabschnitt
				 OBJ_POLY       = 8,  // Polygon, PolyPolygon
				 OBJ_PLIN       = 9,  // PolyLine
				 OBJ_PATHLINE   =10,  // Offene Bezierkurve
				 OBJ_PATHFILL   =11,  // Geschlossene Bezierkurve
				 OBJ_FREELINE   =12,  // Offene Freihandlinie
				 OBJ_FREEFILL   =13,  // Geschlossene Freihandlinie
				 OBJ_SPLNLINE   =14,  // Natuerlicher kubischer Spline          (ni)
				 OBJ_SPLNFILL   =15,  // Periodischer kubischer Spline          (ni)
				 OBJ_TEXT       =16,  // Textobjekt
				 OBJ_TEXTEXT    =17,  // Texterweiterungsrahmen                 (ni)
				 OBJ_wegFITTEXT,      // FitToSize-Text (alle Zeilen gleich)
				 OBJ_wegFITALLTEXT,   // FitToSize-Text (Zeilenweise)           (ni)
				 OBJ_TITLETEXT  =20,  // Titeltext. Spezial-Textobjekt fuer StarDraw
				 OBJ_OUTLINETEXT=21,  // OutlineText. Spezial-Textobjekt fuer StarDraw
				 OBJ_GRAF       =22,  // Fremdgrafik - (StarView Graphic)
				 OBJ_OLE2       =23,  // OLE-Objekt
				 OBJ_EDGE       =24,  // Verbindungsobjekt fuer Konnektoren
				 OBJ_CAPTION    =25,  // Legendenobjekt
				 OBJ_PATHPOLY   =26,  // Polygon/PolyPolygon dargestellt durch SdrPathObj
				 OBJ_PATHPLIN   =27,  // Polyline dargestellt durch SdrPathObj
				 OBJ_PAGE       =28,  // Objekt, das eine SdrPage darstellt
				 OBJ_MEASURE    =29,  // Bemassungsobjekt
				 OBJ_DUMMY      =30,  // Dummyobjekt zum speichern von Luecken (zur anschliessenden Wiederherstellung der Surrogate)
				 OBJ_FRAME      =31,  // staendig aktives OLE (PlugIn-Frame oder sowas)
				 OBJ_UNO        =32,  // Universal Network Object im SvDraw-Obj eingepackt
				 OBJ_MAXI};

// Paintmodes, die den SdrObject::Paint-Methoden mitgegeben werden.
#define SDRPAINTMODE_MASTERPAGE		0x0001 /* Obj gehoert zur eingeblendeten Masterpage */
#define SDRPAINTMODE_TEXTEDIT		0x0002 /* An diesem Objekt ist z.Zt. TextEdit aktiv */
#define SDRPAINTMODE_DRAFTTEXT		0x0004 /* Entwurfsmodus, Text weglassen bzw. nur andeuten (Ersatzdarstellung) */
#define SDRPAINTMODE_DRAFTGRAF		0x0008 /* Entwurfsmodus, Grafiken nur andeuten (Ersatzdarstellung) */
#define SDRPAINTMODE_GLUEPOINTS		0x0010 /* Klebepunkte anzeigen */
#define SDRPAINTMODE_ANILIKEPRN		0x0020 /* Animationen so malen, als ob gedruckt wird (z.B. fuer Laufschrift im SdrPageObj) */
#define SDRPAINTMODE_HIDEDRAFTGRAF  0x0040 /* Entwurfsmodus, angedeutete Grafiken nicht darstellen */
#define SDRPAINTMODE_DRAFTLINE		0x0080 /* draftmode for LINE */
#define SDRPAINTMODE_DRAFTFILL		0x0100 /* draftmode for FILL */
									   /* ... to be continued */
enum SdrUserCallType {SDRUSERCALL_MOVEONLY,       	// Nur verschoben, Groesse unveraendert
					  SDRUSERCALL_RESIZE,         	// Groesse und evtl. auch Pos veraendert
					  SDRUSERCALL_CHGATTR,  		// Attribute veraendert. Moeglicherweise neue Groesse wg. Linienbreite
					  SDRUSERCALL_DELETE,   		// Obj gibt es gleich nicht mehr. Schon keine Attr mehr.
					  SDRUSERCALL_COPY,     		// Zuweisungsoperator gerufen. Kann alles geaendert sein
					  SDRUSERCALL_INSERTED, 		// In eine Objektliste (z.B. Page) eingefuegt
					  SDRUSERCALL_REMOVED,  		// Aus der Objektliste entfernt
					  SDRUSERCALL_CHILD_MOVEONLY, 	// Ein Child einer Gruppe hat sich veraendert
					  SDRUSERCALL_CHILD_RESIZE,   	// Ein Child einer Gruppe hat sich veraendert
					  SDRUSERCALL_CHILD_CHGATTR,  	// Ein Child einer Gruppe hat sich veraendert
					  SDRUSERCALL_CHILD_DELETE,   	// Ein Child einer Gruppe hat sich veraendert
					  SDRUSERCALL_CHILD_COPY,     	// Ein Child einer Gruppe hat sich veraendert
					  SDRUSERCALL_CHILD_INSERTED, 	// Ein Child einer Gruppe hat sich veraendert
					  SDRUSERCALL_CHILD_REMOVED}; 	// Ein Child einer Gruppe hat sich veraendert

/* nur voruebergehend, weil sonst MUSS-Aenderung */
#define nLayerID nLayerId

//************************************************************
//   Hilfsklasse SdrObjUserCall
//************************************************************

class SdrObjUserCall
{
public:
	TYPEINFO();
	virtual ~SdrObjUserCall();
	virtual void Changed(const SdrObject& rObj, SdrUserCallType eType, const Rectangle& rOldBoundRect);
};

//************************************************************
//   Hilfsklasse SdrObjMacroHitRec
//************************************************************

class SdrObjMacroHitRec
{
public:
	Point						aPos;
	Point						aDownPos;
	OutputDevice*				pOut;
	const SetOfByte*			pVisiLayer;
	const SdrPageView*			pPageView;
	USHORT						nTol;
	FASTBOOL					bDown;

public:
	SdrObjMacroHitRec()
	:	pOut(NULL),
		pVisiLayer(NULL),
		pPageView(NULL),
		nTol(0),
		bDown(FALSE)
	{}
};

//************************************************************
//   Hilfsklasse SdrObjUserData
//
// Anwenderdaten an einem Zeichenobjekt, z.B. applikationsspezifische Daten.
// Jedes Zeichenobjekt kann beliebig viele dieser Records haben (SV-Liste).
// Wer hier Daten halten will, muss sich ableiten und auch an der Factory
// einen entsprechenden Link setzen.
//
//************************************************************

class SdrObjUserData
{
protected:
	UINT32						nInventor;
	UINT16						nIdentifier;
	UINT16						nVersion;

private:
	void operator=(const SdrObjUserData& rData);        // nicht implementiert
	FASTBOOL operator==(const SdrObjUserData& rData) const; // nicht implementiert
	FASTBOOL operator!=(const SdrObjUserData& rData) const; // nicht implementiert

public:
	TYPEINFO();

	SdrObjUserData(UINT32 nInv, UINT16 nId, UINT16 nVer)
	:	nInventor(nInv),
		nIdentifier(nId),
		nVersion(nVer)
	{}
	SdrObjUserData(const SdrObjUserData& rData)
	:	nInventor(rData.nInventor),
		nIdentifier(rData.nIdentifier),
		nVersion(rData.nVersion)
	{}
	virtual ~SdrObjUserData();

	virtual SdrObjUserData* Clone(SdrObject* pObj1) const = NULL;
	UINT32  GetInventor() const { return nInventor; }
	UINT16  GetId() const { return nIdentifier; }
	virtual void WriteData(SvStream& rOut);
	virtual void ReadData(SvStream& rIn);

	// z.B. fuer die Wiederherstellung von Surrogaten.
	// Siehe auch SdrObject::AfterRead().
	virtual void AfterRead();

	virtual FASTBOOL HasMacro (const SdrObject* pObj) const;
	virtual SdrObject* CheckMacroHit (const SdrObjMacroHitRec& rRec, const SdrObject* pObj) const;
	virtual Pointer GetMacroPointer (const SdrObjMacroHitRec& rRec, const SdrObject* pObj) const;
	virtual void PaintMacro (ExtOutputDevice& rXOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec, const SdrObject* pObj) const;
	virtual FASTBOOL DoMacro (const SdrObjMacroHitRec& rRec, SdrObject* pObj);
	virtual XubString GetMacroPopupComment(const SdrObjMacroHitRec& rRec, const SdrObject* pObj) const;
};

//************************************************************
//   Hilfsklasse SdrObjUserDataList
//************************************************************

class SdrObjUserDataList
{
	Container					aList;

public:
	SdrObjUserDataList()
	:	aList(1024,4,4)
	{}
	~SdrObjUserDataList() { Clear(); }

	void Clear();
	USHORT GetUserDataCount() const { return USHORT(aList.Count()); }
	SdrObjUserData* GetUserData(USHORT nNum) const { return (SdrObjUserData*)aList.GetObject(nNum); }
	void InsertUserData(SdrObjUserData* pData, USHORT nPos=0xFFFF) { aList.Insert(pData,nPos); }
	SdrObjUserData* RemoveUserData(USHORT nNum) { return (SdrObjUserData*)aList.Remove(nNum);}
	void DeleteUserData(USHORT nNum) { delete RemoveUserData(nNum); }
};

//************************************************************
//   Hilfsklasse SdrObjGeoData
//
// Alle geometrischen Daten eines beliebigen Objektes zur Übergabe an's Undo/Redo
//
//************************************************************

class SdrObjGeoData
{
public:
	Rectangle					aBoundRect;
	Point						aAnchor;
	SdrGluePointList*			pGPL;
	BOOL						bMovProt;
	BOOL						bSizProt;
	BOOL						bNoPrint;
	BOOL						bClosedObj;
	UINT16						nLayerId;

public:
	SdrObjGeoData();
	virtual ~SdrObjGeoData();
};

//************************************************************
//   Hilfsklasse SdrObjPlusData
//
// Bitsack fuer DrawObjekte
//
//************************************************************

class SdrObjPlusData
{
	friend class				SdrObject;

public:
	SfxBroadcaster*				pBroadcast;    // Broadcaster, falls dieses Obj referenziert wird (bVirtObj=TRUE). Auch fuer Konnektoren etc.
	SdrObjUserDataList*			pUserDataList; // applikationsspeziefische Daten
	SdrGluePointList*			pGluePoints;   // Klebepunkte zum Ankleben von Objektverbindern
	ImpSdrMtfAnimator*			pAnimator;     // Fuer Laufschrift und blinkenden Text
	AutoTimer*					pAutoTimer;
	XubString					aObjName;      // Jedes Objekt soll nun einen Namen haben

	// Name to be used by applications
	XubString					aHTMLName;

public:
	TYPEINFO();
	SdrObjPlusData();
	virtual ~SdrObjPlusData();
	virtual SdrObjPlusData* Clone(SdrObject* pObj1) const;
	// Keine Streamoperatoren. Jede Obj streamt seinen Teil in Obj::WriteData().
};

//************************************************************
//   Hilfsklasse SdrObjTransformInfoRec
//
// gibt Auskunft ueber verschiedene Eigenschaften eines ZObjects
//
//************************************************************

class SdrObjTransformInfoRec
{
public:
	unsigned					bSelectAllowed : 1;     // FALSE=Obj kann nicht selektiert werden
	unsigned					bMoveAllowed : 1;       // FALSE=Obj kann nicht verschoben werden
	unsigned					bResizeFreeAllowed : 1; // FALSE=Obj kann nicht frei resized werden
	unsigned					bResizePropAllowed : 1; // FALSE=Obj kann nichtmal proportional resized werden
	unsigned					bRotateFreeAllowed : 1; // FALSE=Obj kann nicht frei gedreht werden
	unsigned					bRotate90Allowed : 1;   // FALSE=Obj kann nichtmal im 90deg Raster gedreht werden
	unsigned					bMirrorFreeAllowed : 1; // FALSE=Obj kann nicht frei gespiegelt werden
	unsigned					bMirror45Allowed : 1;   // FALSE=Obj kann nichtmal ueber Achse im 45deg Raster gespiegelt werden
	unsigned					bMirror90Allowed : 1;   // FALSE=Obj kann ebenfalls nicht ueber Achse im 90deg Raster gespiegelt werden
	unsigned					bTransparenceAllowed : 1; // FALSE=Obj does not have an interactive transparence control
	unsigned					bGradientAllowed : 1; // FALSE=Obj dooes not have an interactive gradient control
	unsigned					bShearAllowed : 1;      // FALSE=Obj kann nicht verzerrt werden
	unsigned					bEdgeRadiusAllowed : 1;
	unsigned					bNoOrthoDesired : 1;    // TRUE bei Rect; ... FALSE bei BMP,MTF;
	unsigned					bNoContortion : 1;      // FALSE=Kein verzerren (bei Crook) moeglich (nur TRUE bei PathObj und Gruppierten PathObjs)
	unsigned					bCanConvToPath : 1;     // FALSE=Keine Konvertierung in PathObj moeglich
	unsigned					bCanConvToPoly : 1;     // FALSE=Keine Konvertierung in PolyObj moeglich
	unsigned					bCanConvToContour : 1;     // FALSE=no conversion down to whole contour possible
	unsigned					bCanConvToPathLineToArea : 1; // FALSE=Keine Konvertierung in PathObj moeglich mit Wandlung von LineToArea
	unsigned					bCanConvToPolyLineToArea : 1; // FALSE=Keine Konvertierung in PolyObj moeglich mit Wandlung von LineToArea

public:
	SdrObjTransformInfoRec()
	:	bSelectAllowed(TRUE),
		bMoveAllowed(TRUE),
		bResizeFreeAllowed(TRUE),
		bResizePropAllowed(TRUE),
		bRotateFreeAllowed(TRUE),
		bRotate90Allowed(TRUE),
		bMirrorFreeAllowed(TRUE),
		bMirror45Allowed(TRUE),
		bMirror90Allowed(TRUE),
		bTransparenceAllowed(TRUE),
		bGradientAllowed(TRUE),
		bShearAllowed(TRUE),
		bEdgeRadiusAllowed(TRUE),
		bNoOrthoDesired(TRUE),
		bNoContortion(TRUE),
		bCanConvToPath(TRUE),
		bCanConvToPoly(TRUE),
		bCanConvToContour(FALSE),
		bCanConvToPathLineToArea(TRUE),
		bCanConvToPolyLineToArea(TRUE)
	{}
};

//************************************************************
//   Hilfsklasse SdrObjTransformInfoRec
//************************************************************

class SdrPaintInfoRec
{
public:
	SetOfByte					aPaintLayer;
	Rectangle					aDirtyRect;
	Rectangle					aCheckRect;
	const SdrPageView*			pPV;  // Die PageView wird u.a. vom TextObj benoetigt fuer Paint wenn TextEdit
	const Link*					pPaintProc;
	const SdrObjList*			pAktList; // falls GroupEntered oder GluePoints nur auf flacher Ebene (ni)
	USHORT						nBrkEvent;
	USHORT						nPaintMode;
	UINT32						nOriginalDrawMode;

	BOOL						bPrinter;
	BOOL						bNotActive;
	BOOL						bOriginalDrawModeSet;

public:
	SdrPaintInfoRec()
	:	aPaintLayer(TRUE),
		pPV(NULL),
		pPaintProc(NULL),
		pAktList(NULL),
		nBrkEvent(0),
		nPaintMode(0),
		nOriginalDrawMode(0L),
		bPrinter(FALSE),
		bNotActive(TRUE),
		bOriginalDrawModeSet(FALSE)
	{}
};

///////////////////////////////////////////////////////////////////////////////

class ImpLineStyleParameterPack
{
	OutputDevice*				mpOut;
	XDash						aDash;

	XLineJoint					eLineJoint;
	XLineStyle					eLineStyle;

	const XPolygon&				rStartPolygon;
	const XPolygon&				rEndPolygon;

	INT32						nLineWidth;
	INT32						nStartWidth;
	INT32						nEndWidth;

	double*						pDotDashArray;
	double						fFullDashDotLen;
	double						fDegreeStepWidth;

	UINT16						nNumDotDashArray;

	BOOL						bStartCentered;
	BOOL						bEndCentered;
	BOOL						bForceNoArrowsLeft;
	BOOL						bForceNoArrowsRight;

public:
	ImpLineStyleParameterPack(const SfxItemSet& rSet,
		BOOL bForceHair, OutputDevice* pOut);
	~ImpLineStyleParameterPack();

	OutputDevice* GetOutDev() const { return mpOut; }
	INT32 GetLineWidth() const { return nLineWidth; }
	XLineStyle GetLineStyle() const { return eLineStyle; }

	INT32 GetStartWidth() const { return nStartWidth; }
	INT32 GetEndWidth() const { return nEndWidth; }

	const XPolygon& GetStartPolygon() const { return rStartPolygon; }
	const XPolygon& GetEndPolygon() const { return rEndPolygon; }

	double GetDegreeStepWidth() const { return fDegreeStepWidth; }

	XLineJoint GetLineJoint() const { return eLineJoint; }
	double GetLinejointMiterUpperBound() const { return 3.0; }

	XDashStyle GetDashStyle() const { return aDash.GetDashStyle(); }
	UINT16 GetDots() const { return aDash.GetDots(); }
	UINT32 GetDotLen() const { return aDash.GetDotLen(); }
	UINT16 GetDashes() const { return aDash.GetDashes(); }
	UINT32 GetDashLen() const { return aDash.GetDashLen(); }
	UINT32 GetDashDistance() const { return aDash.GetDistance(); }
	double GetFullDashDotLen() const { return fFullDashDotLen; }
	UINT16 GetFirstDashDotIndex(double fPos, double& rfDist) const;
	UINT16 GetNextDashDotIndex(UINT16 nInd, double& rfDist) const;

	BOOL IsStartCentered() const { return bStartCentered; }
	BOOL IsEndCentered() const { return bEndCentered; }

	BOOL IsStartActive() const { return (!bForceNoArrowsLeft && GetStartPolygon().GetPointCount() && GetStartWidth()); }
	BOOL IsEndActive() const { return (!bForceNoArrowsRight && GetEndPolygon().GetPointCount() && GetEndWidth()); }

	void ForceNoArrowsLeft(BOOL bNew) { bForceNoArrowsLeft = bNew; }
	void ForceNoArrowsRight(BOOL bNew) { bForceNoArrowsRight = bNew; }
};

////////////////////////////////////////////////////////////////////////////////////////////////////

class ImpLineGeometryCreator
{
	const ImpLineStyleParameterPack&	mrLineAttr;
	PolyPolygon3D&						mrPolyPoly3D;
	PolyPolygon3D&						mrPolyLine3D;
	BOOL								mbLineDraft;

	// private support functions
	// help functions for line geometry creation
	void ImpCreateLineGeometry(const Polygon3D& rSourcePoly);
	double ImpCreateLineStartEnd(Polygon3D& rArrowPoly, const Polygon3D& rSourcePoly, BOOL bFront, double fWantedWidth, BOOL bCentered);
	void ImpCreateSegmentsForLine(const Vector3D* pPrev, const Vector3D* pLeft, const Vector3D* pRight, const Vector3D* pNext, double fPolyPos);
	void ImpCreateLineSegment(const Vector3D* pPrev, const Vector3D* pLeft, const Vector3D* pRight, const Vector3D* pNext);
	double ImpSimpleFindCutPoint(const Vector3D& rEdge1Start, const Vector3D& rEdge1Delta, const Vector3D& rEdge2Start, const Vector3D& rEdge2Delta);

public:
	ImpLineGeometryCreator(const ImpLineStyleParameterPack& rAttr, PolyPolygon3D& rPoPo,
		PolyPolygon3D& rPoLi, BOOL bIsLineDraft = FALSE)
	:	mrLineAttr(rAttr),
		mrPolyPoly3D(rPoPo),
		mrPolyLine3D(rPoLi),
		mbLineDraft(bIsLineDraft)
	{
	}

	void AddPolygon3D(const Polygon3D& rPoly) { ImpCreateLineGeometry(rPoly); }
	const PolyPolygon3D& GetPolyPolygon3D() const { return mrPolyPoly3D; }
	const PolyPolygon3D& GetPolyLines3D() const { return mrPolyLine3D; }
	void Clear() { mrPolyPoly3D.Clear(); mrPolyLine3D.Clear(); }
};

////////////////////////////////////////////////////////////////////////////////////////////////////

class ImpLineGeometry
{
	PolyPolygon3D				maPolyPoly3D;
	PolyPolygon3D				maLinePoly3D;
	BOOL						mbForceOnePixel;
	BOOL						mbForceTwoPixel;

public:
	ImpLineGeometry(PolyPolygon3D& rPolyPoly, PolyPolygon3D& rLinePoly,
		BOOL bForceOnePixel, BOOL bForceTwoPixel)
	:	maPolyPoly3D(rPolyPoly),
		maLinePoly3D(rLinePoly),
		mbForceOnePixel(bForceOnePixel),
		mbForceTwoPixel(bForceTwoPixel)
	{}

	PolyPolygon3D& GetPolyPoly3D() { return maPolyPoly3D; }
	PolyPolygon3D& GetLinePoly3D() { return maLinePoly3D; }
	BOOL DoForceOnePixel() const { return mbForceOnePixel; }
	BOOL DoForceTwoPixel() const { return mbForceTwoPixel; }
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// class to remember broadcast start positions

class SdrBroadcastItemChange
{
	sal_uInt32					mnCount;
	void*						mpData;

public:
	SdrBroadcastItemChange(const SdrObject& rObj);
	~SdrBroadcastItemChange();

	sal_uInt32 GetRectangleCount() const { return mnCount; }
	const Rectangle& GetRectangle(sal_uInt32 nIndex) const;
};

////////////////////////////////////////////////////////////////////////////////////////////////////
//
//   @@@@  @@@@@  @@@@@@ @@@@@  @@@@  @@@@@@
//  @@  @@ @@  @@     @@ @@    @@  @@   @@
//  @@  @@ @@  @@     @@ @@    @@       @@
//  @@  @@ @@@@@      @@ @@@@  @@       @@
//  @@  @@ @@  @@     @@ @@    @@       @@
//  @@  @@ @@  @@ @@  @@ @@    @@  @@   @@
//   @@@@  @@@@@   @@@@  @@@@@  @@@@    @@
//
// Abstraktes DrawObject
//
////////////////////////////////////////////////////////////////////////////////////////////////////

class SdrObject: public SfxListener
{
	friend class				SdrObjListIter;
	friend class				SdrVirtObj;
	friend class				SdrRectObj;

	static SfxItemSet*			mpEmptyItemSet;

protected:
	Rectangle					aOutRect;     // umschliessendes Rechteck fuer Paint (inkl. LineWdt, ...)
	Point						aAnchor;      // Ankerposition (Writer)
	SdrObjList*					pObjList;     // Liste, in dem das Obj eingefuegt ist.
	SdrPage*					pPage;
	SdrModel*					pModel;
	SdrObjUserCall*				pUserCall;
	SdrObjPlusData*				pPlusData;    // Broadcaster, UserData, Konnektoren, ... (Das ist der Bitsack)

	UINT32						nOrdNum;      // Rangnummer des Obj in der Liste
	UINT16						nLayerId;

	// Objekt zeigt nur auf ein Anderes
	BOOL						bVirtObj : 1;
	BOOL						bBoundRectDirty : 1;
	BOOL						bSnapRectDirty : 1;
	BOOL						bNetLock : 1;   // ni
	BOOL						bInserted : 1;  // nur wenn TRUE gibt's RepaintBroadcast & SetModify
	BOOL						bGrouped : 1;   // Member eines GroupObjektes?

	// Die folgende Flags werden gestreamt
	BOOL						bMovProt : 1; // Position geschuetzt
	BOOL						bSizProt : 1; // Groesse geschuetzt
	BOOL						bNoPrint : 1; // Nicht drucken

	// Wenn bEmptyPresObj TRUE ist, handelt es sich um ein
	// Praesentationsobjekt, dem noch kein Inhalt zugewiesen
	// wurde. Default ist das Flag auf FALSE. Die Verwaltung
	// uebernimmt die Applikation. Im Zuweisungsoperator sowie
	// beim Clone wird das Flag nicht mitkopiert!
	// Das Flag ist persistent.
	BOOL						bEmptyPresObj : 1;     // Leeres Praesentationsobjekt (Draw)
	BOOL						bNotPersistent : 1;    // TRUE= Obj wird nicht gestreamt (Writer)
	BOOL						bNeedColorRestore : 1; // TRUE= Obj benoetigt ColorRestore vor Paint-Aufruf (Writer)

	// TRUE=Objekt ist als Objekt der MasterPage nicht sichtbar
	BOOL						bNotVisibleAsMaster : 1;

	// TRUE=Es handelt sich hierbei um ein geschlossenes Objekt, also nicht Linie oder Kreisbogen ...
	BOOL						bClosedObj : 1;
	BOOL						bWriterFlyFrame : 1;   // Special fuer den Writer
	BOOL						bIsEdge : 1;
	BOOL						bIs3DObj : 1;
	BOOL						bMarkProt : 1;  // Markieren verboten. Persistent
	BOOL						bIsUnoObj : 1;
	BOOL						bNotMasterCachable : 1;

	// global static ItemPool for not-yet-insetred items
private:
	static SdrItemPool*			mpGlobalItemPool;
public:
	static SdrItemPool* GetGlobalDrawObjectItemPool();
private:
	static void FreeGlobalDrawObjectItemPool();

protected:
	void ImpDeleteUserData();
	SdrObjUserData* ImpGetMacroUserData() const;
	Rectangle ImpDragCalcRect(const SdrDragStat& rDrag) const;

	// Fuer GetDragComment
	void ImpTakeDescriptionStr(USHORT nStrCacheID, String& rStr, USHORT nVal=0) const;

	void ImpForcePlusData() { if (pPlusData==NULL) pPlusData=NewPlusData(); }
	ImpSdrMtfAnimator* ImpGetMtfAnimator() const { return pPlusData!=NULL ? pPlusData->pAnimator : NULL; }
	ImpSdrMtfAnimator* ImpForceMtfAnimator();

	String GetWinkStr(long nWink, FASTBOOL bNoDegChar=FALSE) const;
	String GetMetrStr(long nVal, MapUnit eWantMap=MAP_MM, FASTBOOL bNoUnitChars=FALSE) const;

	// bNotMyself=TRUE bedeutet: Nur die ObjList auf Dirty setzen, nicht mich.
	// Wird z.B. benoetigt fuer NbcMove, denn da movt man SnapRect und aOutRect
	// i.d.R. gleich mit um die Neuberechnung zu sparen.
	virtual void SetRectsDirty(FASTBOOL bNotMyself=FALSE);

	// ueberladen, wenn man sich von SdrObjPlusData abgeleitet hat:
	virtual SdrObjPlusData* NewPlusData() const;

	// this is a weak reference to a possible living api wrapper for this shape
	::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface > mxUnoShape;

protected:
	// Diese 3 Methoden muss ein abgeleitetes Objekt ueberladen, wenn es eigene
	// geometrische Daten besitzt, die fuer den Undo-Fall gesichert werden
	// sollen. NewGeoData() erzeugt lediglich eine leere Instanz auf eine von
	// SdrObjGeoData abgeleitete Klasse.
	virtual SdrObjGeoData* NewGeoData() const;
	virtual void SaveGeoData(SdrObjGeoData& rGeo) const;
	virtual void RestGeoData(const SdrObjGeoData& rGeo);

public:
	TYPEINFO();
	SdrObject();
	virtual ~SdrObject();

	virtual void SetObjList(SdrObjList* pNewObjList);
	SdrObjList* GetObjList() const { return pObjList; }

	virtual void SetPage(SdrPage* pNewPage);
	SdrPage* GetPage() const { return pPage; }

	virtual void SetModel(SdrModel* pNewModel);
	SdrModel* GetModel() const { return pModel; }
	SdrItemPool* GetItemPool() const;

	void AddListener(SfxListener& rListener);
	void RemoveListener(SfxListener& rListener);
	const SfxBroadcaster* GetBroadcaster() const { return pPlusData!=NULL ? pPlusData->pBroadcast : NULL; }

	virtual void AddReference(SdrVirtObj& rVrtObj);
	virtual void DelReference(SdrVirtObj& rVrtObj);
	virtual UINT32 GetObjInventor() const;
	virtual UINT16 GetObjIdentifier() const;
	virtual void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const;
	virtual SdrLayerID GetLayer() const;

	// Layer muss vorher leer sein!
	virtual void   GetLayer(SetOfByte& rSet) const;
	virtual void   NbcSetLayer(SdrLayerID nLayer);
	virtual void   SetLayer(SdrLayerID nLayer);
	void SetUserCall(SdrObjUserCall* pUser) { pUserCall=pUser; }
	SdrObjUserCall* GetUserCall() const { return pUserCall; }
	void SendUserCall(SdrUserCallType eUserCall, const Rectangle& rBoundRect);

	// Ein solcher Referenzpunkt ist z.B. der Punkt eines Symbols, der
	// der beim Einfuegen des Symbols auf das Raster gefangen werden soll
	// oder der Fixpunkt eines Bildes innerhalb eines Animationsobjektes.
	virtual FASTBOOL HasRefPoint() const;
	virtual Point GetRefPoint() const;
	virtual void SetRefPoint(const Point& rPnt);

	// Ein Objekt kann auch einen individuellen (vom Anwender zu vergebenden)
	// Namen tragen (z.B. Symbol oder Gruppenobjekt, OLE2, ... )
	virtual FASTBOOL HasSetName() const;
	virtual void SetName(const String& rStr);
	virtual String GetName() const;

	// support for HTMLName
	void SetHTMLName(const String& rStr);
	String GetHTMLName() const;

	// Fuer Gruppenobjekte
	FASTBOOL IsGroupObject() const { return GetSubList()!=NULL; }
	virtual SdrObjList* GetSubList() const;
	SdrObject* GetUpGroup() const;

	// Ueber die Objekt-Ordnungsnummer kann man feststellen, ob ein Objekt vor
	// oder hinter einem anderen liegt. Objekte mit kleinen Ordnungsnummern werden
	// zuerst gezeichnet, Objekte mit grossen Ordnungsnummern zuletzt.
	// Wird die Reihenfolge der Objekte in der Liste veraendert, so wird ein
	// Dirty-Flag gesetzt (an der Page). Beim naechsten SdrObject::GetOrdNum()
	// werden die Ordnungsnummer aller Objekte der Liste neu bestimmt.
	UINT32 GetOrdNum() const;

	// Diese Methode sollte nur verwendet werden, wenn man ganz  genau weiss,
	// was man macht:
	UINT32 GetOrdNumDirect() const { return nOrdNum; }

	// Das Setzen der Ordnungsnummer sollte nur vom Model bzw. von der Page
	// geschehen.
	void SetOrdNum(UINT32 nNum) { nOrdNum=nNum; }

	const AutoTimer* GetAutoTimer() const { return pPlusData!=NULL ? pPlusData->pAutoTimer : NULL; }
	AutoTimer* GetAutoTimer() { return pPlusData!=NULL ? pPlusData->pAutoTimer : NULL; }
	AutoTimer* ForceAutoTimer();

	// Das BoundRect wird benoetigt fuer:
	//    Redraw: Nur noetig, wenn Obj im sichtbaren Bereich
	//    Redraw: Bei geaenderten ObjAttributen wird dieser Bereich invalidiert
	//    Selektion (HitTest), 1. Stufe
	//    Obj nach vorn/hinten: Nur Objs im gleichen Bereich werden beruecksichtigt.
	virtual const Rectangle& GetBoundRect() const;
	virtual void RecalcBoundRect();
	void SendRepaintBroadcast(BOOL bNoPaintNeeded = FALSE) const;
	void SendRepaintBroadcast(const Rectangle& rRect) const;

	// Modified-Flag am Model setzen
	virtual void SetChanged();

	// Liefert Paint ein FALSE, so wurde das Paint durch einen Event abgebrochen.
	// nBrkEvent bestimmt, wodurch das Paint unterbrochen werden darf.
	// => pApp->AnyInput(nBrkEvent);
	// Der Parameter nPaintMode wurde Writer-speziefisch eingebaut. Beim InitRedraw
	// an der View kann ein USHORT mitgegeben werden, der dann bis hier zum Objekt
	// durchgereicht wird. rDirtyRect beschreibt den Bereich, der am OutputDevice
	// Invalidiert wurde. rDirtyRect kann groesser sein als das Objekt selbst.
	// Wird ein leeres Rectangle uebergeben, so soll stattdessen ein unendlich
	// grosses Rechteck gelten.
	virtual FASTBOOL Paint(ExtOutputDevice& rXOut, const SdrPaintInfoRec& rInfoRec) const;
	virtual FASTBOOL PaintGluePoints(ExtOutputDevice& rXOut, const SdrPaintInfoRec& rInfoRec) const;

	// new line geometry creation and output (used during Paint())
	ImpLineGeometry* ImpPrepareLineGeometry(ExtOutputDevice& rXOut, const SfxItemSet& rSet, BOOL bIsLineDraft = FALSE) const;
	void ImpDrawLineGeometry(ExtOutputDevice& rXOut, Color& rColor,	sal_uInt16 nTransparence, ImpLineGeometry& rLineGeometry) const;
	void ImpDrawShadowLineGeometry(ExtOutputDevice& rXOut, const SfxItemSet& rSet, ImpLineGeometry& rLineGeometry) const;
	void ImpDrawColorLineGeometry(ExtOutputDevice& rXOut, const SfxItemSet& rSet, ImpLineGeometry& rLineGeometry) const;
	virtual void CreateLinePoly(PolyPolygon3D& rPolyPolygon, PolyPolygon3D& rPolyLine, OutputDevice& rOut,
		BOOL bForceHair = FALSE, BOOL bIsLineDraft = FALSE) const;
	BOOL LineGeometryUsageIsNecessary() const;

	// HitTest, 2. Stufe. nTol ist die zulaessige Toleranz in logischen Einheiten.
	// rVisiLayer ist hauptsaechlich fuer Gruppenobjekte gedacht, die ja Objekte
	// mit unterschiedlichen Layerzuordnungen beinhalten koennen.
	virtual SdrObject* CheckHit(const Point& rPnt, USHORT nTol, const SetOfByte* pVisiLayer) const;
	SdrObject* CheckHit(const Point& rPnt, USHORT nTol) const { return CheckHit(rPnt,nTol,NULL); }
	FASTBOOL IsHit(const Point& rPnt, USHORT nTol, const SetOfByte* pVisiLayer) const { return CheckHit(rPnt,nTol,pVisiLayer)!=NULL; }
	FASTBOOL IsHit(const Point& rPnt, USHORT nTol) const { return CheckHit(rPnt,nTol,NULL)!=NULL; }

	// Clone() soll eine komplette Kopie des Objektes erzeugen.
	virtual SdrObject* Clone() const;
	virtual SdrObject* Clone(SdrPage* pPage, SdrModel* pModel) const;
	virtual void operator=(const SdrObject& rObj);

	// TakeObjName...() ist fuer die Anzeige in der UI, z.B. "3 Rahmen selektiert".
	virtual void TakeObjNameSingul(String& rName) const;
	virtual void TakeObjNamePlural(String& rName) const;

	// Das Xor-Polygon wird von der View zu Draggen des Objektes benoetigt.
	// Alle XPolygone innerhalb des XPolyPolygon werden als PolyLine interpretiert.
	// Moechte man ein XPolygon, so muss man es explizit schliessen.
	virtual void TakeXorPoly(XPolyPolygon& rPoly, FASTBOOL bDetail) const;

	// Die Kontur fuer TextToContour
	virtual void TakeContour(XPolyPolygon& rPoly) const;
	virtual void TakeContour(XPolyPolygon& rXPoly, SdrContourType eType) const;

	// Ueber GetHdlCount gibt ein Objekt die Anzahl seiner Handles preis.
	// Im Normalfall werden dies 8 sein, bei einer Strecke 2. Bei Polygonobjekten
	// (Polygon,Spline,Bezier) kann die Handleanzahl wesentlich groesser werden.
	// Polygonobjekten wird ausserdem die Moeglichkeit eingeraeumt einen Punkt
	// eines selektierten Objekts zu selektieren. Das Handle dieses Punktes wird
	// dann durch einen Satz neuer Handles ausgetauscht (PlusHdl). Bei einem
	// Polygon wird das wohl ein einfacher Selektionshandle sein, bei einer
	// Bezierkurve dagegen koennen das schon bis zu 3 Handles werden (inkl Gewichte).
	// GetHdl() und GetPlusHdl() muessen Handleinstanzen mit new erzeugen!
	// Ein Objekt, das bei HasSpacialDrag() TRUE liefert muss diese Methoden
	// zur Verfuegung stellen (inkl. FillHdlList).
	virtual USHORT GetHdlCount() const;
	virtual SdrHdl* GetHdl(USHORT nHdlNum) const;
	virtual USHORT GetPlusHdlCount(const SdrHdl& rHdl) const;
	virtual SdrHdl* GetPlusHdl(const SdrHdl& rHdl, USHORT nPlNum) const;
	virtual void AddToHdlList(SdrHdlList& rHdlList) const;

	// Die Standardtransformationen (Move,Resize,Rotate,Mirror,Shear) werden von der
	// View uebernommen (TakeXorPoly(),...).
	// Objektspeziefisches draggen wie z.B. Eckenradius bei Rechtecken,
	// Stuetzstellen bei Splines, Gewichte bei Bezierkurven und Pointer von
	// Labelobjekten muss vom Objekt selbst gehandled werden. Um das Model
	// Statusfrei zu halten werden die Statusdaten an der View gehalten und dem
	// Objekt dann uebergeben. EndDrag liefrt im Normalfall TRUE fuer Erfolg.
	// FALSE kann zurueckgegeben werden, wenn das Dragging das Objekt nicht
	// veraendert hat, wobei dir evtl. Tatsache das die Maus nicht bewegt wurde
	// bereits von der View abgefangen wird.
	virtual FASTBOOL HasSpecialDrag() const;
	virtual FASTBOOL BegDrag(SdrDragStat& rDrag) const;
	virtual FASTBOOL MovDrag(SdrDragStat& rDrag) const; // True=Xor muss repainted werden
	virtual FASTBOOL EndDrag(SdrDragStat& rDrag);
	virtual void BrkDrag(SdrDragStat& rDrag) const;
	virtual String GetDragComment(const SdrDragStat& rDrag, FASTBOOL bUndoDragComment, FASTBOOL bCreateComment) const;
	virtual void TakeDragPoly(const SdrDragStat& rDrag, XPolyPolygon& rXPP) const;

	// Jedes Objekt muss in der Lage sein sich selbst interaktiv zu erzeugen.
	// Beim MausDown wird zunaechst ein neues Objekt erzeugt und dann seine
	// BegCreate()-Methode gerufen. Bei jedem MausMode wird dann MovCreate
	// gerufen. BrkCreate() bedeutet, dass der User die interaktive Objekt-
	// erzeugung abgebrochen hat. EndCreate() wird gerufen beim MouseUp-Event.
	// Liefert EndCreate() ein TRUE, so ist die Objekterzeugung abgeschlossen;
	// das Objekt wird in die entsprechende Liste eingefuegt. Andernfalls
	// (EndCreate()==FALSE) gehe ich davon aus, dass weitere Punkte zur
	// Objekterzeugung notwendig sind (Polygon,...). Der Parameter eCmd
	// enthaelt die Anzahl der Mausklicks (so die App diese durchreicht).
	// BckCreate() -> Letztes EndCreate() rueckgaengig machen (z.B. letzten
	// Polygonpunkt wieder loeschen).
	// RetrunCode: TRUE=Weiter gehts, FALSE=Create dadurch abgebrochen.
	virtual FASTBOOL BegCreate(SdrDragStat& rStat);
	virtual FASTBOOL MovCreate(SdrDragStat& rStat); // TRUE=Xor muss repainted werden
	virtual FASTBOOL EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd);
	virtual FASTBOOL BckCreate(SdrDragStat& rStat);
	virtual void BrkCreate(SdrDragStat& rStat);

	// damit holt man sich den Pointer, der das Createn dieses Objekts symbolisiert
	virtual Pointer GetCreatePointer() const;

	// Polygon das waehrend des Erzeugens aufgezogen wird
	virtual void TakeCreatePoly(const SdrDragStat& rDrag, XPolyPolygon& rXPP) const;

	// Die Methoden Move, Resize, Rotate, Mirror, Shear, SetSnapRect und
	// SetLogicRect rufen jeweils die entsprechenden Nbc-Methoden, versenden einen
	// Repaint-Broadcast und setzen den Modified-Status am Model. Abgeleitete
	// Objekte sollten i.d.R. nur die Nbc-Methoden ueberladen.
	// Nbc bedeutet: 'NoBroadcast'.
	virtual void NbcMove  (const Size& rSiz);
	virtual void NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact);
	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, FASTBOOL bVShear);

	virtual void Move  (const Size& rSiz);
	virtual void Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact);
	virtual void Rotate(const Point& rRef, long nWink, double sn, double cs);
	virtual void Mirror(const Point& rRef1, const Point& rRef2);
	virtual void Shear (const Point& rRef, long nWink, double tn, FASTBOOL bVShear);

	// Die relative Position eines Zeichenobjektes ist die Entfernung der
	// linken oberen Eche des logisch umschliessenden Rechtecks (SnapRect)
	// zum Anker.
	virtual void NbcSetRelativePos(const Point& rPnt);
	virtual void SetRelativePos(const Point& rPnt);
	virtual Point GetRelativePos() const;
	void ImpSetAnchorPos(const Point& rPnt) { aAnchor=rPnt; }
	virtual void NbcSetAnchorPos(const Point& rPnt);
	virtual void SetAnchorPos(const Point& rPnt);
	virtual const Point& GetAnchorPos() const;

	// Snap wird nicht auf dem BoundRect ausgefuehrt, sondern nach Moeglichkeit auf
	// logischen Koordinaten (also ohne Beruecksichtigung von Strichstaerke, ... ).
	// SetSnapRect() versucht das Objekt so hinzusizen, dass es in das uebergebene
	// Rect passt (ohne Strichstaerke, ...)
	virtual void RecalcSnapRect();
	virtual const Rectangle& GetSnapRect() const;
	virtual void SetSnapRect(const Rectangle& rRect);
	virtual void NbcSetSnapRect(const Rectangle& rRect);

	// Logic Rect: Beim Rect z.B. ohne Beruecksichtigung des Drehwinkels, Shear, ...
	virtual const Rectangle& GetLogicRect() const;
	virtual void SetLogicRect(const Rectangle& rRect);
	virtual void NbcSetLogicRect(const Rectangle& rRect);

	// Drehwinkel und Shear
	virtual long GetRotateAngle() const;
	virtual long GetShearAngle(FASTBOOL bVertical=FALSE) const;

	// Zum Fangen von/auf ausgezeichneten Punkten eines Obj (Polygonpunkte,
	// Kreismittelpunkt, ...)
	virtual USHORT GetSnapPointCount() const;
	virtual Point GetSnapPoint(USHORT i) const;

	// Fuer Objekte, bei denen jeder einzelne Punkt verschoben werden kann,
	// z.B. Polygone, Polylines, Linien, ... . Bei diesen Objekten werden
	// Punkte selektiert (ggf. Mehrfachselektion), geloescht, eingefuegt,
	// als Mehrfachselektion verschoben und gedreht, ...
	// Nur solche Objekte koennen PlusHandles haben (z.B. die Gewichte an den
	// Bezierkurven.
	virtual FASTBOOL IsPolyObj() const;
	virtual USHORT GetPointCount() const;
	virtual const Point& GetPoint(USHORT i) const;
	virtual void SetPoint(const Point& rPnt, USHORT i);
	virtual void NbcSetPoint(const Point& rPnt, USHORT i);

	// Einfuegen eines neuen Polygonpunktes. Ret muss die Nummer des passenden
	// Hdl sein. 0xFFFF= einfuegen nicht moeglich.
	// Is bHideHim=TRUE, dann ist interaktives Ins angesagt. Der Punkt ist dann
	// geographisch so zu platzieren, dass er nicht auffaellt (z.B. identische
	// Pos wie ein Nachbarpunkt).
	// bNewObj=TRUE => Ein PolyPolygonObj soll nach Moeglichkeit ein neues
	// Polygon beginnen.
	// Ueber rInsNextAfter kann ein Flag zurueckgegeben werden, ob weitere
	// Punkte vor oder hinter dem gerade Eingefuegten eingefuegt werden sollten
	// (z.B. fuer Polylines Punkte anhaengen am Anfang/Ende).
	// => Beim einfuegen neuer Punkte ueber die View wird zunaechst die Methode
	// ohne Indexparameter gerufen. Diese stellt dann fest wo der Neue hinkommt
	// und ob Folgepunkte, vor oder hinter diesem eingefuegt werden sollen.
	// Ist das einfuegen diese Punktes an der View abgeschlossen wird dort
	// automatisch das einfuegen eines weiteren Punktes gestartet. Am Obj wird
	// dafuer die InsPoint-Methode mit Indexparameter gerufen (der Index
	// entspricht genau der Handlenummer, die im letzten Aufruf zurueckgegeben
	// wurde). Der Parameter bInsAfter enthaelt genau den Wert, den der 1.
	// Aufruf (InsPoint ohne Indexparameter) zurueckgab.
	virtual USHORT InsPoint(const Point& rPos, FASTBOOL bNewObj, FASTBOOL& rInsNextAfter);
	virtual USHORT NbcInsPoint(const Point& rPos, FASTBOOL bNewObj, FASTBOOL bHideHim, FASTBOOL& rInsNextAfter);

	// Neuen Punkt an (bInsAfter?nach:vor) einem bestimmten Index einfuegen.
	virtual USHORT InsPoint(USHORT i, const Point& rPos, FASTBOOL bInsAfter, FASTBOOL bNewObj);
	virtual USHORT NbcInsPoint(USHORT i, const Point& rPos, FASTBOOL bInsAfter, FASTBOOL bNewObj, FASTBOOL bHideHim);

	// Loeschen eines Punktes. Ret=FALSE -> Obj besser loeschen
	virtual FASTBOOL DelPoint(USHORT i);
	virtual FASTBOOL NbcDelPoint(USHORT i);

	// Wenn Objektspaltung, dann Ret=NeuesObj, sonst Ret=NULL.
	// Bei Objektspaltung das Ursprungsobjekt die Punkte mit den niedrigen
	// Handlenummern behalten und den oberen Teil an das neue Objekt uebergeben.
	// Wenn sich beim Rip die Handlezuordnungen aendern muss das Objekt dies
	// ueber den Rueckgabeparameter rNewPt0Index bekanntgeben. Das passiert z.B.
	// wenn ein Polygon aufgetrennt wird und dadurch eine Polyline entsteht.
	// Das Zeichenobjekt muss in den Parameter rNewPt0Index (default=0) dann
	// die Handlenummer (=Index) schreiben, unter der der Punkt, der vorher mit
	// Index 0 ansprechbar war, nun erreichbar ist.
	// Das ist zwingend notwendig, wenn an der View Auftrennen bei
	// Mehrfachpunktselektion vollzogen wird.
	virtual SdrObject* RipPoint(USHORT i, USHORT& rNewPt0Index);
	virtual SdrObject* NbcRipPoint(USHORT i, USHORT& rNewPt0Index);

	// Objekt schliessen (z.B. Polyline->Polygon)
	virtual void Shut();
	virtual void NbcShut();

	// Alle geometrischen Daten holen fuer's Undo/Redo
	virtual SdrObjGeoData* GetGeoData() const;
	virtual void SetGeoData(const SdrObjGeoData& rGeo);

	// ItemSet access
	virtual const SfxItemSet& GetItemSet() const;
	virtual SfxItemSet* CreateNewItemSet(SfxItemPool& rPool);
	virtual void SetItem(const SfxPoolItem& rItem);
	virtual void ClearItem(const sal_uInt16 nWhich = 0);
	virtual void SetItemSet(const SfxItemSet& rSet);
	virtual void BroadcastItemChange(const SdrBroadcastItemChange& rChange);
	virtual void ItemSetChanged(const SfxItemSet& rSet);

	// syntactical sugar for ItemSet accesses
	void SetItemAndBroadcast(const SfxPoolItem& rItem);
	void ClearItemAndBroadcast(const sal_uInt16 nWhich = 0);
	void SetItemSetAndBroadcast(const SfxItemSet& rSet);
	const SfxPoolItem& GetItem(const sal_uInt16 nWhich) const;

	// private support routines for ItemSet access. NULL pointer means clear item.
	virtual BOOL AllowItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem = 0) const;
	virtual void ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem = 0);
	virtual void PostItemChange(const sal_uInt16 nWhich);

	// pre- and postprocessing for objects for saving
	virtual void PreSave();
	virtual void PostSave();

	// NotPersistAttr fuer Layer, ObjName, geometrische Transformationen, ...
	void TakeNotPersistAttr(SfxItemSet& rAttr, FASTBOOL bMerge) const;
	void ApplyNotPersistAttr(const SfxItemSet& rAttr);
	void NbcApplyNotPersistAttr(const SfxItemSet& rAttr);

	// bDontRemoveHardAttr=FALSE: alle in der Vorlage gesetzten Attribute werden am
	// Zeichenobjekt auf Default gesetzt; TRUE: alle harten Attribute bleiben erhalten.
	virtual void SetStyleSheet(SfxStyleSheet* pNewStyleSheet, FASTBOOL bDontRemoveHardAttr);
	virtual void NbcSetStyleSheet(SfxStyleSheet* pNewStyleSheet, FASTBOOL bDontRemoveHardAttr);
	virtual SfxStyleSheet* GetStyleSheet() const;

	// TextEdit
	virtual FASTBOOL HasTextEdit() const;
	virtual SdrObject* CheckTextEditHit(const Point& rPnt, USHORT nTol, const SetOfByte* pVisiLayer) const;
	SdrObject* CheckTextEditHit(const Point& rPnt, USHORT nTol) const { return CheckTextEditHit(rPnt,nTol,NULL); }
	FASTBOOL IsTextEditHit(const Point& rPnt, USHORT nTol, const SetOfByte* pVisiLayer) const { return CheckTextEditHit(rPnt,nTol,pVisiLayer)!=NULL; }
	FASTBOOL IsTextEditHit(const Point& rPnt, USHORT nTol) const { return CheckTextEditHit(rPnt,nTol,NULL)!=NULL; }

	// Return==TRUE: TextEditMode gestartet
	virtual FASTBOOL BegTextEdit(SdrOutliner& rOutl);
	virtual void EndTextEdit(SdrOutliner& rOutl);

	// Text wird im Format des Outliners gehalten
	// SetOutlinerParaObject: Eigentumsuebereignung von *pTextObject!
	virtual void SetOutlinerParaObject(OutlinerParaObject* pTextObject);
	virtual void NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject);
	virtual OutlinerParaObject* GetOutlinerParaObject() const;
	virtual void NbcReformatText();
	virtual void ReformatText();
	virtual void BurnInStyleSheetAttributes( BOOL bPseudoSheetsOnly=FALSE );

	// Animations-Iterationscounter Resetten. Neustart der Animation
	// beim naechsten Paint. pPageView=NULL: Alle PageViews.
	virtual void RestartAnimation(SdrPageView* pPageView) const;

	// Macrofaehigkeit, z.B. ein Rechteck als PushButton.
	virtual FASTBOOL HasMacro() const;
	virtual SdrObject* CheckMacroHit (const SdrObjMacroHitRec& rRec) const;
	virtual Pointer GetMacroPointer (const SdrObjMacroHitRec& rRec) const;
	virtual void PaintMacro (ExtOutputDevice& rXOut, const Rectangle& rDirtyRect, const SdrObjMacroHitRec& rRec) const;
	virtual FASTBOOL DoMacro (const SdrObjMacroHitRec& rRec);
	virtual XubString GetMacroPopupComment(const SdrObjMacroHitRec& rRec) const;
	FASTBOOL IsMacroHit(const SdrObjMacroHitRec& rRec) const { return CheckMacroHit(rRec)!=NULL; }

	// Konnektoren. (siehe auch Dokumentation in SvdoEdge.HXX, SdrEdgeObj
	//               sowie SvdGlue.HXX und SvdGlEV.HXX)
	// Es gibt Knoten und Kanten. Eine Kante kann theoretisch auch Knoten
	// sein, das ist jedoch in dieser Version noch nicht implementiert.
	// Ein Knoten hat eine Anzahl von Klebepunkten, wo Kanten angeklebt
	// werden koennen.
	// Eine Kante kann
	// - ohne Verbindungen sein
	// - an einem Ende auf der Wiese stehen und am anderen Ende an
	//   genau einem Knoten gebunden sein
	// - an beiden Enden mit jeweils genau einem Knoten verbunden sein.
	// Die Kante ist Listener bei seinen bis zu 2 Knoten.
	// Wird der Knoten verschoben oder Resized, folgen alle angebundenen
	// Kanten. Ebenso bei SetGluePoint()... am Knoten.
	// Beim Verschieben/Resizen der Kante wird dagegen die Verbindung
	// geloesst.
	// Objekt ist ein Knoten?
	virtual FASTBOOL IsNode() const;

	// Automatische Klebepunkte:
	// je 4 Scheitelpunkt- und Eckpositionen muss ein Knotenobjekt liefern
	// i.d.R. 0=oben, 1=rechts, 2=unten, 3=links
	virtual SdrGluePoint GetVertexGluePoint(USHORT nNum) const;

	// i.d.R. 0=linksoben, 1=rechtsoben, 2=rechtsunten, 3=linksunten
	virtual SdrGluePoint GetCornerGluePoint(USHORT nNum) const;

	// Liste aller Klebepunkte. Kann NULL sein.
	virtual const SdrGluePointList* GetGluePointList() const;
	virtual SdrGluePointList* GetGluePointList();

	// Nach veraendern der GluePointList muss man am Obj SendRepaintBroadcast rufen!
	virtual SdrGluePointList* ForceGluePointList();

	// Temporaer zu setzen fuer Transformationen am Bezugsobjekt
	void SetGlueReallyAbsolute(FASTBOOL bOn);
	void NbcRotateGluePoints(const Point& rRef, long nWink, double sn, double cs);
	void NbcMirrorGluePoints(const Point& rRef1, const Point& rRef2);
	void NbcShearGluePoints (const Point& rRef, long nWink, double tn, FASTBOOL bVShear);

	// Objekt ist eine Kante?
	virtual FASTBOOL IsEdge() const;

	// Xor-Darstellung der Kante beim Draggen einer der beiden Knoten
	virtual void ToggleEdgeXor(const SdrDragStat& rDrag, ExtOutputDevice& rXOut, FASTBOOL bTail1, FASTBOOL bTail2, FASTBOOL bDetail) const;
	virtual void NspToggleEdgeXor(const SdrDragStat& rDrag, ExtOutputDevice& rXOut, FASTBOOL bTail1, FASTBOOL bTail2, FASTBOOL bDetail) const;

	// bTail1=TRUE: Linienanfang, sonst LinienEnde
	// pObj=NULL: Disconnect
	virtual void ConnectToNode(FASTBOOL bTail1, SdrObject* pObj);
	virtual void DisconnectFromNode(FASTBOOL bTail1);
	virtual SdrObject* GetConnectedNode(FASTBOOL bTail1) const;

	// Wenn ein Objekt in der Lage ist, sich in ein Polygon oder in eine
	// Bezierkurve (oder beides) zu verwandeln, dann sollten die folgenden
	// Methoden ueberladen werden.
	// Z.B. Ein RectObj mit Strichstaerke 10, SOLID_PEN in Polygon wandeln:
	// Im Modus bLineToArea=FALSE soll ein PolyObj mit 4 Stuetzstellen,
	// Strichstaerke 10 und SOLiD_PEN erzeugt werden.
	// Im Modus bLineToArea=TRUE dagegen soll das generierte Obj immer ein
	// LinienAttribut NULL_PEN haben, und die Linie (auch Linienmuster) selbst
	// durch Polygonflaechen emuliert werden, die dadurch anschliessend vom
	// Anwender manipuliert werden koennen. Das RectObj kann sich somit also
	// nur korrekt konvertieren, wenn es als Flaechenattribut NULL_BRUSH
	// besitzt. Es muesste in diesem Fall dann:
	// - SOLID_BRUSH mit der Farbe des gesetzten Pen setzen
	// - NULL_PEN setzen
	// - PolyPolygon mit 2 Polygonen zu je 4 Stuetzstellen generieren.
	// Der Returnwert ist jeweils ein SdrObject*, da als Rueckgabe zur Not
	// auch Gruppenobjekte erlaubt sind (z.B. fuer SdrTextObj).
	// Bei der Konvertierung von TextObj nach PathObj wird es wohl so sein,
	// dass beide Modi (bLineToArea=TRUE/FALSE) identisch sind.
	// Defaulted sind diese Methoden auf "Ich kann das nicht" (FALSE/NULL).
	virtual SdrObject* DoConvertToPolyObj(BOOL bBezier) const;
	SdrObject* ConvertToPolyObj(BOOL bBezier, BOOL bLineToArea) const;

	// convert this path object to contour object; bForceLineDash converts even
	// when there is no filled new polygon created from line-to-polygon conversion,
	// specially used for XLINE_DASH and 3D conversion
	SdrObject* ConvertToContourObj(SdrObject* pRet, BOOL bForceLineDash = FALSE) const;
	SdrObject* ImpConvertToContourObj(SdrObject* pRet, BOOL bForceLineDash = FALSE) const;

	// Schreiben in einen Stream: Der Operator << schreibt zunaest den 28 Bytes
	//   langen SdrObjIOHeader in den Stream und ruft anschliessend die vMethode
	//   WriteData() auf. Zum Schluss wird noch das vorerst auf 0 initiallisierte
	//   Feld nByteAnz des SdrObjIOHeader gefuellt. Die geerbte Methode WriteData
	//   ist in ueberlagerten Methoden stets am Anfang zu rufen.
	virtual void WriteData(SvStream& rOut) const;

	// Lesen aus einem Stream: Zunaest wird der SdrIOHeader von einem Reader am
	//   SdrModel gelesen (Read und SeekBack). Der Reader versucht dann eine
	//   Instanz der entsprechenden Klasse entweder selbst zu erzeugen oder bei
	//   durch Aufruf eines Links erzeugen zu lassen. Anschliessend wird vom
	//   Reader der Operator >> aufgerufen der wiederum die vMethode ReadData()
	//   ruft. Der Parameter aHead in ReadData() erlaubt eine Versionskontrolle
	//   der zu lesenden Daten.
	virtual void ReadData(const SdrObjIOHeader& rHead, SvStream& rIn);

	// AfterRead wird gerufen, nachdem das gesamte Model eingestreamt
	// worden ist. Damit ist ein PostProcessing moeglich um beispielsweise
	// Objektverknuepfungen ueber Surrogate herzustellen o.ae.
	// Anwendungsbeispiel hierfuer SdrEdgeObj (Objektverbinder)
	virtual void AfterRead();

	friend SvStream& operator<<(SvStream& rOut, const SdrObject& rObj);
	friend SvStream& operator>>(SvStream& rIn, SdrObject& rObj);

	// TRUE: Referenz auf ein Obj
	FASTBOOL IsVirtualObj() const { return bVirtObj; }

	// TRUE=Obj kann warsch. gefuellt werden; FALSE=Obj kann warsch. Linienenden haben.
	// ungueltig, wenn es sich um ein GroupObj handelt.
	FASTBOOL IsClosedObj() const { return bClosedObj; }
	FASTBOOL IsWriterFlyFrame() const { return bWriterFlyFrame; }
	FASTBOOL IsEdgeObj() const { return bIsEdge; }
	FASTBOOL Is3DObj() const { return bIs3DObj; }
	FASTBOOL IsUnoObj() const { return bIsUnoObj; }
	FASTBOOL IsMasterCachable() const { return !bNotMasterCachable; }
	FASTBOOL ShareLock() { FASTBOOL r=!bNetLock; bNetLock=TRUE; return r; }
	void ShareUnlock() { bNetLock=FALSE; }
	FASTBOOL IsShareLock() const { return bNetLock; }
	void SetMarkProtect(FASTBOOL bProt) { bMarkProt=bProt; }
	FASTBOOL IsMarkProtect() const { return bMarkProt; }
	void SetInserted(FASTBOOL bIns);
	FASTBOOL IsInserted() const { return bInserted; }
	void SetGrouped(FASTBOOL bGrp) { bGrouped=bGrp; }
	FASTBOOL IsGrouped() const { return bGrouped; }
	void SetMoveProtect(FASTBOOL bProt);
	FASTBOOL IsMoveProtect() const { return bMovProt; }
	void SetResizeProtect(FASTBOOL bProt);
	FASTBOOL IsResizeProtect() const { return bSizProt; }
	void SetPrintable(FASTBOOL bPrn);
	FASTBOOL IsPrintable() const { return !bNoPrint; }
	void SetEmptyPresObj(FASTBOOL bEpt) { bEmptyPresObj=bEpt; }
	FASTBOOL IsEmptyPresObj() const { return bEmptyPresObj; }
	FASTBOOL IsNotPersistent() const { return bNotPersistent; }
	FASTBOOL IsNeedColorRestore() const { return bNeedColorRestore; }
	void SetNotVisibleAsMaster(FASTBOOL bFlg) { bNotVisibleAsMaster=bFlg; }
	FASTBOOL IsNotVisibleAsMaster() const { return bNotVisibleAsMaster; }

	// applikationsspeziefische Daten
	USHORT GetUserDataCount() const;
	SdrObjUserData* GetUserData(USHORT nNum) const;

	// Insert uebernimmt den auf dem Heap angelegten Record in den Besitz
	// des Zeichenobjekts
	void InsertUserData(SdrObjUserData* pData, USHORT nPos=0xFFFF);

	// Delete entfernt den Record aus der Liste und ruft
	// ein delete (FreeMem+Dtor).
	void DeleteUserData(USHORT nNum);

	// ItemPool fuer dieses Objekt wechseln
	virtual void MigrateItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel = NULL );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// access to the UNO representation of the shape
	::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getUnoShape();
	::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface > getWeakUnoShape() { return mxUnoShape; }

	// helper struct for granting access exclusive to SvxShape
	struct GrantXShapeAccess
	{
		friend class SvxShape;
	private:
		GrantXShapeAccess() { }
	};

	// setting the UNO representation is allowed for the UNO representation itself only!
	void setUnoShape(
		const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxUnoShape,
		GrantXShapeAccess aGrant
	)
	{
		mxUnoShape = _rxUnoShape;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	//
	// transformation interface for StarOfficeAPI. This implements support for
	// homogen 3x3 matrices containing the transformation of the SdrObject. At the
	// moment it contains a shearX, rotation and translation, but for setting all linear
	// transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
	//
	// gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
	// with the base geometry and returns TRUE. Otherwise it returns FALSE.
	virtual BOOL TRGetBaseGeometry(Matrix3D& rMat, XPolyPolygon& rPolyPolygon) const;
	// sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
	// If it's an SdrPathObj it will use the provided geometry information. The Polygon has
	// to use (0,0) as upper left and will be scaled to the given size in the matrix.
	virtual void TRSetBaseGeometry(const Matrix3D& rMat, const XPolyPolygon& rPolyPolygon);

	FASTBOOL IsTransparent( BOOL bCheckForAlphaChannel = FALSE ) const;
};

//************************************************************
//   SdrDummyObj
//
// Wer sich eigene Objekte schafft muss einen Link in der Klasse
// SdrObjFactory setzen. Der Handler hat folgendes aussehen:
//    void Hdl(SdrObjFactory*)
// Er muss sich aus der uebergebenen Instanz die Werte nInventor und
// nIdentifier ansehen und entsprechend mit new eine Zeichenobjektinstanz
// erzeugen. Einen Zeiger auf diese Instanz hat er in der Membervariablen
// pNewObj zu hinterlassen.
//
//************************************************************

class SdrObjFactory
{
public:
	UINT32						nInventor;
	UINT16						nIdentifier;

	// fuer MakeNewObj():
	SdrPage*					pPage;
	SdrModel*					pModel;
	SdrObject*					pNewObj;

	// fuer MakeNewObjUserData():
	SdrObject*					pObj;
	SdrObjUserData*				pNewData;

private:
	SdrObjFactory(UINT32 nInvent, UINT16 nIdent, SdrPage* pNewPage, SdrModel* pNewModel) { nInventor=nInvent; nIdentifier=nIdent; pNewObj=NULL; pPage=pNewPage; pModel=pNewModel; pObj=NULL; pNewData=NULL; }
	SdrObjFactory(UINT32 nInvent, UINT16 nIdent, SdrObject* pObj1) { nInventor=nInvent; nIdentifier=nIdent; pNewObj=NULL; pPage=NULL; pModel=NULL; pObj=pObj1; pNewData=NULL; }

public:
	static SdrObject* MakeNewObject(UINT32 nInvent, UINT16 nIdent, SdrPage* pPage, SdrModel* pModel=NULL);
	static void InsertMakeObjectHdl(const Link& rLink);
	static void RemoveMakeObjectHdl(const Link& rLink);
	static SdrObjUserData* MakeNewObjUserData(UINT32 nInvent, UINT16 nIdent, SdrObject* pObj);
	static void InsertMakeUserDataHdl(const Link& rLink);
	static void RemoveMakeUserDataHdl(const Link& rLink);
};

#endif //_SVDOBJ_HXX

