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