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_sc.hxx" 30 31 32 33 #include "scitems.hxx" 34 #include <editeng/eeitem.hxx> 35 #include <svx/svdpool.hxx> 36 #include <svx/svdobj.hxx> 37 #include <editeng/editeng.hxx> 38 #include <editeng/editobj.hxx> 39 #include <editeng/flditem.hxx> 40 #include <svx/unomid.hxx> 41 #include <editeng/unoprnms.hxx> 42 #include <editeng/unofored.hxx> 43 #include <rtl/uuid.h> 44 #include <vcl/virdev.hxx> 45 #include <com/sun/star/awt/FontSlant.hpp> 46 47 #include <com/sun/star/beans/PropertyAttribute.hpp> 48 #include <editeng/unoipset.hxx> 49 #include "textuno.hxx" 50 #include "fielduno.hxx" 51 #include "servuno.hxx" 52 #include "editsrc.hxx" 53 #include "docsh.hxx" 54 #include "editutil.hxx" 55 #include "unoguard.hxx" 56 #include "miscuno.hxx" 57 #include "cellsuno.hxx" 58 #include "hints.hxx" 59 #include "patattr.hxx" 60 #include "cell.hxx" 61 #include "docfunc.hxx" 62 #include "scmod.hxx" 63 64 using namespace com::sun::star; 65 66 //------------------------------------------------------------------------ 67 68 const SvxItemPropertySet * lcl_GetHdFtPropertySet() 69 { 70 static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] = 71 { 72 SVX_UNOEDIT_CHAR_PROPERTIES, 73 SVX_UNOEDIT_FONT_PROPERTIES, 74 SVX_UNOEDIT_PARA_PROPERTIES, 75 SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties 76 {0,0,0,0,0,0} 77 }; 78 static sal_Bool bTwipsSet = sal_False; 79 80 if (!bTwipsSet) 81 { 82 // modify PropertyMap to include CONVERT_TWIPS flag for font height 83 // (headers/footers are in twips) 84 85 SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl; 86 while (pEntry->pName) 87 { 88 if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT || 89 pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK || 90 pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) && 91 pEntry->nMemberId == MID_FONTHEIGHT ) 92 { 93 pEntry->nMemberId |= CONVERT_TWIPS; 94 } 95 96 ++pEntry; 97 } 98 bTwipsSet = sal_True; 99 } 100 static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() ); 101 return &aHdFtPropertySet_Impl; 102 } 103 104 //------------------------------------------------------------------------ 105 106 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" ) 107 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" ) 108 109 //------------------------------------------------------------------------ 110 111 ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft, 112 const EditTextObject* pCenter, 113 const EditTextObject* pRight ) : 114 pLeftText ( NULL ), 115 pCenterText ( NULL ), 116 pRightText ( NULL ) 117 { 118 if ( pLeft ) 119 pLeftText = pLeft->Clone(); 120 if ( pCenter ) 121 pCenterText = pCenter->Clone(); 122 if ( pRight ) 123 pRightText = pRight->Clone(); 124 } 125 126 ScHeaderFooterContentObj::~ScHeaderFooterContentObj() 127 { 128 delete pLeftText; 129 delete pCenterText; 130 delete pRightText; 131 } 132 133 void ScHeaderFooterContentObj::AddListener( SfxListener& rListener ) 134 { 135 rListener.StartListening( aBC ); 136 } 137 138 void ScHeaderFooterContentObj::RemoveListener( SfxListener& rListener ) 139 { 140 rListener.EndListening( aBC ); 141 } 142 143 void ScHeaderFooterContentObj::UpdateText( sal_uInt16 nPart, EditEngine& rSource ) 144 { 145 EditTextObject* pNew = rSource.CreateTextObject(); 146 switch (nPart) 147 { 148 case SC_HDFT_LEFT: 149 delete pLeftText; 150 pLeftText = pNew; 151 break; 152 case SC_HDFT_CENTER: 153 delete pCenterText; 154 pCenterText = pNew; 155 break; 156 default: // SC_HDFT_RIGHT 157 delete pRightText; 158 pRightText = pNew; 159 break; 160 } 161 162 aBC.Broadcast( ScHeaderFooterChangedHint( nPart ) ); 163 } 164 165 // XHeaderFooterContent 166 167 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText() 168 throw(uno::RuntimeException) 169 { 170 ScUnoGuard aGuard; 171 return new ScHeaderFooterTextObj( *this, SC_HDFT_LEFT ); 172 } 173 174 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText() 175 throw(uno::RuntimeException) 176 { 177 ScUnoGuard aGuard; 178 return new ScHeaderFooterTextObj( *this, SC_HDFT_CENTER ); 179 } 180 181 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText() 182 throw(uno::RuntimeException) 183 { 184 ScUnoGuard aGuard; 185 return new ScHeaderFooterTextObj( *this, SC_HDFT_RIGHT ); 186 } 187 188 // XUnoTunnel 189 190 sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething( 191 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException) 192 { 193 if ( rId.getLength() == 16 && 194 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 195 rId.getConstArray(), 16 ) ) 196 { 197 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); 198 } 199 return 0; 200 } 201 202 // static 203 const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId() 204 { 205 static uno::Sequence<sal_Int8> * pSeq = 0; 206 if( !pSeq ) 207 { 208 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 209 if( !pSeq ) 210 { 211 static uno::Sequence< sal_Int8 > aSeq( 16 ); 212 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 213 pSeq = &aSeq; 214 } 215 } 216 return *pSeq; 217 } 218 219 // static 220 ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation( 221 const uno::Reference<sheet::XHeaderFooterContent> xObj ) 222 { 223 ScHeaderFooterContentObj* pRet = NULL; 224 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY ); 225 if (xUT.is()) 226 pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId()))); 227 return pRet; 228 } 229 230 231 //------------------------------------------------------------------------ 232 233 ScHeaderFooterTextData::ScHeaderFooterTextData( ScHeaderFooterContentObj& rContent, 234 sal_uInt16 nP ) : 235 rContentObj( rContent ), 236 nPart( nP ), 237 pEditEngine( NULL ), 238 pForwarder( NULL ), 239 bDataValid( sal_False ), 240 bInUpdate( sal_False ) 241 { 242 rContentObj.acquire(); // must not go away 243 rContentObj.AddListener( *this ); 244 } 245 246 ScHeaderFooterTextData::~ScHeaderFooterTextData() 247 { 248 ScUnoGuard aGuard; // needed for EditEngine dtor 249 250 rContentObj.RemoveListener( *this ); 251 252 delete pForwarder; 253 delete pEditEngine; 254 255 rContentObj.release(); 256 } 257 258 void ScHeaderFooterTextData::Notify( SfxBroadcaster&, const SfxHint& rHint ) 259 { 260 if ( rHint.ISA( ScHeaderFooterChangedHint ) ) 261 { 262 if ( ((const ScHeaderFooterChangedHint&)rHint).GetPart() == nPart ) 263 { 264 if (!bInUpdate) // not for own updates 265 bDataValid = sal_False; // text has to be fetched again 266 } 267 } 268 } 269 270 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder() 271 { 272 if (!pEditEngine) 273 { 274 SfxItemPool* pEnginePool = EditEngine::CreatePool(); 275 pEnginePool->FreezeIdRanges(); 276 ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, sal_True ); 277 278 pHdrEngine->EnableUndo( sal_False ); 279 pHdrEngine->SetRefMapMode( MAP_TWIP ); 280 281 // default font must be set, independently of document 282 // -> use global pool from module 283 284 SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() ); 285 const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN); 286 rPattern.FillEditItemSet( &aDefaults ); 287 // FillEditItemSet adjusts font height to 1/100th mm, 288 // but for header/footer twips is needed, as in the PatternAttr: 289 aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT ); 290 aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK ); 291 aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL ); 292 pHdrEngine->SetDefaults( aDefaults ); 293 294 ScHeaderFieldData aData; 295 ScHeaderFooterTextObj::FillDummyFieldData( aData ); 296 pHdrEngine->SetData( aData ); 297 298 pEditEngine = pHdrEngine; 299 pForwarder = new SvxEditEngineForwarder(*pEditEngine); 300 } 301 302 if (bDataValid) 303 return pForwarder; 304 305 const EditTextObject* pData; 306 if (nPart == SC_HDFT_LEFT) 307 pData = rContentObj.GetLeftEditObject(); 308 else if (nPart == SC_HDFT_CENTER) 309 pData = rContentObj.GetCenterEditObject(); 310 else 311 pData = rContentObj.GetRightEditObject(); 312 313 if (pData) 314 pEditEngine->SetText(*pData); 315 316 bDataValid = sal_True; 317 return pForwarder; 318 } 319 320 void ScHeaderFooterTextData::UpdateData() 321 { 322 if ( pEditEngine ) 323 { 324 bInUpdate = sal_True; // don't reset bDataValid during UpdateText 325 326 rContentObj.UpdateText( nPart, *pEditEngine ); 327 328 bInUpdate = sal_False; 329 } 330 } 331 332 //------------------------------------------------------------------------ 333 334 ScHeaderFooterTextObj::ScHeaderFooterTextObj( ScHeaderFooterContentObj& rContent, 335 sal_uInt16 nP ) : 336 aTextData( rContent, nP ), 337 pUnoText( NULL ) 338 { 339 // ScHeaderFooterTextData acquires rContent 340 // pUnoText is created on demand (getString/setString work without it) 341 } 342 343 void ScHeaderFooterTextObj::CreateUnoText_Impl() 344 { 345 if ( !pUnoText ) 346 { 347 // can't be aggregated because getString/setString is handled here 348 ScSharedHeaderFooterEditSource aEditSource( &aTextData ); 349 pUnoText = new SvxUnoText( &aEditSource, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>() ); 350 pUnoText->acquire(); 351 } 352 } 353 354 ScHeaderFooterTextObj::~ScHeaderFooterTextObj() 355 { 356 if (pUnoText) 357 pUnoText->release(); 358 } 359 360 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText() 361 { 362 if (!pUnoText) 363 CreateUnoText_Impl(); 364 return *pUnoText; 365 } 366 367 // XText 368 369 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor() 370 throw(uno::RuntimeException) 371 { 372 ScUnoGuard aGuard; 373 return new ScHeaderFooterTextCursor( *this ); 374 } 375 376 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange( 377 const uno::Reference<text::XTextRange>& aTextPosition ) 378 throw(uno::RuntimeException) 379 { 380 ScUnoGuard aGuard; 381 if (!pUnoText) 382 CreateUnoText_Impl(); 383 return pUnoText->createTextCursorByRange(aTextPosition); 384 //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar 385 } 386 387 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData ) // static 388 { 389 String aDummy(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "???" ))); 390 rData.aTitle = aDummy; 391 rData.aLongDocName = aDummy; 392 rData.aShortDocName = aDummy; 393 rData.aTabName = aDummy; 394 rData.nPageNo = 1; 395 rData.nTotalPages = 99; 396 } 397 398 rtl::OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException) 399 { 400 ScUnoGuard aGuard; 401 rtl::OUString aRet; 402 const EditTextObject* pData; 403 404 sal_uInt16 nPart = aTextData.GetPart(); 405 ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj(); 406 407 if (nPart == SC_HDFT_LEFT) 408 pData = rContentObj.GetLeftEditObject(); 409 else if (nPart == SC_HDFT_CENTER) 410 pData = rContentObj.GetCenterEditObject(); 411 else 412 pData = rContentObj.GetRightEditObject(); 413 if (pData) 414 { 415 // for pure text, no font info is needed in pool defaults 416 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True ); 417 418 ScHeaderFieldData aData; 419 FillDummyFieldData( aData ); 420 aEditEngine.SetData( aData ); 421 422 aEditEngine.SetText(*pData); 423 aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine ); 424 } 425 return aRet; 426 } 427 428 void SAL_CALL ScHeaderFooterTextObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException) 429 { 430 ScUnoGuard aGuard; 431 String aString(aText); 432 433 // for pure text, no font info is needed in pool defaults 434 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True ); 435 aEditEngine.SetText( aString ); 436 437 aTextData.GetContentObj().UpdateText( aTextData.GetPart(), aEditEngine ); 438 } 439 440 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange, 441 const rtl::OUString& aString, sal_Bool bAbsorb ) 442 throw(uno::RuntimeException) 443 { 444 ScUnoGuard aGuard; 445 if (!pUnoText) 446 CreateUnoText_Impl(); 447 pUnoText->insertString( xRange, aString, bAbsorb ); 448 } 449 450 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter( 451 const uno::Reference<text::XTextRange>& xRange, 452 sal_Int16 nControlCharacter, sal_Bool bAbsorb ) 453 throw(lang::IllegalArgumentException, uno::RuntimeException) 454 { 455 ScUnoGuard aGuard; 456 if (!pUnoText) 457 CreateUnoText_Impl(); 458 pUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb ); 459 } 460 461 void SAL_CALL ScHeaderFooterTextObj::insertTextContent( 462 const uno::Reference<text::XTextRange >& xRange, 463 const uno::Reference<text::XTextContent >& xContent, 464 sal_Bool bAbsorb ) 465 throw(lang::IllegalArgumentException, uno::RuntimeException) 466 { 467 ScUnoGuard aGuard; 468 if ( xContent.is() && xRange.is() ) 469 { 470 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent ); 471 472 SvxUnoTextRangeBase* pTextRange = 473 ScHeaderFooterTextCursor::getImplementation( xRange ); 474 475 #if 0 476 if (!pTextRange) 477 pTextRange = (SvxUnoTextRange*)xRange->getImplementation( 478 SvxUnoTextRange_getReflection() ); 479 //! bei SvxUnoTextRange testen, ob in passendem Objekt !!! 480 #endif 481 482 if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange ) 483 { 484 SvxEditSource* pEditSource = pTextRange->GetEditSource(); 485 ESelection aSelection(pTextRange->GetSelection()); 486 487 if (!bAbsorb) 488 { 489 // don't replace -> append at end 490 aSelection.Adjust(); 491 aSelection.nStartPara = aSelection.nEndPara; 492 aSelection.nStartPos = aSelection.nEndPos; 493 } 494 495 SvxFieldItem aItem(pHeaderField->CreateFieldItem()); 496 497 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder(); 498 pForwarder->QuickInsertField( aItem, aSelection ); 499 pEditSource->UpdateData(); 500 501 // neue Selektion: ein Zeichen 502 aSelection.Adjust(); 503 aSelection.nEndPara = aSelection.nStartPara; 504 aSelection.nEndPos = aSelection.nStartPos + 1; 505 pHeaderField->InitDoc( &aTextData.GetContentObj(), aTextData.GetPart(), aSelection ); 506 507 // #91431# for bAbsorb=sal_False, the new selection must be behind the inserted content 508 // (the xml filter relies on this) 509 if (!bAbsorb) 510 aSelection.nStartPos = aSelection.nEndPos; 511 512 pTextRange->SetSelection( aSelection ); 513 514 return; 515 } 516 } 517 518 if (!pUnoText) 519 CreateUnoText_Impl(); 520 pUnoText->insertTextContent( xRange, xContent, bAbsorb ); 521 } 522 523 void SAL_CALL ScHeaderFooterTextObj::removeTextContent( 524 const uno::Reference<text::XTextContent>& xContent ) 525 throw(container::NoSuchElementException, uno::RuntimeException) 526 { 527 ScUnoGuard aGuard; 528 if ( xContent.is() ) 529 { 530 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent ); 531 if ( pHeaderField && pHeaderField->IsInserted() ) 532 { 533 //! Testen, ob das Feld in dieser Zelle ist 534 pHeaderField->DeleteField(); 535 return; 536 } 537 } 538 if (!pUnoText) 539 CreateUnoText_Impl(); 540 pUnoText->removeTextContent( xContent ); 541 } 542 543 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException) 544 { 545 ScUnoGuard aGuard; 546 if (!pUnoText) 547 CreateUnoText_Impl(); 548 return pUnoText->getText(); 549 } 550 551 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException) 552 { 553 ScUnoGuard aGuard; 554 if (!pUnoText) 555 CreateUnoText_Impl(); 556 return pUnoText->getStart(); 557 } 558 559 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException) 560 { 561 ScUnoGuard aGuard; 562 if (!pUnoText) 563 CreateUnoText_Impl(); 564 return pUnoText->getEnd(); 565 } 566 567 // XTextFieldsSupplier 568 569 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields() 570 throw(uno::RuntimeException) 571 { 572 ScUnoGuard aGuard; 573 // all fields 574 return new ScHeaderFieldsObj( &aTextData.GetContentObj(), aTextData.GetPart(), SC_SERVICE_INVALID ); 575 } 576 577 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters() 578 throw(uno::RuntimeException) 579 { 580 // sowas gibts nicht im Calc (?) 581 return NULL; 582 } 583 584 // XTextRangeMover 585 586 void SAL_CALL ScHeaderFooterTextObj::moveTextRange( 587 const uno::Reference<text::XTextRange>& xRange, 588 sal_Int16 nParagraphs ) 589 throw(uno::RuntimeException) 590 { 591 ScUnoGuard aGuard; 592 if (!pUnoText) 593 CreateUnoText_Impl(); 594 pUnoText->moveTextRange( xRange, nParagraphs ); 595 } 596 597 // XEnumerationAccess 598 599 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration() 600 throw(uno::RuntimeException) 601 { 602 ScUnoGuard aGuard; 603 if (!pUnoText) 604 CreateUnoText_Impl(); 605 return pUnoText->createEnumeration(); 606 } 607 608 // XElementAccess 609 610 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException) 611 { 612 ScUnoGuard aGuard; 613 if (!pUnoText) 614 CreateUnoText_Impl(); 615 return pUnoText->getElementType(); 616 } 617 618 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException) 619 { 620 ScUnoGuard aGuard; 621 if (!pUnoText) 622 CreateUnoText_Impl(); 623 return pUnoText->hasElements(); 624 } 625 626 //------------------------------------------------------------------------ 627 628 ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) : 629 SvxUnoTextCursor( rOther ), 630 rTextObj( rOther.rTextObj ) 631 { 632 rTextObj.acquire(); 633 } 634 635 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) : 636 SvxUnoTextCursor( rText.GetUnoText() ), 637 rTextObj( rText ) 638 { 639 rTextObj.acquire(); 640 } 641 642 ScCellTextCursor::~ScCellTextCursor() throw() 643 { 644 rTextObj.release(); 645 } 646 647 // SvxUnoTextCursor methods reimplemented here to return the right objects: 648 649 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException) 650 { 651 ScUnoGuard aGuard; 652 return &rTextObj; 653 } 654 655 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException) 656 { 657 ScUnoGuard aGuard; 658 659 //! use other object for range than cursor? 660 661 ScCellTextCursor* pNew = new ScCellTextCursor( *this ); 662 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) ); 663 664 ESelection aNewSel(GetSelection()); 665 aNewSel.nEndPara = aNewSel.nStartPara; 666 aNewSel.nEndPos = aNewSel.nStartPos; 667 pNew->SetSelection( aNewSel ); 668 669 return xRange; 670 } 671 672 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException) 673 { 674 ScUnoGuard aGuard; 675 676 //! use other object for range than cursor? 677 678 ScCellTextCursor* pNew = new ScCellTextCursor( *this ); 679 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) ); 680 681 ESelection aNewSel(GetSelection()); 682 aNewSel.nStartPara = aNewSel.nEndPara; 683 aNewSel.nStartPos = aNewSel.nEndPos; 684 pNew->SetSelection( aNewSel ); 685 686 return xRange; 687 } 688 689 // XUnoTunnel 690 691 sal_Int64 SAL_CALL ScCellTextCursor::getSomething( 692 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException) 693 { 694 if ( rId.getLength() == 16 && 695 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 696 rId.getConstArray(), 16 ) ) 697 { 698 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); 699 } 700 return SvxUnoTextCursor::getSomething( rId ); 701 } 702 703 // static 704 const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId() 705 { 706 static uno::Sequence<sal_Int8> * pSeq = 0; 707 if( !pSeq ) 708 { 709 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 710 if( !pSeq ) 711 { 712 static uno::Sequence< sal_Int8 > aSeq( 16 ); 713 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 714 pSeq = &aSeq; 715 } 716 } 717 return *pSeq; 718 } 719 720 // static 721 ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj ) 722 { 723 ScCellTextCursor* pRet = NULL; 724 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY ); 725 if (xUT.is()) 726 pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId()))); 727 return pRet; 728 } 729 730 //------------------------------------------------------------------------ 731 732 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) : 733 SvxUnoTextCursor( rOther ), 734 rTextObj( rOther.rTextObj ) 735 { 736 rTextObj.acquire(); 737 } 738 739 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) : 740 SvxUnoTextCursor( rText.GetUnoText() ), 741 rTextObj( rText ) 742 { 743 rTextObj.acquire(); 744 } 745 746 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw() 747 { 748 rTextObj.release(); 749 } 750 751 // SvxUnoTextCursor methods reimplemented here to return the right objects: 752 753 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException) 754 { 755 ScUnoGuard aGuard; 756 return &rTextObj; 757 } 758 759 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException) 760 { 761 ScUnoGuard aGuard; 762 763 //! use other object for range than cursor? 764 765 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this ); 766 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) ); 767 768 ESelection aNewSel(GetSelection()); 769 aNewSel.nEndPara = aNewSel.nStartPara; 770 aNewSel.nEndPos = aNewSel.nStartPos; 771 pNew->SetSelection( aNewSel ); 772 773 return xRange; 774 } 775 776 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException) 777 { 778 ScUnoGuard aGuard; 779 780 //! use other object for range than cursor? 781 782 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this ); 783 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) ); 784 785 ESelection aNewSel(GetSelection()); 786 aNewSel.nStartPara = aNewSel.nEndPara; 787 aNewSel.nStartPos = aNewSel.nEndPos; 788 pNew->SetSelection( aNewSel ); 789 790 return xRange; 791 } 792 793 // XUnoTunnel 794 795 sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething( 796 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException) 797 { 798 if ( rId.getLength() == 16 && 799 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 800 rId.getConstArray(), 16 ) ) 801 { 802 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); 803 } 804 return SvxUnoTextCursor::getSomething( rId ); 805 } 806 807 // static 808 const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId() 809 { 810 static uno::Sequence<sal_Int8> * pSeq = 0; 811 if( !pSeq ) 812 { 813 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 814 if( !pSeq ) 815 { 816 static uno::Sequence< sal_Int8 > aSeq( 16 ); 817 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 818 pSeq = &aSeq; 819 } 820 } 821 return *pSeq; 822 } 823 824 // static 825 ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation( 826 const uno::Reference<uno::XInterface> xObj ) 827 { 828 ScHeaderFooterTextCursor* pRet = NULL; 829 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY ); 830 if (xUT.is()) 831 pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId()))); 832 return pRet; 833 } 834 835 //------------------------------------------------------------------------ 836 837 ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) : 838 SvxUnoTextCursor( rOther ), 839 xParentText( rOther.xParentText ) 840 { 841 } 842 843 ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent, 844 const SvxUnoTextBase& rText ) : 845 SvxUnoTextCursor( rText ), 846 xParentText( xParent ) 847 848 { 849 } 850 851 ScDrawTextCursor::~ScDrawTextCursor() throw() 852 { 853 } 854 855 // SvxUnoTextCursor methods reimplemented here to return the right objects: 856 857 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException) 858 { 859 ScUnoGuard aGuard; 860 return xParentText; 861 } 862 863 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException) 864 { 865 ScUnoGuard aGuard; 866 867 //! use other object for range than cursor? 868 869 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this ); 870 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) ); 871 872 ESelection aNewSel(GetSelection()); 873 aNewSel.nEndPara = aNewSel.nStartPara; 874 aNewSel.nEndPos = aNewSel.nStartPos; 875 pNew->SetSelection( aNewSel ); 876 877 return xRange; 878 } 879 880 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException) 881 { 882 ScUnoGuard aGuard; 883 884 //! use other object for range than cursor? 885 886 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this ); 887 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) ); 888 889 ESelection aNewSel(GetSelection()); 890 aNewSel.nStartPara = aNewSel.nEndPara; 891 aNewSel.nStartPos = aNewSel.nEndPos; 892 pNew->SetSelection( aNewSel ); 893 894 return xRange; 895 } 896 897 // XUnoTunnel 898 899 sal_Int64 SAL_CALL ScDrawTextCursor::getSomething( 900 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException) 901 { 902 if ( rId.getLength() == 16 && 903 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 904 rId.getConstArray(), 16 ) ) 905 { 906 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this)); 907 } 908 return SvxUnoTextCursor::getSomething( rId ); 909 } 910 911 // static 912 const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId() 913 { 914 static uno::Sequence<sal_Int8> * pSeq = 0; 915 if( !pSeq ) 916 { 917 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); 918 if( !pSeq ) 919 { 920 static uno::Sequence< sal_Int8 > aSeq( 16 ); 921 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); 922 pSeq = &aSeq; 923 } 924 } 925 return *pSeq; 926 } 927 928 // static 929 ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj ) 930 { 931 ScDrawTextCursor* pRet = NULL; 932 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY ); 933 if (xUT.is()) 934 pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId()))); 935 return pRet; 936 } 937 938 //------------------------------------------------------------------------ 939 940 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper() 941 { 942 SfxItemPool* pEnginePool = EditEngine::CreatePool(); 943 pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM ); 944 pEnginePool->FreezeIdRanges(); 945 946 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); // TRUE: become owner of pool 947 pForwarder = new SvxEditEngineForwarder( *pEditEngine ); 948 pOriginalSource = new ScSimpleEditSource( pForwarder ); 949 } 950 951 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper() 952 { 953 ScUnoGuard aGuard; // needed for EditEngine dtor 954 955 delete pOriginalSource; 956 delete pForwarder; 957 delete pEditEngine; 958 } 959 960 ScEditEngineTextObj::ScEditEngineTextObj() : 961 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() ) 962 { 963 } 964 965 ScEditEngineTextObj::~ScEditEngineTextObj() throw() 966 { 967 } 968 969 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject ) 970 { 971 GetEditEngine()->SetText( rTextObject ); 972 973 ESelection aSel; 974 ::GetSelection( aSel, GetEditSource()->GetTextForwarder() ); 975 SetSelection( aSel ); 976 } 977 978 EditTextObject* ScEditEngineTextObj::CreateTextObject() 979 { 980 return GetEditEngine()->CreateTextObject(); 981 } 982 983 //------------------------------------------------------------------------ 984 985 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) : 986 pDocShell( pDocSh ), 987 aCellPos( rP ), 988 pEditEngine( NULL ), 989 pForwarder( NULL ), 990 pOriginalSource( NULL ), 991 bDataValid( sal_False ), 992 bInUpdate( sal_False ), 993 bDirty( sal_False ), 994 bDoUpdate( sal_True ) 995 { 996 if (pDocShell) 997 pDocShell->GetDocument()->AddUnoObject(*this); 998 } 999 1000 ScCellTextData::~ScCellTextData() 1001 { 1002 ScUnoGuard aGuard; // needed for EditEngine dtor 1003 1004 if (pDocShell) 1005 { 1006 pDocShell->GetDocument()->RemoveUnoObject(*this); 1007 pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine); 1008 } 1009 else 1010 delete pEditEngine; 1011 1012 delete pForwarder; 1013 1014 delete pOriginalSource; 1015 } 1016 1017 ScSharedCellEditSource* ScCellTextData::GetOriginalSource() 1018 { 1019 if (!pOriginalSource) 1020 pOriginalSource = new ScSharedCellEditSource( this ); 1021 return pOriginalSource; 1022 } 1023 1024 void ScCellTextData::GetCellText(const ScAddress& rCellPos, String& rText) 1025 { 1026 if (pDocShell) 1027 { 1028 ScDocument* pDoc = pDocShell->GetDocument(); 1029 pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText ); 1030 } 1031 } 1032 1033 SvxTextForwarder* ScCellTextData::GetTextForwarder() 1034 { 1035 if (!pEditEngine) 1036 { 1037 if ( pDocShell ) 1038 { 1039 ScDocument* pDoc = pDocShell->GetDocument(); 1040 pEditEngine = pDoc->CreateFieldEditEngine(); 1041 } 1042 else 1043 { 1044 SfxItemPool* pEnginePool = EditEngine::CreatePool(); 1045 pEnginePool->FreezeIdRanges(); 1046 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); 1047 } 1048 // currently, GetPortions doesn't work if UpdateMode is sal_False, 1049 // this will be fixed (in EditEngine) by src600 1050 // pEditEngine->SetUpdateMode( sal_False ); 1051 pEditEngine->EnableUndo( sal_False ); 1052 if (pDocShell) 1053 pEditEngine->SetRefDevice(pDocShell->GetRefDevice()); 1054 else 1055 pEditEngine->SetRefMapMode( MAP_100TH_MM ); 1056 pForwarder = new SvxEditEngineForwarder(*pEditEngine); 1057 } 1058 1059 if (bDataValid) 1060 return pForwarder; 1061 1062 String aText; 1063 1064 if (pDocShell) 1065 { 1066 ScDocument* pDoc = pDocShell->GetDocument(); 1067 1068 SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() ); 1069 if( const ScPatternAttr* pPattern = 1070 pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) ) 1071 { 1072 pPattern->FillEditItemSet( &aDefaults ); 1073 pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading) 1074 } 1075 1076 const ScBaseCell* pCell = pDoc->GetCell( aCellPos ); 1077 if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT ) 1078 pEditEngine->SetTextNewDefaults( *((const ScEditCell*)pCell)->GetData(), aDefaults ); 1079 else 1080 { 1081 GetCellText( aCellPos, aText ); 1082 if (aText.Len()) 1083 pEditEngine->SetTextNewDefaults( aText, aDefaults ); 1084 else 1085 pEditEngine->SetDefaults(aDefaults); 1086 } 1087 } 1088 1089 bDataValid = sal_True; 1090 return pForwarder; 1091 } 1092 1093 void ScCellTextData::UpdateData() 1094 { 1095 if ( bDoUpdate ) 1096 { 1097 DBG_ASSERT(pEditEngine != NULL, "no EditEngine for UpdateData()"); 1098 if ( pDocShell && pEditEngine ) 1099 { 1100 // during the own UpdateData call, bDataValid must not be reset, 1101 // or things like attributes after the text would be lost 1102 // (are not stored in the cell) 1103 1104 bInUpdate = sal_True; // prevents bDataValid from being reset 1105 1106 ScDocFunc aFunc(*pDocShell); 1107 aFunc.PutData( aCellPos, *pEditEngine, sal_False, sal_True ); // always as text 1108 1109 bInUpdate = sal_False; 1110 bDirty = sal_False; 1111 } 1112 } 1113 else 1114 bDirty = sal_True; 1115 } 1116 1117 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint ) 1118 { 1119 if ( rHint.ISA( ScUpdateRefHint ) ) 1120 { 1121 // const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint; 1122 1123 //! Ref-Update 1124 } 1125 else if ( rHint.ISA( SfxSimpleHint ) ) 1126 { 1127 sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId(); 1128 if ( nId == SFX_HINT_DYING ) 1129 { 1130 pDocShell = NULL; // invalid now 1131 1132 DELETEZ( pForwarder ); 1133 DELETEZ( pEditEngine ); // EditEngine uses document's pool 1134 } 1135 else if ( nId == SFX_HINT_DATACHANGED ) 1136 { 1137 if (!bInUpdate) // not for own UpdateData calls 1138 bDataValid = sal_False; // text has to be read from the cell again 1139 } 1140 } 1141 } 1142 1143 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) : 1144 ScCellTextData( pDocSh, rP ), 1145 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() ) 1146 { 1147 } 1148 1149 ScCellTextObj::~ScCellTextObj() throw() 1150 { 1151 } 1152 1153