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