/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define _SVSTDARR_USHORTS #define _SVSTDARR_USHORTSSORT #define _SVSTDARR_XUB_STRLEN #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using ::rtl::OUString; namespace sw { sal_Bool SupportsServiceImpl( size_t const nServices, char const*const pServices[], ::rtl::OUString const & rServiceName) { for (size_t i = 0; i < nServices; ++i) { if (rServiceName.equalsAscii(pServices[i])) { return sal_True; } } return sal_False; } uno::Sequence< ::rtl::OUString > GetSupportedServiceNamesImpl( size_t const nServices, char const*const pServices[]) { uno::Sequence< ::rtl::OUString > ret(nServices); for (size_t i = 0; i < nServices; ++i) { ret[i] = C2U(pServices[i]); } return ret; } } // namespace sw namespace sw { void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget) { rTarget = rSource; if (rSource.GetNext() != &rSource) { SwPaM *pPam = static_cast(rSource.GetNext()); do { // create new PaM SwPaM *const pNew = new SwPaM(*pPam); // insert into ring pNew->MoveTo(&rTarget); pPam = static_cast(pPam->GetNext()); } while (pPam != &rSource); } } } // namespace sw struct FrameDependSortListLess { bool operator() (FrameDependSortListEntry const& r1, FrameDependSortListEntry const& r2) { return (r1.nIndex < r2.nIndex) || ((r1.nIndex == r2.nIndex) && (r1.nOrder < r2.nOrder)); } }; // OD 2004-05-07 #i28701# - adjust 4th parameter void CollectFrameAtNode( SwClient& rClnt, const SwNodeIndex& rIdx, FrameDependSortList_t & rFrames, const bool _bAtCharAnchoredObjs ) { // _bAtCharAnchoredObjs: // : at-character anchored objects are collected // : at-paragraph anchored objects are collected // alle Rahmen, Grafiken und OLEs suchen, die an diesem Absatz // gebunden sind SwDoc* pDoc = rIdx.GetNode().GetDoc(); sal_uInt16 nChkType = static_cast< sal_uInt16 >((_bAtCharAnchoredObjs) ? FLY_AT_CHAR : FLY_AT_PARA); const SwCntntFrm* pCFrm; const SwCntntNode* pCNd; if( pDoc->GetCurrentViewShell() && //swmod 071108//swmod 071225 0 != (pCNd = rIdx.GetNode().GetCntntNode()) && 0 != (pCFrm = pCNd->getLayoutFrm( pDoc->GetCurrentLayout())) ) { const SwSortedObjs *pObjs = pCFrm->GetDrawObjs(); if( pObjs ) for( sal_uInt16 i = 0; i < pObjs->Count(); ++i ) { SwAnchoredObject* pAnchoredObj = (*pObjs)[i]; SwFrmFmt& rFmt = pAnchoredObj->GetFrmFmt(); if ( rFmt.GetAnchor().GetAnchorId() == nChkType ) { // create SwDepend and insert into array SwDepend* pNewDepend = new SwDepend( &rClnt, &rFmt ); xub_StrLen idx = rFmt.GetAnchor().GetCntntAnchor()->nContent.GetIndex(); sal_uInt32 nOrder = rFmt.GetAnchor().GetOrder(); // OD 2004-05-07 #i28701# - sorting no longer needed, // because list is already sorted. FrameDependSortListEntry entry(idx, nOrder, pNewDepend); rFrames.push_back(entry); } } } else { const SwSpzFrmFmts& rFmts = *pDoc->GetSpzFrmFmts(); sal_uInt16 nSize = rFmts.Count(); for ( sal_uInt16 i = 0; i < nSize; i++) { const SwFrmFmt* pFmt = rFmts[ i ]; const SwFmtAnchor& rAnchor = pFmt->GetAnchor(); const SwPosition* pAnchorPos; if( rAnchor.GetAnchorId() == nChkType && 0 != (pAnchorPos = rAnchor.GetCntntAnchor()) && pAnchorPos->nNode == rIdx ) { //jetzt einen SwDepend anlegen und in das Array einfuegen SwDepend* pNewDepend = new SwDepend( &rClnt, (SwFrmFmt*)pFmt); // OD 2004-05-07 #i28701# - determine insert position for // sorted xub_StrLen nIndex = pAnchorPos->nContent.GetIndex(); sal_uInt32 nOrder = rAnchor.GetOrder(); FrameDependSortListEntry entry(nIndex, nOrder, pNewDepend); rFrames.push_back(entry); } } ::std::sort(rFrames.begin(), rFrames.end(), FrameDependSortListLess()); } } /**************************************************************************** ActionContext ****************************************************************************/ UnoActionContext::UnoActionContext(SwDoc *const pDoc) : m_pDoc(pDoc) { SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); if (pRootFrm) { pRootFrm->StartAllAction(); } } UnoActionContext::~UnoActionContext() { // Doc may already have been removed here if (m_pDoc) { SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); if (pRootFrm) { pRootFrm->EndAllAction(); } } } /**************************************************************************** ActionRemoveContext ****************************************************************************/ UnoActionRemoveContext::UnoActionRemoveContext(SwDoc *const pDoc) : m_pDoc(pDoc) { SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); if (pRootFrm) { pRootFrm->UnoRemoveAllActions(); } } /* -----------------07.07.98 12:05------------------- * * --------------------------------------------------*/ UnoActionRemoveContext::~UnoActionRemoveContext() { SwRootFrm *const pRootFrm = m_pDoc->GetCurrentLayout(); if (pRootFrm) { pRootFrm->UnoRestoreAllActions(); } } void ClientModify(SwClient* pClient, const SfxPoolItem *pOld, const SfxPoolItem *pNew) { switch( pOld ? pOld->Which() : 0 ) { case RES_REMOVE_UNO_OBJECT: case RES_OBJECTDYING: if( (void*)pClient->GetRegisteredIn() == ((SwPtrMsgPoolItem *)pOld)->pObject ) ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient); break; case RES_FMT_CHG: // wurden wir an das neue umgehaengt und wird das alte geloscht? if( ((SwFmtChg*)pNew)->pChangedFmt == pClient->GetRegisteredIn() && ((SwFmtChg*)pOld)->pChangedFmt->IsFmtInDTOR() ) ((SwModify*)pClient->GetRegisteredIn())->Remove(pClient); break; } } void SwUnoCursorHelper::SetCrsrAttr(SwPaM & rPam, const SfxItemSet& rSet, const SetAttrMode nAttrMode, const bool bTableMode) { const SetAttrMode nFlags = nAttrMode | nsSetAttrMode::SETATTR_APICALL; SwDoc* pDoc = rPam.GetDoc(); //StartEndAction UnoActionContext aAction(pDoc); if (rPam.GetNext() != &rPam) // Ring of Cursors { pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSATTR, NULL); SwPaM *pCurrent = &rPam; do { if (pCurrent->HasMark() && ( (bTableMode) || (*pCurrent->GetPoint() != *pCurrent->GetMark()) )) { pDoc->InsertItemSet(*pCurrent, rSet, nFlags); } pCurrent= static_cast(pCurrent->GetNext()); } while (pCurrent != &rPam); pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSATTR, NULL); } else { // if( !HasSelection() ) // UpdateAttr(); pDoc->InsertItemSet( rPam, rSet, nFlags ); } //#outline level,add by zhaojianwei if( rSet.GetItemState( RES_PARATR_OUTLINELEVEL, false ) >= SFX_ITEM_AVAILABLE ) { SwTxtNode * pTmpNode = rPam.GetNode()->GetTxtNode(); if ( pTmpNode ) { rPam.GetDoc()->GetNodes().UpdateOutlineNode( *pTmpNode ); } } //<-end,zhaojianwei } // --> OD 2006-07-12 #i63870# // split third parameter into new parameters // and to get better control about resulting void SwUnoCursorHelper::GetCrsrAttr(SwPaM & rPam, SfxItemSet & rSet, const bool bOnlyTxtAttr, const bool bGetFromChrFmt) { static const sal_uInt16 nMaxLookup = 1000; SfxItemSet aSet( *rSet.GetPool(), rSet.GetRanges() ); SfxItemSet *pSet = &rSet; SwPaM *pCurrent = & rPam; do { SwPosition const & rStart( *pCurrent->Start() ); SwPosition const & rEnd( *pCurrent->End() ); const sal_uLong nSttNd = rStart.nNode.GetIndex(); const sal_uLong nEndNd = rEnd .nNode.GetIndex(); if (nEndNd - nSttNd >= nMaxLookup) { rSet.ClearItem(); rSet.InvalidateAllItems(); return;// uno::Any(); } // the first node inserts the values into the get set // all other nodes merge their values into the get set for (sal_uLong n = nSttNd; n <= nEndNd; ++n) { SwNode *const pNd = rPam.GetDoc()->GetNodes()[ n ]; switch (pNd->GetNodeType()) { case ND_TEXTNODE: { const xub_StrLen nStart = (n == nSttNd) ? rStart.nContent.GetIndex() : 0; const xub_StrLen nEnd = (n == nEndNd) ? rEnd.nContent.GetIndex() : static_cast(pNd)->GetTxt().Len(); static_cast(pNd)->GetAttr( *pSet, nStart, nEnd, bOnlyTxtAttr, bGetFromChrFmt); } break; case ND_GRFNODE: case ND_OLENODE: static_cast(pNd)->GetAttr( *pSet ); break; default: continue; // skip this node } if (pSet != &rSet) { rSet.MergeValues( aSet ); } else { pSet = &aSet; } if (aSet.Count()) { aSet.ClearItem(); } } pCurrent= static_cast(pCurrent->GetNext()); } while ( pCurrent != &rPam ); } /****************************************************************** * SwXParagraphEnumeration ******************************************************************/ class SwXParagraphEnumeration::Impl : public SwClient { public: uno::Reference< text::XText > const m_xParentText; const CursorType m_eCursorType; /// Start node of the cell _or_ table the enumeration belongs to. /// Used to restrict the movement of the UNO cursor to the cell and its /// embedded tables. SwStartNode const*const m_pOwnStartNode; SwTable const*const m_pOwnTable; const sal_uLong m_nEndIndex; sal_Int32 m_nFirstParaStart; sal_Int32 m_nLastParaEnd; bool m_bFirstParagraph; uno::Reference< text::XTextContent > m_xNextPara; Impl( uno::Reference< text::XText > const& xParent, ::std::auto_ptr pCursor, const CursorType eType, SwStartNode const*const pStartNode, SwTable const*const pTable) : SwClient( pCursor.release() ) , m_xParentText( xParent ) , m_eCursorType( eType ) // remember table and start node for later travelling // (used in export of tables in tables) , m_pOwnStartNode( pStartNode ) // for import of tables in tables we have to remember the actual // table and start node of the current position in the enumeration. , m_pOwnTable( pTable ) , m_nEndIndex( GetCursor()->End()->nNode.GetIndex() ) , m_nFirstParaStart( -1 ) , m_nLastParaEnd( -1 ) , m_bFirstParagraph( true ) { OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?"); OSL_ENSURE(GetRegisteredIn(), "SwXParagraphEnumeration: no cursor?"); OSL_ENSURE( !((CURSOR_SELECTION_IN_TABLE == eType) || (CURSOR_TBLTEXT == eType)) || (m_pOwnTable && m_pOwnStartNode), "SwXParagraphEnumeration: table type but no start node or table?"); if ((CURSOR_SELECTION == m_eCursorType) || (CURSOR_SELECTION_IN_TABLE == m_eCursorType)) { SwUnoCrsr & rCursor = *GetCursor(); rCursor.Normalize(); m_nFirstParaStart = rCursor.GetPoint()->nContent.GetIndex(); m_nLastParaEnd = rCursor.GetMark()->nContent.GetIndex(); rCursor.DeleteMark(); } } ~Impl() { // Impl owns the cursor; delete it here: SolarMutex is locked delete GetRegisteredIn(); } SwUnoCrsr * GetCursor() { return static_cast( const_cast(GetRegisteredIn())); } uno::Reference< text::XTextContent > NextElement_Impl() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException); protected: // SwClient virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew); }; void SwXParagraphEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) { ClientModify(this, pOld, pNew); } SwXParagraphEnumeration::SwXParagraphEnumeration( uno::Reference< text::XText > const& xParent, ::std::auto_ptr pCursor, const CursorType eType, SwStartNode const*const pStartNode, SwTable const*const pTable) : m_pImpl( new SwXParagraphEnumeration::Impl(xParent, pCursor, eType, pStartNode, pTable) ) { } SwXParagraphEnumeration::~SwXParagraphEnumeration() { } OUString SAL_CALL SwXParagraphEnumeration::getImplementationName() throw (uno::RuntimeException) { return C2U("SwXParagraphEnumeration"); } static char const*const g_ServicesParagraphEnum[] = { "com.sun.star.text.ParagraphEnumeration", }; static const size_t g_nServicesParagraphEnum( sizeof(g_ServicesParagraphEnum)/sizeof(g_ServicesParagraphEnum[0])); sal_Bool SAL_CALL SwXParagraphEnumeration::supportsService(const OUString& rServiceName) throw (uno::RuntimeException) { return ::sw::SupportsServiceImpl( g_nServicesParagraphEnum, g_ServicesParagraphEnum, rServiceName); } uno::Sequence< OUString > SAL_CALL SwXParagraphEnumeration::getSupportedServiceNames() throw (uno::RuntimeException) { return ::sw::GetSupportedServiceNamesImpl( g_nServicesParagraphEnum, g_ServicesParagraphEnum); } sal_Bool SAL_CALL SwXParagraphEnumeration::hasMoreElements() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); return (m_pImpl->m_bFirstParagraph) ? sal_True : m_pImpl->m_xNextPara.is(); } //!! compare to SwShellTableCrsr::FillRects() in viscrs.cxx static SwTableNode * lcl_FindTopLevelTable( SwTableNode *const pTblNode, SwTable const*const pOwnTable) { // find top-most table in current context (section) level SwTableNode * pLast = pTblNode; for (SwTableNode* pTmp = pLast; pTmp != NULL && &pTmp->GetTable() != pOwnTable; /* we must not go up higher than the own table! */ pTmp = pTmp->StartOfSectionNode()->FindTableNode() ) { pLast = pTmp; } return pLast; } static bool lcl_CursorIsInSection( SwUnoCrsr const*const pUnoCrsr, SwStartNode const*const pOwnStartNode) { // returns true if the cursor is in the section (or in a sub section!) // represented by pOwnStartNode bool bRes = true; if (pUnoCrsr && pOwnStartNode) { const SwEndNode * pOwnEndNode = pOwnStartNode->EndOfSectionNode(); bRes = pOwnStartNode->GetIndex() <= pUnoCrsr->Start()->nNode.GetIndex() && pUnoCrsr->End()->nNode.GetIndex() <= pOwnEndNode->GetIndex(); } return bRes; } uno::Reference< text::XTextContent > SwXParagraphEnumeration::Impl::NextElement_Impl() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { SwUnoCrsr *const pUnoCrsr = GetCursor(); if (!pUnoCrsr) { throw uno::RuntimeException(); } // check for exceeding selections if (!m_bFirstParagraph && ((CURSOR_SELECTION == m_eCursorType) || (CURSOR_SELECTION_IN_TABLE == m_eCursorType))) { SwPosition* pStart = pUnoCrsr->Start(); const ::std::auto_ptr aNewCrsr( pUnoCrsr->GetDoc()->CreateUnoCrsr(*pStart, sal_False) ); // one may also go into tables here if ((CURSOR_TBLTEXT != m_eCursorType) && (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) { aNewCrsr->SetRemainInSection( sal_False ); } // os 2005-01-14: This part is only necessary to detect movements out // of a selection; if there is no selection we don't have to care SwTableNode *const pTblNode = aNewCrsr->GetNode()->FindTableNode(); if (((CURSOR_TBLTEXT != m_eCursorType) && (CURSOR_SELECTION_IN_TABLE != m_eCursorType)) && pTblNode) { aNewCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex(); aNewCrsr->Move(fnMoveForward, fnGoNode); } else { aNewCrsr->MovePara(fnParaNext, fnParaStart); } if (m_nEndIndex < aNewCrsr->Start()->nNode.GetIndex()) { return 0; } } sal_Bool bInTable = sal_False; if (!m_bFirstParagraph) { pUnoCrsr->SetRemainInSection( sal_False ); // what to do if already in a table? SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode(); pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable ); if (pTblNode && (&pTblNode->GetTable() != m_pOwnTable)) { // this is a foreign table: go to end pUnoCrsr->GetPoint()->nNode = pTblNode->EndOfSectionIndex(); if (!pUnoCrsr->Move(fnMoveForward, fnGoNode)) { return 0; } bInTable = sal_True; } } uno::Reference< text::XTextContent > xRef; // the cursor must remain in the current section or a subsection // before AND after the movement... if (lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode ) && (m_bFirstParagraph || bInTable || (pUnoCrsr->MovePara(fnParaNext, fnParaStart) && lcl_CursorIsInSection( pUnoCrsr, m_pOwnStartNode )))) { SwPosition* pStart = pUnoCrsr->Start(); const sal_Int32 nFirstContent = (m_bFirstParagraph) ? m_nFirstParaStart : -1; const sal_Int32 nLastContent = (m_nEndIndex == pStart->nNode.GetIndex()) ? m_nLastParaEnd : -1; // position in a table, or in a simple paragraph? SwTableNode * pTblNode = pUnoCrsr->GetNode()->FindTableNode(); pTblNode = lcl_FindTopLevelTable( pTblNode, m_pOwnTable ); if (/*CURSOR_TBLTEXT != eCursorType && CURSOR_SELECTION_IN_TABLE != eCursorType && */ pTblNode && (&pTblNode->GetTable() != m_pOwnTable)) { // this is a foreign table SwFrmFmt* pTableFmt = static_cast(pTblNode->GetTable().GetFrmFmt()); text::XTextTable *const pTable = SwXTextTables::GetObject( *pTableFmt ); xRef = static_cast( static_cast(pTable)); } else { text::XText *const pText = m_xParentText.get(); xRef = SwXParagraph::CreateXParagraph(*pUnoCrsr->GetDoc(), *pStart->nNode.GetNode().GetTxtNode(), static_cast(pText), nFirstContent, nLastContent); } } return xRef; } uno::Any SAL_CALL SwXParagraphEnumeration::nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (m_pImpl->m_bFirstParagraph) { m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl(); m_pImpl->m_bFirstParagraph = false; } const uno::Reference< text::XTextContent > xRef = m_pImpl->m_xNextPara; if (!xRef.is()) { throw container::NoSuchElementException(); } m_pImpl->m_xNextPara = m_pImpl->NextElement_Impl(); uno::Any aRet; aRet <<= xRef; return aRet; } /****************************************************************** * SwXTextRange ******************************************************************/ class SwXTextRange::Impl : public SwClient { public: const SfxItemPropertySet & m_rPropSet; const enum RangePosition m_eRangePosition; SwDoc & m_rDoc; uno::Reference m_xParentText; SwDepend m_ObjectDepend; // register at format of table or frame ::sw::mark::IMark * m_pMark; Impl( SwDoc & rDoc, const enum RangePosition eRange, SwFrmFmt *const pTblFmt = 0, const uno::Reference< text::XText > & xParent = 0) : SwClient() , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)) , m_eRangePosition(eRange) , m_rDoc(rDoc) , m_xParentText(xParent) , m_ObjectDepend(this, pTblFmt) , m_pMark(0) { } ~Impl() { // Impl owns the bookmark; delete it here: SolarMutex is locked Invalidate(); } void Invalidate() { if (m_pMark) { m_rDoc.getIDocumentMarkAccess()->deleteMark(m_pMark); m_pMark = 0; } } const ::sw::mark::IMark * GetBookmark() const { return m_pMark; } protected: // SwClient virtual void Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew); }; void SwXTextRange::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew) { const bool bAlreadyRegistered = 0 != GetRegisteredIn(); ClientModify(this, pOld, pNew); if (m_ObjectDepend.GetRegisteredIn()) { ClientModify(&m_ObjectDepend, pOld, pNew); // if the depend was removed then the range must be removed too if (!m_ObjectDepend.GetRegisteredIn() && GetRegisteredIn()) { const_cast(GetRegisteredIn())->Remove(this); } // or if the range has been removed but the depend ist still // connected then the depend must be removed else if (bAlreadyRegistered && !GetRegisteredIn() && m_ObjectDepend.GetRegisteredIn()) { const_cast(m_ObjectDepend.GetRegisteredIn()) ->Remove(& m_ObjectDepend); } } if (!GetRegisteredIn()) { m_pMark = 0; } } SwXTextRange::SwXTextRange(SwPaM& rPam, const uno::Reference< text::XText > & xParent, const enum RangePosition eRange) : m_pImpl( new SwXTextRange::Impl(*rPam.GetDoc(), eRange, 0, xParent) ) { SetPositions(rPam); } SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt) : m_pImpl( new SwXTextRange::Impl(*rTblFmt.GetDoc(), RANGE_IS_TABLE, &rTblFmt) ) { SwTable *const pTable = SwTable::FindTable( &rTblFmt ); SwTableNode *const pTblNode = pTable->GetTableNode(); SwPosition aPosition( *pTblNode ); SwPaM aPam( aPosition ); SetPositions( aPam ); } SwXTextRange::~SwXTextRange() { } const SwDoc * SwXTextRange::GetDoc() const { return & m_pImpl->m_rDoc; } SwDoc * SwXTextRange::GetDoc() { return & m_pImpl->m_rDoc; } void SwXTextRange::Invalidate() { m_pImpl->Invalidate(); } void SwXTextRange::SetPositions(const SwPaM& rPam) { m_pImpl->Invalidate(); IDocumentMarkAccess* const pMA = m_pImpl->m_rDoc.getIDocumentMarkAccess(); m_pImpl->m_pMark = pMA->makeMark(rPam, ::rtl::OUString(), IDocumentMarkAccess::UNO_BOOKMARK); m_pImpl->m_pMark->Add(m_pImpl.get()); } void SwXTextRange::DeleteAndInsert( const ::rtl::OUString& rText, const bool bForceExpandHints) throw (uno::RuntimeException) { if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) { // setString on table not allowed throw uno::RuntimeException(); } const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent()); SwCursor aCursor(aPos, 0, false); if (GetPositions(aCursor)) { UnoActionContext aAction(& m_pImpl->m_rDoc); m_pImpl->m_rDoc.GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL); if (aCursor.HasMark()) { m_pImpl->m_rDoc.DeleteAndJoin(aCursor); } if (rText.getLength()) { SwUnoCursorHelper::DocInsertStringSplitCR( m_pImpl->m_rDoc, aCursor, rText, bForceExpandHints); SwUnoCursorHelper::SelectPam(aCursor, true); aCursor.Left(rText.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False); } SetPositions(aCursor); m_pImpl->m_rDoc.GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL); } } const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId() { static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId(); return aSeq; } // XUnoTunnel sal_Int64 SAL_CALL SwXTextRange::getSomething(const uno::Sequence< sal_Int8 >& rId) throw (uno::RuntimeException) { return ::sw::UnoTunnelImpl(rId, this); } OUString SAL_CALL SwXTextRange::getImplementationName() throw (uno::RuntimeException) { return OUString::createFromAscii("SwXTextRange"); } static char const*const g_ServicesTextRange[] = { "com.sun.star.text.TextRange", "com.sun.star.style.CharacterProperties", "com.sun.star.style.CharacterPropertiesAsian", "com.sun.star.style.CharacterPropertiesComplex", "com.sun.star.style.ParagraphProperties", "com.sun.star.style.ParagraphPropertiesAsian", "com.sun.star.style.ParagraphPropertiesComplex", }; static const size_t g_nServicesTextRange( sizeof(g_ServicesTextRange)/sizeof(g_ServicesTextRange[0])); sal_Bool SAL_CALL SwXTextRange::supportsService(const OUString& rServiceName) throw (uno::RuntimeException) { return ::sw::SupportsServiceImpl( g_nServicesTextRange, g_ServicesTextRange, rServiceName); } uno::Sequence< OUString > SAL_CALL SwXTextRange::getSupportedServiceNames() throw (uno::RuntimeException) { return ::sw::GetSupportedServiceNamesImpl( g_nServicesTextRange, g_ServicesTextRange); } uno::Reference< text::XText > SAL_CALL SwXTextRange::getText() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!m_pImpl->m_xParentText.is()) { if (m_pImpl->m_eRangePosition == RANGE_IS_TABLE && m_pImpl->m_ObjectDepend.GetRegisteredIn()) { SwFrmFmt const*const pTblFmt = static_cast( m_pImpl->m_ObjectDepend.GetRegisteredIn()); SwTable const*const pTable = SwTable::FindTable( pTblFmt ); SwTableNode const*const pTblNode = pTable->GetTableNode(); const SwPosition aPosition( *pTblNode ); m_pImpl->m_xParentText = ::sw::CreateParentXText(m_pImpl->m_rDoc, aPosition); } } OSL_ENSURE(m_pImpl->m_xParentText.is(), "SwXTextRange::getText: no text"); return m_pImpl->m_xParentText; } uno::Reference< text::XTextRange > SAL_CALL SwXTextRange::getStart() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); uno::Reference< text::XTextRange > xRet; ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); if (!m_pImpl->m_xParentText.is()) { getText(); } if(pBkmk) { SwPaM aPam(pBkmk->GetMarkStart()); xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText); } else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) { // start and end are this, if its a table xRet = this; } else { throw uno::RuntimeException(); } return xRet; } uno::Reference< text::XTextRange > SAL_CALL SwXTextRange::getEnd() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); uno::Reference< text::XTextRange > xRet; ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); if (!m_pImpl->m_xParentText.is()) { getText(); } if(pBkmk) { SwPaM aPam(pBkmk->GetMarkEnd()); xRet = new SwXTextRange(aPam, m_pImpl->m_xParentText); } else if (RANGE_IS_TABLE == m_pImpl->m_eRangePosition) { // start and end are this, if its a table xRet = this; } else { throw uno::RuntimeException(); } return xRet; } OUString SAL_CALL SwXTextRange::getString() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); OUString sRet; // for tables there is no bookmark, thus also no text // one could export the table as ASCII here maybe? SwPaM aPaM(GetDoc()->GetNodes()); if (GetPositions(aPaM) && aPaM.HasMark()) { SwUnoCursorHelper::GetTextFromPam(aPaM, sRet); } return sRet; } void SAL_CALL SwXTextRange::setString(const OUString& rString) throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); DeleteAndInsert(rString, false); } bool SwXTextRange::GetPositions(SwPaM& rToFill) const { ::sw::mark::IMark const * const pBkmk = m_pImpl->GetBookmark(); if(pBkmk) { *rToFill.GetPoint() = pBkmk->GetMarkPos(); if(pBkmk->IsExpanded()) { rToFill.SetMark(); *rToFill.GetMark() = pBkmk->GetOtherMarkPos(); } else { rToFill.DeleteMark(); } return true; } return false; } namespace sw { bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill, const uno::Reference< text::XTextRange > & xTextRange) { bool bRet = false; uno::Reference xRangeTunnel( xTextRange, uno::UNO_QUERY); SwXTextRange* pRange = 0; OTextCursorHelper* pCursor = 0; SwXTextPortion* pPortion = 0; SwXText* pText = 0; SwXParagraph* pPara = 0; if(xRangeTunnel.is()) { pRange = ::sw::UnoTunnelGetImplementation(xRangeTunnel); pCursor = ::sw::UnoTunnelGetImplementation(xRangeTunnel); pPortion= ::sw::UnoTunnelGetImplementation(xRangeTunnel); pText = ::sw::UnoTunnelGetImplementation(xRangeTunnel); pPara = ::sw::UnoTunnelGetImplementation(xRangeTunnel); } // if it's a text then create a temporary cursor there and re-use // the pCursor variable // #i108489#: Reference in outside scope to keep cursor alive uno::Reference< text::XTextCursor > xTextCursor; if (pText) { xTextCursor.set( pText->CreateCursor() ); xTextCursor->gotoEnd(sal_True); const uno::Reference xCrsrTunnel( xTextCursor, uno::UNO_QUERY); pCursor = ::sw::UnoTunnelGetImplementation(xCrsrTunnel); } if(pRange && pRange->GetDoc() == rToFill.GetDoc()) { bRet = pRange->GetPositions(rToFill); } else { if (pPara) { bRet = pPara->SelectPaM(rToFill); } else { SwDoc* const pDoc = (pCursor) ? pCursor->GetDoc() : ((pPortion) ? pPortion->GetCursor()->GetDoc() : 0); const SwPaM* const pUnoCrsr = (pCursor) ? pCursor->GetPaM() : ((pPortion) ? pPortion->GetCursor() : 0); if (pUnoCrsr && pDoc == rToFill.GetDoc()) { DBG_ASSERT((SwPaM*)pUnoCrsr->GetNext() == pUnoCrsr, "what to do about rings?"); bRet = true; *rToFill.GetPoint() = *pUnoCrsr->GetPoint(); if (pUnoCrsr->HasMark()) { rToFill.SetMark(); *rToFill.GetMark() = *pUnoCrsr->GetMark(); } else rToFill.DeleteMark(); } } } return bRet; } static bool lcl_IsStartNodeInFormat(const bool bHeader, SwStartNode *const pSttNode, SwFrmFmt const*const pFrmFmt, SwFrmFmt*& rpFormat) { bool bRet = false; const SfxItemSet& rSet = pFrmFmt->GetAttrSet(); const SfxPoolItem* pItem; if (SFX_ITEM_SET == rSet.GetItemState( static_cast(bHeader ? RES_HEADER : RES_FOOTER), sal_True, &pItem)) { SfxPoolItem *const pItemNonConst(const_cast(pItem)); SwFrmFmt *const pHeadFootFmt = (bHeader) ? static_cast(pItemNonConst)->GetHeaderFmt() : static_cast(pItemNonConst)->GetFooterFmt(); if (pHeadFootFmt) { const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt(); const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode(); SwStartNode const*const pCurSttNode = rNode.FindSttNodeByType( (bHeader) ? SwHeaderStartNode : SwFooterStartNode); if (pCurSttNode && (pCurSttNode == pSttNode)) { rpFormat = pHeadFootFmt; bRet = true; } } } return bRet; } } // namespace sw uno::Reference< text::XTextRange > SwXTextRange::CreateXTextRange( SwDoc & rDoc, const SwPosition& rPos, const SwPosition *const pMark) { const uno::Reference xParentText( ::sw::CreateParentXText(rDoc, rPos)); const ::std::auto_ptr pNewCrsr( rDoc.CreateUnoCrsr(rPos, sal_False)); if(pMark) { pNewCrsr->SetMark(); *pNewCrsr->GetMark() = *pMark; } const bool isCell( dynamic_cast(xParentText.get()) ); const uno::Reference< text::XTextRange > xRet( new SwXTextRange(*pNewCrsr, xParentText, isCell ? RANGE_IN_CELL : RANGE_IN_TEXT) ); return xRet; } namespace sw { uno::Reference< text::XText > CreateParentXText(SwDoc & rDoc, const SwPosition& rPos) { uno::Reference< text::XText > xParentText; SwStartNode* pSttNode = rPos.nNode.GetNode().StartOfSectionNode(); while(pSttNode && pSttNode->IsSectionNode()) { pSttNode = pSttNode->StartOfSectionNode(); } SwStartNodeType eType = pSttNode->GetStartNodeType(); switch(eType) { case SwTableBoxStartNode: { SwTableNode const*const pTblNode = pSttNode->FindTableNode(); SwFrmFmt *const pTableFmt = static_cast(pTblNode->GetTable().GetFrmFmt()); SwTableBox *const pBox = pSttNode->GetTblBox(); xParentText = (pBox) ? SwXCell::CreateXCell( pTableFmt, pBox ) : new SwXCell( pTableFmt, *pSttNode ); } break; case SwFlyStartNode: { SwFrmFmt *const pFmt = pSttNode->GetFlyFmt(); if (0 != pFmt) { SwXTextFrame* pFrame = SwIterator::FirstElement( *pFmt ); xParentText = pFrame ? pFrame : new SwXTextFrame( *pFmt ); } } break; case SwHeaderStartNode: case SwFooterStartNode: { const bool bHeader = (SwHeaderStartNode == eType); const sal_uInt16 nPDescCount = rDoc.GetPageDescCnt(); for(sal_uInt16 i = 0; i < nPDescCount; i++) { const SwPageDesc& rDesc = // C++ is retarded const_cast(rDoc).GetPageDesc( i ); const SwFrmFmt* pFrmFmtMaster = &rDesc.GetMaster(); const SwFrmFmt* pFrmFmtLeft = &rDesc.GetLeft(); SwFrmFmt* pHeadFootFmt = 0; if (!lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtMaster, pHeadFootFmt)) { lcl_IsStartNodeInFormat(bHeader, pSttNode, pFrmFmtLeft, pHeadFootFmt); } if (pHeadFootFmt) { xParentText = SwXHeadFootText::CreateXHeadFootText( *pHeadFootFmt, bHeader); } } } break; case SwFootnoteStartNode: { const sal_uInt16 nFtnCnt = rDoc.GetFtnIdxs().Count(); uno::Reference< text::XFootnote > xRef; for (sal_uInt16 n = 0; n < nFtnCnt; ++n ) { const SwTxtFtn* pTxtFtn = rDoc.GetFtnIdxs()[ n ]; const SwFmtFtn& rFtn = pTxtFtn->GetFtn(); pTxtFtn = rFtn.GetTxtFtn(); #if OSL_DEBUG_LEVEL > 1 const SwStartNode* pTmpSttNode = pTxtFtn->GetStartNode()->GetNode(). FindSttNodeByType(SwFootnoteStartNode); (void)pTmpSttNode; #endif if (pSttNode == pTxtFtn->GetStartNode()->GetNode(). FindSttNodeByType(SwFootnoteStartNode)) { xParentText = SwXFootnote::CreateXFootnote(rDoc, rFtn); break; } } } break; default: { // then it is the body text const uno::Reference xModel = rDoc.GetDocShell()->GetBaseModel(); const uno::Reference< text::XTextDocument > xDoc( xModel, uno::UNO_QUERY); xParentText = xDoc->getText(); } } OSL_ENSURE(xParentText.is(), "no parent text?"); return xParentText; } } // namespace sw uno::Reference< container::XEnumeration > SAL_CALL SwXTextRange::createContentEnumeration(const OUString& rServiceName) throw (uno::RuntimeException) { vos::OGuard g(Application::GetSolarMutex()); if (!rServiceName.equalsAscii("com.sun.star.text.TextContent")) { throw uno::RuntimeException(); } if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent()); const ::std::auto_ptr pNewCrsr( m_pImpl->m_rDoc.CreateUnoCrsr(aPos, sal_False)); if (!GetPositions(*pNewCrsr)) { throw uno::RuntimeException(); } const uno::Reference< container::XEnumeration > xRet = new SwXParaFrameEnumeration(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE); return xRet; } uno::Reference< container::XEnumeration > SAL_CALL SwXTextRange::createEnumeration() throw (uno::RuntimeException) { vos::OGuard g(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } const SwPosition aPos(GetDoc()->GetNodes().GetEndOfContent()); ::std::auto_ptr pNewCrsr( m_pImpl->m_rDoc.CreateUnoCrsr(aPos, sal_False)); if (!GetPositions(*pNewCrsr)) { throw uno::RuntimeException(); } if (!m_pImpl->m_xParentText.is()) { getText(); } const CursorType eSetType = (RANGE_IN_CELL == m_pImpl->m_eRangePosition) ? CURSOR_SELECTION_IN_TABLE : CURSOR_SELECTION; const uno::Reference< container::XEnumeration > xRet = new SwXParagraphEnumeration(m_pImpl->m_xParentText, pNewCrsr, eSetType); return xRet; } uno::Type SAL_CALL SwXTextRange::getElementType() throw (uno::RuntimeException) { return text::XTextRange::static_type(); } sal_Bool SAL_CALL SwXTextRange::hasElements() throw (uno::RuntimeException) { return sal_True; } uno::Sequence< OUString > SAL_CALL SwXTextRange::getAvailableServiceNames() throw (uno::RuntimeException) { uno::Sequence< OUString > aRet(1); OUString* pArray = aRet.getArray(); pArray[0] = OUString::createFromAscii("com.sun.star.text.TextContent"); return aRet; } uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXTextRange::getPropertySetInfo() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); static uno::Reference< beans::XPropertySetInfo > xRef = m_pImpl->m_rPropSet.getPropertySetInfo(); return xRef; } void SAL_CALL SwXTextRange::setPropertyValue( const OUString& rPropertyName, const uno::Any& rValue) throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } SwPaM aPaM(GetDoc()->GetNodes()); GetPositions(aPaM); SwUnoCursorHelper::SetPropertyValue(aPaM, m_pImpl->m_rPropSet, rPropertyName, rValue); } uno::Any SAL_CALL SwXTextRange::getPropertyValue(const OUString& rPropertyName) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } SwPaM aPaM(GetDoc()->GetNodes()); GetPositions(aPaM); return SwUnoCursorHelper::GetPropertyValue(aPaM, m_pImpl->m_rPropSet, rPropertyName); } void SAL_CALL SwXTextRange::addPropertyChangeListener( const ::rtl::OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { OSL_ENSURE(false, "SwXTextRange::addPropertyChangeListener(): not implemented"); } void SAL_CALL SwXTextRange::removePropertyChangeListener( const ::rtl::OUString& /*rPropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { OSL_ENSURE(false, "SwXTextRange::removePropertyChangeListener(): not implemented"); } void SAL_CALL SwXTextRange::addVetoableChangeListener( const ::rtl::OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { OSL_ENSURE(false, "SwXTextRange::addVetoableChangeListener(): not implemented"); } void SAL_CALL SwXTextRange::removeVetoableChangeListener( const ::rtl::OUString& /*rPropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { OSL_ENSURE(false, "SwXTextRange::removeVetoableChangeListener(): not implemented"); } beans::PropertyState SAL_CALL SwXTextRange::getPropertyState(const OUString& rPropertyName) throw (beans::UnknownPropertyException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } SwPaM aPaM(GetDoc()->GetNodes()); GetPositions(aPaM); return SwUnoCursorHelper::GetPropertyState(aPaM, m_pImpl->m_rPropSet, rPropertyName); } uno::Sequence< beans::PropertyState > SAL_CALL SwXTextRange::getPropertyStates(const uno::Sequence< OUString >& rPropertyName) throw (beans::UnknownPropertyException, uno::RuntimeException) { vos::OGuard g(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } SwPaM aPaM(GetDoc()->GetNodes()); GetPositions(aPaM); return SwUnoCursorHelper::GetPropertyStates(aPaM, m_pImpl->m_rPropSet, rPropertyName); } void SAL_CALL SwXTextRange::setPropertyToDefault(const OUString& rPropertyName) throw (beans::UnknownPropertyException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } SwPaM aPaM(GetDoc()->GetNodes()); GetPositions(aPaM); SwUnoCursorHelper::SetPropertyToDefault(aPaM, m_pImpl->m_rPropSet, rPropertyName); } uno::Any SAL_CALL SwXTextRange::getPropertyDefault(const OUString& rPropertyName) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } SwPaM aPaM(GetDoc()->GetNodes()); GetPositions(aPaM); return SwUnoCursorHelper::GetPropertyDefault(aPaM, m_pImpl->m_rPropSet, rPropertyName); } void SAL_CALL SwXTextRange::makeRedline( const ::rtl::OUString& rRedlineType, const uno::Sequence< beans::PropertyValue >& rRedlineProperties ) throw (lang::IllegalArgumentException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!GetDoc() || !m_pImpl->GetBookmark()) { throw uno::RuntimeException(); } SwPaM aPaM(GetDoc()->GetNodes()); SwXTextRange::GetPositions(aPaM); SwUnoCursorHelper::makeRedline( aPaM, rRedlineType, rRedlineProperties ); } /****************************************************************** * SwXTextRanges ******************************************************************/ class SwXTextRanges::Impl : public SwClient { public: ::std::vector< uno::Reference< text::XTextRange > > m_Ranges; Impl(SwPaM *const pPaM) : SwClient( (pPaM) ? pPaM->GetDoc()->CreateUnoCrsr(*pPaM->GetPoint()) : 0 ) { if (pPaM) { ::sw::DeepCopyPaM(*pPaM, *GetCursor()); } MakeRanges(); } ~Impl() { // Impl owns the cursor; delete it here: SolarMutex is locked delete GetRegisteredIn(); } SwUnoCrsr * GetCursor() { return static_cast( const_cast(GetRegisteredIn())); } void MakeRanges(); protected: // SwClient virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew); }; void SwXTextRanges::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) { ClientModify(this, pOld, pNew); } void SwXTextRanges::Impl::MakeRanges() { SwUnoCrsr *const pCursor = GetCursor(); if (pCursor) { SwPaM *pTmpCursor = pCursor; do { const uno::Reference< text::XTextRange > xRange( SwXTextRange::CreateXTextRange( *pTmpCursor->GetDoc(), *pTmpCursor->GetPoint(), pTmpCursor->GetMark())); if (xRange.is()) { m_Ranges.push_back(xRange); } pTmpCursor = static_cast(pTmpCursor->GetNext()); } while (pTmpCursor != pCursor); } } const SwUnoCrsr* SwXTextRanges::GetCursor() const { return m_pImpl->GetCursor(); } SwXTextRanges::SwXTextRanges(SwPaM *const pPaM) : m_pImpl( new SwXTextRanges::Impl(pPaM) ) { } SwXTextRanges::~SwXTextRanges() { } const uno::Sequence< sal_Int8 > & SwXTextRanges::getUnoTunnelId() { static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId(); return aSeq; } sal_Int64 SAL_CALL SwXTextRanges::getSomething(const uno::Sequence< sal_Int8 >& rId) throw (uno::RuntimeException) { return ::sw::UnoTunnelImpl(rId, this); } /**************************************************************************** * Text positions * Bis zum ersten Zugriff auf eine TextPosition wird ein SwCursor gehalten, * danach wird ein Array mit uno::Reference< XTextPosition > angelegt * ****************************************************************************/ OUString SAL_CALL SwXTextRanges::getImplementationName() throw (uno::RuntimeException) { return C2U("SwXTextRanges"); } static char const*const g_ServicesTextRanges[] = { "com.sun.star.text.TextRanges", }; static const size_t g_nServicesTextRanges( sizeof(g_ServicesTextRanges)/sizeof(g_ServicesTextRanges[0])); sal_Bool SAL_CALL SwXTextRanges::supportsService(const OUString& rServiceName) throw (uno::RuntimeException) { return ::sw::SupportsServiceImpl( g_nServicesTextRanges, g_ServicesTextRanges, rServiceName); } uno::Sequence< OUString > SAL_CALL SwXTextRanges::getSupportedServiceNames() throw (uno::RuntimeException) { return ::sw::GetSupportedServiceNamesImpl( g_nServicesTextRanges, g_ServicesTextRanges); } sal_Int32 SAL_CALL SwXTextRanges::getCount() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); return static_cast(m_pImpl->m_Ranges.size()); } uno::Any SAL_CALL SwXTextRanges::getByIndex(sal_Int32 nIndex) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if ((nIndex < 0) || (static_cast(nIndex) >= m_pImpl->m_Ranges.size())) { throw lang::IndexOutOfBoundsException(); } uno::Any ret; ret <<= (m_pImpl->m_Ranges.at(nIndex)); return ret; } uno::Type SAL_CALL SwXTextRanges::getElementType() throw (uno::RuntimeException) { return text::XTextRange::static_type(); } sal_Bool SAL_CALL SwXTextRanges::hasElements() throw (uno::RuntimeException) { // no mutex necessary: getCount() does locking return getCount() > 0; } void SwUnoCursorHelper::SetString(SwCursor & rCursor, const OUString& rString) { // Start/EndAction SwDoc *const pDoc = rCursor.GetDoc(); UnoActionContext aAction(pDoc); pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL); if (rCursor.HasMark()) { pDoc->DeleteAndJoin(rCursor); } if (rString.getLength()) { String aText(rString); const bool bSuccess( SwUnoCursorHelper::DocInsertStringSplitCR( *pDoc, rCursor, aText, false ) ); DBG_ASSERT( bSuccess, "DocInsertStringSplitCR" ); (void) bSuccess; SwUnoCursorHelper::SelectPam(rCursor, true); rCursor.Left(rString.getLength(), CRSR_SKIP_CHARS, sal_False, sal_False); } pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL); } /****************************************************************** * SwXParaFrameEnumeration ******************************************************************/ class SwXParaFrameEnumeration::Impl : public SwClient { public: // created by hasMoreElements uno::Reference< text::XTextContent > m_xNextObject; FrameDependList_t m_Frames; Impl(SwPaM const & rPaM) : SwClient(rPaM.GetDoc()->CreateUnoCrsr(*rPaM.GetPoint(), sal_False)) { if (rPaM.HasMark()) { GetCursor()->SetMark(); *GetCursor()->GetMark() = *rPaM.GetMark(); } } ~Impl() { // Impl owns the cursor; delete it here: SolarMutex is locked delete GetRegisteredIn(); } SwUnoCrsr * GetCursor() { return static_cast( const_cast(GetRegisteredIn())); } protected: // SwClient virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew); }; struct InvalidFrameDepend { bool operator() (::boost::shared_ptr const & rEntry) { return !rEntry->GetRegisteredIn(); } }; void SwXParaFrameEnumeration::Impl::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) { ClientModify(this, pOld, pNew); if(!GetRegisteredIn()) { m_Frames.clear(); m_xNextObject = 0; } else { // check if any frame went away... FrameDependList_t::iterator const iter = ::std::remove_if(m_Frames.begin(), m_Frames.end(), InvalidFrameDepend()); m_Frames.erase(iter, m_Frames.end()); } } static sal_Bool lcl_CreateNextObject(SwUnoCrsr& i_rUnoCrsr, uno::Reference & o_rNextObject, FrameDependList_t & i_rFrames) { if (!i_rFrames.size()) return sal_False; SwFrmFmt *const pFormat = static_cast(const_cast( i_rFrames.front()->GetRegisteredIn())); i_rFrames.pop_front(); // the format should be valid here, otherwise the client // would have been removed in ::Modify // check for a shape first SwDrawContact* const pContact = SwIterator::FirstElement( *pFormat ); if (pContact) { SdrObject * const pSdr = pContact->GetMaster(); if (pSdr) { o_rNextObject.set(pSdr->getUnoShape(), uno::UNO_QUERY); } } else { const SwNodeIndex* pIdx = pFormat->GetCntnt().GetCntntIdx(); DBG_ASSERT(pIdx, "where is the index?"); SwNode const*const pNd = i_rUnoCrsr.GetDoc()->GetNodes()[ pIdx->GetIndex() + 1 ]; const FlyCntType eType = (!pNd->IsNoTxtNode()) ? FLYCNTTYPE_FRM : ( (pNd->IsGrfNode()) ? FLYCNTTYPE_GRF : FLYCNTTYPE_OLE ); const uno::Reference< container::XNamed > xFrame = SwXFrames::GetObject(*pFormat, eType); o_rNextObject.set(xFrame, uno::UNO_QUERY); } return o_rNextObject.is(); } /* -----------------------------03.04.00 10:15-------------------------------- Description: Search for a FLYCNT text attribute at the cursor point and fill the frame into the array ---------------------------------------------------------------------------*/ static void lcl_FillFrame(SwClient & rEnum, SwUnoCrsr& rUnoCrsr, FrameDependList_t & rFrames) { // search for objects at the cursor - anchored at/as char SwTxtAttr const*const pTxtAttr = rUnoCrsr.GetNode()->GetTxtNode()->GetTxtAttrForCharAt( rUnoCrsr.GetPoint()->nContent.GetIndex(), RES_TXTATR_FLYCNT); if (pTxtAttr) { const SwFmtFlyCnt& rFlyCnt = pTxtAttr->GetFlyCnt(); SwFrmFmt * const pFrmFmt = rFlyCnt.GetFrmFmt(); SwDepend * const pNewDepend = new SwDepend(&rEnum, pFrmFmt); rFrames.push_back( ::boost::shared_ptr(pNewDepend) ); } } SwXParaFrameEnumeration::SwXParaFrameEnumeration( const SwPaM& rPaM, const enum ParaFrameMode eParaFrameMode, SwFrmFmt *const pFmt) : m_pImpl( new SwXParaFrameEnumeration::Impl(rPaM) ) { if (PARAFRAME_PORTION_PARAGRAPH == eParaFrameMode) { FrameDependSortList_t frames; ::CollectFrameAtNode(*m_pImpl.get(), rPaM.GetPoint()->nNode, frames, false); ::std::transform(frames.begin(), frames.end(), ::std::back_inserter(m_pImpl->m_Frames), ::boost::bind(&FrameDependSortListEntry::pFrameDepend, _1)); } else if (pFmt) { // create SwDepend for frame and insert into array SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFmt); m_pImpl->m_Frames.push_back(::boost::shared_ptr(pNewDepend)); } else if ((PARAFRAME_PORTION_CHAR == eParaFrameMode) || (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode)) { if (PARAFRAME_PORTION_TEXTRANGE == eParaFrameMode) { //get all frames that are bound at paragraph or at character SwPosFlyFrms aFlyFrms(rPaM.GetDoc()->GetAllFlyFmts(m_pImpl->GetCursor())); for(SwPosFlyFrms::const_iterator aIter(aFlyFrms.begin()); aIter != aFlyFrms.end(); aIter++) { SwFrmFmt *const pFrmFmt = const_cast(&((*aIter)->GetFmt())); // create SwDepend for frame and insert into array SwDepend *const pNewDepend = new SwDepend(m_pImpl.get(), pFrmFmt); m_pImpl->m_Frames.push_back(::boost::shared_ptr(pNewDepend)); } //created from any text range if (m_pImpl->GetCursor()->HasMark()) { m_pImpl->GetCursor()->Normalize(); do { lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(), m_pImpl->m_Frames); m_pImpl->GetCursor()->Right( 1, CRSR_SKIP_CHARS, sal_False, sal_False); } while (*m_pImpl->GetCursor()->GetPoint() < *m_pImpl->GetCursor()->GetMark()); } } lcl_FillFrame(*m_pImpl.get(), *m_pImpl->GetCursor(), m_pImpl->m_Frames); } } SwXParaFrameEnumeration::~SwXParaFrameEnumeration() { } sal_Bool SAL_CALL SwXParaFrameEnumeration::hasMoreElements() throw (uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!m_pImpl->GetCursor()) throw uno::RuntimeException(); return (m_pImpl->m_xNextObject.is()) ? sal_True : lcl_CreateNextObject(*m_pImpl->GetCursor(), m_pImpl->m_xNextObject, m_pImpl->m_Frames); } uno::Any SAL_CALL SwXParaFrameEnumeration::nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { vos::OGuard aGuard(Application::GetSolarMutex()); if (!m_pImpl->GetCursor()) { throw uno::RuntimeException(); } if (!m_pImpl->m_xNextObject.is() && m_pImpl->m_Frames.size()) { lcl_CreateNextObject(*m_pImpl->GetCursor(), m_pImpl->m_xNextObject, m_pImpl->m_Frames); } if (!m_pImpl->m_xNextObject.is()) { throw container::NoSuchElementException(); } uno::Any aRet; aRet <<= m_pImpl->m_xNextObject; m_pImpl->m_xNextObject = 0; return aRet; } OUString SAL_CALL SwXParaFrameEnumeration::getImplementationName() throw (uno::RuntimeException) { return C2U("SwXParaFrameEnumeration"); } static char const*const g_ServicesParaFrameEnum[] = { "com.sun.star.util.ContentEnumeration", }; static const size_t g_nServicesParaFrameEnum( sizeof(g_ServicesParaFrameEnum)/sizeof(g_ServicesParaFrameEnum[0])); sal_Bool SAL_CALL SwXParaFrameEnumeration::supportsService(const OUString& rServiceName) throw (uno::RuntimeException) { return ::sw::SupportsServiceImpl( g_nServicesParaFrameEnum, g_ServicesParaFrameEnum, rServiceName); } uno::Sequence< OUString > SAL_CALL SwXParaFrameEnumeration::getSupportedServiceNames() throw (uno::RuntimeException) { return ::sw::GetSupportedServiceNamesImpl( g_nServicesParaFrameEnum, g_ServicesParaFrameEnum); }