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 #include <rtl/ustrbuf.hxx> 28 #include <swtypes.hxx> 29 #include <hintids.hxx> 30 #include <cmdid.h> 31 #include <hints.hxx> 32 #include <IMark.hxx> 33 #include <bookmrk.hxx> 34 #include <frmfmt.hxx> 35 #include <doc.hxx> 36 #include <IDocumentUndoRedo.hxx> 37 #include <ndtxt.hxx> 38 #include <ndnotxt.hxx> 39 #include <unocrsr.hxx> 40 #include <swundo.hxx> 41 #include <rootfrm.hxx> 42 #include <flyfrm.hxx> 43 #include <ftnidx.hxx> 44 #include <sfx2/linkmgr.hxx> 45 #include <docary.hxx> 46 #include <paratr.hxx> 47 #include <tools/urlobj.hxx> 48 #include <pam.hxx> 49 #include <tools/cachestr.hxx> 50 #include <shellio.hxx> 51 #include <swerror.h> 52 #include <swtblfmt.hxx> 53 #include <docsh.hxx> 54 #include <docstyle.hxx> 55 #include <charfmt.hxx> 56 #include <txtfld.hxx> 57 #include <fmtfld.hxx> 58 #include <fmtpdsc.hxx> 59 #include <pagedesc.hxx> 60 #include <poolfmt.hrc> 61 #include <poolfmt.hxx> 62 #include <edimp.hxx> 63 #include <fchrfmt.hxx> 64 #include <cntfrm.hxx> 65 #include <pagefrm.hxx> 66 #include <doctxm.hxx> 67 #include <sfx2/docfilt.hxx> 68 #include <sfx2/docfile.hxx> 69 #include <sfx2/fcontnr.hxx> 70 #include <fmtrfmrk.hxx> 71 #include <txtrfmrk.hxx> 72 #include <unoparaframeenum.hxx> 73 #include <unofootnote.hxx> 74 #include <unotextbodyhf.hxx> 75 #include <unotextrange.hxx> 76 #include <unoparagraph.hxx> 77 #include <unomap.hxx> 78 #include <unoport.hxx> 79 #include <unocrsrhelper.hxx> 80 #include <unosett.hxx> 81 #include <unoprnms.hxx> 82 #include <unotbl.hxx> 83 #include <unodraw.hxx> 84 #include <unocoll.hxx> 85 #include <unostyle.hxx> 86 #include <unofield.hxx> 87 #include <fmtanchr.hxx> 88 #include <editeng/flstitem.hxx> 89 #include <editeng/unolingu.hxx> 90 #include <svtools/ctrltool.hxx> 91 #include <flypos.hxx> 92 #include <txtftn.hxx> 93 #include <fmtftn.hxx> 94 #include <fmtcntnt.hxx> 95 #include <com/sun/star/text/WrapTextMode.hpp> 96 #include <com/sun/star/text/TextContentAnchorType.hpp> 97 #include <com/sun/star/style/PageStyleLayout.hpp> 98 #include <com/sun/star/text/XTextDocument.hpp> 99 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> 100 #include <com/sun/star/drawing/XDrawPageSupplier.hpp> 101 #include <unoidx.hxx> 102 #include <unoframe.hxx> 103 #include <fmthdft.hxx> 104 #include <vos/mutex.hxx> 105 #include <vcl/svapp.hxx> 106 #include <fmtflcnt.hxx> 107 #define _SVSTDARR_USHORTS 108 #define _SVSTDARR_USHORTSSORT 109 #define _SVSTDARR_XUB_STRLEN 110 #include <svl/svstdarr.hxx> 111 #include <editeng/brshitem.hxx> 112 #include <fmtclds.hxx> 113 #include <dcontact.hxx> 114 #include <dflyobj.hxx> 115 #include <crsskip.hxx> 116 #include <vector> 117 #include <sortedobjs.hxx> 118 #include <sortopt.hxx> 119 #include <algorithm> 120 #include <iterator> 121 #include <boost/bind.hpp> 122 #include <switerator.hxx> 123 124 using namespace ::com::sun::star; 125 using ::rtl::OUString; 126 127 128 namespace sw { 129 130 sal_Bool SupportsServiceImpl( 131 size_t const nServices, char const*const pServices[], 132 ::rtl::OUString const & rServiceName) 133 { 134 for (size_t i = 0; i < nServices; ++i) 135 { 136 if (rServiceName.equalsAscii(pServices[i])) 137 { 138 return sal_True; 139 } 140 } 141 return sal_False; 142 } 143 144 uno::Sequence< ::rtl::OUString > 145 GetSupportedServiceNamesImpl( 146 size_t const nServices, char const*const pServices[]) 147 { 148 uno::Sequence< ::rtl::OUString > ret(nServices); 149 for (size_t i = 0; i < nServices; ++i) 150 { 151 ret[i] = C2U(pServices[i]); 152 } 153 return ret; 154 } 155 156 } // namespace sw 157 158 159 namespace sw { 160 161 void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget) 162 { 163 rTarget = rSource; 164 165 if (rSource.GetNext() != &rSource) 166 { 167 SwPaM *pPam = static_cast<SwPaM *>(rSource.GetNext()); 168 do 169 { 170 // create new PaM 171 SwPaM *const pNew = new SwPaM(*pPam); 172 // insert into ring 173 pNew->MoveTo(&rTarget); 174 pPam = static_cast<SwPaM *>(pPam->GetNext()); 175 } 176 while (pPam != &rSource); 177 } 178 } 179 180 } // namespace sw 181 182 struct FrameDependSortListLess 183 { 184 bool operator() (FrameDependSortListEntry const& r1, 185 FrameDependSortListEntry const& r2) 186 { 187 return (r1.nIndex < r2.nIndex) 188 || ((r1.nIndex == r2.nIndex) && (r1.nOrder < r2.nOrder)); 189 } 190 }; 191 192 // OD 2004-05-07 #i28701# - adjust 4th parameter 193 void CollectFrameAtNode( SwClient& rClnt, const SwNodeIndex& rIdx, 194 FrameDependSortList_t & rFrames, 195 const bool _bAtCharAnchoredObjs ) 196 { 197 // _bAtCharAnchoredObjs: 198 // <sal_True>: at-character anchored objects are collected 199 // <sal_False>: at-paragraph anchored objects are collected 200 201 // alle Rahmen, Grafiken und OLEs suchen, die an diesem Absatz 202 // gebunden sind 203 SwDoc* pDoc = rIdx.GetNode().GetDoc(); 204 205 sal_uInt16 nChkType = static_cast< sal_uInt16 >((_bAtCharAnchoredObjs) 206 ? FLY_AT_CHAR : FLY_AT_PARA); 207 const SwCntntFrm* pCFrm; 208 const SwCntntNode* pCNd; 209 if( pDoc->GetCurrentViewShell() && //swmod 071108//swmod 071225 210 0 != (pCNd = rIdx.GetNode().GetCntntNode()) && 211 0 != (pCFrm = pCNd->getLayoutFrm( pDoc->GetCurrentLayout())) ) 212 { 213 const SwSortedObjs *pObjs = pCFrm->GetDrawObjs(); 214 if( pObjs ) 215 for( sal_uInt16 i = 0; i < pObjs->Count(); ++i ) 216 { 217 SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; 218 SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); 219 if ( rFmt.GetAnchor().GetAnchorId() == nChkType ) 220 { 221 // create SwDepend and insert into array 222 SwDepend* pNewDepend = new SwDepend( &rClnt, &rFmt ); 223 xub_StrLen idx = 224 rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex(); 225 sal_uInt32 nOrder = rFmt.GetAnchor().GetOrder(); 226 227 // OD 2004-05-07 #i28701# - sorting no longer needed, 228 // because list <SwSortedObjs> is already sorted. 229 FrameDependSortListEntry entry(idx, nOrder, pNewDepend); 230 rFrames.push_back(entry); 231 } 232 } 233 } 234 else 235 { 236 const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts(); 237 sal_uInt16 nSize = rFmts.Count(); 238 for ( sal_uInt16 i = 0; i < nSize; i++) 239 { 240 const SwFrmFmt* pFmt = rFmts[ i ]; 241 const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); 242 const SwPosition* pAnchorPos; 243 if( rAnchor.GetAnchorId() == nChkType && 244 0 != (pAnchorPos = rAnchor.GetCntntAnchor()) && 245 pAnchorPos->nNode == rIdx ) 246 { 247 //jetzt einen SwDepend anlegen und in das Array einfuegen 248 SwDepend* pNewDepend = new SwDepend( &rClnt, (SwFrmFmt*)pFmt); 249 250 // OD 2004-05-07 #i28701# - determine insert position for 251 // sorted <rFrameArr> 252 xub_StrLen nIndex = pAnchorPos->nContent.GetIndex(); 253 sal_uInt32 nOrder = rAnchor.GetOrder(); 254 255 FrameDependSortListEntry entry(nIndex, nOrder, pNewDepend); 256 rFrames.push_back(entry); 257 } 258 } 259 ::std::sort(rFrames.begin(), rFrames.end(), FrameDependSortListLess()); 260 } 261 } 262 263 /**************************************************************************** 264 ActionContext 265 ****************************************************************************/ 266 UnoActionContext::UnoActionContext(SwDoc *const pDoc) 267 : m_pDoc(pDoc) 268 { 269 SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); 270 if (pRootFrm) 271 { 272 pRootFrm->StartAllAction(); 273 } 274 } 275 276 UnoActionContext::~UnoActionContext() 277 { 278 // Doc may already have been removed here 279 if (m_pDoc) 280 { 281 SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); 282 if (pRootFrm) 283 { 284 pRootFrm->EndAllAction(); 285 } 286 } 287 } 288 289 /**************************************************************************** 290 ActionRemoveContext 291 ****************************************************************************/ 292 UnoActionRemoveContext::UnoActionRemoveContext(SwDoc *const pDoc) 293 : m_pDoc(pDoc) 294 { 295 SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); 296 if (pRootFrm) 297 { 298 pRootFrm->UnoRemoveAllActions(); 299 } 300 } 301 302 /* -----------------07.07.98 12:05------------------- 303 * 304 * --------------------------------------------------*/ 305 UnoActionRemoveContext::~UnoActionRemoveContext() 306 { 307 SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); 308 if (pRootFrm) 309 { 310 pRootFrm->UnoRestoreAllActions(); 311 } 312 } 313 314 315 void ClientModify(SwClient* pClient, const SfxPoolItem *pOld, const SfxPoolItem *pNew) 316 { 317 switch( pOld ? pOld->Which() : 0 ) 318 { 319 case RES_REMOVE_UNO_OBJECT: 320 case RES_OBJECTDYING: 321 if( (void*)pClient->GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject ) 322 ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient); 323 break; 324 325 case RES_FMT_CHG: 326 // wurden wir an das neue umgehaengt und wird das alte geloscht? 327 if( ((SwFmtChg*)pNew)->pChangedFmt == pClient->GetRegisteredIn() && 328 ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() ) 329 ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient); 330 break; 331 } 332 } 333 334 335 void SwUnoCursorHelper::SetCrsrAttr(SwPaM & rPam, 336 const SfxItemSet& rSet, 337 const SetAttrMode nAttrMode, const bool bTableMode) 338 { 339 const SetAttrMode nFlags = nAttrMode | nsSetAttrMode::SETATTR_APICALL; 340 SwDoc* pDoc = rPam.GetDoc(); 341 //StartEndAction 342 UnoActionContext aAction(pDoc); 343 if (rPam.GetNext() != &rPam) // Ring of Cursors 344 { 345 pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSATTR, NULL); 346 347 SwPaM *pCurrent = &rPam; 348 do 349 { 350 if (pCurrent->HasMark() && 351 ( (bTableMode) || 352 (*pCurrent->GetPoint() != *pCurrent->GetMark()) )) 353 { 354 pDoc->InsertItemSet(*pCurrent, rSet, nFlags); 355 } 356 pCurrent= static_cast<SwPaM *>(pCurrent->GetNext()); 357 } while (pCurrent != &rPam); 358 359 pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSATTR, NULL); 360 } 361 else 362 { 363 // if( !HasSelection() ) 364 // UpdateAttr(); 365 pDoc->InsertItemSet( rPam, rSet, nFlags ); 366 } 367 //#outline level,add by zhaojianwei 368 if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SFX_ITEM_AVAILABLE ) 369 { 370 SwTxtNode * pTmpNode = rPam.GetNode()->GetTxtNode(); 371 if ( pTmpNode ) 372 { 373 rPam.GetDoc()->GetNodes().UpdateOutlineNode( *pTmpNode ); 374 } 375 } 376 //<-end,zhaojianwei 377 } 378 379 // --> OD 2006-07-12 #i63870# 380 // split third parameter <bCurrentAttrOnly> into new parameters <bOnlyTxtAttr> 381 // and <bGetFromChrFmt> to get better control about resulting <SfxItemSet> 382 void SwUnoCursorHelper::GetCrsrAttr(SwPaM & rPam, 383 SfxItemSet & rSet, const bool bOnlyTxtAttr, const bool bGetFromChrFmt) 384 { 385 static const sal_uInt16 nMaxLookup = 1000; 386 SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() ); 387 SfxItemSet *pSet = &rSet; 388 SwPaM *pCurrent = & rPam; 389 do 390 { 391 SwPosition const & rStart( *pCurrent->Start() ); 392 SwPosition const & rEnd( *pCurrent->End() ); 393 const sal_uLong nSttNd = rStart.nNode.GetIndex(); 394 const sal_uLong nEndNd = rEnd .nNode.GetIndex(); 395 396 if (nEndNd - nSttNd >= nMaxLookup) 397 { 398 rSet.ClearItem(); 399 rSet.InvalidateAllItems(); 400 return;// uno::Any(); 401 } 402 403 // the first node inserts the values into the get set 404 // all other nodes merge their values into the get set 405 for (sal_uLong n = nSttNd; n <= nEndNd; ++n) 406 { 407 SwNode *const pNd = rPam.GetDoc()->GetNodes()[ n ]; 408 switch (pNd->GetNodeType()) 409 { 410 case ND_TEXTNODE: 411 { 412 const xub_StrLen nStart = (n == nSttNd) 413 ? rStart.nContent.GetIndex() : 0; 414 const xub_StrLen nEnd = (n == nEndNd) 415 ? rEnd.nContent.GetIndex() 416 : static_cast<SwTxtNode*>(pNd)->GetTxt().Len(); 417 static_cast<SwTxtNode*>(pNd)->GetAttr( 418 *pSet, nStart, nEnd, bOnlyTxtAttr, bGetFromChrFmt); 419 } 420 break; 421 case ND_GRFNODE: 422 case ND_OLENODE: 423 static_cast<SwCntntNode*>(pNd)->GetAttr( *pSet ); 424 break; 425 426 default: 427 continue; // skip this node 428 } 429 430 if (pSet != &rSet) 431 { 432 rSet.MergeValues( aSet ); 433 } 434 else 435 { 436 pSet = &aSet; 437 } 438 439 if (aSet.Count()) 440 { 441 aSet.ClearItem(); 442 } 443 } 444 pCurrent= static_cast<SwPaM *>(pCurrent->GetNext()); 445 } while ( pCurrent != &rPam ); 446 } 447 448 /****************************************************************** 449 * SwXParagraphEnumeration 450 ******************************************************************/ 451 452 class SwXParagraphEnumeration::Impl 453 : public SwClient 454 { 455 456 public: 457 458 uno::Reference< text::XText > const m_xParentText; 459 const CursorType m_eCursorType; 460 /// Start node of the cell _or_ table the enumeration belongs to. 461 /// Used to restrict the movement of the UNO cursor to the cell and its 462 /// embedded tables. 463 SwStartNode const*const m_pOwnStartNode; 464 SwTable const*const m_pOwnTable; 465 const sal_uLong m_nEndIndex; 466 sal_Int32 m_nFirstParaStart; 467 sal_Int32 m_nLastParaEnd; 468 bool m_bFirstParagraph; 469 uno::Reference< text::XTextContent > m_xNextPara; 470 471 Impl( uno::Reference< text::XText > const& xParent, 472 ::std::auto_ptr<SwUnoCrsr> pCursor, 473 const CursorType eType, 474 SwStartNode const*const pStartNode, SwTable const*const pTable) 475 : SwClient( pCursor.release() ) 476 , m_xParentText( xParent ) 477 , m_eCursorType( eType ) 478 // remember table and start node for later travelling 479 // (used in export of tables in tables) 480 , m_pOwnStartNode( pStartNode ) 481 // for import of tables in tables we have to remember the actual 482 // table and start node of the current position in the enumeration. 483 , m_pOwnTable( pTable ) 484 , m_nEndIndex( GetCursor()->End()->nNode.GetIndex() ) 485 , m_nFirstParaStart( -1 ) 486 , m_nLastParaEnd( -1 ) 487 , m_bFirstParagraph( true ) 488 { 489 OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?"); 490 OSL_ENSURE(GetRegisteredIn(), "SwXParagraphEnumeration: no cursor?"); 491 OSL_ENSURE( !((CURSOR_SELECTION_IN_TABLE == eType) || 492 (CURSOR_TBLTEXT == eType)) 493 || (m_pOwnTable && m_pOwnStartNode), 494 "SwXParagraphEnumeration: table type but no start node or table?"); 495 496 if ((CURSOR_SELECTION == m_eCursorType) || 497 (CURSOR_SELECTION_IN_TABLE == m_eCursorType)) 498 { 499 SwUnoCrsr & rCursor = *GetCursor(); 500 rCursor.Normalize(); 501 m_nFirstParaStart = rCursor.GetPoint()->nContent.GetIndex(); 502 m_nLastParaEnd = rCursor.GetMark()->nContent.GetIndex(); 503 rCursor.DeleteMark(); 504 } 505 } 506 507 ~Impl() { 508 // Impl owns the cursor; delete it here: SolarMutex is locked 509 delete GetRegisteredIn(); 510 } 511 512 SwUnoCrsr * GetCursor() { 513 return static_cast<SwUnoCrsr*>( 514 const_cast<SwModify*>(GetRegisteredIn())); 515 } 516 517 uno::Reference< text::XTextContent > NextElement_Impl() 518 throw (container::NoSuchElementException, lang::WrappedTargetException, 519 uno::RuntimeException); 520 protected: 521 // SwClient 522 virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew); 523 524 }; 525 526 void SwXParagraphEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) 527 { 528 ClientModify(this, pOld, pNew); 529 } 530 531 SwXParagraphEnumeration::SwXParagraphEnumeration( 532 uno::Reference< text::XText > const& xParent, 533 ::std::auto_ptr<SwUnoCrsr> pCursor, 534 const CursorType eType, 535 SwStartNode const*const pStartNode, SwTable const*const pTable) 536 : m_pImpl( new SwXParagraphEnumeration::Impl(xParent, pCursor, eType, 537 pStartNode, pTable) ) 538 { 539 } 540 541 SwXParagraphEnumeration::~SwXParagraphEnumeration() 542 { 543 } 544 545 OUString SAL_CALL 546 SwXParagraphEnumeration::getImplementationName() throw (uno::RuntimeException) 547 { 548 return C2U("SwXParagraphEnumeration"); 549 } 550 551 static char const*const g_ServicesParagraphEnum[] = 552 { 553 "com.sun.star.text.ParagraphEnumeration", 554 }; 555 static const size_t g_nServicesParagraphEnum( 556 sizeof(g_ServicesParagraphEnum)/sizeof(g_ServicesParagraphEnum[0])); 557 558 sal_Bool SAL_CALL 559 SwXParagraphEnumeration::supportsService(const OUString& rServiceName) 560 throw (uno::RuntimeException) 561 { 562 return ::sw::SupportsServiceImpl( 563 g_nServicesParagraphEnum, g_ServicesParagraphEnum, rServiceName); 564 } 565 566 uno::Sequence< OUString > SAL_CALL 567 SwXParagraphEnumeration::getSupportedServiceNames() 568 throw (uno::RuntimeException) 569 { 570 return ::sw::GetSupportedServiceNamesImpl( 571 g_nServicesParagraphEnum, g_ServicesParagraphEnum); 572 } 573 574 sal_Bool SAL_CALL 575 SwXParagraphEnumeration::hasMoreElements() throw (uno::RuntimeException) 576 { 577 vos::OGuard aGuard(Application::GetSolarMutex()); 578 579 return (m_pImpl->m_bFirstParagraph) ? sal_True : m_pImpl->m_xNextPara.is(); 580 } 581 582 //!! compare to SwShellTableCrsr::FillRects() in viscrs.cxx 583 static SwTableNode * 584 lcl_FindTopLevelTable( 585 SwTableNode *const pTblNode, SwTable const*const pOwnTable) 586 { 587 // find top-most table in current context (section) level 588 589 SwTableNode * pLast = pTblNode; 590 for (SwTableNode* pTmp = pLast; 591 pTmp != NULL && &pTmp->GetTable() != pOwnTable; /* we must not go up higher than the own table! */ 592 pTmp = pTmp->StartOfSectionNode()->FindTableNode() ) 593 { 594 pLast = pTmp; 595 } 596 return pLast; 597 } 598 599 600 static bool 601 lcl_CursorIsInSection( 602 SwUnoCrsr const*const pUnoCrsr, SwStartNode const*const pOwnStartNode) 603 { 604 // returns true if the cursor is in the section (or in a sub section!) 605 // represented by pOwnStartNode 606 607 bool bRes = true; 608 if (pUnoCrsr && pOwnStartNode) 609 { 610 const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode(); 611 bRes = pOwnStartNode->GetIndex() <= pUnoCrsr->Start()->nNode.GetIndex() && 612 pUnoCrsr->End()->nNode.GetIndex() <= pOwnEndNode->GetIndex(); 613 } 614 return bRes; 615 } 616 617 618 uno::Reference< text::XTextContent > 619 SwXParagraphEnumeration::Impl::NextElement_Impl() 620 throw (container::NoSuchElementException, lang::WrappedTargetException, 621 uno::RuntimeException) 622 { 623 SwUnoCrsr *const pUnoCrsr = GetCursor(); 624 if (!pUnoCrsr) 625 { 626 throw uno::RuntimeException(); 627 } 628 629 // check for exceeding selections 630 if (!m_bFirstParagraph && 631 ((CURSOR_SELECTION == m_eCursorType) || 632 (CURSOR_SELECTION_IN_TABLE == m_eCursorType))) 633 { 634 SwPosition* pStart = pUnoCrsr->Start(); 635 const ::std::auto_ptr<SwUnoCrsr> aNewCrsr( 636 pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, sal_False) ); 637 // one may also go into tables here 638 if ((CURSOR_TBLTEXT != m_eCursorType) && 639 (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) 640 { 641 aNewCrsr->SetRemainInSection( sal_False ); 642 } 643 644 // os 2005-01-14: This part is only necessary to detect movements out 645 // of a selection; if there is no selection we don't have to care 646 SwTableNode *const pTblNode = aNewCrsr->GetNode()->FindTableNode(); 647 if (((CURSOR_TBLTEXT != m_eCursorType) && 648 (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) && pTblNode) 649 { 650 aNewCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex(); 651 aNewCrsr->Move(fnMoveForward, fnGoNode); 652 } 653 else 654 { 655 aNewCrsr->MovePara(fnParaNext, fnParaStart); 656 } 657 if (m_nEndIndex < aNewCrsr->Start()->nNode.GetIndex()) 658 { 659 return 0; 660 } 661 } 662 663 sal_Bool bInTable = sal_False; 664 if (!m_bFirstParagraph) 665 { 666 pUnoCrsr->SetRemainInSection( sal_False ); 667 // what to do if already in a table? 668 SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode(); 669 pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable ); 670 if (pTblNode && (&pTblNode->GetTable() != m_pOwnTable)) 671 { 672 // this is a foreign table: go to end 673 pUnoCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex(); 674 if (!pUnoCrsr->Move(fnMoveForward, fnGoNode)) 675 { 676 return 0; 677 } 678 bInTable = sal_True; 679 } 680 } 681 682 uno::Reference< text::XTextContent > xRef; 683 // the cursor must remain in the current section or a subsection 684 // before AND after the movement... 685 if (lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ) && 686 (m_bFirstParagraph || bInTable || 687 (pUnoCrsr->MovePara(fnParaNext, fnParaStart) && 688 lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode )))) 689 { 690 SwPosition* pStart = pUnoCrsr->Start(); 691 const sal_Int32 nFirstContent = 692 (m_bFirstParagraph) ? m_nFirstParaStart : -1; 693 const sal_Int32 nLastContent = 694 (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1; 695 696 // position in a table, or in a simple paragraph? 697 SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode(); 698 pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable ); 699 if (/*CURSOR_TBLTEXT != eCursorType && CURSOR_SELECTION_IN_TABLE != eCursorType && */ 700 pTblNode && (&pTblNode->GetTable() != m_pOwnTable)) 701 { 702 // this is a foreign table 703 SwFrmFmt* pTableFmt = 704 static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt()); 705 text::XTextTable *const pTable = 706 SwXTextTables::GetObject( *pTableFmt ); 707 xRef = static_cast<text::XTextContent*>( 708 static_cast<SwXTextTable*>(pTable)); 709 } 710 else 711 { 712 text::XText *const pText = m_xParentText.get(); 713 xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(), 714 *pStart->nNode.GetNode().GetTxtNode(), 715 static_cast<SwXText*>(pText), nFirstContent, nLastContent); 716 } 717 } 718 719 return xRef; 720 } 721 722 uno::Any SAL_CALL SwXParagraphEnumeration::nextElement() 723 throw (container::NoSuchElementException, lang::WrappedTargetException, 724 uno::RuntimeException) 725 { 726 vos::OGuard aGuard(Application::GetSolarMutex()); 727 728 if (m_pImpl->m_bFirstParagraph) 729 { 730 m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl(); 731 m_pImpl->m_bFirstParagraph = false; 732 } 733 const uno::Reference< text::XTextContent > xRef = m_pImpl->m_xNextPara; 734 if (!xRef.is()) 735 { 736 throw container::NoSuchElementException(); 737 } 738 m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl(); 739 740 uno::Any aRet; 741 aRet <<= xRef; 742 return aRet; 743 } 744 745 /****************************************************************** 746 * SwXTextRange 747 ******************************************************************/ 748 749 class SwXTextRange::Impl 750 : public SwClient 751 { 752 753 public: 754 755 const SfxItemPropertySet & m_rPropSet; 756 const enum RangePosition m_eRangePosition; 757 SwDoc & m_rDoc; 758 uno::Reference<text::XText> m_xParentText; 759 SwDepend m_ObjectDepend; // register at format of table or frame 760 ::sw::mark::IMark * m_pMark; 761 762 Impl( SwDoc & rDoc, const enum RangePosition eRange, 763 SwFrmFmt *const pTblFmt = 0, 764 const uno::Reference< text::XText > & xParent = 0) 765 : SwClient() 766 , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) 767 , m_eRangePosition(eRange) 768 , m_rDoc(rDoc) 769 , m_xParentText(xParent) 770 , m_ObjectDepend(this, pTblFmt) 771 , m_pMark(0) 772 { 773 } 774 775 ~Impl() 776 { 777 // Impl owns the bookmark; delete it here: SolarMutex is locked 778 Invalidate(); 779 } 780 781 void Invalidate() 782 { 783 if (m_pMark) 784 { 785 m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark); 786 m_pMark = 0; 787 } 788 } 789 790 const ::sw::mark::IMark * GetBookmark() const { return m_pMark; } 791 protected: 792 // SwClient 793 virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew); 794 795 }; 796 797 void SwXTextRange::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) 798 { 799 const bool bAlreadyRegistered = 0 != GetRegisteredIn(); 800 ClientModify(this, pOld, pNew); 801 if (m_ObjectDepend.GetRegisteredIn()) 802 { 803 ClientModify(&m_ObjectDepend, pOld, pNew); 804 // if the depend was removed then the range must be removed too 805 if (!m_ObjectDepend.GetRegisteredIn() && GetRegisteredIn()) 806 { 807 const_cast<SwModify*>(GetRegisteredIn())->Remove(this); 808 } 809 // or if the range has been removed but the depend ist still 810 // connected then the depend must be removed 811 else if (bAlreadyRegistered && !GetRegisteredIn() && 812 m_ObjectDepend.GetRegisteredIn()) 813 { 814 const_cast<SwModify*>(m_ObjectDepend.GetRegisteredIn()) 815 ->Remove(& m_ObjectDepend); 816 } 817 } 818 if (!GetRegisteredIn()) 819 { 820 m_pMark = 0; 821 } 822 } 823 824 825 SwXTextRange::SwXTextRange(SwPaM& rPam, 826 const uno::Reference< text::XText > & xParent, 827 const enum RangePosition eRange) 828 : m_pImpl( new SwXTextRange::Impl(*rPam.GetDoc(), eRange, 0, xParent) ) 829 { 830 SetPositions(rPam); 831 } 832 833 SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt) 834 : m_pImpl( 835 new SwXTextRange::Impl(*rTblFmt.GetDoc(), RANGE_IS_TABLE, &rTblFmt) ) 836 { 837 SwTable *const pTable = SwTable::FindTable( &rTblFmt ); 838 SwTableNode *const pTblNode = pTable->GetTableNode(); 839 SwPosition aPosition( *pTblNode ); 840 SwPaM aPam( aPosition ); 841 842 SetPositions( aPam ); 843 } 844 845 SwXTextRange::~SwXTextRange() 846 { 847 } 848 849 const SwDoc * SwXTextRange::GetDoc() const 850 { 851 return & m_pImpl->m_rDoc; 852 } 853 854 SwDoc * SwXTextRange::GetDoc() 855 { 856 return & m_pImpl->m_rDoc; 857 } 858 859 860 void SwXTextRange::Invalidate() 861 { 862 m_pImpl->Invalidate(); 863 } 864 865 void SwXTextRange::SetPositions(const SwPaM& rPam) 866 { 867 m_pImpl->Invalidate(); 868 IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess(); 869 m_pImpl->m_pMark = pMA->makeMark(rPam, ::rtl::OUString(), 870 IDocumentMarkAccess::UNO_BOOKMARK); 871 m_pImpl->m_pMark->Add(m_pImpl.get()); 872 } 873 874 void SwXTextRange::DeleteAndInsert( 875 const ::rtl::OUString& rText, const bool bForceExpandHints) 876 throw (uno::RuntimeException) 877 { 878 if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) 879 { 880 // setString on table not allowed 881 throw uno::RuntimeException(); 882 } 883 884 const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent()); 885 SwCursor aCursor(aPos, 0, false); 886 if (GetPositions(aCursor)) 887 { 888 UnoActionContext aAction(& m_pImpl->m_rDoc); 889 m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL); 890 if (aCursor.HasMark()) 891 { 892 m_pImpl->m_rDoc.DeleteAndJoin(aCursor); 893 } 894 895 if (rText.getLength()) 896 { 897 SwUnoCursorHelper::DocInsertStringSplitCR( 898 m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints); 899 900 SwUnoCursorHelper::SelectPam(aCursor, true); 901 aCursor.Left(rText.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False); 902 } 903 SetPositions(aCursor); 904 m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL); 905 } 906 } 907 908 const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId() 909 { 910 static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId(); 911 return aSeq; 912 } 913 914 // XUnoTunnel 915 sal_Int64 SAL_CALL 916 SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId) 917 throw (uno::RuntimeException) 918 { 919 return ::sw::UnoTunnelImpl<SwXTextRange>(rId, this); 920 } 921 922 OUString SAL_CALL 923 SwXTextRange::getImplementationName() throw (uno::RuntimeException) 924 { 925 return OUString::createFromAscii("SwXTextRange"); 926 } 927 928 static char const*const g_ServicesTextRange[] = 929 { 930 "com.sun.star.text.TextRange", 931 "com.sun.star.style.CharacterProperties", 932 "com.sun.star.style.CharacterPropertiesAsian", 933 "com.sun.star.style.CharacterPropertiesComplex", 934 "com.sun.star.style.ParagraphProperties", 935 "com.sun.star.style.ParagraphPropertiesAsian", 936 "com.sun.star.style.ParagraphPropertiesComplex", 937 }; 938 static const size_t g_nServicesTextRange( 939 sizeof(g_ServicesTextRange)/sizeof(g_ServicesTextRange[0])); 940 941 sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName) 942 throw (uno::RuntimeException) 943 { 944 return ::sw::SupportsServiceImpl( 945 g_nServicesTextRange, g_ServicesTextRange, rServiceName); 946 } 947 948 uno::Sequence< OUString > SAL_CALL 949 SwXTextRange::getSupportedServiceNames() throw (uno::RuntimeException) 950 { 951 return ::sw::GetSupportedServiceNamesImpl( 952 g_nServicesTextRange, g_ServicesTextRange); 953 } 954 955 uno::Reference< text::XText > SAL_CALL 956 SwXTextRange::getText() throw (uno::RuntimeException) 957 { 958 vos::OGuard aGuard(Application::GetSolarMutex()); 959 960 if (!m_pImpl->m_xParentText.is()) 961 { 962 if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE && 963 m_pImpl->m_ObjectDepend.GetRegisteredIn()) 964 { 965 SwFrmFmt const*const pTblFmt = static_cast<SwFrmFmt const*>( 966 m_pImpl->m_ObjectDepend.GetRegisteredIn()); 967 SwTable const*const pTable = SwTable::FindTable( pTblFmt ); 968 SwTableNode const*const pTblNode = pTable->GetTableNode(); 969 const SwPosition aPosition( *pTblNode ); 970 m_pImpl->m_xParentText = 971 ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition); 972 } 973 } 974 OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text"); 975 return m_pImpl->m_xParentText; 976 } 977 978 uno::Reference< text::XTextRange > SAL_CALL 979 SwXTextRange::getStart() throw (uno::RuntimeException) 980 { 981 vos::OGuard aGuard(Application::GetSolarMutex()); 982 983 uno::Reference< text::XTextRange > xRet; 984 ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); 985 if (!m_pImpl->m_xParentText.is()) 986 { 987 getText(); 988 } 989 if(pBkmk) 990 { 991 SwPaM aPam(pBkmk->GetMarkStart()); 992 xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText); 993 } 994 else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) 995 { 996 // start and end are this, if its a table 997 xRet = this; 998 } 999 else 1000 { 1001 throw uno::RuntimeException(); 1002 } 1003 return xRet; 1004 } 1005 1006 uno::Reference< text::XTextRange > SAL_CALL 1007 SwXTextRange::getEnd() throw (uno::RuntimeException) 1008 { 1009 vos::OGuard aGuard(Application::GetSolarMutex()); 1010 1011 uno::Reference< text::XTextRange > xRet; 1012 ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); 1013 if (!m_pImpl->m_xParentText.is()) 1014 { 1015 getText(); 1016 } 1017 if(pBkmk) 1018 { 1019 SwPaM aPam(pBkmk->GetMarkEnd()); 1020 xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText); 1021 } 1022 else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) 1023 { 1024 // start and end are this, if its a table 1025 xRet = this; 1026 } 1027 else 1028 { 1029 throw uno::RuntimeException(); 1030 } 1031 return xRet; 1032 } 1033 1034 OUString SAL_CALL SwXTextRange::getString() throw (uno::RuntimeException) 1035 { 1036 vos::OGuard aGuard(Application::GetSolarMutex()); 1037 1038 OUString sRet; 1039 // for tables there is no bookmark, thus also no text 1040 // one could export the table as ASCII here maybe? 1041 SwPaM aPaM(GetDoc()->GetNodes()); 1042 if (GetPositions(aPaM) && aPaM.HasMark()) 1043 { 1044 SwUnoCursorHelper::GetTextFromPam(aPaM, sRet); 1045 } 1046 return sRet; 1047 } 1048 1049 void SAL_CALL SwXTextRange::setString(const OUString& rString) 1050 throw (uno::RuntimeException) 1051 { 1052 vos::OGuard aGuard(Application::GetSolarMutex()); 1053 1054 DeleteAndInsert(rString, false); 1055 } 1056 1057 bool SwXTextRange::GetPositions(SwPaM& rToFill) const 1058 { 1059 ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); 1060 if(pBkmk) 1061 { 1062 *rToFill.GetPoint() = pBkmk->GetMarkPos(); 1063 if(pBkmk->IsExpanded()) 1064 { 1065 rToFill.SetMark(); 1066 *rToFill.GetMark() = pBkmk->GetOtherMarkPos(); 1067 } 1068 else 1069 { 1070 rToFill.DeleteMark(); 1071 } 1072 return true; 1073 } 1074 return false; 1075 } 1076 1077 namespace sw { 1078 1079 bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill, 1080 const uno::Reference< text::XTextRange > & xTextRange) 1081 { 1082 bool bRet = false; 1083 1084 uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY); 1085 SwXTextRange* pRange = 0; 1086 OTextCursorHelper* pCursor = 0; 1087 SwXTextPortion* pPortion = 0; 1088 SwXText* pText = 0; 1089 SwXParagraph* pPara = 0; 1090 if(xRangeTunnel.is()) 1091 { 1092 pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel); 1093 pCursor = 1094 ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel); 1095 pPortion= 1096 ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel); 1097 pText = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel); 1098 pPara = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel); 1099 } 1100 1101 // if it's a text then create a temporary cursor there and re-use 1102 // the pCursor variable 1103 // #i108489#: Reference in outside scope to keep cursor alive 1104 uno::Reference< text::XTextCursor > xTextCursor; 1105 if (pText) 1106 { 1107 xTextCursor.set( pText->CreateCursor() ); 1108 xTextCursor->gotoEnd(sal_True); 1109 const uno::Reference<lang::XUnoTunnel> xCrsrTunnel( 1110 xTextCursor, uno::UNO_QUERY); 1111 pCursor = 1112 ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xCrsrTunnel); 1113 } 1114 if(pRange && pRange->GetDoc() == rToFill.GetDoc()) 1115 { 1116 bRet = pRange->GetPositions(rToFill); 1117 } 1118 else 1119 { 1120 if (pPara) 1121 { 1122 bRet = pPara->SelectPaM(rToFill); 1123 } 1124 else 1125 { 1126 SwDoc* const pDoc = (pCursor) ? pCursor->GetDoc() 1127 : ((pPortion) ? pPortion->GetCursor()->GetDoc() : 0); 1128 const SwPaM* const pUnoCrsr = (pCursor) ? pCursor->GetPaM() 1129 : ((pPortion) ? pPortion->GetCursor() : 0); 1130 if (pUnoCrsr && pDoc == rToFill.GetDoc()) 1131 { 1132 DBG_ASSERT((SwPaM*)pUnoCrsr->GetNext() == pUnoCrsr, 1133 "what to do about rings?"); 1134 bRet = true; 1135 *rToFill.GetPoint() = *pUnoCrsr->GetPoint(); 1136 if (pUnoCrsr->HasMark()) 1137 { 1138 rToFill.SetMark(); 1139 *rToFill.GetMark() = *pUnoCrsr->GetMark(); 1140 } 1141 else 1142 rToFill.DeleteMark(); 1143 } 1144 } 1145 } 1146 return bRet; 1147 } 1148 1149 static bool 1150 lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode *const pSttNode, 1151 SwFrmFmt const*const pFrmFmt, SwFrmFmt*& rpFormat) 1152 { 1153 bool bRet = false; 1154 const SfxItemSet& rSet = pFrmFmt->GetAttrSet(); 1155 const SfxPoolItem* pItem; 1156 if (SFX_ITEM_SET == rSet.GetItemState( 1157 static_cast<sal_uInt16>(bHeader ? RES_HEADER : RES_FOOTER), 1158 sal_True, &pItem)) 1159 { 1160 SfxPoolItem *const pItemNonConst(const_cast<SfxPoolItem *>(pItem)); 1161 SwFrmFmt *const pHeadFootFmt = (bHeader) ? 1162 static_cast<SwFmtHeader*>(pItemNonConst)->GetHeaderFmt() : 1163 static_cast<SwFmtFooter*>(pItemNonConst)->GetFooterFmt(); 1164 if (pHeadFootFmt) 1165 { 1166 const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt(); 1167 const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode(); 1168 SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType( 1169 (bHeader) ? SwHeaderStartNode : SwFooterStartNode); 1170 if (pCurSttNode && (pCurSttNode == pSttNode)) 1171 { 1172 rpFormat = pHeadFootFmt; 1173 bRet = true; 1174 } 1175 } 1176 } 1177 return bRet; 1178 } 1179 1180 } // namespace sw 1181 1182 uno::Reference< text::XTextRange > 1183 SwXTextRange::CreateXTextRange( 1184 SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark) 1185 { 1186 const uno::Reference<text::XText> xParentText( 1187 ::sw::CreateParentXText(rDoc, rPos)); 1188 const ::std::auto_ptr<SwUnoCrsr> pNewCrsr( 1189 rDoc.CreateUnoCrsr(rPos, sal_False)); 1190 if(pMark) 1191 { 1192 pNewCrsr->SetMark(); 1193 *pNewCrsr->GetMark() = *pMark; 1194 } 1195 const bool isCell( dynamic_cast<SwXCell*>(xParentText.get()) ); 1196 const uno::Reference< text::XTextRange > xRet( 1197 new SwXTextRange(*pNewCrsr, xParentText, 1198 isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) ); 1199 return xRet; 1200 } 1201 1202 namespace sw { 1203 1204 uno::Reference< text::XText > 1205 CreateParentXText(SwDoc & rDoc, const SwPosition& rPos) 1206 { 1207 uno::Reference< text::XText > xParentText; 1208 SwStartNode* pSttNode = rPos.nNode.GetNode().StartOfSectionNode(); 1209 while(pSttNode && pSttNode->IsSectionNode()) 1210 { 1211 pSttNode = pSttNode->StartOfSectionNode(); 1212 } 1213 SwStartNodeType eType = pSttNode->GetStartNodeType(); 1214 switch(eType) 1215 { 1216 case SwTableBoxStartNode: 1217 { 1218 SwTableNode const*const pTblNode = pSttNode->FindTableNode(); 1219 SwFrmFmt *const pTableFmt = 1220 static_cast<SwFrmFmt*>(pTblNode->GetTable().GetFrmFmt()); 1221 SwTableBox *const pBox = pSttNode->GetTblBox(); 1222 1223 xParentText = (pBox) 1224 ? SwXCell::CreateXCell( pTableFmt, pBox ) 1225 : new SwXCell( pTableFmt, *pSttNode ); 1226 } 1227 break; 1228 case SwFlyStartNode: 1229 { 1230 SwFrmFmt *const pFmt = pSttNode->GetFlyFmt(); 1231 if (0 != pFmt) 1232 { 1233 SwXTextFrame* pFrame = SwIterator<SwXTextFrame,SwFmt>::FirstElement( *pFmt ); 1234 xParentText = pFrame ? pFrame : new SwXTextFrame( *pFmt ); 1235 } 1236 } 1237 break; 1238 case SwHeaderStartNode: 1239 case SwFooterStartNode: 1240 { 1241 const bool bHeader = (SwHeaderStartNode == eType); 1242 const sal_uInt16 nPDescCount = rDoc.GetPageDescCnt(); 1243 for(sal_uInt16 i = 0; i < nPDescCount; i++) 1244 { 1245 const SwPageDesc& rDesc = 1246 // C++ is retarded 1247 const_cast<SwDoc const&>(rDoc).GetPageDesc( i ); 1248 const SwFrmFmt* pFrmFmtMaster = &rDesc.GetMaster(); 1249 const SwFrmFmt* pFrmFmtLeft = &rDesc.GetLeft(); 1250 1251 SwFrmFmt* pHeadFootFmt = 0; 1252 if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtMaster, 1253 pHeadFootFmt)) 1254 { 1255 lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtLeft, 1256 pHeadFootFmt); 1257 } 1258 1259 if (pHeadFootFmt) 1260 { 1261 xParentText = SwXHeadFootText::CreateXHeadFootText( 1262 *pHeadFootFmt, bHeader); 1263 } 1264 } 1265 } 1266 break; 1267 case SwFootnoteStartNode: 1268 { 1269 const sal_uInt16 nFtnCnt = rDoc.GetFtnIdxs().Count(); 1270 uno::Reference< text::XFootnote > xRef; 1271 for (sal_uInt16 n = 0; n < nFtnCnt; ++n ) 1272 { 1273 const SwTxtFtn* pTxtFtn = rDoc.GetFtnIdxs()[ n ]; 1274 const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); 1275 pTxtFtn = rFtn.GetTxtFtn(); 1276 #if OSL_DEBUG_LEVEL > 1 1277 const SwStartNode* pTmpSttNode = 1278 pTxtFtn->GetStartNode()->GetNode(). 1279 FindSttNodeByType(SwFootnoteStartNode); 1280 (void)pTmpSttNode; 1281 #endif 1282 1283 if (pSttNode == pTxtFtn->GetStartNode()->GetNode(). 1284 FindSttNodeByType(SwFootnoteStartNode)) 1285 { 1286 xParentText = SwXFootnote::CreateXFootnote(rDoc, rFtn); 1287 break; 1288 } 1289 } 1290 } 1291 break; 1292 default: 1293 { 1294 // then it is the body text 1295 const uno::Reference<frame::XModel> xModel = 1296 rDoc.GetDocShell()->GetBaseModel(); 1297 const uno::Reference< text::XTextDocument > xDoc( 1298 xModel, uno::UNO_QUERY); 1299 xParentText = xDoc->getText(); 1300 } 1301 } 1302 OSL_ENSURE(xParentText.is(), "no parent text?"); 1303 return xParentText; 1304 } 1305 1306 } // namespace sw 1307 1308 uno::Reference< container::XEnumeration > SAL_CALL 1309 SwXTextRange::createContentEnumeration(const OUString& rServiceName) 1310 throw (uno::RuntimeException) 1311 { 1312 vos::OGuard g(Application::GetSolarMutex()); 1313 1314 if (!rServiceName.equalsAscii("com.sun.star.text.TextContent")) 1315 { 1316 throw uno::RuntimeException(); 1317 } 1318 1319 if (!GetDoc() || !m_pImpl->GetBookmark()) 1320 { 1321 throw uno::RuntimeException(); 1322 } 1323 const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent()); 1324 const ::std::auto_ptr<SwUnoCrsr> pNewCrsr( 1325 m_pImpl->m_rDoc.CreateUnoCrsr(aPos, sal_False)); 1326 if (!GetPositions(*pNewCrsr)) 1327 { 1328 throw uno::RuntimeException(); 1329 } 1330 1331 const uno::Reference< container::XEnumeration > xRet = 1332 new SwXParaFrameEnumeration(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE); 1333 return xRet; 1334 } 1335 1336 uno::Reference< container::XEnumeration > SAL_CALL 1337 SwXTextRange::createEnumeration() throw (uno::RuntimeException) 1338 { 1339 vos::OGuard g(Application::GetSolarMutex()); 1340 1341 if (!GetDoc() || !m_pImpl->GetBookmark()) 1342 { 1343 throw uno::RuntimeException(); 1344 } 1345 const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent()); 1346 ::std::auto_ptr<SwUnoCrsr> pNewCrsr( 1347 m_pImpl->m_rDoc.CreateUnoCrsr(aPos, sal_False)); 1348 if (!GetPositions(*pNewCrsr)) 1349 { 1350 throw uno::RuntimeException(); 1351 } 1352 if (!m_pImpl->m_xParentText.is()) 1353 { 1354 getText(); 1355 } 1356 1357 const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition) 1358 ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION; 1359 const uno::Reference< container::XEnumeration > xRet = 1360 new SwXParagraphEnumeration(m_pImpl->m_xParentText, pNewCrsr, eSetType); 1361 return xRet; 1362 } 1363 1364 uno::Type SAL_CALL SwXTextRange::getElementType() throw (uno::RuntimeException) 1365 { 1366 return text::XTextRange::static_type(); 1367 } 1368 1369 sal_Bool SAL_CALL SwXTextRange::hasElements() throw (uno::RuntimeException) 1370 { 1371 return sal_True; 1372 } 1373 1374 uno::Sequence< OUString > SAL_CALL 1375 SwXTextRange::getAvailableServiceNames() throw (uno::RuntimeException) 1376 { 1377 uno::Sequence< OUString > aRet(1); 1378 OUString* pArray = aRet.getArray(); 1379 pArray[0] = OUString::createFromAscii("com.sun.star.text.TextContent"); 1380 return aRet; 1381 } 1382 1383 uno::Reference< beans::XPropertySetInfo > SAL_CALL 1384 SwXTextRange::getPropertySetInfo() throw (uno::RuntimeException) 1385 { 1386 vos::OGuard aGuard(Application::GetSolarMutex()); 1387 1388 static uno::Reference< beans::XPropertySetInfo > xRef = 1389 m_pImpl->m_rPropSet.getPropertySetInfo(); 1390 return xRef; 1391 } 1392 1393 void SAL_CALL 1394 SwXTextRange::setPropertyValue( 1395 const OUString& rPropertyName, const uno::Any& rValue) 1396 throw (beans::UnknownPropertyException, beans::PropertyVetoException, 1397 lang::IllegalArgumentException, lang::WrappedTargetException, 1398 uno::RuntimeException) 1399 { 1400 vos::OGuard aGuard(Application::GetSolarMutex()); 1401 1402 if (!GetDoc() || !m_pImpl->GetBookmark()) 1403 { 1404 throw uno::RuntimeException(); 1405 } 1406 SwPaM aPaM(GetDoc()->GetNodes()); 1407 GetPositions(aPaM); 1408 SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet, 1409 rPropertyName, rValue); 1410 } 1411 1412 uno::Any SAL_CALL 1413 SwXTextRange::getPropertyValue(const OUString& rPropertyName) 1414 throw (beans::UnknownPropertyException, lang::WrappedTargetException, 1415 uno::RuntimeException) 1416 { 1417 vos::OGuard aGuard(Application::GetSolarMutex()); 1418 1419 if (!GetDoc() || !m_pImpl->GetBookmark()) 1420 { 1421 throw uno::RuntimeException(); 1422 } 1423 SwPaM aPaM(GetDoc()->GetNodes()); 1424 GetPositions(aPaM); 1425 return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet, 1426 rPropertyName); 1427 } 1428 1429 void SAL_CALL 1430 SwXTextRange::addPropertyChangeListener( 1431 const ::rtl::OUString& /*rPropertyName*/, 1432 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/) 1433 throw (beans::UnknownPropertyException, lang::WrappedTargetException, 1434 uno::RuntimeException) 1435 { 1436 OSL_ENSURE(false, 1437 "SwXTextRange::addPropertyChangeListener(): not implemented"); 1438 } 1439 1440 void SAL_CALL 1441 SwXTextRange::removePropertyChangeListener( 1442 const ::rtl::OUString& /*rPropertyName*/, 1443 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/) 1444 throw (beans::UnknownPropertyException, lang::WrappedTargetException, 1445 uno::RuntimeException) 1446 { 1447 OSL_ENSURE(false, 1448 "SwXTextRange::removePropertyChangeListener(): not implemented"); 1449 } 1450 1451 void SAL_CALL 1452 SwXTextRange::addVetoableChangeListener( 1453 const ::rtl::OUString& /*rPropertyName*/, 1454 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/) 1455 throw (beans::UnknownPropertyException, lang::WrappedTargetException, 1456 uno::RuntimeException) 1457 { 1458 OSL_ENSURE(false, 1459 "SwXTextRange::addVetoableChangeListener(): not implemented"); 1460 } 1461 1462 void SAL_CALL 1463 SwXTextRange::removeVetoableChangeListener( 1464 const ::rtl::OUString& /*rPropertyName*/, 1465 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/) 1466 throw (beans::UnknownPropertyException, lang::WrappedTargetException, 1467 uno::RuntimeException) 1468 { 1469 OSL_ENSURE(false, 1470 "SwXTextRange::removeVetoableChangeListener(): not implemented"); 1471 } 1472 1473 beans::PropertyState SAL_CALL 1474 SwXTextRange::getPropertyState(const OUString& rPropertyName) 1475 throw (beans::UnknownPropertyException, uno::RuntimeException) 1476 { 1477 vos::OGuard aGuard(Application::GetSolarMutex()); 1478 1479 if (!GetDoc() || !m_pImpl->GetBookmark()) 1480 { 1481 throw uno::RuntimeException(); 1482 } 1483 SwPaM aPaM(GetDoc()->GetNodes()); 1484 GetPositions(aPaM); 1485 return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet, 1486 rPropertyName); 1487 } 1488 1489 uno::Sequence< beans::PropertyState > SAL_CALL 1490 SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName) 1491 throw (beans::UnknownPropertyException, uno::RuntimeException) 1492 { 1493 vos::OGuard g(Application::GetSolarMutex()); 1494 1495 if (!GetDoc() || !m_pImpl->GetBookmark()) 1496 { 1497 throw uno::RuntimeException(); 1498 } 1499 SwPaM aPaM(GetDoc()->GetNodes()); 1500 GetPositions(aPaM); 1501 return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet, 1502 rPropertyName); 1503 } 1504 1505 void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName) 1506 throw (beans::UnknownPropertyException, uno::RuntimeException) 1507 { 1508 vos::OGuard aGuard(Application::GetSolarMutex()); 1509 1510 if (!GetDoc() || !m_pImpl->GetBookmark()) 1511 { 1512 throw uno::RuntimeException(); 1513 } 1514 SwPaM aPaM(GetDoc()->GetNodes()); 1515 GetPositions(aPaM); 1516 SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet, 1517 rPropertyName); 1518 } 1519 1520 uno::Any SAL_CALL 1521 SwXTextRange::getPropertyDefault(const OUString& rPropertyName) 1522 throw (beans::UnknownPropertyException, lang::WrappedTargetException, 1523 uno::RuntimeException) 1524 { 1525 vos::OGuard aGuard(Application::GetSolarMutex()); 1526 1527 if (!GetDoc() || !m_pImpl->GetBookmark()) 1528 { 1529 throw uno::RuntimeException(); 1530 } 1531 SwPaM aPaM(GetDoc()->GetNodes()); 1532 GetPositions(aPaM); 1533 return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet, 1534 rPropertyName); 1535 } 1536 1537 void SAL_CALL 1538 SwXTextRange::makeRedline( 1539 const ::rtl::OUString& rRedlineType, 1540 const uno::Sequence< beans::PropertyValue >& rRedlineProperties ) 1541 throw (lang::IllegalArgumentException, uno::RuntimeException) 1542 { 1543 vos::OGuard aGuard(Application::GetSolarMutex()); 1544 1545 if (!GetDoc() || !m_pImpl->GetBookmark()) 1546 { 1547 throw uno::RuntimeException(); 1548 } 1549 SwPaM aPaM(GetDoc()->GetNodes()); 1550 SwXTextRange::GetPositions(aPaM); 1551 SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties ); 1552 } 1553 1554 /****************************************************************** 1555 * SwXTextRanges 1556 ******************************************************************/ 1557 1558 class SwXTextRanges::Impl 1559 : public SwClient 1560 { 1561 1562 public: 1563 1564 ::std::vector< uno::Reference< text::XTextRange > > m_Ranges; 1565 1566 Impl(SwPaM *const pPaM) 1567 : SwClient( (pPaM) 1568 ? pPaM->GetDoc()->CreateUnoCrsr(*pPaM->GetPoint()) 1569 : 0 ) 1570 { 1571 if (pPaM) 1572 { 1573 ::sw::DeepCopyPaM(*pPaM, *GetCursor()); 1574 } 1575 MakeRanges(); 1576 } 1577 1578 ~Impl() { 1579 // Impl owns the cursor; delete it here: SolarMutex is locked 1580 delete GetRegisteredIn(); 1581 } 1582 1583 SwUnoCrsr * GetCursor() { 1584 return static_cast<SwUnoCrsr*>( 1585 const_cast<SwModify*>(GetRegisteredIn())); 1586 } 1587 1588 void MakeRanges(); 1589 protected: 1590 // SwClient 1591 virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew); 1592 1593 }; 1594 1595 void SwXTextRanges::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) 1596 { 1597 ClientModify(this, pOld, pNew); 1598 } 1599 1600 void SwXTextRanges::Impl::MakeRanges() 1601 { 1602 SwUnoCrsr *const pCursor = GetCursor(); 1603 if (pCursor) 1604 { 1605 SwPaM *pTmpCursor = pCursor; 1606 do { 1607 const uno::Reference< text::XTextRange > xRange( 1608 SwXTextRange::CreateXTextRange( 1609 *pTmpCursor->GetDoc(), 1610 *pTmpCursor->GetPoint(), pTmpCursor->GetMark())); 1611 if (xRange.is()) 1612 { 1613 m_Ranges.push_back(xRange); 1614 } 1615 pTmpCursor = static_cast<SwPaM*>(pTmpCursor->GetNext()); 1616 } 1617 while (pTmpCursor != pCursor); 1618 } 1619 } 1620 1621 const SwUnoCrsr* SwXTextRanges::GetCursor() const 1622 { 1623 return m_pImpl->GetCursor(); 1624 } 1625 1626 SwXTextRanges::SwXTextRanges(SwPaM *const pPaM) 1627 : m_pImpl( new SwXTextRanges::Impl(pPaM) ) 1628 { 1629 } 1630 1631 SwXTextRanges::~SwXTextRanges() 1632 { 1633 } 1634 1635 const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId() 1636 { 1637 static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId(); 1638 return aSeq; 1639 } 1640 1641 sal_Int64 SAL_CALL 1642 SwXTextRanges::getSomething(const uno::Sequence< sal_Int8 >& rId) 1643 throw (uno::RuntimeException) 1644 { 1645 return ::sw::UnoTunnelImpl<SwXTextRanges>(rId, this); 1646 } 1647 1648 /**************************************************************************** 1649 * Text positions 1650 * Bis zum ersten Zugriff auf eine TextPosition wird ein SwCursor gehalten, 1651 * danach wird ein Array mit uno::Reference< XTextPosition > angelegt 1652 * 1653 ****************************************************************************/ 1654 OUString SAL_CALL 1655 SwXTextRanges::getImplementationName() throw (uno::RuntimeException) 1656 { 1657 return C2U("SwXTextRanges"); 1658 } 1659 1660 static char const*const g_ServicesTextRanges[] = 1661 { 1662 "com.sun.star.text.TextRanges", 1663 }; 1664 static const size_t g_nServicesTextRanges( 1665 sizeof(g_ServicesTextRanges)/sizeof(g_ServicesTextRanges[0])); 1666 1667 sal_Bool SAL_CALL SwXTextRanges::supportsService(const OUString& rServiceName) 1668 throw (uno::RuntimeException) 1669 { 1670 return ::sw::SupportsServiceImpl( 1671 g_nServicesTextRanges, g_ServicesTextRanges, rServiceName); 1672 } 1673 1674 uno::Sequence< OUString > SAL_CALL 1675 SwXTextRanges::getSupportedServiceNames() throw (uno::RuntimeException) 1676 { 1677 return ::sw::GetSupportedServiceNamesImpl( 1678 g_nServicesTextRanges, g_ServicesTextRanges); 1679 } 1680 1681 sal_Int32 SAL_CALL SwXTextRanges::getCount() throw (uno::RuntimeException) 1682 { 1683 vos::OGuard aGuard(Application::GetSolarMutex()); 1684 1685 return static_cast<sal_Int32>(m_pImpl->m_Ranges.size()); 1686 } 1687 1688 uno::Any SAL_CALL SwXTextRanges::getByIndex(sal_Int32 nIndex) 1689 throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, 1690 uno::RuntimeException) 1691 { 1692 vos::OGuard aGuard(Application::GetSolarMutex()); 1693 1694 if ((nIndex < 0) || 1695 (static_cast<size_t>(nIndex) >= m_pImpl->m_Ranges.size())) 1696 { 1697 throw lang::IndexOutOfBoundsException(); 1698 } 1699 uno::Any ret; 1700 ret <<= (m_pImpl->m_Ranges.at(nIndex)); 1701 return ret; 1702 } 1703 1704 uno::Type SAL_CALL 1705 SwXTextRanges::getElementType() throw (uno::RuntimeException) 1706 { 1707 return text::XTextRange::static_type(); 1708 } 1709 1710 sal_Bool SAL_CALL SwXTextRanges::hasElements() throw (uno::RuntimeException) 1711 { 1712 // no mutex necessary: getCount() does locking 1713 return getCount() > 0; 1714 } 1715 1716 void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString) 1717 { 1718 // Start/EndAction 1719 SwDoc *const pDoc = rCursor.GetDoc(); 1720 UnoActionContext aAction(pDoc); 1721 pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL); 1722 if (rCursor.HasMark()) 1723 { 1724 pDoc->DeleteAndJoin(rCursor); 1725 } 1726 if (rString.getLength()) 1727 { 1728 String aText(rString); 1729 const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR( 1730 *pDoc, rCursor, aText, false ) ); 1731 DBG_ASSERT( bSuccess, "DocInsertStringSplitCR" ); 1732 (void) bSuccess; 1733 SwUnoCursorHelper::SelectPam(rCursor, true); 1734 rCursor.Left(rString.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False); 1735 } 1736 pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL); 1737 } 1738 1739 /****************************************************************** 1740 * SwXParaFrameEnumeration 1741 ******************************************************************/ 1742 1743 class SwXParaFrameEnumeration::Impl 1744 : public SwClient 1745 { 1746 1747 public: 1748 1749 // created by hasMoreElements 1750 uno::Reference< text::XTextContent > m_xNextObject; 1751 FrameDependList_t m_Frames; 1752 1753 Impl(SwPaM const & rPaM) 1754 : SwClient(rPaM.GetDoc()->CreateUnoCrsr(*rPaM.GetPoint(), sal_False)) 1755 { 1756 if (rPaM.HasMark()) 1757 { 1758 GetCursor()->SetMark(); 1759 *GetCursor()->GetMark() = *rPaM.GetMark(); 1760 } 1761 } 1762 1763 ~Impl() { 1764 // Impl owns the cursor; delete it here: SolarMutex is locked 1765 delete GetRegisteredIn(); 1766 } 1767 1768 SwUnoCrsr * GetCursor() { 1769 return static_cast<SwUnoCrsr*>( 1770 const_cast<SwModify*>(GetRegisteredIn())); 1771 } 1772 protected: 1773 // SwClient 1774 virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew); 1775 1776 }; 1777 1778 struct InvalidFrameDepend { 1779 bool operator() (::boost::shared_ptr<SwDepend> const & rEntry) 1780 { return !rEntry->GetRegisteredIn(); } 1781 }; 1782 1783 void SwXParaFrameEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) 1784 { 1785 ClientModify(this, pOld, pNew); 1786 if(!GetRegisteredIn()) 1787 { 1788 m_Frames.clear(); 1789 m_xNextObject = 0; 1790 } 1791 else 1792 { 1793 // check if any frame went away... 1794 FrameDependList_t::iterator const iter = 1795 ::std::remove_if(m_Frames.begin(), m_Frames.end(), 1796 InvalidFrameDepend()); 1797 m_Frames.erase(iter, m_Frames.end()); 1798 } 1799 } 1800 1801 static sal_Bool 1802 lcl_CreateNextObject(SwUnoCrsr& i_rUnoCrsr, 1803 uno::Reference<text::XTextContent> & o_rNextObject, 1804 FrameDependList_t & i_rFrames) 1805 { 1806 if (!i_rFrames.size()) 1807 return sal_False; 1808 1809 SwFrmFmt *const pFormat = static_cast<SwFrmFmt*>(const_cast<SwModify*>( 1810 i_rFrames.front()->GetRegisteredIn())); 1811 i_rFrames.pop_front(); 1812 // the format should be valid here, otherwise the client 1813 // would have been removed in ::Modify 1814 // check for a shape first 1815 SwDrawContact* const pContact = SwIterator<SwDrawContact,SwFmt>::FirstElement( *pFormat ); 1816 if (pContact) 1817 { 1818 SdrObject * const pSdr = pContact->GetMaster(); 1819 if (pSdr) 1820 { 1821 o_rNextObject.set(pSdr->getUnoShape(), uno::UNO_QUERY); 1822 } 1823 } 1824 else 1825 { 1826 const SwNodeIndex* pIdx = pFormat->GetCntnt().GetCntntIdx(); 1827 DBG_ASSERT(pIdx, "where is the index?"); 1828 SwNode const*const pNd = 1829 i_rUnoCrsr.GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ]; 1830 1831 const FlyCntType eType = (!pNd->IsNoTxtNode()) ? FLYCNTTYPE_FRM 1832 : ( (pNd->IsGrfNode()) ? FLYCNTTYPE_GRF : FLYCNTTYPE_OLE ); 1833 1834 const uno::Reference< container::XNamed > xFrame = 1835 SwXFrames::GetObject(*pFormat, eType); 1836 o_rNextObject.set(xFrame, uno::UNO_QUERY); 1837 } 1838 1839 return o_rNextObject.is(); 1840 } 1841 1842 /* -----------------------------03.04.00 10:15-------------------------------- 1843 Description: Search for a FLYCNT text attribute at the cursor point 1844 and fill the frame into the array 1845 ---------------------------------------------------------------------------*/ 1846 static void 1847 lcl_FillFrame(SwClient & rEnum, SwUnoCrsr& rUnoCrsr, 1848 FrameDependList_t & rFrames) 1849 { 1850 // search for objects at the cursor - anchored at/as char 1851 SwTxtAttr const*const pTxtAttr = 1852 rUnoCrsr.GetNode()->GetTxtNode()->GetTxtAttrForCharAt( 1853 rUnoCrsr.GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT); 1854 if (pTxtAttr) 1855 { 1856 const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt(); 1857 SwFrmFmt * const pFrmFmt = rFlyCnt.GetFrmFmt(); 1858 SwDepend * const pNewDepend = new SwDepend(&rEnum, pFrmFmt); 1859 rFrames.push_back( ::boost::shared_ptr<SwDepend>(pNewDepend) ); 1860 } 1861 } 1862 1863 SwXParaFrameEnumeration::SwXParaFrameEnumeration( 1864 const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, 1865 SwFrmFmt *const pFmt) 1866 : m_pImpl( new SwXParaFrameEnumeration::Impl(rPaM) ) 1867 { 1868 if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode) 1869 { 1870 FrameDependSortList_t frames; 1871 ::CollectFrameAtNode(*m_pImpl.get(), rPaM.GetPoint()->nNode, 1872 frames, false); 1873 ::std::transform(frames.begin(), frames.end(), 1874 ::std::back_inserter(m_pImpl->m_Frames), 1875 ::boost::bind(&FrameDependSortListEntry::pFrameDepend, _1)); 1876 } 1877 else if (pFmt) 1878 { 1879 // create SwDepend for frame and insert into array 1880 SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFmt); 1881 m_pImpl->m_Frames.push_back(::boost::shared_ptr<SwDepend>(pNewDepend)); 1882 } 1883 else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) || 1884 (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)) 1885 { 1886 if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode) 1887 { 1888 SwPosFlyFrms aFlyFrms; 1889 //get all frames that are bound at paragraph or at character 1890 rPaM.GetDoc()->GetAllFlyFmts(aFlyFrms, m_pImpl->GetCursor()); 1891 for(sal_uInt16 i = 0; i < aFlyFrms.Count(); i++) 1892 { 1893 SwPosFlyFrm* pPosFly = aFlyFrms[i]; 1894 SwFrmFmt *const pFrmFmt = 1895 const_cast<SwFrmFmt*>(&pPosFly->GetFmt()); 1896 // create SwDepend for frame and insert into array 1897 SwDepend *const pNewDepend = 1898 new SwDepend(m_pImpl.get(), pFrmFmt); 1899 m_pImpl->m_Frames.push_back( 1900 ::boost::shared_ptr<SwDepend>(pNewDepend) ); 1901 } 1902 //created from any text range 1903 if (m_pImpl->GetCursor()->HasMark()) 1904 { 1905 m_pImpl->GetCursor()->Normalize(); 1906 do 1907 { 1908 lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(), 1909 m_pImpl->m_Frames); 1910 m_pImpl->GetCursor()->Right( 1911 1, CRSR_SKIP_CHARS, sal_False, sal_False); 1912 } 1913 while (*m_pImpl->GetCursor()->GetPoint() < 1914 *m_pImpl->GetCursor()->GetMark()); 1915 } 1916 } 1917 lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(), m_pImpl->m_Frames); 1918 } 1919 } 1920 1921 SwXParaFrameEnumeration::~SwXParaFrameEnumeration() 1922 { 1923 } 1924 1925 sal_Bool SAL_CALL 1926 SwXParaFrameEnumeration::hasMoreElements() throw (uno::RuntimeException) 1927 { 1928 vos::OGuard aGuard(Application::GetSolarMutex()); 1929 1930 if (!m_pImpl->GetCursor()) 1931 throw uno::RuntimeException(); 1932 1933 return (m_pImpl->m_xNextObject.is()) 1934 ? sal_True 1935 : lcl_CreateNextObject(*m_pImpl->GetCursor(), 1936 m_pImpl->m_xNextObject, m_pImpl->m_Frames); 1937 } 1938 1939 uno::Any SAL_CALL SwXParaFrameEnumeration::nextElement() 1940 throw (container::NoSuchElementException, 1941 lang::WrappedTargetException, uno::RuntimeException) 1942 { 1943 vos::OGuard aGuard(Application::GetSolarMutex()); 1944 1945 if (!m_pImpl->GetCursor()) 1946 { 1947 throw uno::RuntimeException(); 1948 } 1949 1950 if (!m_pImpl->m_xNextObject.is() && m_pImpl->m_Frames.size()) 1951 { 1952 lcl_CreateNextObject(*m_pImpl->GetCursor(), 1953 m_pImpl->m_xNextObject, m_pImpl->m_Frames); 1954 } 1955 if (!m_pImpl->m_xNextObject.is()) 1956 { 1957 throw container::NoSuchElementException(); 1958 } 1959 uno::Any aRet; 1960 aRet <<= m_pImpl->m_xNextObject; 1961 m_pImpl->m_xNextObject = 0; 1962 return aRet; 1963 } 1964 1965 OUString SAL_CALL 1966 SwXParaFrameEnumeration::getImplementationName() throw (uno::RuntimeException) 1967 { 1968 return C2U("SwXParaFrameEnumeration"); 1969 } 1970 1971 static char const*const g_ServicesParaFrameEnum[] = 1972 { 1973 "com.sun.star.util.ContentEnumeration", 1974 }; 1975 static const size_t g_nServicesParaFrameEnum( 1976 sizeof(g_ServicesParaFrameEnum)/sizeof(g_ServicesParaFrameEnum[0])); 1977 1978 sal_Bool SAL_CALL 1979 SwXParaFrameEnumeration::supportsService(const OUString& rServiceName) 1980 throw (uno::RuntimeException) 1981 { 1982 return ::sw::SupportsServiceImpl( 1983 g_nServicesParaFrameEnum, g_ServicesParaFrameEnum, rServiceName); 1984 } 1985 1986 uno::Sequence< OUString > SAL_CALL 1987 SwXParaFrameEnumeration::getSupportedServiceNames() 1988 throw (uno::RuntimeException) 1989 { 1990 return ::sw::GetSupportedServiceNamesImpl( 1991 g_nServicesParaFrameEnum, g_ServicesParaFrameEnum); 1992 } 1993 1994