1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "svdconv.hxx"
21 #include "svdglob.hxx"
22 #include "svx/svdstr.hrc"
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>
37 #include <svl/smplhint.hxx>
38 #include <svl/style.hxx>
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>
77 SdrMeasureObjGeoData::SdrMeasureObjGeoData() {}
78 SdrMeasureObjGeoData::~SdrMeasureObjGeoData() {}
80 OUString
SdrMeasureObj::TakeRepresentation(SdrMeasureFieldKind eMeasureFieldKind
) const
83 Fraction
aMeasureScale(1, 1);
84 bool bTextRota90(false);
85 bool bShowUnit(false);
86 FieldUnit
eMeasureUnit(FUNIT_NONE
);
87 FieldUnit
eModUIUnit(FUNIT_NONE
);
89 const SfxItemSet
& rSet
= GetMergedItemSet();
90 bTextRota90
= static_cast<const SdrMeasureTextRota90Item
&>(rSet
.Get(SDRATTR_MEASURETEXTROTA90
)).GetValue();
91 eMeasureUnit
= static_cast<const SdrMeasureUnitItem
&>(rSet
.Get(SDRATTR_MEASUREUNIT
)).GetValue();
92 aMeasureScale
= static_cast<const SdrMeasureScaleItem
&>(rSet
.Get(SDRATTR_MEASURESCALE
)).GetValue();
93 bShowUnit
= static_cast<const SdrYesNoItem
&>(rSet
.Get(SDRATTR_MEASURESHOWUNIT
)).GetValue();
94 sal_Int16 nNumDigits
= static_cast<const SdrMeasureDecimalPlacesItem
&>(rSet
.Get(SDRATTR_MEASUREDECIMALPLACES
)).GetValue();
96 switch(eMeasureFieldKind
)
98 case SDRMEASUREFIELD_VALUE
:
102 eModUIUnit
= pModel
->GetUIUnit();
104 if(eMeasureUnit
== FUNIT_NONE
)
105 eMeasureUnit
= eModUIUnit
;
107 sal_Int32
nLen(GetLen(aPt2
- aPt1
));
110 if(eMeasureUnit
!= eModUIUnit
)
112 // for the unit conversion
113 aFact
*= GetMapFactor(eModUIUnit
, eMeasureUnit
).X();
116 if(aMeasureScale
.GetNumerator() != aMeasureScale
.GetDenominator())
118 aFact
*= aMeasureScale
;
121 if(aFact
.GetNumerator() != aFact
.GetDenominator())
123 // scale via BigInt, to avoid overruns
124 nLen
= BigMulDiv(nLen
, aFact
.GetNumerator(), aFact
.GetDenominator());
128 pModel
->TakeMetricStr(nLen
, aTmp
, true, nNumDigits
);
136 sal_Unicode
cDec(SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]);
138 if(aStr
.indexOf(cDec
) != -1)
140 sal_Int32
nLen2(aStr
.getLength() - 1);
142 while(aStr
[nLen2
] == '0')
144 aStr
= aStr
.copy(0, nLen2
);
148 if(aStr
[nLen2
] == cDec
)
150 aStr
= aStr
.copy(0, nLen2
);
160 // if there's no Model ... (e. g. preview in dialog)
166 case SDRMEASUREFIELD_UNIT
:
172 eModUIUnit
= pModel
->GetUIUnit();
174 if(eMeasureUnit
== FUNIT_NONE
)
175 eMeasureUnit
= eModUIUnit
;
178 SdrModel::TakeUnitStr(eMeasureUnit
, aStr
);
184 case SDRMEASUREFIELD_ROTA90BLANCS
:
198 // BaseProperties section
200 sdr::properties::BaseProperties
* SdrMeasureObj::CreateObjectSpecificProperties()
202 return new sdr::properties::MeasureProperties(*this);
206 // DrawContact section
208 sdr::contact::ViewContact
* SdrMeasureObj::CreateObjectSpecificViewContact()
210 return new sdr::contact::ViewContactOfSdrMeasureObj(*this);
215 TYPEINIT1(SdrMeasureObj
,SdrTextObj
);
217 SdrMeasureObj::SdrMeasureObj():
221 mbSupportTextIndentingOnLineWidthChange
= false;
224 SdrMeasureObj::SdrMeasureObj(const Point
& rPt1
, const Point
& rPt2
):
230 mbSupportTextIndentingOnLineWidthChange
= false;
233 SdrMeasureObj::~SdrMeasureObj()
237 void SdrMeasureObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
239 rInfo
.bSelectAllowed
=true;
240 rInfo
.bMoveAllowed
=true;
241 rInfo
.bResizeFreeAllowed
=true;
242 rInfo
.bResizePropAllowed
=true;
243 rInfo
.bRotateFreeAllowed
=true;
244 rInfo
.bRotate90Allowed
=true;
245 rInfo
.bMirrorFreeAllowed
=true;
246 rInfo
.bMirror45Allowed
=true;
247 rInfo
.bMirror90Allowed
=true;
248 rInfo
.bTransparenceAllowed
= false;
249 rInfo
.bGradientAllowed
= false;
250 rInfo
.bShearAllowed
=true;
251 rInfo
.bEdgeRadiusAllowed
=false;
252 rInfo
.bNoOrthoDesired
=true;
253 rInfo
.bNoContortion
=false;
254 rInfo
.bCanConvToPath
=false;
255 rInfo
.bCanConvToPoly
=true;
256 rInfo
.bCanConvToPathLineToArea
=false;
257 rInfo
.bCanConvToPolyLineToArea
=false;
258 rInfo
.bCanConvToContour
= (rInfo
.bCanConvToPoly
|| LineGeometryUsageIsNecessary());
261 sal_uInt16
SdrMeasureObj::GetObjIdentifier() const
263 return (sal_uInt16
)OBJ_MEASURE
;
266 struct ImpMeasureRec
: public SdrDragStatUserData
270 SdrMeasureKind eKind
;
271 SdrMeasureTextHPos eWantTextHPos
;
272 SdrMeasureTextVPos eWantTextVPos
;
274 long nHelplineOverhang
;
280 bool bTextUpsideDown
;
281 long nMeasureOverhang
;
282 FieldUnit eMeasureUnit
;
283 Fraction aMeasureScale
;
285 OUString aFormatString
;
287 long nTextAutoAngleView
;
288 bool bTextIsFixedAngle
;
289 long nTextFixedAngle
;
298 struct ImpMeasurePoly
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
;
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
331 void SdrMeasureObj::ImpTakeAttr(ImpMeasureRec
& rRec
) const
336 const SfxItemSet
& rSet
= GetObjectItemSet();
337 rRec
.eKind
=static_cast<const SdrMeasureKindItem
& >(rSet
.Get(SDRATTR_MEASUREKIND
)).GetValue();
338 rRec
.eWantTextHPos
=static_cast<const SdrMeasureTextHPosItem
& >(rSet
.Get(SDRATTR_MEASURETEXTHPOS
)).GetValue();
339 rRec
.eWantTextVPos
=static_cast<const SdrMeasureTextVPosItem
& >(rSet
.Get(SDRATTR_MEASURETEXTVPOS
)).GetValue();
340 rRec
.nLineDist
=static_cast<const SdrMetricItem
& >(rSet
.Get(SDRATTR_MEASURELINEDIST
)).GetValue();
341 rRec
.nHelplineOverhang
=static_cast<const SdrMetricItem
& >(rSet
.Get(SDRATTR_MEASUREHELPLINEOVERHANG
)).GetValue();
342 rRec
.nHelplineDist
=static_cast<const SdrMetricItem
& >(rSet
.Get(SDRATTR_MEASUREHELPLINEDIST
)).GetValue();
343 rRec
.nHelpline1Len
=static_cast<const SdrMetricItem
& >(rSet
.Get(SDRATTR_MEASUREHELPLINE1LEN
)).GetValue();
344 rRec
.nHelpline2Len
=static_cast<const SdrMetricItem
& >(rSet
.Get(SDRATTR_MEASUREHELPLINE2LEN
)).GetValue();
345 rRec
.bBelowRefEdge
=static_cast<const SdrMeasureBelowRefEdgeItem
& >(rSet
.Get(SDRATTR_MEASUREBELOWREFEDGE
)).GetValue();
346 rRec
.bTextRota90
=static_cast<const SdrMeasureTextRota90Item
& >(rSet
.Get(SDRATTR_MEASURETEXTROTA90
)).GetValue();
347 rRec
.bTextUpsideDown
=static_cast<const SdrMeasureTextUpsideDownItem
& >(rSet
.Get(SDRATTR_MEASURETEXTUPSIDEDOWN
)).GetValue();
348 rRec
.nMeasureOverhang
=static_cast<const SdrMeasureOverhangItem
& >(rSet
.Get(SDRATTR_MEASUREOVERHANG
)).GetValue();
349 rRec
.eMeasureUnit
=static_cast<const SdrMeasureUnitItem
& >(rSet
.Get(SDRATTR_MEASUREUNIT
)).GetValue();
350 rRec
.aMeasureScale
=static_cast<const SdrMeasureScaleItem
& >(rSet
.Get(SDRATTR_MEASURESCALE
)).GetValue();
351 rRec
.bShowUnit
=static_cast<const SdrYesNoItem
& >(rSet
.Get(SDRATTR_MEASURESHOWUNIT
)).GetValue();
352 rRec
.aFormatString
=static_cast<const SdrMeasureFormatStringItem
& >(rSet
.Get(SDRATTR_MEASUREFORMATSTRING
)).GetValue();
353 rRec
.bTextAutoAngle
=static_cast<const SdrMeasureTextAutoAngleItem
& >(rSet
.Get(SDRATTR_MEASURETEXTAUTOANGLE
)).GetValue();
354 rRec
.nTextAutoAngleView
=static_cast<const SdrMeasureTextAutoAngleViewItem
&>(rSet
.Get(SDRATTR_MEASURETEXTAUTOANGLEVIEW
)).GetValue();
355 rRec
.bTextIsFixedAngle
=static_cast<const SdrMeasureTextIsFixedAngleItem
& >(rSet
.Get(SDRATTR_MEASURETEXTISFIXEDANGLE
)).GetValue();
356 rRec
.nTextFixedAngle
=static_cast<const SdrMeasureTextFixedAngleItem
& >(rSet
.Get(SDRATTR_MEASURETEXTFIXEDANGLE
)).GetValue();
359 long impGetLineStartEndDistance(const basegfx::B2DPolyPolygon
& rPolyPolygon
, long nNewWidth
, bool bCenter
)
361 const basegfx::B2DRange
aPolygonRange(rPolyPolygon
.getB2DRange());
362 const double fOldWidth(aPolygonRange
.getWidth() > 1.0 ? aPolygonRange
.getWidth() : 1.0);
363 const double fScale((double)nNewWidth
/ fOldWidth
);
364 long nHeight(basegfx::fround(aPolygonRange
.getHeight() * fScale
));
374 void SdrMeasureObj::ImpCalcGeometrics(const ImpMeasureRec
& rRec
, ImpMeasurePoly
& rPol
) const
376 Point
aP1(rRec
.aPt1
);
377 Point
aP2(rRec
.aPt2
);
378 Point
aDelt(aP2
); aDelt
-=aP1
;
380 rPol
.aTextSize
=GetTextSize();
381 rPol
.nLineLen
=GetLen(aDelt
);
384 long nArrow1Len
=0; bool bArrow1Center
=false;
385 long nArrow2Len
=0; bool bArrow2Center
=false;
392 bool bPfeileAussen
= false;
394 const SfxItemSet
& rSet
= GetObjectItemSet();
395 sal_Int32 nLineWdt
= static_cast<const XLineWidthItem
&>(rSet
.Get(XATTR_LINEWIDTH
)).GetValue(); // line width
396 rPol
.nLineWdt2
= (nLineWdt
+ 1) / 2;
398 nArrow1Wdt
= static_cast<const XLineStartWidthItem
&>(rSet
.Get(XATTR_LINESTARTWIDTH
)).GetValue();
400 nArrow1Wdt
= -nLineWdt
* nArrow1Wdt
/ 100; // <0 = relativ
402 nArrow2Wdt
= static_cast<const XLineEndWidthItem
&>(rSet
.Get(XATTR_LINEENDWIDTH
)).GetValue();
404 nArrow2Wdt
= -nLineWdt
* nArrow2Wdt
/ 100; // <0 = relativ
406 basegfx::B2DPolyPolygon
aPol1(static_cast<const XLineStartItem
&>(rSet
.Get(XATTR_LINESTART
)).GetLineStartValue());
407 basegfx::B2DPolyPolygon
aPol2(static_cast<const XLineEndItem
&>(rSet
.Get(XATTR_LINEEND
)).GetLineEndValue());
408 bArrow1Center
= static_cast<const XLineStartCenterItem
&>(rSet
.Get(XATTR_LINESTARTCENTER
)).GetValue();
409 bArrow2Center
= static_cast<const XLineEndCenterItem
&>(rSet
.Get(XATTR_LINEENDCENTER
)).GetValue();
410 nArrow1Len
= impGetLineStartEndDistance(aPol1
, nArrow1Wdt
, bArrow1Center
) - 1;
411 nArrow2Len
= impGetLineStartEndDistance(aPol2
, nArrow2Wdt
, bArrow2Center
) - 1;
413 // nArrowLen is already halved at bCenter.
414 // In the case of 2 arrowheads each 4mm long, we can't go below 10mm.
415 nArrowNeed
=nArrow1Len
+nArrow2Len
+(nArrow1Wdt
+nArrow2Wdt
)/2;
416 if (rPol
.nLineLen
<nArrowNeed
) bPfeileAussen
= true;
417 nShortLen
=(nArrow1Len
+nArrow1Wdt
+ nArrow2Len
+nArrow2Wdt
) /2;
419 rPol
.eUsedTextHPos
=rRec
.eWantTextHPos
;
420 rPol
.eUsedTextVPos
=rRec
.eWantTextVPos
;
421 if (rPol
.eUsedTextVPos
==SDRMEASURE_TEXTVAUTO
) rPol
.eUsedTextVPos
=SDRMEASURE_ABOVE
;
422 bool bBrkLine
=rPol
.eUsedTextVPos
==SDRMEASURETEXT_BREAKEDLINE
;
423 if (rPol
.eUsedTextVPos
==SDRMEASURETEXT_VERTICALCENTERED
)
425 OutlinerParaObject
* pOutlinerParaObject
= SdrTextObj::GetOutlinerParaObject();
426 if (pOutlinerParaObject
!=NULL
&& pOutlinerParaObject
->GetTextObject().GetParagraphCount()==1)
428 bBrkLine
=true; // dashed line if there's only on paragraph.
431 rPol
.bBreakedLine
=bBrkLine
;
432 if (rPol
.eUsedTextHPos
==SDRMEASURE_TEXTHAUTO
) { // if text is too wide, push it outside
433 bool bOutside
= false;
434 long nNeedSiz
=!rRec
.bTextRota90
? rPol
.aTextSize
.Width() : rPol
.aTextSize
.Height();
435 if (nNeedSiz
>rPol
.nLineLen
) bOutside
= true; // text doesn't fit in between
437 if (nNeedSiz
+nArrowNeed
>rPol
.nLineLen
) bPfeileAussen
= true; // text fits in between, if arrowheads are on the outside
439 long nSmallNeed
=nArrow1Len
+nArrow2Len
+(nArrow1Wdt
+nArrow2Wdt
)/2/4;
440 if (nNeedSiz
+nSmallNeed
>rPol
.nLineLen
) bPfeileAussen
= true; // text fits in between, if arrowheads are on the outside
442 rPol
.eUsedTextHPos
=bOutside
? SDRMEASURE_TEXTLEFTOUTSIDE
: SDRMEASURE_TEXTINSIDE
;
444 if (rPol
.eUsedTextHPos
!=SDRMEASURE_TEXTINSIDE
) bPfeileAussen
= true;
445 rPol
.nArrow1Wdt
=nArrow1Wdt
;
446 rPol
.nArrow2Wdt
=nArrow2Wdt
;
447 rPol
.nShortLineLen
=nShortLen
;
448 rPol
.bPfeileAussen
=bPfeileAussen
;
449 rPol
.nArrow1Len
=nArrow1Len
;
450 rPol
.bArrow1Center
=bArrow1Center
;
451 rPol
.nArrow2Len
=nArrow2Len
;
452 rPol
.bArrow2Center
=bArrow2Center
;
454 rPol
.nLineAngle
=GetAngle(aDelt
);
455 double a
=rPol
.nLineAngle
*nPi180
;
456 double nLineSin
=sin(a
);
457 double nLineCos
=cos(a
);
458 rPol
.nLineSin
=nLineSin
;
459 rPol
.nLineCos
=nLineCos
;
461 rPol
.nTextAngle
=rPol
.nLineAngle
;
462 if (rRec
.bTextRota90
) rPol
.nTextAngle
+=9000;
464 rPol
.bAutoUpsideDown
=false;
465 if (rRec
.bTextAutoAngle
) {
466 long nTmpAngle
=NormAngle360(rPol
.nTextAngle
-rRec
.nTextAutoAngleView
);
467 if (nTmpAngle
>=18000) {
468 rPol
.nTextAngle
+=18000;
469 rPol
.bAutoUpsideDown
=true;
473 if (rRec
.bTextUpsideDown
) rPol
.nTextAngle
+=18000;
474 rPol
.nTextAngle
=NormAngle360(rPol
.nTextAngle
);
475 rPol
.nHlpAngle
=rPol
.nLineAngle
+9000;
476 if (rRec
.bBelowRefEdge
) rPol
.nHlpAngle
+=18000;
477 rPol
.nHlpAngle
=NormAngle360(rPol
.nHlpAngle
);
478 double nHlpSin
=nLineCos
;
479 double nHlpCos
=-nLineSin
;
480 if (rRec
.bBelowRefEdge
) {
484 rPol
.nHlpSin
=nHlpSin
;
485 rPol
.nHlpCos
=nHlpCos
;
487 long nLineDist
=rRec
.nLineDist
;
488 long nOverhang
=rRec
.nHelplineOverhang
;
489 long nHelplineDist
=rRec
.nHelplineDist
;
491 long dx
= Round(nLineDist
*nHlpCos
);
492 long dy
=-Round(nLineDist
*nHlpSin
);
493 long dxh1a
= Round((nHelplineDist
-rRec
.nHelpline1Len
)*nHlpCos
);
494 long dyh1a
=-Round((nHelplineDist
-rRec
.nHelpline1Len
)*nHlpSin
);
495 long dxh1b
= Round((nHelplineDist
-rRec
.nHelpline2Len
)*nHlpCos
);
496 long dyh1b
=-Round((nHelplineDist
-rRec
.nHelpline2Len
)*nHlpSin
);
497 long dxh2
= Round((nLineDist
+nOverhang
)*nHlpCos
);
498 long dyh2
=-Round((nLineDist
+nOverhang
)*nHlpSin
);
501 rPol
.aHelpline1
.aP1
=Point(aP1
.X()+dxh1a
,aP1
.Y()+dyh1a
);
502 rPol
.aHelpline1
.aP2
=Point(aP1
.X()+dxh2
,aP1
.Y()+dyh2
);
505 rPol
.aHelpline2
.aP1
=Point(aP2
.X()+dxh1b
,aP2
.Y()+dyh1b
);
506 rPol
.aHelpline2
.aP2
=Point(aP2
.X()+dxh2
,aP2
.Y()+dyh2
);
509 Point
aMainlinePt1(aP1
.X()+dx
,aP1
.Y()+dy
);
510 Point
aMainlinePt2(aP2
.X()+dx
,aP2
.Y()+dy
);
511 if (!bPfeileAussen
) {
512 rPol
.aMainline1
.aP1
=aMainlinePt1
;
513 rPol
.aMainline1
.aP2
=aMainlinePt2
;
514 rPol
.aMainline2
=rPol
.aMainline1
;
515 rPol
.aMainline3
=rPol
.aMainline1
;
518 long nNeedSiz
=!rRec
.bTextRota90
? rPol
.aTextSize
.Width() : rPol
.aTextSize
.Height();
519 long nHalfLen
=(rPol
.nLineLen
-nNeedSiz
-nArrow1Wdt
/4-nArrow2Wdt
/4) /2;
521 rPol
.aMainline1
.aP2
=aMainlinePt1
;
522 rPol
.aMainline1
.aP2
.X()+=nHalfLen
;
523 RotatePoint(rPol
.aMainline1
.aP2
,rPol
.aMainline1
.aP1
,nLineSin
,nLineCos
);
524 rPol
.aMainline2
.aP1
=aMainlinePt2
;
525 rPol
.aMainline2
.aP1
.X()-=nHalfLen
;
526 RotatePoint(rPol
.aMainline2
.aP1
,rPol
.aMainline2
.aP2
,nLineSin
,nLineCos
);
529 long nLen1
=nShortLen
; // arrowhead's width as line length outside of the arrowhead
530 long nLen2
=nShortLen
;
531 long nTextWdt
=rRec
.bTextRota90
? rPol
.aTextSize
.Height() : rPol
.aTextSize
.Width();
533 if (rPol
.eUsedTextHPos
==SDRMEASURE_TEXTLEFTOUTSIDE
) nLen1
=nArrow1Len
+nTextWdt
;
534 if (rPol
.eUsedTextHPos
==SDRMEASURE_TEXTRIGHTOUTSIDE
) nLen2
=nArrow2Len
+nTextWdt
;
536 rPol
.aMainline1
.aP1
=aMainlinePt1
;
537 rPol
.aMainline1
.aP2
=aMainlinePt1
; rPol
.aMainline1
.aP2
.X()-=nLen1
; RotatePoint(rPol
.aMainline1
.aP2
,aMainlinePt1
,nLineSin
,nLineCos
);
538 rPol
.aMainline2
.aP1
=aMainlinePt2
; rPol
.aMainline2
.aP1
.X()+=nLen2
; RotatePoint(rPol
.aMainline2
.aP1
,aMainlinePt2
,nLineSin
,nLineCos
);
539 rPol
.aMainline2
.aP2
=aMainlinePt2
;
540 rPol
.aMainline3
.aP1
=aMainlinePt1
;
541 rPol
.aMainline3
.aP2
=aMainlinePt2
;
543 if (bBrkLine
&& rPol
.eUsedTextHPos
==SDRMEASURE_TEXTINSIDE
) rPol
.nMainlineAnz
=2;
547 basegfx::B2DPolyPolygon
SdrMeasureObj::ImpCalcXPoly(const ImpMeasurePoly
& rPol
)
549 basegfx::B2DPolyPolygon aRetval
;
550 basegfx::B2DPolygon aPartPolyA
;
551 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aMainline1
.aP1
.X(), rPol
.aMainline1
.aP1
.Y()));
552 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aMainline1
.aP2
.X(), rPol
.aMainline1
.aP2
.Y()));
553 aRetval
.append(aPartPolyA
);
555 if(rPol
.nMainlineAnz
> 1)
558 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aMainline2
.aP1
.X(), rPol
.aMainline2
.aP1
.Y()));
559 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aMainline2
.aP2
.X(), rPol
.aMainline2
.aP2
.Y()));
560 aRetval
.append(aPartPolyA
);
563 if(rPol
.nMainlineAnz
> 2)
566 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aMainline3
.aP1
.X(), rPol
.aMainline3
.aP1
.Y()));
567 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aMainline3
.aP2
.X(), rPol
.aMainline3
.aP2
.Y()));
568 aRetval
.append(aPartPolyA
);
572 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aHelpline1
.aP1
.X(), rPol
.aHelpline1
.aP1
.Y()));
573 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aHelpline1
.aP2
.X(), rPol
.aHelpline1
.aP2
.Y()));
574 aRetval
.append(aPartPolyA
);
577 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aHelpline2
.aP1
.X(), rPol
.aHelpline2
.aP1
.Y()));
578 aPartPolyA
.append(basegfx::B2DPoint(rPol
.aHelpline2
.aP2
.X(), rPol
.aHelpline2
.aP2
.Y()));
579 aRetval
.append(aPartPolyA
);
584 bool SdrMeasureObj::CalcFieldValue(const SvxFieldItem
& rField
, sal_Int32 nPara
, sal_uInt16 nPos
,
586 Color
*& rpTxtColor
, Color
*& rpFldColor
, OUString
& rRet
) const
588 const SvxFieldData
* pField
=rField
.GetField();
589 const SdrMeasureField
* pMeasureField
=PTR_CAST(SdrMeasureField
,pField
);
590 if (pMeasureField
!=NULL
) {
591 rRet
= TakeRepresentation(pMeasureField
->GetMeasureFieldKind());
592 if (rpFldColor
!=NULL
) {
601 return SdrTextObj::CalcFieldValue(rField
,nPara
,nPos
,bEdit
,rpTxtColor
,rpFldColor
,rRet
);
605 void SdrMeasureObj::UndirtyText() const
609 SdrOutliner
& rOutliner
=ImpGetDrawOutliner();
610 OutlinerParaObject
* pOutlinerParaObject
= SdrTextObj::GetOutlinerParaObject();
611 if(pOutlinerParaObject
==NULL
)
613 rOutliner
.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS
), EE_FEATURE_FIELD
), ESelection(0,0));
614 rOutliner
.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_VALUE
), EE_FEATURE_FIELD
),ESelection(0,1));
615 rOutliner
.QuickInsertText(" ", ESelection(0,2));
616 rOutliner
.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_UNIT
), EE_FEATURE_FIELD
),ESelection(0,3));
617 rOutliner
.QuickInsertField(SvxFieldItem(SdrMeasureField(SDRMEASUREFIELD_ROTA90BLANCS
), EE_FEATURE_FIELD
),ESelection(0,4));
620 rOutliner
.SetStyleSheet(0, GetStyleSheet());
622 rOutliner
.SetParaAttribs(0, GetObjectItemSet());
625 const_cast<SdrMeasureObj
*>(this)->NbcSetOutlinerParaObject( rOutliner
.CreateParaObject() );
629 rOutliner
.SetText(*pOutlinerParaObject
);
632 rOutliner
.SetUpdateMode(true);
633 rOutliner
.UpdateFields();
634 Size
aSiz(rOutliner
.CalcTextSize());
636 // cast to nonconst three times
637 const_cast<SdrMeasureObj
*>(this)->aTextSize
=aSiz
;
638 const_cast<SdrMeasureObj
*>(this)->bTextSizeDirty
=false;
639 const_cast<SdrMeasureObj
*>(this)->bTextDirty
=false;
643 void SdrMeasureObj::TakeUnrotatedSnapRect(Rectangle
& rRect
) const
645 if (bTextDirty
) UndirtyText();
647 ImpMeasurePoly aMPol
;
649 ImpCalcGeometrics(aRec
,aMPol
);
651 // determine TextSize including text frame margins
652 Size
aTextSize2(aMPol
.aTextSize
);
653 if (aTextSize2
.Width()<1) aTextSize2
.Width()=1;
654 if (aTextSize2
.Height()<1) aTextSize2
.Height()=1;
655 aTextSize2
.Width()+=GetTextLeftDistance()+GetTextRightDistance();
656 aTextSize2
.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
658 Point
aPt1b(aMPol
.aMainline1
.aP1
);
659 long nLen
=aMPol
.nLineLen
;
660 long nLWdt
=aMPol
.nLineWdt2
;
661 long nArr1Len
=aMPol
.nArrow1Len
;
662 long nArr2Len
=aMPol
.nArrow2Len
;
663 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
667 nArr1Len
=aMPol
.nShortLineLen
+aMPol
.nArrow1Wdt
/4;
668 nArr2Len
=aMPol
.nShortLineLen
+aMPol
.nArrow2Wdt
/4;
672 bool bRota90
=aRec
.bTextRota90
;
673 bool bUpsideDown
=aRec
.bTextUpsideDown
!=aMPol
.bAutoUpsideDown
;
674 bool bBelowRefEdge
=aRec
.bBelowRefEdge
;
675 SdrMeasureTextHPos eMH
=aMPol
.eUsedTextHPos
;
676 SdrMeasureTextVPos eMV
=aMPol
.eUsedTextVPos
;
679 case SDRMEASURE_TEXTLEFTOUTSIDE
: aTextPos
.X()=aPt1b
.X()-aTextSize2
.Width()-nArr1Len
-nLWdt
; break;
680 case SDRMEASURE_TEXTRIGHTOUTSIDE
: aTextPos
.X()=aPt1b
.X()+nLen
+nArr2Len
+nLWdt
; break;
681 default: aTextPos
.X()=aPt1b
.X(); aTextSize2
.Width()=nLen
;
684 case SDRMEASURETEXT_VERTICALCENTERED
:
685 case SDRMEASURETEXT_BREAKEDLINE
: aTextPos
.Y()=aPt1b
.Y()-aTextSize2
.Height()/2; break;
686 case SDRMEASURE_BELOW
: {
687 if (!bUpsideDown
) aTextPos
.Y()=aPt1b
.Y()+nLWdt
;
688 else aTextPos
.Y()=aPt1b
.Y()-aTextSize2
.Height()-nLWdt
;
691 if (!bUpsideDown
) aTextPos
.Y()=aPt1b
.Y()-aTextSize2
.Height()-nLWdt
;
692 else aTextPos
.Y()=aPt1b
.Y()+nLWdt
;
696 aTextPos
.X()+=aTextSize2
.Width();
697 aTextPos
.Y()+=aTextSize2
.Height();
699 } else { // also if bTextRota90==TRUE
701 case SDRMEASURE_TEXTLEFTOUTSIDE
: aTextPos
.X()=aPt1b
.X()-aTextSize2
.Height()-nArr1Len
; break;
702 case SDRMEASURE_TEXTRIGHTOUTSIDE
: aTextPos
.X()=aPt1b
.X()+nLen
+nArr2Len
; break;
703 default: aTextPos
.X()=aPt1b
.X(); aTextSize2
.Height()=nLen
;
706 case SDRMEASURETEXT_VERTICALCENTERED
:
707 case SDRMEASURETEXT_BREAKEDLINE
: aTextPos
.Y()=aPt1b
.Y()+aTextSize2
.Width()/2; break;
708 case SDRMEASURE_BELOW
: {
709 if (!bBelowRefEdge
) aTextPos
.Y()=aPt1b
.Y()+aTextSize2
.Width()+nLWdt
;
710 else aTextPos
.Y()=aPt1b
.Y()-nLWdt
;
713 if (!bBelowRefEdge
) aTextPos
.Y()=aPt1b
.Y()-nLWdt
;
714 else aTextPos
.Y()=aPt1b
.Y()+aTextSize2
.Width()+nLWdt
;
718 aTextPos
.X()+=aTextSize2
.Height();
719 aTextPos
.Y()-=aTextSize2
.Width();
722 if (aMPol
.nTextAngle
!=aGeo
.nRotationAngle
) {
723 const_cast<SdrMeasureObj
*>(this)->aGeo
.nRotationAngle
=aMPol
.nTextAngle
;
724 const_cast<SdrMeasureObj
*>(this)->aGeo
.RecalcSinCos();
726 RotatePoint(aTextPos
,aPt1b
,aMPol
.nLineSin
,aMPol
.nLineCos
);
727 aTextSize2
.Width()++; aTextSize2
.Height()++; // because of the Rect-Ctor's odd behavior
728 rRect
=Rectangle(aTextPos
,aTextSize2
);
730 const_cast<SdrMeasureObj
*>(this)->maRect
=rRect
;
732 if (aMPol
.nTextAngle
!=aGeo
.nRotationAngle
) {
733 const_cast<SdrMeasureObj
*>(this)->aGeo
.nRotationAngle
=aMPol
.nTextAngle
;
734 const_cast<SdrMeasureObj
*>(this)->aGeo
.RecalcSinCos();
738 SdrMeasureObj
* SdrMeasureObj::Clone() const
740 return CloneHelper
< SdrMeasureObj
>();
743 OUString
SdrMeasureObj::TakeObjNameSingul() const
745 OUStringBuffer
sName(ImpGetResStr(STR_ObjNameSingulMEASURE
));
747 OUString
aName( GetName() );
748 if (!aName
.isEmpty())
756 return sName
.makeStringAndClear();
759 OUString
SdrMeasureObj::TakeObjNamePlural() const
761 return ImpGetResStr(STR_ObjNamePluralMEASURE
);
764 basegfx::B2DPolyPolygon
SdrMeasureObj::TakeXorPoly() const
767 ImpMeasurePoly aMPol
;
769 ImpCalcGeometrics(aRec
,aMPol
);
770 return ImpCalcXPoly(aMPol
);
773 sal_uInt32
SdrMeasureObj::GetHdlCount() const
778 SdrHdl
* SdrMeasureObj::GetHdl(sal_uInt32 nHdlNum
) const
781 ImpMeasurePoly aMPol
;
783 aRec
.nHelplineDist
=0;
784 ImpCalcGeometrics(aRec
,aMPol
);
788 case 0: aPt
=aMPol
.aHelpline1
.aP1
; break;
789 case 1: aPt
=aMPol
.aHelpline2
.aP1
; break;
790 case 2: aPt
=aPt1
; break;
791 case 3: aPt
=aPt2
; break;
792 case 4: aPt
=aMPol
.aHelpline1
.aP2
; break;
793 case 5: aPt
=aMPol
.aHelpline2
.aP2
; break;
795 SdrHdl
* pHdl
=new ImpMeasureHdl(aPt
,HDL_USER
);
796 pHdl
->SetObjHdlNum(nHdlNum
);
797 pHdl
->SetRotationAngle(aMPol
.nLineAngle
);
803 bool SdrMeasureObj::hasSpecialDrag() const
808 bool SdrMeasureObj::beginSpecialDrag(SdrDragStat
& rDrag
) const
810 const SdrHdl
* pHdl
= rDrag
.GetHdl();
814 const sal_uInt32
nHdlNum(pHdl
->GetObjHdlNum());
816 if(nHdlNum
!= 2 && nHdlNum
!= 3)
818 rDrag
.SetEndDragChangesAttributes(true);
827 bool SdrMeasureObj::applySpecialDrag(SdrDragStat
& rDrag
)
829 ImpMeasureRec aMeasureRec
;
830 const SdrHdl
* pHdl
= rDrag
.GetHdl();
831 const sal_uInt32
nHdlNum(pHdl
->GetObjHdlNum());
833 ImpTakeAttr(aMeasureRec
);
834 ImpEvalDrag(aMeasureRec
, rDrag
);
840 aPt1
= aMeasureRec
.aPt1
;
846 aPt2
= aMeasureRec
.aPt2
;
857 ImpMeasureRec aOrigMeasureRec
;
858 ImpTakeAttr(aOrigMeasureRec
);
860 if(aMeasureRec
.nHelpline1Len
!= aOrigMeasureRec
.nHelpline1Len
)
862 SetObjectItem(makeSdrMeasureHelpline1LenItem(aMeasureRec
.nHelpline1Len
));
865 if(aMeasureRec
.nHelpline2Len
!= aOrigMeasureRec
.nHelpline2Len
)
867 SetObjectItem(makeSdrMeasureHelpline2LenItem(aMeasureRec
.nHelpline2Len
));
876 ImpMeasureRec aOrigMeasureRec
;
877 ImpTakeAttr(aOrigMeasureRec
);
879 if(aMeasureRec
.nLineDist
!= aOrigMeasureRec
.nLineDist
)
881 SetObjectItem(makeSdrMeasureLineDistItem(aMeasureRec
.nLineDist
));
884 if(aMeasureRec
.bBelowRefEdge
!= aOrigMeasureRec
.bBelowRefEdge
)
886 SetObjectItem(SdrMeasureBelowRefEdgeItem(aMeasureRec
.bBelowRefEdge
));
899 OUString
SdrMeasureObj::getSpecialDragComment(const SdrDragStat
& /*rDrag*/) const
904 void SdrMeasureObj::ImpEvalDrag(ImpMeasureRec
& rRec
, const SdrDragStat
& rDrag
) const
906 long nLineAngle
=GetAngle(rRec
.aPt2
-rRec
.aPt1
);
907 double a
=nLineAngle
*nPi180
;
911 const SdrHdl
* pHdl
=rDrag
.GetHdl();
912 sal_uInt32
nHdlNum(pHdl
->GetObjHdlNum());
913 bool bOrtho
=rDrag
.GetView()!=NULL
&& rDrag
.GetView()->IsOrtho();
914 bool bBigOrtho
=bOrtho
&& rDrag
.GetView()->IsBigOrtho();
915 bool bBelow
=rRec
.bBelowRefEdge
;
916 Point
aPt(rDrag
.GetNow());
920 RotatePoint(aPt
,aPt1
,nSin
,-nCos
);
921 rRec
.nHelpline1Len
=aPt1
.Y()-aPt
.Y();
922 if (bBelow
) rRec
.nHelpline1Len
=-rRec
.nHelpline1Len
;
923 if (bOrtho
) rRec
.nHelpline2Len
=rRec
.nHelpline1Len
;
926 RotatePoint(aPt
,aPt2
,nSin
,-nCos
);
927 rRec
.nHelpline2Len
=aPt2
.Y()-aPt
.Y();
928 if (bBelow
) rRec
.nHelpline2Len
=-rRec
.nHelpline2Len
;
929 if (bOrtho
) rRec
.nHelpline1Len
=rRec
.nHelpline2Len
;
932 bool bAnf
=nHdlNum
==2;
933 Point
& rMov
=bAnf
? rRec
.aPt1
: rRec
.aPt2
;
935 Point
aFix(bAnf
? rRec
.aPt2
: rRec
.aPt1
);
937 long ndx0
=aMov
.X()-aFix
.X();
938 long ndy0
=aMov
.Y()-aFix
.Y();
941 if (!bHLin
|| !bVLin
) { // else aPt1==aPt2
942 long ndx
=aPt
.X()-aFix
.X();
943 long ndy
=aPt
.Y()-aFix
.Y();
944 double nXFact
=0; if (!bVLin
) nXFact
=(double)ndx
/(double)ndx0
;
945 double nYFact
=0; if (!bHLin
) nYFact
=(double)ndy
/(double)ndy0
;
946 bool bHor
=bHLin
|| (!bVLin
&& (nXFact
>nYFact
) ==bBigOrtho
);
947 bool bVer
=bVLin
|| (!bHLin
&& (nXFact
<=nYFact
)==bBigOrtho
);
948 if (bHor
) ndy
=long(ndy0
*nXFact
);
949 if (bVer
) ndx
=long(ndx0
*nYFact
);
958 long nVal0
=rRec
.nLineDist
;
959 RotatePoint(aPt
,(nHdlNum
==4 ? aPt1
: aPt2
),nSin
,-nCos
);
960 rRec
.nLineDist
=aPt
.Y()- (nHdlNum
==4 ? aPt1
.Y() : aPt2
.Y());
961 if (bBelow
) rRec
.nLineDist
=-rRec
.nLineDist
;
962 if (rRec
.nLineDist
<0) {
963 rRec
.nLineDist
=-rRec
.nLineDist
;
964 rRec
.bBelowRefEdge
=!bBelow
;
966 rRec
.nLineDist
-=rRec
.nHelplineOverhang
;
967 if (bOrtho
) rRec
.nLineDist
=nVal0
;
974 bool SdrMeasureObj::BegCreate(SdrDragStat
& rStat
)
976 rStat
.SetOrtho8Possible();
977 aPt1
=rStat
.GetStart();
983 bool SdrMeasureObj::MovCreate(SdrDragStat
& rStat
)
985 SdrView
* pView
=rStat
.GetView();
986 aPt1
=rStat
.GetStart();
988 if (pView
!=NULL
&& pView
->IsCreate1stPointAsCenter()) {
998 bool SdrMeasureObj::EndCreate(SdrDragStat
& rStat
, SdrCreateCmd eCmd
)
1002 return (eCmd
==SDRCREATE_FORCEEND
|| rStat
.GetPointAnz()>=2);
1005 bool SdrMeasureObj::BckCreate(SdrDragStat
& /*rStat*/)
1010 void SdrMeasureObj::BrkCreate(SdrDragStat
& /*rStat*/)
1014 basegfx::B2DPolyPolygon
SdrMeasureObj::TakeCreatePoly(const SdrDragStat
& /*rDrag*/) const
1017 ImpMeasurePoly aMPol
;
1020 ImpCalcGeometrics(aRec
, aMPol
);
1022 return ImpCalcXPoly(aMPol
);
1025 Pointer
SdrMeasureObj::GetCreatePointer() const
1027 return Pointer(PointerStyle::Cross
);
1030 void SdrMeasureObj::NbcMove(const Size
& rSiz
)
1032 SdrTextObj::NbcMove(rSiz
);
1033 MovePoint(aPt1
,rSiz
);
1034 MovePoint(aPt2
,rSiz
);
1037 void SdrMeasureObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
1039 SdrTextObj::NbcResize(rRef
,xFact
,yFact
);
1040 ResizePoint(aPt1
,rRef
,xFact
,yFact
);
1041 ResizePoint(aPt2
,rRef
,xFact
,yFact
);
1045 void SdrMeasureObj::NbcRotate(const Point
& rRef
, long nAngle
, double sn
, double cs
)
1047 SdrTextObj::NbcRotate(rRef
,nAngle
,sn
,cs
);
1048 long nLen0
=GetLen(aPt2
-aPt1
);
1049 RotatePoint(aPt1
,rRef
,sn
,cs
);
1050 RotatePoint(aPt2
,rRef
,sn
,cs
);
1051 long nLen1
=GetLen(aPt2
-aPt1
);
1052 if (nLen1
!=nLen0
) { // rounding error!
1053 long dx
=aPt2
.X()-aPt1
.X();
1054 long dy
=aPt2
.Y()-aPt1
.Y();
1055 dx
=BigMulDiv(dx
,nLen0
,nLen1
);
1056 dy
=BigMulDiv(dy
,nLen0
,nLen1
);
1058 aPt1
.X()=aPt2
.X()-dx
;
1059 aPt1
.Y()=aPt2
.Y()-dy
;
1061 aPt2
.X()=aPt1
.X()+dx
;
1062 aPt2
.Y()=aPt1
.Y()+dy
;
1068 void SdrMeasureObj::NbcMirror(const Point
& rRef1
, const Point
& rRef2
)
1070 SdrTextObj::NbcMirror(rRef1
,rRef2
);
1071 MirrorPoint(aPt1
,rRef1
,rRef2
);
1072 MirrorPoint(aPt2
,rRef1
,rRef2
);
1076 void SdrMeasureObj::NbcShear(const Point
& rRef
, long nAngle
, double tn
, bool bVShear
)
1078 SdrTextObj::NbcShear(rRef
,nAngle
,tn
,bVShear
);
1079 ShearPoint(aPt1
,rRef
,tn
,bVShear
);
1080 ShearPoint(aPt2
,rRef
,tn
,bVShear
);
1085 long SdrMeasureObj::GetRotateAngle() const
1087 return GetAngle(aPt2
-aPt1
);
1090 void SdrMeasureObj::RecalcSnapRect()
1093 ImpMeasurePoly aMPol
;
1097 ImpCalcGeometrics(aRec
, aMPol
);
1098 aXPP
= XPolyPolygon(ImpCalcXPoly(aMPol
));
1099 maSnapRect
= aXPP
.GetBoundRect();
1102 sal_uInt32
SdrMeasureObj::GetSnapPointCount() const
1107 Point
SdrMeasureObj::GetSnapPoint(sal_uInt32 i
) const
1109 if (i
==0) return aPt1
;
1113 bool SdrMeasureObj::IsPolyObj() const
1118 sal_uInt32
SdrMeasureObj::GetPointCount() const
1123 Point
SdrMeasureObj::GetPoint(sal_uInt32 i
) const
1125 return (0L == i
) ? aPt1
: aPt2
;
1128 void SdrMeasureObj::NbcSetPoint(const Point
& rPnt
, sal_uInt32 i
)
1138 SdrObjGeoData
* SdrMeasureObj::NewGeoData() const
1140 return new SdrMeasureObjGeoData
;
1143 void SdrMeasureObj::SaveGeoData(SdrObjGeoData
& rGeo
) const
1145 SdrTextObj::SaveGeoData(rGeo
);
1146 SdrMeasureObjGeoData
& rMGeo
=static_cast<SdrMeasureObjGeoData
&>(rGeo
);
1151 void SdrMeasureObj::RestGeoData(const SdrObjGeoData
& rGeo
)
1153 SdrTextObj::RestGeoData(rGeo
);
1154 const SdrMeasureObjGeoData
& rMGeo
=static_cast<const SdrMeasureObjGeoData
&>(rGeo
);
1160 SdrObject
* SdrMeasureObj::DoConvertToPolyObj(bool bBezier
, bool bAddText
) const
1162 // get XOR Poly as base
1163 XPolyPolygon
aTmpPolyPolygon(TakeXorPoly());
1165 // get local ItemSet and StyleSheet
1166 SfxItemSet
aSet(GetObjectItemSet());
1167 SfxStyleSheet
* pStyleSheet
= GetStyleSheet();
1170 SdrObjGroup
* pGroup
= new SdrObjGroup
;
1171 pGroup
->SetModel(GetModel());
1173 // prepare parameters
1174 basegfx::B2DPolyPolygon aPolyPoly
;
1176 sal_uInt16
nCount(aTmpPolyPolygon
.Count());
1177 sal_uInt16
nLoopStart(0);
1181 // three lines, first one is the middle one
1183 aPolyPoly
.append(aTmpPolyPolygon
[0].getB2DPolygon());
1185 pPath
= new SdrPathObj(OBJ_PATHLINE
, aPolyPoly
);
1186 pPath
->SetModel(GetModel());
1187 pPath
->SetMergedItemSet(aSet
);
1188 pPath
->SetStyleSheet(pStyleSheet
, true);
1189 pGroup
->GetSubList()->NbcInsertObject(pPath
);
1190 aSet
.Put(XLineStartWidthItem(0L));
1191 aSet
.Put(XLineEndWidthItem(0L));
1194 else if(nCount
== 4)
1196 // four lines, middle line with gap, so there are two lines used
1197 // which have one arrow each
1198 sal_Int32 nEndWidth
= static_cast<const XLineEndWidthItem
&>(aSet
.Get(XATTR_LINEENDWIDTH
)).GetValue();
1199 aSet
.Put(XLineEndWidthItem(0L));
1202 aPolyPoly
.append(aTmpPolyPolygon
[0].getB2DPolygon());
1203 pPath
= new SdrPathObj(OBJ_PATHLINE
, aPolyPoly
);
1204 pPath
->SetModel(GetModel());
1205 pPath
->SetMergedItemSet(aSet
);
1206 pPath
->SetStyleSheet(pStyleSheet
, true);
1208 pGroup
->GetSubList()->NbcInsertObject(pPath
);
1210 aSet
.Put(XLineEndWidthItem(nEndWidth
));
1211 aSet
.Put(XLineStartWidthItem(0L));
1214 aPolyPoly
.append(aTmpPolyPolygon
[1].getB2DPolygon());
1215 pPath
= new SdrPathObj(OBJ_PATHLINE
, aPolyPoly
);
1216 pPath
->SetModel(GetModel());
1217 pPath
->SetMergedItemSet(aSet
);
1218 pPath
->SetStyleSheet(pStyleSheet
, true);
1220 pGroup
->GetSubList()->NbcInsertObject(pPath
);
1222 aSet
.Put(XLineEndWidthItem(0L));
1225 else if(nCount
== 5)
1227 // five lines, first two are the outer ones
1228 sal_Int32 nEndWidth
= static_cast<const XLineEndWidthItem
&>(aSet
.Get(XATTR_LINEENDWIDTH
)).GetValue();
1230 aSet
.Put(XLineEndWidthItem(0L));
1233 aPolyPoly
.append(aTmpPolyPolygon
[0].getB2DPolygon());
1234 pPath
= new SdrPathObj(OBJ_PATHLINE
, aPolyPoly
);
1235 pPath
->SetModel(GetModel());
1236 pPath
->SetMergedItemSet(aSet
);
1237 pPath
->SetStyleSheet(pStyleSheet
, true);
1239 pGroup
->GetSubList()->NbcInsertObject(pPath
);
1241 aSet
.Put(XLineEndWidthItem(nEndWidth
));
1242 aSet
.Put(XLineStartWidthItem(0L));
1245 aPolyPoly
.append(aTmpPolyPolygon
[1].getB2DPolygon());
1246 pPath
= new SdrPathObj(OBJ_PATHLINE
, aPolyPoly
);
1247 pPath
->SetModel(GetModel());
1248 pPath
->SetMergedItemSet(aSet
);
1249 pPath
->SetStyleSheet(pStyleSheet
, true);
1251 pGroup
->GetSubList()->NbcInsertObject(pPath
);
1253 aSet
.Put(XLineEndWidthItem(0L));
1257 for(;nLoopStart
<nCount
;nLoopStart
++)
1260 aPolyPoly
.append(aTmpPolyPolygon
[nLoopStart
].getB2DPolygon());
1261 pPath
= new SdrPathObj(OBJ_PATHLINE
, aPolyPoly
);
1262 pPath
->SetModel(GetModel());
1263 pPath
->SetMergedItemSet(aSet
);
1264 pPath
->SetStyleSheet(pStyleSheet
, true);
1266 pGroup
->GetSubList()->NbcInsertObject(pPath
);
1271 return ImpConvertAddText(pGroup
, bBezier
);
1279 bool SdrMeasureObj::BegTextEdit(SdrOutliner
& rOutl
)
1282 return SdrTextObj::BegTextEdit(rOutl
);
1285 const Size
& SdrMeasureObj::GetTextSize() const
1287 if (bTextDirty
) UndirtyText();
1288 return SdrTextObj::GetTextSize();
1291 OutlinerParaObject
* SdrMeasureObj::GetOutlinerParaObject() const
1295 return SdrTextObj::GetOutlinerParaObject();
1298 void SdrMeasureObj::NbcSetOutlinerParaObject(OutlinerParaObject
* pTextObject
)
1300 SdrTextObj::NbcSetOutlinerParaObject(pTextObject
);
1301 if(SdrTextObj::GetOutlinerParaObject())
1302 SetTextDirty(); // recalculate text
1305 void SdrMeasureObj::TakeTextRect( SdrOutliner
& rOutliner
, Rectangle
& rTextRect
, bool bNoEditText
,
1306 Rectangle
* pAnchorRect
, bool bLineWidth
) const
1308 if (bTextDirty
) UndirtyText();
1309 SdrTextObj::TakeTextRect( rOutliner
, rTextRect
, bNoEditText
, pAnchorRect
, bLineWidth
);
1312 void SdrMeasureObj::TakeTextAnchorRect(Rectangle
& rAnchorRect
) const
1314 if (bTextDirty
) UndirtyText();
1315 SdrTextObj::TakeTextAnchorRect(rAnchorRect
);
1318 void SdrMeasureObj::TakeTextEditArea(Size
* pPaperMin
, Size
* pPaperMax
, Rectangle
* pViewInit
, Rectangle
* pViewMin
) const
1320 if (bTextDirty
) UndirtyText();
1321 SdrTextObj::TakeTextEditArea(pPaperMin
,pPaperMax
,pViewInit
,pViewMin
);
1324 sal_uInt16
SdrMeasureObj::GetOutlinerViewAnchorMode() const
1326 if (bTextDirty
) UndirtyText();
1328 ImpMeasurePoly aMPol
;
1330 ImpCalcGeometrics(aRec
,aMPol
);
1332 SdrTextHorzAdjust eTH
=GetTextHorizontalAdjust();
1333 SdrTextVertAdjust eTV
=GetTextVerticalAdjust();
1334 SdrMeasureTextHPos eMH
=aMPol
.eUsedTextHPos
;
1335 SdrMeasureTextVPos eMV
=aMPol
.eUsedTextVPos
;
1336 bool bTextRota90
=aRec
.bTextRota90
;
1337 bool bBelowRefEdge
=aRec
.bBelowRefEdge
;
1339 // TODO: bTextUpsideDown should be interpreted here!
1341 if (eMH
==SDRMEASURE_TEXTLEFTOUTSIDE
) eTH
=SDRTEXTHORZADJUST_RIGHT
;
1342 if (eMH
==SDRMEASURE_TEXTRIGHTOUTSIDE
) eTH
=SDRTEXTHORZADJUST_LEFT
;
1343 // at eMH==SDRMEASURE_TEXTINSIDE we can anchor horizontally
1344 if (eMV
==SDRMEASURE_ABOVE
) eTV
=SDRTEXTVERTADJUST_BOTTOM
;
1345 if (eMV
==SDRMEASURE_BELOW
) eTV
=SDRTEXTVERTADJUST_TOP
;
1346 if (eMV
==SDRMEASURETEXT_BREAKEDLINE
|| eMV
==SDRMEASURETEXT_VERTICALCENTERED
) eTV
=SDRTEXTVERTADJUST_CENTER
;
1348 if (eMH
==SDRMEASURE_TEXTLEFTOUTSIDE
) eTV
=SDRTEXTVERTADJUST_BOTTOM
;
1349 if (eMH
==SDRMEASURE_TEXTRIGHTOUTSIDE
) eTV
=SDRTEXTVERTADJUST_TOP
;
1350 // at eMH==SDRMEASURE_TEXTINSIDE we can anchor vertically
1351 if (!bBelowRefEdge
) {
1352 if (eMV
==SDRMEASURE_ABOVE
) eTH
=SDRTEXTHORZADJUST_LEFT
;
1353 if (eMV
==SDRMEASURE_BELOW
) eTH
=SDRTEXTHORZADJUST_RIGHT
;
1355 if (eMV
==SDRMEASURE_ABOVE
) eTH
=SDRTEXTHORZADJUST_RIGHT
;
1356 if (eMV
==SDRMEASURE_BELOW
) eTH
=SDRTEXTHORZADJUST_LEFT
;
1358 if (eMV
==SDRMEASURETEXT_BREAKEDLINE
|| eMV
==SDRMEASURETEXT_VERTICALCENTERED
) eTH
=SDRTEXTHORZADJUST_CENTER
;
1361 EVAnchorMode eRet
=ANCHOR_BOTTOM_HCENTER
;
1362 if (eTH
==SDRTEXTHORZADJUST_LEFT
) {
1363 if (eTV
==SDRTEXTVERTADJUST_TOP
) eRet
=ANCHOR_TOP_LEFT
;
1364 else if (eTV
==SDRTEXTVERTADJUST_BOTTOM
) eRet
=ANCHOR_BOTTOM_LEFT
;
1365 else eRet
=ANCHOR_VCENTER_LEFT
;
1366 } else if (eTH
==SDRTEXTHORZADJUST_RIGHT
) {
1367 if (eTV
==SDRTEXTVERTADJUST_TOP
) eRet
=ANCHOR_TOP_RIGHT
;
1368 else if (eTV
==SDRTEXTVERTADJUST_BOTTOM
) eRet
=ANCHOR_BOTTOM_RIGHT
;
1369 else eRet
=ANCHOR_VCENTER_RIGHT
;
1371 if (eTV
==SDRTEXTVERTADJUST_TOP
) eRet
=ANCHOR_TOP_HCENTER
;
1372 else if (eTV
==SDRTEXTVERTADJUST_BOTTOM
) eRet
=ANCHOR_BOTTOM_HCENTER
;
1373 else eRet
=ANCHOR_VCENTER_HCENTER
;
1375 return (sal_uInt16
)eRet
;
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
1385 bool SdrMeasureObj::TRGetBaseGeometry(basegfx::B2DHomMatrix
& rMatrix
, basegfx::B2DPolyPolygon
& /*rPolyPolygon*/) const
1387 // handle the same as a simple line since the definition is based on two points
1388 const basegfx::B2DRange
aRange(aPt1
.X(), aPt1
.Y(), aPt2
.X(), aPt2
.Y());
1389 basegfx::B2DTuple
aScale(aRange
.getRange());
1390 basegfx::B2DTuple
aTranslate(aRange
.getMinimum());
1392 // position maybe relative to anchor position, convert
1393 if( pModel
->IsWriter() )
1395 if(GetAnchorPos().X() || GetAnchorPos().Y())
1397 aTranslate
-= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1401 // force MapUnit to 100th mm
1402 SfxMapUnit eMapUnit
= pModel
->GetItemPool().GetMetric(0);
1403 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
1407 case SFX_MAPUNIT_TWIP
:
1410 aTranslate
.setX(ImplTwipsToMM(aTranslate
.getX()));
1411 aTranslate
.setY(ImplTwipsToMM(aTranslate
.getY()));
1414 aScale
.setX(ImplTwipsToMM(aScale
.getX()));
1415 aScale
.setY(ImplTwipsToMM(aScale
.getY()));
1421 OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1426 // build return value matrix
1427 rMatrix
= basegfx::tools::createScaleTranslateB2DHomMatrix(aScale
, aTranslate
);
1432 void SdrMeasureObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix
& rMatrix
, const basegfx::B2DPolyPolygon
& /*rPolyPolygon*/)
1434 // use given transformation to derive the two defining points from unit line
1435 basegfx::B2DPoint
aPosA(rMatrix
* basegfx::B2DPoint(0.0, 0.0));
1436 basegfx::B2DPoint
aPosB(rMatrix
* basegfx::B2DPoint(1.0, 0.0));
1438 // force metric to pool metric
1439 SfxMapUnit eMapUnit
= pModel
->GetItemPool().GetMetric(0);
1440 if(eMapUnit
!= SFX_MAPUNIT_100TH_MM
)
1444 case SFX_MAPUNIT_TWIP
:
1447 aPosA
.setX(ImplMMToTwips(aPosA
.getX()));
1448 aPosA
.setY(ImplMMToTwips(aPosA
.getY()));
1449 aPosB
.setX(ImplMMToTwips(aPosB
.getX()));
1450 aPosB
.setY(ImplMMToTwips(aPosB
.getY()));
1456 OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1461 if( pModel
->IsWriter() )
1463 // if anchor is used, make position relative to it
1464 if(GetAnchorPos().X() || GetAnchorPos().Y())
1466 const basegfx::B2DVector
aAnchorOffset(GetAnchorPos().X(), GetAnchorPos().Y());
1468 aPosA
+= aAnchorOffset
;
1469 aPosB
+= aAnchorOffset
;
1473 // derive new model data
1474 const Point
aNewPt1(basegfx::fround(aPosA
.getX()), basegfx::fround(aPosA
.getY()));
1475 const Point
aNewPt2(basegfx::fround(aPosB
.getX()), basegfx::fround(aPosB
.getY()));
1477 if(aNewPt1
!= aPt1
|| aNewPt2
!= aPt2
)
1479 // set model values and broadcast
1480 Rectangle aBoundRect0
; if (pUserCall
!=NULL
) aBoundRect0
=GetLastBoundRect();
1488 BroadcastObjectChange();
1489 SendUserCall(SDRUSERCALL_MOVEONLY
,aBoundRect0
);
1493 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */