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