Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <comphelper/string.hxx>
22 : #include <svx/svdotext.hxx>
23 : #include "svx/svditext.hxx"
24 : #include <svx/svdpagv.hxx> // for the request in Paint to see whether
25 : #include <svx/svdview.hxx> // the object is currently being edited
26 : #include <svx/svdpage.hxx> // and for AnimationHandler (ticker text)
27 : #include <svx/svdetc.hxx>
28 : #include <svx/svdoutl.hxx>
29 : #include <svx/svdmodel.hxx> // OutlinerDefaults
30 : #include "svx/svdglob.hxx" // Stringcache
31 : #include "svx/svdstr.hrc" // the object's name
32 : #include <editeng/writingmodeitem.hxx>
33 : #include <svx/sdtfchim.hxx>
34 : #include <svtools/colorcfg.hxx>
35 : #include <editeng/eeitem.hxx>
36 : #include <editeng/editstat.hxx>
37 : #include <editeng/outlobj.hxx>
38 : #include <editeng/editobj.hxx>
39 : #include <editeng/outliner.hxx>
40 : #include <editeng/fhgtitem.hxx>
41 : #include <svl/itempool.hxx>
42 : #include <editeng/adjitem.hxx>
43 : #include <editeng/flditem.hxx>
44 : #include <svx/xftouit.hxx>
45 : #include <tools/helpers.hxx>
46 : #include <svx/xflgrit.hxx>
47 : #include <svx/svdpool.hxx>
48 : #include <svx/xflclit.hxx>
49 : #include <svl/style.hxx>
50 : #include <editeng/editeng.hxx>
51 : #include <svl/itemiter.hxx>
52 : #include <svx/sdr/properties/textproperties.hxx>
53 : #include <vcl/metaact.hxx>
54 : #include <svx/sdr/contact/viewcontactoftextobj.hxx>
55 : #include <basegfx/tuple/b2dtuple.hxx>
56 : #include <basegfx/matrix/b2dhommatrix.hxx>
57 : #include <basegfx/polygon/b2dpolygon.hxx>
58 : #include <drawinglayer/geometry/viewinformation2d.hxx>
59 : #include <vcl/virdev.hxx>
60 : #include <basegfx/matrix/b2dhommatrixtools.hxx>
61 : #include "svdconv.hxx"
62 :
63 : //////////////////////////////////////////////////////////////////////////////
64 :
65 : using namespace com::sun::star;
66 :
67 : //////////////////////////////////////////////////////////////////////////////
68 : // BaseProperties section
69 :
70 1355 : sdr::properties::BaseProperties* SdrTextObj::CreateObjectSpecificProperties()
71 : {
72 1355 : return new sdr::properties::TextProperties(*this);
73 : }
74 :
75 : //////////////////////////////////////////////////////////////////////////////
76 : // DrawContact section
77 :
78 0 : sdr::contact::ViewContact* SdrTextObj::CreateObjectSpecificViewContact()
79 : {
80 0 : return new sdr::contact::ViewContactOfTextObj(*this);
81 : }
82 :
83 : //////////////////////////////////////////////////////////////////////////////
84 :
85 245509 : TYPEINIT1(SdrTextObj,SdrAttrObj);
86 :
87 2798 : SdrTextObj::SdrTextObj()
88 : : SdrAttrObj(),
89 : mpText(NULL),
90 : pEdtOutl(NULL),
91 : pFormTextBoundRect(NULL),
92 2798 : eTextKind(OBJ_TEXT)
93 : {
94 2798 : bTextSizeDirty=sal_False;
95 2798 : bTextFrame=sal_False;
96 2798 : bNoShear=sal_False;
97 2798 : bNoRotate=sal_False;
98 2798 : bNoMirror=sal_False;
99 2798 : bDisableAutoWidthOnDragging=sal_False;
100 :
101 2798 : mbInEditMode = sal_False;
102 2798 : mbTextHidden = sal_False;
103 2798 : mbTextAnimationAllowed = sal_True;
104 2798 : maTextEditOffset = Point(0, 0);
105 :
106 : // #i25616#
107 2798 : mbSupportTextIndentingOnLineWidthChange = sal_True;
108 2798 : mbInDownScale = sal_False;
109 2798 : }
110 :
111 59 : SdrTextObj::SdrTextObj(const Rectangle& rNewRect)
112 : : SdrAttrObj(),
113 : aRect(rNewRect),
114 : mpText(NULL),
115 : pEdtOutl(NULL),
116 : pFormTextBoundRect(NULL),
117 59 : eTextKind(OBJ_TEXT)
118 : {
119 59 : bTextSizeDirty=sal_False;
120 59 : bTextFrame=sal_False;
121 59 : bNoShear=sal_False;
122 59 : bNoRotate=sal_False;
123 59 : bNoMirror=sal_False;
124 59 : bDisableAutoWidthOnDragging=sal_False;
125 59 : ImpJustifyRect(aRect);
126 :
127 59 : mbInEditMode = sal_False;
128 59 : mbTextHidden = sal_False;
129 59 : mbTextAnimationAllowed = sal_True;
130 59 : mbInDownScale = sal_False;
131 59 : maTextEditOffset = Point(0, 0);
132 :
133 : // #i25616#
134 59 : mbSupportTextIndentingOnLineWidthChange = sal_True;
135 59 : }
136 :
137 1280 : SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind)
138 : : SdrAttrObj(),
139 : mpText(NULL),
140 : pEdtOutl(NULL),
141 : pFormTextBoundRect(NULL),
142 1280 : eTextKind(eNewTextKind)
143 : {
144 1280 : bTextSizeDirty=sal_False;
145 1280 : bTextFrame=sal_True;
146 1280 : bNoShear=sal_True;
147 1280 : bNoRotate=sal_False;
148 1280 : bNoMirror=sal_True;
149 1280 : bDisableAutoWidthOnDragging=sal_False;
150 :
151 1280 : mbInEditMode = sal_False;
152 1280 : mbTextHidden = sal_False;
153 1280 : mbTextAnimationAllowed = sal_True;
154 1280 : mbInDownScale = sal_False;
155 1280 : maTextEditOffset = Point(0, 0);
156 :
157 : // #i25616#
158 1280 : mbSupportTextIndentingOnLineWidthChange = sal_True;
159 1280 : }
160 :
161 51 : SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect)
162 : : SdrAttrObj(),
163 : aRect(rNewRect),
164 : mpText(NULL),
165 : pEdtOutl(NULL),
166 : pFormTextBoundRect(NULL),
167 51 : eTextKind(eNewTextKind)
168 : {
169 51 : bTextSizeDirty=sal_False;
170 51 : bTextFrame=sal_True;
171 51 : bNoShear=sal_True;
172 51 : bNoRotate=sal_False;
173 51 : bNoMirror=sal_True;
174 51 : bDisableAutoWidthOnDragging=sal_False;
175 51 : ImpJustifyRect(aRect);
176 :
177 51 : mbInEditMode = sal_False;
178 51 : mbTextHidden = sal_False;
179 51 : mbTextAnimationAllowed = sal_True;
180 51 : mbInDownScale = sal_False;
181 51 : maTextEditOffset = Point(0, 0);
182 :
183 : // #i25616#
184 51 : mbSupportTextIndentingOnLineWidthChange = sal_True;
185 51 : }
186 :
187 8216 : SdrTextObj::~SdrTextObj()
188 : {
189 4108 : if( pModel )
190 : {
191 4108 : SdrOutliner& rOutl = pModel->GetHitTestOutliner();
192 4108 : if( rOutl.GetTextObj() == this )
193 0 : rOutl.SetTextObj( NULL );
194 : }
195 :
196 4108 : if(mpText!=NULL)
197 4073 : delete mpText;
198 :
199 4108 : if (pFormTextBoundRect!=NULL)
200 0 : delete pFormTextBoundRect;
201 :
202 4108 : ImpLinkAbmeldung();
203 4108 : }
204 :
205 0 : void SdrTextObj::FitFrameToTextSize()
206 : {
207 : DBG_ASSERT(pModel!=NULL,"SdrTextObj::FitFrameToTextSize(): pModel=NULL!");
208 0 : ImpJustifyRect(aRect);
209 :
210 0 : SdrText* pText = getActiveText();
211 0 : if( pText!=NULL && pText->GetOutlinerParaObject() && pModel!=NULL)
212 : {
213 0 : SdrOutliner& rOutliner=ImpGetDrawOutliner();
214 0 : rOutliner.SetPaperSize(Size(aRect.Right()-aRect.Left(),aRect.Bottom()-aRect.Top()));
215 0 : rOutliner.SetUpdateMode(sal_True);
216 0 : rOutliner.SetText(*pText->GetOutlinerParaObject());
217 0 : Rectangle aTextRect;
218 0 : Size aNewSize(rOutliner.CalcTextSize());
219 0 : rOutliner.Clear();
220 0 : aNewSize.Width()++; // because of possible rounding errors
221 0 : aNewSize.Width()+=GetTextLeftDistance()+GetTextRightDistance();
222 0 : aNewSize.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
223 0 : Rectangle aNewRect(aRect);
224 0 : aNewRect.SetSize(aNewSize);
225 0 : ImpJustifyRect(aNewRect);
226 0 : if (aNewRect!=aRect) {
227 0 : SetLogicRect(aNewRect);
228 : }
229 : }
230 0 : }
231 :
232 26 : void SdrTextObj::NbcSetText(const XubString& rStr)
233 : {
234 26 : SdrOutliner& rOutliner=ImpGetDrawOutliner();
235 26 : rOutliner.SetStyleSheet( 0, GetStyleSheet());
236 26 : rOutliner.SetUpdateMode(sal_True);
237 26 : rOutliner.SetText(rStr,rOutliner.GetParagraph( 0 ));
238 26 : OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
239 26 : Size aSiz(rOutliner.CalcTextSize());
240 26 : rOutliner.Clear();
241 26 : NbcSetOutlinerParaObject(pNewText);
242 26 : aTextSize=aSiz;
243 26 : bTextSizeDirty=sal_False;
244 26 : }
245 :
246 1 : void SdrTextObj::SetText(const XubString& rStr)
247 : {
248 1 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
249 1 : NbcSetText(rStr);
250 1 : SetChanged();
251 1 : BroadcastObjectChange();
252 1 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
253 1 : }
254 :
255 0 : void SdrTextObj::NbcSetText(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
256 : {
257 0 : SdrOutliner& rOutliner=ImpGetDrawOutliner();
258 0 : rOutliner.SetStyleSheet( 0, GetStyleSheet());
259 0 : rOutliner.Read(rInput,rBaseURL,eFormat);
260 0 : OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
261 0 : rOutliner.SetUpdateMode(sal_True);
262 0 : Size aSiz(rOutliner.CalcTextSize());
263 0 : rOutliner.Clear();
264 0 : NbcSetOutlinerParaObject(pNewText);
265 0 : aTextSize=aSiz;
266 0 : bTextSizeDirty=sal_False;
267 0 : }
268 :
269 0 : void SdrTextObj::SetText(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
270 : {
271 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
272 0 : NbcSetText(rInput,rBaseURL,eFormat);
273 0 : SetChanged();
274 0 : BroadcastObjectChange();
275 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
276 0 : }
277 :
278 0 : const Size& SdrTextObj::GetTextSize() const
279 : {
280 0 : if (bTextSizeDirty)
281 : {
282 0 : Size aSiz;
283 0 : SdrText* pText = getActiveText();
284 0 : if( pText && pText->GetOutlinerParaObject ())
285 : {
286 0 : SdrOutliner& rOutliner=ImpGetDrawOutliner();
287 0 : rOutliner.SetText(*pText->GetOutlinerParaObject());
288 0 : rOutliner.SetUpdateMode(sal_True);
289 0 : aSiz=rOutliner.CalcTextSize();
290 0 : rOutliner.Clear();
291 : }
292 : // casting to nonconst twice
293 0 : ((SdrTextObj*)this)->aTextSize=aSiz;
294 0 : ((SdrTextObj*)this)->bTextSizeDirty=sal_False;
295 : }
296 0 : return aTextSize;
297 : }
298 :
299 14614 : bool SdrTextObj::IsAutoGrowHeight() const
300 : {
301 14614 : if(!bTextFrame)
302 0 : return sal_False; // AutoGrow only together with TextFrames
303 :
304 14614 : const SfxItemSet& rSet = GetObjectItemSet();
305 14614 : sal_Bool bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
306 :
307 14614 : if(bRet)
308 : {
309 12093 : SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
310 :
311 12093 : if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
312 : {
313 0 : SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
314 :
315 0 : if(eDirection == SDRTEXTANI_UP || eDirection == SDRTEXTANI_DOWN)
316 : {
317 0 : bRet = sal_False;
318 : }
319 : }
320 : }
321 14614 : return bRet;
322 : }
323 :
324 19529 : bool SdrTextObj::IsAutoGrowWidth() const
325 : {
326 19529 : if(!bTextFrame)
327 12 : return sal_False; // AutoGrow only together with TextFrames
328 :
329 19517 : const SfxItemSet& rSet = GetObjectItemSet();
330 19517 : sal_Bool bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
331 :
332 19517 : sal_Bool bInEditMOde = IsInEditMode();
333 :
334 19517 : if(!bInEditMOde && bRet)
335 : {
336 5519 : SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
337 :
338 5519 : if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
339 : {
340 0 : SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
341 :
342 0 : if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
343 : {
344 0 : bRet = sal_False;
345 : }
346 : }
347 : }
348 19517 : return bRet;
349 : }
350 :
351 2177 : SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust() const
352 : {
353 2177 : return GetTextHorizontalAdjust(GetObjectItemSet());
354 : }
355 :
356 2267 : SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust(const SfxItemSet& rSet) const
357 : {
358 2267 : if(IsContourTextFrame())
359 0 : return SDRTEXTHORZADJUST_BLOCK;
360 :
361 2267 : SdrTextHorzAdjust eRet = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
362 :
363 2267 : sal_Bool bInEditMode = IsInEditMode();
364 :
365 2267 : if(!bInEditMode && eRet == SDRTEXTHORZADJUST_BLOCK)
366 : {
367 126 : SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
368 :
369 126 : if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
370 : {
371 0 : SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
372 :
373 0 : if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
374 : {
375 0 : eRet = SDRTEXTHORZADJUST_LEFT;
376 : }
377 : }
378 : }
379 :
380 2267 : return eRet;
381 : } // defaults: BLOCK (justify) for text frame, CENTER for captions of drawing objects
382 :
383 5161 : SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust() const
384 : {
385 5161 : return GetTextVerticalAdjust(GetObjectItemSet());
386 : }
387 :
388 5251 : SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust(const SfxItemSet& rSet) const
389 : {
390 5251 : if(IsContourTextFrame())
391 0 : return SDRTEXTVERTADJUST_TOP;
392 :
393 : // Take care for vertical text animation here
394 5251 : SdrTextVertAdjust eRet = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
395 5251 : sal_Bool bInEditMode = IsInEditMode();
396 :
397 : // Take care for vertical text animation here
398 5251 : if(!bInEditMode && eRet == SDRTEXTVERTADJUST_BLOCK)
399 : {
400 0 : SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
401 :
402 0 : if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
403 : {
404 0 : SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
405 :
406 0 : if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
407 : {
408 0 : eRet = SDRTEXTVERTADJUST_TOP;
409 : }
410 : }
411 : }
412 :
413 5251 : return eRet;
414 : } // defaults: TOP for text frame, CENTER for captions of drawing objects
415 :
416 8603 : void SdrTextObj::ImpJustifyRect(Rectangle& rRect) const
417 : {
418 8603 : if (!rRect.IsEmpty()) {
419 8421 : rRect.Justify();
420 8421 : if (rRect.Left()==rRect.Right()) rRect.Right()++;
421 8421 : if (rRect.Top()==rRect.Bottom()) rRect.Bottom()++;
422 : }
423 8603 : }
424 :
425 5676 : void SdrTextObj::ImpCheckShear()
426 : {
427 5676 : if (bNoShear && aGeo.nShearWink!=0) {
428 0 : aGeo.nShearWink=0;
429 0 : aGeo.nTan=0;
430 : }
431 5676 : }
432 :
433 0 : void SdrTextObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
434 : {
435 0 : bool bNoTextFrame=!IsTextFrame();
436 0 : rInfo.bResizeFreeAllowed=bNoTextFrame || aGeo.nDrehWink%9000==0;
437 0 : rInfo.bResizePropAllowed=sal_True;
438 0 : rInfo.bRotateFreeAllowed=sal_True;
439 0 : rInfo.bRotate90Allowed =sal_True;
440 0 : rInfo.bMirrorFreeAllowed=bNoTextFrame;
441 0 : rInfo.bMirror45Allowed =bNoTextFrame;
442 0 : rInfo.bMirror90Allowed =bNoTextFrame;
443 :
444 : // allow transparency
445 0 : rInfo.bTransparenceAllowed = sal_True;
446 :
447 : // gradient depends on fillstyle
448 0 : XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
449 0 : rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
450 0 : rInfo.bShearAllowed =bNoTextFrame;
451 0 : rInfo.bEdgeRadiusAllowed=sal_True;
452 0 : bool bCanConv=ImpCanConvTextToCurve();
453 0 : rInfo.bCanConvToPath =bCanConv;
454 0 : rInfo.bCanConvToPoly =bCanConv;
455 0 : rInfo.bCanConvToPathLineToArea=bCanConv;
456 0 : rInfo.bCanConvToPolyLineToArea=bCanConv;
457 0 : rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
458 0 : }
459 :
460 0 : sal_uInt16 SdrTextObj::GetObjIdentifier() const
461 : {
462 0 : return sal_uInt16(eTextKind);
463 : }
464 :
465 2238 : bool SdrTextObj::HasTextImpl( SdrOutliner* pOutliner )
466 : {
467 2238 : bool bRet=false;
468 2238 : if(pOutliner)
469 : {
470 0 : Paragraph* p1stPara=pOutliner->GetParagraph( 0 );
471 0 : sal_uIntPtr nParaAnz=pOutliner->GetParagraphCount();
472 0 : if(p1stPara==NULL)
473 0 : nParaAnz=0;
474 :
475 0 : if(nParaAnz==1)
476 : {
477 : // if it is only one paragraph, check if that paragraph is empty
478 0 : XubString aStr(pOutliner->GetText(p1stPara));
479 :
480 0 : if(!aStr.Len())
481 0 : nParaAnz = 0;
482 : }
483 :
484 0 : bRet= nParaAnz!=0;
485 : }
486 2238 : return bRet;
487 : }
488 :
489 0 : bool SdrTextObj::HasEditText() const
490 : {
491 0 : return HasTextImpl( pEdtOutl );
492 : }
493 :
494 6885 : void SdrTextObj::SetPage(SdrPage* pNewPage)
495 : {
496 6885 : bool bRemove=pNewPage==NULL && pPage!=NULL;
497 6885 : bool bInsert=pNewPage!=NULL && pPage==NULL;
498 6885 : bool bLinked=IsLinkedText();
499 :
500 6885 : if (bLinked && bRemove) {
501 0 : ImpLinkAbmeldung();
502 : }
503 :
504 6885 : SdrAttrObj::SetPage(pNewPage);
505 :
506 6885 : if (bLinked && bInsert) {
507 0 : ImpLinkAnmeldung();
508 : }
509 6885 : }
510 :
511 6413 : void SdrTextObj::SetModel(SdrModel* pNewModel)
512 : {
513 6413 : SdrModel* pOldModel=pModel;
514 6413 : bool bLinked=IsLinkedText();
515 6413 : bool bChg=pNewModel!=pModel;
516 :
517 6413 : if (bLinked && bChg)
518 : {
519 0 : ImpLinkAbmeldung();
520 : }
521 :
522 6413 : SdrAttrObj::SetModel(pNewModel);
523 :
524 6413 : if( bChg )
525 : {
526 4149 : if( pNewModel != 0 && pOldModel != 0 )
527 0 : SetTextSizeDirty();
528 :
529 4149 : sal_Int32 nCount = getTextCount();
530 8298 : for( sal_Int32 nText = 0; nText < nCount; nText++ )
531 : {
532 4149 : SdrText* pText = getText( nText );
533 4149 : if( pText )
534 4149 : pText->SetModel( pNewModel );
535 : }
536 : }
537 :
538 6413 : if (bLinked && bChg)
539 : {
540 0 : ImpLinkAnmeldung();
541 : }
542 6413 : }
543 :
544 0 : bool SdrTextObj::NbcSetEckenradius(long nRad)
545 : {
546 0 : SetObjectItem(SdrEckenradiusItem(nRad));
547 0 : return true;
548 : }
549 :
550 3524 : bool SdrTextObj::NbcSetMinTextFrameHeight(long nHgt)
551 : {
552 3524 : if( bTextFrame && ( !pModel || !pModel->isLocked() ) ) // #i44922#
553 : {
554 225 : SetObjectItem(SdrTextMinFrameHeightItem(nHgt));
555 :
556 : // use bDisableAutoWidthOnDragging as
557 : // bDisableAutoHeightOnDragging if vertical.
558 225 : if(IsVerticalWriting() && bDisableAutoWidthOnDragging)
559 : {
560 0 : bDisableAutoWidthOnDragging = sal_False;
561 0 : SetObjectItem(SdrTextAutoGrowHeightItem(sal_False));
562 : }
563 :
564 225 : return true;
565 : }
566 3299 : return false;
567 : }
568 :
569 1235 : bool SdrTextObj::NbcSetMinTextFrameWidth(long nWdt)
570 : {
571 1235 : if( bTextFrame && ( !pModel || !pModel->isLocked() ) ) // #i44922#
572 : {
573 0 : SetObjectItem(SdrTextMinFrameWidthItem(nWdt));
574 :
575 : // use bDisableAutoWidthOnDragging only
576 : // when not vertical.
577 0 : if(!IsVerticalWriting() && bDisableAutoWidthOnDragging)
578 : {
579 0 : bDisableAutoWidthOnDragging = sal_False;
580 0 : SetObjectItem(SdrTextAutoGrowWidthItem(sal_False));
581 : }
582 :
583 0 : return true;
584 : }
585 1235 : return false;
586 : }
587 :
588 0 : void SdrTextObj::ImpSetContourPolygon( SdrOutliner& rOutliner, Rectangle& rAnchorRect, sal_Bool bLineWidth ) const
589 : {
590 0 : basegfx::B2DPolyPolygon aXorPolyPolygon(TakeXorPoly());
591 0 : basegfx::B2DPolyPolygon* pContourPolyPolygon = 0L;
592 : basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
593 0 : -rAnchorRect.Left(), -rAnchorRect.Top()));
594 :
595 0 : if(aGeo.nDrehWink)
596 : {
597 : // Unrotate!
598 0 : aMatrix.rotate(-aGeo.nDrehWink * nPi180);
599 : }
600 :
601 0 : aXorPolyPolygon.transform(aMatrix);
602 :
603 0 : if( bLineWidth )
604 : {
605 : // Take line width into account.
606 : // When doing the hit test, avoid this. (Performance!)
607 0 : pContourPolyPolygon = new basegfx::B2DPolyPolygon();
608 :
609 : // test if shadow needs to be avoided for TakeContour()
610 0 : const SfxItemSet& rSet = GetObjectItemSet();
611 0 : sal_Bool bShadowOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
612 :
613 : // #i33696#
614 : // Remember TextObject currently set at the DrawOutliner, it WILL be
615 : // replaced during calculating the outline since it uses an own paint
616 : // and that one uses the DrawOutliner, too.
617 0 : const SdrTextObj* pLastTextObject = rOutliner.GetTextObj();
618 :
619 0 : if(bShadowOn)
620 : {
621 : // force shadow off
622 0 : SdrObject* pCopy = Clone();
623 0 : pCopy->SetMergedItem(SdrShadowItem(sal_False));
624 0 : *pContourPolyPolygon = pCopy->TakeContour();
625 0 : SdrObject::Free( pCopy );
626 : }
627 : else
628 : {
629 0 : *pContourPolyPolygon = TakeContour();
630 : }
631 :
632 : // #i33696#
633 : // restore remembered text object
634 0 : if(pLastTextObject != rOutliner.GetTextObj())
635 : {
636 0 : rOutliner.SetTextObj(pLastTextObject);
637 : }
638 :
639 0 : pContourPolyPolygon->transform(aMatrix);
640 : }
641 :
642 0 : rOutliner.SetPolygon(aXorPolyPolygon, pContourPolyPolygon);
643 0 : }
644 :
645 0 : void SdrTextObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
646 : {
647 0 : rRect=aRect;
648 0 : }
649 :
650 0 : void SdrTextObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
651 : {
652 0 : long nLeftDist=GetTextLeftDistance();
653 0 : long nRightDist=GetTextRightDistance();
654 0 : long nUpperDist=GetTextUpperDistance();
655 0 : long nLowerDist=GetTextLowerDistance();
656 0 : Rectangle aAnkRect(aRect); // the rectangle in which we anchor
657 0 : bool bFrame=IsTextFrame();
658 0 : if (!bFrame) {
659 0 : TakeUnrotatedSnapRect(aAnkRect);
660 : }
661 0 : Point aRotateRef(aAnkRect.TopLeft());
662 0 : aAnkRect.Left()+=nLeftDist;
663 0 : aAnkRect.Top()+=nUpperDist;
664 0 : aAnkRect.Right()-=nRightDist;
665 0 : aAnkRect.Bottom()-=nLowerDist;
666 :
667 : // Since sizes may be bigger than the object bounds it is necessary to
668 : // justify the rect now.
669 0 : ImpJustifyRect(aAnkRect);
670 :
671 0 : if (bFrame) {
672 : // TODO: Optimize this.
673 0 : if (aAnkRect.GetWidth()<2) aAnkRect.Right()=aAnkRect.Left()+1; // minimum size h and v: 2 px
674 0 : if (aAnkRect.GetHeight()<2) aAnkRect.Bottom()=aAnkRect.Top()+1;
675 : }
676 0 : if (aGeo.nDrehWink!=0) {
677 0 : Point aTmpPt(aAnkRect.TopLeft());
678 0 : RotatePoint(aTmpPt,aRotateRef,aGeo.nSin,aGeo.nCos);
679 0 : aTmpPt-=aAnkRect.TopLeft();
680 0 : aAnkRect.Move(aTmpPt.X(),aTmpPt.Y());
681 : }
682 0 : rAnchorRect=aAnkRect;
683 0 : }
684 :
685 0 : void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, bool bNoEditText,
686 : Rectangle* pAnchorRect, bool bLineWidth ) const
687 : {
688 0 : Rectangle aAnkRect; // the rectangle in which we anchor
689 0 : TakeTextAnchorRect(aAnkRect);
690 0 : SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
691 0 : SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
692 0 : SdrTextAniKind eAniKind=GetTextAniKind();
693 0 : SdrTextAniDirection eAniDirection=GetTextAniDirection();
694 :
695 0 : bool bFitToSize(IsFitToSize());
696 0 : bool bContourFrame=IsContourTextFrame();
697 :
698 0 : bool bFrame=IsTextFrame();
699 0 : sal_uIntPtr nStat0=rOutliner.GetControlWord();
700 0 : Size aNullSize;
701 0 : if (!bContourFrame)
702 : {
703 0 : rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
704 0 : rOutliner.SetMinAutoPaperSize(aNullSize);
705 0 : rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
706 : }
707 :
708 0 : if (!bFitToSize && !bContourFrame)
709 : {
710 0 : long nAnkWdt=aAnkRect.GetWidth();
711 0 : long nAnkHgt=aAnkRect.GetHeight();
712 0 : if (bFrame)
713 : {
714 0 : long nWdt=nAnkWdt;
715 0 : long nHgt=nAnkHgt;
716 :
717 0 : sal_Bool bInEditMode = IsInEditMode();
718 :
719 0 : if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
720 : {
721 : // unlimited paper size for ticker text
722 0 : if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nWdt=1000000;
723 0 : if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nHgt=1000000;
724 : }
725 0 : rOutliner.SetMaxAutoPaperSize(Size(nWdt,nHgt));
726 : }
727 :
728 : // New try with _BLOCK for hor and ver after completely
729 : // supporting full width for vertical text.
730 0 : if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
731 : {
732 0 : rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
733 : }
734 :
735 0 : if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
736 : {
737 0 : rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
738 : }
739 : }
740 :
741 0 : rOutliner.SetPaperSize(aNullSize);
742 0 : if (bContourFrame)
743 0 : ImpSetContourPolygon( rOutliner, aAnkRect, bLineWidth );
744 :
745 : // put text into the outliner, if available from the edit outliner
746 0 : SdrText* pText = getActiveText();
747 0 : OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
748 0 : OutlinerParaObject* pPara = (pEdtOutl && !bNoEditText) ? pEdtOutl->CreateParaObject() : pOutlinerParaObject;
749 :
750 0 : if (pPara)
751 : {
752 0 : sal_Bool bHitTest = sal_False;
753 0 : if( pModel )
754 0 : bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
755 :
756 0 : const SdrTextObj* pTestObj = rOutliner.GetTextObj();
757 0 : if( !pTestObj || !bHitTest || pTestObj != this ||
758 0 : pTestObj->GetOutlinerParaObject() != pOutlinerParaObject )
759 : {
760 0 : if( bHitTest ) // #i33696# take back fix #i27510#
761 : {
762 0 : rOutliner.SetTextObj( this );
763 0 : rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
764 : }
765 :
766 0 : rOutliner.SetUpdateMode(sal_True);
767 0 : rOutliner.SetText(*pPara);
768 : }
769 : }
770 : else
771 : {
772 0 : rOutliner.SetTextObj( NULL );
773 : }
774 :
775 0 : if (pEdtOutl && !bNoEditText && pPara)
776 0 : delete pPara;
777 :
778 0 : rOutliner.SetUpdateMode(sal_True);
779 0 : rOutliner.SetControlWord(nStat0);
780 :
781 0 : if( pText )
782 0 : pText->CheckPortionInfo(rOutliner);
783 :
784 0 : Point aTextPos(aAnkRect.TopLeft());
785 0 : Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() adds a little tolerance, right?
786 :
787 : // For draw objects containing text correct hor/ver alignment if text is bigger
788 : // than the object itself. Without that correction, the text would always be
789 : // formatted to the left edge (or top edge when vertical) of the draw object.
790 0 : if(!IsTextFrame())
791 : {
792 0 : if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
793 : {
794 : // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
795 : // else the alignment is wanted.
796 0 : if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
797 : {
798 0 : eHAdj = SDRTEXTHORZADJUST_CENTER;
799 : }
800 : }
801 :
802 0 : if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
803 : {
804 : // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
805 : // else the alignment is wanted.
806 0 : if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
807 : {
808 0 : eVAdj = SDRTEXTVERTADJUST_CENTER;
809 : }
810 : }
811 : }
812 :
813 0 : if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
814 : {
815 0 : long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
816 0 : if (eHAdj==SDRTEXTHORZADJUST_CENTER)
817 0 : aTextPos.X()+=nFreeWdt/2;
818 0 : if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
819 0 : aTextPos.X()+=nFreeWdt;
820 : }
821 0 : if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
822 : {
823 0 : long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
824 0 : if (eVAdj==SDRTEXTVERTADJUST_CENTER)
825 0 : aTextPos.Y()+=nFreeHgt/2;
826 0 : if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
827 0 : aTextPos.Y()+=nFreeHgt;
828 : }
829 0 : if (aGeo.nDrehWink!=0)
830 0 : RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
831 :
832 0 : if (pAnchorRect)
833 0 : *pAnchorRect=aAnkRect;
834 :
835 : // rTextRect might not be correct in some cases at ContourFrame
836 0 : rTextRect=Rectangle(aTextPos,aTextSiz);
837 0 : if (bContourFrame)
838 0 : rTextRect=aAnkRect;
839 0 : }
840 :
841 2238 : OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const
842 : {
843 2238 : OutlinerParaObject* pPara=NULL;
844 2238 : if( HasTextImpl( pEdtOutl ) )
845 : {
846 0 : sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( pEdtOutl->GetParagraphCount() );
847 0 : pPara = pEdtOutl->CreateParaObject(0, nParaAnz);
848 : }
849 2238 : return pPara;
850 : }
851 :
852 0 : void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Size& rTextSize, const Size& rShapeSize, Fraction& rFitXKorreg) const
853 : {
854 0 : OutputDevice* pOut = rOutliner.GetRefDevice();
855 0 : sal_Bool bNoStretching(sal_False);
856 :
857 0 : if(pOut && pOut->GetOutDevType() == OUTDEV_PRINTER)
858 : {
859 : // check whether CharStretching is possible at all
860 0 : GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
861 0 : rtl::OUString aTestString(static_cast<sal_Unicode>('J'));
862 :
863 0 : if(pMtf && (!pMtf->IsRecord() || pMtf->IsPause()))
864 0 : pMtf = NULL;
865 :
866 0 : if(pMtf)
867 0 : pMtf->Pause(sal_True);
868 :
869 0 : Font aFontMerk(pOut->GetFont());
870 0 : Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
871 :
872 0 : aTmpFont.SetSize(Size(0,100));
873 0 : pOut->SetFont(aTmpFont);
874 0 : Size aSize1(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
875 0 : aTmpFont.SetSize(Size(800,100));
876 0 : pOut->SetFont(aTmpFont);
877 0 : Size aSize2(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
878 0 : pOut->SetFont(aFontMerk);
879 :
880 0 : if(pMtf)
881 0 : pMtf->Pause(sal_False);
882 :
883 0 : bNoStretching = (aSize1 == aSize2);
884 :
885 : #ifdef WNT
886 : // Windows zooms the font proportionally when using Size(100,500),
887 : // we don't like that.
888 : if(aSize2.Height() >= aSize1.Height() * 2)
889 : {
890 : bNoStretching = sal_True;
891 : }
892 : #endif
893 : }
894 0 : unsigned nLoopCount=0;
895 0 : bool bNoMoreLoop = false;
896 0 : long nXDiff0=0x7FFFFFFF;
897 0 : long nWantWdt=rShapeSize.Width();
898 0 : long nIsWdt=rTextSize.Width();
899 0 : if (nIsWdt==0) nIsWdt=1;
900 :
901 0 : long nWantHgt=rShapeSize.Height();
902 0 : long nIsHgt=rTextSize.Height();
903 0 : if (nIsHgt==0) nIsHgt=1;
904 :
905 0 : long nXTolPl=nWantWdt/100; // tolerance: +1%
906 0 : long nXTolMi=nWantWdt/25; // tolerance: -4%
907 0 : long nXKorr =nWantWdt/20; // correction scale: 5%
908 :
909 0 : long nX=(nWantWdt*100) /nIsWdt; // calculate X stretching
910 0 : long nY=(nWantHgt*100) /nIsHgt; // calculate Y stretching
911 0 : bool bChkX = true;
912 0 : if (bNoStretching) { // might only be be possible proportionally
913 0 : if (nX>nY) { nX=nY; bChkX=sal_False; }
914 0 : else { nY=nX; }
915 : }
916 :
917 0 : while (nLoopCount<5 && !bNoMoreLoop) {
918 0 : if (nX<0) nX=-nX;
919 0 : if (nX<1) { nX=1; bNoMoreLoop = true; }
920 0 : if (nX>65535) { nX=65535; bNoMoreLoop = true; }
921 :
922 0 : if (nY<0) nY=-nY;
923 0 : if (nY<1) { nY=1; bNoMoreLoop = true; }
924 0 : if (nY>65535) { nY=65535; bNoMoreLoop = true; }
925 :
926 : // exception, there is no text yet (horizontal case)
927 0 : if(nIsWdt <= 1)
928 : {
929 0 : nX = nY;
930 0 : bNoMoreLoop = true;
931 : }
932 :
933 : // exception, there is no text yet (vertical case)
934 0 : if(nIsHgt <= 1)
935 : {
936 0 : nY = nX;
937 0 : bNoMoreLoop = true;
938 : }
939 :
940 0 : rOutliner.SetGlobalCharStretching((sal_uInt16)nX,(sal_uInt16)nY);
941 0 : nLoopCount++;
942 0 : Size aSiz(rOutliner.CalcTextSize());
943 0 : long nXDiff=aSiz.Width()-nWantWdt;
944 0 : rFitXKorreg=Fraction(nWantWdt,aSiz.Width());
945 0 : if (((nXDiff>=nXTolMi || !bChkX) && nXDiff<=nXTolPl) || nXDiff==nXDiff0) {
946 0 : bNoMoreLoop = true;
947 : } else {
948 : // correct stretching factors
949 0 : long nMul=nWantWdt;
950 0 : long nDiv=aSiz.Width();
951 0 : if (Abs(nXDiff)<=2*nXKorr) {
952 0 : if (nMul>nDiv) nDiv+=(nMul-nDiv)/2; // but only add half of what we calculated,
953 0 : else nMul+=(nDiv-nMul)/2; // because the EditEngine calculates wrongly later on
954 : }
955 0 : nX=nX*nMul/nDiv;
956 0 : if (bNoStretching) nY=nX;
957 : }
958 0 : nXDiff0=nXDiff;
959 : }
960 0 : }
961 :
962 32 : void SdrTextObj::TakeObjNameSingul(XubString& rName) const
963 : {
964 32 : XubString aStr;
965 :
966 32 : switch(eTextKind)
967 : {
968 : case OBJ_OUTLINETEXT:
969 : {
970 6 : aStr = ImpGetResStr(STR_ObjNameSingulOUTLINETEXT);
971 6 : break;
972 : }
973 :
974 : case OBJ_TITLETEXT :
975 : {
976 10 : aStr = ImpGetResStr(STR_ObjNameSingulTITLETEXT);
977 10 : break;
978 : }
979 :
980 : default:
981 : {
982 16 : if(IsLinkedText())
983 0 : aStr = ImpGetResStr(STR_ObjNameSingulTEXTLNK);
984 : else
985 16 : aStr = ImpGetResStr(STR_ObjNameSingulTEXT);
986 16 : break;
987 : }
988 : }
989 :
990 32 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
991 32 : if(pOutlinerParaObject && eTextKind != OBJ_OUTLINETEXT)
992 : {
993 : // shouldn't currently cause any problems at OUTLINETEXT
994 26 : XubString aStr2(comphelper::string::stripStart(pOutlinerParaObject->GetTextObject().GetText(0), ' '));
995 :
996 : // avoid non expanded text portions in object name
997 : // (second condition is new)
998 26 : if(aStr2.Len() && aStr2.Search(sal_Unicode(255)) == STRING_NOTFOUND)
999 : {
1000 : // space between ResStr and content text
1001 26 : aStr += sal_Unicode(' ');
1002 :
1003 26 : aStr += sal_Unicode('\'');
1004 :
1005 26 : if(aStr2.Len() > 10)
1006 : {
1007 12 : aStr2.Erase(8);
1008 12 : aStr2.AppendAscii("...", 3);
1009 : }
1010 :
1011 26 : aStr += aStr2;
1012 26 : aStr += sal_Unicode('\'');
1013 26 : }
1014 : }
1015 :
1016 32 : rName = aStr;
1017 :
1018 32 : String aName( GetName() );
1019 32 : if(aName.Len())
1020 : {
1021 0 : rName += sal_Unicode(' ');
1022 0 : rName += sal_Unicode('\'');
1023 0 : rName += aName;
1024 0 : rName += sal_Unicode('\'');
1025 32 : }
1026 :
1027 32 : }
1028 :
1029 0 : void SdrTextObj::TakeObjNamePlural(XubString& rName) const
1030 : {
1031 0 : switch (eTextKind) {
1032 0 : case OBJ_OUTLINETEXT: rName=ImpGetResStr(STR_ObjNamePluralOUTLINETEXT); break;
1033 0 : case OBJ_TITLETEXT : rName=ImpGetResStr(STR_ObjNamePluralTITLETEXT); break;
1034 : default: {
1035 0 : if (IsLinkedText()) {
1036 0 : rName=ImpGetResStr(STR_ObjNamePluralTEXTLNK);
1037 : } else {
1038 0 : rName=ImpGetResStr(STR_ObjNamePluralTEXT);
1039 : }
1040 0 : } break;
1041 : } // switch
1042 0 : }
1043 :
1044 0 : SdrTextObj* SdrTextObj::Clone() const
1045 : {
1046 0 : return CloneHelper< SdrTextObj >();
1047 : }
1048 :
1049 4 : SdrTextObj& SdrTextObj::operator=(const SdrTextObj& rObj)
1050 : {
1051 4 : if( this == &rObj )
1052 0 : return *this;
1053 : // call parent
1054 4 : SdrObject::operator=(rObj);
1055 :
1056 4 : aRect =rObj.aRect;
1057 4 : aGeo =rObj.aGeo;
1058 4 : eTextKind =rObj.eTextKind;
1059 4 : bTextFrame=rObj.bTextFrame;
1060 4 : aTextSize=rObj.aTextSize;
1061 4 : bTextSizeDirty=rObj.bTextSizeDirty;
1062 :
1063 : // Not all of the necessary parameters were copied yet.
1064 4 : bNoShear = rObj.bNoShear;
1065 4 : bNoRotate = rObj.bNoRotate;
1066 4 : bNoMirror = rObj.bNoMirror;
1067 4 : bDisableAutoWidthOnDragging = rObj.bDisableAutoWidthOnDragging;
1068 :
1069 4 : OutlinerParaObject* pNewOutlinerParaObject = 0;
1070 :
1071 4 : SdrText* pText = getActiveText();
1072 :
1073 4 : if( pText && rObj.HasText() )
1074 : {
1075 0 : const Outliner* pEO=rObj.pEdtOutl;
1076 0 : if (pEO!=NULL)
1077 : {
1078 0 : pNewOutlinerParaObject = pEO->CreateParaObject();
1079 : }
1080 : else
1081 : {
1082 0 : pNewOutlinerParaObject = new OutlinerParaObject(*rObj.getActiveText()->GetOutlinerParaObject());
1083 : }
1084 : }
1085 :
1086 4 : mpText->SetOutlinerParaObject( pNewOutlinerParaObject );
1087 4 : ImpSetTextStyleSheetListeners();
1088 4 : return *this;
1089 : }
1090 :
1091 0 : basegfx::B2DPolyPolygon SdrTextObj::TakeXorPoly() const
1092 : {
1093 0 : Polygon aPol(aRect);
1094 0 : if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1095 0 : if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1096 :
1097 0 : basegfx::B2DPolyPolygon aRetval;
1098 0 : aRetval.append(aPol.getB2DPolygon());
1099 0 : return aRetval;
1100 : }
1101 :
1102 0 : basegfx::B2DPolyPolygon SdrTextObj::TakeContour() const
1103 : {
1104 0 : basegfx::B2DPolyPolygon aRetval(SdrAttrObj::TakeContour());
1105 :
1106 : // and now add the BoundRect of the text, if necessary
1107 0 : if ( pModel && GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
1108 : {
1109 : // using Clone()-Paint() strategy inside TakeContour() leaves a destroyed
1110 : // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner
1111 : // in every case
1112 0 : SdrOutliner& rOutliner=ImpGetDrawOutliner();
1113 :
1114 0 : Rectangle aAnchor2;
1115 0 : Rectangle aR;
1116 0 : TakeTextRect(rOutliner,aR,sal_False,&aAnchor2);
1117 0 : rOutliner.Clear();
1118 0 : bool bFitToSize(IsFitToSize());
1119 0 : if (bFitToSize) aR=aAnchor2;
1120 0 : Polygon aPol(aR);
1121 0 : if (aGeo.nDrehWink!=0) RotatePoly(aPol,aR.TopLeft(),aGeo.nSin,aGeo.nCos);
1122 :
1123 0 : aRetval.append(aPol.getB2DPolygon());
1124 : }
1125 :
1126 0 : return aRetval;
1127 : }
1128 :
1129 2820 : void SdrTextObj::RecalcSnapRect()
1130 : {
1131 2820 : if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
1132 7 : Polygon aPol(aRect);
1133 7 : if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1134 7 : if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1135 7 : maSnapRect=aPol.GetBoundRect();
1136 : } else {
1137 2813 : maSnapRect=aRect;
1138 : }
1139 2820 : }
1140 :
1141 0 : sal_uInt32 SdrTextObj::GetSnapPointCount() const
1142 : {
1143 0 : return 4L;
1144 : }
1145 :
1146 0 : Point SdrTextObj::GetSnapPoint(sal_uInt32 i) const
1147 : {
1148 0 : Point aP;
1149 0 : switch (i) {
1150 0 : case 0: aP=aRect.TopLeft(); break;
1151 0 : case 1: aP=aRect.TopRight(); break;
1152 0 : case 2: aP=aRect.BottomLeft(); break;
1153 0 : case 3: aP=aRect.BottomRight(); break;
1154 0 : default: aP=aRect.Center(); break;
1155 : }
1156 0 : if (aGeo.nShearWink!=0) ShearPoint(aP,aRect.TopLeft(),aGeo.nTan);
1157 0 : if (aGeo.nDrehWink!=0) RotatePoint(aP,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1158 0 : return aP;
1159 : }
1160 :
1161 3615 : void SdrTextObj::ImpCheckMasterCachable()
1162 : {
1163 3615 : bNotMasterCachable=sal_False;
1164 :
1165 3615 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1166 :
1167 3615 : if(!bNotVisibleAsMaster && pOutlinerParaObject && pOutlinerParaObject->IsEditDoc() )
1168 : {
1169 3229 : const EditTextObject& rText= pOutlinerParaObject->GetTextObject();
1170 3229 : bNotMasterCachable=rText.HasField(SvxPageField::StaticType());
1171 3229 : if( !bNotMasterCachable )
1172 : {
1173 3105 : bNotMasterCachable=rText.HasField(SvxHeaderField::StaticType());
1174 3105 : if( !bNotMasterCachable )
1175 : {
1176 3043 : bNotMasterCachable=rText.HasField(SvxFooterField::StaticType());
1177 3043 : if( !bNotMasterCachable )
1178 : {
1179 2931 : bNotMasterCachable=rText.HasField(SvxDateTimeField::StaticType());
1180 : }
1181 : }
1182 : }
1183 : }
1184 3615 : }
1185 :
1186 : // Extracted from ImpGetDrawOutliner()
1187 19492 : void SdrTextObj::ImpInitDrawOutliner( SdrOutliner& rOutl ) const
1188 : {
1189 19492 : rOutl.SetUpdateMode(sal_False);
1190 19492 : sal_uInt16 nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
1191 19492 : if ( !IsOutlText() )
1192 18341 : nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
1193 19492 : rOutl.Init( nOutlinerMode );
1194 :
1195 19492 : rOutl.SetGlobalCharStretching(100,100);
1196 19492 : sal_uIntPtr nStat=rOutl.GetControlWord();
1197 19492 : nStat&=~(EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
1198 19492 : rOutl.SetControlWord(nStat);
1199 19492 : Size aNullSize;
1200 19492 : Size aMaxSize(100000,100000);
1201 19492 : rOutl.SetMinAutoPaperSize(aNullSize);
1202 19492 : rOutl.SetMaxAutoPaperSize(aMaxSize);
1203 19492 : rOutl.SetPaperSize(aMaxSize);
1204 19492 : rOutl.ClearPolygon();
1205 19492 : }
1206 :
1207 19492 : SdrOutliner& SdrTextObj::ImpGetDrawOutliner() const
1208 : {
1209 19492 : SdrOutliner& rOutl=pModel->GetDrawOutliner(this);
1210 :
1211 : // Code extracted to ImpInitDrawOutliner()
1212 19492 : ImpInitDrawOutliner( rOutl );
1213 :
1214 19492 : return rOutl;
1215 : }
1216 :
1217 : // Extracted from Paint()
1218 0 : void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool bContourFrame,
1219 : SdrOutliner& rOutliner,
1220 : Rectangle& rTextRect,
1221 : Rectangle& rAnchorRect,
1222 : Rectangle& rPaintRect,
1223 : Fraction& rFitXKorreg ) const
1224 : {
1225 0 : if (!bContourFrame)
1226 : {
1227 : // FitToSize can't be used together with ContourFrame for now
1228 0 : if (IsFitToSize() || IsAutoFit())
1229 : {
1230 0 : sal_uIntPtr nStat=rOutliner.GetControlWord();
1231 0 : nStat|=EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE;
1232 0 : rOutliner.SetControlWord(nStat);
1233 : }
1234 : }
1235 0 : rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
1236 0 : TakeTextRect(rOutliner, rTextRect, sal_False, &rAnchorRect);
1237 0 : rPaintRect = rTextRect;
1238 :
1239 0 : if (!bContourFrame)
1240 : {
1241 : // FitToSize can't be used together with ContourFrame for now
1242 0 : if (IsFitToSize())
1243 : {
1244 0 : ImpSetCharStretching(rOutliner,rTextRect.GetSize(),rAnchorRect.GetSize(),rFitXKorreg);
1245 0 : rPaintRect=rAnchorRect;
1246 : }
1247 0 : else if (IsAutoFit())
1248 : {
1249 0 : ImpAutoFitText(rOutliner);
1250 : }
1251 : }
1252 0 : }
1253 :
1254 0 : void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner ) const
1255 : {
1256 0 : const Size aShapeSize=GetSnapRect().GetSize();
1257 : ImpAutoFitText( rOutliner,
1258 0 : Size(aShapeSize.Width()-GetTextLeftDistance()-GetTextRightDistance(),
1259 0 : aShapeSize.Height()-GetTextUpperDistance()-GetTextLowerDistance()),
1260 0 : IsVerticalWriting() );
1261 0 : }
1262 :
1263 2 : void SdrTextObj::ImpAutoFitText( SdrOutliner& rOutliner, const Size& rTextSize, bool bIsVerticalWriting )
1264 : {
1265 : // EditEngine formatting is unstable enough for
1266 : // line-breaking text that we need some more samples
1267 :
1268 : // loop early-exits if we detect an already attained value
1269 2 : sal_uInt16 nMinStretchX=0, nMinStretchY=0;
1270 2 : sal_uInt16 aOldStretchXVals[]={0,0,0,0,0,0,0,0,0,0};
1271 2 : const size_t aStretchArySize=SAL_N_ELEMENTS(aOldStretchXVals);
1272 4 : for(unsigned int i=0; i<aStretchArySize; ++i)
1273 : {
1274 4 : const Size aCurrTextSize = rOutliner.CalcTextSizeNTP();
1275 4 : double fFactor(1.0);
1276 4 : if( bIsVerticalWriting )
1277 0 : fFactor = double(rTextSize.Width())/aCurrTextSize.Width();
1278 : else
1279 4 : fFactor = double(rTextSize.Height())/aCurrTextSize.Height();
1280 :
1281 : sal_uInt16 nCurrStretchX, nCurrStretchY;
1282 4 : rOutliner.GetGlobalCharStretching(nCurrStretchX, nCurrStretchY);
1283 :
1284 4 : if (fFactor >= 1.0 )
1285 : {
1286 : // resulting text area fits into available shape rect -
1287 : // err on the larger stretching, to optimally fill area
1288 4 : nMinStretchX = std::max(nMinStretchX,nCurrStretchX);
1289 4 : nMinStretchY = std::max(nMinStretchY,nCurrStretchY);
1290 : }
1291 :
1292 4 : aOldStretchXVals[i] = nCurrStretchX;
1293 4 : if( std::find(aOldStretchXVals, aOldStretchXVals+i, nCurrStretchX) != aOldStretchXVals+i )
1294 : break; // same value already attained once; algo is looping, exit
1295 :
1296 2 : if (fFactor < 1.0 || (fFactor >= 1.0 && nCurrStretchX != 100))
1297 : {
1298 0 : nCurrStretchX = sal::static_int_cast<sal_uInt16>(nCurrStretchX*fFactor);
1299 0 : nCurrStretchY = sal::static_int_cast<sal_uInt16>(nCurrStretchY*fFactor);
1300 0 : rOutliner.SetGlobalCharStretching(std::min(sal_uInt16(100),nCurrStretchX),
1301 0 : std::min(sal_uInt16(100),nCurrStretchY));
1302 : OSL_TRACE("SdrTextObj::onEditOutlinerStatusEvent(): zoom is %d", nCurrStretchX);
1303 : }
1304 : }
1305 :
1306 : OSL_TRACE("---- SdrTextObj::onEditOutlinerStatusEvent(): final zoom is %d ----", nMinStretchX);
1307 4 : rOutliner.SetGlobalCharStretching(std::min(sal_uInt16(100),nMinStretchX),
1308 6 : std::min(sal_uInt16(100),nMinStretchY));
1309 2 : }
1310 :
1311 0 : void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1312 : {
1313 0 : ImpInitDrawOutliner( rOutl );
1314 0 : UpdateOutlinerFormatting( rOutl, rPaintRect );
1315 0 : }
1316 :
1317 0 : void SdrTextObj::UpdateOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1318 : {
1319 0 : Rectangle aTextRect;
1320 0 : Rectangle aAnchorRect;
1321 0 : Fraction aFitXKorreg(1,1);
1322 :
1323 0 : bool bContourFrame=IsContourTextFrame();
1324 :
1325 0 : if( GetModel() )
1326 : {
1327 : MapMode aMapMode(GetModel()->GetScaleUnit(), Point(0,0),
1328 0 : GetModel()->GetScaleFraction(),
1329 0 : GetModel()->GetScaleFraction());
1330 0 : rOutl.SetRefMapMode(aMapMode);
1331 : }
1332 :
1333 0 : ImpSetupDrawOutlinerForPaint( bContourFrame, rOutl, aTextRect, aAnchorRect, rPaintRect, aFitXKorreg );
1334 0 : }
1335 :
1336 : ////////////////////////////////////////////////////////////////////////////////////////////////////
1337 :
1338 24229 : OutlinerParaObject* SdrTextObj::GetOutlinerParaObject() const
1339 : {
1340 24229 : SdrText* pText = getActiveText();
1341 24229 : if( pText )
1342 24229 : return pText->GetOutlinerParaObject();
1343 : else
1344 0 : return 0;
1345 : }
1346 :
1347 0 : bool SdrTextObj::HasOutlinerParaObject() const
1348 : {
1349 0 : SdrText* pText = getActiveText();
1350 0 : if( pText && pText->GetOutlinerParaObject() )
1351 0 : return true;
1352 0 : return false;
1353 : }
1354 :
1355 919 : void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
1356 : {
1357 919 : NbcSetOutlinerParaObjectForText( pTextObject, getActiveText() );
1358 919 : }
1359 :
1360 3615 : void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject* pTextObject, SdrText* pText )
1361 : {
1362 3615 : if( pText )
1363 3615 : pText->SetOutlinerParaObject( pTextObject );
1364 :
1365 3615 : if( pText->GetOutlinerParaObject() )
1366 : {
1367 3503 : SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical()
1368 : ? com::sun::star::text::WritingMode_TB_RL
1369 : : com::sun::star::text::WritingMode_LR_TB,
1370 3503 : SDRATTR_TEXTDIRECTION);
1371 3503 : GetProperties().SetObjectItemDirect(aWritingMode);
1372 : }
1373 :
1374 3615 : SetTextSizeDirty();
1375 3615 : if (IsTextFrame() && (IsAutoGrowHeight() || IsAutoGrowWidth()))
1376 : { // adapt text frame!
1377 2273 : NbcAdjustTextFrameWidthAndHeight();
1378 : }
1379 3615 : if (!IsTextFrame())
1380 : {
1381 : // the SnapRect keeps its size
1382 757 : SetRectsDirty(sal_True);
1383 : }
1384 :
1385 : // always invalidate BoundRect on change
1386 3615 : SetBoundRectDirty();
1387 3615 : ActionChanged();
1388 :
1389 3615 : ImpSetTextStyleSheetListeners();
1390 3615 : ImpCheckMasterCachable();
1391 3615 : }
1392 :
1393 1 : void SdrTextObj::NbcReformatText()
1394 : {
1395 1 : SdrText* pText = getActiveText();
1396 1 : if( pText && pText->GetOutlinerParaObject() )
1397 : {
1398 0 : pText->ReformatText();
1399 0 : if (bTextFrame)
1400 : {
1401 0 : NbcAdjustTextFrameWidthAndHeight();
1402 : }
1403 : else
1404 : {
1405 : // the SnapRect keeps its size
1406 0 : SetBoundRectDirty();
1407 0 : SetRectsDirty(sal_True);
1408 : }
1409 0 : SetTextSizeDirty();
1410 0 : ActionChanged();
1411 : // i22396
1412 : // Necessary here since we have no compare operator at the outliner
1413 : // para object which may detect changes regarding the combination
1414 : // of outliner para data and configuration (e.g., change of
1415 : // formatting of text numerals)
1416 0 : GetViewContact().flushViewObjectContacts(false);
1417 : }
1418 1 : }
1419 :
1420 0 : void SdrTextObj::ReformatText()
1421 : {
1422 0 : if(GetOutlinerParaObject())
1423 : {
1424 0 : Rectangle aBoundRect0;
1425 0 : if (pUserCall!=NULL)
1426 0 : aBoundRect0=GetLastBoundRect();
1427 :
1428 0 : NbcReformatText();
1429 0 : SetChanged();
1430 0 : BroadcastObjectChange();
1431 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1432 : }
1433 0 : }
1434 :
1435 0 : SdrObjGeoData* SdrTextObj::NewGeoData() const
1436 : {
1437 0 : return new SdrTextObjGeoData;
1438 : }
1439 :
1440 78 : void SdrTextObj::SaveGeoData(SdrObjGeoData& rGeo) const
1441 : {
1442 78 : SdrAttrObj::SaveGeoData(rGeo);
1443 78 : SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1444 78 : rTGeo.aRect =aRect;
1445 78 : rTGeo.aGeo =aGeo;
1446 78 : }
1447 :
1448 0 : void SdrTextObj::RestGeoData(const SdrObjGeoData& rGeo)
1449 : { // RectsDirty is called by SdrObject
1450 0 : SdrAttrObj::RestGeoData(rGeo);
1451 0 : SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1452 0 : NbcSetLogicRect(rTGeo.aRect);
1453 0 : aGeo =rTGeo.aGeo;
1454 0 : SetTextSizeDirty();
1455 0 : }
1456 :
1457 8288 : SdrFitToSizeType SdrTextObj::GetFitToSize() const
1458 : {
1459 8288 : SdrFitToSizeType eType = SDRTEXTFIT_NONE;
1460 :
1461 8288 : if(!IsAutoGrowWidth())
1462 6138 : eType = ((SdrTextFitToSizeTypeItem&)(GetObjectItem(SDRATTR_TEXT_FITTOSIZE))).GetValue();
1463 :
1464 8288 : return eType;
1465 : }
1466 :
1467 583 : void SdrTextObj::ForceOutlinerParaObject()
1468 : {
1469 583 : SdrText* pText = getActiveText();
1470 583 : if( pText && (pText->GetOutlinerParaObject() == 0) )
1471 : {
1472 4 : sal_uInt16 nOutlMode = OUTLINERMODE_TEXTOBJECT;
1473 4 : if( IsTextFrame() && eTextKind == OBJ_OUTLINETEXT )
1474 0 : nOutlMode = OUTLINERMODE_OUTLINEOBJECT;
1475 :
1476 4 : pText->ForceOutlinerParaObject( nOutlMode );
1477 : }
1478 583 : }
1479 :
1480 514 : sal_Bool SdrTextObj::IsVerticalWriting() const
1481 : {
1482 514 : if(pEdtOutl)
1483 : {
1484 0 : return pEdtOutl->IsVertical();
1485 : }
1486 :
1487 514 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1488 514 : if(pOutlinerParaObject)
1489 : {
1490 214 : return pOutlinerParaObject->IsVertical();
1491 : }
1492 :
1493 300 : return sal_False;
1494 : }
1495 :
1496 3830 : void SdrTextObj::SetVerticalWriting(sal_Bool bVertical)
1497 : {
1498 3830 : OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1499 3830 : if( !pOutlinerParaObject && bVertical )
1500 : {
1501 : // we only need to force a outliner para object if the default of
1502 : // horizontal text is changed
1503 0 : ForceOutlinerParaObject();
1504 0 : pOutlinerParaObject = GetOutlinerParaObject();
1505 : }
1506 :
1507 3830 : if( pOutlinerParaObject && (pOutlinerParaObject->IsVertical() != (bool)bVertical) )
1508 : {
1509 : // get item settings
1510 0 : const SfxItemSet& rSet = GetObjectItemSet();
1511 0 : sal_Bool bAutoGrowWidth = ((SdrTextAutoGrowWidthItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH)).GetValue();
1512 0 : sal_Bool bAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue();
1513 :
1514 : // Also exchange hor/ver adjust items
1515 0 : SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
1516 0 : SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
1517 :
1518 : // rescue object size
1519 0 : Rectangle aObjectRect = GetSnapRect();
1520 :
1521 : // prepare ItemSet to set exchanged width and height items
1522 0 : SfxItemSet aNewSet(*rSet.GetPool(),
1523 : SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
1524 : // Expanded item ranges to also support hor and ver adjust.
1525 : SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
1526 : SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
1527 0 : 0, 0);
1528 :
1529 0 : aNewSet.Put(rSet);
1530 0 : aNewSet.Put(SdrTextAutoGrowWidthItem(bAutoGrowHeight));
1531 0 : aNewSet.Put(SdrTextAutoGrowHeightItem(bAutoGrowWidth));
1532 :
1533 : // Exchange horz and vert adjusts
1534 0 : switch(eVert)
1535 : {
1536 0 : case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
1537 0 : case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
1538 0 : case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
1539 0 : case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
1540 : }
1541 0 : switch(eHorz)
1542 : {
1543 0 : case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
1544 0 : case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
1545 0 : case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
1546 0 : case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
1547 : }
1548 :
1549 0 : SetObjectItemSet(aNewSet);
1550 :
1551 0 : pOutlinerParaObject = GetOutlinerParaObject();
1552 0 : if( pOutlinerParaObject )
1553 : {
1554 : // set ParaObject orientation accordingly
1555 0 : pOutlinerParaObject->SetVertical(bVertical);
1556 : }
1557 :
1558 : // restore object size
1559 0 : SetSnapRect(aObjectRect);
1560 : }
1561 3830 : }
1562 :
1563 : ////////////////////////////////////////////////////////////////////////////////////////////////////
1564 : //
1565 : // transformation interface for StarOfficeAPI. This implements support for
1566 : // homogeneous 3x3 matrices containing the transformation of the SdrObject. At the
1567 : // moment it contains a shearX, rotation and translation, but for setting all linear
1568 : // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
1569 : //
1570 : ////////////////////////////////////////////////////////////////////////////////////////////////////
1571 : // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
1572 : // with the base geometry and returns TRUE. Otherwise it returns FALSE.
1573 1303 : sal_Bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
1574 : {
1575 : // get turn and shear
1576 1303 : double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
1577 1303 : double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
1578 :
1579 : // get aRect, this is the unrotated snaprect
1580 1303 : Rectangle aRectangle(aRect);
1581 :
1582 : // fill other values
1583 1303 : basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
1584 1303 : basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
1585 :
1586 : // position maybe relative to anchorpos, convert
1587 1303 : if( pModel && pModel->IsWriter() )
1588 : {
1589 13 : if(GetAnchorPos().X() || GetAnchorPos().Y())
1590 : {
1591 0 : aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1592 : }
1593 : }
1594 :
1595 : // force MapUnit to 100th mm
1596 1303 : SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
1597 1303 : if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1598 : {
1599 13 : switch(eMapUnit)
1600 : {
1601 : case SFX_MAPUNIT_TWIP :
1602 : {
1603 : // postion
1604 13 : aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
1605 13 : aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
1606 :
1607 : // size
1608 13 : aScale.setX(ImplTwipsToMM(aScale.getX()));
1609 13 : aScale.setY(ImplTwipsToMM(aScale.getY()));
1610 :
1611 13 : break;
1612 : }
1613 : default:
1614 : {
1615 : OSL_FAIL("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1616 : }
1617 : }
1618 : }
1619 :
1620 : // build matrix
1621 : rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1622 : aScale,
1623 1303 : basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
1624 1303 : basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
1625 2606 : aTranslate);
1626 :
1627 1303 : return sal_False;
1628 : }
1629 :
1630 : // sets the base geometry of the object using infos contained in the homogeneous 3x3 matrix.
1631 : // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
1632 : // to use (0,0) as upper left and will be scaled to the given size in the matrix.
1633 1300 : void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
1634 : {
1635 : // break up matrix
1636 1300 : basegfx::B2DTuple aScale;
1637 1300 : basegfx::B2DTuple aTranslate;
1638 1300 : double fRotate(0.0);
1639 1300 : double fShearX(0.0);
1640 1300 : rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1641 :
1642 : // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
1643 : // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
1644 1300 : if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
1645 : {
1646 0 : aScale.setX(fabs(aScale.getX()));
1647 0 : aScale.setY(fabs(aScale.getY()));
1648 0 : fRotate = fmod(fRotate + F_PI, F_2PI);
1649 : }
1650 :
1651 : // reset object shear and rotations
1652 1300 : aGeo.nDrehWink = 0;
1653 1300 : aGeo.RecalcSinCos();
1654 1300 : aGeo.nShearWink = 0;
1655 1300 : aGeo.RecalcTan();
1656 :
1657 : // force metric to pool metric
1658 1300 : SfxMapUnit eMapUnit = GetObjectItemSet().GetPool()->GetMetric(0);
1659 1300 : if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1660 : {
1661 13 : switch(eMapUnit)
1662 : {
1663 : case SFX_MAPUNIT_TWIP :
1664 : {
1665 : // position
1666 13 : aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
1667 13 : aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
1668 :
1669 : // size
1670 13 : aScale.setX(ImplMMToTwips(aScale.getX()));
1671 13 : aScale.setY(ImplMMToTwips(aScale.getY()));
1672 :
1673 13 : break;
1674 : }
1675 : default:
1676 : {
1677 : OSL_FAIL("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1678 : }
1679 : }
1680 : }
1681 :
1682 : // if anchor is used, make position relative to it
1683 1300 : if( pModel && pModel->IsWriter() )
1684 : {
1685 13 : if(GetAnchorPos().X() || GetAnchorPos().Y())
1686 : {
1687 0 : aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1688 : }
1689 : }
1690 :
1691 : // build and set BaseRect (use scale)
1692 1300 : Point aPoint = Point();
1693 1300 : Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
1694 1300 : Rectangle aBaseRect(aPoint, aSize);
1695 1300 : SetSnapRect(aBaseRect);
1696 :
1697 : // shear?
1698 1300 : if(!basegfx::fTools::equalZero(fShearX))
1699 : {
1700 0 : GeoStat aGeoStat;
1701 0 : aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
1702 0 : aGeoStat.RecalcTan();
1703 0 : Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, sal_False);
1704 : }
1705 :
1706 : // rotation?
1707 1300 : if(!basegfx::fTools::equalZero(fRotate))
1708 : {
1709 5 : GeoStat aGeoStat;
1710 :
1711 : // #i78696#
1712 : // fRotate is matematically correct, but aGeoStat.nDrehWink is
1713 : // mirrored -> mirror value here
1714 5 : aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
1715 5 : aGeoStat.RecalcSinCos();
1716 5 : Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1717 : }
1718 :
1719 : // translate?
1720 1300 : if(!aTranslate.equalZero())
1721 : {
1722 1285 : Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
1723 1300 : }
1724 1300 : }
1725 :
1726 0 : bool SdrTextObj::IsRealyEdited() const
1727 : {
1728 0 : return pEdtOutl && pEdtOutl->IsModified();
1729 : }
1730 :
1731 : /////////////////////////////////////////////////////////////////////////////////////////////////
1732 : // moved inlines here form hxx
1733 :
1734 1917 : long SdrTextObj::GetEckenradius() const
1735 : {
1736 1917 : return ((SdrEckenradiusItem&)(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS))).GetValue();
1737 : }
1738 :
1739 6437 : long SdrTextObj::GetMinTextFrameHeight() const
1740 : {
1741 6437 : return ((SdrTextMinFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT))).GetValue();
1742 : }
1743 :
1744 6437 : long SdrTextObj::GetMaxTextFrameHeight() const
1745 : {
1746 6437 : return ((SdrTextMaxFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT))).GetValue();
1747 : }
1748 :
1749 2192 : long SdrTextObj::GetMinTextFrameWidth() const
1750 : {
1751 2192 : return ((SdrTextMinFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH))).GetValue();
1752 : }
1753 :
1754 2192 : long SdrTextObj::GetMaxTextFrameWidth() const
1755 : {
1756 2192 : return ((SdrTextMaxFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH))).GetValue();
1757 : }
1758 :
1759 1 : bool SdrTextObj::IsFontwork() const
1760 : {
1761 : return (bTextFrame) ? false // Default is FALSE
1762 1 : : ((XFormTextStyleItem&)(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE))).GetValue()!=XFT_NONE;
1763 : }
1764 :
1765 0 : bool SdrTextObj::IsHideContour() const
1766 : {
1767 : return (bTextFrame) ? false // Default is: no, don't HideContour; HideContour not together with TextFrames
1768 0 : : ((XFormTextHideFormItem&)(GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM))).GetValue();
1769 : }
1770 :
1771 7518 : bool SdrTextObj::IsContourTextFrame() const
1772 : {
1773 : return (bTextFrame) ? false // ContourFrame not together with normal TextFrames
1774 7518 : : ((SdrTextContourFrameItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME))).GetValue();
1775 : }
1776 :
1777 13574 : long SdrTextObj::GetTextLeftDistance() const
1778 : {
1779 13574 : return ((SdrTextLeftDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue();
1780 : }
1781 :
1782 13574 : long SdrTextObj::GetTextRightDistance() const
1783 : {
1784 13574 : return ((SdrTextRightDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue();
1785 : }
1786 :
1787 13574 : long SdrTextObj::GetTextUpperDistance() const
1788 : {
1789 13574 : return ((SdrTextUpperDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue();
1790 : }
1791 :
1792 13574 : long SdrTextObj::GetTextLowerDistance() const
1793 : {
1794 13574 : return ((SdrTextLowerDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue();
1795 : }
1796 :
1797 54079 : SdrTextAniKind SdrTextObj::GetTextAniKind() const
1798 : {
1799 54079 : return ((SdrTextAniKindItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND))).GetValue();
1800 : }
1801 :
1802 8111 : SdrTextAniDirection SdrTextObj::GetTextAniDirection() const
1803 : {
1804 8111 : return ((SdrTextAniDirectionItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1805 : }
1806 :
1807 : // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
1808 : // painting rectangle. Rotation is excluded from the returned values.
1809 0 : GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
1810 : Rectangle& rScrollRectangle, Rectangle& rPaintRectangle)
1811 : {
1812 0 : GDIMetaFile* pRetval = 0L;
1813 0 : SdrOutliner& rOutliner = ImpGetDrawOutliner();
1814 0 : Rectangle aTextRect;
1815 0 : Rectangle aAnchorRect;
1816 0 : Rectangle aPaintRect;
1817 0 : Fraction aFitXKorreg(1,1);
1818 0 : bool bContourFrame(IsContourTextFrame());
1819 :
1820 : // get outliner set up. To avoid getting a somehow rotated MetaFile,
1821 : // temporarily disable object rotation.
1822 0 : sal_Int32 nAngle(aGeo.nDrehWink);
1823 0 : aGeo.nDrehWink = 0L;
1824 0 : ImpSetupDrawOutlinerForPaint( bContourFrame, rOutliner, aTextRect, aAnchorRect, aPaintRect, aFitXKorreg );
1825 0 : aGeo.nDrehWink = nAngle;
1826 :
1827 0 : Rectangle aScrollFrameRect(aPaintRect);
1828 0 : const SfxItemSet& rSet = GetObjectItemSet();
1829 0 : SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1830 :
1831 0 : if(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection)
1832 : {
1833 0 : aScrollFrameRect.Left() = aAnchorRect.Left();
1834 0 : aScrollFrameRect.Right() = aAnchorRect.Right();
1835 : }
1836 :
1837 0 : if(SDRTEXTANI_UP == eDirection || SDRTEXTANI_DOWN == eDirection)
1838 : {
1839 0 : aScrollFrameRect.Top() = aAnchorRect.Top();
1840 0 : aScrollFrameRect.Bottom() = aAnchorRect.Bottom();
1841 : }
1842 :
1843 : // create the MetaFile
1844 0 : pRetval = new GDIMetaFile;
1845 0 : VirtualDevice aBlackHole;
1846 0 : aBlackHole.EnableOutput(sal_False);
1847 0 : pRetval->Record(&aBlackHole);
1848 0 : Point aPaintPos = aPaintRect.TopLeft();
1849 :
1850 0 : rOutliner.Draw(&aBlackHole, aPaintPos);
1851 :
1852 0 : pRetval->Stop();
1853 0 : pRetval->WindStart();
1854 :
1855 : // return PaintRectanglePixel and pRetval;
1856 0 : rScrollRectangle = aScrollFrameRect;
1857 0 : rPaintRectangle = aPaintRect;
1858 :
1859 0 : return pRetval;
1860 : }
1861 :
1862 : // Access to TextAnimationAllowed flag
1863 89 : bool SdrTextObj::IsAutoFit() const
1864 : {
1865 89 : return GetFitToSize()==SDRTEXTFIT_AUTOFIT;
1866 : }
1867 :
1868 8199 : bool SdrTextObj::IsFitToSize() const
1869 : {
1870 8199 : const SdrFitToSizeType eFit=GetFitToSize();
1871 8199 : return (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
1872 : }
1873 :
1874 0 : void SdrTextObj::SetTextAnimationAllowed(sal_Bool bNew)
1875 : {
1876 0 : if(mbTextAnimationAllowed != bNew)
1877 : {
1878 0 : mbTextAnimationAllowed = bNew;
1879 0 : ActionChanged();
1880 : }
1881 0 : }
1882 :
1883 : /** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
1884 0 : void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
1885 : {
1886 0 : const sal_uInt32 nStat = pEditStatus->GetStatusWord();
1887 0 : const bool bGrowX=(nStat & EE_STAT_TEXTWIDTHCHANGED) !=0;
1888 0 : const bool bGrowY=(nStat & EE_STAT_TEXTHEIGHTCHANGED) !=0;
1889 0 : if(bTextFrame && (bGrowX || bGrowY))
1890 : {
1891 0 : if ((bGrowX && IsAutoGrowWidth()) || (bGrowY && IsAutoGrowHeight()))
1892 : {
1893 0 : AdjustTextFrameWidthAndHeight();
1894 : }
1895 0 : else if (IsAutoFit() && !mbInDownScale)
1896 : {
1897 : OSL_ASSERT(pEdtOutl);
1898 0 : mbInDownScale = sal_True;
1899 :
1900 : // sucks that we cannot disable paints via
1901 : // pEdtOutl->SetUpdateMode(FALSE) - but EditEngine skips
1902 : // formatting as well, then.
1903 0 : ImpAutoFitText(*pEdtOutl);
1904 0 : mbInDownScale = sal_False;
1905 : }
1906 : }
1907 0 : }
1908 :
1909 : /** returns the currently active text. */
1910 26870 : SdrText* SdrTextObj::getActiveText() const
1911 : {
1912 26870 : if( !mpText )
1913 4 : return getText( 0 );
1914 : else
1915 26866 : return mpText;
1916 : }
1917 :
1918 : /** returns the nth available text. */
1919 33346 : SdrText* SdrTextObj::getText( sal_Int32 nIndex ) const
1920 : {
1921 33346 : if( nIndex == 0 )
1922 : {
1923 33346 : if( mpText == 0 )
1924 4153 : const_cast< SdrTextObj* >(this)->mpText = new SdrText( *(const_cast< SdrTextObj* >(this)) );
1925 33346 : return mpText;
1926 : }
1927 : else
1928 : {
1929 0 : return 0;
1930 : }
1931 : }
1932 :
1933 : /** returns the number of texts available for this object. */
1934 27599 : sal_Int32 SdrTextObj::getTextCount() const
1935 : {
1936 27599 : return 1;
1937 : }
1938 :
1939 : /** changes the current active text */
1940 0 : void SdrTextObj::setActiveText( sal_Int32 /*nIndex*/ )
1941 : {
1942 0 : }
1943 :
1944 : /** returns the index of the text that contains the given point or -1 */
1945 0 : sal_Int32 SdrTextObj::CheckTextHit(const Point& /*rPnt*/) const
1946 : {
1947 0 : return 0;
1948 : }
1949 :
1950 0 : void SdrTextObj::SetObjectItemNoBroadcast(const SfxPoolItem& rItem)
1951 : {
1952 0 : static_cast< sdr::properties::TextProperties& >(GetProperties()).SetObjectItemNoBroadcast(rItem);
1953 0 : }
1954 :
1955 : /////////////////////////////////////////////////////////////////////////////////////////////////
1956 : //
1957 : // The concept of the text object:
1958 : // ~~~~~~~~~~~~~~~~~~~~~~~~
1959 : // Attributes/Variations:
1960 : // - sal_Bool text frame / graphics object with caption
1961 : // - sal_Bool FontWork (if it is not a text frame and not a ContourTextFrame)
1962 : // - sal_Bool ContourTextFrame (if it is not a text frame and not Fontwork)
1963 : // - long rotation angle (if it is not FontWork)
1964 : // - long text frame margins (if it is not FontWork)
1965 : // - sal_Bool FitToSize (if it is not FontWork)
1966 : // - sal_Bool AutoGrowingWidth/Height (if it is not FitToSize and not FontWork)
1967 : // - long Min/MaxFrameWidth/Height (if AutoGrowingWidth/Height)
1968 : // - enum horizontal text anchoring left,center,right,justify/block,Stretch(ni)
1969 : // - enum vertical text anchoring top, middle, bottom, block, stretch(ni)
1970 : // - enum ticker text (if it is not FontWork)
1971 : //
1972 : // Every derived object is either a text frame (bTextFrame=sal_True)
1973 : // or a drawing object with a caption (bTextFrame=sal_False).
1974 : //
1975 : // Default anchoring for text frames:
1976 : // SDRTEXTHORZADJUST_BLOCK, SDRTEXTVERTADJUST_TOP
1977 : // = static Pool defaults
1978 : // Default anchoring for drawing objects with a caption:
1979 : // SDRTEXTHORZADJUST_CENTER, SDRTEXTVERTADJUST_CENTER
1980 : // via "hard" attribution of SdrAttrObj
1981 : //
1982 : // Every object derived from SdrTextObj must return an "UnrotatedSnapRect"
1983 : // (->TakeUnrotatedSnapRect()) (the reference point for the rotation is the top
1984 : // left of the rectangle (aGeo.nDrehWink)) which is the basis for anchoring
1985 : // text. We then subtract the text frame margins from this rectangle, as a re-
1986 : // sult we get the anchoring area (->TakeTextAnchorRect()). Within this area, we
1987 : // calculate the anchoring point and the painting area, depending on the hori-
1988 : // zontal and vertical adjustment of the text (SdrTextVertAdjust,
1989 : // SdrTextHorzAdjust).
1990 : // In the case of drawing objects with a caption the painting area might well
1991 : // be larger than the anchoring area, for text frames on the other hand, it is
1992 : // always of the same or a smaller size (except when there are negative text
1993 : // frame margins).
1994 : //
1995 : // FitToSize takes priority over text anchoring and AutoGrowHeight/Width. When
1996 : // FitToSize is turned on, the painting area is always equal to the anchoring
1997 : // area. Additionally, FitToSize doesn't allow automatic line breaks.
1998 : //
1999 : // ContourTextFrame:
2000 : // - long rotation angle
2001 : // - long text frame margins (maybe later)
2002 : // - sal_Bool FitToSize (maybe later)
2003 : // - sal_Bool AutoGrowingWidth/Height (maybe much later)
2004 : // - long Min/MaxFrameWidth/Height (maybe much later)
2005 : // - enum horizontal text anchoring (maybe later, for now: left, centered)
2006 : // - enum vertical text anchoring (maybe later, for now: top)
2007 : // - enum ticker text (maybe later, maybe even with correct clipping)
2008 : //
2009 : // When making changes, check these:
2010 : // - Paint
2011 : // - HitTest
2012 : // - ConvertToPoly
2013 : // - Edit
2014 : // - Printing, Saving, Painting in neighboring View while editing
2015 : // - ModelChanged (e. g. through a neighboring View or rulers) while editing
2016 : // - FillColorChanged while editin
2017 : // - and many more...
2018 : //
2019 : /////////////////////////////////////////////////////////////////////////////////////////////////
2020 :
2021 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|