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 73 inline double ImplTwipsToMM(double fVal) { return (fVal * (127.0 / 72.0)); } 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 91 sdr::properties::BaseProperties* SdrTextObj::CreateObjectSpecificProperties() 92 { 93 return new sdr::properties::TextProperties(*this); 94 } 95 96 ////////////////////////////////////////////////////////////////////////////// 97 // DrawContact section 98 99 sdr::contact::ViewContact* SdrTextObj::CreateObjectSpecificViewContact() 100 { 101 return new sdr::contact::ViewContactOfTextObj(*this); 102 } 103 104 ////////////////////////////////////////////////////////////////////////////// 105 106 TYPEINIT1(SdrTextObj,SdrAttrObj); 107 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 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 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 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 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 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 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 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 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 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 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 363 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 384 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 409 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 437 SdrTextHorzAdjust SdrTextObj::GetTextHorizontalAdjust() const 438 { 439 return GetTextHorizontalAdjust(GetObjectItemSet()); 440 } 441 442 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 470 SdrTextVertAdjust SdrTextObj::GetTextVerticalAdjust() const 471 { 472 return GetTextVerticalAdjust(GetObjectItemSet()); 473 } 474 475 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 503 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 512 void SdrTextObj::ImpCheckShear() 513 { 514 if (bNoShear && aGeo.nShearWink!=0) { 515 aGeo.nShearWink=0; 516 aGeo.nTan=0; 517 } 518 } 519 520 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 547 sal_uInt16 SdrTextObj::GetObjIdentifier() const 548 { 549 return sal_uInt16(eTextKind); 550 } 551 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 576 FASTBOOL SdrTextObj::HasEditText() const 577 { 578 return HasTextImpl( pEdtOutl ); 579 } 580 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 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 631 FASTBOOL SdrTextObj::NbcSetEckenradius(long nRad) 632 { 633 SetObjectItem(SdrEckenradiusItem(nRad)); 634 return sal_True; 635 } 636 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 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 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 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 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 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 738 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 795 void SdrTextObj::TakeUnrotatedSnapRect(Rectangle& rRect) const 796 { 797 rRect=aRect; 798 } 799 800 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 836 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 1008 OutlinerParaObject* SdrTextObj::GetEditOutlinerParaObject() const 1009 { 1010 OutlinerParaObject* pPara=NULL; 1011 if( HasTextImpl( pEdtOutl ) ) 1012 { 1013 sal_uInt16 nParaAnz = static_cast< sal_uInt16 >( pEdtOutl->GetParagraphCount() ); 1014 pPara = pEdtOutl->CreateParaObject(0, nParaAnz); 1015 } 1016 return pPara; 1017 } 1018 1019 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 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 1137 void SdrTextObj::StopTextAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/) 1138 { 1139 // #111096# 1140 // use new text animation 1141 SetTextAnimationAllowed(sal_False); 1142 } 1143 1144 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 1212 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 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 1270 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 1281 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 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 1321 sal_uInt32 SdrTextObj::GetSnapPointCount() const 1322 { 1323 return 4L; 1324 } 1325 1326 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 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() 1367 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 1387 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 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() 1405 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 1439 void SdrTextObj::SetupOutlinerFormatting( SdrOutliner& rOutl, Rectangle& rPaintRect ) const 1440 { 1441 ImpInitDrawOutliner( rOutl ); 1442 UpdateOutlinerFormatting( rOutl, rPaintRect ); 1443 } 1444 1445 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 1466 OutlinerParaObject* SdrTextObj::GetOutlinerParaObject() const 1467 { 1468 SdrText* pText = getActiveText(); 1469 if( pText ) 1470 return pText->GetOutlinerParaObject(); 1471 else 1472 return 0; 1473 } 1474 1475 bool SdrTextObj::HasOutlinerParaObject() const 1476 { 1477 SdrText* pText = getActiveText(); 1478 if( pText && pText->GetOutlinerParaObject() ) 1479 return true; 1480 return false; 1481 } 1482 1483 void SdrTextObj::NbcSetOutlinerParaObject(OutlinerParaObject* pTextObject) 1484 { 1485 NbcSetOutlinerParaObjectForText( pTextObject, getActiveText() ); 1486 } 1487 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 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 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 1564 SdrObjGeoData* SdrTextObj::NewGeoData() const 1565 { 1566 return new SdrTextObjGeoData; 1567 } 1568 1569 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 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 1586 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 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 1609 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 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. 1703 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 // postion 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. 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 1856 bool SdrTextObj::IsRealyEdited() const 1857 { 1858 return pEdtOutl && pEdtOutl->IsModified(); 1859 } 1860 1861 ///////////////////////////////////////////////////////////////////////////////////////////////// 1862 // moved inlines here form hxx 1863 1864 long SdrTextObj::GetEckenradius() const 1865 { 1866 return ((SdrEckenradiusItem&)(GetObjectItemSet().Get(SDRATTR_ECKENRADIUS))).GetValue(); 1867 } 1868 1869 long SdrTextObj::GetMinTextFrameHeight() const 1870 { 1871 return ((SdrTextMinFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEHEIGHT))).GetValue(); 1872 } 1873 1874 long SdrTextObj::GetMaxTextFrameHeight() const 1875 { 1876 return ((SdrTextMaxFrameHeightItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEHEIGHT))).GetValue(); 1877 } 1878 1879 long SdrTextObj::GetMinTextFrameWidth() const 1880 { 1881 return ((SdrTextMinFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MINFRAMEWIDTH))).GetValue(); 1882 } 1883 1884 long SdrTextObj::GetMaxTextFrameWidth() const 1885 { 1886 return ((SdrTextMaxFrameWidthItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_MAXFRAMEWIDTH))).GetValue(); 1887 } 1888 1889 FASTBOOL SdrTextObj::IsFontwork() const 1890 { 1891 return (bTextFrame) ? sal_False // Default ist FALSE 1892 : ((XFormTextStyleItem&)(GetObjectItemSet().Get(XATTR_FORMTXTSTYLE))).GetValue()!=XFT_NONE; 1893 } 1894 1895 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 1901 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 1907 long SdrTextObj::GetTextLeftDistance() const 1908 { 1909 return ((SdrTextLeftDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LEFTDIST))).GetValue(); 1910 } 1911 1912 long SdrTextObj::GetTextRightDistance() const 1913 { 1914 return ((SdrTextRightDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_RIGHTDIST))).GetValue(); 1915 } 1916 1917 long SdrTextObj::GetTextUpperDistance() const 1918 { 1919 return ((SdrTextUpperDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_UPPERDIST))).GetValue(); 1920 } 1921 1922 long SdrTextObj::GetTextLowerDistance() const 1923 { 1924 return ((SdrTextLowerDistItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_LOWERDIST))).GetValue(); 1925 } 1926 1927 SdrTextAniKind SdrTextObj::GetTextAniKind() const 1928 { 1929 return ((SdrTextAniKindItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIKIND))).GetValue(); 1930 } 1931 1932 SdrTextAniDirection SdrTextObj::GetTextAniDirection() const 1933 { 1934 return ((SdrTextAniDirectionItem&)(GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION))).GetValue(); 1935 } 1936 1937 // #111096# 1938 // Access to thext hidden flag 1939 sal_Bool SdrTextObj::GetTextHidden() const 1940 { 1941 return mbTextHidden; 1942 } 1943 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. 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 2010 bool SdrTextObj::IsTextAnimationAllowed() const 2011 { 2012 return mbTextAnimationAllowed; 2013 } 2014 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 */ 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. */ 2043 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. */ 2052 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. */ 2067 sal_Int32 SdrTextObj::getTextCount() const 2068 { 2069 return 1; 2070 } 2071 2072 /** changes the current active text */ 2073 void SdrTextObj::setActiveText( sal_Int32 /*nIndex*/ ) 2074 { 2075 } 2076 2077 /** returns the index of the text that contains the given point or -1 */ 2078 sal_Int32 SdrTextObj::CheckTextHit(const Point& /*rPnt*/) const 2079 { 2080 return 0; 2081 } 2082 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