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_sw.hxx" 30 31 #include <hintids.hxx> 32 #include <tools/list.hxx> 33 #include <tools/urlobj.hxx> 34 #include <vcl/cmdevt.hxx> 35 #include <unotools/charclass.hxx> 36 #include <comphelper/processfactory.hxx> 37 #include <unotools/transliterationwrapper.hxx> 38 #include <swwait.hxx> 39 #include <fmtsrnd.hxx> 40 #include <fmtinfmt.hxx> 41 #include <txtinet.hxx> 42 #include <frmfmt.hxx> 43 #include <charfmt.hxx> 44 #include <doc.hxx> 45 #include <IDocumentUndoRedo.hxx> 46 #include <docary.hxx> 47 #include <editsh.hxx> 48 #include <frame.hxx> 49 #include <cntfrm.hxx> 50 #include <pam.hxx> 51 #include <ndtxt.hxx> // fuer SwTxtNode 52 #include <grfatr.hxx> 53 #include <flyfrm.hxx> 54 #include <swtable.hxx> 55 #include <swundo.hxx> // UNDO_START, UNDO_END 56 #include <calc.hxx> 57 #include <edimp.hxx> 58 #include <ndgrf.hxx> 59 #include <ndole.hxx> 60 #include <txtfrm.hxx> 61 #include <rootfrm.hxx> 62 #include <extinput.hxx> 63 #include <crsskip.hxx> 64 #include <scriptinfo.hxx> 65 #include <unocrsrhelper.hxx> 66 #include <section.hxx> 67 #include <unochart.hxx> 68 #include <numrule.hxx> 69 #include <SwNodeNum.hxx> 70 #include <unocrsr.hxx> 71 #include <switerator.hxx> 72 73 using namespace com::sun::star; 74 75 76 SV_IMPL_PTRARR(SwGetINetAttrs, SwGetINetAttr*) 77 78 /****************************************************************************** 79 * void SwEditShell::Insert(char c) 80 ******************************************************************************/ 81 82 83 void SwEditShell::Insert( sal_Unicode c, sal_Bool bOnlyCurrCrsr ) 84 { 85 StartAllAction(); 86 FOREACHPAM_START(this) 87 88 const bool bSuccess = GetDoc()->InsertString(*PCURCRSR, c); 89 ASSERT( bSuccess, "Doc->Insert() failed." ); 90 (void) bSuccess; 91 92 SaveTblBoxCntnt( PCURCRSR->GetPoint() ); 93 if( bOnlyCurrCrsr ) 94 break; 95 96 FOREACHPAM_END() 97 98 EndAllAction(); 99 } 100 101 102 /****************************************************************************** 103 * void SwEditShell::Insert(const String &rStr) 104 ******************************************************************************/ 105 106 107 void SwEditShell::Insert2(const String &rStr, const bool bForceExpandHints ) 108 { 109 StartAllAction(); 110 { 111 const enum IDocumentContentOperations::InsertFlags nInsertFlags = 112 (bForceExpandHints) 113 ? static_cast<IDocumentContentOperations::InsertFlags>( 114 IDocumentContentOperations::INS_FORCEHINTEXPAND | 115 IDocumentContentOperations::INS_EMPTYEXPAND) 116 : IDocumentContentOperations::INS_EMPTYEXPAND; 117 118 SwPaM *_pStartCrsr = getShellCrsr( true ), *__pStartCrsr = _pStartCrsr; 119 do { 120 //OPT: GetSystemCharSet 121 const bool bSuccess = 122 GetDoc()->InsertString(*_pStartCrsr, rStr, nInsertFlags); 123 ASSERT( bSuccess, "Doc->Insert() failed." ); 124 (void) bSuccess; 125 126 SaveTblBoxCntnt( _pStartCrsr->GetPoint() ); 127 128 } while( (_pStartCrsr=(SwPaM *)_pStartCrsr->GetNext()) != __pStartCrsr ); 129 } 130 131 // calculate cursor bidi level 132 SwCursor* pTmpCrsr = _GetCrsr(); 133 const sal_Bool bDoNotSetBidiLevel = ! pTmpCrsr || 134 ( 0 != dynamic_cast<SwUnoCrsr*>(pTmpCrsr) ); 135 136 if ( ! bDoNotSetBidiLevel ) 137 { 138 SwNode& rNode = pTmpCrsr->GetPoint()->nNode.GetNode(); 139 if ( rNode.IsTxtNode() ) 140 { 141 SwIndex& rIdx = pTmpCrsr->GetPoint()->nContent; 142 xub_StrLen nPos = rIdx.GetIndex(); 143 xub_StrLen nPrevPos = nPos; 144 if ( nPrevPos ) 145 --nPrevPos; 146 147 SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo( ((SwTxtNode&)rNode), 148 sal_True ); 149 150 sal_uInt8 nLevel = 0; 151 if ( ! pSI ) 152 { 153 // seems to be an empty paragraph. 154 Point aPt; 155 SwCntntFrm* pFrm = 156 ((SwTxtNode&)rNode).getLayoutFrm( GetLayout(), &aPt, pTmpCrsr->GetPoint(), 157 sal_False ); 158 159 SwScriptInfo aScriptInfo; 160 aScriptInfo.InitScriptInfo( (SwTxtNode&)rNode, pFrm->IsRightToLeft() ); 161 nLevel = aScriptInfo.DirType( nPrevPos ); 162 } 163 else 164 { 165 if ( STRING_LEN != pSI->GetInvalidity() ) 166 pSI->InitScriptInfo( (SwTxtNode&)rNode ); 167 nLevel = pSI->DirType( nPrevPos ); 168 } 169 170 pTmpCrsr->SetCrsrBidiLevel( nLevel ); 171 } 172 } 173 174 SetInFrontOfLabel( sal_False ); // #i27615# 175 176 EndAllAction(); 177 } 178 179 180 /****************************************************************************** 181 * void SwEditShell::Overwrite(const String &rStr) 182 ******************************************************************************/ 183 184 185 void SwEditShell::Overwrite(const String &rStr) 186 { 187 StartAllAction(); 188 FOREACHPAM_START(this) 189 if( !GetDoc()->Overwrite(*PCURCRSR, rStr ) ) 190 { 191 ASSERT( sal_False, "Doc->Overwrite(Str) failed." ) 192 } 193 SaveTblBoxCntnt( PCURCRSR->GetPoint() ); 194 FOREACHPAM_END() 195 EndAllAction(); 196 } 197 198 199 /****************************************************************************** 200 * long SwEditShell::SplitNode() 201 ******************************************************************************/ 202 203 long SwEditShell::SplitNode( sal_Bool bAutoFormat, sal_Bool bCheckTableStart ) 204 { 205 StartAllAction(); 206 GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL); 207 208 FOREACHPAM_START(this) 209 // eine Tabellen Zelle wird jetzt zu einer normalen Textzelle! 210 GetDoc()->ClearBoxNumAttrs( PCURCRSR->GetPoint()->nNode ); 211 GetDoc()->SplitNode( *PCURCRSR->GetPoint(), bCheckTableStart ); 212 FOREACHPAM_END() 213 214 GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL); 215 216 if( bAutoFormat ) 217 AutoFmtBySplitNode(); 218 219 ClearTblBoxCntnt(); 220 221 EndAllAction(); 222 return(1L); 223 } 224 225 /*-- 11.05.2004 09:41:20--------------------------------------------------- 226 227 -----------------------------------------------------------------------*/ 228 sal_Bool SwEditShell::AppendTxtNode() 229 { 230 sal_Bool bRet = sal_False; 231 StartAllAction(); 232 GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL); 233 234 FOREACHPAM_START(this) 235 GetDoc()->ClearBoxNumAttrs( PCURCRSR->GetPoint()->nNode ); 236 bRet = GetDoc()->AppendTxtNode( *PCURCRSR->GetPoint()) || bRet; 237 FOREACHPAM_END() 238 239 GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL); 240 241 ClearTblBoxCntnt(); 242 243 EndAllAction(); 244 return bRet; 245 } 246 247 /****************************************************************************** 248 * liefert einen Pointer auf einen SwGrfNode; dieser wird von 249 * GetGraphic() und GetGraphicSize() verwendet. 250 ******************************************************************************/ 251 252 253 SwGrfNode * SwEditShell::_GetGrfNode() const 254 { 255 SwGrfNode *pGrfNode = 0; 256 SwPaM* pCrsr = GetCrsr(); 257 if( !pCrsr->HasMark() || 258 pCrsr->GetPoint()->nNode == pCrsr->GetMark()->nNode ) 259 pGrfNode = pCrsr->GetPoint()->nNode.GetNode().GetGrfNode(); 260 261 return pGrfNode; 262 } 263 /****************************************************************************** 264 * liefert Pointer auf eine Graphic, wenn CurCrsr->GetPoint() auf 265 * einen SwGrfNode zeigt (und GetMark nicht gesetzt ist 266 * oder auf die gleiche Graphic zeigt) 267 ******************************************************************************/ 268 269 // --> OD 2005-02-09 #119353# - robust 270 const Graphic* SwEditShell::GetGraphic( sal_Bool bWait ) const 271 { 272 SwGrfNode* pGrfNode = _GetGrfNode(); 273 // --> OD 2005-02-09 #119353# - robust 274 const Graphic* pGrf( 0L ); 275 if ( pGrfNode ) 276 { 277 pGrf = &(pGrfNode->GetGrf()); 278 // --> OD 2007-03-01 #i73788# 279 // no load of linked graphic, if its not needed now (bWait = sal_False). 280 if ( bWait ) 281 { 282 if( pGrf->IsSwapOut() || 283 ( pGrfNode->IsLinkedFile() && GRAPHIC_DEFAULT == pGrf->GetType() ) ) 284 { 285 #ifdef DBG_UTIL 286 ASSERT( pGrfNode->SwapIn( bWait ) || !bWait, "Grafik konnte nicht geladen werden" ); 287 #else 288 pGrfNode->SwapIn( bWait ); 289 #endif 290 } 291 } 292 else 293 { 294 if ( pGrf->IsSwapOut() && !pGrfNode->IsLinkedFile() ) 295 { 296 #ifdef DBG_UTIL 297 ASSERT( pGrfNode->SwapIn( bWait ) || !bWait, "Grafik konnte nicht geladen werden" ); 298 #else 299 pGrfNode->SwapIn( bWait ); 300 #endif 301 } 302 } 303 // <-- 304 } 305 return pGrf; 306 // <-- 307 } 308 309 sal_Bool SwEditShell::IsGrfSwapOut( sal_Bool bOnlyLinked ) const 310 { 311 SwGrfNode *pGrfNode = _GetGrfNode(); 312 return pGrfNode && 313 (bOnlyLinked ? ( pGrfNode->IsLinkedFile() && 314 ( GRAPHIC_DEFAULT == pGrfNode->GetGrfObj().GetType()|| 315 pGrfNode->GetGrfObj().IsSwappedOut())) 316 : pGrfNode->GetGrfObj().IsSwappedOut()); 317 } 318 319 // --> OD 2005-02-09 #119353# - robust 320 const GraphicObject* SwEditShell::GetGraphicObj() const 321 { 322 SwGrfNode* pGrfNode = _GetGrfNode(); 323 // --> OD 2005-02-09 #119353# - robust 324 return pGrfNode ? &(pGrfNode->GetGrfObj()) : 0L; 325 // <-- 326 } 327 328 sal_uInt16 SwEditShell::GetGraphicType() const 329 { 330 SwGrfNode *pGrfNode = _GetGrfNode(); 331 return static_cast<sal_uInt16>(pGrfNode ? pGrfNode->GetGrfObj().GetType() : GRAPHIC_NONE); 332 } 333 334 /****************************************************************************** 335 * liefert die Groesse der Graphic, wenn CurCrsr->GetPoint() auf 336 * einen SwGrfNode zeigt (und GetMark nicht gesetzt ist 337 * oder auf die gleiche Graphic zeigt) 338 ******************************************************************************/ 339 340 sal_Bool SwEditShell::GetGrfSize(Size& rSz) const 341 { 342 SwNoTxtNode* pNoTxtNd; 343 SwPaM* pCurrentCrsr = GetCrsr(); 344 if( ( !pCurrentCrsr->HasMark() 345 || pCurrentCrsr->GetPoint()->nNode == pCurrentCrsr->GetMark()->nNode ) 346 && 0 != ( pNoTxtNd = pCurrentCrsr->GetNode()->GetNoTxtNode() ) ) 347 { 348 rSz = pNoTxtNd->GetTwipSize(); 349 return sal_True; 350 } 351 return sal_False; 352 353 } 354 /****************************************************************************** 355 * erneutes Einlesen, falls Graphic nicht Ok ist. Die 356 * aktuelle wird durch die neue ersetzt. 357 ******************************************************************************/ 358 359 void SwEditShell::ReRead( const String& rGrfName, const String& rFltName, 360 const Graphic* pGraphic, const GraphicObject* pGrfObj ) 361 { 362 StartAllAction(); 363 pDoc->ReRead( *GetCrsr(), rGrfName, rFltName, pGraphic, pGrfObj ); 364 EndAllAction(); 365 } 366 367 368 /****************************************************************************** 369 * liefert den Namen und den FilterNamen einer Graphic, wenn der Cursor 370 * auf einer Graphic steht 371 * Ist ein String-Ptr != 0 dann returne den entsp. Namen 372 ******************************************************************************/ 373 374 375 void SwEditShell::GetGrfNms( String* pGrfName, String* pFltName, 376 const SwFlyFrmFmt* pFmt ) const 377 { 378 ASSERT( pGrfName || pFltName, "was wird denn nun erfragt?" ); 379 if( pFmt ) 380 GetDoc()->GetGrfNms( *pFmt, pGrfName, pFltName ); 381 else 382 { 383 SwGrfNode *pGrfNode = _GetGrfNode(); 384 if( pGrfNode && pGrfNode->IsLinkedFile() ) 385 pGrfNode->GetFileFilterNms( pGrfName, pFltName ); 386 } 387 } 388 389 390 // alternativen Text abfragen/setzen 391 //const String& SwEditShell::GetAlternateText() const 392 //{ 393 // SwPaM* pCrsr = GetCrsr(); 394 // const SwNoTxtNode* pNd; 395 // if( !pCrsr->HasMark() && 0 != ( pNd = pCrsr->GetNode()->GetNoTxtNode()) ) 396 // return pNd->GetAlternateText(); 397 398 // return aEmptyStr; 399 //} 400 401 402 //void SwEditShell::SetAlternateText( const String& rTxt ) 403 //{ 404 // SwPaM* pCrsr = GetCrsr(); 405 // SwNoTxtNode* pNd; 406 // if( !pCrsr->HasMark() && 0 != ( pNd = pCrsr->GetNode()->GetNoTxtNode()) ) 407 // { 408 // pNd->SetAlternateText( rTxt, sal_True ); 409 // GetDoc()->SetModified(); 410 // } 411 //} 412 413 414 const PolyPolygon *SwEditShell::GetGraphicPolygon() const 415 { 416 SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode(); 417 return pNd->HasContour(); 418 } 419 420 421 void SwEditShell::SetGraphicPolygon( const PolyPolygon *pPoly ) 422 { 423 SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode(); 424 StartAllAction(); 425 pNd->SetContour( pPoly ); 426 SwFlyFrm *pFly = (SwFlyFrm*)pNd->getLayoutFrm(GetLayout())->GetUpper(); 427 const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround(); 428 pFly->GetFmt()->NotifyClients( (SwFmtSurround*)&rSur, (SwFmtSurround*)&rSur ); 429 GetDoc()->SetModified(); 430 EndAllAction(); 431 } 432 433 void SwEditShell::ClearAutomaticContour() 434 { 435 SwNoTxtNode *pNd = GetCrsr()->GetNode()->GetNoTxtNode(); 436 ASSERT( pNd, "is no NoTxtNode!" ); 437 if( pNd->HasAutomaticContour() ) 438 { 439 StartAllAction(); 440 pNd->SetContour( NULL, sal_False ); 441 SwFlyFrm *pFly = (SwFlyFrm*)pNd->getLayoutFrm(GetLayout())->GetUpper(); 442 const SwFmtSurround &rSur = pFly->GetFmt()->GetSurround(); 443 pFly->GetFmt()->NotifyClients( (SwFmtSurround*)&rSur, (SwFmtSurround*)&rSur ); 444 GetDoc()->SetModified(); 445 EndAllAction(); 446 } 447 } 448 449 /****************************************************************************** 450 * liefert Pointer auf ein SvInPlaceObjectRef, wenn CurCrsr->GetPoint() auf 451 * einen SwOLENode zeigt (und GetMark nicht gesetzt ist 452 * oder auf das gleiche SvInPlaceObjectRef zeigt) 453 * besorgt den Pointer vom Doc wenn das Objekt per Namen gesucht werden 454 * soll 455 ******************************************************************************/ 456 457 svt::EmbeddedObjectRef& SwEditShell::GetOLEObject() const 458 { 459 ASSERT( CNT_OLE == GetCntType(), "GetOLEObj: kein OLENode." ); 460 ASSERT( !GetCrsr()->HasMark() || 461 (GetCrsr()->HasMark() && 462 GetCrsr()->GetPoint()->nNode == GetCrsr()->GetMark()->nNode), 463 "GetOLEObj: kein OLENode." ); 464 465 SwOLENode *pOLENode = GetCrsr()->GetNode()->GetOLENode(); 466 ASSERT( pOLENode, "GetOLEObj: kein OLENode." ); 467 SwOLEObj& rOObj = pOLENode->GetOLEObj(); 468 return rOObj.GetObject(); 469 } 470 471 472 sal_Bool SwEditShell::HasOLEObj( const String &rName ) const 473 { 474 SwStartNode *pStNd; 475 SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 ); 476 while ( 0 != (pStNd = aIdx.GetNode().GetStartNode()) ) 477 { 478 aIdx++; 479 SwNode& rNd = aIdx.GetNode(); 480 if( rNd.IsOLENode() && 481 rName == ((SwOLENode&)rNd).GetChartTblName() && 482 ((SwOLENode&)rNd).getLayoutFrm( GetLayout() ) ) 483 return sal_True; 484 485 aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 ); 486 } 487 return sal_False; 488 } 489 490 491 void SwEditShell::SetChartName( const String &rName ) 492 { 493 SwOLENode *pONd = GetCrsr()->GetNode()->GetOLENode(); 494 ASSERT( pONd, "ChartNode not found" ); 495 pONd->SetChartTblName( rName ); 496 } 497 498 void SwEditShell::UpdateCharts( const String &rName ) 499 { 500 GetDoc()->UpdateCharts( rName ); 501 } 502 503 504 /****************************************************************************** 505 * Aenderung des Tabellennamens 506 ******************************************************************************/ 507 508 void SwEditShell::SetTableName( SwFrmFmt& rTblFmt, const String &rNewName ) 509 { 510 GetDoc()->SetTableName( rTblFmt, rNewName ); 511 } 512 513 // erfragen des akt. Wortes 514 515 String SwEditShell::GetCurWord() 516 { 517 const SwPaM& rPaM = *GetCrsr(); 518 const SwTxtNode* pNd = rPaM.GetNode()->GetTxtNode(); 519 String aString = pNd ? 520 pNd->GetCurWord(rPaM.GetPoint()->nContent.GetIndex()) : 521 aEmptyStr; 522 return aString; 523 } 524 525 /**************************************************************************** 526 * void SwEditShell::UpdateDocStat( SwDocStat& rStat ) 527 ****************************************************************************/ 528 529 530 void SwEditShell::UpdateDocStat( SwDocStat& rStat ) 531 { 532 StartAllAction(); 533 GetDoc()->UpdateDocStat( rStat ); 534 EndAllAction(); 535 } 536 537 // OPT: eddocinl.cxx 538 539 540 // returne zum Namen die im Doc gesetzte Referenz 541 const SwFmtRefMark* SwEditShell::GetRefMark( const String& rName ) const 542 { 543 return GetDoc()->GetRefMark( rName ); 544 } 545 546 // returne die Namen aller im Doc gesetzten Referenzen 547 sal_uInt16 SwEditShell::GetRefMarks( SvStringsDtor* pStrings ) const 548 { 549 return GetDoc()->GetRefMarks( pStrings ); 550 } 551 552 /****************************************************************************** 553 * DropCap-SS 554 ******************************************************************************/ 555 556 557 String SwEditShell::GetDropTxt( const sal_uInt16 nChars ) const 558 { 559 /** 560 * pb: made changes for #i74939# 561 * 562 * always return a string even though there is a selection 563 */ 564 565 String aTxt; 566 SwPaM* pCrsr = GetCrsr(); 567 if ( IsMultiSelection() ) 568 { 569 // if a multi selection exists, search for the first line 570 // -> it is the cursor with the lowest index 571 sal_uLong nIndex = pCrsr->GetMark()->nNode.GetIndex(); 572 bool bPrev = true; 573 SwPaM* pLast = pCrsr; 574 SwPaM* pTemp = pCrsr; 575 while ( bPrev ) 576 { 577 SwPaM* pPrev2 = dynamic_cast< SwPaM* >( pTemp->GetPrev() ); 578 bPrev = ( pPrev2 && pPrev2 != pLast ); 579 if ( bPrev ) 580 { 581 pTemp = pPrev2; 582 sal_uLong nTemp = pPrev2->GetMark()->nNode.GetIndex(); 583 if ( nTemp < nIndex ) 584 { 585 nIndex = nTemp; 586 pCrsr = pPrev2; 587 } 588 } 589 } 590 } 591 592 SwTxtNode* pTxtNd = pCrsr->GetNode( !pCrsr->HasMark() )->GetTxtNode(); 593 if( pTxtNd ) 594 { 595 xub_StrLen nDropLen = pTxtNd->GetDropLen( nChars ); 596 if( nDropLen ) 597 aTxt = pTxtNd->GetTxt().Copy( 0, nDropLen ); 598 } 599 600 return aTxt; 601 } 602 603 void SwEditShell::ReplaceDropTxt( const String &rStr ) 604 { 605 SwPaM* pCrsr = GetCrsr(); 606 if( pCrsr->GetPoint()->nNode == pCrsr->GetMark()->nNode && 607 pCrsr->GetNode()->GetTxtNode()->IsTxtNode() ) 608 { 609 StartAllAction(); 610 611 const SwNodeIndex& rNd = pCrsr->GetPoint()->nNode; 612 SwPaM aPam( rNd, rStr.Len(), rNd, 0 ); 613 if( !GetDoc()->Overwrite( aPam, rStr ) ) 614 { 615 ASSERT( sal_False, "Doc->Overwrite(Str) failed." ); 616 } 617 618 EndAllAction(); 619 } 620 } 621 622 /****************************************************************************** 623 * Methode : 624 * Beschreibung: 625 * Erstellt : OK 25.04.94 13:45 626 * Aenderung : 627 ******************************************************************************/ 628 629 String SwEditShell::Calculate() 630 { 631 String aFormel; // die entgueltige Formel 632 SwPaM *pPaMLast = (SwPaM*)GetCrsr()->GetNext(), 633 *pPaM = pPaMLast; // die Pointer auf Cursor 634 SwCalc aCalc( *GetDoc() ); 635 const CharClass& rCC = GetAppCharClass(); 636 637 do { 638 SwTxtNode* pTxtNd = pPaM->GetNode()->GetTxtNode(); 639 if(pTxtNd) 640 { 641 const SwPosition *pStart = pPaM->Start(), *pEnd = pPaM->End(); 642 xub_StrLen nStt = pStart->nContent.GetIndex(); 643 String aStr = pTxtNd->GetExpandTxt( nStt, pEnd->nContent. 644 GetIndex() - nStt ); 645 646 rCC.toLower( aStr ); 647 648 sal_Unicode ch; 649 sal_Bool bValidFlds = sal_False; 650 xub_StrLen nPos = 0; 651 652 while( nPos < aStr.Len() ) 653 { 654 ch = aStr.GetChar( nPos++ ); 655 if( rCC.isLetter( aStr, nPos-1 ) || ch == '_' ) 656 { 657 xub_StrLen nTmpStt = nPos-1; 658 while( nPos < aStr.Len() && 659 0 != ( ch = aStr.GetChar( nPos++ )) && 660 (rCC.isLetterNumeric( aStr, nPos - 1 ) || 661 ch == '_'|| ch == '.' )) 662 ; 663 664 if( nPos < aStr.Len() ) 665 --nPos; 666 667 String sVar( aStr.Copy( nTmpStt, nPos - nTmpStt )); 668 if( !::FindOperator( sVar ) && 669 (::Find( sVar, aCalc.GetVarTable(),TBLSZ) || 670 aCalc.VarLook( sVar )) ) 671 { 672 if( !bValidFlds ) 673 { 674 GetDoc()->FldsToCalc( aCalc, 675 pStart->nNode.GetIndex(), 676 pStart->nContent.GetIndex() ); 677 bValidFlds = sal_True; 678 } 679 (( aFormel += '(' ) += 680 aCalc.GetStrResult( aCalc.VarLook( sVar ) 681 ->nValue )) += ')'; 682 } 683 else 684 aFormel += sVar; 685 } 686 else 687 aFormel += ch; 688 } 689 } 690 } while( pPaMLast != (pPaM = (SwPaM*)pPaM->GetNext()) ); 691 692 return aCalc.GetStrResult( aCalc.Calculate(aFormel) ); 693 } 694 695 696 sfx2::LinkManager& SwEditShell::GetLinkManager() 697 { 698 return pDoc->GetLinkManager(); 699 } 700 701 702 void *SwEditShell::GetIMapInventor() const 703 { 704 //Als eindeutige Identifikation sollte der Node, auf dem der Crsr steht 705 //genuegen. 706 return (void*)GetCrsr()->GetNode(); 707 } 708 709 // --> OD 2007-03-01 #i73788# 710 // remove default parameter, because method is always called this default value 711 Graphic SwEditShell::GetIMapGraphic() const 712 { 713 //Liefert immer eine Graphic, wenn der Crsr in einem Fly steht. 714 SET_CURR_SHELL( (ViewShell*)this ); 715 Graphic aRet; 716 SwPaM* pCrsr = GetCrsr(); 717 if ( !pCrsr->HasMark() ) 718 { 719 SwNode *pNd =pCrsr->GetNode(); 720 if( pNd->IsGrfNode() ) 721 { 722 const Graphic& rGrf = ((SwGrfNode*)pNd)->GetGrf(); 723 if( rGrf.IsSwapOut() || ( ((SwGrfNode*)pNd)->IsLinkedFile() && 724 GRAPHIC_DEFAULT == rGrf.GetType() ) ) 725 { 726 #ifdef DBG_UTIL 727 ASSERT( ((SwGrfNode*)pNd)->SwapIn( sal_True ) || !sal_True, "Grafik konnte nicht geladen werden" ); 728 #else 729 ((SwGrfNode*)pNd)->SwapIn( sal_True ); 730 #endif 731 } 732 aRet = rGrf; 733 } 734 else if ( pNd->IsOLENode() ) 735 { 736 aRet = *((SwOLENode*)pNd)->GetGraphic(); 737 } 738 else 739 { 740 SwFlyFrm* pFlyFrm = pNd->GetCntntNode()->getLayoutFrm( GetLayout() )->FindFlyFrm(); 741 if(pFlyFrm) 742 aRet = pFlyFrm->GetFmt()->MakeGraphic(); 743 } 744 } 745 return aRet; 746 } 747 748 749 sal_Bool SwEditShell::InsertURL( const SwFmtINetFmt& rFmt, const String& rStr, sal_Bool bKeepSelection ) 750 { 751 // URL und Hinweistext (direkt oder via Selektion) notwendig 752 if( !rFmt.GetValue().Len() || ( !rStr.Len() && !HasSelection() ) ) 753 return sal_False; 754 StartAllAction(); 755 GetDoc()->GetIDocumentUndoRedo().StartUndo( UNDO_UI_INSERT_URLTXT, NULL); 756 sal_Bool bInsTxt = sal_True; 757 758 if( rStr.Len() ) 759 { 760 SwPaM* pCrsr = GetCrsr(); 761 if( pCrsr->HasMark() && *pCrsr->GetPoint() != *pCrsr->GetMark() ) 762 { 763 // Selection vorhanden, MehrfachSelektion? 764 sal_Bool bDelTxt = sal_True; 765 if( pCrsr->GetNext() == pCrsr ) 766 { 767 // einfach Selection -> Text ueberpruefen 768 String sTxt( GetSelTxt() ); 769 sTxt.EraseTrailingChars(); 770 if( sTxt == rStr ) 771 bDelTxt = bInsTxt = sal_False; 772 } 773 else if( rFmt.GetValue() == rStr ) // Name und URL gleich? 774 bDelTxt = bInsTxt = sal_False; 775 776 if( bDelTxt ) 777 Delete(); 778 } 779 else if( pCrsr->GetNext() != pCrsr && rFmt.GetValue() == rStr ) 780 bInsTxt = sal_False; 781 782 if( bInsTxt ) 783 { 784 Insert2( rStr ); 785 SetMark(); 786 ExtendSelection( sal_False, rStr.Len() ); 787 } 788 } 789 else 790 bInsTxt = sal_False; 791 792 SetAttr( rFmt ); 793 if (bInsTxt && !IsCrsrPtAtEnd()) 794 SwapPam(); 795 if(!bKeepSelection) 796 ClearMark(); 797 if( bInsTxt ) 798 DontExpandFmt(); 799 GetDoc()->GetIDocumentUndoRedo().EndUndo( UNDO_UI_INSERT_URLTXT, NULL ); 800 EndAllAction(); 801 return sal_True; 802 } 803 804 805 sal_uInt16 SwEditShell::GetINetAttrs( SwGetINetAttrs& rArr ) 806 { 807 if( rArr.Count() ) 808 rArr.DeleteAndDestroy( 0, rArr.Count() ); 809 810 const SwTxtNode* pTxtNd; 811 const SwCharFmts* pFmts = GetDoc()->GetCharFmts(); 812 for( sal_uInt16 n = pFmts->Count(); 1 < n; ) 813 { 814 SwIterator<SwTxtINetFmt,SwCharFmt> aIter(*(*pFmts)[--n]); 815 for( SwTxtINetFmt* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() ) 816 { 817 if( 0 != ( pTxtNd = pFnd->GetpTxtNode()) && 818 pTxtNd->GetNodes().IsDocNodes() ) 819 { 820 SwTxtINetFmt& rAttr = *pFnd; 821 String sTxt( pTxtNd->GetExpandTxt( *rAttr.GetStart(), 822 *rAttr.GetEnd() - *rAttr.GetStart() ) ); 823 824 sTxt.EraseAllChars( 0x0a ); 825 sTxt.EraseLeadingChars().EraseTrailingChars(); 826 827 if( sTxt.Len() ) 828 { 829 SwGetINetAttr* pNew = new SwGetINetAttr( sTxt, rAttr ); 830 rArr.C40_INSERT( SwGetINetAttr, pNew, rArr.Count() ); 831 } 832 } 833 } 834 } 835 return rArr.Count(); 836 } 837 838 839 // ist der Cursor in eine INetAttribut, dann wird das komplett 840 // geloescht; inclusive des Hinweistextes (wird beim Drag&Drop gebraucht) 841 sal_Bool SwEditShell::DelINetAttrWithText() 842 { 843 sal_Bool bRet = SelectTxtAttr( RES_TXTATR_INETFMT, sal_False ); 844 if( bRet ) 845 DeleteSel( *GetCrsr() ); 846 return bRet; 847 } 848 849 850 // setzen an den Textzeichenattributen das DontExpand-Flag 851 sal_Bool SwEditShell::DontExpandFmt() 852 { 853 sal_Bool bRet = sal_False; 854 if( !IsTableMode() && GetDoc()->DontExpandFmt( *GetCrsr()->GetPoint() )) 855 { 856 bRet = sal_True; 857 CallChgLnk(); 858 } 859 return bRet; 860 } 861 862 SvNumberFormatter* SwEditShell::GetNumberFormatter() 863 { 864 return GetDoc()->GetNumberFormatter(); 865 } 866 867 sal_Bool SwEditShell::RemoveInvisibleContent() 868 { 869 StartAllAction(); 870 sal_Bool bRet = GetDoc()->RemoveInvisibleContent(); 871 EndAllAction(); 872 return bRet; 873 } 874 sal_Bool SwEditShell::ConvertFieldsToText() 875 { 876 StartAllAction(); 877 sal_Bool bRet = GetDoc()->ConvertFieldsToText(); 878 EndAllAction(); 879 return bRet; 880 } 881 void SwEditShell::SetNumberingRestart() 882 { 883 StartAllAction(); 884 Push(); 885 //iterate over all text contents - body, frames, header, footer, footnote text 886 SwPaM* pCrsr = GetCrsr(); 887 for(sal_uInt16 i = 0; i < 2; i++) 888 { 889 if(!i) 890 MakeFindRange(DOCPOS_START, DOCPOS_END, pCrsr); //body content 891 else 892 MakeFindRange(DOCPOS_OTHERSTART, DOCPOS_OTHEREND, pCrsr); //extra content 893 SwPosition* pSttPos = pCrsr->Start(), *pEndPos = pCrsr->End(); 894 sal_uLong nCurrNd = pSttPos->nNode.GetIndex(); 895 sal_uLong nEndNd = pEndPos->nNode.GetIndex(); 896 if( nCurrNd <= nEndNd ) 897 { 898 SwCntntFrm* pCntFrm; 899 sal_Bool bGoOn = sal_True; 900 //iterate over all paragraphs 901 while( bGoOn ) 902 { 903 SwNode* pNd = GetDoc()->GetNodes()[ nCurrNd ]; 904 switch( pNd->GetNodeType() ) 905 { 906 case ND_TEXTNODE: 907 if( 0 != ( pCntFrm = ((SwTxtNode*)pNd)->getLayoutFrm( GetLayout() )) ) 908 { 909 //jump over hidden frames - ignore protection! 910 if( !((SwTxtFrm*)pCntFrm)->IsHiddenNow() ) 911 { 912 //if the node is numbered and the starting value of the numbering equals the 913 //start value of the numbering rule then set this value as hard starting value 914 915 //get the node num 916 // OD 2005-11-09 917 SwTxtNode* pTxtNd( static_cast<SwTxtNode*>(pNd) ); 918 SwNumRule* pNumRule( pTxtNd->GetNumRule() ); 919 920 if ( pNumRule && pTxtNd->GetNum() && 921 ( pTxtNd->HasNumber() || pTxtNd->HasBullet() ) && 922 pTxtNd->IsCountedInList() && 923 !pTxtNd->IsListRestart() && 924 pTxtNd->GetNum()->GetNumber() == 925 pNumRule->Get( static_cast<sal_uInt16>(pTxtNd->GetActualListLevel()) ).GetStart() ) 926 { 927 //now set a the start value as attribute 928 SwPosition aCurrentNode(*pNd); 929 GetDoc()->SetNumRuleStart( aCurrentNode, sal_True ); 930 } 931 } 932 } 933 break; 934 case ND_SECTIONNODE: 935 // jump over hidden sections - ignore protection! 936 if(((SwSectionNode*)pNd)->GetSection().IsHidden() ) 937 nCurrNd = pNd->EndOfSectionIndex(); 938 break; 939 case ND_ENDNODE: 940 { 941 break; 942 } 943 } 944 945 bGoOn = nCurrNd < nEndNd; 946 ++nCurrNd; 947 } 948 } 949 } 950 951 952 Pop(sal_False); 953 EndAllAction(); 954 } 955 956 sal_uInt16 SwEditShell::GetLineCount( sal_Bool bActPos ) 957 { 958 sal_uInt16 nRet = 0; 959 CalcLayout(); 960 SwPaM* pPam = GetCrsr(); 961 SwNodeIndex& rPtIdx = pPam->GetPoint()->nNode; 962 SwNodeIndex aStart( rPtIdx ); 963 SwCntntNode* pCNd; 964 SwCntntFrm *pCntFrm = 0; 965 sal_uLong nTmpPos; 966 967 if( !bActPos ) 968 aStart = 0; 969 else if( rPtIdx > ( nTmpPos = GetDoc()->GetNodes().GetEndOfExtras().GetIndex()) ) 970 // BodyBereich => Start ist EndOfIcons + 1 971 aStart = nTmpPos + 1; 972 else 973 { 974 if( 0 != ( pCNd = pPam->GetCntntNode() ) && 975 0 != ( pCntFrm = pCNd->getLayoutFrm( GetLayout() ) ) ) 976 { 977 const SwStartNode *pTmp; 978 if( pCntFrm->IsInFly() ) // Fly 979 pTmp = pCNd->FindFlyStartNode(); 980 else if( pCntFrm->IsInFtn() ) // Footnote 981 pTmp = pCNd->FindFootnoteStartNode(); 982 else 983 { // Footer/Header 984 const sal_uInt16 nTyp = FRM_HEADER | FRM_FOOTER; 985 SwFrm* pFrm = pCntFrm; 986 while( pFrm && !(pFrm->GetType() & nTyp) ) 987 pFrm = pFrm->GetUpper(); 988 ASSERT( pFrm, "Wo bin ich?" ); 989 if( pFrm && ( pFrm->GetType() & FRM_FOOTER ) ) 990 pTmp = pCNd->FindFooterStartNode(); 991 else 992 pTmp = pCNd->FindHeaderStartNode(); 993 } 994 ASSERT( pTmp, "Missing StartNode" ); 995 aStart = *pTmp; 996 } 997 ASSERT( pCNd && pCntFrm, "Missing Layout-Information" ); 998 } 999 1000 while( 0 != ( pCNd = GetDoc()->GetNodes().GoNextSection( 1001 &aStart, sal_True, sal_False )) && ( !bActPos || aStart <= rPtIdx ) ) 1002 { 1003 if( 0 != ( pCntFrm = pCNd->getLayoutFrm( GetLayout() ) ) && pCntFrm->IsTxtFrm() ) 1004 { 1005 xub_StrLen nActPos = bActPos && aStart == rPtIdx ? 1006 pPam->GetPoint()->nContent.GetIndex() : USHRT_MAX; 1007 nRet = nRet + ((SwTxtFrm*)pCntFrm)->GetLineCount( nActPos ); 1008 } 1009 } 1010 return nRet; 1011 } 1012 1013 long SwEditShell::CompareDoc( const SwDoc& rDoc ) 1014 { 1015 StartAllAction(); 1016 long nRet = GetDoc()->CompareDoc( rDoc ); 1017 EndAllAction(); 1018 return nRet; 1019 } 1020 1021 long SwEditShell::MergeDoc( const SwDoc& rDoc ) 1022 { 1023 StartAllAction(); 1024 long nRet = GetDoc()->MergeDoc( rDoc ); 1025 EndAllAction(); 1026 return nRet; 1027 } 1028 1029 1030 const SwFtnInfo& SwEditShell::GetFtnInfo() const 1031 { 1032 return GetDoc()->GetFtnInfo(); 1033 } 1034 1035 void SwEditShell::SetFtnInfo(const SwFtnInfo& rInfo) 1036 { 1037 StartAllAction(); 1038 SET_CURR_SHELL( this ); 1039 GetDoc()->SetFtnInfo(rInfo); 1040 CallChgLnk(); 1041 EndAllAction(); 1042 } 1043 1044 const SwEndNoteInfo& SwEditShell::GetEndNoteInfo() const 1045 { 1046 return GetDoc()->GetEndNoteInfo(); 1047 } 1048 1049 void SwEditShell::SetEndNoteInfo(const SwEndNoteInfo& rInfo) 1050 { 1051 StartAllAction(); 1052 SET_CURR_SHELL( this ); 1053 GetDoc()->SetEndNoteInfo(rInfo); 1054 EndAllAction(); 1055 } 1056 1057 const SwLineNumberInfo& SwEditShell::GetLineNumberInfo() const 1058 { 1059 return GetDoc()->GetLineNumberInfo(); 1060 } 1061 1062 void SwEditShell::SetLineNumberInfo(const SwLineNumberInfo& rInfo) 1063 { 1064 StartAllAction(); 1065 SET_CURR_SHELL( this ); 1066 GetDoc()->SetLineNumberInfo(rInfo); 1067 AddPaintRect( GetLayout()->Frm() ); 1068 EndAllAction(); 1069 } 1070 1071 sal_uInt16 SwEditShell::GetLinkUpdMode(sal_Bool bDocSettings) const 1072 { 1073 return getIDocumentSettingAccess()->getLinkUpdateMode( !bDocSettings ); 1074 } 1075 1076 void SwEditShell::SetLinkUpdMode( sal_uInt16 nMode ) 1077 { 1078 getIDocumentSettingAccess()->setLinkUpdateMode( nMode ); 1079 } 1080 1081 1082 // Schnittstelle fuer die TextInputDaten - ( fuer die Texteingabe 1083 // von japanischen/chinesischen Zeichen) 1084 SwExtTextInput* SwEditShell::CreateExtTextInput(LanguageType eInputLanguage) 1085 { 1086 SwExtTextInput* pRet = GetDoc()->CreateExtTextInput( *GetCrsr() ); 1087 pRet->SetLanguage(eInputLanguage); 1088 pRet->SetOverwriteCursor( SwCrsrShell::IsOverwriteCrsr() ); 1089 return pRet; 1090 } 1091 1092 String SwEditShell::DeleteExtTextInput( SwExtTextInput* pDel, sal_Bool bInsText ) 1093 { 1094 if( !pDel ) 1095 { 1096 const SwPosition& rPos = *GetCrsr()->GetPoint(); 1097 pDel = GetDoc()->GetExtTextInput( rPos.nNode.GetNode(), 1098 rPos.nContent.GetIndex() ); 1099 if( !pDel ) 1100 { 1101 //JP 25.10.2001: under UNIX the cursor is moved before the Input- 1102 // Engine event comes in. So take any - normally there 1103 // exist only one at the time. -- Task 92016 1104 pDel = GetDoc()->GetExtTextInput(); 1105 } 1106 } 1107 String sRet; 1108 if( pDel ) 1109 { 1110 rtl::OUString sTmp; 1111 SwUnoCursorHelper::GetTextFromPam(*pDel, sTmp); 1112 sRet = sTmp; 1113 SET_CURR_SHELL( this ); 1114 StartAllAction(); 1115 pDel->SetInsText( bInsText ); 1116 SetOverwriteCrsr( pDel->IsOverwriteCursor() ); 1117 const SwPosition aPos( *pDel->GetPoint() ); 1118 GetDoc()->DeleteExtTextInput( pDel ); 1119 1120 // In this case, the "replace" function did not set the cursor 1121 // to the original position. Therefore we have to do this manually. 1122 if ( ! bInsText && IsOverwriteCrsr() ) 1123 *GetCrsr()->GetPoint() = aPos; 1124 1125 EndAllAction(); 1126 } 1127 return sRet; 1128 } 1129 1130 void SwEditShell::SetExtTextInputData( const CommandExtTextInputData& rData ) 1131 { 1132 const SwPosition& rPos = *GetCrsr()->GetPoint(); 1133 SwExtTextInput* pInput = GetDoc()->GetExtTextInput( rPos.nNode.GetNode() 1134 /*, rPos.nContent.GetIndex()*/ ); 1135 if( pInput ) 1136 { 1137 StartAllAction(); 1138 SET_CURR_SHELL( this ); 1139 1140 if( !rData.IsOnlyCursorChanged() ) 1141 pInput->SetInputData( rData ); 1142 // Cursor positionieren: 1143 const SwPosition& rStt = *pInput->Start(); 1144 xub_StrLen nNewCrsrPos = rStt.nContent.GetIndex() + rData.GetCursorPos(); 1145 1146 // zwar unschoen aber was hilfts 1147 ShowCrsr(); 1148 long nDiff = nNewCrsrPos - rPos.nContent.GetIndex(); 1149 if( 0 > nDiff ) 1150 Left( (xub_StrLen)-nDiff, CRSR_SKIP_CHARS ); 1151 else if( 0 < nDiff ) 1152 Right( (xub_StrLen)nDiff, CRSR_SKIP_CHARS ); 1153 1154 SetOverwriteCrsr( rData.IsCursorOverwrite() ); 1155 1156 EndAllAction(); 1157 1158 if( !rData.IsCursorVisible() ) // must be called after the EndAction 1159 HideCrsr(); 1160 } 1161 } 1162 1163 void SwEditShell::TransliterateText( sal_uInt32 nType ) 1164 { 1165 utl::TransliterationWrapper aTrans( ::comphelper::getProcessServiceFactory(), nType ); 1166 StartAllAction(); 1167 SET_CURR_SHELL( this ); 1168 1169 SwPaM* pCrsr = GetCrsr(); 1170 if( pCrsr->GetNext() != pCrsr ) 1171 { 1172 GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_EMPTY, NULL); 1173 FOREACHPAM_START( this ) 1174 1175 if( PCURCRSR->HasMark() ) 1176 GetDoc()->TransliterateText( *PCURCRSR, aTrans ); 1177 1178 FOREACHPAM_END() 1179 GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_EMPTY, NULL); 1180 } 1181 else 1182 GetDoc()->TransliterateText( *pCrsr, aTrans ); 1183 1184 EndAllAction(); 1185 } 1186 1187 void SwEditShell::CountWords( SwDocStat& rStat ) const 1188 { 1189 FOREACHPAM_START( this ) 1190 1191 if( PCURCRSR->HasMark() ) 1192 GetDoc()->CountWords( *PCURCRSR, rStat ); 1193 1194 FOREACHPAM_END() 1195 } 1196 1197 void SwEditShell::ApplyViewOptions( const SwViewOption &rOpt ) 1198 { 1199 SwCrsrShell::StartAction(); 1200 ViewShell::ApplyViewOptions( rOpt ); 1201 SwEditShell::EndAction(); 1202 } 1203 1204 1205