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_sw.hxx" 26 27 28 #include <hintids.hxx> 29 30 #include <editeng/tstpitem.hxx> 31 #include <editeng/lrspitem.hxx> 32 #include <editeng/scripttypeitem.hxx> 33 #include <com/sun/star/i18n/ScriptType.hdl> 34 #include <txatbase.hxx> 35 #include <txtftn.hxx> 36 #include <fmtftn.hxx> 37 #include <editsh.hxx> 38 #include <edimp.hxx> // fuer MACROS 39 #include <doc.hxx> 40 #include <swundo.hxx> // fuer UNDO-Ids 41 #include <ndtxt.hxx> 42 #include <ftnidx.hxx> 43 #include <expfld.hxx> 44 #include <rootfrm.hxx> 45 #include <cntfrm.hxx> 46 #include <breakit.hxx> 47 #include <txtfld.hxx> 48 #include <fmtfld.hxx> 49 #include <crsskip.hxx> 50 #include <txtfrm.hxx> // SwTxtFrm 51 #include <scriptinfo.hxx> 52 #include <svl/ctloptions.hxx> 53 #include <charfmt.hxx> // #i27615# 54 #include <numrule.hxx> 55 56 57 /************************************* 58 * harte Formatierung (Attribute) 59 *************************************/ 60 61 // wenn Selektion groesser Max Nodes oder mehr als Max Selektionen 62 // => keine Attribute 63 const sal_uInt16& getMaxLookup() 64 { 65 static const sal_uInt16 nMaxLookup = 1000; 66 return nMaxLookup; 67 } 68 69 // --> OD 2008-01-16 #newlistlevelattrs# 70 sal_Bool SwEditShell::GetCurAttr( SfxItemSet& rSet, 71 const bool bMergeIndentValuesOfNumRule ) const 72 // <-- 73 { 74 if( GetCrsrCnt() > getMaxLookup() ) 75 { 76 rSet.InvalidateAllItems(); 77 return sal_False; 78 } 79 80 SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() ); 81 SfxItemSet *pSet = &rSet; 82 83 FOREACHPAM_START(this) 84 85 // #i27615# if the cursor is in front of the numbering label 86 // the attributes to get are those from the numbering format. 87 if (PCURCRSR->IsInFrontOfLabel()) 88 { 89 SwTxtNode * pTxtNd = 90 PCURCRSR->GetPoint()->nNode.GetNode().GetTxtNode(); 91 92 if (pTxtNd) 93 { 94 SwNumRule * pNumRule = pTxtNd->GetNumRule(); 95 96 if (pNumRule) 97 { 98 const String & aCharFmtName = 99 pNumRule->Get(static_cast<sal_uInt16>(pTxtNd->GetActualListLevel())).GetCharFmtName(); 100 SwCharFmt * pCharFmt = 101 GetDoc()->FindCharFmtByName(aCharFmtName); 102 103 if (pCharFmt) 104 rSet.Put(pCharFmt->GetAttrSet()); 105 } 106 } 107 108 continue; 109 } 110 111 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(), 112 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex(); 113 xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(), 114 nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex(); 115 116 if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt )) 117 { 118 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; 119 nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp; 120 } 121 122 if( nEndNd - nSttNd >= getMaxLookup() ) 123 { 124 rSet.ClearItem(); 125 rSet.InvalidateAllItems(); 126 return sal_False; 127 } 128 129 // beim 1.Node traegt der Node die Werte in den GetSet ein (Initial) 130 // alle weiteren Nodes werden zum GetSet zu gemergt 131 for( sal_uLong n = nSttNd; n <= nEndNd; ++n ) 132 { 133 SwNode* pNd = GetDoc()->GetNodes()[ n ]; 134 switch( pNd->GetNodeType() ) 135 { 136 case ND_TEXTNODE: 137 { 138 xub_StrLen nStt = n == nSttNd ? nSttCnt : 0, 139 nEnd = n == nEndNd ? nEndCnt 140 : ((SwTxtNode*)pNd)->GetTxt().Len(); 141 // --> OD 2008-01-16 #newlistlevelattrs# 142 ((SwTxtNode*)pNd)->GetAttr( *pSet, nStt, nEnd, 143 sal_False, sal_True, 144 bMergeIndentValuesOfNumRule ); 145 // <-- 146 } 147 break; 148 case ND_GRFNODE: 149 case ND_OLENODE: 150 ((SwCntntNode*)pNd)->GetAttr( *pSet ); 151 break; 152 153 default: 154 pNd = 0; 155 } 156 157 if( pNd ) 158 { 159 if( pSet != &rSet ) 160 rSet.MergeValues( aSet ); 161 162 if( aSet.Count() ) 163 aSet.ClearItem(); 164 } 165 pSet = &aSet; 166 } 167 168 FOREACHPAM_END() 169 170 return sal_True; 171 } 172 173 SwTxtFmtColl* SwEditShell::GetCurTxtFmtColl() const 174 { 175 SwTxtFmtColl *pFmt = 0; 176 177 if ( GetCrsrCnt() > getMaxLookup() ) 178 return 0; 179 180 FOREACHPAM_START(this) 181 182 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(), 183 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex(); 184 xub_StrLen nSttCnt = PCURCRSR->GetMark()->nContent.GetIndex(), 185 nEndCnt = PCURCRSR->GetPoint()->nContent.GetIndex(); 186 187 if( nSttNd > nEndNd || ( nSttNd == nEndNd && nSttCnt > nEndCnt )) 188 { 189 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; 190 nTmp = nSttCnt; nSttCnt = nEndCnt; nEndCnt = (xub_StrLen)nTmp; 191 } 192 193 if( nEndNd - nSttNd >= getMaxLookup() ) 194 { 195 pFmt = 0; 196 break; 197 } 198 199 for( sal_uLong n = nSttNd; n <= nEndNd; ++n ) 200 { 201 SwNode* pNd = GetDoc()->GetNodes()[ n ]; 202 if( pNd->IsTxtNode() ) 203 { 204 if( !pFmt ) 205 pFmt = ((SwTxtNode*)pNd)->GetTxtColl(); 206 else if( pFmt == ((SwTxtNode*)pNd)->GetTxtColl() ) // ??? 207 break; 208 } 209 } 210 211 FOREACHPAM_END() 212 return pFmt; 213 } 214 215 216 217 sal_Bool SwEditShell::GetCurFtn( SwFmtFtn* pFillFtn ) 218 { 219 // der Cursor muss auf dem akt. Fussnoten-Anker stehen: 220 SwPaM* pCrsr = GetCrsr(); 221 SwTxtNode* pTxtNd = pCrsr->GetNode()->GetTxtNode(); 222 if( !pTxtNd ) 223 return sal_False; 224 225 SwTxtAttr *const pFtn = pTxtNd->GetTxtAttrForCharAt( 226 pCrsr->GetPoint()->nContent.GetIndex(), RES_TXTATR_FTN); 227 if( pFtn && pFillFtn ) 228 { 229 // Daten vom Attribut uebertragen 230 const SwFmtFtn &rFtn = ((SwTxtFtn*)pFtn)->GetFtn(); 231 pFillFtn->SetNumber( rFtn ); 232 pFillFtn->SetEndNote( rFtn.IsEndNote() ); 233 } 234 return 0 != pFtn; 235 } 236 237 238 bool SwEditShell::SetCurFtn( const SwFmtFtn& rFillFtn ) 239 { 240 bool bChgd = false; 241 StartAllAction(); 242 243 SwPaM* pCrsr = GetCrsr(), *pFirst = pCrsr; 244 do { 245 bChgd |= 246 pDoc->SetCurFtn( *pCrsr, rFillFtn.GetNumStr(), rFillFtn.GetNumber(), rFillFtn.IsEndNote() ); 247 248 } while( pFirst != ( pCrsr = (SwPaM*)pCrsr->GetNext() )); 249 250 EndAllAction(); 251 return bChgd; 252 } 253 254 255 256 /*sal_uInt16 SwEditShell::GetFtnCnt( sal_Bool bEndNotes = sal_False ) const 257 { 258 const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs(); 259 sal_uInt16 nCnt = 0; 260 for ( sal_uInt16 i = 0; i < rIdxs.Count(); ++i ) 261 { 262 const SwFmtFtn &rFtn = rIdxs[i]->GetFtn(); 263 if ( bEndNotes == rFtn.IsEndNote() ) 264 nCnt++; 265 } 266 return nCnt; 267 } */ 268 269 270 bool SwEditShell::HasFtns( bool bEndNotes ) const 271 { 272 const SwFtnIdxs &rIdxs = pDoc->GetFtnIdxs(); 273 for ( sal_uInt16 i = 0; i < rIdxs.Count(); ++i ) 274 { 275 const SwFmtFtn &rFtn = rIdxs[i]->GetFtn(); 276 if ( bEndNotes == rFtn.IsEndNote() ) 277 return sal_True; 278 } 279 return sal_False; 280 } 281 282 283 // gebe Liste aller Fussnoten und deren Anfangstexte 284 sal_uInt16 SwEditShell::GetSeqFtnList( SwSeqFldList& rList, bool bEndNotes ) 285 { 286 if( rList.Count() ) 287 rList.Remove( 0, rList.Count() ); 288 289 sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().Count(); 290 SwTxtFtn* pTxtFtn; 291 for( n = 0; n < nFtnCnt; ++n ) 292 { 293 pTxtFtn = pDoc->GetFtnIdxs()[ n ]; 294 const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); 295 if ( rFtn.IsEndNote() != bEndNotes ) 296 continue; 297 298 SwNodeIndex* pIdx = pTxtFtn->GetStartNode(); 299 if( pIdx ) 300 { 301 SwNodeIndex aIdx( *pIdx, 1 ); 302 SwTxtNode* pTxtNd = aIdx.GetNode().GetTxtNode(); 303 if( !pTxtNd ) 304 pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx ); 305 306 if( pTxtNd ) 307 { 308 String sTxt( rFtn.GetViewNumStr( *pDoc )); 309 if( sTxt.Len() ) 310 sTxt += ' '; 311 sTxt += pTxtNd->GetExpandTxt( 0, USHRT_MAX ); 312 313 _SeqFldLstElem* pNew = new _SeqFldLstElem( sTxt, 314 pTxtFtn->GetSeqRefNo() ); 315 while( rList.InsertSort( pNew ) ) 316 pNew->sDlgEntry += ' '; 317 } 318 } 319 } 320 321 return rList.Count(); 322 } 323 324 325 // linken Rand ueber Objectleiste einstellen (aenhlich dem Stufen von 326 // Numerierungen) 327 sal_Bool SwEditShell::IsMoveLeftMargin( sal_Bool bRight, sal_Bool bModulus ) const 328 { 329 sal_Bool bRet = sal_True; 330 331 const SvxTabStopItem& rTabItem = (SvxTabStopItem&)GetDoc()-> 332 GetDefault( RES_PARATR_TABSTOP ); 333 sal_uInt16 nDefDist = static_cast<sal_uInt16>(rTabItem.Count() ? rTabItem[0].GetTabPos() : 1134); 334 if( !nDefDist ) 335 return sal_False; 336 337 FOREACHPAM_START(this) 338 339 sal_uLong nSttNd = PCURCRSR->GetMark()->nNode.GetIndex(), 340 nEndNd = PCURCRSR->GetPoint()->nNode.GetIndex(); 341 342 if( nSttNd > nEndNd ) 343 { 344 sal_uLong nTmp = nSttNd; nSttNd = nEndNd; nEndNd = nTmp; 345 } 346 347 SwCntntNode* pCNd; 348 for( sal_uLong n = nSttNd; bRet && n <= nEndNd; ++n ) 349 if( 0 != ( pCNd = GetDoc()->GetNodes()[ n ]->GetTxtNode() )) 350 { 351 const SvxLRSpaceItem& rLS = (SvxLRSpaceItem&) 352 pCNd->GetAttr( RES_LR_SPACE ); 353 if( bRight ) 354 { 355 long nNext = rLS.GetTxtLeft() + nDefDist; 356 if( bModulus ) 357 nNext = ( nNext / nDefDist ) * nDefDist; 358 SwFrm* pFrm = pCNd->getLayoutFrm( GetLayout() ); 359 if ( pFrm ) 360 { 361 const sal_uInt16 nFrmWidth = static_cast<sal_uInt16>( pFrm->IsVertical() ? 362 pFrm->Frm().Height() : 363 pFrm->Frm().Width() ); 364 bRet = nFrmWidth > ( nNext + MM50 ); 365 } 366 else 367 bRet = sal_False; 368 } 369 } 370 371 if( !bRet ) 372 break; 373 374 FOREACHPAM_END() 375 return bRet; 376 } 377 378 void SwEditShell::MoveLeftMargin( sal_Bool bRight, sal_Bool bModulus ) 379 { 380 StartAllAction(); 381 StartUndo( UNDO_START ); 382 383 SwPaM* pCrsr = GetCrsr(); 384 if( pCrsr->GetNext() != pCrsr ) // Mehrfachselektion ? 385 { 386 SwPamRanges aRangeArr( *pCrsr ); 387 SwPaM aPam( *pCrsr->GetPoint() ); 388 for( sal_uInt16 n = 0; n < aRangeArr.Count(); ++n ) 389 GetDoc()->MoveLeftMargin( aRangeArr.SetPam( n, aPam ), 390 bRight, bModulus ); 391 } 392 else 393 GetDoc()->MoveLeftMargin( *pCrsr, bRight, bModulus ); 394 395 EndUndo( UNDO_END ); 396 EndAllAction(); 397 } 398 399 400 inline sal_uInt16 lcl_SetScriptFlags( sal_uInt16 nType ) 401 { 402 sal_uInt16 nRet; 403 switch( nType ) 404 { 405 case ::com::sun::star::i18n::ScriptType::LATIN: nRet = SCRIPTTYPE_LATIN; break; 406 case ::com::sun::star::i18n::ScriptType::ASIAN: nRet = SCRIPTTYPE_ASIAN; break; 407 case ::com::sun::star::i18n::ScriptType::COMPLEX: nRet = SCRIPTTYPE_COMPLEX; break; 408 default: nRet = 0; 409 } 410 return nRet; 411 } 412 413 sal_Bool lcl_IsNoEndTxtAttrAtPos( const SwTxtNode& rTNd, xub_StrLen nPos, 414 sal_uInt16 &rScrpt, sal_Bool bInSelection, sal_Bool bNum ) 415 { 416 sal_Bool bRet = sal_False; 417 const String& rTxt = rTNd.GetTxt(); 418 String sExp; 419 420 // consider numbering 421 if ( bNum ) 422 { 423 bRet = sal_False; 424 425 if ( rTNd.IsInList() ) 426 { 427 ASSERT( rTNd.GetNumRule(), 428 "<lcl_IsNoEndTxtAttrAtPos(..)> - no list style found at text node. Serious defect -> please inform OD." ); 429 const SwNumRule* pNumRule = rTNd.GetNumRule(); 430 //Modified for i119959,2012.6.12 431 //Under this scenario,this pointer is null,but on win,it doesn't crash immediately 432 //it exits with exception,and associated memory will have problem which leads to crash problem in 433 //other place in dev env... 434 if ( pNumRule ) 435 { 436 //End 437 const SwNumFmt &rNumFmt = pNumRule->Get( static_cast<sal_uInt16>(rTNd.GetActualListLevel()) ); 438 if( SVX_NUM_BITMAP != rNumFmt.GetNumberingType() ) 439 { 440 if ( SVX_NUM_CHAR_SPECIAL == rNumFmt.GetNumberingType() ) 441 sExp = rNumFmt.GetBulletChar(); 442 else 443 sExp = rTNd.GetNumString(); 444 } 445 //Modified for i119959,2012.6.12 446 //Under this scenario,this pointer is null,but on win,it doesn't crash immediately 447 //it exits with exception,and associated memory will have problem which leads to crash problem in 448 //other place in dev env... 449 } 450 //End 451 } 452 } 453 454 // and fields 455 if ( CH_TXTATR_BREAKWORD == rTxt.GetChar( nPos ) ) 456 { 457 const SwTxtAttr* const pAttr = rTNd.GetTxtAttrForCharAt( nPos ); 458 if (pAttr) 459 { 460 bRet = sal_True; // all other than fields can be 461 // defined as weak-script ? 462 if ( RES_TXTATR_FIELD == pAttr->Which() ) 463 { 464 const SwField* const pFld = pAttr->GetFmtFld().GetField(); 465 if (pFld) 466 { 467 sExp += pFld->ExpandField(true); 468 } 469 } 470 } 471 } 472 473 xub_StrLen nEnd = sExp.Len(); 474 if ( nEnd ) 475 { 476 xub_StrLen n; 477 if( bInSelection ) 478 { 479 sal_uInt16 nScript; 480 for( n = 0; n < nEnd; n = (xub_StrLen) 481 pBreakIt->GetBreakIter()->endOfScript( sExp, n, nScript )) 482 { 483 nScript = pBreakIt->GetBreakIter()->getScriptType( sExp, n ); 484 rScrpt |= lcl_SetScriptFlags( nScript ); 485 } 486 } 487 else 488 rScrpt |= lcl_SetScriptFlags( pBreakIt->GetBreakIter()-> 489 getScriptType( sExp, nEnd-1 )); 490 } 491 492 return bRet; 493 } 494 495 496 // returns the scripttpye of the selection 497 sal_uInt16 SwEditShell::GetScriptType() const 498 { 499 sal_uInt16 nRet = 0; 500 //if( pBreakIt->GetBreakIter().is() ) 501 { 502 FOREACHPAM_START(this) 503 504 const SwPosition *pStt = PCURCRSR->Start(), 505 *pEnd = pStt == PCURCRSR->GetMark() 506 ? PCURCRSR->GetPoint() 507 : PCURCRSR->GetMark(); 508 if( pStt == pEnd || *pStt == *pEnd ) 509 { 510 const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode(); 511 if( pTNd ) 512 { 513 // try to get SwScriptInfo 514 const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd ); 515 516 xub_StrLen nPos = pStt->nContent.GetIndex(); 517 //Task 90448: we need the scripttype of the previous 518 // position, if no selection exist! 519 if( nPos ) 520 { 521 SwIndex aIdx( pStt->nContent ); 522 if( pTNd->GoPrevious( &aIdx, CRSR_SKIP_CHARS ) ) 523 nPos = aIdx.GetIndex(); 524 } 525 526 sal_uInt16 nScript; 527 528 if ( pTNd->GetTxt().Len() ) 529 { 530 nScript = pScriptInfo ? 531 pScriptInfo->ScriptType( nPos ) : 532 pBreakIt->GetBreakIter()->getScriptType( pTNd->GetTxt(), nPos ); 533 } 534 else 535 nScript = GetI18NScriptTypeOfLanguage( (sal_uInt16)GetAppLanguage() ); 536 537 if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nPos, nRet, sal_False, sal_False )) 538 nRet |= lcl_SetScriptFlags( nScript ); 539 } 540 } 541 else if ( pBreakIt->GetBreakIter().is() ) 542 { 543 sal_uLong nEndIdx = pEnd->nNode.GetIndex(); 544 SwNodeIndex aIdx( pStt->nNode ); 545 for( ; aIdx.GetIndex() <= nEndIdx; aIdx++ ) 546 if( aIdx.GetNode().IsTxtNode() ) 547 { 548 const SwTxtNode* pTNd = aIdx.GetNode().GetTxtNode(); 549 const String& rTxt = pTNd->GetTxt(); 550 551 // try to get SwScriptInfo 552 const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd ); 553 554 xub_StrLen nChg = aIdx == pStt->nNode 555 ? pStt->nContent.GetIndex() 556 : 0, 557 nEndPos = aIdx == nEndIdx 558 ? pEnd->nContent.GetIndex() 559 : rTxt.Len(); 560 561 ASSERT( nEndPos <= rTxt.Len(), "Index outside the range - endless loop!" ); 562 if( nEndPos > rTxt.Len() ) 563 nEndPos = rTxt.Len(); 564 565 sal_uInt16 nScript; 566 while( nChg < nEndPos ) 567 { 568 nScript = pScriptInfo ? 569 pScriptInfo->ScriptType( nChg ) : 570 pBreakIt->GetBreakIter()->getScriptType( 571 rTxt, nChg ); 572 573 if( !lcl_IsNoEndTxtAttrAtPos( *pTNd, nChg, nRet, sal_True, 574 0 == nChg && rTxt.Len() == nEndPos ) ) 575 nRet |= lcl_SetScriptFlags( nScript ); 576 577 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | 578 SCRIPTTYPE_COMPLEX) == nRet ) 579 break; 580 581 xub_StrLen nFldPos = nChg+1; 582 583 nChg = pScriptInfo ? 584 pScriptInfo->NextScriptChg( nChg ) : 585 (xub_StrLen)pBreakIt->GetBreakIter()->endOfScript( 586 rTxt, nChg, nScript ); 587 588 nFldPos = rTxt.Search( 589 CH_TXTATR_BREAKWORD, nFldPos ); 590 if( nFldPos < nChg ) 591 nChg = nFldPos; 592 } 593 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | 594 SCRIPTTYPE_COMPLEX) == nRet ) 595 break; 596 } 597 } 598 if( (SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | 599 SCRIPTTYPE_COMPLEX) == nRet ) 600 break; 601 602 FOREACHPAM_END() 603 } 604 if( !nRet ) 605 nRet = SvtLanguageOptions::GetScriptTypeOfLanguage( LANGUAGE_SYSTEM ); 606 return nRet; 607 } 608 609 610 sal_uInt16 SwEditShell::GetCurLang() const 611 { 612 const SwPaM* pCrsr = GetCrsr(); 613 const SwPosition& rPos = *pCrsr->GetPoint(); 614 const SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode(); 615 sal_uInt16 nLang; 616 if( pTNd ) 617 { 618 //JP 24.9.2001: if exist no selection, then get the language before 619 // the current character! 620 xub_StrLen nPos = rPos.nContent.GetIndex(); 621 if( nPos && !pCrsr->HasMark() ) 622 --nPos; 623 nLang = pTNd->GetLang( nPos ); 624 } 625 else 626 nLang = LANGUAGE_DONTKNOW; 627 return nLang; 628 } 629 630 sal_uInt16 SwEditShell::GetScalingOfSelectedText() const 631 { 632 const SwPaM* pCrsr = GetCrsr(); 633 const SwPosition* pStt = pCrsr->Start(); 634 const SwTxtNode* pTNd = pStt->nNode.GetNode().GetTxtNode(); 635 ASSERT( pTNd, "no textnode available" ); 636 637 sal_uInt16 nScaleWidth; 638 if( pTNd ) 639 { 640 xub_StrLen nStt = pStt->nContent.GetIndex(), nEnd; 641 const SwPosition* pEnd = pStt == pCrsr->GetPoint() 642 ? pCrsr->GetMark() 643 : pCrsr->GetPoint(); 644 if( pStt->nNode == pEnd->nNode ) 645 nEnd = pEnd->nContent.GetIndex(); 646 else 647 nEnd = pTNd->GetTxt().Len(); 648 nScaleWidth = pTNd->GetScalingOfSelectedText( nStt, nEnd ); 649 } 650 else 651 nScaleWidth = 100; // default are no scaling -> 100% 652 return nScaleWidth; 653 } 654