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 #include <svx/sdr/properties/textproperties.hxx> 27 #include <svl/itemset.hxx> 28 #include <svl/style.hxx> 29 #include <svl/itemiter.hxx> 30 #include <svl/smplhint.hxx> 31 #include <svx/svddef.hxx> 32 #include <svx/svdotext.hxx> 33 #include <svx/svdoutl.hxx> 34 #include <editeng/writingmodeitem.hxx> 35 #include <svx/svdmodel.hxx> 36 #include <editeng/outlobj.hxx> 37 #include <svx/xflclit.hxx> 38 #include <editeng/adjitem.hxx> 39 #include <svx/svdetc.hxx> 40 #include <editeng/editeng.hxx> 41 #include <editeng/flditem.hxx> 42 #include <svx/xlnwtit.hxx> 43 #include <svx/svdpool.hxx> 44 45 ////////////////////////////////////////////////////////////////////////////// 46 47 namespace sdr 48 { 49 namespace properties 50 { CreateObjectSpecificItemSet(SfxItemPool & rPool)51 SfxItemSet& TextProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool) 52 { 53 return *(new SfxItemSet(rPool, 54 55 // range from SdrAttrObj 56 SDRATTR_START, SDRATTR_SHADOW_LAST, 57 SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST, 58 SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION, 59 60 // range from SdrTextObj 61 EE_ITEMS_START, EE_ITEMS_END, 62 63 // end 64 0, 0)); 65 } 66 TextProperties(SdrObject & rObj)67 TextProperties::TextProperties(SdrObject& rObj) 68 : AttributeProperties(rObj), 69 maVersion(0) 70 { 71 } 72 TextProperties(const TextProperties & rProps,SdrObject & rObj)73 TextProperties::TextProperties(const TextProperties& rProps, SdrObject& rObj) 74 : AttributeProperties(rProps, rObj), 75 maVersion(rProps.getVersion()) 76 { 77 } 78 ~TextProperties()79 TextProperties::~TextProperties() 80 { 81 } 82 Clone(SdrObject & rObj) const83 BaseProperties& TextProperties::Clone(SdrObject& rObj) const 84 { 85 return *(new TextProperties(*this, rObj)); 86 } 87 ItemSetChanged(const SfxItemSet & rSet)88 void TextProperties::ItemSetChanged(const SfxItemSet& rSet) 89 { 90 SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); 91 sal_Int32 nText = rObj.getTextCount(); 92 93 // #i101556# ItemSet has changed -> new version 94 maVersion++; 95 96 while( --nText >= 0 ) 97 { 98 SdrText* pText = rObj.getText( nText ); 99 100 OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0; 101 102 if(pParaObj) 103 { 104 const bool bTextEdit = rObj.IsTextEditActive() && (rObj.getActiveText() == pText); 105 106 // handle outliner attributes 107 GetObjectItemSet(); 108 Outliner* pOutliner = rObj.GetTextEditOutliner(); 109 110 if(!bTextEdit) 111 { 112 pOutliner = &rObj.ImpGetDrawOutliner(); 113 pOutliner->SetText(*pParaObj); 114 } 115 116 sal_uInt32 nParaCount(pOutliner->GetParagraphCount()); 117 118 for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++) 119 { 120 SfxItemSet aSet(pOutliner->GetParaAttribs(nPara)); 121 aSet.Put(rSet); 122 pOutliner->SetParaAttribs(nPara, aSet); 123 } 124 125 if(!bTextEdit) 126 { 127 if(nParaCount) 128 { 129 // force ItemSet 130 GetObjectItemSet(); 131 132 SfxItemSet aNewSet(pOutliner->GetParaAttribs(0L)); 133 mpItemSet->Put(aNewSet); 134 } 135 136 OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount); 137 pOutliner->Clear(); 138 139 rObj.NbcSetOutlinerParaObjectForText(pTemp,pText); 140 } 141 } 142 } 143 144 // Extra-Repaint for radical layout changes (#43139#) 145 if(SFX_ITEM_SET == rSet.GetItemState(SDRATTR_TEXT_CONTOURFRAME)) 146 { 147 // Here only repaint wanted 148 rObj.ActionChanged(); 149 //rObj.BroadcastObjectChange(); 150 } 151 152 // call parent 153 AttributeProperties::ItemSetChanged(rSet); 154 } 155 ItemChange(const sal_uInt16 nWhich,const SfxPoolItem * pNewItem)156 void TextProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) 157 { 158 SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); 159 160 // #i25616# 161 sal_Int32 nOldLineWidth(0L); 162 163 if(XATTR_LINEWIDTH == nWhich && rObj.DoesSupportTextIndentingOnLineWidthChange()) 164 { 165 nOldLineWidth = ((const XLineWidthItem&)GetItem(XATTR_LINEWIDTH)).GetValue(); 166 } 167 168 if(pNewItem && (SDRATTR_TEXTDIRECTION == nWhich)) 169 { 170 sal_Bool bVertical(com::sun::star::text::WritingMode_TB_RL == ((SvxWritingModeItem*)pNewItem)->GetValue()); 171 rObj.SetVerticalWriting(bVertical); 172 } 173 174 // #95501# reset to default 175 if(!pNewItem && !nWhich && rObj.HasText() ) 176 { 177 SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner(); 178 179 sal_Int32 nCount = rObj.getTextCount(); 180 while( nCount-- ) 181 { 182 SdrText* pText = rObj.getText( nCount ); 183 OutlinerParaObject* pParaObj = pText->GetOutlinerParaObject(); 184 if( pParaObj ) 185 { 186 rOutliner.SetText(*pParaObj); 187 sal_uInt32 nParaCount(rOutliner.GetParagraphCount()); 188 189 if(nParaCount) 190 { 191 ESelection aSelection( 0, 0, EE_PARA_ALL, EE_PARA_ALL); 192 rOutliner.RemoveAttribs(aSelection, sal_True, 0); 193 194 OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount); 195 rOutliner.Clear(); 196 197 rObj.NbcSetOutlinerParaObjectForText( pTemp, pText ); 198 } 199 } 200 } 201 } 202 203 // call parent 204 AttributeProperties::ItemChange( nWhich, pNewItem ); 205 206 // #i25616# 207 if(XATTR_LINEWIDTH == nWhich && rObj.DoesSupportTextIndentingOnLineWidthChange()) 208 { 209 const sal_Int32 nNewLineWidth(((const XLineWidthItem&)GetItem(XATTR_LINEWIDTH)).GetValue()); 210 const sal_Int32 nDifference((nNewLineWidth - nOldLineWidth) / 2); 211 212 if(nDifference) 213 { 214 const sal_Bool bLineVisible(XLINE_NONE != ((const XLineStyleItem&)(GetItem(XATTR_LINESTYLE))).GetValue()); 215 216 if(bLineVisible) 217 { 218 const sal_Int32 nLeftDist(((const SdrTextLeftDistItem&)GetItem(SDRATTR_TEXT_LEFTDIST)).GetValue()); 219 const sal_Int32 nRightDist(((const SdrTextRightDistItem&)GetItem(SDRATTR_TEXT_RIGHTDIST)).GetValue()); 220 const sal_Int32 nUpperDist(((const SdrTextUpperDistItem&)GetItem(SDRATTR_TEXT_UPPERDIST)).GetValue()); 221 const sal_Int32 nLowerDist(((const SdrTextLowerDistItem&)GetItem(SDRATTR_TEXT_LOWERDIST)).GetValue()); 222 223 SetObjectItemDirect(SdrTextLeftDistItem(nLeftDist + nDifference)); 224 SetObjectItemDirect(SdrTextRightDistItem(nRightDist + nDifference)); 225 SetObjectItemDirect(SdrTextUpperDistItem(nUpperDist + nDifference)); 226 SetObjectItemDirect(SdrTextLowerDistItem(nLowerDist + nDifference)); 227 } 228 } 229 } 230 } 231 SetStyleSheet(SfxStyleSheet * pNewStyleSheet,sal_Bool bDontRemoveHardAttr)232 void TextProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr) 233 { 234 SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); 235 236 // call parent 237 AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); 238 239 // #i101556# StyleSheet has changed -> new version 240 maVersion++; 241 242 if( rObj.GetModel() /*&& !rObj.IsTextEditActive()*/ && !rObj.IsLinkedText() ) 243 { 244 SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner(); 245 246 sal_Int32 nText = rObj.getTextCount(); 247 248 while( --nText >= 0 ) 249 { 250 SdrText* pText = rObj.getText( nText ); 251 252 OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0; 253 if( !pParaObj ) 254 continue; 255 256 // apply StyleSheet to all paragraphs 257 rOutliner.SetText(*pParaObj); 258 sal_uInt32 nParaCount(rOutliner.GetParagraphCount()); 259 260 if(nParaCount) 261 { 262 for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++) 263 { 264 SfxItemSet* pTempSet = 0L; 265 266 // since setting the stylesheet removes all para attributes 267 if(bDontRemoveHardAttr) 268 { 269 // we need to remember them if we want to keep them 270 pTempSet = new SfxItemSet(rOutliner.GetParaAttribs(nPara)); 271 } 272 273 if(GetStyleSheet()) 274 { 275 if((OBJ_OUTLINETEXT == rObj.GetTextKind()) && (SdrInventor == rObj.GetObjInventor())) 276 { 277 String aNewStyleSheetName(GetStyleSheet()->GetName()); 278 aNewStyleSheetName.Erase(aNewStyleSheetName.Len() - 1, 1); 279 sal_Int16 nDepth = rOutliner.GetDepth((sal_uInt16)nPara); 280 aNewStyleSheetName += String::CreateFromInt32( nDepth <= 0 ? 1 : nDepth + 1); 281 282 SdrModel* pModel = rObj.GetModel(); 283 SfxStyleSheetBasePool* pStylePool = (pModel != NULL) ? pModel->GetStyleSheetPool() : 0L; 284 SfxStyleSheet* pNewStyle = (SfxStyleSheet*)pStylePool->Find(aNewStyleSheetName, GetStyleSheet()->GetFamily()); 285 DBG_ASSERT( pNewStyle, "AutoStyleSheetName - Style not found!" ); 286 287 if(pNewStyle) 288 { 289 rOutliner.SetStyleSheet(nPara, pNewStyle); 290 } 291 } 292 else 293 { 294 rOutliner.SetStyleSheet(nPara, GetStyleSheet()); 295 } 296 } 297 else 298 { 299 // remove StyleSheet 300 rOutliner.SetStyleSheet(nPara, 0L); 301 } 302 303 if(bDontRemoveHardAttr) 304 { 305 if(pTempSet) 306 { 307 // restore para attributes 308 rOutliner.SetParaAttribs(nPara, *pTempSet); 309 } 310 } 311 else 312 { 313 if(pNewStyleSheet) 314 { 315 // remove all hard paragraph attributes 316 // which occur in StyleSheet, take care of 317 // parents (!) 318 SfxItemIter aIter(pNewStyleSheet->GetItemSet()); 319 const SfxPoolItem* pItem = aIter.FirstItem(); 320 321 while(pItem) 322 { 323 if(!IsInvalidItem(pItem)) 324 { 325 sal_uInt16 nW(pItem->Which()); 326 327 if(nW >= EE_ITEMS_START && nW <= EE_ITEMS_END) 328 { 329 rOutliner.QuickRemoveCharAttribs((sal_uInt16)nPara, nW); 330 } 331 } 332 pItem = aIter.NextItem(); 333 } 334 } 335 } 336 337 if(pTempSet) 338 { 339 delete pTempSet; 340 } 341 } 342 343 OutlinerParaObject* pTemp = rOutliner.CreateParaObject(0, (sal_uInt16)nParaCount); 344 rOutliner.Clear(); 345 rObj.NbcSetOutlinerParaObjectForText(pTemp, pText); 346 } 347 } 348 } 349 350 if(rObj.IsTextFrame()) 351 { 352 rObj.NbcAdjustTextFrameWidthAndHeight(); 353 } 354 } 355 ForceDefaultAttributes()356 void TextProperties::ForceDefaultAttributes() 357 { 358 SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); 359 360 if( rObj.GetObjInventor() == SdrInventor ) 361 { 362 const sal_uInt16 nSdrObjKind = rObj.GetObjIdentifier(); 363 364 if( nSdrObjKind == OBJ_TITLETEXT || nSdrObjKind == OBJ_OUTLINETEXT ) 365 return; // no defaults for presentation objects 366 } 367 368 bool bTextFrame(rObj.IsTextFrame()); 369 370 // force ItemSet 371 GetObjectItemSet(); 372 373 if(bTextFrame) 374 { 375 mpItemSet->Put(XLineStyleItem(XLINE_NONE)); 376 mpItemSet->Put(XFillColorItem(String(), Color(COL_WHITE))); 377 mpItemSet->Put(XFillStyleItem(XFILL_NONE)); 378 } 379 else 380 { 381 mpItemSet->Put(SvxAdjustItem(SVX_ADJUST_CENTER, EE_PARA_JUST)); 382 mpItemSet->Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); 383 mpItemSet->Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); 384 } 385 } 386 ForceStyleToHardAttributes()387 void TextProperties::ForceStyleToHardAttributes() 388 { 389 // #i61284# call parent first to get the hard ObjectItemSet 390 AttributeProperties::ForceStyleToHardAttributes(); 391 392 // #i61284# push hard ObjectItemSet to OutlinerParaObject attributes 393 // using existing functionality 394 GetObjectItemSet(); // force ItemSet 395 ItemSetChanged(*mpItemSet); 396 397 // now the standard TextProperties stuff 398 SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); 399 400 if(rObj.GetModel() 401 && !rObj.IsTextEditActive() 402 && !rObj.IsLinkedText()) 403 { 404 Outliner* pOutliner = SdrMakeOutliner(OUTLINERMODE_OUTLINEOBJECT, rObj.GetModel()); 405 sal_Int32 nText = rObj.getTextCount(); 406 407 while( --nText >= 0 ) 408 { 409 SdrText* pText = rObj.getText( nText ); 410 411 OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : 0; 412 if( !pParaObj ) 413 continue; 414 415 pOutliner->SetText(*pParaObj); 416 417 sal_uInt32 nParaCount(pOutliner->GetParagraphCount()); 418 419 if(nParaCount) 420 { 421 sal_Bool bBurnIn(sal_False); 422 423 for(sal_uInt16 nPara = 0; nPara < nParaCount; nPara++) 424 { 425 SfxStyleSheet* pSheet = pOutliner->GetStyleSheet(nPara); 426 427 if(pSheet) 428 { 429 SfxItemSet aParaSet(pOutliner->GetParaAttribs(nPara)); 430 SfxItemSet aSet(*aParaSet.GetPool()); 431 aSet.Put(pSheet->GetItemSet()); 432 433 /** the next code handles a special case for paragraphs that contain a 434 url field. The color for URL fields is either the system color for 435 urls or the char color attribute that formats the portion in which the 436 url field is contained. 437 When we set a char color attribute to the paragraphs item set from the 438 styles item set, we would have this char color attribute as an attribute 439 that is spanned over the complete paragraph after xml import due to some 440 problems in the xml import (using a XCursor on import so it does not know 441 the paragraphs and can't set char attributes to paragraphs ). 442 443 To avoid this, as soon as we try to set a char color attribute from the style 444 we 445 1. check if we have at least one url field in this paragraph 446 2. if we found at least one url field, we span the char color attribute over 447 all portions that are not url fields and remove the char color attribute 448 from the paragraphs item set 449 */ 450 451 sal_Bool bHasURL(sal_False); 452 453 if(aSet.GetItemState(EE_CHAR_COLOR) == SFX_ITEM_SET) 454 { 455 EditEngine* pEditEngine = const_cast<EditEngine*>(&(pOutliner->GetEditEngine())); 456 EECharAttribArray aAttribs; 457 pEditEngine->GetCharAttribs((sal_uInt16)nPara, aAttribs); 458 sal_uInt16 nAttrib; 459 460 for(nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++) 461 { 462 struct EECharAttrib aAttrib(aAttribs.GetObject(nAttrib)); 463 464 if(EE_FEATURE_FIELD == aAttrib.pAttr->Which()) 465 { 466 if(aAttrib.pAttr) 467 { 468 SvxFieldItem* pFieldItem = (SvxFieldItem*)aAttrib.pAttr; 469 470 if(pFieldItem) 471 { 472 const SvxFieldData* pData = pFieldItem->GetField(); 473 474 if(pData && pData->ISA(SvxURLField)) 475 { 476 bHasURL = sal_True; 477 break; 478 } 479 } 480 } 481 } 482 } 483 484 if(bHasURL) 485 { 486 SfxItemSet aColorSet(*aSet.GetPool(), EE_CHAR_COLOR, EE_CHAR_COLOR ); 487 aColorSet.Put(aSet, sal_False); 488 489 ESelection aSel((sal_uInt16)nPara, 0); 490 491 for(nAttrib = 0; nAttrib < aAttribs.Count(); nAttrib++) 492 { 493 struct EECharAttrib aAttrib(aAttribs.GetObject(nAttrib)); 494 495 if(EE_FEATURE_FIELD == aAttrib.pAttr->Which()) 496 { 497 aSel.nEndPos = aAttrib.nStart; 498 499 if(aSel.nStartPos != aSel.nEndPos) 500 { 501 pEditEngine->QuickSetAttribs(aColorSet, aSel); 502 } 503 504 aSel.nStartPos = aAttrib.nEnd; 505 } 506 } 507 508 aSel.nEndPos = pEditEngine->GetTextLen((sal_uInt16)nPara); 509 510 if(aSel.nStartPos != aSel.nEndPos) 511 { 512 pEditEngine->QuickSetAttribs( aColorSet, aSel ); 513 } 514 } 515 516 } 517 518 aSet.Put(aParaSet, sal_False); 519 520 if(bHasURL) 521 { 522 aSet.ClearItem(EE_CHAR_COLOR); 523 } 524 525 pOutliner->SetParaAttribs(nPara, aSet); 526 bBurnIn = sal_True; // #i51163# Flag was set wrong 527 } 528 } 529 530 if(bBurnIn) 531 { 532 OutlinerParaObject* pTemp = pOutliner->CreateParaObject(0, (sal_uInt16)nParaCount); 533 rObj.NbcSetOutlinerParaObjectForText(pTemp,pText); 534 } 535 } 536 537 pOutliner->Clear(); 538 } 539 delete pOutliner; 540 } 541 } 542 SetObjectItemNoBroadcast(const SfxPoolItem & rItem)543 void TextProperties::SetObjectItemNoBroadcast(const SfxPoolItem& rItem) 544 { 545 GetObjectItemSet(); 546 mpItemSet->Put(rItem); 547 } 548 549 Notify(SfxBroadcaster & rBC,const SfxHint & rHint)550 void TextProperties::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) 551 { 552 // call parent 553 AttributeProperties::Notify(rBC, rHint); 554 555 SdrTextObj& rObj = (SdrTextObj&)GetSdrObject(); 556 if(rObj.HasText()) 557 { 558 if(HAS_BASE(SfxStyleSheet, &rBC)) 559 { 560 SfxSimpleHint* pSimple = PTR_CAST(SfxSimpleHint, &rHint); 561 sal_uInt32 nId(pSimple ? pSimple->GetId() : 0L); 562 563 if(SFX_HINT_DATACHANGED == nId) 564 { 565 rObj.SetPortionInfoChecked(sal_False); 566 567 sal_Int32 nText = rObj.getTextCount(); 568 while( --nText > 0 ) 569 { 570 OutlinerParaObject* pParaObj = rObj.getText(nText )->GetOutlinerParaObject(); 571 if( pParaObj ) 572 pParaObj->ClearPortionInfo(); 573 } 574 rObj.SetTextSizeDirty(); 575 576 if(rObj.IsTextFrame() && rObj.NbcAdjustTextFrameWidthAndHeight()) 577 { 578 // here only repaint wanted 579 rObj.ActionChanged(); 580 //rObj.BroadcastObjectChange(); 581 } 582 583 // #i101556# content of StyleSheet has changed -> new version 584 maVersion++; 585 } 586 587 if(SFX_HINT_DYING == nId) 588 { 589 rObj.SetPortionInfoChecked(sal_False); 590 sal_Int32 nText = rObj.getTextCount(); 591 while( --nText > 0 ) 592 { 593 OutlinerParaObject* pParaObj = rObj.getText(nText )->GetOutlinerParaObject(); 594 if( pParaObj ) 595 pParaObj->ClearPortionInfo(); 596 } 597 } 598 } 599 else if(HAS_BASE(SfxStyleSheetBasePool, &rBC)) 600 { 601 SfxStyleSheetHintExtended* pExtendedHint = PTR_CAST(SfxStyleSheetHintExtended, &rHint); 602 603 if(pExtendedHint 604 && SFX_STYLESHEET_MODIFIED == pExtendedHint->GetHint()) 605 { 606 String aOldName(pExtendedHint->GetOldName()); 607 String aNewName(pExtendedHint->GetStyleSheet()->GetName()); 608 SfxStyleFamily eFamily = pExtendedHint->GetStyleSheet()->GetFamily(); 609 610 if(!aOldName.Equals(aNewName)) 611 { 612 sal_Int32 nText = rObj.getTextCount(); 613 while( --nText > 0 ) 614 { 615 OutlinerParaObject* pParaObj = rObj.getText(nText )->GetOutlinerParaObject(); 616 if( pParaObj ) 617 pParaObj->ChangeStyleSheetName(eFamily, aOldName, aNewName); 618 } 619 } 620 } 621 } 622 } 623 } 624 625 // #i101556# Handout version information getVersion() const626 sal_uInt32 TextProperties::getVersion() const 627 { 628 return maVersion; 629 } 630 } // end of namespace properties 631 } // end of namespace sdr 632 633 ////////////////////////////////////////////////////////////////////////////// 634 // eof 635