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