summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--svx/source/svdraw/svdopath.cxx989
1 files changed, 563 insertions, 426 deletions
diff --git a/svx/source/svdraw/svdopath.cxx b/svx/source/svdraw/svdopath.cxx
index 43ffc42c0961..106f75878266 100644
--- a/svx/source/svdraw/svdopath.cxx
+++ b/svx/source/svdraw/svdopath.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: svdopath.cxx,v $
*
- * $Revision: 1.10 $
+ * $Revision: 1.11 $
*
- * last change: $Author: aw $ $Date: 2001-04-24 11:31:29 $
+ * last change: $Author: aw $ $Date: 2001-08-13 10:17:00 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -713,63 +713,97 @@ public:
USHORT nNextNextPnt0;
FASTBOOL bEliminate; // Punkt loeschen? (wird von MovDrag gesetzt)
+ // ##
+ BOOL mbMultiPointDrag;
+ const XPolyPolygon& mrOrig;
+ XPolyPolygon maMove;
+ Container maHandles;
+
public:
- ImpSdrPathDragData(const SdrPathObj& rPO, const SdrHdl& rHdl);
+ ImpSdrPathDragData(const SdrPathObj& rPO, const SdrHdl& rHdl, BOOL bMuPoDr, const SdrDragStat& rDrag);
void ResetPoly(const SdrPathObj& rPO);
+ BOOL IsMultiPointDrag() const { return mbMultiPointDrag; }
};
-ImpSdrPathDragData::ImpSdrPathDragData(const SdrPathObj& rPO, const SdrHdl& rHdl):
- aXP(5)
+ImpSdrPathDragData::ImpSdrPathDragData(const SdrPathObj& rPO, const SdrHdl& rHdl, BOOL bMuPoDr, const SdrDragStat& rDrag)
+: aXP(5),
+ mbMultiPointDrag(bMuPoDr),
+ mrOrig(rPO.GetPathPoly()),
+ maHandles(0)
{
- bValid=FALSE;
- bClosed=rPO.IsClosed(); // geschlossenes Objekt?
- nPoly=rHdl.GetPolyNum(); // Nummer des Polygons im PolyPolygon
- nPnt=rHdl.GetPointNum(); // Punktnummer innerhalb des obigen Polygons
- const XPolygon& rXP=rPO.aPathPolygon[nPoly]; // Referenz auf das Polygon
- nPntAnz=rXP.GetPointCount(); // Punktanzahl des Polygons
- if (nPntAnz==0 || (bClosed && nPntAnz==1)) return; // min. 1Pt bei Line, min. 2 bei Polygon
- nPntMax=nPntAnz-1; // Maximaler Index
- bBegPnt=!bClosed && nPnt==0; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
- bEndPnt=!bClosed && nPnt==nPntMax; // Gedraggter Punkt ist der Endpunkt einer Polyline
- if (bClosed && nPntAnz<=3) { // Falls Polygon auch nur eine Linie ist
- bBegPnt=(nPntAnz<3) || nPnt==0;
- bEndPnt=(nPntAnz<3) || nPnt==nPntMax-1;
- }
- nPrevPnt=nPnt; // Index des vorherigen Punkts
- nNextPnt=nPnt; // Index des naechsten Punkts
- if (!bBegPnt) nPrevPnt=GetPrevPnt(nPnt,nPntMax,bClosed);
- if (!bEndPnt) nNextPnt=GetNextPnt(nPnt,nPntMax,bClosed);
- bPrevIsBegPnt=bBegPnt || (!bClosed && nPrevPnt==0);
- bNextIsEndPnt=bEndPnt || (!bClosed && nNextPnt==nPntMax);
- nPrevPrevPnt=nPnt; // Index des vorvorherigen Punkts
- nNextNextPnt=nPnt; // Index des uebernaechsten Punkts
- if (!bPrevIsBegPnt) nPrevPrevPnt=GetPrevPnt(nPrevPnt,nPntMax,bClosed);
- if (!bNextIsEndPnt) nNextNextPnt=GetNextPnt(nNextPnt,nPntMax,bClosed);
- bControl=rHdl.IsPlusHdl(); // Punkt ist ein Kontrollpunkt
- bIsPrevControl=FALSE; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
- bIsNextControl=FALSE; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
- bPrevIsControl=FALSE; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
- bNextIsControl=FALSE; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
- if (bControl) {
- bIsPrevControl=rXP.IsControl(nPrevPnt);
- bIsNextControl=!bIsPrevControl;
- } else {
- bPrevIsControl=!bBegPnt && !bPrevIsBegPnt && rXP.GetFlags(nPrevPnt)==XPOLY_CONTROL;
- bNextIsControl=!bEndPnt && !bNextIsEndPnt && rXP.GetFlags(nNextPnt)==XPOLY_CONTROL;
- }
- nPrevPrevPnt0=nPrevPrevPnt;
- nPrevPnt0 =nPrevPnt;
- nPnt0 =nPnt;
- nNextPnt0 =nNextPnt;
- nNextNextPnt0=nNextNextPnt;
- nPrevPrevPnt=0;
- nPrevPnt=1;
- nPnt=2;
- nNextPnt=3;
- nNextNextPnt=4;
- bEliminate=FALSE;
- ResetPoly(rPO);
- bValid=TRUE;
+ if(mbMultiPointDrag)
+ {
+ const SdrMarkView& rMarkView = *rDrag.GetView();
+ const SdrHdlList& rHdlList = rMarkView.GetHdlList();
+ const sal_uInt32 nHdlCount = rHdlList.GetHdlCount();
+
+ for(sal_uInt32 a(0); a < nHdlCount; a++)
+ {
+ SdrHdl* pTestHdl = rHdlList.GetHdl(a);
+
+ if(pTestHdl
+ && pTestHdl->IsSelected()
+ && pTestHdl->GetObj() == (SdrObject*)&rPO)
+ {
+ maHandles.Insert(pTestHdl, CONTAINER_APPEND);
+ }
+ }
+
+ maMove = mrOrig;
+ bValid = TRUE;
+ }
+ else
+ {
+ bValid=FALSE;
+ bClosed=rPO.IsClosed(); // geschlossenes Objekt?
+ nPoly=rHdl.GetPolyNum(); // Nummer des Polygons im PolyPolygon
+ nPnt=rHdl.GetPointNum(); // Punktnummer innerhalb des obigen Polygons
+ const XPolygon& rXP=rPO.aPathPolygon[nPoly]; // Referenz auf das Polygon
+ nPntAnz=rXP.GetPointCount(); // Punktanzahl des Polygons
+ if (nPntAnz==0 || (bClosed && nPntAnz==1)) return; // min. 1Pt bei Line, min. 2 bei Polygon
+ nPntMax=nPntAnz-1; // Maximaler Index
+ bBegPnt=!bClosed && nPnt==0; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
+ bEndPnt=!bClosed && nPnt==nPntMax; // Gedraggter Punkt ist der Endpunkt einer Polyline
+ if (bClosed && nPntAnz<=3) { // Falls Polygon auch nur eine Linie ist
+ bBegPnt=(nPntAnz<3) || nPnt==0;
+ bEndPnt=(nPntAnz<3) || nPnt==nPntMax-1;
+ }
+ nPrevPnt=nPnt; // Index des vorherigen Punkts
+ nNextPnt=nPnt; // Index des naechsten Punkts
+ if (!bBegPnt) nPrevPnt=GetPrevPnt(nPnt,nPntMax,bClosed);
+ if (!bEndPnt) nNextPnt=GetNextPnt(nPnt,nPntMax,bClosed);
+ bPrevIsBegPnt=bBegPnt || (!bClosed && nPrevPnt==0);
+ bNextIsEndPnt=bEndPnt || (!bClosed && nNextPnt==nPntMax);
+ nPrevPrevPnt=nPnt; // Index des vorvorherigen Punkts
+ nNextNextPnt=nPnt; // Index des uebernaechsten Punkts
+ if (!bPrevIsBegPnt) nPrevPrevPnt=GetPrevPnt(nPrevPnt,nPntMax,bClosed);
+ if (!bNextIsEndPnt) nNextNextPnt=GetNextPnt(nNextPnt,nPntMax,bClosed);
+ bControl=rHdl.IsPlusHdl(); // Punkt ist ein Kontrollpunkt
+ bIsPrevControl=FALSE; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
+ bIsNextControl=FALSE; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
+ bPrevIsControl=FALSE; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
+ bNextIsControl=FALSE; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
+ if (bControl) {
+ bIsPrevControl=rXP.IsControl(nPrevPnt);
+ bIsNextControl=!bIsPrevControl;
+ } else {
+ bPrevIsControl=!bBegPnt && !bPrevIsBegPnt && rXP.GetFlags(nPrevPnt)==XPOLY_CONTROL;
+ bNextIsControl=!bEndPnt && !bNextIsEndPnt && rXP.GetFlags(nNextPnt)==XPOLY_CONTROL;
+ }
+ nPrevPrevPnt0=nPrevPrevPnt;
+ nPrevPnt0 =nPrevPnt;
+ nPnt0 =nPnt;
+ nNextPnt0 =nNextPnt;
+ nNextNextPnt0=nNextNextPnt;
+ nPrevPrevPnt=0;
+ nPrevPnt=1;
+ nPnt=2;
+ nNextPnt=3;
+ nNextNextPnt=4;
+ bEliminate=FALSE;
+ ResetPoly(rPO);
+ bValid=TRUE;
+ }
}
void ImpSdrPathDragData::ResetPoly(const SdrPathObj& rPO)
@@ -1056,13 +1090,44 @@ XPolygon ImpPathCreateUser::GetRectPoly() const
FASTBOOL SdrPathObj::BegDrag(SdrDragStat& rDrag) const
{
const SdrHdl* pHdl=rDrag.GetHdl();
- if (pHdl==NULL) return FALSE;
- ImpSdrPathDragData* pID=new ImpSdrPathDragData(*this,*pHdl);
+ if(!pHdl)
+ return FALSE;
+
+ BOOL bMultiPointDrag(TRUE);
+
+ if(aPathPolygon[pHdl->GetPolyNum()].IsControl(pHdl->GetPointNum()))
+ bMultiPointDrag = FALSE;
+
+ if(bMultiPointDrag)
+ {
+ const SdrMarkView& rMarkView = *rDrag.GetView();
+ const SdrHdlList& rHdlList = rMarkView.GetHdlList();
+ const sal_uInt32 nHdlCount = rHdlList.GetHdlCount();
+ sal_uInt32 nSelectedPoints(0);
+
+ for(sal_uInt32 a(0); a < nHdlCount; a++)
+ {
+ SdrHdl* pTestHdl = rHdlList.GetHdl(a);
+
+ if(pTestHdl
+ && pTestHdl->IsSelected()
+ && pTestHdl->GetObj() == (SdrObject*)this)
+ {
+ nSelectedPoints++;
+ }
+ }
+
+ if(nSelectedPoints <= 1)
+ bMultiPointDrag = FALSE;
+ }
+
+ ImpSdrPathDragData* pID=new ImpSdrPathDragData(*this,*pHdl,bMultiPointDrag,rDrag);
if (!pID->bValid) {
DBG_ERROR("SdrPathObj::BegDrag(): ImpSdrPathDragData ist ungueltig");
delete pID;
return FALSE;
}
+
rDrag.SetUser(pID);
return TRUE;
}
@@ -1074,178 +1139,228 @@ FASTBOOL SdrPathObj::MovDrag(SdrDragStat& rDrag) const
DBG_ERROR("SdrPathObj::MovDrag(): ImpSdrPathDragData ist ungueltig");
return FALSE;
}
- pID->ResetPoly(*this);
-
- // Div. Daten lokal Kopieren fuer weniger Code und schnelleren Zugriff
- FASTBOOL bClosed =pID->bClosed ; // geschlossenes Objekt?
- USHORT nPnt =pID->nPnt ; // Punktnummer innerhalb des obigen Polygons
- FASTBOOL bBegPnt =pID->bBegPnt ; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
- FASTBOOL bEndPnt =pID->bEndPnt ; // Gedraggter Punkt ist der Endpunkt einer Polyline
- USHORT nPrevPnt =pID->nPrevPnt ; // Index des vorherigen Punkts
- USHORT nNextPnt =pID->nNextPnt ; // Index des naechsten Punkts
- FASTBOOL bPrevIsBegPnt =pID->bPrevIsBegPnt ; // Vorheriger Punkt ist Anfangspunkt einer Polyline
- FASTBOOL bNextIsEndPnt =pID->bNextIsEndPnt ; // Folgepunkt ist Endpunkt einer Polyline
- USHORT nPrevPrevPnt =pID->nPrevPrevPnt ; // Index des vorvorherigen Punkts
- USHORT nNextNextPnt =pID->nNextNextPnt ; // Index des uebernaechsten Punkts
- FASTBOOL bControl =pID->bControl ; // Punkt ist ein Kontrollpunkt
- FASTBOOL bIsPrevControl=pID->bIsPrevControl; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
- FASTBOOL bIsNextControl=pID->bIsNextControl; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
- FASTBOOL bPrevIsControl=pID->bPrevIsControl; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
- FASTBOOL bNextIsControl=pID->bNextIsControl; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
-
- // Ortho bei Linien/Polygonen = Winkel beibehalten
- if (!bControl && rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho()) {
- FASTBOOL bBigOrtho=rDrag.GetView()->IsBigOrtho();
- Point aPos(rDrag.GetNow()); // die aktuelle Position
- Point aPnt(pID->aXP[nPnt]); // der gedraggte Punkt
- USHORT nPnt1=0xFFFF,nPnt2=0xFFFF; // seine Nachbarpunkte
- Point aNeuPos1,aNeuPos2; // die neuen Alternativen fuer aPos
- FASTBOOL bPnt1=FALSE,bPnt2=FALSE; // die neuen Alternativen gueltig?
- if (!bClosed && pID->nPntAnz>=2) { // Mind. 2 Pt bei Linien
- if (!bBegPnt) nPnt1=nPrevPnt;
- if (!bEndPnt) nPnt2=nNextPnt;
- }
- if (bClosed && pID->nPntAnz>=3) { // Mind. 3 Pt bei Polygon
- nPnt1=nPrevPnt;
- nPnt2=nNextPnt;
- }
- if (nPnt1!=0xFFFF && !bPrevIsControl) {
- Point aPnt1=pID->aXP[nPnt1];
- long ndx0=aPnt.X()-aPnt1.X();
- long ndy0=aPnt.Y()-aPnt1.Y();
- FASTBOOL bHLin=ndy0==0;
- FASTBOOL bVLin=ndx0==0;
- if (!bHLin || !bVLin) {
- long ndx=aPos.X()-aPnt1.X();
- long ndy=aPos.Y()-aPnt1.Y();
- bPnt1=TRUE;
- double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
- double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
- FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
- FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
- if (bHor) ndy=long(ndy0*nXFact);
- if (bVer) ndx=long(ndx0*nYFact);
- aNeuPos1=aPnt1;
- aNeuPos1.X()+=ndx;
- aNeuPos1.Y()+=ndy;
- }
- }
- if (nPnt2!=0xFFFF && !bNextIsControl) {
- Point aPnt2=pID->aXP[nPnt2];
- long ndx0=aPnt.X()-aPnt2.X();
- long ndy0=aPnt.Y()-aPnt2.Y();
- FASTBOOL bHLin=ndy0==0;
- FASTBOOL bVLin=ndx0==0;
- if (!bHLin || !bVLin) {
- long ndx=aPos.X()-aPnt2.X();
- long ndy=aPos.Y()-aPnt2.Y();
- bPnt2=TRUE;
- double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
- double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
- FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
- FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
- if (bHor) ndy=long(ndy0*nXFact);
- if (bVer) ndx=long(ndx0*nYFact);
- aNeuPos2=aPnt2;
- aNeuPos2.X()+=ndx;
- aNeuPos2.Y()+=ndy;
- }
- }
- if (bPnt1 && bPnt2) { // beide Alternativen vorhanden (Konkurenz)
- BigInt nX1(aNeuPos1.X()-aPos.X()); nX1*=nX1;
- BigInt nY1(aNeuPos1.Y()-aPos.Y()); nY1*=nY1;
- BigInt nX2(aNeuPos2.X()-aPos.X()); nX2*=nX2;
- BigInt nY2(aNeuPos2.Y()-aPos.Y()); nY2*=nY2;
- nX1+=nY1; // Korrekturabstand zum Quadrat
- nX2+=nY2; // Korrekturabstand zum Quadrat
- // Die Alternative mit dem geringeren Korrekturbedarf gewinnt
- if (nX1<nX2) bPnt2=FALSE; else bPnt1=FALSE;
- }
- if (bPnt1) rDrag.Now()=aNeuPos1;
- if (bPnt2) rDrag.Now()=aNeuPos2;
- }
- rDrag.SetActionRect(Rectangle(rDrag.GetNow(),rDrag.GetNow()));
-
- // IBM Special: Punkte eliminieren, wenn die beiden angrenzenden
- // Linien eh' fast 180 deg sind.
- if (!bControl && rDrag.GetView()!=NULL && rDrag.GetView()->IsEliminatePolyPoints() &&
- !bBegPnt && !bEndPnt && !bPrevIsControl && !bNextIsControl)
+
+ if(pID->IsMultiPointDrag())
{
- Point aPt(pID->aXP[nNextPnt]);
- aPt-=rDrag.GetNow();
- long nWink1=GetAngle(aPt);
- aPt=rDrag.GetNow();
- aPt-=pID->aXP[nPrevPnt];
- long nWink2=GetAngle(aPt);
- long nDiff=nWink1-nWink2;
- nDiff=Abs(nDiff);
- pID->bEliminate=nDiff<=rDrag.GetView()->GetEliminatePolyPointLimitAngle();
- if (pID->bEliminate) { // Position anpassen, damit Smooth an den Enden stimmt
- aPt=pID->aXP[nNextPnt];
- aPt+=pID->aXP[nPrevPnt];
- aPt/=2;
- rDrag.Now()=aPt;
- }
- }
-
- // Um diese Entfernung wurde insgesamt gedraggd
- Point aDiff(rDrag.GetNow()); aDiff-=pID->aXP[nPnt];
-
- // Insgesamt sind 8 Faelle moeglich:
- // X 1. Weder rechts noch links Ctrl.
- // o--X--o 2. Rechts und links Ctrl, gedraggd wird St.
- // o--X 3. Nur links Ctrl, gedraggd wird St.
- // X--o 4. Nur rechts Ctrl, gedraggd wird St.
- // x--O--o 5. Rechts und links Ctrl, gedraggd wird links.
- // x--O 6. Nur links Ctrl, gedraggd wird links.
- // o--O--x 7. Rechts und links Ctrl, gedraggd wird rechts.
- // O--x 8. Nur rechts Ctrl, gedraggd wird rechts.
- // Zusaetzlich ist zu beachten, dass das Veraendern einer Linie (keine Kurve)
- // eine evtl. Kurve am anderen Ende der Linie bewirkt, falls dort Smooth
- // gesetzt ist (Kontrollpunktausrichtung an Gerade).
-
- pID->aXP[nPnt]+=aDiff; // <<<<<<<<<<
-
- // Nun symmetrische PlusHandles etc. checken
- if (bControl) { // Faelle 5,6,7,8
- USHORT nSt=nPnt; // der zugehoerige Stuetzpunkt
- USHORT nFix=nPnt; // der gegenueberliegende Kontrollpunkt
- if (bIsNextControl) { // Wenn der naechste ein Kontrollpunkt ist, muss der vorh. der Stuetzpunkt sein
- nSt=nPrevPnt;
- nFix=nPrevPrevPnt;
- } else {
- nSt=nNextPnt;
- nFix=nNextNextPnt;
- }
- if (pID->aXP.IsSmooth(nSt)) {
- pID->aXP.CalcSmoothJoin(nSt,nPnt,nFix); // <<<<<<<<<<
+ Point aDelta(rDrag.GetNow() - rDrag.GetStart());
+
+ if(aDelta.X() || aDelta.Y())
+ {
+ for(sal_uInt32 a(0); a < pID->maHandles.Count(); a++)
+ {
+ SdrHdl* pHandle = (SdrHdl*)pID->maHandles.GetObject(a);
+ const sal_uInt16 nPolyIndex(pHandle->GetPolyNum());
+ const sal_uInt16 nPointIndex(pHandle->GetPointNum());
+ const XPolygon& rOrig = pID->mrOrig[nPolyIndex];
+ XPolygon& rMove = pID->maMove[nPolyIndex];
+ const sal_uInt16 nPointCount(rOrig.GetPointCount());
+ BOOL bClosed(rOrig[0] == rOrig[nPointCount-1]);
+
+ // move point itself
+ rMove[nPointIndex] = rOrig[nPointIndex] + aDelta;
+
+ // when point is first and poly closed, move close point, too.
+ if(nPointCount > 0 && !nPointIndex && bClosed)
+ {
+ rMove[nPointCount - 1] = rOrig[nPointCount - 1] + aDelta;
+
+ // when moving the last point it may be necessary to move the
+ // control point in front of this one, too.
+ if(nPointCount > 1 && rOrig.IsControl(nPointCount - 2))
+ rMove[nPointCount - 2] = rOrig[nPointCount - 2] + aDelta;
+ }
+
+ // is a control point before this?
+ if(nPointIndex > 0 && rOrig.IsControl(nPointIndex - 1))
+ {
+ // Yes, move it, too
+ rMove[nPointIndex - 1] = rOrig[nPointIndex - 1] + aDelta;
+ }
+
+ // is a control point after this?
+ if(nPointIndex + 1 < nPointCount && rOrig.IsControl(nPointIndex + 1))
+ {
+ // Yes, move it, too
+ rMove[nPointIndex + 1] = rOrig[nPointIndex + 1] + aDelta;
+ }
+ }
}
}
-
- if (!bControl) { // Faelle 1,2,3,4 wobei bei 1 nix passiert und bei 3+4 unten noch mehr folgt
- // die beiden Kontrollpunkte mit verschieben
- if (bPrevIsControl) pID->aXP[nPrevPnt]+=aDiff; // <<<<<<<<<<
- if (bNextIsControl) pID->aXP[nNextPnt]+=aDiff; // <<<<<<<<<<
- // Kontrollpunkt ggf. an Gerade ausrichten
- if (pID->aXP.IsSmooth(nPnt)) {
- if (bPrevIsControl && !bNextIsControl && !bEndPnt) { // Fall 3
- pID->aXP.CalcSmoothJoin(nPnt,nNextPnt,nPrevPnt); // <<<<<<<<<<
+ else
+ {
+ pID->ResetPoly(*this);
+
+ // Div. Daten lokal Kopieren fuer weniger Code und schnelleren Zugriff
+ FASTBOOL bClosed =pID->bClosed ; // geschlossenes Objekt?
+ USHORT nPnt =pID->nPnt ; // Punktnummer innerhalb des obigen Polygons
+ FASTBOOL bBegPnt =pID->bBegPnt ; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
+ FASTBOOL bEndPnt =pID->bEndPnt ; // Gedraggter Punkt ist der Endpunkt einer Polyline
+ USHORT nPrevPnt =pID->nPrevPnt ; // Index des vorherigen Punkts
+ USHORT nNextPnt =pID->nNextPnt ; // Index des naechsten Punkts
+ FASTBOOL bPrevIsBegPnt =pID->bPrevIsBegPnt ; // Vorheriger Punkt ist Anfangspunkt einer Polyline
+ FASTBOOL bNextIsEndPnt =pID->bNextIsEndPnt ; // Folgepunkt ist Endpunkt einer Polyline
+ USHORT nPrevPrevPnt =pID->nPrevPrevPnt ; // Index des vorvorherigen Punkts
+ USHORT nNextNextPnt =pID->nNextNextPnt ; // Index des uebernaechsten Punkts
+ FASTBOOL bControl =pID->bControl ; // Punkt ist ein Kontrollpunkt
+ FASTBOOL bIsPrevControl=pID->bIsPrevControl; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
+ FASTBOOL bIsNextControl=pID->bIsNextControl; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
+ FASTBOOL bPrevIsControl=pID->bPrevIsControl; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
+ FASTBOOL bNextIsControl=pID->bNextIsControl; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
+
+ // Ortho bei Linien/Polygonen = Winkel beibehalten
+ if (!bControl && rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho()) {
+ FASTBOOL bBigOrtho=rDrag.GetView()->IsBigOrtho();
+ Point aPos(rDrag.GetNow()); // die aktuelle Position
+ Point aPnt(pID->aXP[nPnt]); // der gedraggte Punkt
+ USHORT nPnt1=0xFFFF,nPnt2=0xFFFF; // seine Nachbarpunkte
+ Point aNeuPos1,aNeuPos2; // die neuen Alternativen fuer aPos
+ FASTBOOL bPnt1=FALSE,bPnt2=FALSE; // die neuen Alternativen gueltig?
+ if (!bClosed && pID->nPntAnz>=2) { // Mind. 2 Pt bei Linien
+ if (!bBegPnt) nPnt1=nPrevPnt;
+ if (!bEndPnt) nPnt2=nNextPnt;
+ }
+ if (bClosed && pID->nPntAnz>=3) { // Mind. 3 Pt bei Polygon
+ nPnt1=nPrevPnt;
+ nPnt2=nNextPnt;
+ }
+ if (nPnt1!=0xFFFF && !bPrevIsControl) {
+ Point aPnt1=pID->aXP[nPnt1];
+ long ndx0=aPnt.X()-aPnt1.X();
+ long ndy0=aPnt.Y()-aPnt1.Y();
+ FASTBOOL bHLin=ndy0==0;
+ FASTBOOL bVLin=ndx0==0;
+ if (!bHLin || !bVLin) {
+ long ndx=aPos.X()-aPnt1.X();
+ long ndy=aPos.Y()-aPnt1.Y();
+ bPnt1=TRUE;
+ double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
+ double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
+ FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
+ FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
+ if (bHor) ndy=long(ndy0*nXFact);
+ if (bVer) ndx=long(ndx0*nYFact);
+ aNeuPos1=aPnt1;
+ aNeuPos1.X()+=ndx;
+ aNeuPos1.Y()+=ndy;
+ }
}
- if (bNextIsControl && !bPrevIsControl && !bBegPnt) { // Fall 4
- pID->aXP.CalcSmoothJoin(nPnt,nPrevPnt,nNextPnt); // <<<<<<<<<<
+ if (nPnt2!=0xFFFF && !bNextIsControl) {
+ Point aPnt2=pID->aXP[nPnt2];
+ long ndx0=aPnt.X()-aPnt2.X();
+ long ndy0=aPnt.Y()-aPnt2.Y();
+ FASTBOOL bHLin=ndy0==0;
+ FASTBOOL bVLin=ndx0==0;
+ if (!bHLin || !bVLin) {
+ long ndx=aPos.X()-aPnt2.X();
+ long ndy=aPos.Y()-aPnt2.Y();
+ bPnt2=TRUE;
+ double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
+ double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
+ FASTBOOL bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
+ FASTBOOL bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
+ if (bHor) ndy=long(ndy0*nXFact);
+ if (bVer) ndx=long(ndx0*nYFact);
+ aNeuPos2=aPnt2;
+ aNeuPos2.X()+=ndx;
+ aNeuPos2.Y()+=ndy;
+ }
+ }
+ if (bPnt1 && bPnt2) { // beide Alternativen vorhanden (Konkurenz)
+ BigInt nX1(aNeuPos1.X()-aPos.X()); nX1*=nX1;
+ BigInt nY1(aNeuPos1.Y()-aPos.Y()); nY1*=nY1;
+ BigInt nX2(aNeuPos2.X()-aPos.X()); nX2*=nX2;
+ BigInt nY2(aNeuPos2.Y()-aPos.Y()); nY2*=nY2;
+ nX1+=nY1; // Korrekturabstand zum Quadrat
+ nX2+=nY2; // Korrekturabstand zum Quadrat
+ // Die Alternative mit dem geringeren Korrekturbedarf gewinnt
+ if (nX1<nX2) bPnt2=FALSE; else bPnt1=FALSE;
}
+ if (bPnt1) rDrag.Now()=aNeuPos1;
+ if (bPnt2) rDrag.Now()=aNeuPos2;
}
- // Und nun noch die anderen Enden der Strecken ueberpruefen (nPnt+-1).
- // Ist dort eine Kurve (IsControl(nPnt+-2)) mit SmoothJoin (nPnt+-1),
- // so muss der entsprechende Kontrollpunkt (nPnt+-2) angepasst werden.
- if (!bBegPnt && !bPrevIsControl && !bPrevIsBegPnt && pID->aXP.IsSmooth(nPrevPnt)) {
- if (pID->aXP.IsControl(nPrevPrevPnt)) {
- pID->aXP.CalcSmoothJoin(nPrevPnt,nPnt,nPrevPrevPnt); // <<<<<<<<<<
+ rDrag.SetActionRect(Rectangle(rDrag.GetNow(),rDrag.GetNow()));
+
+ // IBM Special: Punkte eliminieren, wenn die beiden angrenzenden
+ // Linien eh' fast 180 deg sind.
+ if (!bControl && rDrag.GetView()!=NULL && rDrag.GetView()->IsEliminatePolyPoints() &&
+ !bBegPnt && !bEndPnt && !bPrevIsControl && !bNextIsControl)
+ {
+ Point aPt(pID->aXP[nNextPnt]);
+ aPt-=rDrag.GetNow();
+ long nWink1=GetAngle(aPt);
+ aPt=rDrag.GetNow();
+ aPt-=pID->aXP[nPrevPnt];
+ long nWink2=GetAngle(aPt);
+ long nDiff=nWink1-nWink2;
+ nDiff=Abs(nDiff);
+ pID->bEliminate=nDiff<=rDrag.GetView()->GetEliminatePolyPointLimitAngle();
+ if (pID->bEliminate) { // Position anpassen, damit Smooth an den Enden stimmt
+ aPt=pID->aXP[nNextPnt];
+ aPt+=pID->aXP[nPrevPnt];
+ aPt/=2;
+ rDrag.Now()=aPt;
}
}
- if (!bEndPnt && !bNextIsControl && !bNextIsEndPnt && pID->aXP.IsSmooth(nNextPnt)) {
- if (pID->aXP.IsControl(nNextNextPnt)) {
- pID->aXP.CalcSmoothJoin(nNextPnt,nPnt,nNextNextPnt); // <<<<<<<<<<
+
+ // Um diese Entfernung wurde insgesamt gedraggd
+ Point aDiff(rDrag.GetNow()); aDiff-=pID->aXP[nPnt];
+
+ // Insgesamt sind 8 Faelle moeglich:
+ // X 1. Weder rechts noch links Ctrl.
+ // o--X--o 2. Rechts und links Ctrl, gedraggd wird St.
+ // o--X 3. Nur links Ctrl, gedraggd wird St.
+ // X--o 4. Nur rechts Ctrl, gedraggd wird St.
+ // x--O--o 5. Rechts und links Ctrl, gedraggd wird links.
+ // x--O 6. Nur links Ctrl, gedraggd wird links.
+ // o--O--x 7. Rechts und links Ctrl, gedraggd wird rechts.
+ // O--x 8. Nur rechts Ctrl, gedraggd wird rechts.
+ // Zusaetzlich ist zu beachten, dass das Veraendern einer Linie (keine Kurve)
+ // eine evtl. Kurve am anderen Ende der Linie bewirkt, falls dort Smooth
+ // gesetzt ist (Kontrollpunktausrichtung an Gerade).
+
+ pID->aXP[nPnt]+=aDiff; // <<<<<<<<<<
+
+ // Nun symmetrische PlusHandles etc. checken
+ if (bControl) { // Faelle 5,6,7,8
+ USHORT nSt=nPnt; // der zugehoerige Stuetzpunkt
+ USHORT nFix=nPnt; // der gegenueberliegende Kontrollpunkt
+ if (bIsNextControl) { // Wenn der naechste ein Kontrollpunkt ist, muss der vorh. der Stuetzpunkt sein
+ nSt=nPrevPnt;
+ nFix=nPrevPrevPnt;
+ } else {
+ nSt=nNextPnt;
+ nFix=nNextNextPnt;
+ }
+ if (pID->aXP.IsSmooth(nSt)) {
+ pID->aXP.CalcSmoothJoin(nSt,nPnt,nFix); // <<<<<<<<<<
+ }
+ }
+
+ if (!bControl) { // Faelle 1,2,3,4 wobei bei 1 nix passiert und bei 3+4 unten noch mehr folgt
+ // die beiden Kontrollpunkte mit verschieben
+ if (bPrevIsControl) pID->aXP[nPrevPnt]+=aDiff; // <<<<<<<<<<
+ if (bNextIsControl) pID->aXP[nNextPnt]+=aDiff; // <<<<<<<<<<
+ // Kontrollpunkt ggf. an Gerade ausrichten
+ if (pID->aXP.IsSmooth(nPnt)) {
+ if (bPrevIsControl && !bNextIsControl && !bEndPnt) { // Fall 3
+ pID->aXP.CalcSmoothJoin(nPnt,nNextPnt,nPrevPnt); // <<<<<<<<<<
+ }
+ if (bNextIsControl && !bPrevIsControl && !bBegPnt) { // Fall 4
+ pID->aXP.CalcSmoothJoin(nPnt,nPrevPnt,nNextPnt); // <<<<<<<<<<
+ }
+ }
+ // Und nun noch die anderen Enden der Strecken ueberpruefen (nPnt+-1).
+ // Ist dort eine Kurve (IsControl(nPnt+-2)) mit SmoothJoin (nPnt+-1),
+ // so muss der entsprechende Kontrollpunkt (nPnt+-2) angepasst werden.
+ if (!bBegPnt && !bPrevIsControl && !bPrevIsBegPnt && pID->aXP.IsSmooth(nPrevPnt)) {
+ if (pID->aXP.IsControl(nPrevPrevPnt)) {
+ pID->aXP.CalcSmoothJoin(nPrevPnt,nPnt,nPrevPrevPnt); // <<<<<<<<<<
+ }
+ }
+ if (!bEndPnt && !bNextIsControl && !bNextIsEndPnt && pID->aXP.IsSmooth(nNextPnt)) {
+ if (pID->aXP.IsControl(nNextNextPnt)) {
+ pID->aXP.CalcSmoothJoin(nNextPnt,nPnt,nNextNextPnt); // <<<<<<<<<<
+ }
}
}
}
@@ -1264,56 +1379,66 @@ FASTBOOL SdrPathObj::EndDrag(SdrDragStat& rDrag)
aLinePt2=rXP[1];
}
ImpSdrPathDragData* pID=(ImpSdrPathDragData*)rDrag.GetUser();
- const SdrHdl* pHdl=rDrag.GetHdl();
- if (pID==NULL || !pID->bValid) {
- DBG_ERROR("SdrPathObj::EndDrag(): ImpSdrPathDragData ist ungueltig");
- return FALSE;
+
+ if(pID->IsMultiPointDrag())
+ {
+ SetPathPoly(pID->maMove);
}
- Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetBoundRect();
- SendRepaintBroadcast();
- // Referenz auf das Polygon
- XPolygon& rXP=aPathPolygon[pHdl->GetPolyNum()];
-
- // Die 5 Punkte die sich evtl. geaendert haben
- if (!pID->bPrevIsBegPnt) rXP[pID->nPrevPrevPnt0]=pID->aXP[pID->nPrevPrevPnt];
- if (!pID->bNextIsEndPnt) rXP[pID->nNextNextPnt0]=pID->aXP[pID->nNextNextPnt];
- if (!pID->bBegPnt) rXP[pID->nPrevPnt0] =pID->aXP[pID->nPrevPnt];
- if (!pID->bEndPnt) rXP[pID->nNextPnt0] =pID->aXP[pID->nNextPnt];
- rXP[pID->nPnt0] =pID->aXP[pID->nPnt];
-
- // Letzter Punkt muss beim Geschlossenen immer gleich dem Ersten sein
- if (pID->bClosed) rXP[rXP.GetPointCount()-1]=rXP[0];
- if (pID->bEliminate) {
- NbcDelPoint(rDrag.GetHdl()->GetSourceHdlNum());
- }
- ImpForceKind(); // Wg. impliziter Punktloeschung evtl. von PolyLine nach Line
- // Winkel anpassen fuer Text an einfacher Linie
- SetRectsDirty();
- if (bLineGlueMirror) { // #40549#
- XPolygon& rXP=aPathPolygon[0];
- Point aLinePt1_(rXP[0]);
- Point aLinePt2_(rXP[1]);
- FASTBOOL bXMirr=(aLinePt1_.X()>aLinePt2_.X())!=(aLinePt1.X()>aLinePt2.X());
- FASTBOOL bYMirr=(aLinePt1_.Y()>aLinePt2_.Y())!=(aLinePt1.Y()>aLinePt2.Y());
- if (bXMirr || bYMirr) {
- Point aRef1(GetSnapRect().Center());
- if (bXMirr) {
- Point aRef2(aRef1);
- aRef2.Y()++;
- NbcMirrorGluePoints(aRef1,aRef2);
- }
- if (bYMirr) {
- Point aRef2(aRef1);
- aRef2.X()++;
- NbcMirrorGluePoints(aRef1,aRef2);
+ else
+ {
+ const SdrHdl* pHdl=rDrag.GetHdl();
+ if (pID==NULL || !pID->bValid) {
+ DBG_ERROR("SdrPathObj::EndDrag(): ImpSdrPathDragData ist ungueltig");
+ return FALSE;
+ }
+ Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetBoundRect();
+ SendRepaintBroadcast();
+ // Referenz auf das Polygon
+ XPolygon& rXP=aPathPolygon[pHdl->GetPolyNum()];
+
+ // Die 5 Punkte die sich evtl. geaendert haben
+ if (!pID->bPrevIsBegPnt) rXP[pID->nPrevPrevPnt0]=pID->aXP[pID->nPrevPrevPnt];
+ if (!pID->bNextIsEndPnt) rXP[pID->nNextNextPnt0]=pID->aXP[pID->nNextNextPnt];
+ if (!pID->bBegPnt) rXP[pID->nPrevPnt0] =pID->aXP[pID->nPrevPnt];
+ if (!pID->bEndPnt) rXP[pID->nNextPnt0] =pID->aXP[pID->nNextPnt];
+ rXP[pID->nPnt0] =pID->aXP[pID->nPnt];
+
+ // Letzter Punkt muss beim Geschlossenen immer gleich dem Ersten sein
+ if (pID->bClosed) rXP[rXP.GetPointCount()-1]=rXP[0];
+ if (pID->bEliminate) {
+ NbcDelPoint(rDrag.GetHdl()->GetSourceHdlNum());
+ }
+ ImpForceKind(); // Wg. impliziter Punktloeschung evtl. von PolyLine nach Line
+ // Winkel anpassen fuer Text an einfacher Linie
+ SetRectsDirty();
+ if (bLineGlueMirror) { // #40549#
+ XPolygon& rXP=aPathPolygon[0];
+ Point aLinePt1_(rXP[0]);
+ Point aLinePt2_(rXP[1]);
+ FASTBOOL bXMirr=(aLinePt1_.X()>aLinePt2_.X())!=(aLinePt1.X()>aLinePt2.X());
+ FASTBOOL bYMirr=(aLinePt1_.Y()>aLinePt2_.Y())!=(aLinePt1.Y()>aLinePt2.Y());
+ if (bXMirr || bYMirr) {
+ Point aRef1(GetSnapRect().Center());
+ if (bXMirr) {
+ Point aRef2(aRef1);
+ aRef2.Y()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
+ if (bYMirr) {
+ Point aRef2(aRef1);
+ aRef2.X()++;
+ NbcMirrorGluePoints(aRef1,aRef2);
+ }
}
}
+ SetChanged();
+ SendRepaintBroadcast();
+ SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
}
- SetChanged();
- SendRepaintBroadcast();
- SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
+
delete pID;
rDrag.SetUser(NULL);
+
return TRUE;
}
@@ -1346,7 +1471,7 @@ XubString SdrPathObj::GetDragComment(const SdrDragStat& rDrag, FASTBOOL bUndoDra
}
else
{
- if(pID->bEliminate)
+ if(!pID->IsMultiPointDrag() && pID->bEliminate)
{
// Punkt von ...
ImpTakeDescriptionStr(STR_ViewMarkedPoint, aStr);
@@ -1376,108 +1501,111 @@ XubString SdrPathObj::GetDragComment(const SdrDragStat& rDrag, FASTBOOL bUndoDra
pModel->TakeMetricStr(aNow.Y() - aBeg.Y(), aMetr, TRUE);
aStr += aMetr;
- UINT16 nPntNum(pHdl->GetPointNum());
- const XPolygon& rXPoly = aPathPolygon[rDrag.GetHdl()->GetPolyNum()];
- UINT16 nPntAnz(rXPoly.GetPointCount());
- BOOL bClose(IsClosed());
-
- if(bClose)
- nPntAnz--;
-
- if(pHdl->IsPlusHdl())
- {
- // Hebel
- UINT16 nRef(nPntNum);
-
- if(rXPoly.IsControl(nPntNum + 1))
- nRef--;
- else
- nRef++;
-
- aNow -= rXPoly[nRef];
-
- INT32 nLen(GetLen(aNow));
- aStr.AppendAscii(" l=");
- pModel->TakeMetricStr(nLen, aMetr, TRUE);
- aStr += aMetr;
-
- INT32 nWink(GetAngle(aNow));
- aStr += sal_Unicode(' ');
- pModel->TakeWinkStr(nWink, aMetr);
- aStr += aMetr;
- }
- else if(nPntAnz > 1)
+ if(!pID->IsMultiPointDrag())
{
- UINT16 nPntMax(nPntAnz - 1);
- Point aPt1,aPt2;
+ UINT16 nPntNum(pHdl->GetPointNum());
+ const XPolygon& rXPoly = aPathPolygon[rDrag.GetHdl()->GetPolyNum()];
+ UINT16 nPntAnz(rXPoly.GetPointCount());
BOOL bClose(IsClosed());
- BOOL bPt1(nPntNum > 0);
- BOOL bPt2(nPntNum < nPntMax);
- if(bClose && nPntAnz > 2)
- {
- bPt1 = TRUE;
- bPt2 = TRUE;
- }
+ if(bClose)
+ nPntAnz--;
- UINT16 nPt1,nPt2;
-
- if(nPntNum > 0)
- nPt1 = nPntNum - 1;
- else
- nPt1 = nPntMax;
-
- if(nPntNum < nPntMax)
- nPt2 = nPntNum + 1;
- else
- nPt2 = 0;
+ if(pHdl->IsPlusHdl())
+ {
+ // Hebel
+ UINT16 nRef(nPntNum);
- if(bPt1 && rXPoly.IsControl(nPt1))
- bPt1 = FALSE; // Keine Anzeige
+ if(rXPoly.IsControl(nPntNum + 1))
+ nRef--;
+ else
+ nRef++;
- if(bPt2 && rXPoly.IsControl(nPt2))
- bPt2 = FALSE; // von Bezierdaten
+ aNow -= rXPoly[nRef];
- if(bPt1)
- {
- Point aPt(aNow);
- aPt -= rXPoly[nPt1];
-
- INT32 nLen(GetLen(aPt));
+ INT32 nLen(GetLen(aNow));
aStr.AppendAscii(" l=");
pModel->TakeMetricStr(nLen, aMetr, TRUE);
aStr += aMetr;
- INT32 nWink(GetAngle(aPt));
+ INT32 nWink(GetAngle(aNow));
aStr += sal_Unicode(' ');
pModel->TakeWinkStr(nWink, aMetr);
aStr += aMetr;
}
-
- if(bPt2)
+ else if(nPntAnz > 1)
{
- if(bPt1)
- aStr.AppendAscii(" / ");
+ UINT16 nPntMax(nPntAnz - 1);
+ Point aPt1,aPt2;
+ BOOL bClose(IsClosed());
+ BOOL bPt1(nPntNum > 0);
+ BOOL bPt2(nPntNum < nPntMax);
+
+ if(bClose && nPntAnz > 2)
+ {
+ bPt1 = TRUE;
+ bPt2 = TRUE;
+ }
+
+ UINT16 nPt1,nPt2;
+
+ if(nPntNum > 0)
+ nPt1 = nPntNum - 1;
else
- aStr.AppendAscii(" ");
+ nPt1 = nPntMax;
- Point aPt(aNow);
- aPt -= rXPoly[nPt2];
+ if(nPntNum < nPntMax)
+ nPt2 = nPntNum + 1;
+ else
+ nPt2 = 0;
- INT32 nLen(GetLen(aPt));
- aStr.AppendAscii("l=");
- pModel->TakeMetricStr(nLen, aMetr, TRUE);
- aStr += aMetr;
+ if(bPt1 && rXPoly.IsControl(nPt1))
+ bPt1 = FALSE; // Keine Anzeige
- INT32 nWink(GetAngle(aPt));
- aStr += sal_Unicode(' ');
- pModel->TakeWinkStr(nWink, aMetr);
- aStr += aMetr;
+ if(bPt2 && rXPoly.IsControl(nPt2))
+ bPt2 = FALSE; // von Bezierdaten
+
+ if(bPt1)
+ {
+ Point aPt(aNow);
+ aPt -= rXPoly[nPt1];
+
+ INT32 nLen(GetLen(aPt));
+ aStr.AppendAscii(" l=");
+ pModel->TakeMetricStr(nLen, aMetr, TRUE);
+ aStr += aMetr;
+
+ INT32 nWink(GetAngle(aPt));
+ aStr += sal_Unicode(' ');
+ pModel->TakeWinkStr(nWink, aMetr);
+ aStr += aMetr;
+ }
+
+ if(bPt2)
+ {
+ if(bPt1)
+ aStr.AppendAscii(" / ");
+ else
+ aStr.AppendAscii(" ");
+
+ Point aPt(aNow);
+ aPt -= rXPoly[nPt2];
+
+ INT32 nLen(GetLen(aPt));
+ aStr.AppendAscii("l=");
+ pModel->TakeMetricStr(nLen, aMetr, TRUE);
+ aStr += aMetr;
+
+ INT32 nWink(GetAngle(aPt));
+ aStr += sal_Unicode(' ');
+ pModel->TakeWinkStr(nWink, aMetr);
+ aStr += aMetr;
+ }
}
}
}
}
- else if(pModel)
+ else if(pModel && !pID->IsMultiPointDrag())
{
// Ansonsten CreateComment
ImpPathCreateUser* pU = (ImpPathCreateUser*)rDrag.GetUser();
@@ -1531,6 +1659,7 @@ XubString SdrPathObj::GetDragComment(const SdrDragStat& rDrag, FASTBOOL bUndoDra
aStr += sal_Unicode(')');
}
+
return aStr;
}
@@ -1548,102 +1677,110 @@ void SdrPathObj::TakeDragPoly(const SdrDragStat& rDrag, XPolyPolygon& rXPP) cons
{
rXPP.Clear();
ImpSdrPathDragData* pID=(ImpSdrPathDragData*)rDrag.GetUser();
- const XPolygon& rXP=aPathPolygon[rDrag.GetHdl()->GetPolyNum()];
- if (rXP.GetPointCount()<=2 /*|| rXPoly.GetFlags(1)==XPOLY_CONTROL && rXPoly.GetPointCount()<=4*/) {
- XPolygon aXPoly(rXP);
- aXPoly[rDrag.GetHdl()->GetPointNum()]=rDrag.GetNow();
- rXPP.Insert(aXPoly);
- return;
- }
- // Div. Daten lokal Kopieren fuer weniger Code und schnelleren Zugriff
- FASTBOOL bClosed =pID->bClosed ; // geschlossenes Objekt?
- USHORT nPntAnz =pID->nPntAnz ; // Punktanzahl
- USHORT nPnt =pID->nPnt ; // Punktnummer innerhalb des Polygons
- FASTBOOL bBegPnt =pID->bBegPnt ; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
- FASTBOOL bEndPnt =pID->bEndPnt ; // Gedraggter Punkt ist der Endpunkt einer Polyline
- USHORT nPrevPnt =pID->nPrevPnt ; // Index des vorherigen Punkts
- USHORT nNextPnt =pID->nNextPnt ; // Index des naechsten Punkts
- FASTBOOL bPrevIsBegPnt =pID->bPrevIsBegPnt ; // Vorheriger Punkt ist Anfangspunkt einer Polyline
- FASTBOOL bNextIsEndPnt =pID->bNextIsEndPnt ; // Folgepunkt ist Endpunkt einer Polyline
- USHORT nPrevPrevPnt =pID->nPrevPrevPnt ; // Index des vorvorherigen Punkts
- USHORT nNextNextPnt =pID->nNextNextPnt ; // Index des uebernaechsten Punkts
- FASTBOOL bControl =pID->bControl ; // Punkt ist ein Kontrollpunkt
- FASTBOOL bIsPrevControl=pID->bIsPrevControl; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
- FASTBOOL bIsNextControl=pID->bIsNextControl; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
- FASTBOOL bPrevIsControl=pID->bPrevIsControl; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
- FASTBOOL bNextIsControl=pID->bNextIsControl; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
- XPolygon aXPoly(pID->aXP);
- XPolygon aLine1(2);
- XPolygon aLine2(2);
- XPolygon aLine3(2);
- XPolygon aLine4(2);
- if (bControl) {
- aLine1[1]=pID->aXP[nPnt];
- if (bIsNextControl) { // bin ich Kontrollpunkt hinter der Stuetzstelle?
- aLine1[0]=pID->aXP[nPrevPnt];
- aLine2[0]=pID->aXP[nNextNextPnt];
- aLine2[1]=pID->aXP[nNextPnt];
- if (pID->aXP.IsSmooth(nPrevPnt) && !bPrevIsBegPnt && pID->aXP.IsControl(nPrevPrevPnt)) {
+
+ if(pID->IsMultiPointDrag())
+ {
+ rXPP.Insert(pID->maMove);
+ }
+ else
+ {
+ const XPolygon& rXP=aPathPolygon[rDrag.GetHdl()->GetPolyNum()];
+ if (rXP.GetPointCount()<=2 /*|| rXPoly.GetFlags(1)==XPOLY_CONTROL && rXPoly.GetPointCount()<=4*/) {
+ XPolygon aXPoly(rXP);
+ aXPoly[rDrag.GetHdl()->GetPointNum()]=rDrag.GetNow();
+ rXPP.Insert(aXPoly);
+ return;
+ }
+ // Div. Daten lokal Kopieren fuer weniger Code und schnelleren Zugriff
+ FASTBOOL bClosed =pID->bClosed ; // geschlossenes Objekt?
+ USHORT nPntAnz =pID->nPntAnz ; // Punktanzahl
+ USHORT nPnt =pID->nPnt ; // Punktnummer innerhalb des Polygons
+ FASTBOOL bBegPnt =pID->bBegPnt ; // Gedraggter Punkt ist der Anfangspunkt einer Polyline
+ FASTBOOL bEndPnt =pID->bEndPnt ; // Gedraggter Punkt ist der Endpunkt einer Polyline
+ USHORT nPrevPnt =pID->nPrevPnt ; // Index des vorherigen Punkts
+ USHORT nNextPnt =pID->nNextPnt ; // Index des naechsten Punkts
+ FASTBOOL bPrevIsBegPnt =pID->bPrevIsBegPnt ; // Vorheriger Punkt ist Anfangspunkt einer Polyline
+ FASTBOOL bNextIsEndPnt =pID->bNextIsEndPnt ; // Folgepunkt ist Endpunkt einer Polyline
+ USHORT nPrevPrevPnt =pID->nPrevPrevPnt ; // Index des vorvorherigen Punkts
+ USHORT nNextNextPnt =pID->nNextNextPnt ; // Index des uebernaechsten Punkts
+ FASTBOOL bControl =pID->bControl ; // Punkt ist ein Kontrollpunkt
+ FASTBOOL bIsPrevControl=pID->bIsPrevControl; // Punkt ist Kontrollpunkt vor einem Stuetzpunkt
+ FASTBOOL bIsNextControl=pID->bIsNextControl; // Punkt ist Kontrollpunkt hinter einem Stuetzpunkt
+ FASTBOOL bPrevIsControl=pID->bPrevIsControl; // Falls nPnt ein StPnt: Davor ist ein Kontrollpunkt
+ FASTBOOL bNextIsControl=pID->bNextIsControl; // Falls nPnt ein StPnt: Dahinter ist ein Kontrollpunkt
+ XPolygon aXPoly(pID->aXP);
+ XPolygon aLine1(2);
+ XPolygon aLine2(2);
+ XPolygon aLine3(2);
+ XPolygon aLine4(2);
+ if (bControl) {
+ aLine1[1]=pID->aXP[nPnt];
+ if (bIsNextControl) { // bin ich Kontrollpunkt hinter der Stuetzstelle?
+ aLine1[0]=pID->aXP[nPrevPnt];
+ aLine2[0]=pID->aXP[nNextNextPnt];
+ aLine2[1]=pID->aXP[nNextPnt];
+ if (pID->aXP.IsSmooth(nPrevPnt) && !bPrevIsBegPnt && pID->aXP.IsControl(nPrevPrevPnt)) {
+ aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-1],XPOLY_CONTROL);
+ aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-2],XPOLY_NORMAL);
+ // Hebellienien fuer das gegenueberliegende Kurvensegment
+ aLine3[0]=pID->aXP[nPrevPnt];
+ aLine3[1]=pID->aXP[nPrevPrevPnt];
+ aLine4[0]=rXP[pID->nPrevPrevPnt0-2];
+ aLine4[1]=rXP[pID->nPrevPrevPnt0-1];
+ } else {
+ aXPoly.Remove(0,1);
+ }
+ } else { // ansonsten bin ich Kontrollpunkt vor der Stuetzstelle
+ aLine1[0]=pID->aXP[nNextPnt];
+ aLine2[0]=pID->aXP[nPrevPrevPnt];
+ aLine2[1]=pID->aXP[nPrevPnt];
+ if (pID->aXP.IsSmooth(nNextPnt) && !bNextIsEndPnt && pID->aXP.IsControl(nNextNextPnt)) {
+ aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+1],XPOLY_CONTROL);
+ aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+2],XPOLY_NORMAL);
+ // Hebellinien fuer das gegenueberliegende Kurvensegment
+ aLine3[0]=pID->aXP[nNextPnt];
+ aLine3[1]=pID->aXP[nNextNextPnt];
+ aLine4[0]=rXP[pID->nNextNextPnt0+2];
+ aLine4[1]=rXP[pID->nNextNextPnt0+1];
+ } else {
+ aXPoly.Remove(aXPoly.GetPointCount()-1,1);
+ }
+ }
+ } else { // ansonsten kein Kontrollpunkt
+ if (pID->bEliminate) {
+ aXPoly.Remove(2,1);
+ }
+ if (bPrevIsControl) aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-1],XPOLY_NORMAL);
+ else if (!bBegPnt && !bPrevIsBegPnt && pID->aXP.IsControl(nPrevPrevPnt)) {
aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-1],XPOLY_CONTROL);
aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-2],XPOLY_NORMAL);
- // Hebellienien fuer das gegenueberliegende Kurvensegment
- aLine3[0]=pID->aXP[nPrevPnt];
- aLine3[1]=pID->aXP[nPrevPrevPnt];
- aLine4[0]=rXP[pID->nPrevPrevPnt0-2];
- aLine4[1]=rXP[pID->nPrevPrevPnt0-1];
} else {
aXPoly.Remove(0,1);
+ if (bBegPnt) aXPoly.Remove(0,1);
}
- } else { // ansonsten bin ich Kontrollpunkt vor der Stuetzstelle
- aLine1[0]=pID->aXP[nNextPnt];
- aLine2[0]=pID->aXP[nPrevPrevPnt];
- aLine2[1]=pID->aXP[nPrevPnt];
- if (pID->aXP.IsSmooth(nNextPnt) && !bNextIsEndPnt && pID->aXP.IsControl(nNextNextPnt)) {
+ if (bNextIsControl) aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+1],XPOLY_NORMAL);
+ else if (!bEndPnt && !bNextIsEndPnt && pID->aXP.IsControl(nNextNextPnt)) {
aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+1],XPOLY_CONTROL);
aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+2],XPOLY_NORMAL);
- // Hebellinien fuer das gegenueberliegende Kurvensegment
- aLine3[0]=pID->aXP[nNextPnt];
- aLine3[1]=pID->aXP[nNextNextPnt];
- aLine4[0]=rXP[pID->nNextNextPnt0+2];
- aLine4[1]=rXP[pID->nNextNextPnt0+1];
} else {
aXPoly.Remove(aXPoly.GetPointCount()-1,1);
+ if (bEndPnt) aXPoly.Remove(aXPoly.GetPointCount()-1,1);
}
- }
- } else { // ansonsten kein Kontrollpunkt
- if (pID->bEliminate) {
- aXPoly.Remove(2,1);
- }
- if (bPrevIsControl) aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-1],XPOLY_NORMAL);
- else if (!bBegPnt && !bPrevIsBegPnt && pID->aXP.IsControl(nPrevPrevPnt)) {
- aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-1],XPOLY_CONTROL);
- aXPoly.Insert(0,rXP[pID->nPrevPrevPnt0-2],XPOLY_NORMAL);
- } else {
- aXPoly.Remove(0,1);
- if (bBegPnt) aXPoly.Remove(0,1);
- }
- if (bNextIsControl) aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+1],XPOLY_NORMAL);
- else if (!bEndPnt && !bNextIsEndPnt && pID->aXP.IsControl(nNextNextPnt)) {
- aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+1],XPOLY_CONTROL);
- aXPoly.Insert(XPOLY_APPEND,rXP[pID->nNextNextPnt0+2],XPOLY_NORMAL);
- } else {
- aXPoly.Remove(aXPoly.GetPointCount()-1,1);
- if (bEndPnt) aXPoly.Remove(aXPoly.GetPointCount()-1,1);
- }
- if (bClosed) { // "Birnenproblem": 2 Linien, 1 Kurve, alles Smooth, Punkt zw. beiden Linien wird gedraggt
- if (aXPoly.GetPointCount()>nPntAnz && aXPoly.IsControl(1)) {
- USHORT a=aXPoly.GetPointCount();
- aXPoly[a-2]=aXPoly[2]; aXPoly.SetFlags(a-2,aXPoly.GetFlags(2));
- aXPoly[a-1]=aXPoly[3]; aXPoly.SetFlags(a-1,aXPoly.GetFlags(3));
- aXPoly.Remove(0,3);
+ if (bClosed) { // "Birnenproblem": 2 Linien, 1 Kurve, alles Smooth, Punkt zw. beiden Linien wird gedraggt
+ if (aXPoly.GetPointCount()>nPntAnz && aXPoly.IsControl(1)) {
+ USHORT a=aXPoly.GetPointCount();
+ aXPoly[a-2]=aXPoly[2]; aXPoly.SetFlags(a-2,aXPoly.GetFlags(2));
+ aXPoly[a-1]=aXPoly[3]; aXPoly.SetFlags(a-1,aXPoly.GetFlags(3));
+ aXPoly.Remove(0,3);
+ }
}
}
+ rXPP.Insert(aXPoly);
+ if (aLine1.GetPointCount()>1) rXPP.Insert(aLine1);
+ if (aLine2.GetPointCount()>1) rXPP.Insert(aLine2);
+ if (aLine3.GetPointCount()>1) rXPP.Insert(aLine3);
+ if (aLine4.GetPointCount()>1) rXPP.Insert(aLine4);
}
- rXPP.Insert(aXPoly);
- if (aLine1.GetPointCount()>1) rXPP.Insert(aLine1);
- if (aLine2.GetPointCount()>1) rXPP.Insert(aLine2);
- if (aLine3.GetPointCount()>1) rXPP.Insert(aLine3);
- if (aLine4.GetPointCount()>1) rXPP.Insert(aLine4);
}
FASTBOOL SdrPathObj::BegCreate(SdrDragStat& rStat)