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