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