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/svdotext.hxx>
28 #include "svx/svditext.hxx"
29 #include <svx/svdpagv.hxx> // fuer Abfrage im Paint, ob das
30 #include <svx/svdview.hxx> // Objekt gerade editiert wird
31 #include <svx/svdpage.hxx> // und fuer AnimationHandler (Laufschrift)
32 #include <svx/svdetc.hxx>
33 #include <svx/svdoutl.hxx>
34 #include <svx/svdmodel.hxx> // OutlinerDefaults
35 #include "svx/svdglob.hxx" // Stringcache
36 #include "svx/svdstr.hrc" // Objektname
37 #include <editeng/writingmodeitem.hxx>
38 #include <svx/sdtfchim.hxx>
39 #include <svtools/colorcfg.hxx>
40 #include <editeng/eeitem.hxx>
41 #include <editeng/editstat.hxx>
42 #include <editeng/outlobj.hxx>
43 #include <editeng/editobj.hxx>
44 #include <editeng/outliner.hxx>
45 #include <editeng/fhgtitem.hxx>
46 #include <svl/itempool.hxx>
47 #include <editeng/adjitem.hxx>
48 #include <editeng/flditem.hxx>
49 #include <svx/xftouit.hxx>
50 #include <vcl/salbtype.hxx> // FRound
51 #include <svx/xflgrit.hxx>
52 #include <svx/svdpool.hxx>
53 #include <svx/xflclit.hxx>
54 #include <svl/style.hxx>
55 #include <editeng/editeng.hxx>
56 #include <svl/itemiter.hxx>
57 #include <svx/sdr/properties/textproperties.hxx>
58 #include <vcl/metaact.hxx>
59 #include <svx/sdr/contact/viewcontactoftextobj.hxx>
60 #include <basegfx/tuple/b2dtuple.hxx>
61 #include <basegfx/matrix/b2dhommatrix.hxx>
62 #include <basegfx/polygon/b2dpolygon.hxx>
63 #include <drawinglayer/geometry/viewinformation2d.hxx>
64 #include <vcl/virdev.hxx>
65 #include <basegfx/matrix/b2dhommatrixtools.hxx>
66
67 //////////////////////////////////////////////////////////////////////////////
68
69 using namespace com::sun::star;
70
71 //////////////////////////////////////////////////////////////////////////////
72 // #104018# replace macros above with type-safe methods
ImplTwipsToMM(double fVal)73 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); }
ImplMMToTwips(double fVal)74 inline double ImplMMToTwips(double fVal) { return (fVal * (72.0 / 127.0)); }
75
76 ////////////////////////////////////////////////////////////////////////////////////////////////////
77 //
78 // @@@@@@ @@@@@ @@ @@ @@@@@@ @@@@ @@@@@ @@@@@@
79 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@
80 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
81 // @@ @@@@ @@@ @@ @@ @@ @@@@@ @@
82 // @@ @@ @@@@@ @@ @@ @@ @@ @@ @@
83 // @@ @@ @@@ @@@ @@ @@ @@ @@ @@ @@ @@
84 // @@ @@@@@ @@ @@ @@ @@@@ @@@@@ @@@@
85 //
86 ////////////////////////////////////////////////////////////////////////////////////////////////////
87
88 //////////////////////////////////////////////////////////////////////////////
89 // BaseProperties section
90
CreateObjectSpecificProperties()91 sdr::properties::BaseProperties* SdrTextObj::CreateObjectSpecificProperties()
92 {
93 return new sdr::properties::TextProperties(*this);
94 }
95
96 //////////////////////////////////////////////////////////////////////////////
97 // DrawContact section
98
CreateObjectSpecificViewContact()99 sdr::contact::ViewContact* SdrTextObj::CreateObjectSpecificViewContact()
100 {
101 return new sdr::contact::ViewContactOfTextObj(*this);
102 }
103
104 //////////////////////////////////////////////////////////////////////////////
105
106 TYPEINIT1(SdrTextObj,SdrAttrObj);
107
SdrTextObj()108 SdrTextObj::SdrTextObj()
109 : SdrAttrObj(),
110 mpText(NULL),
111 pEdtOutl(NULL),
112 pFormTextBoundRect(NULL),
113 eTextKind(OBJ_TEXT)
114 {
115 bTextSizeDirty=sal_False;
116 bTextFrame=sal_False;
117 bNoShear=sal_False;
118 bNoRotate=sal_False;
119 bNoMirror=sal_False;
120 bDisableAutoWidthOnDragging=sal_False;
121
122 // #101684#
123 mbInEditMode = sal_False;
124
125 // #111096#
126 mbTextHidden = sal_False;
127
128 // #111096#
129 mbTextAnimationAllowed = sal_True;
130
131 // #108784#
132 maTextEditOffset = Point(0, 0);
133
134 // #i25616#
135 mbSupportTextIndentingOnLineWidthChange = sal_True;
136 }
137
SdrTextObj(const Rectangle & rNewRect)138 SdrTextObj::SdrTextObj(const Rectangle& rNewRect)
139 : SdrAttrObj(),
140 aRect(rNewRect),
141 mpText(NULL),
142 pEdtOutl(NULL),
143 pFormTextBoundRect(NULL)
144 {
145 bTextSizeDirty=sal_False;
146 bTextFrame=sal_False;
147 bNoShear=sal_False;
148 bNoRotate=sal_False;
149 bNoMirror=sal_False;
150 bDisableAutoWidthOnDragging=sal_False;
151 ImpJustifyRect(aRect);
152
153 // #101684#
154 mbInEditMode = sal_False;
155
156 // #111096#
157 mbTextHidden = sal_False;
158
159 // #111096#
160 mbTextAnimationAllowed = sal_True;
161
162 // #108784#
163 maTextEditOffset = Point(0, 0);
164
165 // #i25616#
166 mbSupportTextIndentingOnLineWidthChange = sal_True;
167 }
168
SdrTextObj(SdrObjKind eNewTextKind)169 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind)
170 : SdrAttrObj(),
171 mpText(NULL),
172 pEdtOutl(NULL),
173 pFormTextBoundRect(NULL),
174 eTextKind(eNewTextKind)
175 {
176 bTextSizeDirty=sal_False;
177 bTextFrame=sal_True;
178 bNoShear=sal_True;
179 bNoRotate=sal_False;
180 bNoMirror=sal_True;
181 bDisableAutoWidthOnDragging=sal_False;
182
183 // #101684#
184 mbInEditMode = sal_False;
185
186 // #111096#
187 mbTextHidden = sal_False;
188
189 // #111096#
190 mbTextAnimationAllowed = sal_True;
191
192 // #108784#
193 maTextEditOffset = Point(0, 0);
194
195 // #i25616#
196 mbSupportTextIndentingOnLineWidthChange = sal_True;
197 }
198
SdrTextObj(SdrObjKind eNewTextKind,const Rectangle & rNewRect)199 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect)
200 : SdrAttrObj(),
201 aRect(rNewRect),
202 mpText(NULL),
203 pEdtOutl(NULL),
204 pFormTextBoundRect(NULL),
205 eTextKind(eNewTextKind)
206 {
207 bTextSizeDirty=sal_False;
208 bTextFrame=sal_True;
209 bNoShear=sal_True;
210 bNoRotate=sal_False;
211 bNoMirror=sal_True;
212 bDisableAutoWidthOnDragging=sal_False;
213 ImpJustifyRect(aRect);
214
215 // #101684#
216 mbInEditMode = sal_False;
217
218 // #111096#
219 mbTextHidden = sal_False;
220
221 // #111096#
222 mbTextAnimationAllowed = sal_True;
223
224 // #108784#
225 maTextEditOffset = Point(0, 0);
226
227 // #i25616#
228 mbSupportTextIndentingOnLineWidthChange = sal_True;
229 }
230
SdrTextObj(SdrObjKind eNewTextKind,const Rectangle & rNewRect,SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat)231 SdrTextObj::SdrTextObj(SdrObjKind eNewTextKind, const Rectangle& rNewRect, SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
232 : SdrAttrObj(),
233 aRect(rNewRect),
234 mpText(NULL),
235 pEdtOutl(NULL),
236 pFormTextBoundRect(NULL),
237 eTextKind(eNewTextKind)
238 {
239 bTextSizeDirty=sal_False;
240 bTextFrame=sal_True;
241 bNoShear=sal_True;
242 bNoRotate=sal_False;
243 bNoMirror=sal_True;
244 bDisableAutoWidthOnDragging=sal_False;
245 ImpJustifyRect(aRect);
246
247 NbcSetText(rInput, rBaseURL, eFormat);
248
249 // #101684#
250 mbInEditMode = sal_False;
251
252 // #111096#
253 mbTextHidden = sal_False;
254
255 // #111096#
256 mbTextAnimationAllowed = sal_True;
257
258 // #108784#
259 maTextEditOffset = Point(0, 0);
260
261 // #i25616#
262 mbSupportTextIndentingOnLineWidthChange = sal_True;
263 }
264
~SdrTextObj()265 SdrTextObj::~SdrTextObj()
266 {
267 if( pModel )
268 {
269 SdrOutliner& rOutl = pModel->GetHitTestOutliner();
270 if( rOutl.GetTextObj() == this )
271 rOutl.SetTextObj( NULL );
272 }
273
274 if(mpText!=NULL)
275 delete mpText;
276
277 if (pFormTextBoundRect!=NULL)
278 delete pFormTextBoundRect;
279
280 ImpLinkAbmeldung();
281 }
282
FitFrameToTextSize()283 void SdrTextObj::FitFrameToTextSize()
284 {
285 DBG_ASSERT(pModel!=NULL,"SdrTextObj::FitFrameToTextSize(): pModel=NULL!");
286 ImpJustifyRect(aRect);
287
288 SdrText* pText = getActiveText();
289 if( pText!=NULL && pText->GetOutlinerParaObject() && pModel!=NULL)
290 {
291 SdrOutliner& rOutliner=ImpGetDrawOutliner();
292 rOutliner.SetPaperSize(Size(aRect.Right()-aRect.Left(),aRect.Bottom()-aRect.Top()));
293 rOutliner.SetUpdateMode(sal_True);
294 rOutliner.SetText(*pText->GetOutlinerParaObject());
295 Rectangle aTextRect;
296 Size aNewSize(rOutliner.CalcTextSize());
297 rOutliner.Clear();
298 aNewSize.Width()++; // wegen evtl. Rundungsfehler
299 aNewSize.Width()+=GetTextLeftDistance()+GetTextRightDistance();
300 aNewSize.Height()+=GetTextUpperDistance()+GetTextLowerDistance();
301 Rectangle aNewRect(aRect);
302 aNewRect.SetSize(aNewSize);
303 ImpJustifyRect(aNewRect);
304 if (aNewRect!=aRect) {
305 SetLogicRect(aNewRect);
306 }
307 }
308 }
309
NbcSetText(const XubString & rStr)310 void SdrTextObj::NbcSetText(const XubString& rStr)
311 {
312 SdrOutliner& rOutliner=ImpGetDrawOutliner();
313 rOutliner.SetStyleSheet( 0, GetStyleSheet());
314 //OutputDevice* pRef1=rOutliner.GetRefDevice();
315 rOutliner.SetUpdateMode(sal_True);
316 rOutliner.SetText(rStr,rOutliner.GetParagraph( 0 ));
317 OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
318 Size aSiz(rOutliner.CalcTextSize());
319 //OutputDevice* pRef2=rOutliner.GetRefDevice();
320 rOutliner.Clear();
321 NbcSetOutlinerParaObject(pNewText);
322 aTextSize=aSiz;
323 bTextSizeDirty=sal_False;
324 }
325
SetText(const XubString & rStr)326 void SdrTextObj::SetText(const XubString& rStr)
327 {
328 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
329 // #110094#-14 SendRepaintBroadcast();
330 NbcSetText(rStr);
331 SetChanged();
332 BroadcastObjectChange();
333 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
334 //if (GetBoundRect()!=aBoundRect0) {
335 // SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
336 //}
337 }
338
NbcSetText(SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat)339 void SdrTextObj::NbcSetText(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
340 {
341 SdrOutliner& rOutliner=ImpGetDrawOutliner();
342 rOutliner.SetStyleSheet( 0, GetStyleSheet());
343 rOutliner.Read(rInput,rBaseURL,eFormat);
344 OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
345 rOutliner.SetUpdateMode(sal_True);
346 Size aSiz(rOutliner.CalcTextSize());
347 rOutliner.Clear();
348 NbcSetOutlinerParaObject(pNewText);
349 aTextSize=aSiz;
350 bTextSizeDirty=sal_False;
351 }
352
SetText(SvStream & rInput,const String & rBaseURL,sal_uInt16 eFormat)353 void SdrTextObj::SetText(SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat)
354 {
355 Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
356 // #110094#-14 SendRepaintBroadcast();
357 NbcSetText(rInput,rBaseURL,eFormat);
358 SetChanged();
359 BroadcastObjectChange();
360 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
361 }
362
GetTextSize() const363 const Size& SdrTextObj::GetTextSize() const
364 {
365 if (bTextSizeDirty)
366 {
367 Size aSiz;
368 SdrText* pText = getActiveText();
369 if( pText && pText->GetOutlinerParaObject ())
370 {
371 SdrOutliner& rOutliner=ImpGetDrawOutliner();
372 rOutliner.SetText(*pText->GetOutlinerParaObject());
373 rOutliner.SetUpdateMode(sal_True);
374 aSiz=rOutliner.CalcTextSize();
375 rOutliner.Clear();
376 }
377 // 2x casting auf nonconst
378 ((SdrTextObj*)this)->aTextSize=aSiz;
379 ((SdrTextObj*)this)->bTextSizeDirty=sal_False;
380 }
381 return aTextSize;
382 }
383
IsAutoGrowHeight() const384 FASTBOOL SdrTextObj::IsAutoGrowHeight() const
385 {
386 if(!bTextFrame)
387 return sal_False; // AutoGrow nur bei TextFrames
388
389 const SfxItemSet& rSet = GetObjectItemSet();
390 sal_Bool bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
391
392 if(bRet)
393 {
394 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
395
396 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
397 {
398 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
399
400 if(eDirection == SDRTEXTANI_UP || eDirection == SDRTEXTANI_DOWN)
401 {
402 bRet = sal_False;
403 }
404 }
405 }
406 return bRet;
407 }
408
IsAutoGrowWidth() const409 FASTBOOL SdrTextObj::IsAutoGrowWidth() const
410 {
411 if(!bTextFrame)
412 return sal_False; // AutoGrow nur bei TextFrames
413
414 const SfxItemSet& rSet = GetObjectItemSet();
415 sal_Bool bRet = ((SdrTextAutoGrowHeightItem&)(rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
416
417 // #101684#
418 sal_Bool bInEditMOde = IsInEditMode();
419
420 if(!bInEditMOde && bRet)
421 {
422 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
423
424 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
425 {
426 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
427
428 if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
429 {
430 bRet = sal_False;
431 }
432 }
433 }
434 return bRet;
435 }
436
GetTextHorizontalAdjust() const437 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust() const
438 {
439 return GetTextHorizontalAdjust(GetObjectItemSet());
440 }
441
GetTextHorizontalAdjust(const SfxItemSet & rSet) const442 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust(const SfxItemSet& rSet) const
443 {
444 if(IsContourTextFrame())
445 return SDRTEXTHORZADJUST_BLOCK;
446
447 SdrTextHorzAdjust eRet = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
448
449 // #101684#
450 sal_Bool bInEditMode = IsInEditMode();
451
452 if(!bInEditMode && eRet == SDRTEXTHORZADJUST_BLOCK)
453 {
454 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
455
456 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
457 {
458 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
459
460 if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
461 {
462 eRet = SDRTEXTHORZADJUST_LEFT;
463 }
464 }
465 }
466
467 return eRet;
468 } // defaults: BLOCK fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
469
GetTextVerticalAdjust() const470 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust() const
471 {
472 return GetTextVerticalAdjust(GetObjectItemSet());
473 }
474
GetTextVerticalAdjust(const SfxItemSet & rSet) const475 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust(const SfxItemSet& rSet) const
476 {
477 if(IsContourTextFrame())
478 return SDRTEXTVERTADJUST_TOP;
479
480 // #103516# Take care for vertical text animation here
481 SdrTextVertAdjust eRet = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
482 sal_Bool bInEditMode = IsInEditMode();
483
484 // #103516# Take care for vertical text animation here
485 if(!bInEditMode && eRet == SDRTEXTVERTADJUST_BLOCK)
486 {
487 SdrTextAniKind eAniKind = ((SdrTextAniKindItem&)(rSet.Get(SDRATTR_TEXT_ANIKIND))).GetValue();
488
489 if(eAniKind == SDRTEXTANI_SCROLL || eAniKind == SDRTEXTANI_ALTERNATE || eAniKind == SDRTEXTANI_SLIDE)
490 {
491 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
492
493 if(eDirection == SDRTEXTANI_LEFT || eDirection == SDRTEXTANI_RIGHT)
494 {
495 eRet = SDRTEXTVERTADJUST_TOP;
496 }
497 }
498 }
499
500 return eRet;
501 } // defaults: TOP fuer Textrahmen, CENTER fuer beschriftete Grafikobjekte
502
ImpJustifyRect(Rectangle & rRect) const503 void SdrTextObj::ImpJustifyRect(Rectangle& rRect) const
504 {
505 if (!rRect.IsEmpty()) {
506 rRect.Justify();
507 if (rRect.Left()==rRect.Right()) rRect.Right()++;
508 if (rRect.Top()==rRect.Bottom()) rRect.Bottom()++;
509 }
510 }
511
ImpCheckShear()512 void SdrTextObj::ImpCheckShear()
513 {
514 if (bNoShear && aGeo.nShearWink!=0) {
515 aGeo.nShearWink=0;
516 aGeo.nTan=0;
517 }
518 }
519
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const520 void SdrTextObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
521 {
522 FASTBOOL bNoTextFrame=!IsTextFrame();
523 rInfo.bResizeFreeAllowed=bNoTextFrame || aGeo.nDrehWink%9000==0;
524 rInfo.bResizePropAllowed=sal_True;
525 rInfo.bRotateFreeAllowed=sal_True;
526 rInfo.bRotate90Allowed =sal_True;
527 rInfo.bMirrorFreeAllowed=bNoTextFrame;
528 rInfo.bMirror45Allowed =bNoTextFrame;
529 rInfo.bMirror90Allowed =bNoTextFrame;
530
531 // allow transparence
532 rInfo.bTransparenceAllowed = sal_True;
533
534 // gradient depends on fillstyle
535 XFillStyle eFillStyle = ((XFillStyleItem&)(GetObjectItem(XATTR_FILLSTYLE))).GetValue();
536 rInfo.bGradientAllowed = (eFillStyle == XFILL_GRADIENT);
537 rInfo.bShearAllowed =bNoTextFrame;
538 rInfo.bEdgeRadiusAllowed=sal_True;
539 FASTBOOL bCanConv=ImpCanConvTextToCurve();
540 rInfo.bCanConvToPath =bCanConv;
541 rInfo.bCanConvToPoly =bCanConv;
542 rInfo.bCanConvToPathLineToArea=bCanConv;
543 rInfo.bCanConvToPolyLineToArea=bCanConv;
544 rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
545 }
546
GetObjIdentifier() const547 sal_uInt16 SdrTextObj::GetObjIdentifier() const
548 {
549 return sal_uInt16(eTextKind);
550 }
551
HasTextImpl(SdrOutliner * pOutliner)552 bool SdrTextObj::HasTextImpl( SdrOutliner* pOutliner )
553 {
554 bool bRet=false;
555 if(pOutliner)
556 {
557 Paragraph* p1stPara=pOutliner->GetParagraph( 0 );
558 sal_uIntPtr nParaAnz=pOutliner->GetParagraphCount();
559 if(p1stPara==NULL)
560 nParaAnz=0;
561
562 if(nParaAnz==1)
563 {
564 // if it is only one paragraph, check if that paragraph is empty
565 XubString aStr(pOutliner->GetText(p1stPara));
566
567 if(!aStr.Len())
568 nParaAnz = 0;
569 }
570
571 bRet= nParaAnz!=0;
572 }
573 return bRet;
574 }
575
HasEditText() const576 FASTBOOL SdrTextObj::HasEditText() const
577 {
578 return HasTextImpl( pEdtOutl );
579 }
580
SetPage(SdrPage * pNewPage)581 void SdrTextObj::SetPage(SdrPage* pNewPage)
582 {
583 FASTBOOL bRemove=pNewPage==NULL && pPage!=NULL;
584 FASTBOOL bInsert=pNewPage!=NULL && pPage==NULL;
585 FASTBOOL bLinked=IsLinkedText();
586
587 if (bLinked && bRemove) {
588 ImpLinkAbmeldung();
589 }
590
591 SdrAttrObj::SetPage(pNewPage);
592
593 if (bLinked && bInsert) {
594 ImpLinkAnmeldung();
595 }
596 }
597
SetModel(SdrModel * pNewModel)598 void SdrTextObj::SetModel(SdrModel* pNewModel)
599 {
600 SdrModel* pOldModel=pModel;
601 bool bLinked=IsLinkedText();
602 bool bChg=pNewModel!=pModel;
603
604 if (bLinked && bChg)
605 {
606 ImpLinkAbmeldung();
607 }
608
609 SdrAttrObj::SetModel(pNewModel);
610
611 if( bChg )
612 {
613 if( pNewModel != 0 && pOldModel != 0 )
614 SetTextSizeDirty();
615
616 sal_Int32 nCount = getTextCount();
617 for( sal_Int32 nText = 0; nText < nCount; nText++ )
618 {
619 SdrText* pText = getText( nText );
620 if( pText )
621 pText->SetModel( pNewModel );
622 }
623 }
624
625 if (bLinked && bChg)
626 {
627 ImpLinkAnmeldung();
628 }
629 }
630
NbcSetEckenradius(long nRad)631 FASTBOOL SdrTextObj::NbcSetEckenradius(long nRad)
632 {
633 SetObjectItem(SdrEckenradiusItem(nRad));
634 return sal_True;
635 }
636
NbcSetAutoGrowHeight(bool bAuto)637 FASTBOOL SdrTextObj::NbcSetAutoGrowHeight(bool bAuto)
638 {
639 if(bTextFrame)
640 {
641 SetObjectItem(SdrTextAutoGrowHeightItem(bAuto));
642 return sal_True;
643 }
644 return sal_False;
645 }
646
647 // #115391# This implementation is based on the object size (aRect) and the
648 // states of IsAutoGrowWidth/Height to correctly set TextMinFrameWidth/Height
AdaptTextMinSize()649 void SdrTextObj::AdaptTextMinSize()
650 {
651 if(bTextFrame && (!pModel || !pModel->IsPasteResize()))
652 {
653 const bool bW(IsAutoGrowWidth());
654 const bool bH(IsAutoGrowHeight());
655
656 if(bW || bH)
657 {
658 SfxItemSet aSet(
659 *GetObjectItemSet().GetPool(),
660 SDRATTR_TEXT_MINFRAMEHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
661 SDRATTR_TEXT_MINFRAMEWIDTH, SDRATTR_TEXT_AUTOGROWWIDTH, // contains SDRATTR_TEXT_MAXFRAMEWIDTH
662 0, 0);
663
664 if(bW)
665 {
666 const long nDist(GetTextLeftDistance() + GetTextRightDistance());
667 const long nW(std::max(long(0), (long)(aRect.GetWidth() - 1 - nDist)));
668
669 aSet.Put(SdrTextMinFrameWidthItem(nW));
670
671 if(!IsVerticalWriting() && bDisableAutoWidthOnDragging)
672 {
673 bDisableAutoWidthOnDragging = true;
674 aSet.Put(SdrTextAutoGrowWidthItem(false));
675 }
676 }
677
678 if(bH)
679 {
680 const long nDist(GetTextUpperDistance() + GetTextLowerDistance());
681 const long nH(std::max(long(0), (long)(aRect.GetHeight() - 1 - nDist)));
682
683 aSet.Put(SdrTextMinFrameHeightItem(nH));
684
685 if(IsVerticalWriting() && bDisableAutoWidthOnDragging)
686 {
687 bDisableAutoWidthOnDragging = false;
688 aSet.Put(SdrTextAutoGrowHeightItem(false));
689 }
690 }
691
692 SetObjectItemSet(aSet);
693 NbcAdjustTextFrameWidthAndHeight();
694 }
695 }
696 }
697
NbcSetMaxTextFrameHeight(long nHgt)698 FASTBOOL SdrTextObj::NbcSetMaxTextFrameHeight(long nHgt)
699 {
700 if(bTextFrame)
701 {
702 SetObjectItem(SdrTextMaxFrameHeightItem(nHgt));
703 return sal_True;
704 }
705 return sal_False;
706 }
707
NbcSetAutoGrowWidth(bool bAuto)708 FASTBOOL SdrTextObj::NbcSetAutoGrowWidth(bool bAuto)
709 {
710 if(bTextFrame)
711 {
712 SetObjectItem(SdrTextAutoGrowWidthItem(bAuto));
713 return sal_True;
714 }
715 return sal_False;
716 }
717
NbcSetMaxTextFrameWidth(long nWdt)718 FASTBOOL SdrTextObj::NbcSetMaxTextFrameWidth(long nWdt)
719 {
720 if(bTextFrame)
721 {
722 SetObjectItem(SdrTextMaxFrameWidthItem(nWdt));
723 return sal_True;
724 }
725 return sal_False;
726 }
727
NbcSetFitToSize(SdrFitToSizeType eFit)728 FASTBOOL SdrTextObj::NbcSetFitToSize(SdrFitToSizeType eFit)
729 {
730 if(bTextFrame)
731 {
732 SetObjectItem(SdrTextFitToSizeTypeItem(eFit));
733 return sal_True;
734 }
735 return sal_False;
736 }
737
ImpSetContourPolygon(SdrOutliner & rOutliner,Rectangle & rAnchorRect,sal_Bool bLineWidth) const738 void SdrTextObj::ImpSetContourPolygon( SdrOutliner& rOutliner, Rectangle& rAnchorRect, sal_Bool bLineWidth ) const
739 {
740 basegfx::B2DPolyPolygon aXorPolyPolygon(TakeXorPoly());
741 basegfx::B2DPolyPolygon* pContourPolyPolygon = 0L;
742 basegfx::B2DHomMatrix aMatrix(basegfx::tools::createTranslateB2DHomMatrix(
743 -rAnchorRect.Left(), -rAnchorRect.Top()));
744
745 if(aGeo.nDrehWink)
746 {
747 // Unrotate!
748 aMatrix.rotate(-aGeo.nDrehWink * nPi180);
749 }
750
751 aXorPolyPolygon.transform(aMatrix);
752
753 if( bLineWidth )
754 {
755 // Strichstaerke beruecksichtigen
756 // Beim Hittest muss das unterbleiben (Performance!)
757 pContourPolyPolygon = new basegfx::B2DPolyPolygon();
758
759 // #86258# test if shadow needs to be avoided for TakeContour()
760 const SfxItemSet& rSet = GetObjectItemSet();
761 sal_Bool bShadowOn = ((SdrShadowItem&)(rSet.Get(SDRATTR_SHADOW))).GetValue();
762
763 // #i33696#
764 // Remember TextObject currently set at the DrawOutliner, it WILL be
765 // replaced during calculating the outline since it uses an own paint
766 // and that one uses the DrawOutliner, too.
767 const SdrTextObj* pLastTextObject = rOutliner.GetTextObj();
768
769 if(bShadowOn)
770 {
771 // #86258# force shadow off
772 SdrObject* pCopy = Clone();
773 pCopy->SetMergedItem(SdrShadowItem(sal_False));
774 *pContourPolyPolygon = pCopy->TakeContour();
775 SdrObject::Free( pCopy );
776 }
777 else
778 {
779 *pContourPolyPolygon = TakeContour();
780 }
781
782 // #i33696#
783 // restore remembered text object
784 if(pLastTextObject != rOutliner.GetTextObj())
785 {
786 rOutliner.SetTextObj(pLastTextObject);
787 }
788
789 pContourPolyPolygon->transform(aMatrix);
790 }
791
792 rOutliner.SetPolygon(aXorPolyPolygon, pContourPolyPolygon);
793 }
794
TakeUnrotatedSnapRect(Rectangle & rRect) const795 void SdrTextObj::TakeUnrotatedSnapRect(Rectangle& rRect) const
796 {
797 rRect=aRect;
798 }
799
TakeTextAnchorRect(Rectangle & rAnchorRect) const800 void SdrTextObj::TakeTextAnchorRect(Rectangle& rAnchorRect) const
801 {
802 long nLeftDist=GetTextLeftDistance();
803 long nRightDist=GetTextRightDistance();
804 long nUpperDist=GetTextUpperDistance();
805 long nLowerDist=GetTextLowerDistance();
806 Rectangle aAnkRect(aRect); // Rect innerhalb dem geankert wird
807 FASTBOOL bFrame=IsTextFrame();
808 if (!bFrame) {
809 TakeUnrotatedSnapRect(aAnkRect);
810 }
811 Point aRotateRef(aAnkRect.TopLeft());
812 aAnkRect.Left()+=nLeftDist;
813 aAnkRect.Top()+=nUpperDist;
814 aAnkRect.Right()-=nRightDist;
815 aAnkRect.Bottom()-=nLowerDist;
816
817 // #108816#
818 // Since sizes may be bigger than the object bounds it is necessary to
819 // justify the rect now.
820 ImpJustifyRect(aAnkRect);
821
822 if (bFrame) {
823 // !!! hier noch etwas verfeinern !!!
824 if (aAnkRect.GetWidth()<2) aAnkRect.Right()=aAnkRect.Left()+1; // Mindestgroesse 2
825 if (aAnkRect.GetHeight()<2) aAnkRect.Bottom()=aAnkRect.Top()+1; // Mindestgroesse 2
826 }
827 if (aGeo.nDrehWink!=0) {
828 Point aTmpPt(aAnkRect.TopLeft());
829 RotatePoint(aTmpPt,aRotateRef,aGeo.nSin,aGeo.nCos);
830 aTmpPt-=aAnkRect.TopLeft();
831 aAnkRect.Move(aTmpPt.X(),aTmpPt.Y());
832 }
833 rAnchorRect=aAnkRect;
834 }
835
TakeTextRect(SdrOutliner & rOutliner,Rectangle & rTextRect,FASTBOOL bNoEditText,Rectangle * pAnchorRect,sal_Bool bLineWidth) const836 void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, Rectangle& rTextRect, FASTBOOL bNoEditText,
837 Rectangle* pAnchorRect, sal_Bool bLineWidth ) const
838 {
839 Rectangle aAnkRect; // Rect innerhalb dem geankert wird
840 TakeTextAnchorRect(aAnkRect);
841 SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
842 SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
843 SdrTextAniKind eAniKind=GetTextAniKind();
844 SdrTextAniDirection eAniDirection=GetTextAniDirection();
845
846 SdrFitToSizeType eFit=GetFitToSize();
847 FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
848 FASTBOOL bContourFrame=IsContourTextFrame();
849
850 FASTBOOL bFrame=IsTextFrame();
851 sal_uIntPtr nStat0=rOutliner.GetControlWord();
852 Size aNullSize;
853 if (!bContourFrame)
854 {
855 rOutliner.SetControlWord(nStat0|EE_CNTRL_AUTOPAGESIZE);
856 rOutliner.SetMinAutoPaperSize(aNullSize);
857 rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
858 }
859
860 if (!bFitToSize && !bContourFrame)
861 {
862 long nAnkWdt=aAnkRect.GetWidth();
863 long nAnkHgt=aAnkRect.GetHeight();
864 if (bFrame)
865 {
866 long nWdt=nAnkWdt;
867 long nHgt=nAnkHgt;
868
869 // #101684#
870 sal_Bool bInEditMode = IsInEditMode();
871
872 if (!bInEditMode && (eAniKind==SDRTEXTANI_SCROLL || eAniKind==SDRTEXTANI_ALTERNATE || eAniKind==SDRTEXTANI_SLIDE))
873 {
874 // Grenzenlose Papiergroesse fuer Laufschrift
875 if (eAniDirection==SDRTEXTANI_LEFT || eAniDirection==SDRTEXTANI_RIGHT) nWdt=1000000;
876 if (eAniDirection==SDRTEXTANI_UP || eAniDirection==SDRTEXTANI_DOWN) nHgt=1000000;
877 }
878
879 // #119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
880 if(IsVerticalWriting())
881 {
882 nWdt = 1000000;
883 }
884 else
885 {
886 nHgt = 1000000;
887 }
888
889 rOutliner.SetMaxAutoPaperSize(Size(nWdt,nHgt));
890 }
891
892 // #103516# New try with _BLOCK for hor and ver after completely
893 // supporting full width for vertical text.
894 if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
895 {
896 rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
897 }
898
899 if(SDRTEXTVERTADJUST_BLOCK == eVAdj && IsVerticalWriting())
900 {
901 rOutliner.SetMinAutoPaperSize(Size(0, nAnkHgt));
902 }
903 }
904
905 rOutliner.SetPaperSize(aNullSize);
906 if (bContourFrame)
907 ImpSetContourPolygon( rOutliner, aAnkRect, bLineWidth );
908
909 // put text into the outliner, if available from the edit outliner
910 SdrText* pText = getActiveText();
911 OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : 0;
912 OutlinerParaObject* pPara = (pEdtOutl && !bNoEditText) ? pEdtOutl->CreateParaObject() : pOutlinerParaObject;
913
914 if (pPara)
915 {
916 sal_Bool bHitTest = sal_False;
917 if( pModel )
918 bHitTest = &pModel->GetHitTestOutliner() == &rOutliner;
919
920 const SdrTextObj* pTestObj = rOutliner.GetTextObj();
921 if( !pTestObj || !bHitTest || pTestObj != this ||
922 pTestObj->GetOutlinerParaObject() != pOutlinerParaObject )
923 {
924 if( bHitTest ) // #i33696# take back fix #i27510#
925 {
926 rOutliner.SetTextObj( this );
927 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
928 }
929
930 rOutliner.SetUpdateMode(sal_True);
931 rOutliner.SetText(*pPara);
932 }
933 }
934 else
935 {
936 rOutliner.SetTextObj( NULL );
937 }
938
939 if (pEdtOutl && !bNoEditText && pPara)
940 delete pPara;
941
942 rOutliner.SetUpdateMode(sal_True);
943 rOutliner.SetControlWord(nStat0);
944
945 if( pText )
946 pText->CheckPortionInfo(rOutliner);
947
948 Point aTextPos(aAnkRect.TopLeft());
949 Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() hat etwas Toleranz drauf, oder?
950
951 // #106653#
952 // For draw objects containing text correct hor/ver alignment if text is bigger
953 // than the object itself. Without that correction, the text would always be
954 // formatted to the left edge (or top edge when vertical) of the draw object.
955 if(!IsTextFrame())
956 {
957 if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
958 {
959 // #110129#
960 // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
961 // else the alignment is wanted.
962 if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
963 {
964 eHAdj = SDRTEXTHORZADJUST_CENTER;
965 }
966 }
967
968 if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
969 {
970 // #110129#
971 // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
972 // else the alignment is wanted.
973 if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
974 {
975 eVAdj = SDRTEXTVERTADJUST_CENTER;
976 }
977 }
978 }
979
980 if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
981 {
982 long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width();
983 if (eHAdj==SDRTEXTHORZADJUST_CENTER)
984 aTextPos.X()+=nFreeWdt/2;
985 if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
986 aTextPos.X()+=nFreeWdt;
987 }
988 if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
989 {
990 long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height();
991 if (eVAdj==SDRTEXTVERTADJUST_CENTER)
992 aTextPos.Y()+=nFreeHgt/2;
993 if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
994 aTextPos.Y()+=nFreeHgt;
995 }
996 if (aGeo.nDrehWink!=0)
997 RotatePoint(aTextPos,aAnkRect.TopLeft(),aGeo.nSin,aGeo.nCos);
998
999 if (pAnchorRect)
1000 *pAnchorRect=aAnkRect;
1001
1002 // rTextRect ist bei ContourFrame in einigen Faellen nicht korrekt
1003 rTextRect=Rectangle(aTextPos,aTextSiz);
1004 if (bContourFrame)
1005 rTextRect=aAnkRect;
1006 }
1007
GetEditOutlinerParaObject() const1008 OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const
1009 {
1010 OutlinerParaObject* pPara=NULL;
1011 if( HasTextImpl( pEdtOutl ) )
1012 {
1013 sal_uInt32 nParaAnz = pEdtOutl->GetParagraphCount();
1014 pPara = pEdtOutl->CreateParaObject(0, nParaAnz);
1015 }
1016 return pPara;
1017 }
1018
ImpSetCharStretching(SdrOutliner & rOutliner,const Rectangle & rTextRect,const Rectangle & rAnchorRect,Fraction & rFitXKorreg) const1019 void SdrTextObj::ImpSetCharStretching(SdrOutliner& rOutliner, const Rectangle& rTextRect, const Rectangle& rAnchorRect, Fraction& rFitXKorreg) const
1020 {
1021 OutputDevice* pOut = rOutliner.GetRefDevice();
1022 sal_Bool bNoStretching(sal_False);
1023
1024 if(pOut && pOut->GetOutDevType() == OUTDEV_PRINTER)
1025 {
1026 // #35762#: Checken ob CharStretching ueberhaupt moeglich
1027 GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
1028 UniString aTestString(sal_Unicode('J'));
1029
1030 if(pMtf && (!pMtf->IsRecord() || pMtf->IsPause()))
1031 pMtf = NULL;
1032
1033 if(pMtf)
1034 pMtf->Pause(sal_True);
1035
1036 Font aFontMerk(pOut->GetFont());
1037 Font aTmpFont( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ) );
1038
1039 aTmpFont.SetSize(Size(0,100));
1040 pOut->SetFont(aTmpFont);
1041 Size aSize1(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1042 aTmpFont.SetSize(Size(800,100));
1043 pOut->SetFont(aTmpFont);
1044 Size aSize2(pOut->GetTextWidth(aTestString), pOut->GetTextHeight());
1045 pOut->SetFont(aFontMerk);
1046
1047 if(pMtf)
1048 pMtf->Pause(sal_False);
1049
1050 bNoStretching = (aSize1 == aSize2);
1051
1052 #ifdef WNT
1053 // #35762# Windows vergroessert bei Size(100,500) den Font proportional
1054 // Und das finden wir nicht so schoen.
1055 if(aSize2.Height() >= aSize1.Height() * 2)
1056 {
1057 bNoStretching = sal_True;
1058 }
1059 #endif
1060 }
1061 unsigned nLoopCount=0;
1062 FASTBOOL bNoMoreLoop=sal_False;
1063 long nXDiff0=0x7FFFFFFF;
1064 long nWantWdt=rAnchorRect.Right()-rAnchorRect.Left();
1065 long nIsWdt=rTextRect.Right()-rTextRect.Left();
1066 if (nIsWdt==0) nIsWdt=1;
1067
1068 long nWantHgt=rAnchorRect.Bottom()-rAnchorRect.Top();
1069 long nIsHgt=rTextRect.Bottom()-rTextRect.Top();
1070 if (nIsHgt==0) nIsHgt=1;
1071
1072 long nXTolPl=nWantWdt/100; // Toleranz +1%
1073 long nXTolMi=nWantWdt/25; // Toleranz -4%
1074 long nXKorr =nWantWdt/20; // Korrekturmasstab 5%
1075
1076 long nX=(nWantWdt*100) /nIsWdt; // X-Stretching berechnen
1077 long nY=(nWantHgt*100) /nIsHgt; // Y-Stretching berechnen
1078 FASTBOOL bChkX=sal_True;
1079 FASTBOOL bChkY=sal_True;
1080 if (bNoStretching) { // #35762# evtl. nur proportional moeglich
1081 if (nX>nY) { nX=nY; bChkX=sal_False; }
1082 else { nY=nX; bChkY=sal_False; }
1083 }
1084
1085 while (nLoopCount<5 && !bNoMoreLoop) {
1086 if (nX<0) nX=-nX;
1087 if (nX<1) { nX=1; bNoMoreLoop=sal_True; }
1088 if (nX>65535) { nX=65535; bNoMoreLoop=sal_True; }
1089
1090 if (nY<0) nY=-nY;
1091 if (nY<1) { nY=1; bNoMoreLoop=sal_True; }
1092 if (nY>65535) { nY=65535; bNoMoreLoop=sal_True; }
1093
1094 // exception, there is no text yet (horizontal case)
1095 if(nIsWdt <= 1)
1096 {
1097 nX = nY;
1098 bNoMoreLoop = sal_True;
1099 }
1100
1101 // #87877# exception, there is no text yet (vertical case)
1102 if(nIsHgt <= 1)
1103 {
1104 nY = nX;
1105 bNoMoreLoop = sal_True;
1106 }
1107
1108 rOutliner.SetGlobalCharStretching((sal_uInt16)nX,(sal_uInt16)nY);
1109 nLoopCount++;
1110 Size aSiz(rOutliner.CalcTextSize());
1111 long nXDiff=aSiz.Width()-nWantWdt;
1112 rFitXKorreg=Fraction(nWantWdt,aSiz.Width());
1113 if (((nXDiff>=nXTolMi || !bChkX) && nXDiff<=nXTolPl) || nXDiff==nXDiff0/*&& Abs(nYDiff)<=nYTol*/) {
1114 bNoMoreLoop=sal_True;
1115 } else {
1116 // Stretchingfaktoren korregieren
1117 long nMul=nWantWdt;
1118 long nDiv=aSiz.Width();
1119 if (Abs(nXDiff)<=2*nXKorr) {
1120 if (nMul>nDiv) nDiv+=(nMul-nDiv)/2; // und zwar nur um die haelfte des berechneten
1121 else nMul+=(nDiv-nMul)/2; // weil die EE ja eh wieder falsch rechnet
1122 }
1123 nX=nX*nMul/nDiv;
1124 if (bNoStretching) nY=nX;
1125 }
1126 nXDiff0=nXDiff;
1127 }
1128 }
1129
StartTextAnimation(OutputDevice *,const Point &,long)1130 void SdrTextObj::StartTextAnimation(OutputDevice* /*pOutDev*/, const Point& /*rOffset*/, long /*nExtraData*/)
1131 {
1132 // #111096#
1133 // use new text animation
1134 SetTextAnimationAllowed(sal_True);
1135 }
1136
StopTextAnimation(OutputDevice *,long)1137 void SdrTextObj::StopTextAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1138 {
1139 // #111096#
1140 // use new text animation
1141 SetTextAnimationAllowed(sal_False);
1142 }
1143
TakeObjNameSingul(XubString & rName) const1144 void SdrTextObj::TakeObjNameSingul(XubString& rName) const
1145 {
1146 XubString aStr;
1147
1148 switch(eTextKind)
1149 {
1150 case OBJ_OUTLINETEXT:
1151 {
1152 aStr = ImpGetResStr(STR_ObjNameSingulOUTLINETEXT);
1153 break;
1154 }
1155
1156 case OBJ_TITLETEXT :
1157 {
1158 aStr = ImpGetResStr(STR_ObjNameSingulTITLETEXT);
1159 break;
1160 }
1161
1162 default:
1163 {
1164 if(IsLinkedText())
1165 aStr = ImpGetResStr(STR_ObjNameSingulTEXTLNK);
1166 else
1167 aStr = ImpGetResStr(STR_ObjNameSingulTEXT);
1168 break;
1169 }
1170 }
1171
1172 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1173 if(pOutlinerParaObject && eTextKind != OBJ_OUTLINETEXT)
1174 {
1175 // Macht bei OUTLINETEXT wohl derzeit noch etwas Probleme
1176 XubString aStr2(pOutlinerParaObject->GetTextObject().GetText(0));
1177 aStr2.EraseLeadingChars();
1178
1179 // #69446# avoid non expanded text portions in object name
1180 // (second condition is new)
1181 if(aStr2.Len() && aStr2.Search(sal_Unicode(255)) == STRING_NOTFOUND)
1182 {
1183 // #76681# space between ResStr and content text
1184 aStr += sal_Unicode(' ');
1185
1186 aStr += sal_Unicode('\'');
1187
1188 if(aStr2.Len() > 10)
1189 {
1190 aStr2.Erase(8);
1191 aStr2.AppendAscii("...", 3);
1192 }
1193
1194 aStr += aStr2;
1195 aStr += sal_Unicode('\'');
1196 }
1197 }
1198
1199 rName = aStr;
1200
1201 String aName( GetName() );
1202 if(aName.Len())
1203 {
1204 rName += sal_Unicode(' ');
1205 rName += sal_Unicode('\'');
1206 rName += aName;
1207 rName += sal_Unicode('\'');
1208 }
1209
1210 }
1211
TakeObjNamePlural(XubString & rName) const1212 void SdrTextObj::TakeObjNamePlural(XubString& rName) const
1213 {
1214 switch (eTextKind) {
1215 case OBJ_OUTLINETEXT: rName=ImpGetResStr(STR_ObjNamePluralOUTLINETEXT); break;
1216 case OBJ_TITLETEXT : rName=ImpGetResStr(STR_ObjNamePluralTITLETEXT); break;
1217 default: {
1218 if (IsLinkedText()) {
1219 rName=ImpGetResStr(STR_ObjNamePluralTEXTLNK);
1220 } else {
1221 rName=ImpGetResStr(STR_ObjNamePluralTEXT);
1222 }
1223 } break;
1224 } // switch
1225 }
1226
operator =(const SdrObject & rObj)1227 void SdrTextObj::operator=(const SdrObject& rObj)
1228 {
1229 // call parent
1230 SdrObject::operator=(rObj);
1231
1232 const SdrTextObj* pTextObj = dynamic_cast< const SdrTextObj* >( &rObj );
1233 if (pTextObj!=NULL)
1234 {
1235 aRect =pTextObj->aRect;
1236 aGeo =pTextObj->aGeo;
1237 eTextKind =pTextObj->eTextKind;
1238 bTextFrame=pTextObj->bTextFrame;
1239 aTextSize=pTextObj->aTextSize;
1240 bTextSizeDirty=pTextObj->bTextSizeDirty;
1241
1242 // #101776# Not all of the necessary parameters were copied yet.
1243 bNoShear = pTextObj->bNoShear;
1244 bNoRotate = pTextObj->bNoRotate;
1245 bNoMirror = pTextObj->bNoMirror;
1246 bDisableAutoWidthOnDragging = pTextObj->bDisableAutoWidthOnDragging;
1247
1248 OutlinerParaObject* pNewOutlinerParaObject = 0;
1249
1250 SdrText* pText = getActiveText();
1251
1252 if( pText && pTextObj->HasText() )
1253 {
1254 const Outliner* pEO=pTextObj->pEdtOutl;
1255 if (pEO!=NULL)
1256 {
1257 pNewOutlinerParaObject = pEO->CreateParaObject();
1258 }
1259 else
1260 {
1261 pNewOutlinerParaObject = new OutlinerParaObject(*pTextObj->getActiveText()->GetOutlinerParaObject());
1262 }
1263 }
1264
1265 mpText->SetOutlinerParaObject( pNewOutlinerParaObject );
1266 ImpSetTextStyleSheetListeners();
1267 }
1268 }
1269
TakeXorPoly() const1270 basegfx::B2DPolyPolygon SdrTextObj::TakeXorPoly() const
1271 {
1272 Polygon aPol(aRect);
1273 if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1274 if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1275
1276 basegfx::B2DPolyPolygon aRetval;
1277 aRetval.append(aPol.getB2DPolygon());
1278 return aRetval;
1279 }
1280
TakeContour() const1281 basegfx::B2DPolyPolygon SdrTextObj::TakeContour() const
1282 {
1283 basegfx::B2DPolyPolygon aRetval(SdrAttrObj::TakeContour());
1284
1285 // und nun noch ggf. das BoundRect des Textes dazu
1286 if ( pModel && GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
1287 {
1288 // #80328# using Clone()-Paint() strategy inside TakeContour() leaves a destroyed
1289 // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner
1290 // in every case
1291 SdrOutliner& rOutliner=ImpGetDrawOutliner();
1292
1293 Rectangle aAnchor2;
1294 Rectangle aR;
1295 TakeTextRect(rOutliner,aR,sal_False,&aAnchor2);
1296 rOutliner.Clear();
1297 SdrFitToSizeType eFit=GetFitToSize();
1298 FASTBOOL bFitToSize=(eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES);
1299 if (bFitToSize) aR=aAnchor2;
1300 Polygon aPol(aR);
1301 if (aGeo.nDrehWink!=0) RotatePoly(aPol,aR.TopLeft(),aGeo.nSin,aGeo.nCos);
1302
1303 aRetval.append(aPol.getB2DPolygon());
1304 }
1305
1306 return aRetval;
1307 }
1308
RecalcSnapRect()1309 void SdrTextObj::RecalcSnapRect()
1310 {
1311 if (aGeo.nDrehWink!=0 || aGeo.nShearWink!=0) {
1312 Polygon aPol(aRect);
1313 if (aGeo.nShearWink!=0) ShearPoly(aPol,aRect.TopLeft(),aGeo.nTan);
1314 if (aGeo.nDrehWink!=0) RotatePoly(aPol,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1315 maSnapRect=aPol.GetBoundRect();
1316 } else {
1317 maSnapRect=aRect;
1318 }
1319 }
1320
GetSnapPointCount() const1321 sal_uInt32 SdrTextObj::GetSnapPointCount() const
1322 {
1323 return 4L;
1324 }
1325
GetSnapPoint(sal_uInt32 i) const1326 Point SdrTextObj::GetSnapPoint(sal_uInt32 i) const
1327 {
1328 Point aP;
1329 switch (i) {
1330 case 0: aP=aRect.TopLeft(); break;
1331 case 1: aP=aRect.TopRight(); break;
1332 case 2: aP=aRect.BottomLeft(); break;
1333 case 3: aP=aRect.BottomRight(); break;
1334 default: aP=aRect.Center(); break;
1335 }
1336 if (aGeo.nShearWink!=0) ShearPoint(aP,aRect.TopLeft(),aGeo.nTan);
1337 if (aGeo.nDrehWink!=0) RotatePoint(aP,aRect.TopLeft(),aGeo.nSin,aGeo.nCos);
1338 return aP;
1339 }
1340
ImpCheckMasterCachable()1341 void SdrTextObj::ImpCheckMasterCachable()
1342 {
1343 bNotMasterCachable=sal_False;
1344
1345 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1346
1347 if(!bNotVisibleAsMaster && pOutlinerParaObject && pOutlinerParaObject->IsEditDoc() )
1348 {
1349 const EditTextObject& rText= pOutlinerParaObject->GetTextObject();
1350 bNotMasterCachable=rText.HasField(SvxPageField::StaticType());
1351 if( !bNotMasterCachable )
1352 {
1353 bNotMasterCachable=rText.HasField(SvxHeaderField::StaticType());
1354 if( !bNotMasterCachable )
1355 {
1356 bNotMasterCachable=rText.HasField(SvxFooterField::StaticType());
1357 if( !bNotMasterCachable )
1358 {
1359 bNotMasterCachable=rText.HasField(SvxDateTimeField::StaticType());
1360 }
1361 }
1362 }
1363 }
1364 }
1365
1366 // #101029#: Extracted from ImpGetDrawOutliner()
ImpInitDrawOutliner(SdrOutliner & rOutl) const1367 void SdrTextObj::ImpInitDrawOutliner( SdrOutliner& rOutl ) const
1368 {
1369 rOutl.SetUpdateMode(sal_False);
1370 sal_uInt16 nOutlinerMode = OUTLINERMODE_OUTLINEOBJECT;
1371 if ( !IsOutlText() )
1372 nOutlinerMode = OUTLINERMODE_TEXTOBJECT;
1373 rOutl.Init( nOutlinerMode );
1374
1375 rOutl.SetGlobalCharStretching(100,100);
1376 sal_uIntPtr nStat=rOutl.GetControlWord();
1377 nStat&=~(EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
1378 rOutl.SetControlWord(nStat);
1379 Size aNullSize;
1380 Size aMaxSize(100000,100000);
1381 rOutl.SetMinAutoPaperSize(aNullSize);
1382 rOutl.SetMaxAutoPaperSize(aMaxSize);
1383 rOutl.SetPaperSize(aMaxSize);
1384 rOutl.ClearPolygon();
1385 }
1386
ImpGetDrawOutliner() const1387 SdrOutliner& SdrTextObj::ImpGetDrawOutliner() const
1388 {
1389 SdrOutliner& rOutl=pModel->GetDrawOutliner(this);
1390
1391 // #101029#: Code extracted to ImpInitDrawOutliner()
1392 ImpInitDrawOutliner( rOutl );
1393
1394 return rOutl;
1395 }
1396
CreateDrawOutliner()1397 boost::shared_ptr< SdrOutliner > SdrTextObj::CreateDrawOutliner()
1398 {
1399 boost::shared_ptr< SdrOutliner > xDrawOutliner( pModel->CreateDrawOutliner(this) );
1400 ImpInitDrawOutliner( *(xDrawOutliner.get()) );
1401 return xDrawOutliner;
1402 }
1403
1404 // #101029#: Extracted from Paint()
ImpSetupDrawOutlinerForPaint(FASTBOOL bContourFrame,SdrOutliner & rOutliner,Rectangle & rTextRect,Rectangle & rAnchorRect,Rectangle & rPaintRect,Fraction & rFitXKorreg) const1405 void SdrTextObj::ImpSetupDrawOutlinerForPaint( FASTBOOL bContourFrame,
1406 SdrOutliner& rOutliner,
1407 Rectangle& rTextRect,
1408 Rectangle& rAnchorRect,
1409 Rectangle& rPaintRect,
1410 Fraction& rFitXKorreg ) const
1411 {
1412 if (!bContourFrame)
1413 {
1414 // FitToSize erstmal nicht mit ContourFrame
1415 SdrFitToSizeType eFit=GetFitToSize();
1416 if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
1417 {
1418 sal_uIntPtr nStat=rOutliner.GetControlWord();
1419 nStat|=EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE;
1420 rOutliner.SetControlWord(nStat);
1421 }
1422 }
1423 rOutliner.SetFixedCellHeight(((const SdrTextFixedCellHeightItem&)GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT)).GetValue());
1424 TakeTextRect(rOutliner, rTextRect, sal_False, &rAnchorRect);
1425 rPaintRect = rTextRect;
1426
1427 if (!bContourFrame)
1428 {
1429 // FitToSize erstmal nicht mit ContourFrame
1430 SdrFitToSizeType eFit=GetFitToSize();
1431 if (eFit==SDRTEXTFIT_PROPORTIONAL || eFit==SDRTEXTFIT_ALLLINES)
1432 {
1433 ImpSetCharStretching(rOutliner,rTextRect,rAnchorRect,rFitXKorreg);
1434 rPaintRect=rAnchorRect;
1435 }
1436 }
1437 }
1438
SetupOutlinerFormatting(SdrOutliner & rOutl,Rectangle & rPaintRect) const1439 void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1440 {
1441 ImpInitDrawOutliner( rOutl );
1442 UpdateOutlinerFormatting( rOutl, rPaintRect );
1443 }
1444
UpdateOutlinerFormatting(SdrOutliner & rOutl,Rectangle & rPaintRect) const1445 void SdrTextObj::UpdateOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const
1446 {
1447 Rectangle aTextRect;
1448 Rectangle aAnchorRect;
1449 Fraction aFitXKorreg(1,1);
1450
1451 FASTBOOL bContourFrame=IsContourTextFrame();
1452
1453 if( GetModel() )
1454 {
1455 MapMode aMapMode(GetModel()->GetScaleUnit(), Point(0,0),
1456 GetModel()->GetScaleFraction(),
1457 GetModel()->GetScaleFraction());
1458 rOutl.SetRefMapMode(aMapMode);
1459 }
1460
1461 ImpSetupDrawOutlinerForPaint( bContourFrame, rOutl, aTextRect, aAnchorRect, rPaintRect, aFitXKorreg );
1462 }
1463
1464 ////////////////////////////////////////////////////////////////////////////////////////////////////
1465
GetOutlinerParaObject() const1466 OutlinerParaObject* SdrTextObj::GetOutlinerParaObject() const
1467 {
1468 SdrText* pText = getActiveText();
1469 if( pText )
1470 return pText->GetOutlinerParaObject();
1471 else
1472 return 0;
1473 }
1474
HasOutlinerParaObject() const1475 bool SdrTextObj::HasOutlinerParaObject() const
1476 {
1477 SdrText* pText = getActiveText();
1478 if( pText && pText->GetOutlinerParaObject() )
1479 return true;
1480 return false;
1481 }
1482
NbcSetOutlinerParaObject(OutlinerParaObject * pTextObject)1483 void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject)
1484 {
1485 NbcSetOutlinerParaObjectForText( pTextObject, getActiveText() );
1486 }
1487
NbcSetOutlinerParaObjectForText(OutlinerParaObject * pTextObject,SdrText * pText)1488 void SdrTextObj::NbcSetOutlinerParaObjectForText( OutlinerParaObject* pTextObject, SdrText* pText )
1489 {
1490 if( pText )
1491 pText->SetOutlinerParaObject( pTextObject );
1492
1493 if( pText->GetOutlinerParaObject() )
1494 {
1495 SvxWritingModeItem aWritingMode(pText->GetOutlinerParaObject()->IsVertical()
1496 ? com::sun::star::text::WritingMode_TB_RL
1497 : com::sun::star::text::WritingMode_LR_TB,
1498 SDRATTR_TEXTDIRECTION);
1499 GetProperties().SetObjectItemDirect(aWritingMode);
1500 }
1501
1502 SetTextSizeDirty();
1503 if (IsTextFrame() && (IsAutoGrowHeight() || IsAutoGrowWidth()))
1504 { // Textrahmen anpassen!
1505 NbcAdjustTextFrameWidthAndHeight();
1506 }
1507 if (!IsTextFrame())
1508 {
1509 // Das SnapRect behaelt seine Groesse bei
1510 SetRectsDirty(sal_True);
1511 }
1512
1513 // always invalidate BoundRect on change
1514 SetBoundRectDirty();
1515 ActionChanged();
1516
1517 ImpSetTextStyleSheetListeners();
1518 ImpCheckMasterCachable();
1519 }
1520
NbcReformatText()1521 void SdrTextObj::NbcReformatText()
1522 {
1523 SdrText* pText = getActiveText();
1524 if( pText && pText->GetOutlinerParaObject() )
1525 {
1526 pText->ReformatText();
1527 if (bTextFrame)
1528 {
1529 NbcAdjustTextFrameWidthAndHeight();
1530 }
1531 else
1532 {
1533 // Das SnapRect behaelt seine Groesse bei
1534 SetBoundRectDirty();
1535 SetRectsDirty(sal_True);
1536 }
1537 SetTextSizeDirty();
1538 ActionChanged();
1539 // FME, AW: i22396
1540 // Necessary here since we have no compare operator at the outliner
1541 // para object which may detect changes regarding the combination
1542 // of outliner para data and configuration (e.g., change of
1543 // formatting of text numerals)
1544 GetViewContact().flushViewObjectContacts(false);
1545 }
1546 }
1547
ReformatText()1548 void SdrTextObj::ReformatText()
1549 {
1550 if(GetOutlinerParaObject())
1551 {
1552 Rectangle aBoundRect0;
1553 if (pUserCall!=NULL)
1554 aBoundRect0=GetLastBoundRect();
1555
1556 // #110094#-14 SendRepaintBroadcast();
1557 NbcReformatText();
1558 SetChanged();
1559 BroadcastObjectChange();
1560 SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
1561 }
1562 }
1563
NewGeoData() const1564 SdrObjGeoData* SdrTextObj::NewGeoData() const
1565 {
1566 return new SdrTextObjGeoData;
1567 }
1568
SaveGeoData(SdrObjGeoData & rGeo) const1569 void SdrTextObj::SaveGeoData(SdrObjGeoData& rGeo) const
1570 {
1571 SdrAttrObj::SaveGeoData(rGeo);
1572 SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1573 rTGeo.aRect =aRect;
1574 rTGeo.aGeo =aGeo;
1575 }
1576
RestGeoData(const SdrObjGeoData & rGeo)1577 void SdrTextObj::RestGeoData(const SdrObjGeoData& rGeo)
1578 { // RectsDirty wird von SdrObject gerufen
1579 SdrAttrObj::RestGeoData(rGeo);
1580 SdrTextObjGeoData& rTGeo=(SdrTextObjGeoData&)rGeo;
1581 aRect =rTGeo.aRect;
1582 aGeo =rTGeo.aGeo;
1583 SetTextSizeDirty();
1584 }
1585
GetFitToSize() const1586 SdrFitToSizeType SdrTextObj::GetFitToSize() const
1587 {
1588 SdrFitToSizeType eType = SDRTEXTFIT_NONE;
1589
1590 if(!IsAutoGrowWidth())
1591 eType = ((SdrTextFitToSizeTypeItem&)(GetObjectItem(SDRATTR_TEXT_FITTOSIZE))).GetValue();
1592
1593 return eType;
1594 }
1595
ForceOutlinerParaObject()1596 void SdrTextObj::ForceOutlinerParaObject()
1597 {
1598 SdrText* pText = getActiveText();
1599 if( pText && (pText->GetOutlinerParaObject() == 0) )
1600 {
1601 sal_uInt16 nOutlMode = OUTLINERMODE_TEXTOBJECT;
1602 if( IsTextFrame() && eTextKind == OBJ_OUTLINETEXT )
1603 nOutlMode = OUTLINERMODE_OUTLINEOBJECT;
1604
1605 pText->ForceOutlinerParaObject( nOutlMode );
1606 }
1607 }
1608
IsVerticalWriting() const1609 sal_Bool SdrTextObj::IsVerticalWriting() const
1610 {
1611 // #89459#
1612 if(pEdtOutl)
1613 {
1614 return pEdtOutl->IsVertical();
1615 }
1616
1617 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1618 if(pOutlinerParaObject)
1619 {
1620 return pOutlinerParaObject->IsVertical();
1621 }
1622
1623 return sal_False;
1624 }
1625
SetVerticalWriting(sal_Bool bVertical)1626 void SdrTextObj::SetVerticalWriting(sal_Bool bVertical)
1627 {
1628 OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject();
1629 if( !pOutlinerParaObject && bVertical )
1630 {
1631 // we only need to force a outliner para object if the default of
1632 // horizontal text is changed
1633 ForceOutlinerParaObject();
1634 pOutlinerParaObject = GetOutlinerParaObject();
1635 }
1636
1637 if( pOutlinerParaObject && (pOutlinerParaObject->IsVertical() != (bool)bVertical) )
1638 {
1639 // get item settings
1640 const SfxItemSet& rSet = GetObjectItemSet();
1641 sal_Bool bAutoGrowWidth = ((SdrTextAutoGrowWidthItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWWIDTH)).GetValue();
1642 sal_Bool bAutoGrowHeight = ((SdrTextAutoGrowHeightItem&)rSet.Get(SDRATTR_TEXT_AUTOGROWHEIGHT)).GetValue();
1643
1644 // #103516# Also exchange hor/ver adjust items
1645 SdrTextHorzAdjust eHorz = ((SdrTextHorzAdjustItem&)(rSet.Get(SDRATTR_TEXT_HORZADJUST))).GetValue();
1646 SdrTextVertAdjust eVert = ((SdrTextVertAdjustItem&)(rSet.Get(SDRATTR_TEXT_VERTADJUST))).GetValue();
1647
1648 // rescue object size
1649 Rectangle aObjectRect = GetSnapRect();
1650
1651 // prepare ItemSet to set exchanged width and height items
1652 SfxItemSet aNewSet(*rSet.GetPool(),
1653 SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT,
1654 // #103516# Expanded item ranges to also support hor and ver adjust.
1655 SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
1656 SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST,
1657 0, 0);
1658
1659 aNewSet.Put(rSet);
1660 aNewSet.Put(SdrTextAutoGrowWidthItem(bAutoGrowHeight));
1661 aNewSet.Put(SdrTextAutoGrowHeightItem(bAutoGrowWidth));
1662
1663 // #103516# Exchange horz and vert adjusts
1664 switch(eVert)
1665 {
1666 case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break;
1667 case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break;
1668 case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break;
1669 case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
1670 }
1671 switch(eHorz)
1672 {
1673 case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break;
1674 case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break;
1675 case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break;
1676 case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
1677 }
1678
1679 SetObjectItemSet(aNewSet);
1680
1681 pOutlinerParaObject = GetOutlinerParaObject();
1682 if( pOutlinerParaObject )
1683 {
1684 // set ParaObject orientation accordingly
1685 pOutlinerParaObject->SetVertical(bVertical);
1686 }
1687
1688 // restore object size
1689 SetSnapRect(aObjectRect);
1690 }
1691 }
1692
1693 ////////////////////////////////////////////////////////////////////////////////////////////////////
1694 //
1695 // transformation interface for StarOfficeAPI. This implements support for
1696 // homogen 3x3 matrices containing the transformation of the SdrObject. At the
1697 // moment it contains a shearX, rotation and translation, but for setting all linear
1698 // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
1699 //
1700 ////////////////////////////////////////////////////////////////////////////////////////////////////
1701 // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon
1702 // with the base geometry and returns TRUE. Otherwise it returns FALSE.
TRGetBaseGeometry(basegfx::B2DHomMatrix & rMatrix,basegfx::B2DPolyPolygon &) const1703 sal_Bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
1704 {
1705 // get turn and shear
1706 double fRotate = (aGeo.nDrehWink / 100.0) * F_PI180;
1707 double fShearX = (aGeo.nShearWink / 100.0) * F_PI180;
1708
1709 // get aRect, this is the unrotated snaprect
1710 Rectangle aRectangle(aRect);
1711
1712 // fill other values
1713 basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
1714 basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
1715
1716 // position maybe relative to anchorpos, convert
1717 if( pModel && pModel->IsWriter() )
1718 {
1719 if(GetAnchorPos().X() || GetAnchorPos().Y())
1720 {
1721 aTranslate -= basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1722 }
1723 }
1724
1725 // force MapUnit to 100th mm
1726 const SfxMapUnit eMapUnit(GetObjectMapUnit());
1727 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1728 {
1729 switch(eMapUnit)
1730 {
1731 case SFX_MAPUNIT_TWIP :
1732 {
1733 // position
1734 aTranslate.setX(ImplTwipsToMM(aTranslate.getX()));
1735 aTranslate.setY(ImplTwipsToMM(aTranslate.getY()));
1736
1737 // size
1738 aScale.setX(ImplTwipsToMM(aScale.getX()));
1739 aScale.setY(ImplTwipsToMM(aScale.getY()));
1740
1741 break;
1742 }
1743 default:
1744 {
1745 DBG_ERROR("TRGetBaseGeometry: Missing unit translation to 100th mm!");
1746 }
1747 }
1748 }
1749
1750 // build matrix
1751 rMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1752 aScale,
1753 basegfx::fTools::equalZero(fShearX) ? 0.0 : tan(fShearX),
1754 basegfx::fTools::equalZero(fRotate) ? 0.0 : -fRotate,
1755 aTranslate);
1756
1757 return sal_False;
1758 }
1759
1760 // sets the base geometry of the object using infos contained in the homogen 3x3 matrix.
1761 // If it's an SdrPathObj it will use the provided geometry information. The Polygon has
1762 // to use (0,0) as upper left and will be scaled to the given size in the matrix.
TRSetBaseGeometry(const basegfx::B2DHomMatrix & rMatrix,const basegfx::B2DPolyPolygon &)1763 void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
1764 {
1765 // break up matrix
1766 basegfx::B2DTuple aScale;
1767 basegfx::B2DTuple aTranslate;
1768 double fRotate(0.0);
1769 double fShearX(0.0);
1770 rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1771
1772 // #i75086# Old DrawingLayer (GeoStat and geometry) does not support holding negative scalings
1773 // in X and Y which equal a 180 degree rotation. Recognize it and react accordingly
1774 if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
1775 {
1776 aScale.setX(fabs(aScale.getX()));
1777 aScale.setY(fabs(aScale.getY()));
1778 fRotate = fmod(fRotate + F_PI, F_2PI);
1779 }
1780
1781 // reset object shear and rotations
1782 aGeo.nDrehWink = 0;
1783 aGeo.RecalcSinCos();
1784 aGeo.nShearWink = 0;
1785 aGeo.RecalcTan();
1786
1787 // force metric to pool metric
1788 const SfxMapUnit eMapUnit(GetObjectMapUnit());
1789 if(eMapUnit != SFX_MAPUNIT_100TH_MM)
1790 {
1791 switch(eMapUnit)
1792 {
1793 case SFX_MAPUNIT_TWIP :
1794 {
1795 // position
1796 aTranslate.setX(ImplMMToTwips(aTranslate.getX()));
1797 aTranslate.setY(ImplMMToTwips(aTranslate.getY()));
1798
1799 // size
1800 aScale.setX(ImplMMToTwips(aScale.getX()));
1801 aScale.setY(ImplMMToTwips(aScale.getY()));
1802
1803 break;
1804 }
1805 default:
1806 {
1807 DBG_ERROR("TRSetBaseGeometry: Missing unit translation to PoolMetric!");
1808 }
1809 }
1810 }
1811
1812 // if anchor is used, make position relative to it
1813 if( pModel && pModel->IsWriter() )
1814 {
1815 if(GetAnchorPos().X() || GetAnchorPos().Y())
1816 {
1817 aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
1818 }
1819 }
1820
1821 // build and set BaseRect (use scale)
1822 Point aPoint = Point();
1823 Size aSize(FRound(aScale.getX()), FRound(aScale.getY()));
1824 Rectangle aBaseRect(aPoint, aSize);
1825 SetSnapRect(aBaseRect);
1826
1827 // shear?
1828 if(!basegfx::fTools::equalZero(fShearX))
1829 {
1830 GeoStat aGeoStat;
1831 aGeoStat.nShearWink = FRound((atan(fShearX) / F_PI180) * 100.0);
1832 aGeoStat.RecalcTan();
1833 Shear(Point(), aGeoStat.nShearWink, aGeoStat.nTan, sal_False);
1834 }
1835
1836 // rotation?
1837 if(!basegfx::fTools::equalZero(fRotate))
1838 {
1839 GeoStat aGeoStat;
1840
1841 // #i78696#
1842 // fRotate is matematically correct, but aGeoStat.nDrehWink is
1843 // mirrored -> mirror value here
1844 aGeoStat.nDrehWink = NormAngle360(FRound(-fRotate / F_PI18000));
1845 aGeoStat.RecalcSinCos();
1846 Rotate(Point(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1847 }
1848
1849 // translate?
1850 if(!aTranslate.equalZero())
1851 {
1852 Move(Size(FRound(aTranslate.getX()), FRound(aTranslate.getY())));
1853 }
1854 }
1855
IsRealyEdited() const1856 bool SdrTextObj::IsRealyEdited() const
1857 {
1858 return pEdtOutl && pEdtOutl->IsModified();
1859 }
1860
1861 /////////////////////////////////////////////////////////////////////////////////////////////////
1862 // moved inlines here form hxx
1863
GetEckenradius() const1864 long SdrTextObj::GetEckenradius() const
1865 {
1866 return ((SdrEckenradiusItem&)(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS))).GetValue();
1867 }
1868
GetMinTextFrameHeight() const1869 long SdrTextObj::GetMinTextFrameHeight() const
1870 {
1871 return ((SdrTextMinFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT))).GetValue();
1872 }
1873
GetMaxTextFrameHeight() const1874 long SdrTextObj::GetMaxTextFrameHeight() const
1875 {
1876 return ((SdrTextMaxFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT))).GetValue();
1877 }
1878
GetMinTextFrameWidth() const1879 long SdrTextObj::GetMinTextFrameWidth() const
1880 {
1881 return ((SdrTextMinFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH))).GetValue();
1882 }
1883
GetMaxTextFrameWidth() const1884 long SdrTextObj::GetMaxTextFrameWidth() const
1885 {
1886 return ((SdrTextMaxFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH))).GetValue();
1887 }
1888
IsFontwork() const1889 FASTBOOL SdrTextObj::IsFontwork() const
1890 {
1891 return (bTextFrame) ? sal_False // Default ist FALSE
1892 : ((XFormTextStyleItem&)(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE))).GetValue()!=XFT_NONE;
1893 }
1894
IsHideContour() const1895 FASTBOOL SdrTextObj::IsHideContour() const
1896 {
1897 return (bTextFrame) ? sal_False // Default ist: Nein, kein HideContour; HideContour nicht bei TextFrames
1898 : ((XFormTextHideFormItem&)(GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM))).GetValue();
1899 }
1900
IsContourTextFrame() const1901 FASTBOOL SdrTextObj::IsContourTextFrame() const
1902 {
1903 return (bTextFrame) ? sal_False // ContourFrame nicht bei normalen TextFrames
1904 : ((SdrTextContourFrameItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME))).GetValue();
1905 }
1906
GetTextLeftDistance() const1907 long SdrTextObj::GetTextLeftDistance() const
1908 {
1909 return ((SdrTextLeftDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue();
1910 }
1911
GetTextRightDistance() const1912 long SdrTextObj::GetTextRightDistance() const
1913 {
1914 return ((SdrTextRightDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue();
1915 }
1916
GetTextUpperDistance() const1917 long SdrTextObj::GetTextUpperDistance() const
1918 {
1919 return ((SdrTextUpperDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue();
1920 }
1921
GetTextLowerDistance() const1922 long SdrTextObj::GetTextLowerDistance() const
1923 {
1924 return ((SdrTextLowerDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue();
1925 }
1926
GetTextAniKind() const1927 SdrTextAniKind SdrTextObj::GetTextAniKind() const
1928 {
1929 return ((SdrTextAniKindItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND))).GetValue();
1930 }
1931
GetTextAniDirection() const1932 SdrTextAniDirection SdrTextObj::GetTextAniDirection() const
1933 {
1934 return ((SdrTextAniDirectionItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1935 }
1936
1937 // #111096#
1938 // Access to thext hidden flag
GetTextHidden() const1939 sal_Bool SdrTextObj::GetTextHidden() const
1940 {
1941 return mbTextHidden;
1942 }
1943
NbcSetTextHidden(sal_Bool bNew)1944 void SdrTextObj::NbcSetTextHidden(sal_Bool bNew)
1945 {
1946 if(bNew != mbTextHidden)
1947 {
1948 mbTextHidden = bNew;
1949 }
1950 }
1951
1952 // #111096#
1953 // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a
1954 // painting rectangle. Rotation is excluded from the returned values.
GetTextScrollMetaFileAndRectangle(Rectangle & rScrollRectangle,Rectangle & rPaintRectangle)1955 GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
1956 Rectangle& rScrollRectangle, Rectangle& rPaintRectangle)
1957 {
1958 GDIMetaFile* pRetval = 0L;
1959 SdrOutliner& rOutliner = ImpGetDrawOutliner();
1960 Rectangle aTextRect;
1961 Rectangle aAnchorRect;
1962 Rectangle aPaintRect;
1963 Fraction aFitXKorreg(1,1);
1964 bool bContourFrame(IsContourTextFrame());
1965
1966 // get outliner set up. To avoid getting a somehow rotated MetaFile,
1967 // temporarily disable object rotation.
1968 sal_Int32 nAngle(aGeo.nDrehWink);
1969 aGeo.nDrehWink = 0L;
1970 ImpSetupDrawOutlinerForPaint( bContourFrame, rOutliner, aTextRect, aAnchorRect, aPaintRect, aFitXKorreg );
1971 aGeo.nDrehWink = nAngle;
1972
1973 Rectangle aScrollFrameRect(aPaintRect);
1974 const SfxItemSet& rSet = GetObjectItemSet();
1975 SdrTextAniDirection eDirection = ((SdrTextAniDirectionItem&)(rSet.Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue();
1976
1977 if(SDRTEXTANI_LEFT == eDirection || SDRTEXTANI_RIGHT == eDirection)
1978 {
1979 aScrollFrameRect.Left() = aAnchorRect.Left();
1980 aScrollFrameRect.Right() = aAnchorRect.Right();
1981 }
1982
1983 if(SDRTEXTANI_UP == eDirection || SDRTEXTANI_DOWN == eDirection)
1984 {
1985 aScrollFrameRect.Top() = aAnchorRect.Top();
1986 aScrollFrameRect.Bottom() = aAnchorRect.Bottom();
1987 }
1988
1989 // create the MetaFile
1990 pRetval = new GDIMetaFile;
1991 VirtualDevice aBlackHole;
1992 aBlackHole.EnableOutput(sal_False);
1993 pRetval->Record(&aBlackHole);
1994 Point aPaintPos = aPaintRect.TopLeft();
1995
1996 rOutliner.Draw(&aBlackHole, aPaintPos);
1997
1998 pRetval->Stop();
1999 pRetval->WindStart();
2000
2001 // return PaintRectanglePixel and pRetval;
2002 rScrollRectangle = aScrollFrameRect;
2003 rPaintRectangle = aPaintRect;
2004
2005 return pRetval;
2006 }
2007
2008 // #111096#
2009 // Access to TextAnimationAllowed flag
IsTextAnimationAllowed() const2010 bool SdrTextObj::IsTextAnimationAllowed() const
2011 {
2012 return mbTextAnimationAllowed;
2013 }
2014
SetTextAnimationAllowed(sal_Bool bNew)2015 void SdrTextObj::SetTextAnimationAllowed(sal_Bool bNew)
2016 {
2017 if(mbTextAnimationAllowed != bNew)
2018 {
2019 mbTextAnimationAllowed = bNew;
2020 ActionChanged();
2021 }
2022 }
2023
2024 /** called from the SdrObjEditView during text edit when the status of the edit outliner changes */
onEditOutlinerStatusEvent(EditStatus * pEditStatus)2025 void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
2026 {
2027 const sal_uInt32 nStat = pEditStatus->GetStatusWord();
2028 const bool bGrowX=(nStat & EE_STAT_TEXTWIDTHCHANGED) !=0;
2029 const bool bGrowY=(nStat & EE_STAT_TEXTHEIGHTCHANGED) !=0;
2030 if(bTextFrame && (bGrowX || bGrowY))
2031 {
2032 const bool bAutoGrowHgt= bTextFrame && IsAutoGrowHeight();
2033 const bool bAutoGrowWdt= bTextFrame && IsAutoGrowWidth();
2034
2035 if ((bGrowX && bAutoGrowWdt) || (bGrowY && bAutoGrowHgt))
2036 {
2037 AdjustTextFrameWidthAndHeight();
2038 }
2039 }
2040 }
2041
2042 /** returns the currently active text. */
getActiveText() const2043 SdrText* SdrTextObj::getActiveText() const
2044 {
2045 if( !mpText )
2046 return getText( 0 );
2047 else
2048 return mpText;
2049 }
2050
2051 /** returns the nth available text. */
getText(sal_Int32 nIndex) const2052 SdrText* SdrTextObj::getText( sal_Int32 nIndex ) const
2053 {
2054 if( nIndex == 0 )
2055 {
2056 if( mpText == 0 )
2057 const_cast< SdrTextObj* >(this)->mpText = new SdrText( *(const_cast< SdrTextObj* >(this)) );
2058 return mpText;
2059 }
2060 else
2061 {
2062 return 0;
2063 }
2064 }
2065
2066 /** returns the number of texts available for this object. */
getTextCount() const2067 sal_Int32 SdrTextObj::getTextCount() const
2068 {
2069 return 1;
2070 }
2071
2072 /** changes the current active text */
setActiveText(sal_Int32)2073 void SdrTextObj::setActiveText( sal_Int32 /*nIndex*/ )
2074 {
2075 }
2076
2077 /** returns the index of the text that contains the given point or -1 */
CheckTextHit(const Point &) const2078 sal_Int32 SdrTextObj::CheckTextHit(const Point& /*rPnt*/) const
2079 {
2080 return 0;
2081 }
2082
SetObjectItemNoBroadcast(const SfxPoolItem & rItem)2083 void SdrTextObj::SetObjectItemNoBroadcast(const SfxPoolItem& rItem)
2084 {
2085 static_cast< sdr::properties::TextProperties& >(GetProperties()).SetObjectItemNoBroadcast(rItem);
2086 }
2087
2088 /////////////////////////////////////////////////////////////////////////////////////////////////
2089 //
2090 // Konzept des TextObjekts:
2091 // ~~~~~~~~~~~~~~~~~~~~~~~~
2092 // Attribute/Varianten:
2093 // - sal_Bool Textrahmen / beschriftetes Zeichenobjekt
2094 // - sal_Bool FontWork (wenn nicht Textrahmen und nicht ContourTextFrame)
2095 // - sal_Bool ContourTextFrame (wenn nicht Textrahmen und nicht Fontwork)
2096 // - long Drehwinkel (wenn nicht FontWork)
2097 // - long Textrahmenabstaende (wenn nicht FontWork)
2098 // - sal_Bool FitToSize (wenn nicht FontWork)
2099 // - sal_Bool AutoGrowingWidth/Height (wenn nicht FitToSize und nicht FontWork)
2100 // - long Min/MaxFrameWidth/Height (wenn AutoGrowingWidth/Height)
2101 // - enum Horizontale Textverankerung Links,Mitte,Rechts,Block,Stretch(ni)
2102 // - enum Vertikale Textverankerung Oben,Mitte,Unten,Block,Stretch(ni)
2103 // - enum Laufschrift (wenn nicht FontWork)
2104 //
2105 // Jedes abgeleitete Objekt ist entweder ein Textrahmen (bTextFrame=sal_True)
2106 // oder ein beschriftetes Zeichenobjekt (bTextFrame=sal_False).
2107 //
2108 // Defaultverankerung von Textrahmen:
2109 // SDRTEXTHORZADJUST_BLOCK, SDRTEXTVERTADJUST_TOP
2110 // = statische Pooldefaults
2111 // Defaultverankerung von beschrifteten Zeichenobjekten:
2112 // SDRTEXTHORZADJUST_CENTER, SDRTEXTVERTADJUST_CENTER
2113 // durch harte Attributierung von SdrAttrObj
2114 //
2115 // Jedes vom SdrTextObj abgeleitete Objekt muss ein "UnrotatedSnapRect"
2116 // (->TakeUnrotatedSnapRect()) liefern (Drehreferenz ist TopLeft dieses
2117 // Rechtecks (aGeo.nDrehWink)), welches die Grundlage der Textverankerung
2118 // bildet. Von diesem werden dann ringsum die Textrahmenabstaende abgezogen;
2119 // das Ergebnis ist der Ankerbereich (->TakeTextAnchorRect()). Innerhalb
2120 // dieses Bereichs wird dann in Abhaengigkeit von der horizontalen und
2121 // vertikalen Ausrichtung (SdrTextVertAdjust,SdrTextHorzAdjust) der Ankerpunkt
2122 // sowie der Ausgabebereich bestimmt. Bei beschrifteten Grafikobjekten kann
2123 // der Ausgabebereich durchaus groesser als der Ankerbereich werden, bei
2124 // Textrahmen ist er stets kleiner oder gleich (ausser bei negativen Textrahmen-
2125 // abstaenden).
2126 //
2127 // FitToSize hat Prioritaet vor Textverankerung und AutoGrowHeight/Width. Der
2128 // Ausgabebereich ist bei FitToSize immer genau der Ankerbereich. Weiterhin
2129 // gibt es bei FitToSize keinen automatischen Zeilenumbruch.
2130 //
2131 // ContourTextFrame:
2132 // - long Drehwinkel
2133 // - long Textrahmenabstaende spaeter vielleicht
2134 // - sal_Bool FitToSize spaeter vielleicht
2135 // - sal_Bool AutoGrowingWidth/Height viel spaeter vielleicht
2136 // - long Min/MaxFrameWidth/Height viel spaeter vielleicht
2137 // - enum Horizontale Textverankerung spaeter vielleicht, erstmal Links, Absatz zentr.
2138 // - enum Vertikale Textverankerung spaeter vielleicht, erstmal oben
2139 // - enum Laufschrift spaeter vielleicht (evtl. sogar mit korrektem Clipping)
2140 //
2141 // Bei Aenderungen zu beachten:
2142 // - Paint
2143 // - HitTest
2144 // - ConvertToPoly
2145 // - Edit
2146 // - Drucken,Speichern, Paint in Nachbarview waerend Edit
2147 // - ModelChanged (z.B. durch NachbarView oder Lineale) waerend Edit
2148 // - FillColorChanged waerend Edit
2149 // - uvm...
2150 //
2151 /////////////////////////////////////////////////////////////////////////////////////////////////
2152
2153