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