/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * 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 . */ #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 "txtfrm.hxx" #include #include #include #include using namespace ::com::sun::star; /// go to next/previous point on the same level bool SwCrsrShell::GotoNextNum() { bool bRet = GetDoc()->GotoNextNum( *m_pCurCrsr->GetPoint() ); if( bRet ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); if( !ActionPend() ) { SET_CURR_SHELL( this ); // try to set cursor onto this position, at half of the char- // SRectangle's height Point aPt( m_pCurCrsr->GetPtPos() ); SwCntntFrm * pFrm = m_pCurCrsr->GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, m_pCurCrsr->GetPoint() ); pFrm->GetCharRect( m_aCharRect, *m_pCurCrsr->GetPoint() ); pFrm->Calc(); if( pFrm->IsVertical() ) { aPt.setX(m_aCharRect.Center().getX()); aPt.setY(pFrm->Frm().Top() + m_nUpDownX); } else { aPt.setY(m_aCharRect.Center().getY()); aPt.setX(pFrm->Frm().Left() + m_nUpDownX); } pFrm->GetCrsrOfst( m_pCurCrsr->GetPoint(), aPt ); bRet = !m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); if( bRet ) UpdateCrsr(SwCrsrShell::UPDOWN | SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); } } return bRet; } bool SwCrsrShell::GotoPrevNum() { bool bRet = GetDoc()->GotoPrevNum( *m_pCurCrsr->GetPoint() ); if( bRet ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); if( !ActionPend() ) { SET_CURR_SHELL( this ); // try to set cursor onto this position, at half of the char- // SRectangle's height Point aPt( m_pCurCrsr->GetPtPos() ); SwCntntFrm * pFrm = m_pCurCrsr->GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, m_pCurCrsr->GetPoint() ); pFrm->GetCharRect( m_aCharRect, *m_pCurCrsr->GetPoint() ); pFrm->Calc(); if( pFrm->IsVertical() ) { aPt.setX(m_aCharRect.Center().getX()); aPt.setY(pFrm->Frm().Top() + m_nUpDownX); } else { aPt.setY(m_aCharRect.Center().getY()); aPt.setX(pFrm->Frm().Left() + m_nUpDownX); } pFrm->GetCrsrOfst( m_pCurCrsr->GetPoint(), aPt ); bRet = !m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); if( bRet ) UpdateCrsr(SwCrsrShell::UPDOWN | SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); } } return bRet; } /// jump from content to header sal_Bool SwCrsrShell::GotoHeaderTxt() { const SwFrm* pFrm = GetCurrFrm()->FindPageFrm(); while( pFrm && !pFrm->IsHeaderFrm() ) pFrm = pFrm->GetLower(); // found header, search 1. content frame while( pFrm && !pFrm->IsCntntFrm() ) pFrm = pFrm->GetLower(); if( pFrm ) { SET_CURR_SHELL( this ); // get header frame SwCallLink aLk( *this ); // watch Crsr-Moves SwCursor *pTmpCrsr = getShellCrsr( true ); SwCrsrSaveState aSaveState( *pTmpCrsr ); pFrm->Calc(); Point aPt( pFrm->Frm().Pos() + pFrm->Prt().Pos() ); pFrm->GetCrsrOfst( pTmpCrsr->GetPoint(), aPt ); if( !pTmpCrsr->IsSelOvr() ) UpdateCrsr(); else pFrm = 0; } return 0 != pFrm; } /// jump from content to footer sal_Bool SwCrsrShell::GotoFooterTxt() { const SwPageFrm* pFrm = GetCurrFrm()->FindPageFrm(); if( pFrm ) { const SwFrm* pLower = pFrm->GetLastLower(); while( pLower && !pLower->IsFooterFrm() ) pLower = pLower->GetLower(); // found footer, search 1. content frame while( pLower && !pLower->IsCntntFrm() ) pLower = pLower->GetLower(); if( pLower ) { SwCursor *pTmpCrsr = getShellCrsr( true ); SET_CURR_SHELL( this ); // get position in footer SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *pTmpCrsr ); pLower->Calc(); Point aPt( pLower->Frm().Pos() + pLower->Prt().Pos() ); pLower->GetCrsrOfst( pTmpCrsr->GetPoint(), aPt ); if( !pTmpCrsr->IsSelOvr() ) UpdateCrsr(); else pFrm = 0; } else pFrm = 0; } else pFrm = 0; return 0 != pFrm; } sal_Bool SwCrsrShell::SetCrsrInHdFt( sal_uInt16 nDescNo, sal_Bool bInHeader ) { sal_Bool bRet = sal_False; SwDoc *pMyDoc = GetDoc(); SET_CURR_SHELL( this ); if( USHRT_MAX == nDescNo ) { // take the current one const SwPageFrm* pPage = GetCurrFrm()->FindPageFrm(); if( pPage ) for( sal_uInt16 i = 0; i < pMyDoc->GetPageDescCnt(); ++i ) if( pPage->GetPageDesc() == &pMyDoc->GetPageDesc( i ) ) { nDescNo = i; break; } } if( USHRT_MAX != nDescNo && nDescNo < pMyDoc->GetPageDescCnt() ) { // check if the attribute exists const SwPageDesc& rDesc = const_cast(pMyDoc) ->GetPageDesc( nDescNo ); const SwFmtCntnt* pCnt = 0; if( bInHeader ) { // mirrored pages? ignore for now const SwFmtHeader& rHd = rDesc.GetMaster().GetHeader(); if( rHd.GetHeaderFmt() ) pCnt = &rHd.GetHeaderFmt()->GetCntnt(); } else { const SwFmtFooter& rFt = rDesc.GetMaster().GetFooter(); if( rFt.GetFooterFmt() ) pCnt = &rFt.GetFooterFmt()->GetCntnt(); } if( pCnt && pCnt->GetCntntIdx() ) { SwNodeIndex aIdx( *pCnt->GetCntntIdx(), 1 ); SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); if( !pCNd ) pCNd = pMyDoc->GetNodes().GoNext( &aIdx ); const SwFrm* pFrm; Point aPt( m_pCurCrsr->GetPtPos() ); if( pCNd && 0 != ( pFrm = pCNd->getLayoutFrm( GetLayout(), &aPt, 0, sal_False ) )) { // then we can set the cursor in here SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); ClearMark(); SwPosition& rPos = *m_pCurCrsr->GetPoint(); rPos.nNode = *pCNd; rPos.nContent.Assign( pCNd, 0 ); bRet = !m_pCurCrsr->IsSelOvr(); if( bRet ) UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); } } } return bRet; } /// jump to the next index sal_Bool SwCrsrShell::GotoNextTOXBase( const OUString* pName ) { sal_Bool bRet = sal_False; const SwSectionFmts& rFmts = GetDoc()->GetSections(); SwCntntNode* pFnd = 0; for( sal_uInt16 n = rFmts.size(); n; ) { const SwSection* pSect = rFmts[ --n ]->GetSection(); if (TOX_CONTENT_SECTION == pSect->GetType()) { SwSectionNode const*const pSectNd( pSect->GetFmt()->GetSectionNode()); if ( pSectNd && m_pCurCrsr->GetPoint()->nNode < pSectNd->GetIndex() && (!pFnd || pFnd->GetIndex() > pSectNd->GetIndex()) && (!pName || *pName == static_cast(pSect)->GetTOXName())) { SwNodeIndex aIdx(*pSectNd, 1); SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); if (!pCNd) pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); if (pCNd && pCNd->EndOfSectionIndex() <= pSectNd->EndOfSectionIndex()) { SwCntntFrm const*const pCFrm( pCNd->getLayoutFrm(GetLayout())); if (pCFrm && (IsReadOnlyAvailable() || !pCFrm->IsProtected())) { pFnd = pCNd; } } } } } if( pFnd ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); m_pCurCrsr->GetPoint()->nNode = *pFnd; m_pCurCrsr->GetPoint()->nContent.Assign( pFnd, 0 ); bRet = !m_pCurCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); } return bRet; } /// jump to previous index sal_Bool SwCrsrShell::GotoPrevTOXBase( const OUString* pName ) { sal_Bool bRet = sal_False; const SwSectionFmts& rFmts = GetDoc()->GetSections(); SwCntntNode* pFnd = 0; for( sal_uInt16 n = rFmts.size(); n; ) { const SwSection* pSect = rFmts[ --n ]->GetSection(); if (TOX_CONTENT_SECTION == pSect->GetType()) { SwSectionNode const*const pSectNd( pSect->GetFmt()->GetSectionNode()); if ( pSectNd && m_pCurCrsr->GetPoint()->nNode > pSectNd->EndOfSectionIndex() && (!pFnd || pFnd->GetIndex() < pSectNd->GetIndex()) && (!pName || *pName == static_cast(pSect)->GetTOXName())) { SwNodeIndex aIdx(*pSectNd, 1); SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); if (!pCNd) pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); if (pCNd && pCNd->EndOfSectionIndex() <= pSectNd->EndOfSectionIndex()) { SwCntntFrm const*const pCFrm( pCNd->getLayoutFrm(GetLayout())); if (pCFrm && (IsReadOnlyAvailable() || !pCFrm->IsProtected())) { pFnd = pCNd; } } } } } if( pFnd ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); m_pCurCrsr->GetPoint()->nNode = *pFnd; m_pCurCrsr->GetPoint()->nContent.Assign( pFnd, 0 ); bRet = !m_pCurCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); } return bRet; } /// jump to index of TOXMark sal_Bool SwCrsrShell::GotoTOXMarkBase() { sal_Bool bRet = sal_False; SwTOXMarks aMarks; sal_uInt16 nCnt = GetDoc()->GetCurTOXMark( *m_pCurCrsr->GetPoint(), aMarks ); if( nCnt ) { // Take the 1. and get the index type. Search in its dependency list // for the actual index const SwTOXType* pType = aMarks[0]->GetTOXType(); SwIterator aIter( *pType ); const SwSectionNode* pSectNd; const SwSectionFmt* pSectFmt; for( SwTOXBase* pTOX = aIter.First(); pTOX; pTOX = aIter.Next() ) { if( pTOX->ISA( SwTOXBaseSection ) && 0 != ( pSectFmt = ((SwTOXBaseSection*)pTOX)->GetFmt() ) && 0 != ( pSectNd = pSectFmt->GetSectionNode() )) { SwNodeIndex aIdx( *pSectNd, 1 ); SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); if( !pCNd ) pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); const SwCntntFrm* pCFrm; if( pCNd && pCNd->EndOfSectionIndex() < pSectNd->EndOfSectionIndex() && 0 != ( pCFrm = pCNd->getLayoutFrm( GetLayout() ) ) && ( IsReadOnlyAvailable() || !pCFrm->IsProtected() )) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); m_pCurCrsr->GetPoint()->nNode = *pCNd; m_pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 ); bRet = !m_pCurCrsr->IsInProtectTable() && !m_pCurCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); break; } } } } return bRet; } /// Jump to next/previous table formula /// Optionally it is possible to also jump to broken formulas sal_Bool SwCrsrShell::GotoNxtPrvTblFormula( sal_Bool bNext, sal_Bool bOnlyErrors ) { if( IsTableMode() ) return sal_False; sal_Bool bFnd = sal_False; SwPosition& rPos = *m_pCurCrsr->GetPoint(); Point aPt; SwPosition aFndPos( GetDoc()->GetNodes().GetEndOfContent() ); if( !bNext ) aFndPos.nNode = 0; _SetGetExpFld aFndGEF( aFndPos ), aCurGEF( rPos ); { const SwNode* pSttNd = rPos.nNode.GetNode().FindTableBoxStartNode(); if( pSttNd ) { const SwTableBox* pTBox = pSttNd->FindTableNode()->GetTable(). GetTblBox( pSttNd->GetIndex() ); if( pTBox ) aCurGEF = _SetGetExpFld( *pTBox ); } } if( rPos.nNode < GetDoc()->GetNodes().GetEndOfExtras() ) // also at collection use only the first frame aCurGEF.SetBodyPos( *rPos.nNode.GetNode().GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, &rPos, sal_False ) ); { const SfxPoolItem* pItem; const SwTableBox* pTBox; sal_uInt32 n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA ); for( n = 0; n < nMaxItems; ++n ) if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem2( RES_BOXATR_FORMULA, n ) ) && 0 != (pTBox = ((SwTblBoxFormula*)pItem)->GetTableBox() ) && pTBox->GetSttNd() && pTBox->GetSttNd()->GetNodes().IsDocNodes() && ( !bOnlyErrors || !((SwTblBoxFormula*)pItem)->HasValidBoxes() ) ) { const SwCntntFrm* pCFrm; SwNodeIndex aIdx( *pTBox->GetSttNd() ); const SwCntntNode* pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); if( pCNd && 0 != ( pCFrm = pCNd->getLayoutFrm( GetLayout(), &aPt, 0, sal_False ) ) && (IsReadOnlyAvailable() || !pCFrm->IsProtected() )) { _SetGetExpFld aCmp( *pTBox ); aCmp.SetBodyPos( *pCFrm ); if( bNext ? ( aCurGEF < aCmp && aCmp < aFndGEF ) : ( aCmp < aCurGEF && aFndGEF < aCmp )) { aFndGEF = aCmp; bFnd = sal_True; } } } } if( bFnd ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); aFndGEF.GetPosOfContent( rPos ); m_pCurCrsr->DeleteMark(); bFnd = !m_pCurCrsr->IsSelOvr(); if( bFnd ) UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); } return bFnd; } /// jump to next/previous index marker sal_Bool SwCrsrShell::GotoNxtPrvTOXMark( sal_Bool bNext ) { if( IsTableMode() ) return sal_False; sal_Bool bFnd = sal_False; SwPosition& rPos = *m_pCurCrsr->GetPoint(); Point aPt; SwPosition aFndPos( GetDoc()->GetNodes().GetEndOfContent() ); if( !bNext ) aFndPos.nNode = 0; _SetGetExpFld aFndGEF( aFndPos ), aCurGEF( rPos ); if( rPos.nNode.GetIndex() < GetDoc()->GetNodes().GetEndOfExtras().GetIndex() ) // also at collection use only the first frame aCurGEF.SetBodyPos( *rPos.nNode.GetNode(). GetCntntNode()->getLayoutFrm( GetLayout(), &aPt, &rPos, sal_False ) ); { const SfxPoolItem* pItem; const SwCntntFrm* pCFrm; const SwTxtNode* pTxtNd; const SwTxtTOXMark* pTxtTOX; sal_uInt32 n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK ); for( n = 0; n < nMaxItems; ++n ) if( 0 != (pItem = GetDoc()->GetAttrPool().GetItem2( RES_TXTATR_TOXMARK, n ) ) && 0 != (pTxtTOX = ((SwTOXMark*)pItem)->GetTxtTOXMark() ) && ( pTxtNd = &pTxtTOX->GetTxtNode())->GetNodes().IsDocNodes() && 0 != ( pCFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt, 0, sal_False )) && ( IsReadOnlyAvailable() || !pCFrm->IsProtected() )) { SwNodeIndex aNdIndex( *pTxtNd ); // UNIX needs this object _SetGetExpFld aCmp( aNdIndex, *pTxtTOX, 0 ); aCmp.SetBodyPos( *pCFrm ); if( bNext ? ( aCurGEF < aCmp && aCmp < aFndGEF ) : ( aCmp < aCurGEF && aFndGEF < aCmp )) { aFndGEF = aCmp; bFnd = sal_True; } } } if( bFnd ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); aFndGEF.GetPosOfContent( rPos ); bFnd = !m_pCurCrsr->IsSelOvr(); if( bFnd ) UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); } return bFnd; } /// traveling between marks const SwTOXMark& SwCrsrShell::GotoTOXMark( const SwTOXMark& rStart, SwTOXSearch eDir ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); const SwTOXMark& rNewMark = GetDoc()->GotoTOXMark( rStart, eDir, IsReadOnlyAvailable() ); // set position SwPosition& rPos = *GetCrsr()->GetPoint(); rPos.nNode = rNewMark.GetTxtTOXMark()->GetTxtNode(); rPos.nContent.Assign( rPos.nNode.GetNode().GetCntntNode(), *rNewMark.GetTxtTOXMark()->GetStart() ); if( !m_pCurCrsr->IsSelOvr() ) UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); return rNewMark; } /// jump to next/previous field type void lcl_MakeFldLst( _SetGetExpFlds& rLst, const SwFieldType& rFldType, const bool bInReadOnly, const bool bChkInpFlag = false ) { // always search the 1. frame Point aPt; SwTxtFld* pTxtFld = NULL; SwIterator aIter(rFldType); for( SwFmtFld* pFmtFld = aIter.First(); pFmtFld; pFmtFld = aIter.Next() ) { pTxtFld = pFmtFld->GetTxtFld(); if ( pTxtFld != NULL && ( !bChkInpFlag || ((SwSetExpField*)pTxtFld->GetFmtFld().GetField())->GetInputFlag() ) ) { const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode(); const SwCntntFrm* pCFrm = rTxtNode.getLayoutFrm( rTxtNode.GetDoc()->GetCurrentLayout(), &aPt, 0, sal_False ); if ( pCFrm != NULL && ( bInReadOnly || !pCFrm->IsProtected() ) ) { _SetGetExpFld* pNew = new _SetGetExpFld( SwNodeIndex( rTxtNode ), pTxtFld ); pNew->SetBodyPos( *pCFrm ); rLst.insert( pNew ); } } } } sal_Bool SwCrsrShell::MoveFldType( const SwFieldType* pFldType, const bool bNext, const sal_uInt16 nResType, const bool bAddSetExpressionFldsToInputFlds ) { // sorted list of all fields _SetGetExpFlds aSrtLst; if ( pFldType ) { if( RES_INPUTFLD != pFldType->Which() && !pFldType->GetDepends() ) { return sal_False; } // found Modify object, add all fields to array ::lcl_MakeFldLst( aSrtLst, *pFldType, ( IsReadOnlyAvailable() ? true : false ) ); if( RES_INPUTFLD == pFldType->Which() && bAddSetExpressionFldsToInputFlds ) { // there are hidden input fields in the set exp. fields const SwFldTypes& rFldTypes = *mpDoc->GetFldTypes(); const size_t nSize = rFldTypes.size(); for( size_t i=0; i < nSize; ++i ) { pFldType = rFldTypes[ i ]; if ( RES_SETEXPFLD == pFldType->Which() ) { ::lcl_MakeFldLst( aSrtLst, *pFldType, ( IsReadOnlyAvailable() ? true : false ), true ); } } } } else { const SwFldTypes& rFldTypes = *mpDoc->GetFldTypes(); const size_t nSize = rFldTypes.size(); for( size_t i=0; i < nSize; ++i ) { pFldType = rFldTypes[ i ]; if( nResType == pFldType->Which() ) { ::lcl_MakeFldLst( aSrtLst, *pFldType, ( IsReadOnlyAvailable() ? true : false ) ); } } } // found no fields? if( aSrtLst.empty() ) return sal_False; _SetGetExpFlds::const_iterator it; SwCursor* pCrsr = getShellCrsr( true ); { // (1998): Always use field for search so that the right one is found as // well some are in frames that are anchored to a paragraph that has a // field const SwPosition& rPos = *pCrsr->GetPoint(); SwTxtNode* pTNd = rPos.nNode.GetNode().GetTxtNode(); OSL_ENSURE( pTNd, "No CntntNode" ); SwTxtFld * pTxtFld = pTNd->GetFldTxtAttrAt( rPos.nContent.GetIndex(), true ); const bool bDelFld = ( pTxtFld == NULL ); if( bDelFld ) { // create dummy for the search SwFmtFld* pFmtFld = new SwFmtFld( SwDateTimeField( (SwDateTimeFieldType*)mpDoc->GetSysFldType( RES_DATETIMEFLD ) ) ); pTxtFld = new SwTxtFld( *pFmtFld, rPos.nContent.GetIndex(), mpDoc->IsClipBoard() ); pTxtFld->ChgTxtNode( pTNd ); } _SetGetExpFld aSrch( rPos.nNode, pTxtFld, &rPos.nContent ); if( rPos.nNode.GetIndex() < mpDoc->GetNodes().GetEndOfExtras().GetIndex() ) { // also at collection use only the first frame Point aPt; aSrch.SetBodyPos( *pTNd->getLayoutFrm( GetLayout(), &aPt, &rPos, sal_False ) ); } it = aSrtLst.lower_bound( &aSrch ); if( bDelFld ) { delete (SwFmtFld*)&pTxtFld->GetAttr(); delete pTxtFld; } if( it != aSrtLst.end() && **it == aSrch ) // found { if( bNext ) { if( ++it == aSrtLst.end() ) return sal_False; // already at the end } else { if( it == aSrtLst.begin() ) return sal_False; // no more steps backward possible --it; } } else // not found { if( bNext ) { if( it == aSrtLst.end() ) return sal_False; } else { if( it == aSrtLst.begin() ) return sal_False; // no more steps backward possible --it; } } } const _SetGetExpFld& rFnd = **it; SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *pCrsr ); rFnd.GetPosOfContent( *pCrsr->GetPoint() ); sal_Bool bRet = !m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE ); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); return bRet; } sal_Bool SwCrsrShell::GotoFld( const SwFmtFld& rFld ) { sal_Bool bRet = sal_False; if( rFld.GetTxtFld() ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCursor* pCrsr = getShellCrsr( true ); SwCrsrSaveState aSaveState( *pCrsr ); SwTxtNode* pTNd = (SwTxtNode*)rFld.GetTxtFld()->GetpTxtNode(); pCrsr->GetPoint()->nNode = *pTNd; pCrsr->GetPoint()->nContent.Assign( pTNd, *rFld.GetTxtFld()->GetStart() ); bRet = !pCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); } return bRet; } SwTxtFld * SwCrsrShell::GetTxtFldAtPos( const SwPosition* pPos, const bool bIncludeInputFldAtStart ) const { SwTxtFld* pTxtFld = NULL; SwTxtNode * const pNode = pPos->nNode.GetNode().GetTxtNode(); if ( pNode != NULL ) { pTxtFld = pNode->GetFldTxtAttrAt( pPos->nContent.GetIndex(), bIncludeInputFldAtStart ); } return pTxtFld; } SwField* SwCrsrShell::GetFieldAtCrsr( const SwPaM* pCrsr, const bool bIncludeInputFldAtStart ) const { SwField* pFieldAtCrsr = NULL; SwTxtFld* pTxtFld = GetTxtFldAtPos( pCrsr->Start(), bIncludeInputFldAtStart ); if ( pTxtFld != NULL && pCrsr->Start()->nNode == pCrsr->End()->nNode ) { const xub_StrLen nTxtFldLength = pTxtFld->End() != NULL ? *(pTxtFld->End()) - *(pTxtFld->GetStart()) : 1; if ( ( pCrsr->End()->nContent.GetIndex() - pCrsr->Start()->nContent.GetIndex() ) <= nTxtFldLength ) { pFieldAtCrsr = (SwField*)pTxtFld->GetFmtFld().GetField(); } } return pFieldAtCrsr; } SwField* SwCrsrShell::GetCurFld( const bool bIncludeInputFldAtStart ) const { SwPaM* pCrsr = GetCrsr(); if ( pCrsr->GetNext() != pCrsr ) { // multi selection not handled. return NULL; } SwField* pCurFld = GetFieldAtCrsr( pCrsr, bIncludeInputFldAtStart );; if ( pCurFld != NULL && RES_TABLEFLD == pCurFld->GetTyp()->Which() ) { // TabellenFormel ? wandel internen in externen Namen um const SwTableNode* pTblNd = IsCrsrInTbl(); ((SwTblField*)pCurFld)->PtrToBoxNm( pTblNd ? &pTblNd->GetTable() : 0 ); } return pCurFld; } bool SwCrsrShell::CrsrInsideInputFld() const { bool bCrsrInsideInputFld = false; const SwPaM* pCrsr = GetCrsr(); const SwPaM* pFirst = pCrsr; do { bCrsrInsideInputFld = dynamic_cast(GetFieldAtCrsr( pCrsr, false )) != NULL; pCrsr = static_cast(pCrsr->GetNext()); } while ( !bCrsrInsideInputFld && pCrsr != pFirst ); return bCrsrInsideInputFld; } bool SwCrsrShell::PosInsideInputFld( const SwPosition& rPos ) const { return dynamic_cast(GetTxtFldAtPos( &rPos, false )) != NULL; } bool SwCrsrShell::DocPtInsideInputFld( const Point& rDocPt ) const { SwPosition aPos( *(GetCrsr()->Start()) ); Point aDocPt( rDocPt ); if ( GetLayout()->GetCrsrOfst( &aPos, aDocPt ) ) { return PosInsideInputFld( aPos ); } return false; } xub_StrLen SwCrsrShell::StartOfInputFldAtPos( const SwPosition& rPos ) const { const SwTxtInputFld* pTxtInputFld = dynamic_cast(GetTxtFldAtPos( &rPos, true )); if ( pTxtInputFld == NULL ) { OSL_ENSURE( false, " - no Input Field at given position" ); return 0; } return *(pTxtInputFld->GetStart()); } xub_StrLen SwCrsrShell::EndOfInputFldAtPos( const SwPosition& rPos ) const { const SwTxtInputFld* pTxtInputFld = dynamic_cast(GetTxtFldAtPos( &rPos, true )); if ( pTxtInputFld == NULL ) { OSL_ENSURE( false, " - no Input Field at given position" ); return 0; } return *(pTxtInputFld->End()); } void SwCrsrShell::GotoOutline( sal_uInt16 nIdx ) { SwCursor* pCrsr = getShellCrsr( true ); SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *pCrsr ); const SwNodes& rNds = GetDoc()->GetNodes(); SwTxtNode* pTxtNd = (SwTxtNode*)rNds.GetOutLineNds()[ nIdx ]->GetTxtNode(); pCrsr->GetPoint()->nNode = *pTxtNd; pCrsr->GetPoint()->nContent.Assign( pTxtNd, 0 ); if( !pCrsr->IsSelOvr() ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); } bool SwCrsrShell::GotoOutline( const OUString& rName ) { SwCursor* pCrsr = getShellCrsr( true ); SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *pCrsr ); bool bRet = false; if( mpDoc->GotoOutline( *pCrsr->GetPoint(), rName ) && !pCrsr->IsSelOvr() ) { UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); bRet = true; } return bRet; } /// jump to next node with outline num. sal_Bool SwCrsrShell::GotoNextOutline() { SwCursor* pCrsr = getShellCrsr( true ); const SwNodes& rNds = GetDoc()->GetNodes(); SwNode* pNd = pCrsr->GetNode(); sal_uInt16 nPos; if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos )) ++nPos; if( nPos == rNds.GetOutLineNds().size() ) return sal_False; pNd = rNds.GetOutLineNds()[ nPos ]; SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *pCrsr ); pCrsr->GetPoint()->nNode = *pNd; pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 ); sal_Bool bRet = !pCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); return bRet; } /// jump to previous node with outline num. sal_Bool SwCrsrShell::GotoPrevOutline() { SwCursor* pCrsr = getShellCrsr( true ); const SwNodes& rNds = GetDoc()->GetNodes(); SwNode* pNd = pCrsr->GetNode(); sal_uInt16 nPos; rNds.GetOutLineNds().Seek_Entry( pNd, &nPos ); sal_Bool bRet = sal_False; if( nPos ) { --nPos; // before pNd = rNds.GetOutLineNds()[ nPos ]; if( pNd->GetIndex() > pCrsr->GetPoint()->nNode.GetIndex() ) return sal_False; SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *pCrsr ); pCrsr->GetPoint()->nNode = *pNd; pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)pNd, 0 ); bRet = !pCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); } return bRet; } /// search "outline position" before previous outline node at given level sal_uInt16 SwCrsrShell::GetOutlinePos( sal_uInt8 nLevel ) { SwPaM* pCrsr = getShellCrsr( true ); const SwNodes& rNds = GetDoc()->GetNodes(); SwNode* pNd = pCrsr->GetNode(); sal_uInt16 nPos; if( rNds.GetOutLineNds().Seek_Entry( pNd, &nPos )) nPos++; // is at correct position; take next for while while( nPos-- ) // check the one in front of the current { pNd = rNds.GetOutLineNds()[ nPos ]; if( ((SwTxtNode*)pNd)->GetAttrOutlineLevel()-1 <= nLevel ) return nPos; } return USHRT_MAX; // no more left } sal_Bool SwCrsrShell::MakeOutlineSel( sal_uInt16 nSttPos, sal_uInt16 nEndPos, sal_Bool bWithChildren ) { const SwNodes& rNds = GetDoc()->GetNodes(); const SwOutlineNodes& rOutlNds = rNds.GetOutLineNds(); if( rOutlNds.empty() ) return sal_False; SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves if( nSttPos > nEndPos ) // parameters switched? { OSL_ENSURE( !this, "Start > End for array access" ); sal_uInt16 nTmp = nSttPos; nSttPos = nEndPos; nEndPos = nTmp; } SwNode* pSttNd = rOutlNds[ nSttPos ]; SwNode* pEndNd = rOutlNds[ nEndPos ]; if( bWithChildren ) { const int nLevel = pEndNd->GetTxtNode()->GetAttrOutlineLevel()-1; for( ++nEndPos; nEndPos < rOutlNds.size(); ++nEndPos ) { pEndNd = rOutlNds[ nEndPos ]; const int nNxtLevel = pEndNd->GetTxtNode()->GetAttrOutlineLevel()-1; if( nNxtLevel <= nLevel ) break; // EndPos is now on the next one } } // if without children then set onto next one else if( ++nEndPos < rOutlNds.size() ) pEndNd = rOutlNds[ nEndPos ]; if( nEndPos == rOutlNds.size() ) // no end found pEndNd = &rNds.GetEndOfContent(); KillPams(); SwCrsrSaveState aSaveState( *m_pCurCrsr ); // set end to the end of the previous content node m_pCurCrsr->GetPoint()->nNode = *pSttNd; m_pCurCrsr->GetPoint()->nContent.Assign( pSttNd->GetCntntNode(), 0 ); m_pCurCrsr->SetMark(); m_pCurCrsr->GetPoint()->nNode = *pEndNd; m_pCurCrsr->Move( fnMoveBackward, fnGoNode ); // end of predecessor // and everything is already selected sal_Bool bRet = !m_pCurCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); return bRet; } /// jump to reference marker sal_Bool SwCrsrShell::GotoRefMark( const OUString& rRefMark, sal_uInt16 nSubType, sal_uInt16 nSeqNo ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); sal_Int32 nPos = -1; SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( GetDoc(), rRefMark, nSubType, nSeqNo, &nPos ); if( pTxtNd && pTxtNd->GetNodes().IsDocNodes() ) { m_pCurCrsr->GetPoint()->nNode = *pTxtNd; m_pCurCrsr->GetPoint()->nContent.Assign( pTxtNd, nPos ); if( !m_pCurCrsr->IsSelOvr() ) { UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); return sal_True; } } return sal_False; } sal_Bool SwCrsrShell::IsPageAtPos( const Point &rPt ) const { if( GetLayout() ) return 0 != GetLayout()->GetPageAtPos( rPt ); return sal_False; } sal_Bool SwCrsrShell::GetContentAtPos( const Point& rPt, SwContentAtPos& rCntntAtPos, sal_Bool bSetCrsr, SwRect* pFldRect ) { SET_CURR_SHELL( this ); sal_Bool bRet = sal_False; if( !IsTableMode() ) { Point aPt( rPt ); SwPosition aPos( *m_pCurCrsr->GetPoint() ); SwTxtNode* pTxtNd; SwCntntFrm *pFrm(0); SwTxtAttr* pTxtAttr; SwCrsrMoveState aTmpState; aTmpState.bFieldInfo = sal_True; aTmpState.bExactOnly = !( SwContentAtPos::SW_OUTLINE & rCntntAtPos.eCntntAtPos ); aTmpState.bCntntCheck = (SwContentAtPos::SW_CONTENT_CHECK & rCntntAtPos.eCntntAtPos) ? sal_True : sal_False; aTmpState.bSetInReadOnly = IsReadOnlyAvailable(); SwSpecialPos aSpecialPos; aTmpState.pSpecialPos = ( SwContentAtPos::SW_SMARTTAG & rCntntAtPos.eCntntAtPos ) ? &aSpecialPos : 0; const sal_Bool bCrsrFoundExact = GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ); pTxtNd = aPos.nNode.GetNode().GetTxtNode(); const SwNodes& rNds = GetDoc()->GetNodes(); if( pTxtNd && SwContentAtPos::SW_OUTLINE & rCntntAtPos.eCntntAtPos && !rNds.GetOutLineNds().empty() ) { const SwTxtNode* pONd = pTxtNd->FindOutlineNodeOfLevel( MAXLEVEL-1); if( pONd ) { rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_OUTLINE; rCntntAtPos.sStr = pONd->GetExpandTxt( 0, -1, true, true ); bRet = sal_True; } } else if ( SwContentAtPos::SW_CONTENT_CHECK & rCntntAtPos.eCntntAtPos && bCrsrFoundExact ) { bRet = sal_True; } else if( pTxtNd && SwContentAtPos::SW_NUMLABEL & rCntntAtPos.eCntntAtPos) { bRet = aTmpState.bInNumPortion; rCntntAtPos.aFnd.pNode = pTxtNd; Size aSizeLogic(aTmpState.nInNumPostionOffset, 0); Size aSizePixel = GetWin()->LogicToPixel(aSizeLogic); rCntntAtPos.nDist = aSizePixel.Width(); } else if( bCrsrFoundExact && pTxtNd ) { if( !aTmpState.bPosCorr ) { if ( !bRet && SwContentAtPos::SW_SMARTTAG & rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo ) { const SwWrongList* pSmartTagList = pTxtNd->GetSmartTags(); sal_Int32 nCurrent = aPos.nContent.GetIndex(); const sal_Int32 nBegin = nCurrent; sal_Int32 nLen = 1; if ( pSmartTagList && pSmartTagList->InWrongWord( nCurrent, nLen ) && !pTxtNd->IsSymbol(nBegin) ) { const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin ); const SwWrongList* pSubList = pSmartTagList->SubList( nIndex ); if ( pSubList ) { nCurrent = aTmpState.pSpecialPos->nCharOfst; if ( pSubList->InWrongWord( nCurrent, nLen ) ) bRet = sal_True; } else bRet = sal_True; if( bRet && bSetCrsr ) { SwCrsrSaveState aSaveState( *m_pCurCrsr ); SwCallLink aLk( *this ); // watch Crsr-Moves m_pCurCrsr->DeleteMark(); *m_pCurCrsr->GetPoint() = aPos; if( m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE) ) bRet = sal_False; else UpdateCrsr(); } if( bRet ) { rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_SMARTTAG; if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) ) pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); } } } if ( !bRet && ( SwContentAtPos::SW_FIELD | SwContentAtPos::SW_CLICKFIELD ) & rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo ) { pTxtAttr = pTxtNd->GetFldTxtAttrAt( aPos.nContent.GetIndex() ); const SwField* pFld = pTxtAttr != NULL ? pTxtAttr->GetFmtFld().GetField() : 0; if ( SwContentAtPos::SW_CLICKFIELD & rCntntAtPos.eCntntAtPos && pFld && !pFld->HasClickHdl() ) { pFld = 0; } if ( pFld ) { if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) ) pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); if( bSetCrsr ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); m_pCurCrsr->DeleteMark(); *m_pCurCrsr->GetPoint() = aPos; if( m_pCurCrsr->IsSelOvr() ) { // allow click fields in protected sections // only placeholder is not possible if( SwContentAtPos::SW_FIELD & rCntntAtPos.eCntntAtPos || RES_JUMPEDITFLD == pFld->Which() ) pFld = 0; } else UpdateCrsr(); } else if( RES_TABLEFLD == pFld->Which() && ((SwTblField*)pFld)->IsIntrnlName() ) { // create from internal (for CORE) the external // (for UI) formula const SwTableNode* pTblNd = pTxtNd->FindTableNode(); if( pTblNd ) // steht in einer Tabelle ((SwTblField*)pFld)->PtrToBoxNm( &pTblNd->GetTable() ); } } if( pFld ) { rCntntAtPos.aFnd.pFld = pFld; rCntntAtPos.pFndTxtAttr = pTxtAttr; rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FIELD; bRet = sal_True; } } if( !bRet && SwContentAtPos::SW_FORMCTRL & rCntntAtPos.eCntntAtPos ) { IDocumentMarkAccess* pMarksAccess = GetDoc()->getIDocumentMarkAccess( ); sw::mark::IFieldmark* pFldBookmark = pMarksAccess->getFieldmarkFor( aPos ); if( bCrsrFoundExact && pTxtNd && pFldBookmark) { rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FORMCTRL; rCntntAtPos.aFnd.pFldmark = pFldBookmark; bRet=sal_True; } } if( !bRet && SwContentAtPos::SW_FTN & rCntntAtPos.eCntntAtPos ) { if( aTmpState.bFtnNoInfo ) { // over the footnote's char bRet = sal_True; if( bSetCrsr ) { *m_pCurCrsr->GetPoint() = aPos; if( !GotoFtnAnchor() ) bRet = sal_False; } if( bRet ) rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN; } else if ( 0 != ( pTxtAttr = pTxtNd->GetTxtAttrForCharAt( aPos.nContent.GetIndex(), RES_TXTATR_FTN )) ) { bRet = sal_True; if( bSetCrsr ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); m_pCurCrsr->GetPoint()->nNode = *((SwTxtFtn*)pTxtAttr)->GetStartNode(); SwCntntNode* pCNd = GetDoc()->GetNodes().GoNextSection( &m_pCurCrsr->GetPoint()->nNode, sal_True, !IsReadOnlyAvailable() ); if( pCNd ) { m_pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 ); if( m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE )) bRet = sal_False; else UpdateCrsr(); } else bRet = sal_False; } if( bRet ) { rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_FTN; rCntntAtPos.pFndTxtAttr = pTxtAttr; rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr(); if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) ) pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); } } } if( !bRet && ( SwContentAtPos::SW_TOXMARK | SwContentAtPos::SW_REFMARK ) & rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo ) { pTxtAttr = 0; if( SwContentAtPos::SW_TOXMARK & rCntntAtPos.eCntntAtPos ) { ::std::vector const marks( pTxtNd->GetTxtAttrsAt( aPos.nContent.GetIndex(), RES_TXTATR_TOXMARK)); if (marks.size()) { // hmm... can only return 1 here pTxtAttr = *marks.begin(); } } if( !pTxtAttr && SwContentAtPos::SW_REFMARK & rCntntAtPos.eCntntAtPos ) { ::std::vector const marks( pTxtNd->GetTxtAttrsAt( aPos.nContent.GetIndex(), RES_TXTATR_REFMARK)); if (marks.size()) { // hmm... can only return 1 here pTxtAttr = *marks.begin(); } } if( pTxtAttr ) { bRet = sal_True; if( bSetCrsr ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); m_pCurCrsr->DeleteMark(); *m_pCurCrsr->GetPoint() = aPos; if( m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE ) ) bRet = sal_False; else UpdateCrsr(); } if( bRet ) { const sal_Int32* pEnd = pTxtAttr->GetEnd(); if( pEnd ) rCntntAtPos.sStr = pTxtNd->GetExpandTxt( *pTxtAttr->GetStart(), *pEnd - *pTxtAttr->GetStart() ); else if( RES_TXTATR_TOXMARK == pTxtAttr->Which()) rCntntAtPos.sStr = pTxtAttr->GetTOXMark().GetAlternativeText(); rCntntAtPos.eCntntAtPos = RES_TXTATR_TOXMARK == pTxtAttr->Which() ? SwContentAtPos::SW_TOXMARK : SwContentAtPos::SW_REFMARK; rCntntAtPos.pFndTxtAttr = pTxtAttr; rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr(); if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) ) pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); } } } if ( !bRet && SwContentAtPos::SW_INETATTR & rCntntAtPos.eCntntAtPos && !aTmpState.bFtnNoInfo ) { pTxtAttr = pTxtNd->GetTxtAttrAt( aPos.nContent.GetIndex(), RES_TXTATR_INETFMT); // "detect" only INetAttrs with URLs if( pTxtAttr && !pTxtAttr->GetINetFmt().GetValue().isEmpty() ) { bRet = sal_True; if( bSetCrsr ) { SwCrsrSaveState aSaveState( *m_pCurCrsr ); SwCallLink aLk( *this ); // watch Crsr-Moves m_pCurCrsr->DeleteMark(); *m_pCurCrsr->GetPoint() = aPos; if( m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE) ) bRet = sal_False; else UpdateCrsr(); } if( bRet ) { rCntntAtPos.sStr = pTxtNd->GetExpandTxt( *pTxtAttr->GetStart(), *pTxtAttr->GetEnd() - *pTxtAttr->GetStart() ); rCntntAtPos.aFnd.pAttr = &pTxtAttr->GetAttr(); rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_INETATTR; rCntntAtPos.pFndTxtAttr = pTxtAttr; if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) ) pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); } } } if( !bRet && SwContentAtPos::SW_REDLINE & rCntntAtPos.eCntntAtPos ) { const SwRedline* pRedl = GetDoc()->GetRedline(aPos, NULL); if( pRedl ) { rCntntAtPos.aFnd.pRedl = pRedl; rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_REDLINE; rCntntAtPos.pFndTxtAttr = 0; bRet = sal_True; if( pFldRect && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt ) ) ) pFrm->GetCharRect( *pFldRect, aPos, &aTmpState ); } } } if( !bRet && ( SwContentAtPos::SW_TABLEBOXFML & rCntntAtPos.eCntntAtPos #ifdef DBG_UTIL || SwContentAtPos::SW_TABLEBOXVALUE & rCntntAtPos.eCntntAtPos #endif ) ) { const SwTableNode* pTblNd; const SwTableBox* pBox; const SwStartNode* pSttNd = pTxtNd->FindTableBoxStartNode(); const SfxPoolItem* pItem; if( pSttNd && 0 != ( pTblNd = pTxtNd->FindTableNode()) && 0 != ( pBox = pTblNd->GetTable().GetTblBox( pSttNd->GetIndex() )) && #ifdef DBG_UTIL ( SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMULA, sal_False, &pItem ) || SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( RES_BOXATR_VALUE, sal_False, &pItem )) #else SFX_ITEM_SET == pBox->GetFrmFmt()->GetItemState( RES_BOXATR_FORMULA, sal_False, &pItem ) #endif ) { SwFrm* pF = pTxtNd->getLayoutFrm( GetLayout(), &aPt ); if( pF ) { // then the CellFrame pFrm = (SwCntntFrm*)pF; while( pF && !pF->IsCellFrm() ) pF = pF->GetUpper(); } if( aTmpState.bPosCorr ) { if( pF && !pF->Frm().IsInside( aPt )) pF = 0; } else if( !pF ) pF = pFrm; if( pF ) // only then it is valid { // create from internal (for CORE) the external // (for UI) formula rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXFML; #ifdef DBG_UTIL if( RES_BOXATR_VALUE == pItem->Which() ) rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_TABLEBOXVALUE; else #endif ((SwTblBoxFormula*)pItem)->PtrToBoxNm( &pTblNd->GetTable() ); bRet = sal_True; if( bSetCrsr ) { SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); *m_pCurCrsr->GetPoint() = aPos; if( m_pCurCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE) ) bRet = sal_False; else UpdateCrsr(); } if( bRet ) { if( pFldRect ) { *pFldRect = pF->Prt(); *pFldRect += pF->Frm().Pos(); } rCntntAtPos.pFndTxtAttr = 0; rCntntAtPos.aFnd.pAttr = pItem; } } } } #ifdef DBG_UTIL if( !bRet && SwContentAtPos::SW_CURR_ATTRS & rCntntAtPos.eCntntAtPos ) { const sal_Int32 n = aPos.nContent.GetIndex(); SfxItemSet aSet( GetDoc()->GetAttrPool(), POOLATTR_BEGIN, POOLATTR_END - 1 ); if( pTxtNd->GetpSwpHints() ) { for( sal_uInt16 i = 0; i < pTxtNd->GetSwpHints().Count(); ++i ) { const SwTxtAttr* pHt = pTxtNd->GetSwpHints()[i]; const sal_Int32 nAttrStart = *pHt->GetStart(); if( nAttrStart > n ) // over the section break; if( 0 != pHt->End() && ( ( nAttrStart < n && ( pHt->DontExpand() ? n < *pHt->End() : n <= *pHt->End() )) || ( n == nAttrStart && ( nAttrStart == *pHt->End() || !n ))) ) { aSet.Put( pHt->GetAttr() ); } } if( pTxtNd->HasSwAttrSet() && pTxtNd->GetpSwAttrSet()->Count() ) { SfxItemSet aFmtSet( pTxtNd->GetSwAttrSet() ); // remove all from format set that are also in TextSet aFmtSet.Differentiate( aSet ); // now merge all together aSet.Put( aFmtSet ); } } else pTxtNd->SwCntntNode::GetAttr( aSet ); rCntntAtPos.sStr = "Pos: ("; rCntntAtPos.sStr += OUString::number( aPos.nNode.GetIndex()); rCntntAtPos.sStr += ":"; rCntntAtPos.sStr += OUString::number( aPos.nContent.GetIndex()); rCntntAtPos.sStr += ")"; rCntntAtPos.sStr += "\nAbs.Vorl.: "; // translation *might be* "paragraph template" rCntntAtPos.sStr += pTxtNd->GetFmtColl()->GetName(); if( pTxtNd->GetCondFmtColl() ) { // translation *might be* "conditional template" rCntntAtPos.sStr += "\nBed.Vorl.: " + pTxtNd->GetCondFmtColl()->GetName(); } if( aSet.Count() ) { OUString sAttrs; SfxItemIter aIter( aSet ); const SfxPoolItem* pItem = aIter.FirstItem(); while( true ) { if( !IsInvalidItem( pItem )) { OUString aStr; GetDoc()->GetAttrPool().GetPresentation( *pItem, SFX_ITEM_PRESENTATION_COMPLETE, SFX_MAPUNIT_CM, aStr ); if (!sAttrs.isEmpty()) sAttrs += ", "; sAttrs += aStr; } if( aIter.IsAtEnd() ) break; pItem = aIter.NextItem(); } if (!sAttrs.isEmpty()) { if( !rCntntAtPos.sStr.isEmpty() ) rCntntAtPos.sStr += "\n"; rCntntAtPos.sStr += "Attr: " + sAttrs; } } bRet = sal_True; rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_CURR_ATTRS; } #endif } } if( !bRet ) { rCntntAtPos.eCntntAtPos = SwContentAtPos::SW_NOTHING; rCntntAtPos.aFnd.pFld = 0; } return bRet; } // #i90516# const SwPostItField* SwCrsrShell::GetPostItFieldAtCursor() const { const SwPostItField* pPostItFld = 0; if ( !IsTableMode() ) { const SwPosition* pCursorPos = _GetCrsr()->GetPoint(); const SwTxtNode* pTxtNd = pCursorPos->nNode.GetNode().GetTxtNode(); if ( pTxtNd ) { SwTxtAttr* pTxtAttr = pTxtNd->GetFldTxtAttrAt( pCursorPos->nContent.GetIndex() ); const SwField* pFld = pTxtAttr != NULL ? pTxtAttr->GetFmtFld().GetField() : 0; if ( pFld && pFld->Which()== RES_POSTITFLD ) { pPostItFld = static_cast(pFld); } } } return pPostItFld; } /// is the node in a protected section? bool SwContentAtPos::IsInProtectSect() const { const SwTxtNode* pNd = 0; if( pFndTxtAttr ) { switch( eCntntAtPos ) { case SW_FIELD: case SW_CLICKFIELD: pNd = ((SwTxtFld*)pFndTxtAttr)->GetpTxtNode(); break; case SW_FTN: pNd = &((SwTxtFtn*)pFndTxtAttr)->GetTxtNode(); break; case SW_INETATTR: pNd = ((SwTxtINetFmt*)pFndTxtAttr)->GetpTxtNode(); break; default: break; } } const SwCntntFrm* pFrm; return pNd && ( pNd->IsInProtectSect() || ( 0 != ( pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), 0,0,sal_False)) && pFrm->IsProtected() )); } bool SwContentAtPos::IsInRTLText()const { bool bRet = false; const SwTxtNode* pNd = 0; if (pFndTxtAttr && (eCntntAtPos == SW_FTN)) { const SwTxtFtn* pTxtFtn = static_cast(pFndTxtAttr); if(pTxtFtn->GetStartNode()) { SwStartNode* pSttNd = pTxtFtn->GetStartNode()->GetNode().GetStartNode(); SwPaM aTemp( *pSttNd ); aTemp.Move(fnMoveForward, fnGoNode); SwCntntNode* pCntntNode = aTemp.GetCntntNode(); if(pCntntNode && pCntntNode->IsTxtNode()) pNd = static_cast(pCntntNode); } } if(pNd) { SwIterator aIter(*pNd); SwTxtFrm* pTmpFrm = aIter.First(); while( pTmpFrm ) { if ( !pTmpFrm->IsFollow()) { bRet = pTmpFrm->IsRightToLeft(); break; } pTmpFrm = aIter.Next(); } } return bRet; } sal_Bool SwCrsrShell::SelectTxt( const xub_StrLen nStart, const xub_StrLen nEnd ) { SET_CURR_SHELL( this ); sal_Bool bRet = sal_False; SwCallLink aLk( *this ); SwCrsrSaveState aSaveState( *m_pCurCrsr ); SwPosition& rPos = *m_pCurCrsr->GetPoint(); m_pCurCrsr->DeleteMark(); rPos.nContent = nStart; m_pCurCrsr->SetMark(); rPos.nContent = nEnd; if( !m_pCurCrsr->IsSelOvr() ) { UpdateCrsr(); bRet = sal_True; } return bRet; } sal_Bool SwCrsrShell::SelectTxtAttr( sal_uInt16 nWhich, sal_Bool bExpand, const SwTxtAttr* pTxtAttr ) { SET_CURR_SHELL( this ); sal_Bool bRet = sal_False; if( !IsTableMode() ) { if( !pTxtAttr ) { SwPosition& rPos = *m_pCurCrsr->GetPoint(); SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode(); pTxtAttr = (pTxtNd) ? pTxtNd->GetTxtAttrAt(rPos.nContent.GetIndex(), static_cast(nWhich), (bExpand) ? SwTxtNode::EXPAND : SwTxtNode::DEFAULT) : 0; } if( pTxtAttr ) { const sal_Int32* pEnd = pTxtAttr->End(); bRet = SelectTxt( *pTxtAttr->GetStart(), ( pEnd ? *pEnd : *pTxtAttr->GetStart() + 1 ) ); } } return bRet; } bool SwCrsrShell::GotoINetAttr( const SwTxtINetFmt& rAttr ) { bool bRet = false; if( rAttr.GetpTxtNode() ) { SwCursor* pCrsr = getShellCrsr( true ); SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *pCrsr ); pCrsr->GetPoint()->nNode = *rAttr.GetpTxtNode(); pCrsr->GetPoint()->nContent.Assign( (SwTxtNode*)rAttr.GetpTxtNode(), *rAttr.GetStart() ); bRet = !pCrsr->IsSelOvr(); if( bRet ) UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); } return bRet; } const SwFmtINetFmt* SwCrsrShell::FindINetAttr( const OUString& rName ) const { return mpDoc->FindINetAttr( rName ); } sal_Bool SwCrsrShell::GetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode, SwRect& rRect, sal_Int16& rOrient ) { SET_CURR_SHELL( this ); sal_Bool bRet = sal_False; if (!IsTableMode() && !HasSelection() && GetDoc()->GetIDocumentUndoRedo().DoesUndo()) { Point aPt( rPt ); SwPosition aPos( *m_pCurCrsr->GetPoint() ); SwFillCrsrPos aFPos( eFillMode ); SwCrsrMoveState aTmpState( &aFPos ); if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) && !aPos.nNode.GetNode().IsProtect()) { // start position in protected section? rRect = aFPos.aCrsr; rOrient = aFPos.eOrient; bRet = sal_True; } } return bRet; } sal_Bool SwCrsrShell::SetShadowCrsrPos( const Point& rPt, SwFillMode eFillMode ) { SET_CURR_SHELL( this ); sal_Bool bRet = sal_False; if (!IsTableMode() && !HasSelection() && GetDoc()->GetIDocumentUndoRedo().DoesUndo()) { Point aPt( rPt ); SwPosition aPos( *m_pCurCrsr->GetPoint() ); SwFillCrsrPos aFPos( eFillMode ); SwCrsrMoveState aTmpState( &aFPos ); if( GetLayout()->GetCrsrOfst( &aPos, aPt, &aTmpState ) ) { SwCallLink aLk( *this ); // watch Crsr-Moves StartAction(); SwCntntNode* pCNd = aPos.nNode.GetNode().GetCntntNode(); SwUndoId nUndoId = UNDO_INS_FROM_SHADOWCRSR; // If only the paragraph attributes "Adjust" or "LRSpace" are set, // then the following should not delete those again. if( 0 == aFPos.nParaCnt + aFPos.nColumnCnt && ( FILL_INDENT == aFPos.eMode || ( text::HoriOrientation::NONE != aFPos.eOrient && 0 == aFPos.nTabCnt + aFPos.nSpaceCnt )) && pCNd && pCNd->Len() ) nUndoId = UNDO_EMPTY; GetDoc()->GetIDocumentUndoRedo().StartUndo( nUndoId, NULL ); SwTxtFmtColl* pNextFmt = 0; SwTxtNode* pTNd = pCNd->GetTxtNode(); if( pTNd ) pNextFmt = &pTNd->GetTxtColl()->GetNextTxtFmtColl(); const SwSectionNode* pSectNd = pCNd->FindSectionNode(); if( pSectNd && aFPos.nParaCnt ) { SwNodeIndex aEnd( aPos.nNode, 1 ); while( aEnd.GetNode().IsEndNode() && (const SwNode*)&aEnd.GetNode() != pSectNd->EndOfSectionNode() ) ++aEnd; if( aEnd.GetNode().IsEndNode() && pCNd->Len() == aPos.nContent.GetIndex() ) aPos.nNode = *pSectNd->EndOfSectionNode(); } for( sal_uInt16 n = 0; n < aFPos.nParaCnt + aFPos.nColumnCnt; ++n ) { GetDoc()->AppendTxtNode( aPos ); if( !n && pNextFmt ) { *m_pCurCrsr->GetPoint() = aPos; GetDoc()->SetTxtFmtColl( *m_pCurCrsr, pNextFmt, false ); } if( n < aFPos.nColumnCnt ) { *m_pCurCrsr->GetPoint() = aPos; GetDoc()->InsertPoolItem( *m_pCurCrsr, SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE, RES_BREAK ), 0); } } *m_pCurCrsr->GetPoint() = aPos; switch( aFPos.eMode ) { case FILL_INDENT: if( 0 != (pCNd = aPos.nNode.GetNode().GetCntntNode() )) { SfxItemSet aSet( GetDoc()->GetAttrPool(), RES_LR_SPACE, RES_LR_SPACE, RES_PARATR_ADJUST, RES_PARATR_ADJUST, 0 ); SvxLRSpaceItem aLR( (SvxLRSpaceItem&) pCNd->GetAttr( RES_LR_SPACE ) ); aLR.SetTxtLeft( aFPos.nTabCnt ); aLR.SetTxtFirstLineOfst( 0 ); aSet.Put( aLR ); const SvxAdjustItem& rAdj = (SvxAdjustItem&)pCNd-> GetAttr( RES_PARATR_ADJUST ); if( SVX_ADJUST_LEFT != rAdj.GetAdjust() ) aSet.Put( SvxAdjustItem( SVX_ADJUST_LEFT, RES_PARATR_ADJUST ) ); GetDoc()->InsertItemSet( *m_pCurCrsr, aSet, 0 ); } else { OSL_ENSURE( !this, "No CntntNode" ); } break; case FILL_TAB: case FILL_SPACE: { OUStringBuffer sInsert; if (aFPos.nTabCnt) comphelper::string::padToLength(sInsert, aFPos.nTabCnt, '\t'); if (aFPos.nSpaceCnt) comphelper::string::padToLength(sInsert, sInsert.getLength() + aFPos.nSpaceCnt, ' '); if (!sInsert.isEmpty()) GetDoc()->InsertString( *m_pCurCrsr, sInsert.makeStringAndClear()); } // no break - still need to set orientation case FILL_MARGIN: if( text::HoriOrientation::NONE != aFPos.eOrient ) { SvxAdjustItem aAdj( SVX_ADJUST_LEFT, RES_PARATR_ADJUST ); switch( aFPos.eOrient ) { case text::HoriOrientation::CENTER: aAdj.SetAdjust( SVX_ADJUST_CENTER ); break; case text::HoriOrientation::RIGHT: aAdj.SetAdjust( SVX_ADJUST_RIGHT ); break; default: break; } GetDoc()->InsertPoolItem( *m_pCurCrsr, aAdj, 0 ); } break; } GetDoc()->GetIDocumentUndoRedo().EndUndo( nUndoId, NULL ); EndAction(); bRet = sal_True; } } return bRet; } const SwRedline* SwCrsrShell::SelNextRedline() { const SwRedline* pFnd = 0; if( !IsTableMode() ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); pFnd = GetDoc()->SelNextRedline( *m_pCurCrsr ); if( pFnd && !m_pCurCrsr->IsInProtectTable() && !m_pCurCrsr->IsSelOvr() ) UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); else pFnd = 0; } return pFnd; } const SwRedline* SwCrsrShell::SelPrevRedline() { const SwRedline* pFnd = 0; if( !IsTableMode() ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); pFnd = GetDoc()->SelPrevRedline( *m_pCurCrsr ); if( pFnd && !m_pCurCrsr->IsInProtectTable() && !m_pCurCrsr->IsSelOvr() ) UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); else pFnd = 0; } return pFnd; } const SwRedline* SwCrsrShell::_GotoRedline( sal_uInt16 nArrPos, sal_Bool bSelect ) { const SwRedline* pFnd = 0; SwCallLink aLk( *this ); // watch Crsr-Moves SwCrsrSaveState aSaveState( *m_pCurCrsr ); pFnd = GetDoc()->GetRedlineTbl()[ nArrPos ]; if( pFnd ) { *m_pCurCrsr->GetPoint() = *pFnd->Start(); SwCntntNode* pCNd; SwNodeIndex* pIdx = &m_pCurCrsr->GetPoint()->nNode; if( !pIdx->GetNode().IsCntntNode() && 0 != ( pCNd = GetDoc()->GetNodes().GoNextSection( pIdx, sal_True, IsReadOnlyAvailable() )) ) { if( *pIdx <= pFnd->End()->nNode ) m_pCurCrsr->GetPoint()->nContent.Assign( pCNd, 0 ); else pFnd = 0; } if( pFnd && bSelect ) { m_pCurCrsr->SetMark(); if( nsRedlineType_t::REDLINE_FMTCOLL == pFnd->GetType() ) { pCNd = pIdx->GetNode().GetCntntNode(); m_pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); m_pCurCrsr->GetMark()->nContent.Assign( pCNd, 0 ); } else *m_pCurCrsr->GetPoint() = *pFnd->End(); pIdx = &m_pCurCrsr->GetPoint()->nNode; if( !pIdx->GetNode().IsCntntNode() && 0 != ( pCNd = GetDoc()->GetNodes().GoPrevSection( pIdx, sal_True, IsReadOnlyAvailable() )) ) { if( *pIdx >= m_pCurCrsr->GetMark()->nNode ) m_pCurCrsr->GetPoint()->nContent.Assign( pCNd, pCNd->Len() ); else pFnd = 0; } } if( !pFnd ) { m_pCurCrsr->DeleteMark(); m_pCurCrsr->RestoreSavePos(); } else if( bSelect && *m_pCurCrsr->GetMark() == *m_pCurCrsr->GetPoint() ) m_pCurCrsr->DeleteMark(); if( pFnd && !m_pCurCrsr->IsInProtectTable() && !m_pCurCrsr->IsSelOvr() ) UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); else { pFnd = 0; if( bSelect ) m_pCurCrsr->DeleteMark(); } } return pFnd; } const SwRedline* SwCrsrShell::GotoRedline( sal_uInt16 nArrPos, sal_Bool bSelect ) { const SwRedline* pFnd = 0; if( !IsTableMode() ) { SET_CURR_SHELL( this ); const SwRedlineTbl& rTbl = GetDoc()->GetRedlineTbl(); const SwRedline* pTmp = rTbl[ nArrPos ]; sal_uInt16 nSeqNo = pTmp->GetSeqNo(); if( nSeqNo && bSelect ) { bool bCheck = false; int nLoopCnt = 2; sal_uInt16 nArrSavPos = nArrPos; do { pTmp = _GotoRedline( nArrPos, sal_True ); if( !pFnd ) pFnd = pTmp; if( pTmp && bCheck ) { // Check for overlaps. These can happen when FmtColl- // Redlines were streched over a whole paragraph SwPaM* pCur = m_pCurCrsr; SwPaM* pNextPam = (SwPaM*)pCur->GetNext(); SwPosition* pCStt = pCur->Start(), *pCEnd = pCur->End(); while( pCur != pNextPam ) { const SwPosition *pNStt = pNextPam->Start(), *pNEnd = pNextPam->End(); bool bDel = true; switch( ::ComparePosition( *pCStt, *pCEnd, *pNStt, *pNEnd )) { case POS_INSIDE: // Pos1 is completely in Pos2 if( !pCur->HasMark() ) { pCur->SetMark(); *pCur->GetMark() = *pNStt; } else *pCStt = *pNStt; *pCEnd = *pNEnd; break; case POS_OUTSIDE: // Pos2 is completely in Pos1 case POS_EQUAL: // Pos1 has same size as Pos2 break; case POS_OVERLAP_BEFORE: // Pos1 overlaps Pos2 at beginning if( !pCur->HasMark() ) pCur->SetMark(); *pCEnd = *pNEnd; break; case POS_OVERLAP_BEHIND: // Pos1 overlaps Pos2 at end if( !pCur->HasMark() ) { pCur->SetMark(); *pCur->GetMark() = *pNStt; } else *pCStt = *pNStt; break; default: bDel = false; } if( bDel ) { // not needed anymore SwPaM* pPrevPam = (SwPaM*)pNextPam->GetPrev(); delete pNextPam; pNextPam = pPrevPam; } pNextPam = (SwPaM*)pNextPam->GetNext(); } } sal_uInt16 nFndPos = 2 == nLoopCnt ? rTbl.FindNextOfSeqNo( nArrPos ) : rTbl.FindPrevOfSeqNo( nArrPos ); if( USHRT_MAX != nFndPos || ( 0 != ( --nLoopCnt ) && USHRT_MAX != ( nFndPos = rTbl.FindPrevOfSeqNo( nArrSavPos ))) ) { if( pTmp ) { // create new cursor CreateCrsr(); bCheck = true; } nArrPos = nFndPos; } else nLoopCnt = 0; } while( nLoopCnt ); } else pFnd = _GotoRedline( nArrPos, bSelect ); } return pFnd; } bool SwCrsrShell::SelectNxtPrvHyperlink( bool bNext ) { SwNodes& rNds = GetDoc()->GetNodes(); const SwNode* pBodyEndNd = &rNds.GetEndOfContent(); const SwNode* pBodySttNd = pBodyEndNd->StartOfSectionNode(); sal_uLong nBodySttNdIdx = pBodySttNd->GetIndex(); Point aPt; _SetGetExpFld aCmpPos( SwPosition( bNext ? *pBodyEndNd : *pBodySttNd ) ); _SetGetExpFld aCurPos( bNext ? *m_pCurCrsr->End() : *m_pCurCrsr->Start() ); if( aCurPos.GetNode() < nBodySttNdIdx ) { const SwCntntNode* pCNd = aCurPos.GetNodeFromCntnt()->GetCntntNode(); SwCntntFrm* pFrm; if( pCNd && 0 != ( pFrm = pCNd->getLayoutFrm( GetLayout(), &aPt )) ) aCurPos.SetBodyPos( *pFrm ); } // check first all the hyperlink fields { const SwTxtNode* pTxtNd; const SwCharFmts* pFmts = GetDoc()->GetCharFmts(); for( sal_uInt16 n = pFmts->size(); 1 < n; ) { SwIterator aIter(*(*pFmts)[--n]); for( SwTxtINetFmt* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() ) if( 0 != ( pTxtNd = pFnd->GetpTxtNode()) && pTxtNd->GetNodes().IsDocNodes() ) { SwTxtINetFmt& rAttr = *pFnd; SwPosition aTmpPos( *pTxtNd ); _SetGetExpFld aPos( aTmpPos.nNode, rAttr ); SwCntntFrm* pFrm; if( pTxtNd->GetIndex() < nBodySttNdIdx && 0 != ( pFrm = pTxtNd->getLayoutFrm( GetLayout(), &aPt )) ) aPos.SetBodyPos( *pFrm ); if( bNext ? ( aPos < aCmpPos && aCurPos < aPos ) : ( aCmpPos < aPos && aPos < aCurPos )) { OUString sTxt( pTxtNd->GetExpandTxt( *rAttr.GetStart(), *rAttr.GetEnd() - *rAttr.GetStart() ) ); sTxt = comphelper::string::remove(sTxt, 0x0a); sTxt = comphelper::string::strip(sTxt, ' '); if( !sTxt.isEmpty() ) aCmpPos = aPos; } } } } // then check all the Flys with a URL or imapge map { const SwFrmFmts* pFmts = GetDoc()->GetSpzFrmFmts(); for( sal_uInt16 n = 0, nEnd = pFmts->size(); n < nEnd; ++n ) { SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)(*pFmts)[ n ]; const SwFmtURL& rURLItem = pFmt->GetURL(); if( rURLItem.GetMap() || !rURLItem.GetURL().isEmpty() ) { SwFlyFrm* pFly = pFmt->GetFrm( &aPt, sal_False ); SwPosition aTmpPos( *pBodySttNd ); if( pFly && GetBodyTxtNode( *GetDoc(), aTmpPos, *pFly->GetLower() ) ) { _SetGetExpFld aPos( *pFmt, &aTmpPos ); if( bNext ? ( aPos < aCmpPos && aCurPos < aPos ) : ( aCmpPos < aPos && aPos < aCurPos )) aCmpPos = aPos; } } } } // found any URL ? bool bRet = false; const SwTxtINetFmt* pFndAttr = aCmpPos.GetINetFmt(); const SwFlyFrmFmt* pFndFmt = aCmpPos.GetFlyFmt(); if( pFndAttr || pFndFmt ) { SET_CURR_SHELL( this ); SwCallLink aLk( *this ); // found a text attribute ? if( pFndAttr ) { SwCrsrSaveState aSaveState( *m_pCurCrsr ); aCmpPos.GetPosOfContent( *m_pCurCrsr->GetPoint() ); m_pCurCrsr->DeleteMark(); m_pCurCrsr->SetMark(); m_pCurCrsr->GetPoint()->nContent = *pFndAttr->End(); if( !m_pCurCrsr->IsInProtectTable() && !m_pCurCrsr->IsSelOvr() ) { UpdateCrsr( SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE| SwCrsrShell::READONLY ); bRet = true; } } // found a draw object ? else if( RES_DRAWFRMFMT == pFndFmt->Which() ) { const SdrObject* pSObj = pFndFmt->FindSdrObject(); ((SwFEShell*)this)->SelectObj( pSObj->GetCurrentBoundRect().Center() ); MakeSelVisible(); bRet = true; } else // then is it a fly { SwFlyFrm* pFly = pFndFmt->GetFrm(&aPt, sal_False ); if( pFly ) { ((SwFEShell*)this)->SelectFlyFrm( *pFly, sal_True ); MakeSelVisible(); bRet = true; } } } return bRet; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */