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

Generated by: LCOV version 1.10