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

Generated by: LCOV version 1.11