LCOV - code coverage report
Current view: top level - svx/source/svdraw - svdomeas.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 301 841 35.8 %
Date: 2014-04-11 Functions: 28 73 38.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "svdconv.hxx"
      21             : #include "svx/svdglob.hxx"
      22             : #include "svx/svdstr.hrc"
      23             : 
      24             : #include <basegfx/matrix/b2dhommatrix.hxx>
      25             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      26             : #include <basegfx/point/b2dpoint.hxx>
      27             : #include <basegfx/polygon/b2dpolygon.hxx>
      28             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      29             : #include <editeng/editdata.hxx>
      30             : #include <editeng/editobj.hxx>
      31             : #include <editeng/eeitem.hxx>
      32             : #include <editeng/flditem.hxx>
      33             : #include <editeng/measfld.hxx>
      34             : #include <editeng/outliner.hxx>
      35             : #include <editeng/outlobj.hxx>
      36             : #include <math.h>
      37             : #include <svl/smplhint.hxx>
      38             : #include <svl/style.hxx>
      39             : 
      40             : #include <svx/sdr/contact/viewcontactofsdrmeasureobj.hxx>
      41             : #include <svx/sdr/properties/measureproperties.hxx>
      42             : #include <svx/svddrag.hxx>
      43             : #include <svx/svdhdl.hxx>
      44             : #include <svx/svdmodel.hxx>
      45             : #include <svx/svdogrp.hxx>
      46             : #include <svx/svdomeas.hxx>
      47             : #include <svx/svdopath.hxx>
      48             : #include <svx/svdoutl.hxx>
      49             : #include <svx/svdpage.hxx>
      50             : #include <svx/svdpool.hxx>
      51             : #include <svx/svdtrans.hxx>
      52             : #include <svx/svdview.hxx>
      53             : #include <svx/sxmbritm.hxx>
      54             : #include <svx/sxmfsitm.hxx>
      55             : #include <svx/sxmkitm.hxx>
      56             : #include <svx/sxmlhitm.hxx>
      57             : #include <svx/sxmoitm.hxx>
      58             : #include <svx/sxmsitm.hxx>
      59             : #include <svx/sxmsuitm.hxx>
      60             : #include <svx/sxmtaitm.hxx>
      61             : #include <svx/sxmtfitm.hxx>
      62             : #include <svx/sxmtpitm.hxx>
      63             : #include <svx/sxmtritm.hxx>
      64             : #include <svx/sxmuitm.hxx>
      65             : #include <svx/xlnedcit.hxx>
      66             : #include <svx/xlnedit.hxx>
      67             : #include <svx/xlnedwit.hxx>
      68             : #include <svx/xlnstcit.hxx>
      69             : #include <svx/xlnstit.hxx>
      70             : #include <svx/xlnstwit.hxx>
      71             : #include <svx/xlnwtit.hxx>
      72             : #include <svx/xpoly.hxx>
      73             : #include <unotools/syslocale.hxx>
      74             : 
      75             : 
      76             : 
      77           0 : SdrMeasureObjGeoData::SdrMeasureObjGeoData() {}
      78           0 : SdrMeasureObjGeoData::~SdrMeasureObjGeoData() {}
      79             : 
      80          84 : OUString SdrMeasureObj::TakeRepresentation(SdrMeasureFieldKind eMeasureFieldKind) const
      81             : {
      82          84 :     OUString aStr;
      83          84 :     Fraction aMeasureScale(1, 1);
      84          84 :     sal_Bool bTextRota90(sal_False);
      85          84 :     sal_Bool bShowUnit(sal_False);
      86          84 :     FieldUnit eMeasureUnit(FUNIT_NONE);
      87          84 :     FieldUnit eModUIUnit(FUNIT_NONE);
      88             : 
      89          84 :     const SfxItemSet& rSet = GetMergedItemSet();
      90          84 :     bTextRota90 = ((SdrMeasureTextRota90Item&)rSet.Get(SDRATTR_MEASURETEXTROTA90)).GetValue();
      91          84 :     eMeasureUnit = ((SdrMeasureUnitItem&)rSet.Get(SDRATTR_MEASUREUNIT)).GetValue();
      92          84 :     aMeasureScale = ((SdrMeasureScaleItem&)rSet.Get(SDRATTR_MEASURESCALE)).GetValue();
      93          84 :     bShowUnit = ((SdrMeasureShowUnitItem&)rSet.Get(SDRATTR_MEASURESHOWUNIT)).GetValue();
      94          84 :     sal_Int16 nNumDigits = ((SdrMeasureDecimalPlacesItem&)rSet.Get(SDRATTR_MEASUREDECIMALPLACES)).GetValue();
      95             : 
      96          84 :     switch(eMeasureFieldKind)
      97             :     {
      98             :         case SDRMEASUREFIELD_VALUE:
      99             :         {
     100          21 :             if(pModel)
     101             :             {
     102          21 :                 eModUIUnit = pModel->GetUIUnit();
     103             : 
     104          21 :                 if(eMeasureUnit == FUNIT_NONE)
     105          21 :                     eMeasureUnit = eModUIUnit;
     106             : 
     107          21 :                 sal_Int32 nLen(GetLen(aPt2 - aPt1));
     108          21 :                 Fraction aFact(1,1);
     109             : 
     110          21 :                 if(eMeasureUnit != eModUIUnit)
     111             :                 {
     112             :                     // for the unit conversion
     113           0 :                     aFact *= GetMapFactor(eModUIUnit, eMeasureUnit).X();
     114             :                 }
     115             : 
     116          21 :                 if(aMeasureScale.GetNumerator() != aMeasureScale.GetDenominator())
     117             :                 {
     118           0 :                     aFact *= aMeasureScale;
     119             :                 }
     120             : 
     121          21 :                 if(aFact.GetNumerator() != aFact.GetDenominator())
     122             :                 {
     123             :                     // scale via BigInt, to avoid overruns
     124           0 :                     nLen = BigMulDiv(nLen, aFact.GetNumerator(), aFact.GetDenominator());
     125             :                 }
     126             : 
     127          21 :                 OUString aTmp;
     128          21 :                 pModel->TakeMetricStr(nLen, aTmp, true, nNumDigits);
     129          21 :                 aStr = aTmp;
     130             : 
     131          21 :                 if(!aFact.IsValid())
     132             :                 {
     133           0 :                     aStr = "";
     134           0 :                     aStr += "?";
     135             :                 }
     136             : 
     137          21 :                 sal_Unicode cDec(SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]);
     138             : 
     139          21 :                 if(aStr.indexOf(cDec) != -1)
     140             :                 {
     141          21 :                     sal_Int32 nLen2(aStr.getLength() - 1);
     142             : 
     143          42 :                     while(aStr[nLen2] == '0')
     144             :                     {
     145           0 :                         aStr = aStr.copy(0, nLen2);
     146           0 :                         nLen2--;
     147             :                     }
     148             : 
     149          21 :                     if(aStr[nLen2] == cDec)
     150             :                     {
     151           0 :                         aStr = aStr.copy(0, nLen2);
     152           0 :                         nLen2--;
     153             :                     }
     154             : 
     155          21 :                     if(aStr.isEmpty())
     156           0 :                         aStr += "0";
     157          21 :                 }
     158             :             }
     159             :             else
     160             :             {
     161             :                 // if there's no Model ... (e. g. preview in dialog)
     162           0 :                 aStr = "4711";
     163             :             }
     164             : 
     165          21 :             break;
     166             :         }
     167             :         case SDRMEASUREFIELD_UNIT:
     168             :         {
     169          21 :             if(bShowUnit)
     170             :             {
     171          21 :                 if(pModel)
     172             :                 {
     173          21 :                     eModUIUnit = pModel->GetUIUnit();
     174             : 
     175          21 :                     if(eMeasureUnit == FUNIT_NONE)
     176          21 :                         eMeasureUnit = eModUIUnit;
     177             : 
     178          21 :                     if(bShowUnit)
     179          21 :                         pModel->TakeUnitStr(eMeasureUnit, aStr);
     180             :                 }
     181             :             }
     182             : 
     183          21 :             break;
     184             :         }
     185             :         case SDRMEASUREFIELD_ROTA90BLANCS:
     186             :         {
     187          42 :             if(bTextRota90)
     188             :             {
     189           0 :                 aStr = " ";
     190             :             }
     191             : 
     192          42 :             break;
     193             :         }
     194             :     }
     195          84 :     return aStr;
     196             : }
     197             : 
     198             : 
     199             : // BaseProperties section
     200             : 
     201           1 : sdr::properties::BaseProperties* SdrMeasureObj::CreateObjectSpecificProperties()
     202             : {
     203           1 :     return new sdr::properties::MeasureProperties(*this);
     204             : }
     205             : 
     206             : 
     207             : // DrawContact section
     208             : 
     209           1 : sdr::contact::ViewContact* SdrMeasureObj::CreateObjectSpecificViewContact()
     210             : {
     211           1 :     return new sdr::contact::ViewContactOfSdrMeasureObj(*this);
     212             : }
     213             : 
     214             : 
     215             : 
     216         426 : TYPEINIT1(SdrMeasureObj,SdrTextObj);
     217             : 
     218           0 : SdrMeasureObj::SdrMeasureObj():
     219           0 :     bTextDirty(false)
     220             : {
     221             :     // #i25616#
     222           0 :     mbSupportTextIndentingOnLineWidthChange = false;
     223           0 : }
     224             : 
     225           1 : SdrMeasureObj::SdrMeasureObj(const Point& rPt1, const Point& rPt2):
     226             :     aPt1(rPt1),
     227             :     aPt2(rPt2),
     228           1 :     bTextDirty(false)
     229             : {
     230             :     // #i25616#
     231           1 :     mbSupportTextIndentingOnLineWidthChange = false;
     232           1 : }
     233             : 
     234           2 : SdrMeasureObj::~SdrMeasureObj()
     235             : {
     236           2 : }
     237             : 
     238           0 : void SdrMeasureObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
     239             : {
     240           0 :     rInfo.bSelectAllowed    =true;
     241           0 :     rInfo.bMoveAllowed      =true;
     242           0 :     rInfo.bResizeFreeAllowed=true;
     243           0 :     rInfo.bResizePropAllowed=true;
     244           0 :     rInfo.bRotateFreeAllowed=true;
     245           0 :     rInfo.bRotate90Allowed  =true;
     246           0 :     rInfo.bMirrorFreeAllowed=true;
     247           0 :     rInfo.bMirror45Allowed  =true;
     248           0 :     rInfo.bMirror90Allowed  =true;
     249           0 :     rInfo.bTransparenceAllowed = false;
     250           0 :     rInfo.bGradientAllowed = false;
     251           0 :     rInfo.bShearAllowed     =true;
     252           0 :     rInfo.bEdgeRadiusAllowed=false;
     253           0 :     rInfo.bNoOrthoDesired   =true;
     254           0 :     rInfo.bNoContortion     =false;
     255           0 :     rInfo.bCanConvToPath    =false;
     256           0 :     rInfo.bCanConvToPoly    =true;
     257           0 :     rInfo.bCanConvToPathLineToArea=false;
     258           0 :     rInfo.bCanConvToPolyLineToArea=false;
     259           0 :     rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
     260           0 : }
     261             : 
     262          10 : sal_uInt16 SdrMeasureObj::GetObjIdentifier() const
     263             : {
     264          10 :     return (sal_uInt16)OBJ_MEASURE;
     265             : }
     266             : 
     267           6 : struct ImpMeasureRec : public SdrDragStatUserData
     268             : {
     269             :     Point                       aPt1;
     270             :     Point                       aPt2;
     271             :     SdrMeasureKind              eKind;
     272             :     SdrMeasureTextHPos          eWantTextHPos;
     273             :     SdrMeasureTextVPos          eWantTextVPos;
     274             :     long                        nLineDist;
     275             :     long                        nHelplineOverhang;
     276             :     long                        nHelplineDist;
     277             :     long                        nHelpline1Len;
     278             :     long                        nHelpline2Len;
     279             :     bool                        bBelowRefEdge;
     280             :     bool                        bTextRota90;
     281             :     bool                        bTextUpsideDown;
     282             :     long                        nMeasureOverhang;
     283             :     FieldUnit                   eMeasureUnit;
     284             :     Fraction                    aMeasureScale;
     285             :     bool                        bShowUnit;
     286             :     OUString                    aFormatString;
     287             :     bool                        bTextAutoAngle;
     288             :     long                        nTextAutoAngleView;
     289             :     bool                        bTextIsFixedAngle;
     290             :     long                        nTextFixedAngle;
     291             : };
     292             : 
     293          15 : struct ImpLineRec
     294             : {
     295             :     Point                       aP1;
     296             :     Point                       aP2;
     297             : };
     298             : 
     299           3 : struct ImpMeasurePoly
     300             : {
     301             :     ImpLineRec                  aMainline1; // those with the 1st arrowhead
     302             :     ImpLineRec                  aMainline2; // those with the 2nd arrowhead
     303             :     ImpLineRec                  aMainline3; // those in between
     304             :     ImpLineRec                  aHelpline1;
     305             :     ImpLineRec                  aHelpline2;
     306             :     Rectangle                   aTextRect;
     307             :     Size                        aTextSize;
     308             :     long                        nLineLen;
     309             :     long                        nLineWink;
     310             :     long                        nTextWink;
     311             :     long                        nHlpWink;
     312             :     double                      nLineSin;
     313             :     double                      nLineCos;
     314             :     double                      nHlpSin;
     315             :     double                      nHlpCos;
     316             :     sal_uInt16                      nMainlineAnz;
     317             :     SdrMeasureTextHPos          eUsedTextHPos;
     318             :     SdrMeasureTextVPos          eUsedTextVPos;
     319             :     long                        nLineWdt2;  // half the line width
     320             :     long                        nArrow1Len; // length of 1st arrowhead; for Center, use only half
     321             :     long                        nArrow2Len; // length of 2nd arrowhead; for Center, use only half
     322             :     long                        nArrow1Wdt; // width of 1st arrow
     323             :     long                        nArrow2Wdt; // width of 2nd arrow
     324             :     long                        nShortLineLen; // line length, if PfeileAussen (arrowheads on the outside)
     325             :     bool                        bArrow1Center; // arrowhead 1 centered?
     326             :     bool                        bArrow2Center; // arrowhead 2 centered?
     327             :     bool                        bAutoUpsideDown; // UpsideDown via automation
     328             :     bool                        bPfeileAussen; // arrowheads on the outside
     329             :     bool                        bBreakedLine;
     330             : };
     331             : 
     332           3 : void SdrMeasureObj::ImpTakeAttr(ImpMeasureRec& rRec) const
     333             : {
     334           3 :     rRec.aPt1 = aPt1;
     335           3 :     rRec.aPt2 = aPt2;
     336             : 
     337           3 :     const SfxItemSet& rSet = GetObjectItemSet();
     338           3 :     rRec.eKind            =((SdrMeasureKindItem&            )rSet.Get(SDRATTR_MEASUREKIND            )).GetValue();
     339           3 :     rRec.eWantTextHPos    =((SdrMeasureTextHPosItem&        )rSet.Get(SDRATTR_MEASURETEXTHPOS        )).GetValue();
     340           3 :     rRec.eWantTextVPos    =((SdrMeasureTextVPosItem&        )rSet.Get(SDRATTR_MEASURETEXTVPOS        )).GetValue();
     341           3 :     rRec.nLineDist        =((SdrMeasureLineDistItem&        )rSet.Get(SDRATTR_MEASURELINEDIST        )).GetValue();
     342           3 :     rRec.nHelplineOverhang=((SdrMeasureHelplineOverhangItem&)rSet.Get(SDRATTR_MEASUREHELPLINEOVERHANG)).GetValue();
     343           3 :     rRec.nHelplineDist    =((SdrMeasureHelplineDistItem&    )rSet.Get(SDRATTR_MEASUREHELPLINEDIST    )).GetValue();
     344           3 :     rRec.nHelpline1Len    =((SdrMeasureHelpline1LenItem&    )rSet.Get(SDRATTR_MEASUREHELPLINE1LEN    )).GetValue();
     345           3 :     rRec.nHelpline2Len    =((SdrMeasureHelpline2LenItem&    )rSet.Get(SDRATTR_MEASUREHELPLINE2LEN    )).GetValue();
     346           3 :     rRec.bBelowRefEdge    =((SdrMeasureBelowRefEdgeItem&    )rSet.Get(SDRATTR_MEASUREBELOWREFEDGE    )).GetValue();
     347           3 :     rRec.bTextRota90      =((SdrMeasureTextRota90Item&      )rSet.Get(SDRATTR_MEASURETEXTROTA90      )).GetValue();
     348           3 :     rRec.bTextUpsideDown  =((SdrMeasureTextUpsideDownItem&  )rSet.Get(SDRATTR_MEASURETEXTUPSIDEDOWN  )).GetValue();
     349           3 :     rRec.nMeasureOverhang =((SdrMeasureOverhangItem&        )rSet.Get(SDRATTR_MEASUREOVERHANG        )).GetValue();
     350           3 :     rRec.eMeasureUnit     =((SdrMeasureUnitItem&            )rSet.Get(SDRATTR_MEASUREUNIT            )).GetValue();
     351           3 :     rRec.aMeasureScale    =((SdrMeasureScaleItem&           )rSet.Get(SDRATTR_MEASURESCALE           )).GetValue();
     352           3 :     rRec.bShowUnit        =((SdrMeasureShowUnitItem&        )rSet.Get(SDRATTR_MEASURESHOWUNIT        )).GetValue();
     353           3 :     rRec.aFormatString    =((SdrMeasureFormatStringItem&    )rSet.Get(SDRATTR_MEASUREFORMATSTRING    )).GetValue();
     354           3 :     rRec.bTextAutoAngle    =((SdrMeasureTextAutoAngleItem&    )rSet.Get(SDRATTR_MEASURETEXTAUTOANGLE    )).GetValue();
     355           3 :     rRec.nTextAutoAngleView=((SdrMeasureTextAutoAngleViewItem&)rSet.Get(SDRATTR_MEASURETEXTAUTOANGLEVIEW)).GetValue();
     356           3 :     rRec.bTextIsFixedAngle =((SdrMeasureTextIsFixedAngleItem& )rSet.Get(SDRATTR_MEASURETEXTISFIXEDANGLE )).GetValue();
     357           3 :     rRec.nTextFixedAngle   =((SdrMeasureTextFixedAngleItem&   )rSet.Get(SDRATTR_MEASURETEXTFIXEDANGLE   )).GetValue();
     358           3 : }
     359             : 
     360           6 : long impGetLineStartEndDistance(const basegfx::B2DPolyPolygon& rPolyPolygon, long nNewWidth, bool bCenter)
     361             : {
     362           6 :     const basegfx::B2DRange aPolygonRange(rPolyPolygon.getB2DRange());
     363           6 :     const double fOldWidth(aPolygonRange.getWidth() > 1.0 ? aPolygonRange.getWidth() : 1.0);
     364           6 :     const double fScale((double)nNewWidth / fOldWidth);
     365           6 :     long nHeight(basegfx::fround(aPolygonRange.getHeight() * fScale));
     366             : 
     367           6 :     if(bCenter)
     368             :     {
     369           0 :         nHeight /= 2L;
     370             :     }
     371             : 
     372           6 :     return nHeight;
     373             : }
     374             : 
     375           3 : void SdrMeasureObj::ImpCalcGeometrics(const ImpMeasureRec& rRec, ImpMeasurePoly& rPol) const
     376             : {
     377           3 :     Point aP1(rRec.aPt1);
     378           3 :     Point aP2(rRec.aPt2);
     379           3 :     Point aDelt(aP2); aDelt-=aP1;
     380             : 
     381           3 :     rPol.aTextSize=GetTextSize();
     382           3 :     rPol.nLineLen=GetLen(aDelt);
     383             : 
     384           3 :     rPol.nLineWdt2=0;
     385           3 :     long nArrow1Len=0; bool bArrow1Center=false;
     386           3 :     long nArrow2Len=0; bool bArrow2Center=false;
     387           3 :     long nArrow1Wdt=0;
     388           3 :     long nArrow2Wdt=0;
     389           3 :     rPol.nArrow1Wdt=0;
     390           3 :     rPol.nArrow2Wdt=0;
     391           3 :     long nArrowNeed=0;
     392           3 :     long nShortLen=0;
     393           3 :     bool bPfeileAussen = false;
     394             : 
     395           3 :     const SfxItemSet& rSet = GetObjectItemSet();
     396           3 :     sal_Int32 nLineWdt = ((XLineWidthItem&)(rSet.Get(XATTR_LINEWIDTH))).GetValue(); // line width
     397           3 :     rPol.nLineWdt2 = (nLineWdt + 1) / 2;
     398             : 
     399           3 :     nArrow1Wdt = ((const XLineStartWidthItem&)(rSet.Get(XATTR_LINESTARTWIDTH))).GetValue();
     400           3 :     if(nArrow1Wdt < 0)
     401           0 :         nArrow1Wdt = -nLineWdt * nArrow1Wdt / 100; // <0 = relativ
     402             : 
     403           3 :     nArrow2Wdt = ((const XLineEndWidthItem&)(rSet.Get(XATTR_LINEENDWIDTH))).GetValue();
     404           3 :     if(nArrow2Wdt < 0)
     405           0 :         nArrow2Wdt = -nLineWdt * nArrow2Wdt / 100; // <0 = relativ
     406             : 
     407           3 :     basegfx::B2DPolyPolygon aPol1(((const XLineStartItem&)(rSet.Get(XATTR_LINESTART))).GetLineStartValue());
     408           6 :     basegfx::B2DPolyPolygon aPol2(((const XLineEndItem&)(rSet.Get(XATTR_LINEEND))).GetLineEndValue());
     409           3 :     bArrow1Center = ((const XLineStartCenterItem&)(rSet.Get(XATTR_LINESTARTCENTER))).GetValue();
     410           3 :     bArrow2Center = ((const XLineEndCenterItem&)(rSet.Get(XATTR_LINEENDCENTER))).GetValue();
     411           3 :     nArrow1Len = impGetLineStartEndDistance(aPol1, nArrow1Wdt, bArrow1Center) - 1;
     412           3 :     nArrow2Len = impGetLineStartEndDistance(aPol2, nArrow2Wdt, bArrow2Center) - 1;
     413             : 
     414             :     // nArrowLen is already halved at bCenter.
     415             :     // In the case of 2 arrowheads each 4mm long, we can't go below 10mm.
     416           3 :     nArrowNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2;
     417           3 :     if (rPol.nLineLen<nArrowNeed) bPfeileAussen = true;
     418           3 :     nShortLen=(nArrow1Len+nArrow1Wdt + nArrow2Len+nArrow2Wdt) /2;
     419             : 
     420           3 :     rPol.eUsedTextHPos=rRec.eWantTextHPos;
     421           3 :     rPol.eUsedTextVPos=rRec.eWantTextVPos;
     422           3 :     if (rPol.eUsedTextVPos==SDRMEASURE_TEXTVAUTO) rPol.eUsedTextVPos=SDRMEASURE_ABOVE;
     423           3 :     bool bBrkLine=rPol.eUsedTextVPos==SDRMEASURETEXT_BREAKEDLINE;
     424           3 :     if (rPol.eUsedTextVPos==SDRMEASURETEXT_VERTICALCENTERED)
     425             :     {
     426           0 :         OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject();
     427           0 :         if (pOutlinerParaObject!=NULL && pOutlinerParaObject->GetTextObject().GetParagraphCount()==1)
     428             :         {
     429           0 :             bBrkLine=true; // dashed line if there's only on paragraph.
     430             :         }
     431             :     }
     432           3 :     rPol.bBreakedLine=bBrkLine;
     433           3 :     if (rPol.eUsedTextHPos==SDRMEASURE_TEXTHAUTO) { // if text is too wide, push it outside
     434           3 :         bool bOutside = false;
     435           3 :         long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height();
     436           3 :         if (nNeedSiz>rPol.nLineLen) bOutside = true; // text doesn't fit in between
     437           3 :         if (bBrkLine) {
     438           0 :             if (nNeedSiz+nArrowNeed>rPol.nLineLen) bPfeileAussen = true; // text fits in between, if arrowheads are on the outside
     439             :         } else {
     440           3 :             long nSmallNeed=nArrow1Len+nArrow2Len+(nArrow1Wdt+nArrow2Wdt)/2/4;
     441           3 :             if (nNeedSiz+nSmallNeed>rPol.nLineLen) bPfeileAussen = true; // text fits in between, if arrowheads are on the outside
     442             :         }
     443           3 :         rPol.eUsedTextHPos=bOutside ? SDRMEASURE_TEXTLEFTOUTSIDE : SDRMEASURE_TEXTINSIDE;
     444             :     }
     445           3 :     if (rPol.eUsedTextHPos!=SDRMEASURE_TEXTINSIDE) bPfeileAussen = true;
     446           3 :     rPol.nArrow1Wdt=nArrow1Wdt;
     447           3 :     rPol.nArrow2Wdt=nArrow2Wdt;
     448           3 :     rPol.nShortLineLen=nShortLen;
     449           3 :     rPol.bPfeileAussen=bPfeileAussen;
     450           3 :     rPol.nArrow1Len=nArrow1Len;
     451           3 :     rPol.bArrow1Center=bArrow1Center;
     452           3 :     rPol.nArrow2Len=nArrow2Len;
     453           3 :     rPol.bArrow2Center=bArrow2Center;
     454             : 
     455           3 :     rPol.nLineWink=GetAngle(aDelt);
     456           3 :     double a=rPol.nLineWink*nPi180;
     457           3 :     double nLineSin=sin(a);
     458           3 :     double nLineCos=cos(a);
     459           3 :     rPol.nLineSin=nLineSin;
     460           3 :     rPol.nLineCos=nLineCos;
     461             : 
     462           3 :     rPol.nTextWink=rPol.nLineWink;
     463           3 :     if (rRec.bTextRota90) rPol.nTextWink+=9000;
     464             : 
     465           3 :     rPol.bAutoUpsideDown=false;
     466           3 :     if (rRec.bTextAutoAngle) {
     467           3 :         long nTmpWink=NormAngle360(rPol.nTextWink-rRec.nTextAutoAngleView);
     468           3 :         if (nTmpWink>=18000) {
     469           0 :             rPol.nTextWink+=18000;
     470           0 :             rPol.bAutoUpsideDown=true;
     471             :         }
     472             :     }
     473             : 
     474           3 :     if (rRec.bTextUpsideDown) rPol.nTextWink+=18000;
     475           3 :     rPol.nTextWink=NormAngle360(rPol.nTextWink);
     476           3 :     rPol.nHlpWink=rPol.nLineWink+9000;
     477           3 :     if (rRec.bBelowRefEdge) rPol.nHlpWink+=18000;
     478           3 :     rPol.nHlpWink=NormAngle360(rPol.nHlpWink);
     479           3 :     double nHlpSin=nLineCos;
     480           3 :     double nHlpCos=-nLineSin;
     481           3 :     if (rRec.bBelowRefEdge) {
     482           0 :         nHlpSin=-nHlpSin;
     483           0 :         nHlpCos=-nHlpCos;
     484             :     }
     485           3 :     rPol.nHlpSin=nHlpSin;
     486           3 :     rPol.nHlpCos=nHlpCos;
     487             : 
     488           3 :     long nLineDist=rRec.nLineDist;
     489           3 :     long nOverhang=rRec.nHelplineOverhang;
     490           3 :     long nHelplineDist=rRec.nHelplineDist;
     491             : 
     492           3 :     long dx= Round(nLineDist*nHlpCos);
     493           3 :     long dy=-Round(nLineDist*nHlpSin);
     494           3 :     long dxh1a= Round((nHelplineDist-rRec.nHelpline1Len)*nHlpCos);
     495           3 :     long dyh1a=-Round((nHelplineDist-rRec.nHelpline1Len)*nHlpSin);
     496           3 :     long dxh1b= Round((nHelplineDist-rRec.nHelpline2Len)*nHlpCos);
     497           3 :     long dyh1b=-Round((nHelplineDist-rRec.nHelpline2Len)*nHlpSin);
     498           3 :     long dxh2= Round((nLineDist+nOverhang)*nHlpCos);
     499           3 :     long dyh2=-Round((nLineDist+nOverhang)*nHlpSin);
     500             : 
     501             :     // extension line 1
     502           3 :     rPol.aHelpline1.aP1=Point(aP1.X()+dxh1a,aP1.Y()+dyh1a);
     503           3 :     rPol.aHelpline1.aP2=Point(aP1.X()+dxh2,aP1.Y()+dyh2);
     504             : 
     505             :     // extension line 2
     506           3 :     rPol.aHelpline2.aP1=Point(aP2.X()+dxh1b,aP2.Y()+dyh1b);
     507           3 :     rPol.aHelpline2.aP2=Point(aP2.X()+dxh2,aP2.Y()+dyh2);
     508             : 
     509             :     // dimension line
     510           3 :     Point aMainlinePt1(aP1.X()+dx,aP1.Y()+dy);
     511           3 :     Point aMainlinePt2(aP2.X()+dx,aP2.Y()+dy);
     512           3 :     if (!bPfeileAussen) {
     513           0 :         rPol.aMainline1.aP1=aMainlinePt1;
     514           0 :         rPol.aMainline1.aP2=aMainlinePt2;
     515           0 :         rPol.aMainline2=rPol.aMainline1;
     516           0 :         rPol.aMainline3=rPol.aMainline1;
     517           0 :         rPol.nMainlineAnz=1;
     518           0 :         if (bBrkLine) {
     519           0 :             long nNeedSiz=!rRec.bTextRota90 ? rPol.aTextSize.Width() : rPol.aTextSize.Height();
     520           0 :             long nHalfLen=(rPol.nLineLen-nNeedSiz-nArrow1Wdt/4-nArrow2Wdt/4) /2;
     521           0 :             rPol.nMainlineAnz=2;
     522           0 :             rPol.aMainline1.aP2=aMainlinePt1;
     523           0 :             rPol.aMainline1.aP2.X()+=nHalfLen;
     524           0 :             RotatePoint(rPol.aMainline1.aP2,rPol.aMainline1.aP1,nLineSin,nLineCos);
     525           0 :             rPol.aMainline2.aP1=aMainlinePt2;
     526           0 :             rPol.aMainline2.aP1.X()-=nHalfLen;
     527           0 :             RotatePoint(rPol.aMainline2.aP1,rPol.aMainline2.aP2,nLineSin,nLineCos);
     528             :         }
     529             :     } else {
     530           3 :         long nLen1=nShortLen; // arrowhead's width as line length outside of the arrowhead
     531           3 :         long nLen2=nShortLen;
     532           3 :         long nTextWdt=rRec.bTextRota90 ? rPol.aTextSize.Height() : rPol.aTextSize.Width();
     533           3 :         if (!bBrkLine) {
     534           3 :             if (rPol.eUsedTextHPos==SDRMEASURE_TEXTLEFTOUTSIDE) nLen1=nArrow1Len+nTextWdt;
     535           3 :             if (rPol.eUsedTextHPos==SDRMEASURE_TEXTRIGHTOUTSIDE) nLen2=nArrow2Len+nTextWdt;
     536             :         }
     537           3 :         rPol.aMainline1.aP1=aMainlinePt1;
     538           3 :         rPol.aMainline1.aP2=aMainlinePt1; rPol.aMainline1.aP2.X()-=nLen1; RotatePoint(rPol.aMainline1.aP2,aMainlinePt1,nLineSin,nLineCos);
     539           3 :         rPol.aMainline2.aP1=aMainlinePt2; rPol.aMainline2.aP1.X()+=nLen2; RotatePoint(rPol.aMainline2.aP1,aMainlinePt2,nLineSin,nLineCos);
     540           3 :         rPol.aMainline2.aP2=aMainlinePt2;
     541           3 :         rPol.aMainline3.aP1=aMainlinePt1;
     542           3 :         rPol.aMainline3.aP2=aMainlinePt2;
     543           3 :         rPol.nMainlineAnz=3;
     544           3 :         if (bBrkLine && rPol.eUsedTextHPos==SDRMEASURE_TEXTINSIDE) rPol.nMainlineAnz=2;
     545           3 :     }
     546           3 : }
     547             : 
     548           3 : basegfx::B2DPolyPolygon SdrMeasureObj::ImpCalcXPoly(const ImpMeasurePoly& rPol) const
     549             : {
     550           3 :     basegfx::B2DPolyPolygon aRetval;
     551           6 :     basegfx::B2DPolygon aPartPolyA;
     552           3 :     aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP1.X(), rPol.aMainline1.aP1.Y()));
     553           3 :     aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline1.aP2.X(), rPol.aMainline1.aP2.Y()));
     554           3 :     aRetval.append(aPartPolyA);
     555             : 
     556           3 :     if(rPol.nMainlineAnz > 1)
     557             :     {
     558           3 :         aPartPolyA.clear();
     559           3 :         aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP1.X(), rPol.aMainline2.aP1.Y()));
     560           3 :         aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline2.aP2.X(), rPol.aMainline2.aP2.Y()));
     561           3 :         aRetval.append(aPartPolyA);
     562             :     }
     563             : 
     564           3 :     if(rPol.nMainlineAnz > 2)
     565             :     {
     566           3 :         aPartPolyA.clear();
     567           3 :         aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP1.X(), rPol.aMainline3.aP1.Y()));
     568           3 :         aPartPolyA.append(basegfx::B2DPoint(rPol.aMainline3.aP2.X(), rPol.aMainline3.aP2.Y()));
     569           3 :         aRetval.append(aPartPolyA);
     570             :     }
     571             : 
     572           3 :     aPartPolyA.clear();
     573           3 :     aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP1.X(), rPol.aHelpline1.aP1.Y()));
     574           3 :     aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline1.aP2.X(), rPol.aHelpline1.aP2.Y()));
     575           3 :     aRetval.append(aPartPolyA);
     576             : 
     577           3 :     aPartPolyA.clear();
     578           3 :     aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP1.X(), rPol.aHelpline2.aP1.Y()));
     579           3 :     aPartPolyA.append(basegfx::B2DPoint(rPol.aHelpline2.aP2.X(), rPol.aHelpline2.aP2.Y()));
     580           3 :     aRetval.append(aPartPolyA);
     581             : 
     582           6 :     return aRetval;
     583             : }
     584             : 
     585          84 : bool SdrMeasureObj::CalcFieldValue(const SvxFieldItem& rField, sal_Int32 nPara, sal_uInt16 nPos,
     586             :     bool bEdit,
     587             :     Color*& rpTxtColor, Color*& rpFldColor, OUString& rRet) const
     588             : {
     589          84 :     const SvxFieldData* pField=rField.GetField();
     590          84 :     SdrMeasureField* pMeasureField=PTR_CAST(SdrMeasureField,pField);
     591          84 :     if (pMeasureField!=NULL) {
     592          84 :         rRet = TakeRepresentation(pMeasureField->GetMeasureFieldKind());
     593          84 :         if (rpFldColor!=NULL) {
     594           0 :             if (!bEdit)
     595             :             {
     596           0 :                 delete rpFldColor;
     597           0 :                 rpFldColor=NULL;
     598             :             }
     599             :         }
     600          84 :         return true;
     601             :     } else {
     602           0 :         return SdrTextObj::CalcFieldValue(rField,nPara,nPos,bEdit,rpTxtColor,rpFldColor,rRet);
     603             :     }
     604             : }
     605             : 
     606           7 : void SdrMeasureObj::UndirtyText() const
     607             : {
     608           7 :     if (bTextDirty)
     609             :     {
     610           7 :         SdrOutliner& rOutliner=ImpGetDrawOutliner();
     611           7 :         OutlinerParaObject* pOutlinerParaObject = SdrTextObj::GetOutlinerParaObject();
     612           7 :         if(pOutlinerParaObject==NULL)
     613             :         {
     614           1 :             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD), ESelection(0,0));
     615           1 :             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_VALUE), EE_FEATURE_FIELD),ESelection(0,1));
     616           1 :             rOutliner.QuickInsertText(" ", ESelection(0,2));
     617           1 :             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_UNIT), EE_FEATURE_FIELD),ESelection(0,3));
     618           1 :             rOutliner.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS), EE_FEATURE_FIELD),ESelection(0,4));
     619             : 
     620           1 :             if(GetStyleSheet())
     621           0 :                 rOutliner.SetStyleSheet(0, GetStyleSheet());
     622             : 
     623           1 :             rOutliner.SetParaAttribs(0, GetObjectItemSet());
     624             : 
     625             :             // cast to nonconst
     626           1 :             const_cast<SdrMeasureObj*>(this)->NbcSetOutlinerParaObject( rOutliner.CreateParaObject() );
     627             :         }
     628             :         else
     629             :         {
     630           6 :             rOutliner.SetText(*pOutlinerParaObject);
     631             :         }
     632             : 
     633           7 :         rOutliner.SetUpdateMode(true);
     634           7 :         rOutliner.UpdateFields();
     635           7 :         Size aSiz(rOutliner.CalcTextSize());
     636           7 :         rOutliner.Clear();
     637             :         // cast to nonconst three times
     638           7 :         ((SdrMeasureObj*)this)->aTextSize=aSiz;
     639           7 :         ((SdrMeasureObj*)this)->bTextSizeDirty=false;
     640           7 :         ((SdrMeasureObj*)this)->bTextDirty=false;
     641             :     }
     642           7 : }
     643             : 
     644           0 : void SdrMeasureObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
     645             : {
     646           0 :     if (bTextDirty) UndirtyText();
     647           0 :     ImpMeasureRec aRec;
     648           0 :     ImpMeasurePoly aMPol;
     649           0 :     ImpTakeAttr(aRec);
     650           0 :     ImpCalcGeometrics(aRec,aMPol);
     651             : 
     652             :     // determine TextSize including text frame margins
     653           0 :     Size aTextSize2(aMPol.aTextSize);
     654           0 :     if (aTextSize2.Width()<1) aTextSize2.Width()=1;
     655           0 :     if (aTextSize2.Height()<1) aTextSize2.Height()=1;
     656           0 :     aTextSize2.Width()+=GetTextLeftDistance()+GetTextRightDistance();
     657           0 :     aTextSize2.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
     658             : 
     659           0 :     Point aPt1b(aMPol.aMainline1.aP1);
     660           0 :     long nLen=aMPol.nLineLen;
     661           0 :     long nLWdt=aMPol.nLineWdt2;
     662           0 :     long nArr1Len=aMPol.nArrow1Len;
     663           0 :     long nArr2Len=aMPol.nArrow2Len;
     664           0 :     if (aMPol.bBreakedLine) {
     665             :         // In the case of a dashed line and Outside, the text should be
     666             :         // placed next to the line at the arrowhead instead of directly
     667             :         // at the arrowhead.
     668           0 :         nArr1Len=aMPol.nShortLineLen+aMPol.nArrow1Wdt/4;
     669           0 :         nArr2Len=aMPol.nShortLineLen+aMPol.nArrow2Wdt/4;
     670             :     }
     671             : 
     672           0 :     Point aTextPos;
     673           0 :     bool bRota90=aRec.bTextRota90;
     674           0 :     bool bUpsideDown=aRec.bTextUpsideDown!=aMPol.bAutoUpsideDown;
     675           0 :     bool bBelowRefEdge=aRec.bBelowRefEdge;
     676           0 :     SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos;
     677           0 :     SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos;
     678           0 :     if (!bRota90) {
     679           0 :         switch (eMH) {
     680           0 :             case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Width()-nArr1Len-nLWdt; break;
     681           0 :             case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len+nLWdt; break;
     682           0 :             default: aTextPos.X()=aPt1b.X(); aTextSize2.Width()=nLen;
     683             :         }
     684           0 :         switch (eMV) {
     685             :             case SDRMEASURETEXT_VERTICALCENTERED:
     686           0 :             case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()/2; break;
     687             :             case SDRMEASURE_BELOW: {
     688           0 :                 if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()+nLWdt;
     689           0 :                 else aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt;
     690           0 :             } break;
     691             :             default: {
     692           0 :                 if (!bUpsideDown) aTextPos.Y()=aPt1b.Y()-aTextSize2.Height()-nLWdt;
     693           0 :                 else aTextPos.Y()=aPt1b.Y()+nLWdt;
     694             :             }
     695             :         }
     696           0 :         if (bUpsideDown) {
     697           0 :             aTextPos.X()+=aTextSize2.Width();
     698           0 :             aTextPos.Y()+=aTextSize2.Height();
     699             :         }
     700             :     } else { // also if bTextRota90==TRUE
     701           0 :         switch (eMH) {
     702           0 :             case SDRMEASURE_TEXTLEFTOUTSIDE: aTextPos.X()=aPt1b.X()-aTextSize2.Height()-nArr1Len; break;
     703           0 :             case SDRMEASURE_TEXTRIGHTOUTSIDE: aTextPos.X()=aPt1b.X()+nLen+nArr2Len; break;
     704           0 :             default: aTextPos.X()=aPt1b.X(); aTextSize2.Height()=nLen;
     705             :         }
     706           0 :         switch (eMV) {
     707             :             case SDRMEASURETEXT_VERTICALCENTERED:
     708           0 :             case SDRMEASURETEXT_BREAKEDLINE: aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()/2; break;
     709             :             case SDRMEASURE_BELOW: {
     710           0 :                 if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt;
     711           0 :                 else aTextPos.Y()=aPt1b.Y()-nLWdt;
     712           0 :             } break;
     713             :             default: {
     714           0 :                 if (!bBelowRefEdge) aTextPos.Y()=aPt1b.Y()-nLWdt;
     715           0 :                 else aTextPos.Y()=aPt1b.Y()+aTextSize2.Width()+nLWdt;
     716             :             }
     717             :         }
     718           0 :         if (bUpsideDown) {
     719           0 :             aTextPos.X()+=aTextSize2.Height();
     720           0 :             aTextPos.Y()-=aTextSize2.Width();
     721             :         }
     722             :     }
     723           0 :     if (aMPol.nTextWink!=aGeo.nDrehWink) {
     724           0 :         ((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink;
     725           0 :         ((SdrMeasureObj*)this)->aGeo.RecalcSinCos();
     726             :     }
     727           0 :     RotatePoint(aTextPos,aPt1b,aMPol.nLineSin,aMPol.nLineCos);
     728           0 :     aTextSize2.Width()++; aTextSize2.Height()++; // because of the Rect-Ctor's odd behavior
     729           0 :     rRect=Rectangle(aTextPos,aTextSize2);
     730           0 :     rRect.Justify();
     731           0 :     ((SdrMeasureObj*)this)->aRect=rRect;
     732             : 
     733           0 :     if (aMPol.nTextWink!=aGeo.nDrehWink) {
     734           0 :         ((SdrMeasureObj*)this)->aGeo.nDrehWink=aMPol.nTextWink;
     735           0 :         ((SdrMeasureObj*)this)->aGeo.RecalcSinCos();
     736           0 :     }
     737           0 : }
     738             : 
     739           0 : SdrMeasureObj* SdrMeasureObj::Clone() const
     740             : {
     741           0 :     return CloneHelper< SdrMeasureObj >();
     742             : }
     743             : 
     744           0 : OUString SdrMeasureObj::TakeObjNameSingul() const
     745             : {
     746           0 :     OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulMEASURE));
     747             : 
     748           0 :     OUString aName( GetName() );
     749           0 :     if (!aName.isEmpty())
     750             :     {
     751           0 :         sName.append(' ');
     752           0 :         sName.append('\'');
     753           0 :         sName.append(aName);
     754           0 :         sName.append('\'');
     755             :     }
     756             : 
     757           0 :     return sName.makeStringAndClear();
     758             : }
     759             : 
     760           0 : OUString SdrMeasureObj::TakeObjNamePlural() const
     761             : {
     762           0 :     return ImpGetResStr(STR_ObjNamePluralMEASURE);
     763             : }
     764             : 
     765           0 : basegfx::B2DPolyPolygon SdrMeasureObj::TakeXorPoly() const
     766             : {
     767           0 :     ImpMeasureRec aRec;
     768           0 :     ImpMeasurePoly aMPol;
     769           0 :     ImpTakeAttr(aRec);
     770           0 :     ImpCalcGeometrics(aRec,aMPol);
     771           0 :     return ImpCalcXPoly(aMPol);
     772             : }
     773             : 
     774           0 : sal_uInt32 SdrMeasureObj::GetHdlCount() const
     775             : {
     776           0 :     return 6L;
     777             : }
     778             : 
     779           0 : SdrHdl* SdrMeasureObj::GetHdl(sal_uInt32 nHdlNum) const
     780             : {
     781           0 :     ImpMeasureRec aRec;
     782           0 :     ImpMeasurePoly aMPol;
     783           0 :     ImpTakeAttr(aRec);
     784           0 :     aRec.nHelplineDist=0;
     785           0 :     ImpCalcGeometrics(aRec,aMPol);
     786           0 :     Point aPt;
     787             : 
     788           0 :     switch (nHdlNum) {
     789           0 :         case 0: aPt=aMPol.aHelpline1.aP1; break;
     790           0 :         case 1: aPt=aMPol.aHelpline2.aP1; break;
     791           0 :         case 2: aPt=aPt1;       break;
     792           0 :         case 3: aPt=aPt2;       break;
     793           0 :         case 4: aPt=aMPol.aHelpline1.aP2; break;
     794           0 :         case 5: aPt=aMPol.aHelpline2.aP2; break;
     795             :     } // switch
     796           0 :     SdrHdl* pHdl=new ImpMeasureHdl(aPt,HDL_USER);
     797           0 :     pHdl->SetObjHdlNum(nHdlNum);
     798           0 :     pHdl->SetDrehWink(aMPol.nLineWink);
     799           0 :     return pHdl;
     800             : }
     801             : 
     802             : 
     803             : 
     804           0 : bool SdrMeasureObj::hasSpecialDrag() const
     805             : {
     806           0 :     return true;
     807             : }
     808             : 
     809           0 : bool SdrMeasureObj::beginSpecialDrag(SdrDragStat& rDrag) const
     810             : {
     811           0 :     const SdrHdl* pHdl = rDrag.GetHdl();
     812             : 
     813           0 :     if(pHdl)
     814             :     {
     815           0 :         const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
     816             : 
     817           0 :         if(nHdlNum != 2 && nHdlNum != 3)
     818             :         {
     819           0 :             rDrag.SetEndDragChangesAttributes(true);
     820             :         }
     821             : 
     822           0 :         return true;
     823             :     }
     824             : 
     825           0 :     return false;
     826             : }
     827             : 
     828           0 : bool SdrMeasureObj::applySpecialDrag(SdrDragStat& rDrag)
     829             : {
     830           0 :     ImpMeasureRec aMeasureRec;
     831           0 :     const SdrHdl* pHdl = rDrag.GetHdl();
     832           0 :     const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
     833             : 
     834           0 :     ImpTakeAttr(aMeasureRec);
     835           0 :     ImpEvalDrag(aMeasureRec, rDrag);
     836             : 
     837           0 :     switch (nHdlNum)
     838             :     {
     839             :         case 2:
     840             :         {
     841           0 :             aPt1 = aMeasureRec.aPt1;
     842           0 :             SetTextDirty();
     843           0 :             break;
     844             :         }
     845             :         case 3:
     846             :         {
     847           0 :             aPt2 = aMeasureRec.aPt2;
     848           0 :             SetTextDirty();
     849           0 :             break;
     850             :         }
     851             :         default:
     852             :         {
     853           0 :             switch(nHdlNum)
     854             :             {
     855             :                 case 0:
     856             :                 case 1:
     857             :                 {
     858           0 :                     ImpMeasureRec aOrigMeasureRec;
     859           0 :                     ImpTakeAttr(aOrigMeasureRec);
     860             : 
     861           0 :                     if(aMeasureRec.nHelpline1Len != aOrigMeasureRec.nHelpline1Len)
     862             :                     {
     863           0 :                         SetObjectItem(SdrMeasureHelpline1LenItem(aMeasureRec.nHelpline1Len));
     864             :                     }
     865             : 
     866           0 :                     if(aMeasureRec.nHelpline2Len != aOrigMeasureRec.nHelpline2Len)
     867             :                     {
     868           0 :                         SetObjectItem(SdrMeasureHelpline2LenItem(aMeasureRec.nHelpline2Len));
     869             :                     }
     870             : 
     871           0 :                     break;
     872             :                 }
     873             : 
     874             :                 case 4:
     875             :                 case 5:
     876             :                 {
     877           0 :                     ImpMeasureRec aOrigMeasureRec;
     878           0 :                     ImpTakeAttr(aOrigMeasureRec);
     879             : 
     880           0 :                     if(aMeasureRec.nLineDist != aOrigMeasureRec.nLineDist)
     881             :                     {
     882           0 :                         SetObjectItem(SdrMeasureLineDistItem(aMeasureRec.nLineDist));
     883             :                     }
     884             : 
     885           0 :                     if(aMeasureRec.bBelowRefEdge != aOrigMeasureRec.bBelowRefEdge)
     886             :                     {
     887           0 :                         SetObjectItem(SdrMeasureBelowRefEdgeItem(aMeasureRec.bBelowRefEdge));
     888           0 :                     }
     889             :                 }
     890             :             }
     891             :         }
     892             :     } // switch
     893             : 
     894           0 :     SetRectsDirty();
     895           0 :     SetChanged();
     896             : 
     897           0 :     return true;
     898             : }
     899             : 
     900           0 : OUString SdrMeasureObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const
     901             : {
     902           0 :     return OUString();
     903             : }
     904             : 
     905           0 : void SdrMeasureObj::ImpEvalDrag(ImpMeasureRec& rRec, const SdrDragStat& rDrag) const
     906             : {
     907           0 :     long nLineWink=GetAngle(rRec.aPt2-rRec.aPt1);
     908           0 :     double a=nLineWink*nPi180;
     909           0 :     double nSin=sin(a);
     910           0 :     double nCos=cos(a);
     911             : 
     912           0 :     const SdrHdl* pHdl=rDrag.GetHdl();
     913           0 :     sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
     914           0 :     bool bOrtho=rDrag.GetView()!=NULL && rDrag.GetView()->IsOrtho();
     915           0 :     bool bBigOrtho=bOrtho && rDrag.GetView()->IsBigOrtho();
     916           0 :     bool bBelow=rRec.bBelowRefEdge;
     917           0 :     Point aPt(rDrag.GetNow());
     918             : 
     919           0 :     switch (nHdlNum) {
     920             :         case 0: {
     921           0 :             RotatePoint(aPt,aPt1,nSin,-nCos);
     922           0 :             rRec.nHelpline1Len=aPt1.Y()-aPt.Y();
     923           0 :             if (bBelow) rRec.nHelpline1Len=-rRec.nHelpline1Len;
     924           0 :             if (bOrtho) rRec.nHelpline2Len=rRec.nHelpline1Len;
     925           0 :         } break;
     926             :         case 1: {
     927           0 :             RotatePoint(aPt,aPt2,nSin,-nCos);
     928           0 :             rRec.nHelpline2Len=aPt2.Y()-aPt.Y();
     929           0 :             if (bBelow) rRec.nHelpline2Len=-rRec.nHelpline2Len;
     930           0 :             if (bOrtho) rRec.nHelpline1Len=rRec.nHelpline2Len;
     931           0 :         } break;
     932             :         case 2: case 3: {
     933           0 :             bool bAnf=nHdlNum==2;
     934           0 :             Point& rMov=bAnf ? rRec.aPt1 : rRec.aPt2;
     935           0 :             Point aMov(rMov);
     936           0 :             Point aFix(bAnf ? rRec.aPt2 : rRec.aPt1);
     937           0 :             if (bOrtho) {
     938           0 :                 long ndx0=aMov.X()-aFix.X();
     939           0 :                 long ndy0=aMov.Y()-aFix.Y();
     940           0 :                 bool bHLin=ndy0==0;
     941           0 :                 bool bVLin=ndx0==0;
     942           0 :                 if (!bHLin || !bVLin) { // else aPt1==aPt2
     943           0 :                     long ndx=aPt.X()-aFix.X();
     944           0 :                     long ndy=aPt.Y()-aFix.Y();
     945           0 :                     double nXFact=0; if (!bVLin) nXFact=(double)ndx/(double)ndx0;
     946           0 :                     double nYFact=0; if (!bHLin) nYFact=(double)ndy/(double)ndy0;
     947           0 :                     bool bHor=bHLin || (!bVLin && (nXFact>nYFact) ==bBigOrtho);
     948           0 :                     bool bVer=bVLin || (!bHLin && (nXFact<=nYFact)==bBigOrtho);
     949           0 :                     if (bHor) ndy=long(ndy0*nXFact);
     950           0 :                     if (bVer) ndx=long(ndx0*nYFact);
     951           0 :                     aPt=aFix;
     952           0 :                     aPt.X()+=ndx;
     953           0 :                     aPt.Y()+=ndy;
     954             :                 } // else Ortho8
     955             :             }
     956           0 :             rMov=aPt;
     957           0 :         } break;
     958             :         case 4: case 5: {
     959           0 :             long nVal0=rRec.nLineDist;
     960           0 :             RotatePoint(aPt,(nHdlNum==4 ? aPt1 : aPt2),nSin,-nCos);
     961           0 :             rRec.nLineDist=aPt.Y()- (nHdlNum==4 ? aPt1.Y() : aPt2.Y());
     962           0 :             if (bBelow) rRec.nLineDist=-rRec.nLineDist;
     963           0 :             if (rRec.nLineDist<0) {
     964           0 :                 rRec.nLineDist=-rRec.nLineDist;
     965           0 :                 rRec.bBelowRefEdge=!bBelow;
     966             :             }
     967           0 :             rRec.nLineDist-=rRec.nHelplineOverhang;
     968           0 :             if (bOrtho) rRec.nLineDist=nVal0;
     969           0 :         } break;
     970             :     } // switch
     971           0 : }
     972             : 
     973             : 
     974             : 
     975           0 : bool SdrMeasureObj::BegCreate(SdrDragStat& rStat)
     976             : {
     977           0 :     rStat.SetOrtho8Possible();
     978           0 :     aPt1=rStat.GetStart();
     979           0 :     aPt2=rStat.GetNow();
     980           0 :     SetTextDirty();
     981           0 :     return true;
     982             : }
     983             : 
     984           0 : bool SdrMeasureObj::MovCreate(SdrDragStat& rStat)
     985             : {
     986           0 :     SdrView* pView=rStat.GetView();
     987           0 :     aPt1=rStat.GetStart();
     988           0 :     aPt2=rStat.GetNow();
     989           0 :     if (pView!=NULL && pView->IsCreate1stPointAsCenter()) {
     990           0 :         aPt1+=aPt1;
     991           0 :         aPt1-=rStat.Now();
     992             :     }
     993           0 :     SetTextDirty();
     994           0 :     SetBoundRectDirty();
     995           0 :     bSnapRectDirty=true;
     996           0 :     return true;
     997             : }
     998             : 
     999           0 : bool SdrMeasureObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd)
    1000             : {
    1001           0 :     SetTextDirty();
    1002           0 :     SetRectsDirty();
    1003           0 :     return (eCmd==SDRCREATE_FORCEEND || rStat.GetPointAnz()>=2);
    1004             : }
    1005             : 
    1006           0 : bool SdrMeasureObj::BckCreate(SdrDragStat& /*rStat*/)
    1007             : {
    1008           0 :     return false;
    1009             : }
    1010             : 
    1011           0 : void SdrMeasureObj::BrkCreate(SdrDragStat& /*rStat*/)
    1012             : {
    1013           0 : }
    1014             : 
    1015           0 : basegfx::B2DPolyPolygon SdrMeasureObj::TakeCreatePoly(const SdrDragStat& /*rDrag*/) const
    1016             : {
    1017           0 :     ImpMeasureRec aRec;
    1018           0 :     ImpMeasurePoly aMPol;
    1019             : 
    1020           0 :     ImpTakeAttr(aRec);
    1021           0 :     ImpCalcGeometrics(aRec, aMPol);
    1022             : 
    1023           0 :     return ImpCalcXPoly(aMPol);
    1024             : }
    1025             : 
    1026           0 : Pointer SdrMeasureObj::GetCreatePointer() const
    1027             : {
    1028           0 :     return Pointer(POINTER_CROSS);
    1029             : }
    1030             : 
    1031           6 : void SdrMeasureObj::NbcMove(const Size& rSiz)
    1032             : {
    1033           6 :     SdrTextObj::NbcMove(rSiz);
    1034           6 :     MovePoint(aPt1,rSiz);
    1035           6 :     MovePoint(aPt2,rSiz);
    1036           6 : }
    1037             : 
    1038           1 : void SdrMeasureObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
    1039             : {
    1040           1 :     SdrTextObj::NbcResize(rRef,xFact,yFact);
    1041           1 :     ResizePoint(aPt1,rRef,xFact,yFact);
    1042           1 :     ResizePoint(aPt2,rRef,xFact,yFact);
    1043           1 :     SetTextDirty();
    1044           1 : }
    1045             : 
    1046           0 : void SdrMeasureObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
    1047             : {
    1048           0 :     SdrTextObj::NbcRotate(rRef,nWink,sn,cs);
    1049           0 :     long nLen0=GetLen(aPt2-aPt1);
    1050           0 :     RotatePoint(aPt1,rRef,sn,cs);
    1051           0 :     RotatePoint(aPt2,rRef,sn,cs);
    1052           0 :     long nLen1=GetLen(aPt2-aPt1);
    1053           0 :     if (nLen1!=nLen0) { // rounding error!
    1054           0 :         long dx=aPt2.X()-aPt1.X();
    1055           0 :         long dy=aPt2.Y()-aPt1.Y();
    1056           0 :         dx=BigMulDiv(dx,nLen0,nLen1);
    1057           0 :         dy=BigMulDiv(dy,nLen0,nLen1);
    1058           0 :         if (rRef==aPt2) {
    1059           0 :             aPt1.X()=aPt2.X()-dx;
    1060           0 :             aPt1.Y()=aPt2.Y()-dy;
    1061             :         } else {
    1062           0 :             aPt2.X()=aPt1.X()+dx;
    1063           0 :             aPt2.Y()=aPt1.Y()+dy;
    1064             :         }
    1065             :     }
    1066           0 :     SetRectsDirty();
    1067           0 : }
    1068             : 
    1069           0 : void SdrMeasureObj::NbcMirror(const Point& rRef1, const Point& rRef2)
    1070             : {
    1071           0 :     SdrTextObj::NbcMirror(rRef1,rRef2);
    1072           0 :     MirrorPoint(aPt1,rRef1,rRef2);
    1073           0 :     MirrorPoint(aPt2,rRef1,rRef2);
    1074           0 :     SetRectsDirty();
    1075           0 : }
    1076             : 
    1077           0 : void SdrMeasureObj::NbcShear(const Point& rRef, long nWink, double tn, bool bVShear)
    1078             : {
    1079           0 :     SdrTextObj::NbcShear(rRef,nWink,tn,bVShear);
    1080           0 :     ShearPoint(aPt1,rRef,tn,bVShear);
    1081           0 :     ShearPoint(aPt2,rRef,tn,bVShear);
    1082           0 :     SetRectsDirty();
    1083           0 :     SetTextDirty();
    1084           0 : }
    1085             : 
    1086           0 : long SdrMeasureObj::GetRotateAngle() const
    1087             : {
    1088           0 :     return GetAngle(aPt2-aPt1);
    1089             : }
    1090             : 
    1091           3 : void SdrMeasureObj::RecalcSnapRect()
    1092             : {
    1093           3 :     ImpMeasureRec aRec;
    1094           3 :     ImpMeasurePoly aMPol;
    1095           6 :     XPolyPolygon aXPP;
    1096             : 
    1097           3 :     ImpTakeAttr(aRec);
    1098           3 :     ImpCalcGeometrics(aRec, aMPol);
    1099           3 :     aXPP = XPolyPolygon(ImpCalcXPoly(aMPol));
    1100           6 :     maSnapRect = aXPP.GetBoundRect();
    1101           3 : }
    1102             : 
    1103           0 : sal_uInt32 SdrMeasureObj::GetSnapPointCount() const
    1104             : {
    1105           0 :     return 2L;
    1106             : }
    1107             : 
    1108           0 : Point SdrMeasureObj::GetSnapPoint(sal_uInt32 i) const
    1109             : {
    1110           0 :     if (i==0) return aPt1;
    1111           0 :     else return aPt2;
    1112             : }
    1113             : 
    1114           0 : bool SdrMeasureObj::IsPolyObj() const
    1115             : {
    1116           0 :     return true;
    1117             : }
    1118             : 
    1119           0 : sal_uInt32 SdrMeasureObj::GetPointCount() const
    1120             : {
    1121           0 :     return 2L;
    1122             : }
    1123             : 
    1124           4 : Point SdrMeasureObj::GetPoint(sal_uInt32 i) const
    1125             : {
    1126           4 :      return (0L == i) ? aPt1 : aPt2;
    1127             : }
    1128             : 
    1129           2 : void SdrMeasureObj::NbcSetPoint(const Point& rPnt, sal_uInt32 i)
    1130             : {
    1131           2 :     if (0L == i)
    1132           1 :         aPt1=rPnt;
    1133           2 :     if (1L == i)
    1134           1 :         aPt2=rPnt;
    1135           2 :     SetRectsDirty();
    1136           2 :     SetTextDirty();
    1137           2 : }
    1138             : 
    1139           0 : SdrObjGeoData* SdrMeasureObj::NewGeoData() const
    1140             : {
    1141           0 :     return new SdrMeasureObjGeoData;
    1142             : }
    1143             : 
    1144           0 : void SdrMeasureObj::SaveGeoData(SdrObjGeoData& rGeo) const
    1145             : {
    1146           0 :     SdrTextObj::SaveGeoData(rGeo);
    1147           0 :     SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo;
    1148           0 :     rMGeo.aPt1=aPt1;
    1149           0 :     rMGeo.aPt2=aPt2;
    1150           0 : }
    1151             : 
    1152           0 : void SdrMeasureObj::RestGeoData(const SdrObjGeoData& rGeo)
    1153             : {
    1154           0 :     SdrTextObj::RestGeoData(rGeo);
    1155           0 :     SdrMeasureObjGeoData& rMGeo=(SdrMeasureObjGeoData&)rGeo;
    1156           0 :     aPt1=rMGeo.aPt1;
    1157           0 :     aPt2=rMGeo.aPt2;
    1158           0 :     SetTextDirty();
    1159           0 : }
    1160             : 
    1161           0 : SdrObject* SdrMeasureObj::DoConvertToPolyObj(bool bBezier, bool bAddText) const
    1162             : {
    1163             :     // get XOR Poly as base
    1164           0 :     XPolyPolygon aTmpPolyPolygon(TakeXorPoly());
    1165             : 
    1166             :     // get local ItemSet and StyleSheet
    1167           0 :     SfxItemSet aSet(GetObjectItemSet());
    1168           0 :     SfxStyleSheet* pStyleSheet = GetStyleSheet();
    1169             : 
    1170             :     // prepare group
    1171           0 :     SdrObjGroup* pGroup = new SdrObjGroup;
    1172           0 :     pGroup->SetModel(GetModel());
    1173             : 
    1174             :     // prepare parameters
    1175           0 :     basegfx::B2DPolyPolygon aPolyPoly;
    1176             :     SdrPathObj* pPath;
    1177           0 :     sal_uInt16 nCount(aTmpPolyPolygon.Count());
    1178           0 :     sal_uInt16 nLoopStart(0);
    1179             : 
    1180           0 :     if(nCount == 3)
    1181             :     {
    1182             :         // three lines, first one is the middle one
    1183           0 :         aPolyPoly.clear();
    1184           0 :         aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
    1185             : 
    1186           0 :         pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
    1187           0 :         pPath->SetModel(GetModel());
    1188           0 :         pPath->SetMergedItemSet(aSet);
    1189           0 :         pPath->SetStyleSheet(pStyleSheet, true);
    1190           0 :         pGroup->GetSubList()->NbcInsertObject(pPath);
    1191           0 :         aSet.Put(XLineStartWidthItem(0L));
    1192           0 :         aSet.Put(XLineEndWidthItem(0L));
    1193           0 :         nLoopStart = 1;
    1194             :     }
    1195           0 :     else if(nCount == 4)
    1196             :     {
    1197             :         // four lines, middle line with gap, so there are two lines used
    1198             :         // which have one arrow each
    1199           0 :         sal_Int32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue();
    1200           0 :         aSet.Put(XLineEndWidthItem(0L));
    1201             : 
    1202           0 :         aPolyPoly.clear();
    1203           0 :         aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
    1204           0 :         pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
    1205           0 :         pPath->SetModel(GetModel());
    1206           0 :         pPath->SetMergedItemSet(aSet);
    1207           0 :         pPath->SetStyleSheet(pStyleSheet, true);
    1208             : 
    1209           0 :         pGroup->GetSubList()->NbcInsertObject(pPath);
    1210             : 
    1211           0 :         aSet.Put(XLineEndWidthItem(nEndWidth));
    1212           0 :         aSet.Put(XLineStartWidthItem(0L));
    1213             : 
    1214           0 :         aPolyPoly.clear();
    1215           0 :         aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon());
    1216           0 :         pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
    1217           0 :         pPath->SetModel(GetModel());
    1218           0 :         pPath->SetMergedItemSet(aSet);
    1219           0 :         pPath->SetStyleSheet(pStyleSheet, true);
    1220             : 
    1221           0 :         pGroup->GetSubList()->NbcInsertObject(pPath);
    1222             : 
    1223           0 :         aSet.Put(XLineEndWidthItem(0L));
    1224           0 :         nLoopStart = 2;
    1225             :     }
    1226           0 :     else if(nCount == 5)
    1227             :     {
    1228             :         // five lines, first two are the outer ones
    1229           0 :         sal_Int32 nEndWidth = ((const XLineEndWidthItem&)(aSet.Get(XATTR_LINEENDWIDTH))).GetValue();
    1230             : 
    1231           0 :         aSet.Put(XLineEndWidthItem(0L));
    1232             : 
    1233           0 :         aPolyPoly.clear();
    1234           0 :         aPolyPoly.append(aTmpPolyPolygon[0].getB2DPolygon());
    1235           0 :         pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
    1236           0 :         pPath->SetModel(GetModel());
    1237           0 :         pPath->SetMergedItemSet(aSet);
    1238           0 :         pPath->SetStyleSheet(pStyleSheet, true);
    1239             : 
    1240           0 :         pGroup->GetSubList()->NbcInsertObject(pPath);
    1241             : 
    1242           0 :         aSet.Put(XLineEndWidthItem(nEndWidth));
    1243           0 :         aSet.Put(XLineStartWidthItem(0L));
    1244             : 
    1245           0 :         aPolyPoly.clear();
    1246           0 :         aPolyPoly.append(aTmpPolyPolygon[1].getB2DPolygon());
    1247           0 :         pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
    1248           0 :         pPath->SetModel(GetModel());
    1249           0 :         pPath->SetMergedItemSet(aSet);
    1250           0 :         pPath->SetStyleSheet(pStyleSheet, true);
    1251             : 
    1252           0 :         pGroup->GetSubList()->NbcInsertObject(pPath);
    1253             : 
    1254           0 :         aSet.Put(XLineEndWidthItem(0L));
    1255           0 :         nLoopStart = 2;
    1256             :     }
    1257             : 
    1258           0 :     for(;nLoopStart<nCount;nLoopStart++)
    1259             :     {
    1260           0 :         aPolyPoly.clear();
    1261           0 :         aPolyPoly.append(aTmpPolyPolygon[nLoopStart].getB2DPolygon());
    1262           0 :         pPath = new SdrPathObj(OBJ_PATHLINE, aPolyPoly);
    1263           0 :         pPath->SetModel(GetModel());
    1264           0 :         pPath->SetMergedItemSet(aSet);
    1265           0 :         pPath->SetStyleSheet(pStyleSheet, true);
    1266             : 
    1267           0 :         pGroup->GetSubList()->NbcInsertObject(pPath);
    1268             :     }
    1269             : 
    1270           0 :     if(bAddText)
    1271             :     {
    1272           0 :         return ImpConvertAddText(pGroup, bBezier);
    1273             :     }
    1274             :     else
    1275             :     {
    1276           0 :         return pGroup;
    1277           0 :     }
    1278             : }
    1279             : 
    1280           0 : bool SdrMeasureObj::BegTextEdit(SdrOutliner& rOutl)
    1281             : {
    1282           0 :     UndirtyText();
    1283           0 :     return SdrTextObj::BegTextEdit(rOutl);
    1284             : }
    1285             : 
    1286           3 : const Size& SdrMeasureObj::GetTextSize() const
    1287             : {
    1288           3 :     if (bTextDirty) UndirtyText();
    1289           3 :     return SdrTextObj::GetTextSize();
    1290             : }
    1291             : 
    1292          16 : OutlinerParaObject* SdrMeasureObj::GetOutlinerParaObject() const
    1293             : {
    1294          16 :     if(bTextDirty)
    1295           5 :         UndirtyText();
    1296          16 :     return SdrTextObj::GetOutlinerParaObject();
    1297             : }
    1298             : 
    1299           1 : void SdrMeasureObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
    1300             : {
    1301           1 :     SdrTextObj::NbcSetOutlinerParaObject(pTextObject);
    1302           1 :     if(SdrTextObj::GetOutlinerParaObject())
    1303           1 :         SetTextDirty(); // recalculate text
    1304           1 : }
    1305             : 
    1306           0 : void SdrMeasureObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, bool bNoEditText,
    1307             :     Rectangle* pAnchorRect, bool bLineWidth ) const
    1308             : {
    1309           0 :     if (bTextDirty) UndirtyText();
    1310           0 :     SdrTextObj::TakeTextRect( rOutliner, rTextRect, bNoEditText, pAnchorRect, bLineWidth );
    1311           0 : }
    1312             : 
    1313           0 : void SdrMeasureObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
    1314             : {
    1315           0 :     if (bTextDirty) UndirtyText();
    1316           0 :     SdrTextObj::TakeTextAnchorRect(rAnchorRect);
    1317           0 : }
    1318             : 
    1319           0 : void SdrMeasureObj::TakeTextEditArea(Size* pPaperMin, Size* pPaperMax, Rectangle* pViewInit, Rectangle* pViewMin) const
    1320             : {
    1321           0 :     if (bTextDirty) UndirtyText();
    1322           0 :     SdrTextObj::TakeTextEditArea(pPaperMin,pPaperMax,pViewInit,pViewMin);
    1323           0 : }
    1324             : 
    1325           0 : sal_uInt16 SdrMeasureObj::GetOutlinerViewAnchorMode() const
    1326             : {
    1327           0 :     if (bTextDirty) UndirtyText();
    1328           0 :     ImpMeasureRec aRec;
    1329           0 :     ImpMeasurePoly aMPol;
    1330           0 :     ImpTakeAttr(aRec);
    1331           0 :     ImpCalcGeometrics(aRec,aMPol);
    1332             : 
    1333           0 :     SdrTextHorzAdjust eTH=GetTextHorizontalAdjust();
    1334           0 :     SdrTextVertAdjust eTV=GetTextVerticalAdjust();
    1335           0 :     SdrMeasureTextHPos eMH=aMPol.eUsedTextHPos;
    1336           0 :     SdrMeasureTextVPos eMV=aMPol.eUsedTextVPos;
    1337           0 :     bool bTextRota90=aRec.bTextRota90;
    1338           0 :     bool bBelowRefEdge=aRec.bBelowRefEdge;
    1339             : 
    1340             :     // TODO: bTextUpsideDown should be interpreted here!
    1341           0 :     if (!bTextRota90) {
    1342           0 :         if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTH=SDRTEXTHORZADJUST_RIGHT;
    1343           0 :         if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTH=SDRTEXTHORZADJUST_LEFT;
    1344             :         // at eMH==SDRMEASURE_TEXTINSIDE we can anchor horizontally
    1345           0 :         if (eMV==SDRMEASURE_ABOVE) eTV=SDRTEXTVERTADJUST_BOTTOM;
    1346           0 :         if (eMV==SDRMEASURE_BELOW) eTV=SDRTEXTVERTADJUST_TOP;
    1347           0 :         if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTV=SDRTEXTVERTADJUST_CENTER;
    1348             :     } else {
    1349           0 :         if (eMH==SDRMEASURE_TEXTLEFTOUTSIDE) eTV=SDRTEXTVERTADJUST_BOTTOM;
    1350           0 :         if (eMH==SDRMEASURE_TEXTRIGHTOUTSIDE) eTV=SDRTEXTVERTADJUST_TOP;
    1351             :         // at eMH==SDRMEASURE_TEXTINSIDE we can anchor vertically
    1352           0 :         if (!bBelowRefEdge) {
    1353           0 :             if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_LEFT;
    1354           0 :             if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_RIGHT;
    1355             :         } else {
    1356           0 :             if (eMV==SDRMEASURE_ABOVE) eTH=SDRTEXTHORZADJUST_RIGHT;
    1357           0 :             if (eMV==SDRMEASURE_BELOW) eTH=SDRTEXTHORZADJUST_LEFT;
    1358             :         }
    1359           0 :         if (eMV==SDRMEASURETEXT_BREAKEDLINE || eMV==SDRMEASURETEXT_VERTICALCENTERED) eTH=SDRTEXTHORZADJUST_CENTER;
    1360             :     }
    1361             : 
    1362           0 :     EVAnchorMode eRet=ANCHOR_BOTTOM_HCENTER;
    1363           0 :     if (eTH==SDRTEXTHORZADJUST_LEFT) {
    1364           0 :         if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_LEFT;
    1365           0 :         else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_LEFT;
    1366           0 :         else eRet=ANCHOR_VCENTER_LEFT;
    1367           0 :     } else if (eTH==SDRTEXTHORZADJUST_RIGHT) {
    1368           0 :         if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_RIGHT;
    1369           0 :         else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_RIGHT;
    1370           0 :         else eRet=ANCHOR_VCENTER_RIGHT;
    1371             :     } else {
    1372           0 :         if (eTV==SDRTEXTVERTADJUST_TOP) eRet=ANCHOR_TOP_HCENTER;
    1373           0 :         else if (eTV==SDRTEXTVERTADJUST_BOTTOM) eRet=ANCHOR_BOTTOM_HCENTER;
    1374           0 :         else eRet=ANCHOR_VCENTER_HCENTER;
    1375             :     }
    1376           0 :     return (sal_uInt16)eRet;
    1377             : }
    1378             : 
    1379             : 
    1380             : // #i97878#
    1381             : // TRGetBaseGeometry/TRSetBaseGeometry needs to be based on two positions,
    1382             : // same as line geometry in SdrPathObj. Thus needs to be overloaded and
    1383             : // implemented since currently it is derived from SdrTextObj which uses
    1384             : // a functionality based on SnapRect which is not useful here
    1385             : 
    1386           0 : bool SdrMeasureObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
    1387             : {
    1388             :     // handle the same as a simple line since the definition is based on two points
    1389           0 :     const basegfx::B2DRange aRange(aPt1.X(), aPt1.Y(), aPt2.X(), aPt2.Y());
    1390           0 :     basegfx::B2DTuple aScale(aRange.getRange());
    1391           0 :     basegfx::B2DTuple aTranslate(aRange.getMinimum());
    1392             : 
    1393             :     // position maybe relative to anchor position, convert
    1394           0 :     if( pModel->IsWriter() )
    1395             :     {
    1396           0 :         if(GetAnchorPos().X() || GetAnchorPos().Y())
    1397             :         {
    1398           0 :             aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
    1399             :         }
    1400             :     }
    1401             : 
    1402             :     // force MapUnit to 100th mm
    1403           0 :     SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
    1404           0 :     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
    1405             :     {
    1406           0 :         switch(eMapUnit)
    1407             :         {
    1408             :             case SFX_MAPUNIT_TWIP :
    1409             :             {
    1410             :                 // position
    1411           0 :                 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
    1412           0 :                 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
    1413             : 
    1414             :                 // size
    1415           0 :                 aScale.setX(ImplTwipsToMM(aScale.getX()));
    1416           0 :                 aScale.setY(ImplTwipsToMM(aScale.getY()));
    1417             : 
    1418           0 :                 break;
    1419             :             }
    1420             :             default:
    1421             :             {
    1422             :                 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
    1423             :             }
    1424             :         }
    1425             :     }
    1426             : 
    1427             :     // build return value matrix
    1428           0 :     rMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aScale, aTranslate);
    1429             : 
    1430           0 :     return true;
    1431             : }
    1432             : 
    1433           0 : void SdrMeasureObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
    1434             : {
    1435             :     // use given transformation to derive the two defining points from unit line
    1436           0 :     basegfx::B2DPoint aPosA(rMatrix * basegfx::B2DPoint(0.0, 0.0));
    1437           0 :     basegfx::B2DPoint aPosB(rMatrix * basegfx::B2DPoint(1.0, 0.0));
    1438             : 
    1439             :     // force metric to pool metric
    1440           0 :     SfxMapUnit eMapUnit = pModel->GetItemPool().GetMetric(0);
    1441           0 :     if(eMapUnit != SFX_MAPUNIT_100TH_MM)
    1442             :     {
    1443           0 :         switch(eMapUnit)
    1444             :         {
    1445             :             case SFX_MAPUNIT_TWIP :
    1446             :             {
    1447             :                 // position
    1448           0 :                 aPosA.setX(ImplMMToTwips(aPosA.getX()));
    1449           0 :                 aPosA.setY(ImplMMToTwips(aPosA.getY()));
    1450           0 :                 aPosB.setX(ImplMMToTwips(aPosB.getX()));
    1451           0 :                 aPosB.setY(ImplMMToTwips(aPosB.getY()));
    1452             : 
    1453           0 :                 break;
    1454             :             }
    1455             :             default:
    1456             :             {
    1457             :                 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
    1458             :             }
    1459             :         }
    1460             :     }
    1461             : 
    1462           0 :     if( pModel->IsWriter() )
    1463             :     {
    1464             :         // if anchor is used, make position relative to it
    1465           0 :         if(GetAnchorPos().X() || GetAnchorPos().Y())
    1466             :         {
    1467           0 :             const basegfx::B2DVector aAnchorOffset(GetAnchorPos().X(), GetAnchorPos().Y());
    1468             : 
    1469           0 :             aPosA += aAnchorOffset;
    1470           0 :             aPosB += aAnchorOffset;
    1471             :         }
    1472             :     }
    1473             : 
    1474             :     // derive new model data
    1475           0 :     const Point aNewPt1(basegfx::fround(aPosA.getX()), basegfx::fround(aPosA.getY()));
    1476           0 :     const Point aNewPt2(basegfx::fround(aPosB.getX()), basegfx::fround(aPosB.getY()));
    1477             : 
    1478           0 :     if(aNewPt1 != aPt1 || aNewPt2 != aPt2)
    1479             :     {
    1480             :         // set model values and broadcast
    1481           0 :         Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
    1482             : 
    1483           0 :         aPt1 = aNewPt1;
    1484           0 :         aPt2 = aNewPt2;
    1485             : 
    1486           0 :         SetTextDirty();
    1487           0 :         ActionChanged();
    1488           0 :         SetChanged();
    1489           0 :         BroadcastObjectChange();
    1490           0 :         SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
    1491           0 :     }
    1492           0 : }
    1493             : 
    1494             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10