diff options
Diffstat (limited to 'svx/source/svdraw/svdomeas.cxx')
-rw-r--r-- | svx/source/svdraw/svdomeas.cxx | 1494 |
1 files changed, 1494 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdomeas.cxx b/svx/source/svdraw/svdomeas.cxx new file mode 100644 index 000000000000..2bcf016d0e4a --- /dev/null +++ b/svx/source/svdraw/svdomeas.cxx @@ -0,0 +1,1494 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/svdomeas.hxx> +#include <math.h> +#include "svditext.hxx" // +#include <svx/xpoly.hxx> +#include <svx/svdtrans.hxx> +#include <svx/svdhdl.hxx> +#include <svx/svdoutl.hxx> +#include <svx/svddrag.hxx> +#include <svx/svdpool.hxx> +#include <svx/svdattrx.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdview.hxx> +#include "svdglob.hxx" // StringCache +#include "svdstr.hrc" // Objektname +#include <svl/style.hxx> +#include <svl/smplhint.hxx> +#include <editeng/eeitem.hxx> +#include <svx/xlnstit.hxx> +#include <svx/xlnstwit.hxx> +#include <svx/xlnedit.hxx> +#include <svx/xlnwtit.hxx> +#include <svx/xlnedwit.hxx> +#include <svx/xlnstcit.hxx> +#include <svx/xlnedcit.hxx> +#include <editeng/outlobj.hxx> +#include <editeng/outliner.hxx> +#include <editeng/editobj.hxx> +#include <editeng/measfld.hxx> +#include <editeng/flditem.hxx> +#include <svx/svdogrp.hxx> +#include <svx/svdopath.hxx> +#include <svx/svdpage.hxx> +#include <unotools/syslocale.hxx> +#include "svdoimp.hxx" +#include <svx/sdr/properties/measureproperties.hxx> +#include <svx/sdr/contact/viewcontactofsdrmeasureobj.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolypolygon.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +SdrMeasureObjGeoData::SdrMeasureObjGeoData() {} +SdrMeasureObjGeoData::~SdrMeasureObjGeoData() {} + +void SdrMeasureObj::TakeRepresentation( XubString& rStr, SdrMeasureFieldKind eMeasureFieldKind ) const +{ + rStr.Erase(); + Fraction aMeasureScale(1, 1); + BOOL bTextRota90(FALSE); + BOOL bShowUnit(FALSE); + FieldUnit eMeasureUnit(FUNIT_NONE); + FieldUnit eModUIUnit(FUNIT_NONE); + + const SfxItemSet& rSet = GetMergedItemSet(); + bTextRota90 = ((SdrMeasureTextRota90Item&)rSet.Get(SDRATTR_MEASURETEXTROTA90)).GetValue(); + eMeasureUnit = ((SdrMeasureUnitItem&)rSet.Get(SDRATTR_MEASUREUNIT)).GetValue(); + aMeasureScale = ((SdrMeasureScaleItem&)rSet.Get(SDRATTR_MEASURESCALE)).GetValue(); + bShowUnit = ((SdrMeasureShowUnitItem&)rSet.Get(SDRATTR_MEASURESHOWUNIT)).GetValue(); + sal_Int16 nNumDigits = ((SdrMeasureDecimalPlacesItem&)rSet.Get(SDRATTR_MEASUREDECIMALPLACES)).GetValue(); + + //SdrModel* pModel = rObj.pModel; + + switch(eMeasureFieldKind) + { + case SDRMEASUREFIELD_VALUE: + { + if(pModel) + { + eModUIUnit = pModel->GetUIUnit(); + + if(eMeasureUnit == FUNIT_NONE) + eMeasureUnit = eModUIUnit; + + INT32 nLen(GetLen(aPt2 - aPt1)); + Fraction aFact(1,1); + + if(eMeasureUnit != eModUIUnit) + { + // Zur Umrechnung der Einheiten + aFact *= GetMapFactor(eModUIUnit, eMeasureUnit).X(); + } + + if(aMeasureScale.GetNumerator() != aMeasureScale.GetDenominator()) + { + aFact *= aMeasureScale; + } + + if(aFact.GetNumerator() != aFact.GetDenominator()) + { + // Scaling ueber BigInt, um Ueberlaeufe zu vermeiden + nLen = BigMulDiv(nLen, aFact.GetNumerator(), aFact.GetDenominator()); + } + + pModel->TakeMetricStr(nLen, rStr, TRUE, nNumDigits); + + if(!aFact.IsValid()) + { + rStr = String(); + rStr += sal_Unicode('?'); + } + + sal_Unicode cDec(SvtSysLocale().GetLocaleData().getNumDecimalSep().GetChar(0)); + + if(rStr.Search(cDec) != STRING_NOTFOUND) + { + xub_StrLen nLen2(rStr.Len() - 1); + + while(rStr.GetChar(nLen2) == sal_Unicode('0')) + { + rStr.Erase(nLen2); + nLen2--; + } + + if(rStr.GetChar(nLen2) == cDec) + { + rStr.Erase(nLen2); + nLen2--; + } + + if(!rStr.Len()) + rStr += sal_Unicode('0'); + } + } + else + { + // falls kein Model da ... (z.B. Preview im Dialog) + rStr = String(); + rStr.AppendAscii("4711"); + } + + break; + } + case SDRMEASUREFIELD_UNIT: + { + if(bShowUnit) + { + if(pModel) + { + eModUIUnit = pModel->GetUIUnit(); + + if(eMeasureUnit == FUNIT_NONE) + eMeasureUnit = eModUIUnit; + + if(bShowUnit) + pModel->TakeUnitStr(eMeasureUnit, rStr); + } + } + + break; + } + case SDRMEASUREFIELD_ROTA90BLANCS: + { + if(bTextRota90) + { + rStr = String(); + rStr += sal_Unicode(' '); + } + + break; + } + } +} + +////////////////////////////////////////////////////////////////////////////// +// BaseProperties section + +sdr::properties::BaseProperties* SdrMeasureObj::CreateObjectSpecificProperties() +{ + return new sdr::properties::MeasureProperties(*this); +} + +////////////////////////////////////////////////////////////////////////////// +// DrawContact section + +sdr::contact::ViewContact* SdrMeasureObj::CreateObjectSpecificViewContact() +{ + return new sdr::contact::ViewContactOfSdrMeasureObj(*this); +} + +////////////////////////////////////////////////////////////////////////////// + +TYPEINIT1(SdrMeasureObj,SdrTextObj); + +SdrMeasureObj::SdrMeasureObj(): + bTextDirty(FALSE) +{ + // #i25616# + mbSupportTextIndentingOnLineWidthChange = sal_False; +} + +SdrMeasureObj::SdrMeasureObj(const Point& rPt1, const Point& rPt2): + aPt1(rPt1), + aPt2(rPt2), + bTextDirty(FALSE) +{ + // #i25616# + mbSupportTextIndentingOnLineWidthChange = sal_False; +} + +SdrMeasureObj::~SdrMeasureObj() +{ +} + +void SdrMeasureObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const +{ + rInfo.bSelectAllowed =TRUE; + rInfo.bMoveAllowed =TRUE; + rInfo.bResizeFreeAllowed=TRUE; + rInfo.bResizePropAllowed=TRUE; + rInfo.bRotateFreeAllowed=TRUE; + rInfo.bRotate90Allowed =TRUE; + rInfo.bMirrorFreeAllowed=TRUE; + rInfo.bMirror45Allowed =TRUE; + rInfo.bMirror90Allowed =TRUE; + rInfo.bTransparenceAllowed = FALSE; + rInfo.bGradientAllowed = FALSE; + rInfo.bShearAllowed =TRUE; + rInfo.bEdgeRadiusAllowed=FALSE; + rInfo.bNoOrthoDesired =TRUE; + rInfo.bNoContortion =FALSE; + rInfo.bCanConvToPath =FALSE; + rInfo.bCanConvToPoly =TRUE; + rInfo.bCanConvToPathLineToArea=FALSE; + rInfo.bCanConvToPolyLineToArea=FALSE; + rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary()); +} + +UINT16 SdrMeasureObj::GetObjIdentifier() const +{ + return (UINT16)OBJ_MEASURE; +} + +struct ImpMeasureRec : public SdrDragStatUserData +{ + Point aPt1; + Point aPt2; + SdrMeasureKind eKind; + SdrMeasureTextHPos eWantTextHPos; + SdrMeasureTextVPos eWantTextVPos; + long nLineDist; + long nHelplineOverhang; + long nHelplineDist; + long nHelpline1Len; + long nHelpline2Len; + FASTBOOL bBelowRefEdge; + FASTBOOL bTextRota90; + FASTBOOL bTextUpsideDown; + long nMeasureOverhang; + FieldUnit eMeasureUnit; + Fraction aMeasureScale; + FASTBOOL bShowUnit; + String aFormatString; + FASTBOOL bTextAutoAngle; + long nTextAutoAngleView; + FASTBOOL bTextIsFixedAngle; + long nTextFixedAngle; +}; + +struct ImpLineRec +{ + Point aP1; + Point aP2; +}; + +struct ImpMeasurePoly +{ + ImpLineRec aMainline1; // die mit dem 1. Pfeil + ImpLineRec aMainline2; // die mit dem 2. Pfeil + ImpLineRec aMainline3; // die dazwischen + ImpLineRec aHelpline1; + ImpLineRec aHelpline2; + Rectangle aTextRect; + Size aTextSize; + long nLineLen; + long nLineWink; + long nTextWink; + long nHlpWink; + double nLineSin; + double nLineCos; + double nHlpSin; + double nHlpCos; + USHORT nMainlineAnz; + SdrMeasureTextHPos eUsedTextHPos; + SdrMeasureTextVPos eUsedTextVPos; + long nLineWdt2; // Halbe Strichstaerke + long nArrow1Len; // Laenge des 1. Pfeils. Bei Center nur die Haelfte + long nArrow2Len; // Laenge des 2. Pfeils. Bei Center nur die Haelfte + long nArrow1Wdt; // Breite des 1. Pfeils + long nArrow2Wdt; // Breite des 2. Pfeils + long nShortLineLen; // Linienlaenge, wenn PfeileAussen + FASTBOOL bArrow1Center; // Pfeil 1 zentriert? + FASTBOOL bArrow2Center; // Pfeil 2 zentriert? + FASTBOOL bAutoUpsideDown; // UpsideDown durch Automatik + FASTBOOL bPfeileAussen; + FASTBOOL bBreakedLine; +}; + +void SdrMeasureObj::ImpTakeAttr(ImpMeasureRec& rRec) const +{ + rRec.aPt1 = aPt1; + rRec.aPt2 = aPt2; + + const SfxItemSet& rSet = GetObjectItemSet(); + rRec.eKind =((SdrMeasureKindItem& )rSet.Get(SDRATTR_MEASUREKIND )).GetValue(); + rRec.eWantTextHPos =((SdrMeasureTextHPosItem& )rSet.Get(SDRATTR_MEASURETEXTHPOS )).GetValue(); + rRec.eWantTextVPos =((SdrMeasureTextVPosItem& )rSet.Get(SDRATTR_MEASURETEXTVPOS )).GetValue(); + rRec.nLineDist =((SdrMeasureLineDistItem& )rSet.Get(SDRATTR_MEASURELINEDIST )).GetValue(); + rRec.nHelplineOverhang=((SdrMeasureHelplineOverhangItem&)rSet.Get(SDRATTR_MEASUREHELPLINEOVERHANG)).GetValue(); + rRec.nHelplineDist =((SdrMeasureHelplineDistItem& )rSet.Get(SDRATTR_MEASUREHELPLINEDIST )).GetValue(); + rRec.nHelpline1Len =((SdrMeasureHelpline1LenItem& )rSet.Get(SDRATTR_MEASUREHELPLINE1LEN )).GetValue(); + rRec.nHelpline2Len =((SdrMeasureHelpline2LenItem& )rSet.Get(SDRATTR_MEASUREHELPLINE2LEN )).GetValue(); + rRec.bBelowRefEdge =((SdrMeasureBelowRefEdgeItem& )rSet.Get(SDRATTR_MEASUREBELOWREFEDGE )).GetValue(); + rRec.bTextRota90 =((SdrMeasureTextRota90Item& )rSet.Get(SDRATTR_MEASURETEXTROTA90 )).GetValue(); + rRec.bTextUpsideDown =((SdrMeasureTextUpsideDownItem& )rSet.Get(SDRATTR_MEASURETEXTUPSIDEDOWN )).GetValue(); + rRec.nMeasureOverhang =((SdrMeasureOverhangItem& )rSet.Get(SDRATTR_MEASUREOVERHANG )).GetValue(); + rRec.eMeasureUnit =((SdrMeasureUnitItem& )rSet.Get(SDRATTR_MEASUREUNIT )).GetValue(); + rRec.aMeasureScale =((SdrMeasureScaleItem& )rSet.Get(SDRATTR_MEASURESCALE )).GetValue(); + rRec.bShowUnit =((SdrMeasureShowUnitItem& )rSet.Get(SDRATTR_MEASURESHOWUNIT )).GetValue(); + rRec.aFormatString =((SdrMeasureFormatStringItem& )rSet.Get(SDRATTR_MEASUREFORMATSTRING )).GetValue(); + rRec.bTextAutoAngle =((SdrMeasureTextAutoAngleItem& )rSet.Get(SDRATTR_MEASURETEXTAUTOANGLE )).GetValue(); + rRec.nTextAutoAngleView=((SdrMeasureTextAutoAngleViewItem&)rSet.Get(SDRATTR_MEASURETEXTAUTOANGLEVIEW)).GetValue(); + rRec.bTextIsFixedAngle =((SdrMeasureTextIsFixedAngleItem& )rSet.Get(SDRATTR_MEASURETEXTISFIXEDANGLE )).GetValue(); + rRec.nTextFixedAngle =((SdrMeasureTextFixedAngleItem& )rSet.Get(SDRATTR_MEASURETEXTFIXEDANGLE )).GetValue(); +} + +long impGetLineStartEndDistance(const basegfx::B2DPolyPolygon& rPolyPolygon, long nNewWidth, bool bCenter) +{ + const basegfx::B2DRange aPolygonRange(rPolyPolygon.getB2DRange()); + const double fOldWidth(aPolygonRange.getWidth() > 1.0 ? aPolygonRange.getWidth() : 1.0); + const double fScale((double)nNewWidth / fOldWidth); + long nHeight(basegfx::fround(aPolygonRange.getHeight() * fScale)); + + if(bCenter) + { + nHeight /= 2L; + } + + return nHeight; +} + +void SdrMeasureObj::ImpCalcGeometrics(const ImpMeasureRec& rRec, ImpMeasurePoly& rPol) const +{ + Point aP1(rRec.aPt1); + Point aP2(rRec.aPt2); + Point aDelt(aP2); aDelt-=aP1; + + rPol.aTextSize=GetTextSize(); + rPol.nLineLen=GetLen(aDelt); + + rPol.nLineWdt2=0; + long nArrow1Len=0; bool bArrow1Center=false; + long nArrow2Len=0; bool bArrow2Center=false; + long nArrow1Wdt=0; + long nArrow2Wdt=0; + rPol.nArrow1Wdt=0; + rPol.nArrow2Wdt=0; + long nArrowNeed=0; + long nShortLen=0; + FASTBOOL bPfeileAussen=FALSE; + + const SfxItemSet& rSet = GetObjectItemSet(); + sal_Int32 nLineWdt = ((XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); // Strichstaerke + rPol.nLineWdt2 = (nLineWdt + 1) / 2; + + nArrow1Wdt = ((const XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue(); + if(nArrow1Wdt < 0) + nArrow1Wdt = -nLineWdt * nArrow1Wdt / 100; // <0 = relativ + + nArrow2Wdt = ((const XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue(); + if(nArrow2Wdt < 0) + nArrow2Wdt = -nLineWdt * nArrow2Wdt / 100; // <0 = relativ + + basegfx::B2DPolyPolygon aPol1(((const XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue()); + basegfx::B2DPolyPolygon aPol2(((const XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue()); + bArrow1Center = ((const XLineStartCenterItem&)(rSet.Get(XATTR_LINESTARTCENTER))).GetValue(); + bArrow2Center = ((const XLineEndCenterItem&)(rSet.Get(XATTR_LINEENDCENTER))).GetValue(); + nArrow1Len = impGetLineStartEndDistance(aPol1, nArrow1Wdt, bArrow1Center) - 1; + nArrow2Len = impGetLineStartEndDistance(aPol2, nArrow2Wdt, bArrow2Center) - 1; + + // nArrowLen ist bei bCenter bereits halbiert + // Bei 2 Pfeilen a 4mm ist unter 10mm Schluss. + nArrowNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2; + if (rPol.nLineLen<nArrowNeed) bPfeileAussen=TRUE; + nShortLen=(nArrow1Len+nArrow1Wdt + nArrow2Len+nArrow2Wdt) /2; + + rPol.eUsedTextHPos=rRec.eWantTextHPos; + rPol.eUsedTextVPos=rRec.eWantTextVPos; + if (rPol.eUsedTextVPos==SDRMEASURE_TEXTVAUTO) rPol.eUsedTextVPos=SDRMEASURE_ABOVE; + FASTBOOL bBrkLine=rPol.eUsedTextVPos==SDRMEASURETEXT_BREAKEDLINE; + if (rPol.eUsedTextVPos==SDRMEASURETEXT_VERTICALCENTERED) + { + OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject(); + if (pOutlinerParaObject!=NULL && pOutlinerParaObject->GetTextObject().GetParagraphCount()==1) + { + bBrkLine=TRUE; // Unterbrochene Linie, wenn nur 1 Absatz. + } + } + rPol.bBreakedLine=bBrkLine; + if (rPol.eUsedTextHPos==SDRMEASURE_TEXTHAUTO) { // bei zu breitem Text diesen eventuell nach aussen schieben + FASTBOOL bOutside=FALSE; + long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height(); + if (nNeedSiz>rPol.nLineLen) bOutside=TRUE; // Text passt nicht in die Mitte + if (bBrkLine) { + if (nNeedSiz+nArrowNeed>rPol.nLineLen) bPfeileAussen=TRUE; // Text passt in die Mitte, wenn die Pfeile nach aussen kommen + } else { + long nSmallNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2/4; + if (nNeedSiz+nSmallNeed>rPol.nLineLen) bPfeileAussen=TRUE; // Text passt in die Mitte, wenn die Pfeile nach aussen kommen + } + rPol.eUsedTextHPos=bOutside ? SDRMEASURE_TEXTLEFTOUTSIDE : SDRMEASURE_TEXTINSIDE; + } + if (rPol.eUsedTextHPos!=SDRMEASURE_TEXTINSIDE) bPfeileAussen=TRUE; + rPol.nArrow1Wdt=nArrow1Wdt; + rPol.nArrow2Wdt=nArrow2Wdt; + rPol.nShortLineLen=nShortLen; + rPol.bPfeileAussen=bPfeileAussen; + rPol.nArrow1Len=nArrow1Len; + rPol.bArrow1Center=bArrow1Center; + rPol.nArrow2Len=nArrow2Len; + rPol.bArrow2Center=bArrow2Center; + + rPol.nLineWink=GetAngle(aDelt); + double a=rPol.nLineWink*nPi180; + double nLineSin=sin(a); + double nLineCos=cos(a); + rPol.nLineSin=nLineSin; + rPol.nLineCos=nLineCos; + + rPol.nTextWink=rPol.nLineWink; + if (rRec.bTextRota90) rPol.nTextWink+=9000; + + rPol.bAutoUpsideDown=FALSE; + if (rRec.bTextAutoAngle) { + long nTmpWink=NormAngle360(rPol.nTextWink-rRec.nTextAutoAngleView); + if (nTmpWink>=18000) { + rPol.nTextWink+=18000; + rPol.bAutoUpsideDown=TRUE; + } + } + + if (rRec.bTextUpsideDown) rPol.nTextWink+=18000; + rPol.nTextWink=NormAngle360(rPol.nTextWink); + rPol.nHlpWink=rPol.nLineWink+9000; + if (rRec.bBelowRefEdge) rPol.nHlpWink+=18000; + rPol.nHlpWink=NormAngle360(rPol.nHlpWink); + double nHlpSin=nLineCos; + double nHlpCos=-nLineSin; + if (rRec.bBelowRefEdge) { + nHlpSin=-nHlpSin; + nHlpCos=-nHlpCos; + } + rPol.nHlpSin=nHlpSin; + rPol.nHlpCos=nHlpCos; + + long nLineDist=rRec.nLineDist; + long nOverhang=rRec.nHelplineOverhang; + long nHelplineDist=rRec.nHelplineDist; + + long dx= Round(nLineDist*nHlpCos); + long dy=-Round(nLineDist*nHlpSin); + long dxh1a= Round((nHelplineDist-rRec.nHelpline1Len)*nHlpCos); + long dyh1a=-Round((nHelplineDist-rRec.nHelpline1Len)*nHlpSin); + long dxh1b= Round((nHelplineDist-rRec.nHelpline2Len)*nHlpCos); + long dyh1b=-Round((nHelplineDist-rRec.nHelpline2Len)*nHlpSin); + long dxh2= Round((nLineDist+nOverhang)*nHlpCos); + long dyh2=-Round((nLineDist+nOverhang)*nHlpSin); + + // Masshilfslinie 1 + rPol.aHelpline1.aP1=Point(aP1.X()+dxh1a,aP1.Y()+dyh1a); + rPol.aHelpline1.aP2=Point(aP1.X()+dxh2,aP1.Y()+dyh2); + + // Masshilfslinie 2 + rPol.aHelpline2.aP1=Point(aP2.X()+dxh1b,aP2.Y()+dyh1b); + rPol.aHelpline2.aP2=Point(aP2.X()+dxh2,aP2.Y()+dyh2); + + // Masslinie(n) + Point aMainlinePt1(aP1.X()+dx,aP1.Y()+dy); + Point aMainlinePt2(aP2.X()+dx,aP2.Y()+dy); + if (!bPfeileAussen) { + rPol.aMainline1.aP1=aMainlinePt1; + rPol.aMainline1.aP2=aMainlinePt2; + rPol.aMainline2=rPol.aMainline1; + rPol.aMainline3=rPol.aMainline1; + rPol.nMainlineAnz=1; + if (bBrkLine) { + long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height(); + long nHalfLen=(rPol.nLineLen-nNeedSiz-nArrow1Wdt/4-nArrow2Wdt/4) /2; + rPol.nMainlineAnz=2; + rPol.aMainline1.aP2=aMainlinePt1; + rPol.aMainline1.aP2.X()+=nHalfLen; + RotatePoint(rPol.aMainline1.aP2,rPol.aMainline1.aP1,nLineSin,nLineCos); + rPol.aMainline2.aP1=aMainlinePt2; + rPol.aMainline2.aP1.X()-=nHalfLen; + RotatePoint(rPol.aMainline2.aP1,rPol.aMainline2.aP2,nLineSin,nLineCos); + } + } else { + long nLen1=nShortLen; // Pfeilbreite als Linienlaenge ausserhalb des Pfeils + long nLen2=nShortLen; + long nTextWdt=rRec.bTextRota90 ? rPol.aTextSize.Height() : rPol.aTextSize.Width(); + if (!bBrkLine) { + if (rPol.eUsedTextHPos==SDRMEASURE_TEXTLEFTOUTSIDE) nLen1=nArrow1Len+nTextWdt; + if (rPol.eUsedTextHPos==SDRMEASURE_TEXTRIGHTOUTSIDE) nLen2=nArrow2Len+nTextWdt; + } + rPol.aMainline1.aP1=aMainlinePt1; + rPol.aMainline1.aP2=aMainlinePt1; rPol.aMainline1.aP2.X()-=nLen1; RotatePoint(rPol.aMainline1.aP2,aMainlinePt1,nLineSin,nLineCos); + rPol.aMainline2.aP1=aMainlinePt2; rPol.aMainline2.aP1.X()+=nLen2; RotatePoint(rPol.aMainline2.aP1,aMainlinePt2,nLineSin,nLineCos); + rPol.aMainline2.aP2=aMainlinePt2; + rPol.aMainline3.aP1=aMainlinePt1; + rPol.aMainline3.aP2=aMainlinePt2; + rPol.nMainlineAnz=3; + if (bBrkLine && rPol.eUsedTextHPos==SDRMEASURE_TEXTINSIDE) rPol.nMainlineAnz=2; + } +} + +basegfx::B2DPolyPolygon SdrMeasureObj::ImpCalcXPoly(const ImpMeasurePoly& rPol) const +{ + basegfx::B2DPolyPolygon aRetval; + basegfx::B2DPolygon aPartPolyA; + aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP1.X(), rPol.aMainline1.aP1.Y())); + aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP2.X(), rPol.aMainline1.aP2.Y())); + aRetval.append(aPartPolyA); + + if(rPol.nMainlineAnz > 1) + { + aPartPolyA.clear(); + aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP1.X(), rPol.aMainline2.aP1.Y())); + aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP2.X(), rPol.aMainline2.aP2.Y())); + aRetval.append(aPartPolyA); + } + + if(rPol.nMainlineAnz > 2) + { + aPartPolyA.clear(); + aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP1.X(), rPol.aMainline3.aP1.Y())); + aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP2.X(), rPol.aMainline3.aP2.Y())); + aRetval.append(aPartPolyA); + } + + aPartPolyA.clear(); + aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP1.X(), rPol.aHelpline1.aP1.Y())); + aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP2.X(), rPol.aHelpline1.aP2.Y())); + aRetval.append(aPartPolyA); + + aPartPolyA.clear(); + aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP1.X(), rPol.aHelpline2.aP1.Y())); + aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP2.X(), rPol.aHelpline2.aP2.Y())); + aRetval.append(aPartPolyA); + + return aRetval; +} + +FASTBOOL SdrMeasureObj::CalcFieldValue(const SvxFieldItem& rField, USHORT nPara, USHORT nPos, + FASTBOOL bEdit, + Color*& rpTxtColor, Color*& rpFldColor, XubString& rRet) const +{ + const SvxFieldData* pField=rField.GetField(); + SdrMeasureField* pMeasureField=PTR_CAST(SdrMeasureField,pField); + if (pMeasureField!=NULL) { + TakeRepresentation(rRet, pMeasureField->GetMeasureFieldKind()); + if (rpFldColor!=NULL) { + if (!bEdit) + { + delete rpFldColor; + rpFldColor=NULL; + } + } + return TRUE; + } else { + return SdrTextObj::CalcFieldValue(rField,nPara,nPos,bEdit,rpTxtColor,rpFldColor,rRet); + } +} + +void SdrMeasureObj::UndirtyText() const +{ + if (bTextDirty) + { + SdrOutliner& rOutliner=ImpGetDrawOutliner(); + OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject(); + if(pOutlinerParaObject==NULL) + { + rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD), ESelection(0,0)); + rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_VALUE), EE_FEATURE_FIELD),ESelection(0,1)); + rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_UNIT), EE_FEATURE_FIELD),ESelection(0,2)); + rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD),ESelection(0,3)); + + if(GetStyleSheet()) + rOutliner.SetStyleSheet(0, GetStyleSheet()); + + rOutliner.SetParaAttribs(0, GetObjectItemSet()); + + // casting auf nonconst + const_cast<SdrMeasureObj*>(this)->NbcSetOutlinerParaObject( rOutliner.CreateParaObject() ); + } + else + { + rOutliner.SetText(*pOutlinerParaObject); + } + + rOutliner.SetUpdateMode(TRUE); + rOutliner.UpdateFields(); + Size aSiz(rOutliner.CalcTextSize()); + rOutliner.Clear(); + // 3x casting auf nonconst + ((SdrMeasureObj*)this)->aTextSize=aSiz; + ((SdrMeasureObj*)this)->bTextSizeDirty=FALSE; + ((SdrMeasureObj*)this)->bTextDirty=FALSE; + } +} + +void SdrMeasureObj::TakeUnrotatedSnapRect(Rectangle& rRect) const +{ + if (bTextDirty) UndirtyText(); + ImpMeasureRec aRec; + ImpMeasurePoly aMPol; + ImpTakeAttr(aRec); + ImpCalcGeometrics(aRec,aMPol); + + // TextSize ermitteln inkl. Textrahmenabstaende + Size aTextSize2(aMPol.aTextSize); + if (aTextSize2.Width()<1) aTextSize2.Width()=1; + if (aTextSize2.Height()<1) aTextSize2.Height()=1; + aTextSize2.Width()+=GetTextLeftDistance()+GetTextRightDistance(); + aTextSize2.Height()+=GetTextUpperDistance()+GetTextLowerDistance(); + + Point aPt1b(aMPol.aMainline1.aP1); + long nLen=aMPol.nLineLen; + long nLWdt=aMPol.nLineWdt2; + long nArr1Len=aMPol.nArrow1Len; + long nArr2Len=aMPol.nArrow2Len; + if (aMPol.bBreakedLine) { + // Bei Unterbrochener Linie und Outside muss der Text nicht neben den + // Pfeil sondern neben die Linie an dem Pfeil plaziert werden + nArr1Len=aMPol.nShortLineLen+aMPol.nArrow1Wdt/4; + nArr2Len=aMPol.nShortLineLen+aMPol.nArrow2Wdt/4; + } + + Point aTextPos; + FASTBOOL bRota90=aRec.bTextRota90; + FASTBOOL bUpsideDown=aRec.bTextUpsideDown!=aMPol.bAutoUpsideDown; + FASTBOOL bBelowRefEdge=aRec.bBelowRefEdge; + SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos; + SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos; + if (!bRota90) { + switch (eMH) { + case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Width()-nArr1Len-nLWdt; break; + case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len+nLWdt; break; + default: aTextPos.X()=aPt1b.X(); aTextSize2.Width()=nLen; + } + switch (eMV) { + case SDRMEASURETEXT_VERTICALCENTERED: + case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()/2; break; + case SDRMEASURE_BELOW: { + if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()+nLWdt; + else aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt; + } break; + default: { + if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt; + else aTextPos.Y()=aPt1b.Y()+nLWdt; + } + } + if (bUpsideDown) { + aTextPos.X()+=aTextSize2.Width(); + aTextPos.Y()+=aTextSize2.Height(); + } + } else { // also wenn bTextRota90==TRUE + switch (eMH) { + case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Height()-nArr1Len; break; + case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len; break; + default: aTextPos.X()=aPt1b.X(); aTextSize2.Height()=nLen; + } + switch (eMV) { + case SDRMEASURETEXT_VERTICALCENTERED: + case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()/2; break; + case SDRMEASURE_BELOW: { + if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt; + else aTextPos.Y()=aPt1b.Y()-nLWdt; + } break; + default: { + if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()-nLWdt; + else aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt; + } + } + if (bUpsideDown) { + aTextPos.X()+=aTextSize2.Height(); + aTextPos.Y()-=aTextSize2.Width(); + } + } + if (aMPol.nTextWink!=aGeo.nDrehWink) { + ((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink; + ((SdrMeasureObj*)this)->aGeo.RecalcSinCos(); + } + RotatePoint(aTextPos,aPt1b,aMPol.nLineSin,aMPol.nLineCos); + aTextSize2.Width()++; aTextSize2.Height()++; // wg. des komischen Verhaltens beim Rect-Ctor + rRect=Rectangle(aTextPos,aTextSize2); + rRect.Justify(); + ((SdrMeasureObj*)this)->aRect=rRect; + + if (aMPol.nTextWink!=aGeo.nDrehWink) { + ((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink; + ((SdrMeasureObj*)this)->aGeo.RecalcSinCos(); + } +} + +void SdrMeasureObj::operator=(const SdrObject& rObj) +{ + SdrTextObj::operator=(rObj); + aPt1=((SdrMeasureObj&)rObj).aPt1; + aPt2=((SdrMeasureObj&)rObj).aPt2; + bTextDirty=((SdrMeasureObj&)rObj).bTextDirty; +} + +void SdrMeasureObj::TakeObjNameSingul(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNameSingulMEASURE); + + String aName( GetName() ); + if(aName.Len()) + { + rName += sal_Unicode(' '); + rName += sal_Unicode('\''); + rName += aName; + rName += sal_Unicode('\''); + } +} + +void SdrMeasureObj::TakeObjNamePlural(XubString& rName) const +{ + rName=ImpGetResStr(STR_ObjNamePluralMEASURE); +} + +basegfx::B2DPolyPolygon SdrMeasureObj::TakeXorPoly() const +{ + ImpMeasureRec aRec; + ImpMeasurePoly aMPol; + ImpTakeAttr(aRec); + ImpCalcGeometrics(aRec,aMPol); + return ImpCalcXPoly(aMPol); +} + +sal_uInt32 SdrMeasureObj::GetHdlCount() const +{ + return 6L; +} + +SdrHdl* SdrMeasureObj::GetHdl(sal_uInt32 nHdlNum) const +{ + ImpMeasureRec aRec; + ImpMeasurePoly aMPol; + ImpTakeAttr(aRec); + aRec.nHelplineDist=0; + ImpCalcGeometrics(aRec,aMPol); + Point aPt; + //SdrHdlKind eHdl=HDL_POLY; + switch (nHdlNum) { + case 0: aPt=aMPol.aHelpline1.aP1; break; + case 1: aPt=aMPol.aHelpline2.aP1; break; + case 2: aPt=aPt1; break; + case 3: aPt=aPt2; break; + case 4: aPt=aMPol.aHelpline1.aP2; break; + case 5: aPt=aMPol.aHelpline2.aP2; break; + } // switch + SdrHdl* pHdl=new ImpMeasureHdl(aPt,HDL_USER); + pHdl->SetObjHdlNum(nHdlNum); + pHdl->SetDrehWink(aMPol.nLineWink); + return pHdl; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +bool SdrMeasureObj::hasSpecialDrag() const +{ + return true; +} + +bool SdrMeasureObj::beginSpecialDrag(SdrDragStat& rDrag) const +{ + const SdrHdl* pHdl = rDrag.GetHdl(); + + if(pHdl) + { + const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum()); + + if(nHdlNum != 2 && nHdlNum != 3) + { + rDrag.SetEndDragChangesAttributes(true); + } + + return true; + } + + return false; +} + +bool SdrMeasureObj::applySpecialDrag(SdrDragStat& rDrag) +{ + ImpMeasureRec aMeasureRec; + const SdrHdl* pHdl = rDrag.GetHdl(); + const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum()); + + ImpTakeAttr(aMeasureRec); + ImpEvalDrag(aMeasureRec, rDrag); + + switch (nHdlNum) + { + case 2: + { + aPt1 = aMeasureRec.aPt1; + SetTextDirty(); + break; + } + case 3: + { + aPt2 = aMeasureRec.aPt2; + SetTextDirty(); + break; + } + default: + { + switch(nHdlNum) + { + case 0: + case 1: + { + ImpMeasureRec aOrigMeasureRec; + ImpTakeAttr(aOrigMeasureRec); + + if(aMeasureRec.nHelpline1Len != aOrigMeasureRec.nHelpline1Len) + { + SetObjectItem(SdrMeasureHelpline1LenItem(aMeasureRec.nHelpline1Len)); + } + + if(aMeasureRec.nHelpline2Len != aOrigMeasureRec.nHelpline2Len) + { + SetObjectItem(SdrMeasureHelpline2LenItem(aMeasureRec.nHelpline2Len)); + } + + break; + } + + case 4: + case 5: + { + ImpMeasureRec aOrigMeasureRec; + ImpTakeAttr(aOrigMeasureRec); + + if(aMeasureRec.nLineDist != aOrigMeasureRec.nLineDist) + { + SetObjectItem(SdrMeasureLineDistItem(aMeasureRec.nLineDist)); + } + + if(aMeasureRec.bBelowRefEdge != aOrigMeasureRec.bBelowRefEdge) + { + SetObjectItem(SdrMeasureBelowRefEdgeItem(aMeasureRec.bBelowRefEdge)); + } + } + } + } + } // switch + + SetRectsDirty(); + SetChanged(); + + return true; +} + +String SdrMeasureObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const +{ + XubString aStr; + return aStr; +} + +void SdrMeasureObj::ImpEvalDrag(ImpMeasureRec& rRec, const SdrDragStat& rDrag) const +{ + long nLineWink=GetAngle(rRec.aPt2-rRec.aPt1); + double a=nLineWink*nPi180; + double nSin=sin(a); + double nCos=cos(a); + + const SdrHdl* pHdl=rDrag.GetHdl(); + sal_uInt32 nHdlNum(pHdl->GetObjHdlNum()); + FASTBOOL bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho(); + FASTBOOL bBigOrtho=bOrtho && rDrag.GetView()->IsBigOrtho(); + FASTBOOL bBelow=rRec.bBelowRefEdge; + Point aPt(rDrag.GetNow()); + + switch (nHdlNum) { + case 0: { + RotatePoint(aPt,aPt1,nSin,-nCos); + rRec.nHelpline1Len=aPt1.Y()-aPt.Y(); + if (bBelow) rRec.nHelpline1Len=-rRec.nHelpline1Len; + if (bOrtho) rRec.nHelpline2Len=rRec.nHelpline1Len; + } break; + case 1: { + RotatePoint(aPt,aPt2,nSin,-nCos); + rRec.nHelpline2Len=aPt2.Y()-aPt.Y(); + if (bBelow) rRec.nHelpline2Len=-rRec.nHelpline2Len; + if (bOrtho) rRec.nHelpline1Len=rRec.nHelpline2Len; + } break; + case 2: case 3: { + FASTBOOL bAnf=nHdlNum==2; + Point& rMov=bAnf ? rRec.aPt1 : rRec.aPt2; + Point aMov(rMov); + Point aFix(bAnf ? rRec.aPt2 : rRec.aPt1); + if (bOrtho) { + long ndx0=aMov.X()-aFix.X(); + long ndy0=aMov.Y()-aFix.Y(); + FASTBOOL bHLin=ndy0==0; + FASTBOOL bVLin=ndx0==0; + if (!bHLin || !bVLin) { // sonst ist aPt1==aPt2 + long ndx=aPt.X()-aFix.X(); + long ndy=aPt.Y()-aFix.Y(); + 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); + aPt=aFix; + aPt.X()+=ndx; + aPt.Y()+=ndy; + } // else Ortho8 + } + rMov=aPt; + } break; + case 4: case 5: { + long nVal0=rRec.nLineDist; + RotatePoint(aPt,(nHdlNum==4 ? aPt1 : aPt2),nSin,-nCos); + rRec.nLineDist=aPt.Y()- (nHdlNum==4 ? aPt1.Y() : aPt2.Y()); + if (bBelow) rRec.nLineDist=-rRec.nLineDist; + if (rRec.nLineDist<0) { + rRec.nLineDist=-rRec.nLineDist; + rRec.bBelowRefEdge=!bBelow; + } + rRec.nLineDist-=rRec.nHelplineOverhang; + if (bOrtho) rRec.nLineDist=nVal0; + } break; + } // switch +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +FASTBOOL SdrMeasureObj::BegCreate(SdrDragStat& rStat) +{ + rStat.SetOrtho8Possible(); + aPt1=rStat.GetStart(); + aPt2=rStat.GetNow(); + SetTextDirty(); + return TRUE; +} + +FASTBOOL SdrMeasureObj::MovCreate(SdrDragStat& rStat) +{ + SdrView* pView=rStat.GetView(); + aPt1=rStat.GetStart(); + aPt2=rStat.GetNow(); + if (pView!=NULL && pView->IsCreate1stPointAsCenter()) { + aPt1+=aPt1; + aPt1-=rStat.Now(); + } + SetTextDirty(); + SetBoundRectDirty(); + bSnapRectDirty=TRUE; + return TRUE; +} + +FASTBOOL SdrMeasureObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) +{ + SetTextDirty(); + SetRectsDirty(); + return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2); +} + +FASTBOOL SdrMeasureObj::BckCreate(SdrDragStat& /*rStat*/) +{ + return FALSE; +} + +void SdrMeasureObj::BrkCreate(SdrDragStat& /*rStat*/) +{ +} + +basegfx::B2DPolyPolygon SdrMeasureObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const +{ + ImpMeasureRec aRec; + ImpMeasurePoly aMPol; + + ImpTakeAttr(aRec); + ImpCalcGeometrics(aRec, aMPol); + + return ImpCalcXPoly(aMPol); +} + +Pointer SdrMeasureObj::GetCreatePointer() const +{ + return Pointer(POINTER_CROSS); +} + +void SdrMeasureObj::NbcMove(const Size& rSiz) +{ + SdrTextObj::NbcMove(rSiz); + MovePoint(aPt1,rSiz); + MovePoint(aPt2,rSiz); +} + +void SdrMeasureObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact) +{ + SdrTextObj::NbcResize(rRef,xFact,yFact); + ResizePoint(aPt1,rRef,xFact,yFact); + ResizePoint(aPt2,rRef,xFact,yFact); + SetTextDirty(); +} + +void SdrMeasureObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs) +{ + SdrTextObj::NbcRotate(rRef,nWink,sn,cs); + long nLen0=GetLen(aPt2-aPt1); + RotatePoint(aPt1,rRef,sn,cs); + RotatePoint(aPt2,rRef,sn,cs); + long nLen1=GetLen(aPt2-aPt1); + if (nLen1!=nLen0) { // Aha, Rundungsfehler + long dx=aPt2.X()-aPt1.X(); + long dy=aPt2.Y()-aPt1.Y(); + dx=BigMulDiv(dx,nLen0,nLen1); + dy=BigMulDiv(dy,nLen0,nLen1); + if (rRef==aPt2) { + aPt1.X()=aPt2.X()-dx; + aPt1.Y()=aPt2.Y()-dy; + } else { + aPt2.X()=aPt1.X()+dx; + aPt2.Y()=aPt1.Y()+dy; + } + } + SetRectsDirty(); +} + +void SdrMeasureObj::NbcMirror(const Point& rRef1, const Point& rRef2) +{ + SdrTextObj::NbcMirror(rRef1,rRef2); + MirrorPoint(aPt1,rRef1,rRef2); + MirrorPoint(aPt2,rRef1,rRef2); + SetRectsDirty(); +} + +void SdrMeasureObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear) +{ + SdrTextObj::NbcShear(rRef,nWink,tn,bVShear); + ShearPoint(aPt1,rRef,tn,bVShear); + ShearPoint(aPt2,rRef,tn,bVShear); + SetRectsDirty(); + SetTextDirty(); +} + +long SdrMeasureObj::GetRotateAngle() const +{ + return GetAngle(aPt2-aPt1); +} + +void SdrMeasureObj::RecalcSnapRect() +{ + // #94520# Added correct implementation here. + ImpMeasureRec aRec; + ImpMeasurePoly aMPol; + XPolyPolygon aXPP; + + ImpTakeAttr(aRec); + ImpCalcGeometrics(aRec, aMPol); + aXPP = XPolyPolygon(ImpCalcXPoly(aMPol)); + maSnapRect = aXPP.GetBoundRect(); +} + +sal_uInt32 SdrMeasureObj::GetSnapPointCount() const +{ + return 2L; +} + +Point SdrMeasureObj::GetSnapPoint(sal_uInt32 i) const +{ + if (i==0) return aPt1; + else return aPt2; +} + +sal_Bool SdrMeasureObj::IsPolyObj() const +{ + return sal_True; +} + +sal_uInt32 SdrMeasureObj::GetPointCount() const +{ + return 2L; +} + +Point SdrMeasureObj::GetPoint(sal_uInt32 i) const +{ + return (0L == i) ? aPt1 : aPt2; +} + +void SdrMeasureObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i) +{ + if (0L == i) + aPt1=rPnt; + if (1L == i) + aPt2=rPnt; + SetRectsDirty(); + SetTextDirty(); +} + +SdrObjGeoData* SdrMeasureObj::NewGeoData() const +{ + return new SdrMeasureObjGeoData; +} + +void SdrMeasureObj::SaveGeoData(SdrObjGeoData& rGeo) const +{ + SdrTextObj::SaveGeoData(rGeo); + SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo; + rMGeo.aPt1=aPt1; + rMGeo.aPt2=aPt2; +} + +void SdrMeasureObj::RestGeoData(const SdrObjGeoData& rGeo) +{ + SdrTextObj::RestGeoData(rGeo); + SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo; + aPt1=rMGeo.aPt1; + aPt2=rMGeo.aPt2; + SetTextDirty(); +} + +SdrObject* SdrMeasureObj::DoConvertToPolyObj(BOOL bBezier) const +{ + // get XOR Poly as base + XPolyPolygon aTmpPolyPolygon(TakeXorPoly()); + + // get local ItemSet and StyleSheet + SfxItemSet aSet(GetObjectItemSet()); + SfxStyleSheet* pStyleSheet = GetStyleSheet(); + + // prepare group + SdrObjGroup* pGroup = new SdrObjGroup; + pGroup->SetModel(GetModel()); + + // prepare parameters + basegfx::B2DPolyPolygon aPolyPoly; + SdrPathObj* pPath; + UINT16 nCount(aTmpPolyPolygon.Count()); + UINT16 nLoopStart(0); + + if(nCount == 3) + { + // three lines, first one is the middle one + aPolyPoly.clear(); + aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon()); + + pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly); + pPath->SetModel(GetModel()); + pPath->SetMergedItemSet(aSet); + pPath->SetStyleSheet(pStyleSheet, true); + pGroup->GetSubList()->NbcInsertObject(pPath); + aSet.Put(XLineStartWidthItem(0L)); + aSet.Put(XLineEndWidthItem(0L)); + nLoopStart = 1; + } + else if(nCount == 4) + { + // four lines, middle line with gap, so there are two lines used + // which have one arrow each + //INT32 nStartWidth = ((const XLineStartWidthItem&)(aSet.Get(XATTR_LINESTARTWIDTH))).GetValue(); + INT32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue(); + aSet.Put(XLineEndWidthItem(0L)); + + aPolyPoly.clear(); + aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon()); + pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly); + pPath->SetModel(GetModel()); + pPath->SetMergedItemSet(aSet); + pPath->SetStyleSheet(pStyleSheet, true); + + pGroup->GetSubList()->NbcInsertObject(pPath); + + aSet.Put(XLineEndWidthItem(nEndWidth)); + aSet.Put(XLineStartWidthItem(0L)); + + aPolyPoly.clear(); + aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon()); + pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly); + pPath->SetModel(GetModel()); + pPath->SetMergedItemSet(aSet); + pPath->SetStyleSheet(pStyleSheet, true); + + pGroup->GetSubList()->NbcInsertObject(pPath); + + aSet.Put(XLineEndWidthItem(0L)); + nLoopStart = 2; + } + else if(nCount == 5) + { + // five lines, first two are the outer ones + //INT32 nStartWidth = ((const XLineStartWidthItem&)(aSet.Get(XATTR_LINESTARTWIDTH))).GetValue(); + INT32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue(); + + aSet.Put(XLineEndWidthItem(0L)); + + aPolyPoly.clear(); + aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon()); + pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly); + pPath->SetModel(GetModel()); + pPath->SetMergedItemSet(aSet); + pPath->SetStyleSheet(pStyleSheet, true); + + pGroup->GetSubList()->NbcInsertObject(pPath); + + aSet.Put(XLineEndWidthItem(nEndWidth)); + aSet.Put(XLineStartWidthItem(0L)); + + aPolyPoly.clear(); + aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon()); + pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly); + pPath->SetModel(GetModel()); + pPath->SetMergedItemSet(aSet); + pPath->SetStyleSheet(pStyleSheet, true); + + pGroup->GetSubList()->NbcInsertObject(pPath); + + aSet.Put(XLineEndWidthItem(0L)); + nLoopStart = 2; + } + + for(;nLoopStart<nCount;nLoopStart++) + { + aPolyPoly.clear(); + aPolyPoly.append(aTmpPolyPolygon[nLoopStart].getB2DPolygon()); + pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly); + pPath->SetModel(GetModel()); + pPath->SetMergedItemSet(aSet); + pPath->SetStyleSheet(pStyleSheet, true); + + pGroup->GetSubList()->NbcInsertObject(pPath); + } + + return ImpConvertAddText(pGroup, bBezier); +} + +sal_Bool SdrMeasureObj::BegTextEdit(SdrOutliner& rOutl) +{ + UndirtyText(); + return SdrTextObj::BegTextEdit(rOutl); +} + +const Size& SdrMeasureObj::GetTextSize() const +{ + if (bTextDirty) UndirtyText(); + return SdrTextObj::GetTextSize(); +} + +OutlinerParaObject* SdrMeasureObj::GetOutlinerParaObject() const +{ + if(bTextDirty) + UndirtyText(); + return SdrTextObj::GetOutlinerParaObject(); +} + +void SdrMeasureObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject) +{ + SdrTextObj::NbcSetOutlinerParaObject(pTextObject); + if(SdrTextObj::GetOutlinerParaObject()) + SetTextDirty(); // Text neu berechnen! +} + +void SdrMeasureObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText, + Rectangle* pAnchorRect, BOOL bLineWidth ) const +{ + if (bTextDirty) UndirtyText(); + SdrTextObj::TakeTextRect( rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth ); +} + +void SdrMeasureObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const +{ + if (bTextDirty) UndirtyText(); + SdrTextObj::TakeTextAnchorRect(rAnchorRect); +} + +void SdrMeasureObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const +{ + if (bTextDirty) UndirtyText(); + SdrTextObj::TakeTextEditArea(pPaperMin,pPaperMax,pViewInit,pViewMin); +} + +USHORT SdrMeasureObj::GetOutlinerViewAnchorMode() const +{ + if (bTextDirty) UndirtyText(); + ImpMeasureRec aRec; + ImpMeasurePoly aMPol; + ImpTakeAttr(aRec); + ImpCalcGeometrics(aRec,aMPol); + + SdrTextHorzAdjust eTH=GetTextHorizontalAdjust(); + SdrTextVertAdjust eTV=GetTextVerticalAdjust(); + SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos; + SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos; + FASTBOOL bTextRota90=aRec.bTextRota90; + //FASTBOOL bTextUpsideDown=aRec.bTextUpsideDown; + FASTBOOL bBelowRefEdge=aRec.bBelowRefEdge; + + // bTextUpsideDown muss hier noch ausgewertet werden!!!! + if (!bTextRota90) { + if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTH=SDRTEXTHORZADJUST_RIGHT; + if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTH=SDRTEXTHORZADJUST_LEFT; + // bei eMH==SDRMEASURE_TEXTINSIDE kann horizontal geankert werden. + if (eMV==SDRMEASURE_ABOVE) eTV=SDRTEXTVERTADJUST_BOTTOM; + if (eMV==SDRMEASURE_BELOW) eTV=SDRTEXTVERTADJUST_TOP; + if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTV=SDRTEXTVERTADJUST_CENTER; + } else { + if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTV=SDRTEXTVERTADJUST_BOTTOM; + if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTV=SDRTEXTVERTADJUST_TOP; + // bei eMH==SDRMEASURE_TEXTINSIDE kann vertikal geankert werden. + if (!bBelowRefEdge) { + if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_LEFT; + if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_RIGHT; + } else { + if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_RIGHT; + if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_LEFT; + } + if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTH=SDRTEXTHORZADJUST_CENTER; + } + + EVAnchorMode eRet=ANCHOR_BOTTOM_HCENTER; + if (eTH==SDRTEXTHORZADJUST_LEFT) { + if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_LEFT; + else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_LEFT; + else eRet=ANCHOR_VCENTER_LEFT; + } else if (eTH==SDRTEXTHORZADJUST_RIGHT) { + if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_RIGHT; + else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_RIGHT; + else eRet=ANCHOR_VCENTER_RIGHT; + } else { + if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_HCENTER; + else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_HCENTER; + else eRet=ANCHOR_VCENTER_HCENTER; + } + return (USHORT)eRet; +} + +////////////////////////////////////////////////////////////////////////////// +// #i97878# +// TRGetBaseGeometry/TRSetBaseGeometry needs to be based on two positions, +// same as line geometry in SdrPathObj. Thus needs to be overloaded and +// implemented since currently it is derived from SdrTextObj which uses +// a functionality based on SnapRect which is not useful here + +inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); } +inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); } + +sal_Bool SdrMeasureObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const +{ + // handle the same as a simple line since the definition is based on two points + const basegfx::B2DRange aRange(aPt1.X(), aPt1.Y(), aPt2.X(), aPt2.Y()); + basegfx::B2DTuple aScale(aRange.getRange()); + basegfx::B2DTuple aTranslate(aRange.getMinimum()); + + // position maybe relative to anchorpos, convert + if( pModel->IsWriter() ) + { + if(GetAnchorPos().X() || GetAnchorPos().Y()) + { + aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y()); + } + } + + // force MapUnit to 100th mm + SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0); + if(eMapUnit != SFX_MAPUNIT_100TH_MM) + { + switch(eMapUnit) + { + case SFX_MAPUNIT_TWIP : + { + // postion + aTranslate.setX(ImplTwipsToMM(aTranslate.getX())); + aTranslate.setY(ImplTwipsToMM(aTranslate.getY())); + + // size + aScale.setX(ImplTwipsToMM(aScale.getX())); + aScale.setY(ImplTwipsToMM(aScale.getY())); + + break; + } + default: + { + DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!"); + } + } + } + + // build return value matrix + rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate); + + return sal_True; +} + +void SdrMeasureObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/) +{ + // use given transformation to derive the two defining points from unit line + basegfx::B2DPoint aPosA(rMatrix * basegfx::B2DPoint(0.0, 0.0)); + basegfx::B2DPoint aPosB(rMatrix * basegfx::B2DPoint(1.0, 0.0)); + + // force metric to pool metric + SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0); + if(eMapUnit != SFX_MAPUNIT_100TH_MM) + { + switch(eMapUnit) + { + case SFX_MAPUNIT_TWIP : + { + // position + aPosA.setX(ImplMMToTwips(aPosA.getX())); + aPosA.setY(ImplMMToTwips(aPosA.getY())); + aPosB.setX(ImplMMToTwips(aPosB.getX())); + aPosB.setY(ImplMMToTwips(aPosB.getY())); + + break; + } + default: + { + DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!"); + } + } + } + + if( pModel->IsWriter() ) + { + // if anchor is used, make position relative to it + if(GetAnchorPos().X() || GetAnchorPos().Y()) + { + const basegfx::B2DVector aAnchorOffset(GetAnchorPos().X(), GetAnchorPos().Y()); + + aPosA += aAnchorOffset; + aPosB += aAnchorOffset; + } + } + + // derive new model data + const Point aNewPt1(basegfx::fround(aPosA.getX()), basegfx::fround(aPosA.getY())); + const Point aNewPt2(basegfx::fround(aPosB.getX()), basegfx::fround(aPosB.getY())); + + if(aNewPt1 != aPt1 || aNewPt2 != aPt2) + { + // set model values and broadcast + Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect(); + + aPt1 = aNewPt1; + aPt2 = aNewPt2; + + SetTextDirty(); + ActionChanged(); + SetChanged(); + BroadcastObjectChange(); + SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0); + } +} + +////////////////////////////////////////////////////////////////////////////// +// eof |