| /************************************************************** |
| * |
| * 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 <hintids.hxx> |
| #include <editeng/protitem.hxx> |
| #include <com/sun/star/i18n/WordType.hdl> |
| #include <com/sun/star/i18n/CharType.hdl> |
| #include <unotools/charclass.hxx> |
| #include <svl/ctloptions.hxx> |
| #include <swmodule.hxx> |
| #include <fmtcntnt.hxx> |
| #include <swtblfmt.hxx> |
| #include <swcrsr.hxx> |
| #include <unocrsr.hxx> |
| #include <doc.hxx> |
| #include <IDocumentUndoRedo.hxx> |
| #include <docary.hxx> |
| #include <ndtxt.hxx> |
| #include <section.hxx> |
| #include <swtable.hxx> |
| #include <cntfrm.hxx> |
| #include <rootfrm.hxx> |
| #include <txtfrm.hxx> |
| #include <scriptinfo.hxx> |
| #include <crstate.hxx> |
| #include <docsh.hxx> |
| #include <viewsh.hxx> |
| #include <frmatr.hxx> |
| #include <breakit.hxx> |
| #include <crsskip.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <mdiexp.hxx> // ...Percent() |
| #include <statstr.hrc> // ResId fuer Statusleiste |
| #include <redline.hxx> // SwRedline |
| #include <txatbase.hxx> |
| |
| |
| using namespace ::com::sun::star::i18n; |
| |
| |
| static const sal_uInt16 coSrchRplcThreshold = 60000; |
| |
| struct _PercentHdl |
| { |
| SwDocShell* pDSh; |
| sal_uLong nActPos; |
| sal_Bool bBack, bNodeIdx; |
| |
| _PercentHdl( sal_uLong nStt, sal_uLong nEnd, SwDocShell* pSh ) |
| : pDSh( pSh ) |
| { |
| nActPos = nStt; |
| if( 0 != ( bBack = (nStt > nEnd )) ) |
| { |
| sal_uLong n = nStt; nStt = nEnd; nEnd = n; |
| } |
| ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, 0 ); |
| } |
| |
| _PercentHdl( const SwPaM& rPam ) |
| : pDSh( (SwDocShell*)rPam.GetDoc()->GetDocShell() ) |
| { |
| sal_uLong nStt, nEnd; |
| if( rPam.GetPoint()->nNode == rPam.GetMark()->nNode ) |
| { |
| bNodeIdx = sal_False; |
| nStt = rPam.GetMark()->nContent.GetIndex(); |
| nEnd = rPam.GetPoint()->nContent.GetIndex(); |
| } |
| else |
| { |
| bNodeIdx = sal_True; |
| nStt = rPam.GetMark()->nNode.GetIndex(); |
| nEnd = rPam.GetPoint()->nNode.GetIndex(); |
| } |
| nActPos = nStt; |
| if( 0 != ( bBack = (nStt > nEnd )) ) |
| { |
| sal_uLong n = nStt; nStt = nEnd; nEnd = n; |
| } |
| ::StartProgress( STR_STATSTR_SEARCH, nStt, nEnd, pDSh ); |
| } |
| |
| ~_PercentHdl() { ::EndProgress( pDSh ); } |
| |
| void NextPos( sal_uLong nPos ) const |
| { ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh ); } |
| |
| void NextPos( SwPosition& rPos ) const |
| { |
| sal_uLong nPos; |
| if( bNodeIdx ) |
| nPos = rPos.nNode.GetIndex(); |
| else |
| nPos = rPos.nContent.GetIndex(); |
| ::SetProgressState( bBack ? nActPos - nPos : nPos, pDSh ); |
| } |
| }; |
| |
| SwCursor::SwCursor( const SwPosition &rPos, SwPaM* pRing, bool bColumnSel ) |
| : SwPaM( rPos, pRing ), pSavePos( 0 ), mnRowSpanOffset( 0 ), nCursorBidiLevel( 0 ), |
| mbColumnSelection( bColumnSel ) |
| { |
| } |
| |
| // @@@ semantic: no copy ctor. |
| SwCursor::SwCursor( SwCursor& rCpy ) |
| : SwPaM( rCpy ), pSavePos( 0 ), mnRowSpanOffset( rCpy.mnRowSpanOffset ), |
| nCursorBidiLevel( rCpy.nCursorBidiLevel ), mbColumnSelection( rCpy.mbColumnSelection ) |
| { |
| } |
| |
| SwCursor::~SwCursor() |
| { |
| while( pSavePos ) |
| { |
| _SwCursor_SavePos* pNxt = pSavePos->pNext; |
| delete pSavePos; |
| pSavePos = pNxt; |
| } |
| } |
| |
| SwCursor* SwCursor::Create( SwPaM* pRing ) const |
| { |
| return new SwCursor( *GetPoint(), pRing, false ); |
| } |
| |
| bool SwCursor::IsReadOnlyAvailable() const |
| { |
| return false; |
| } |
| |
| sal_Bool SwCursor::IsSkipOverHiddenSections() const |
| { |
| return sal_True; |
| } |
| |
| sal_Bool SwCursor::IsSkipOverProtectSections() const |
| { |
| return !IsReadOnlyAvailable(); |
| } |
| |
| |
| // Sicher die aktuelle Position, damit ggfs. auf diese zurueck |
| // gefallen werden kann. Die SavePos Objekte werden als Stack verwaltet, |
| // damit das auch alles bei verschachtelten Aufrufen funktioniert. |
| // Das CreateNewSavePos ist virtual, damit abgeleitete Klassen vom Cursor |
| // gegebenenfalls eigene SaveObjecte anlegen und in den virtuellen |
| // Check-Routinen verwenden koennen. |
| |
| void SwCursor::SaveState() |
| { |
| _SwCursor_SavePos* pNew = CreateNewSavePos(); |
| pNew->pNext = pSavePos; |
| pSavePos = pNew; |
| } |
| |
| void SwCursor::RestoreState() |
| { |
| if( pSavePos ) // Robust |
| { |
| _SwCursor_SavePos* pDel = pSavePos; |
| pSavePos = pSavePos->pNext; |
| delete pDel; |
| } |
| } |
| |
| _SwCursor_SavePos* SwCursor::CreateNewSavePos() const |
| { |
| return new _SwCursor_SavePos( *this ); |
| } |
| |
| // stelle fest, ob sich der Point ausserhalb des Content-Bereichs |
| // vom Nodes-Array befindet |
| sal_Bool SwCursor::IsNoCntnt() const |
| { |
| return GetPoint()->nNode.GetIndex() < |
| GetDoc()->GetNodes().GetEndOfExtras().GetIndex(); |
| } |
| |
| bool SwCursor::IsSelOvrCheck(int) |
| { |
| return false; |
| } |
| |
| // extracted from IsSelOvr() |
| bool SwTableCursor::IsSelOvrCheck(int eFlags) |
| { |
| SwNodes& rNds = GetDoc()->GetNodes(); |
| // check sections of nodes array |
| if( (nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION & eFlags) |
| && HasMark() ) |
| { |
| SwNodeIndex aOldPos( rNds, GetSavePos()->nNode ); |
| if( !CheckNodesRange( aOldPos, GetPoint()->nNode, sal_True )) |
| { |
| GetPoint()->nNode = aOldPos; |
| GetPoint()->nContent.Assign( GetCntntNode(), GetSavePos()->nCntnt ); |
| return true; |
| } |
| } |
| return SwCursor::IsSelOvrCheck(eFlags); |
| } |
| |
| sal_Bool SwCursor::IsSelOvr( int eFlags ) |
| { |
| SwDoc* pDoc = GetDoc(); |
| SwNodes& rNds = pDoc->GetNodes(); |
| |
| sal_Bool bSkipOverHiddenSections = IsSkipOverHiddenSections(); |
| sal_Bool bSkipOverProtectSections = IsSkipOverProtectSections(); |
| |
| if ( IsSelOvrCheck( eFlags ) ) |
| { |
| return sal_True; |
| } |
| |
| if( pSavePos->nNode != GetPoint()->nNode.GetIndex() |
| && ( !pDoc->GetDocShell() |
| || !pDoc->GetDocShell()->IsReadOnlyUI() ) ) |
| { |
| // teste doch mal die neuen Sections: |
| SwNodeIndex& rPtIdx = GetPoint()->nNode; |
| const SwSectionNode* pSectNd = rPtIdx.GetNode().FindSectionNode(); |
| if( pSectNd && |
| ((bSkipOverHiddenSections && pSectNd->GetSection().IsHiddenFlag() ) || |
| (bSkipOverProtectSections && pSectNd->GetSection().IsProtectFlag() ))) |
| { |
| if( 0 == ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags ) ) |
| { |
| // dann wars das schon |
| RestoreSavePos(); |
| return sal_True; |
| } |
| |
| // dann setze den Cursor auf die neue Position: |
| SwNodeIndex aIdx( rPtIdx ); |
| xub_StrLen nCntntPos = pSavePos->nCntnt; |
| int bGoNxt = pSavePos->nNode < rPtIdx.GetIndex(); |
| SwCntntNode* pCNd = bGoNxt |
| ? rNds.GoNextSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections) |
| : rNds.GoPrevSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections); |
| if( !pCNd && ( nsSwCursorSelOverFlags::SELOVER_ENABLEREVDIREKTION & eFlags )) |
| { |
| bGoNxt = !bGoNxt; |
| pCNd = bGoNxt ? rNds.GoNextSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections) |
| : rNds.GoPrevSection( &rPtIdx, bSkipOverHiddenSections, bSkipOverProtectSections); |
| } |
| |
| int bIsValidPos = 0 != pCNd; |
| sal_Bool bValidNodesRange = bIsValidPos && |
| ::CheckNodesRange( rPtIdx, aIdx, sal_True ); |
| if( !bValidNodesRange ) |
| { |
| rPtIdx = pSavePos->nNode; |
| if( 0 == ( pCNd = rPtIdx.GetNode().GetCntntNode() ) ) |
| { |
| bIsValidPos = sal_False; |
| nCntntPos = 0; |
| rPtIdx = aIdx; |
| if( 0 == ( pCNd = rPtIdx.GetNode().GetCntntNode() ) ) |
| { |
| // dann auf den Anfang vom Doc |
| rPtIdx = rNds.GetEndOfExtras(); |
| pCNd = rNds.GoNext( &rPtIdx ); |
| } |
| } |
| } |
| |
| // ContentIndex noch anmelden: |
| xub_StrLen nTmpPos = bIsValidPos ? (bGoNxt ? 0 : pCNd->Len()) : nCntntPos; |
| GetPoint()->nContent.Assign( pCNd, nTmpPos ); |
| if( !bIsValidPos || !bValidNodesRange || |
| // sollten wir in einer Tabelle gelandet sein? |
| IsInProtectTable( sal_True ) ) |
| return sal_True; |
| } |
| |
| // oder sollte eine geschuetzte Section innerhalb der Selektion liegen? |
| if( HasMark() && bSkipOverProtectSections) |
| { |
| sal_uLong nSttIdx = GetMark()->nNode.GetIndex(), |
| nEndIdx = GetPoint()->nNode.GetIndex(); |
| if( nEndIdx <= nSttIdx ) |
| { |
| sal_uLong nTmp = nSttIdx; |
| nSttIdx = nEndIdx; |
| nEndIdx = nTmp; |
| } |
| |
| const SwSectionFmts& rFmts = pDoc->GetSections(); |
| for( sal_uInt16 n = 0; n < rFmts.Count(); ++n ) |
| { |
| const SwSectionFmt* pFmt = rFmts[n]; |
| const SvxProtectItem& rProtect = pFmt->GetProtect(); |
| if( rProtect.IsCntntProtected() ) |
| { |
| const SwFmtCntnt& rCntnt = pFmt->GetCntnt(sal_False); |
| ASSERT( rCntnt.GetCntntIdx(), "wo ist der SectionNode?" ); |
| sal_uLong nIdx = rCntnt.GetCntntIdx()->GetIndex(); |
| if( nSttIdx <= nIdx && nEndIdx >= nIdx ) |
| { |
| // ist es keine gelinkte Section, dann kann sie auch |
| // nicht mitselektiert werden |
| const SwSection& rSect = *pFmt->GetSection(); |
| if( CONTENT_SECTION == rSect.GetType() ) |
| { |
| RestoreSavePos(); |
| return sal_True; |
| } |
| } |
| } |
| } |
| } |
| |
| } |
| |
| const SwNode* pNd = &GetPoint()->nNode.GetNode(); |
| if( pNd->IsCntntNode() && !dynamic_cast<SwUnoCrsr*>(this) ) |
| { |
| const SwCntntFrm* pFrm = ((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() ); |
| if( pFrm && pFrm->IsValid() |
| && 0 == pFrm->Frm().Height() |
| && 0 != ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags ) ) |
| { |
| // skip to the next / prev valid paragraph with a layout |
| SwNodeIndex& rPtIdx = GetPoint()->nNode; |
| int bGoNxt = pSavePos->nNode < rPtIdx.GetIndex(); |
| while( 0 != ( pFrm = ( bGoNxt ? pFrm->GetNextCntntFrm() : pFrm->GetPrevCntntFrm() )) |
| && 0 == pFrm->Frm().Height() ) |
| ; |
| |
| // --> LIJIAN/FME 2007-11-27 #i72394# skip to prev /next valid paragraph |
| // with a layout in case the first search did not succeed: |
| if( !pFrm ) |
| { |
| bGoNxt = !bGoNxt; |
| pFrm = ((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() ); |
| while ( pFrm && 0 == pFrm->Frm().Height() ) |
| { |
| pFrm = bGoNxt ? pFrm->GetNextCntntFrm() |
| : pFrm->GetPrevCntntFrm(); |
| } |
| } |
| // <-- |
| |
| SwCntntNode* pCNd; |
| if( pFrm && 0 != (pCNd = (SwCntntNode*)pFrm->GetNode()) ) |
| { |
| // set this cntntNode as new position |
| rPtIdx = *pCNd; |
| pNd = pCNd; |
| |
| // ContentIndex noch anmelden: |
| xub_StrLen nTmpPos = bGoNxt ? 0 : pCNd->Len(); |
| GetPoint()->nContent.Assign( pCNd, nTmpPos ); |
| |
| // sollten wir in einer Tabelle gelandet sein? |
| if( IsInProtectTable( sal_True ) ) |
| pFrm = 0; |
| } |
| } |
| |
| if( !pFrm ) |
| { |
| DeleteMark(); |
| RestoreSavePos(); |
| return sal_True; // ohne Frames geht gar nichts! |
| } |
| } |
| |
| // darf der Cursor in geschuetzen "Nodes" stehen? |
| if( 0 == ( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags ) && !IsAtValidPos() ) |
| { |
| DeleteMark(); |
| RestoreSavePos(); |
| return sal_True; |
| } |
| |
| if( !HasMark() ) |
| return sal_False; |
| |
| //JP 19.08.98: teste mal auf ungueltige Selektion - sprich ueber |
| // GrundSections: |
| if( !::CheckNodesRange( GetMark()->nNode, GetPoint()->nNode, sal_True )) |
| { |
| DeleteMark(); |
| RestoreSavePos(); |
| return sal_True; // ohne Frames geht gar nichts! |
| } |
| |
| if( (pNd = &GetMark()->nNode.GetNode())->IsCntntNode() |
| && !((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() ) |
| && !dynamic_cast<SwUnoCrsr*>(this) ) |
| { |
| DeleteMark(); |
| RestoreSavePos(); |
| return sal_True; // ohne Frames geht gar nichts! |
| } |
| |
| // assure that selection is only inside an InputField or contains the InputField completely |
| { |
| const SwTxtAttr* pInputFldTxtAttrAtPoint = NULL; |
| SwTxtNode* pTxtNdAtPoint = GetPoint()->nNode.GetNode().GetTxtNode(); |
| if ( pTxtNdAtPoint != NULL ) |
| { |
| pInputFldTxtAttrAtPoint = |
| pTxtNdAtPoint->GetTxtAttrAt( GetPoint()->nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTxtNode::PARENT ); |
| } |
| |
| const SwTxtAttr* pInputFldTxtAttrAtMark = NULL; |
| SwTxtNode* pTxtNdAtMark = GetMark()->nNode.GetNode().GetTxtNode(); |
| if ( pTxtNdAtMark != NULL ) |
| { |
| pInputFldTxtAttrAtMark = |
| pTxtNdAtMark->GetTxtAttrAt( GetMark()->nContent.GetIndex(), RES_TXTATR_INPUTFIELD, SwTxtNode::PARENT ); |
| } |
| |
| if ( pInputFldTxtAttrAtPoint != pInputFldTxtAttrAtMark ) |
| { |
| const sal_uLong nRefNodeIdx = |
| ( nsSwCursorSelOverFlags::SELOVER_TOGGLE & eFlags ) |
| ? pSavePos->nNode |
| : GetMark()->nNode.GetIndex(); |
| const xub_StrLen nRefContentIdx = |
| ( nsSwCursorSelOverFlags::SELOVER_TOGGLE & eFlags ) |
| ? pSavePos->nCntnt |
| : GetMark()->nContent.GetIndex(); |
| const bool bIsForwardSelection = |
| nRefNodeIdx < GetPoint()->nNode.GetIndex() |
| || ( nRefNodeIdx == GetPoint()->nNode.GetIndex() |
| && nRefContentIdx < GetPoint()->nContent.GetIndex() ); |
| |
| if ( pInputFldTxtAttrAtPoint != NULL ) |
| { |
| const xub_StrLen nNewPointPos = |
| bIsForwardSelection ? *(pInputFldTxtAttrAtPoint->End()) : *(pInputFldTxtAttrAtPoint->GetStart()); |
| GetPoint()->nContent.Assign( pTxtNdAtPoint, nNewPointPos ); |
| } |
| |
| if ( pInputFldTxtAttrAtMark != NULL ) |
| { |
| const xub_StrLen nNewMarkPos = |
| bIsForwardSelection ? *(pInputFldTxtAttrAtMark->GetStart()) : *(pInputFldTxtAttrAtMark->End()); |
| GetMark()->nContent.Assign( pTxtNdAtMark, nNewMarkPos ); |
| } |
| } |
| } |
| |
| const SwTableNode* pPtNd = GetPoint()->nNode.GetNode().FindTableNode(); |
| const SwTableNode* pMrkNd = GetMark()->nNode.GetNode().FindTableNode(); |
| // beide in keinem oder beide im gleichen TableNode |
| if( ( !pMrkNd && !pPtNd ) || pPtNd == pMrkNd ) |
| return sal_False; |
| |
| // in unterschiedlichen Tabellen oder nur Mark in der Tabelle |
| if( ( pPtNd && pMrkNd ) || pMrkNd ) |
| { |
| // dann lasse das nicht zu, alte Pos zurueck |
| RestoreSavePos(); |
| // Crsr bleibt an der alten Position |
| return sal_True; |
| } |
| |
| // ACHTUNG: dieses kann nicht im TableMode geschehen !! |
| if( pPtNd ) // nur Point in Tabelle, dann gehe hinter/vor diese |
| { |
| if( nsSwCursorSelOverFlags::SELOVER_CHANGEPOS & eFlags ) |
| { |
| sal_Bool bSelTop = GetPoint()->nNode.GetIndex() < |
| (( nsSwCursorSelOverFlags::SELOVER_TOGGLE & eFlags ) ? pSavePos->nNode |
| : GetMark()->nNode.GetIndex()); |
| |
| do { |
| // in Schleife fuer Tabelle hinter Tabelle |
| sal_uLong nSEIdx = pPtNd->EndOfSectionIndex(); |
| sal_uLong nSttEndTbl = nSEIdx + 1; // dflt. Sel. nach unten |
| |
| if( bSelTop ) // Sel. nach oben |
| nSttEndTbl = rNds[ nSEIdx ]->StartOfSectionIndex() - 1; |
| |
| GetPoint()->nNode = nSttEndTbl; |
| const SwNode* pMyNd = GetNode(); |
| |
| if( pMyNd->IsSectionNode() || ( pMyNd->IsEndNode() && |
| pMyNd->StartOfSectionNode()->IsSectionNode() ) ) |
| { |
| // die lassen wir zu: |
| pMyNd = bSelTop |
| ? rNds.GoPrevSection( &GetPoint()->nNode,sal_True,sal_False ) |
| : rNds.GoNextSection( &GetPoint()->nNode,sal_True,sal_False ); |
| |
| /* #i12312# Handle failure of Go{Prev|Next}Section */ |
| if ( 0 == pMyNd) |
| break; |
| |
| if( 0 != ( pPtNd = pMyNd->FindTableNode() )) |
| continue; |
| } |
| |
| if( pMyNd->IsCntntNode() && // ist es ein ContentNode ?? |
| ::CheckNodesRange( GetMark()->nNode, |
| GetPoint()->nNode, sal_True )) |
| { |
| // TABLE IN TABLE |
| const SwTableNode* pOuterTableNd = pMyNd->FindTableNode(); |
| if ( pOuterTableNd ) |
| pMyNd = pOuterTableNd; |
| else |
| { |
| SwCntntNode* pCNd = (SwCntntNode*)pMyNd; |
| xub_StrLen nTmpPos = bSelTop ? pCNd->Len() : 0; |
| GetPoint()->nContent.Assign( pCNd, nTmpPos ); |
| return sal_False; |
| } |
| } |
| if( bSelTop |
| ? ( !pMyNd->IsEndNode() || 0 == ( pPtNd = pMyNd->FindTableNode() )) |
| : 0 == ( pPtNd = pMyNd->GetTableNode() )) |
| break; |
| } while( sal_True ); |
| } |
| |
| // dann verbleibe auf der alten Position |
| RestoreSavePos(); |
| return sal_True; // Crsr bleibt an der alten Position |
| } |
| |
| return sal_False; |
| } |
| |
| #if defined( UNX ) |
| #define IDX (*pCellStt) |
| #else |
| #define IDX aCellStt |
| #endif |
| |
| |
| sal_Bool SwCursor::IsInProtectTable( sal_Bool bMove, sal_Bool bChgCrsr ) |
| { |
| SwCntntNode* pCNd = GetCntntNode(); |
| if( !pCNd ) |
| return sal_False; |
| |
| // No table, no protected cell: |
| const SwTableNode* pTableNode = pCNd->FindTableNode(); |
| if ( !pTableNode ) |
| return sal_False; |
| |
| // Current position == last save position? |
| if ( pSavePos->nNode == GetPoint()->nNode.GetIndex() ) |
| return sal_False; |
| |
| // Check for convered cell: |
| bool bInCoveredCell = false; |
| const SwStartNode* pTmpSttNode = pCNd->FindTableBoxStartNode(); |
| ASSERT( pTmpSttNode, "In table, therefore I expect to get a SwTableBoxStartNode" ) |
| const SwTableBox* pBox = pTmpSttNode ? pTableNode->GetTable().GetTblBox( pTmpSttNode->GetIndex() ) : 0; //Robust #151355 |
| if ( pBox && pBox->getRowSpan() < 1 ) // Robust #151270 |
| bInCoveredCell = true; |
| |
| // Positions of covered cells are not acceptable: |
| if ( !bInCoveredCell ) |
| { |
| // Position not protected? |
| if ( !pCNd->IsProtect() ) |
| return sal_False; |
| |
| // Cursor in protected cells allowed? |
| if ( IsReadOnlyAvailable() ) |
| return sal_False; |
| } |
| |
| // If we reach this point, we are in a protected or covered table cell! |
| |
| if( !bMove ) |
| { |
| if( bChgCrsr ) |
| // restore the last save position |
| RestoreSavePos(); |
| return sal_True; // Crsr bleibt an der alten Position |
| } |
| |
| // wir stehen in einer geschuetzten TabellenZelle |
| // von Oben nach Unten Traveln ? |
| if( pSavePos->nNode < GetPoint()->nNode.GetIndex() ) |
| { |
| // suche die naechste "gueltige" Box |
| |
| // folgt nach dem EndNode der Zelle ein weiterer StartNode, dann |
| // gibt es auch eine naechste Zelle |
| #if defined( UNX ) |
| SwNodeIndex* pCellStt = new SwNodeIndex( *GetNode()-> |
| FindTableBoxStartNode()->EndOfSectionNode(), 1 ); |
| #else |
| SwNodeIndex aCellStt( *GetNode()->FindTableBoxStartNode()->EndOfSectionNode(), 1 ); |
| #endif |
| sal_Bool bProt = sal_True; |
| GoNextCell: |
| do { |
| if( !IDX.GetNode().IsStartNode() ) |
| break; |
| IDX++; |
| if( 0 == ( pCNd = IDX.GetNode().GetCntntNode() )) |
| pCNd = IDX.GetNodes().GoNext( &IDX ); |
| if( 0 == ( bProt = pCNd->IsProtect() )) |
| break; |
| IDX.Assign( *pCNd->FindTableBoxStartNode()->EndOfSectionNode(), 1 ); |
| } while( bProt ); |
| |
| SetNextCrsr: |
| if( !bProt ) // eine freie Zelle gefunden |
| { |
| GetPoint()->nNode = IDX; |
| #if defined( UNX ) |
| delete pCellStt; |
| #endif |
| SwCntntNode* pTmpCNd = GetCntntNode(); |
| if( pTmpCNd ) |
| { |
| GetPoint()->nContent.Assign( pTmpCNd, 0 ); |
| return sal_False; |
| } |
| return IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | |
| nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); |
| } |
| // am Ende der Tabelle, also setze hinter diese |
| IDX++; // auf den naechsten Node |
| SwNode* pNd; |
| if( ( pNd = &IDX.GetNode())->IsEndNode() || HasMark()) |
| { |
| // Tabelle allein in einem FlyFrame oder SSelection, |
| // dann verbleibe auf der alten Position |
| if( bChgCrsr ) |
| RestoreSavePos(); |
| #if defined( UNX ) |
| delete pCellStt; |
| #endif |
| return sal_True; // Crsr bleibt an der alten Position |
| } |
| else if( pNd->IsTableNode() && IDX++ ) |
| goto GoNextCell; |
| |
| bProt = sal_False; // Index steht jetzt auf einem ContentNode |
| goto SetNextCrsr; |
| } |
| |
| // suche die vorherige "gueltige" Box |
| { |
| // liegt vor dem StartNode der Zelle ein weiterer EndNode, dann |
| // gibt es auch eine vorherige Zelle |
| #if defined( UNX ) |
| SwNodeIndex* pCellStt = new SwNodeIndex( |
| *GetNode()->FindTableBoxStartNode(), -1 ); |
| #else |
| SwNodeIndex aCellStt( *GetNode()->FindTableBoxStartNode(), -1 ); |
| #endif |
| SwNode* pNd; |
| sal_Bool bProt = sal_True; |
| GoPrevCell: |
| do { |
| if( !( pNd = &IDX.GetNode())->IsEndNode() ) |
| break; |
| IDX.Assign( *pNd->StartOfSectionNode(), +1 ); |
| if( 0 == ( pCNd = IDX.GetNode().GetCntntNode() )) |
| pCNd = pNd->GetNodes().GoNext( &IDX ); |
| if( 0 == ( bProt = pCNd->IsProtect() )) |
| break; |
| IDX.Assign( *pNd->FindTableBoxStartNode(), -1 ); |
| } while( bProt ); |
| |
| SetPrevCrsr: |
| if( !bProt ) // eine freie Zelle gefunden |
| { |
| GetPoint()->nNode = IDX; |
| #if defined( UNX ) |
| delete pCellStt; |
| #endif |
| SwCntntNode* pTmpCNd = GetCntntNode(); |
| if( pTmpCNd ) |
| { |
| GetPoint()->nContent.Assign( pTmpCNd, 0 ); |
| return sal_False; |
| } |
| return IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | |
| nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); |
| } |
| // am Start der Tabelle, also setze vor diese |
| IDX--; // auf den naechsten Node |
| if( ( pNd = &IDX.GetNode())->IsStartNode() || HasMark() ) |
| { |
| // Tabelle allein in einem FlyFrame oder Selektion, |
| // dann verbleibe auf der alten Position |
| if( bChgCrsr ) |
| RestoreSavePos(); |
| #if defined( UNX ) |
| delete pCellStt; |
| #endif |
| return sal_True; // Crsr bleibt an der alten Position |
| } |
| else if( pNd->StartOfSectionNode()->IsTableNode() && IDX-- ) |
| goto GoPrevCell; |
| |
| bProt = sal_False; // Index steht jetzt auf einem ContentNode |
| goto SetPrevCrsr; |
| } |
| } |
| |
| // sal_True: an die Position kann der Cursor gesetzt werden |
| sal_Bool SwCursor::IsAtValidPos( sal_Bool bPoint ) const |
| { |
| const SwDoc* pDoc = GetDoc(); |
| const SwPosition* pPos = bPoint ? GetPoint() : GetMark(); |
| const SwNode* pNd = &pPos->nNode.GetNode(); |
| |
| if( pNd->IsCntntNode() && !((SwCntntNode*)pNd)->getLayoutFrm( pDoc->GetCurrentLayout() ) && |
| !dynamic_cast<const SwUnoCrsr*>(this) ) |
| { |
| return sal_False; |
| } |
| |
| //JP 28.10.97: Bug 45129 - im UI-ReadOnly ist alles erlaubt |
| if( !pDoc->GetDocShell() || !pDoc->GetDocShell()->IsReadOnlyUI() ) |
| return sal_True; |
| |
| sal_Bool bCrsrInReadOnly = IsReadOnlyAvailable(); |
| if( !bCrsrInReadOnly && pNd->IsProtect() ) |
| return sal_False; |
| |
| const SwSectionNode* pSectNd = pNd->FindSectionNode(); |
| if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() || |
| ( !bCrsrInReadOnly && pSectNd->GetSection().IsProtectFlag() ))) |
| return sal_False; |
| |
| return sal_True; |
| } |
| |
| void SwCursor::SaveTblBoxCntnt( const SwPosition* ) {} |
| |
| // setze den SRange fuer das Suchen im Dokument |
| SwMoveFnCollection* SwCursor::MakeFindRange( SwDocPositions nStart, |
| SwDocPositions nEnd, SwPaM* pRange ) const |
| { |
| pRange->SetMark(); |
| FillFindPos( nStart, *pRange->GetMark() ); |
| FillFindPos( nEnd, *pRange->GetPoint() ); |
| |
| // bestimme die Richtung, in der zu suchen ist |
| // ( GetPoint > GetMark -> vorwaerts, sonst rueckwaerts ) |
| return ( DOCPOS_START == nStart || DOCPOS_OTHERSTART == nStart || |
| (DOCPOS_CURR == nStart && |
| (DOCPOS_END == nEnd || DOCPOS_OTHEREND == nEnd ) )) |
| ? fnMoveForward : fnMoveBackward; |
| } |
| |
| |
| sal_uLong lcl_FindSelection( SwFindParas& rParas, SwCursor* pCurCrsr, |
| SwMoveFn fnMove, SwCursor*& pFndRing, |
| SwPaM& aRegion, FindRanges eFndRngs, |
| sal_Bool bInReadOnly, sal_Bool& bCancel ) |
| { |
| SwDoc* pDoc = pCurCrsr->GetDoc(); |
| bool const bDoesUndo = pDoc->GetIDocumentUndoRedo().DoesUndo(); |
| int nFndRet = 0; |
| sal_uLong nFound = 0; |
| int bSrchBkwrd = fnMove == fnMoveBackward, bEnde = sal_False; |
| SwPaM *pTmpCrsr = pCurCrsr, *pSaveCrsr = pCurCrsr; |
| |
| // only create progress-bar for ShellCrsr |
| bool bIsUnoCrsr = 0 != dynamic_cast<SwUnoCrsr*>(pCurCrsr); |
| _PercentHdl* pPHdl = 0; |
| sal_uInt16 nCrsrCnt = 0; |
| if( FND_IN_SEL & eFndRngs ) |
| { |
| while( pCurCrsr != ( pTmpCrsr = (SwPaM*)pTmpCrsr->GetNext() )) |
| ++nCrsrCnt; |
| if( nCrsrCnt && !bIsUnoCrsr ) |
| pPHdl = new _PercentHdl( 0, nCrsrCnt, pDoc->GetDocShell() ); |
| } |
| else |
| pSaveCrsr = (SwPaM*)pSaveCrsr->GetPrev(); |
| |
| do { |
| aRegion.SetMark(); |
| // egal in welche Richtung, SPoint ist immer groesser als Mark, |
| // wenn der Suchbereich gueltig ist !! |
| SwPosition *pSttPos = aRegion.GetMark(), |
| *pEndPos = aRegion.GetPoint(); |
| *pSttPos = *pTmpCrsr->Start(); |
| *pEndPos = *pTmpCrsr->End(); |
| if( bSrchBkwrd ) |
| aRegion.Exchange(); |
| |
| if( !nCrsrCnt && !pPHdl && !bIsUnoCrsr ) |
| pPHdl = new _PercentHdl( aRegion ); |
| |
| // solange gefunden und nicht auf gleicher Position haengen bleibt |
| while( *pSttPos <= *pEndPos && |
| 0 != ( nFndRet = rParas.Find( pCurCrsr, fnMove, |
| &aRegion, bInReadOnly )) && |
| ( !pFndRing || |
| *pFndRing->GetPoint() != *pCurCrsr->GetPoint() || |
| *pFndRing->GetMark() != *pCurCrsr->GetMark() )) |
| { |
| if( !( FIND_NO_RING & nFndRet )) |
| { |
| // Bug 24084: Ring richtig herum aufbauen -> gleiche Mimik |
| // wie beim CreateCrsr !!!! |
| |
| SwCursor* pNew = pCurCrsr->Create( pFndRing ); |
| if( !pFndRing ) |
| pFndRing = pNew; |
| |
| pNew->SetMark(); |
| *pNew->GetMark() = *pCurCrsr->GetMark(); |
| } |
| |
| ++nFound; |
| |
| if( !( eFndRngs & FND_IN_SELALL) ) |
| { |
| bEnde = sal_True; |
| break; |
| } |
| |
| if ((coSrchRplcThreshold == nFound) |
| && pDoc->GetIDocumentUndoRedo().DoesUndo() |
| && rParas.IsReplaceMode()) |
| { |
| short nRet = pCurCrsr->MaxReplaceArived(); |
| if( RET_YES == nRet ) |
| { |
| pDoc->GetIDocumentUndoRedo().DelAllUndoObj(); |
| pDoc->GetIDocumentUndoRedo().DoUndo(false); |
| } |
| else |
| { |
| bEnde = sal_True; |
| if(RET_CANCEL == nRet) |
| { |
| bCancel = sal_True; |
| //unwind() ?? |
| } |
| break; |
| } |
| } |
| |
| if( bSrchBkwrd ) |
| // bewege pEndPos vor den gefundenen Bereich |
| *pEndPos = *pCurCrsr->Start(); |
| else |
| // bewege pSttPos hinter den gefundenen Bereich |
| *pSttPos = *pCurCrsr->End(); |
| |
| if( *pSttPos == *pEndPos ) // im Bereich, aber am Ende |
| break; // fertig |
| |
| if( !nCrsrCnt && pPHdl ) |
| { |
| pPHdl->NextPos( *aRegion.GetMark() ); |
| } |
| } |
| |
| if( bEnde || !( eFndRngs & ( FND_IN_SELALL | FND_IN_SEL )) ) |
| break; |
| |
| pTmpCrsr = ((SwPaM*)pTmpCrsr->GetNext()); |
| if( nCrsrCnt && pPHdl ) |
| { |
| pPHdl->NextPos( ++pPHdl->nActPos ); |
| } |
| |
| } while( pTmpCrsr != pSaveCrsr ); |
| |
| if( nFound && !pFndRing ) // falls kein Ring aufgebaut werden soll |
| pFndRing = pCurCrsr->Create(); |
| |
| delete pPHdl; |
| pDoc->GetIDocumentUndoRedo().DoUndo(bDoesUndo); |
| return nFound; |
| } |
| |
| |
| int lcl_MakeSelFwrd( const SwNode& rSttNd, const SwNode& rEndNd, |
| SwPaM& rPam, int bFirst ) |
| { |
| if( rSttNd.GetIndex() + 1 == rEndNd.GetIndex() ) |
| return sal_False; |
| |
| SwNodes& rNds = rPam.GetDoc()->GetNodes(); |
| rPam.DeleteMark(); |
| SwCntntNode* pCNd; |
| if( !bFirst ) |
| { |
| rPam.GetPoint()->nNode = rSttNd; |
| pCNd = rNds.GoNext( &rPam.GetPoint()->nNode ); |
| if( !pCNd ) |
| return sal_False; |
| pCNd->MakeStartIndex( &rPam.GetPoint()->nContent ); |
| } |
| else if( rSttNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() || |
| rPam.GetPoint()->nNode.GetIndex() >= rEndNd.GetIndex() ) |
| return sal_False; // steht nicht in dieser Section |
| |
| rPam.SetMark(); |
| rPam.GetPoint()->nNode = rEndNd; |
| pCNd = rNds.GoPrevious( &rPam.GetPoint()->nNode ); |
| if( !pCNd ) |
| return sal_False; |
| pCNd->MakeEndIndex( &rPam.GetPoint()->nContent ); |
| |
| return *rPam.GetMark() < *rPam.GetPoint(); |
| } |
| |
| |
| int lcl_MakeSelBkwrd( const SwNode& rSttNd, const SwNode& rEndNd, |
| SwPaM& rPam, int bFirst ) |
| { |
| if( rEndNd.GetIndex() + 1 == rSttNd.GetIndex() ) |
| return sal_False; |
| |
| SwNodes& rNds = rPam.GetDoc()->GetNodes(); |
| rPam.DeleteMark(); |
| SwCntntNode* pCNd; |
| if( !bFirst ) |
| { |
| rPam.GetPoint()->nNode = rSttNd; |
| pCNd = rNds.GoPrevious( &rPam.GetPoint()->nNode ); |
| if( !pCNd ) |
| return sal_False; |
| pCNd->MakeEndIndex( &rPam.GetPoint()->nContent ); |
| } |
| else if( rEndNd.GetIndex() > rPam.GetPoint()->nNode.GetIndex() || |
| rPam.GetPoint()->nNode.GetIndex() >= rSttNd.GetIndex() ) |
| return sal_False; // steht nicht in dieser Section |
| |
| rPam.SetMark(); |
| rPam.GetPoint()->nNode = rEndNd; |
| pCNd = rNds.GoNext( &rPam.GetPoint()->nNode ); |
| if( !pCNd ) |
| return sal_False; |
| pCNd->MakeStartIndex( &rPam.GetPoint()->nContent ); |
| |
| return *rPam.GetPoint() < *rPam.GetMark(); |
| } |
| |
| |
| // diese Methode "sucht" fuer alle Anwendungsfaelle, denn in SwFindParas |
| // steht immer die richtigen Parameter und die entsprechende Find-Methode |
| |
| sal_uLong SwCursor::FindAll( SwFindParas& rParas, |
| SwDocPositions nStart, SwDocPositions nEnde, |
| FindRanges eFndRngs, sal_Bool& bCancel ) |
| { |
| bCancel = sal_False; |
| SwCrsrSaveState aSaveState( *this ); |
| |
| // Region erzeugen, ohne das diese in den Ring aufgenommen wird ! |
| SwPaM aRegion( *GetPoint() ); |
| SwMoveFn fnMove = MakeFindRange( nStart, nEnde, &aRegion ); |
| |
| sal_uLong nFound = 0; |
| int bMvBkwrd = fnMove == fnMoveBackward; |
| sal_Bool bInReadOnly = IsReadOnlyAvailable(); |
| |
| SwCursor* pFndRing = 0; |
| SwNodes& rNds = GetDoc()->GetNodes(); |
| |
| // suche in Bereichen ? |
| if( FND_IN_SEL & eFndRngs ) |
| { |
| // String nicht im Bereich gefunden, dann erhalte alle Bereiche, |
| // der Cursor beleibt unveraendert |
| if( 0 == ( nFound = lcl_FindSelection( rParas, this, fnMove, |
| pFndRing, aRegion, eFndRngs, |
| bInReadOnly, bCancel ) )) |
| return nFound; |
| |
| // der String wurde ein- bis mehrmals gefunden. Das steht alles |
| // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf |
| while( GetNext() != this ) |
| delete GetNext(); |
| |
| *GetPoint() = *pFndRing->GetPoint(); |
| SetMark(); |
| *GetMark() = *pFndRing->GetMark(); |
| pFndRing->MoveRingTo( this ); |
| delete pFndRing; |
| } |
| else if( FND_IN_OTHER & eFndRngs ) |
| { |
| // Cursor als Kopie vom akt. und in den Ring aufnehmen |
| // Verkettung zeigt immer auf den zuerst erzeugten, also vorwaerts |
| std::auto_ptr< SwCursor > pSav( Create( this ) ); // save the current cursor |
| |
| // wenn schon ausserhalb vom Bodytext, suche von der Position, |
| // ansonsten beginne mit der 1. GrundSection |
| if( bMvBkwrd |
| ? lcl_MakeSelBkwrd( rNds.GetEndOfExtras(), |
| *rNds.GetEndOfPostIts().StartOfSectionNode(), |
| *this, rNds.GetEndOfExtras().GetIndex() >= |
| GetPoint()->nNode.GetIndex() ) |
| : lcl_MakeSelFwrd( *rNds.GetEndOfPostIts().StartOfSectionNode(), |
| rNds.GetEndOfExtras(), *this, |
| rNds.GetEndOfExtras().GetIndex() >= |
| GetPoint()->nNode.GetIndex() )) |
| { |
| nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing, |
| aRegion, eFndRngs, bInReadOnly, bCancel ); |
| } |
| |
| if( !nFound ) |
| { |
| // den alten wieder zurueck |
| *GetPoint() = *pSav->GetPoint(); |
| if( pSav->HasMark() ) |
| { |
| SetMark(); |
| *GetMark() = *pSav->GetMark(); |
| } |
| else |
| DeleteMark(); |
| return 0; |
| } |
| pSav.release(); |
| |
| if( !( FND_IN_SELALL & eFndRngs )) |
| { |
| // es sollte nur einer gesucht werden, also fuege in dazu |
| // egal in welche Richtung, SPoint ist immer groesser als Mark, |
| // wenn der Suchbereich gueltig ist !! |
| *GetPoint() = *pFndRing->GetPoint(); |
| SetMark(); |
| *GetMark() = *pFndRing->GetMark(); |
| } |
| else |
| { |
| // es wurde ein- bis mehrmals gefunden. Das steht alles |
| // im neuen Crsr-Ring. Darum hebe erstmal den alten Ring auf |
| while( GetNext() != this ) |
| delete GetNext(); |
| |
| *GetPoint() = *pFndRing->GetPoint(); |
| SetMark(); |
| *GetMark() = *pFndRing->GetMark(); |
| pFndRing->MoveRingTo( this ); |
| } |
| delete pFndRing; |
| } |
| else if( FND_IN_SELALL & eFndRngs ) |
| { |
| ::std::auto_ptr< SwCursor> pSav( Create( this ) ); // save the current cursor |
| |
| const SwNode* pSttNd = ( FND_IN_BODYONLY & eFndRngs ) |
| ? rNds.GetEndOfContent().StartOfSectionNode() |
| : rNds.GetEndOfPostIts().StartOfSectionNode(); |
| |
| if( bMvBkwrd |
| ? lcl_MakeSelBkwrd( rNds.GetEndOfContent(), *pSttNd,*this, sal_False ) |
| : lcl_MakeSelFwrd( *pSttNd, rNds.GetEndOfContent(), *this, sal_False )) |
| { |
| nFound = lcl_FindSelection( rParas, this, fnMove, pFndRing, |
| aRegion, eFndRngs, bInReadOnly, bCancel ); |
| } |
| |
| if( !nFound ) |
| { |
| // den alten wieder zurueck |
| *GetPoint() = *pSav->GetPoint(); |
| if( pSav->HasMark() ) |
| { |
| SetMark(); |
| *GetMark() = *pSav->GetMark(); |
| } |
| else |
| DeleteMark(); |
| return 0; |
| } |
| pSav.release(); |
| while( GetNext() != this ) |
| delete GetNext(); |
| |
| *GetPoint() = *pFndRing->GetPoint(); |
| SetMark(); |
| *GetMark() = *pFndRing->GetMark(); |
| pFndRing->MoveRingTo( this ); |
| delete pFndRing; |
| } |
| else |
| { |
| // ist ein GetMark gesetzt, dann wird bei gefundenem Object |
| // der GetMark beibehalten !! Dadurch kann ein Bereich mit der Suche |
| // aufgespannt werden. |
| SwPosition aMarkPos( *GetMark() ); |
| int bMarkPos = HasMark() && !eFndRngs; |
| |
| if( 0 != (nFound = rParas.Find( this, fnMove, |
| &aRegion, bInReadOnly ) ? 1 : 0) |
| && bMarkPos ) |
| *GetMark() = aMarkPos; |
| } |
| |
| if( nFound && SwCursor::IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE ) ) |
| nFound = 0; |
| return nFound; |
| } |
| |
| |
| void SwCursor::FillFindPos( SwDocPositions ePos, SwPosition& rPos ) const |
| { |
| sal_Bool bIsStart = sal_True; |
| SwCntntNode* pCNd = 0; |
| SwNodes& rNds = GetDoc()->GetNodes(); |
| |
| switch( ePos ) |
| { |
| case DOCPOS_START: |
| rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode(); |
| pCNd = rNds.GoNext( &rPos.nNode ); |
| break; |
| |
| case DOCPOS_END: |
| rPos.nNode = rNds.GetEndOfContent(); |
| pCNd = rNds.GoPrevious( &rPos.nNode ); |
| bIsStart = sal_False; |
| break; |
| |
| case DOCPOS_OTHERSTART: |
| rPos.nNode = *rNds[ sal_uLong(0) ]; |
| pCNd = rNds.GoNext( &rPos.nNode ); |
| break; |
| |
| case DOCPOS_OTHEREND: |
| rPos.nNode = *rNds.GetEndOfContent().StartOfSectionNode(); |
| pCNd = rNds.GoPrevious( &rPos.nNode ); |
| bIsStart = sal_False; |
| break; |
| |
| // case DOCPOS_CURR: |
| default: |
| rPos = *GetPoint(); |
| } |
| |
| if( pCNd ) |
| { |
| xub_StrLen nCPos = 0; |
| if( !bIsStart ) |
| nCPos = pCNd->Len(); |
| rPos.nContent.Assign( pCNd, nCPos ); |
| } |
| } |
| |
| short SwCursor::MaxReplaceArived() |
| { |
| return RET_YES; |
| } |
| |
| |
| sal_Bool SwCursor::IsStartWord( sal_Int16 nWordType ) const |
| { |
| return IsStartWordWT( nWordType ); |
| } |
| |
| sal_Bool SwCursor::IsEndWord( sal_Int16 nWordType ) const |
| { |
| return IsEndWordWT( nWordType ); |
| } |
| |
| sal_Bool SwCursor::IsInWord( sal_Int16 nWordType ) const |
| { |
| return IsInWordWT( nWordType ); |
| } |
| |
| sal_Bool SwCursor::GoStartWord() |
| { |
| return GoStartWordWT( WordType::ANYWORD_IGNOREWHITESPACES ); |
| } |
| |
| sal_Bool SwCursor::GoEndWord() |
| { |
| return GoEndWordWT( WordType::ANYWORD_IGNOREWHITESPACES ); |
| } |
| |
| sal_Bool SwCursor::GoNextWord() |
| { |
| return GoNextWordWT( WordType::ANYWORD_IGNOREWHITESPACES ); |
| } |
| |
| sal_Bool SwCursor::GoPrevWord() |
| { |
| return GoPrevWordWT( WordType::ANYWORD_IGNOREWHITESPACES ); |
| } |
| |
| sal_Bool SwCursor::SelectWord( ViewShell* pViewShell, const Point* pPt ) |
| { |
| return SelectWordWT( pViewShell, WordType::ANYWORD_IGNOREWHITESPACES, pPt ); |
| } |
| |
| sal_Bool SwCursor::IsStartWordWT( sal_Int16 nWordType ) const |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| bRet = pBreakIt->GetBreakIter()->isBeginWord( |
| pTxtNd->GetTxt(), nPtPos, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos )), |
| nWordType ); |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::IsEndWordWT( sal_Int16 nWordType ) const |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| bRet = pBreakIt->GetBreakIter()->isEndWord( |
| pTxtNd->GetTxt(), nPtPos, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), |
| nWordType ); |
| |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::IsInWordWT( sal_Int16 nWordType ) const |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| Boundary aBoundary = pBreakIt->GetBreakIter()->getWordBoundary( |
| pTxtNd->GetTxt(), nPtPos, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), |
| nWordType, |
| sal_True ); |
| |
| bRet = aBoundary.startPos != aBoundary.endPos && |
| aBoundary.startPos <= nPtPos && |
| nPtPos <= aBoundary.endPos; |
| if(bRet) |
| { |
| const CharClass& rCC = GetAppCharClass(); |
| bRet = rCC.isLetterNumeric( pTxtNd->GetTxt(), static_cast<xub_StrLen>(aBoundary.startPos) ); |
| } |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::IsStartEndSentence( bool bEnd ) const |
| { |
| sal_Bool bRet = bEnd ? |
| GetCntntNode() && GetPoint()->nContent == GetCntntNode()->Len() : |
| GetPoint()->nContent.GetIndex() == 0; |
| |
| if( !bRet ) |
| { |
| SwCursor aCrsr(*GetPoint(), 0, false); |
| SwPosition aOrigPos = *aCrsr.GetPoint(); |
| aCrsr.GoSentence( bEnd ? SwCursor::END_SENT : SwCursor::START_SENT ); |
| bRet = aOrigPos == *aCrsr.GetPoint(); |
| } |
| |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::GoStartWordWT( sal_Int16 nWordType ) |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->getWordBoundary( |
| pTxtNd->GetTxt(), nPtPos, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), |
| nWordType, |
| sal_False ).startPos; |
| |
| if( nPtPos < pTxtNd->GetTxt().Len() ) |
| { |
| GetPoint()->nContent = nPtPos; |
| if( !IsSelOvr() ) |
| bRet = sal_True; |
| } |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::GoEndWordWT( sal_Int16 nWordType ) |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->getWordBoundary( |
| pTxtNd->GetTxt(), nPtPos, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), |
| nWordType, |
| sal_True ).endPos; |
| |
| if( nPtPos <= pTxtNd->GetTxt().Len() && |
| GetPoint()->nContent.GetIndex() != nPtPos ) |
| { |
| GetPoint()->nContent = nPtPos; |
| if( !IsSelOvr() ) |
| bRet = sal_True; |
| } |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::GoNextWordWT( sal_Int16 nWordType ) |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->nextWord( |
| pTxtNd->GetTxt(), nPtPos, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos, 1 ) ), |
| nWordType ).startPos; |
| |
| if( nPtPos < pTxtNd->GetTxt().Len() ) |
| { |
| GetPoint()->nContent = nPtPos; |
| if( !IsSelOvr() ) |
| bRet = sal_True; |
| } |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::GoPrevWordWT( sal_Int16 nWordType ) |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| const xub_StrLen nPtStart = nPtPos; |
| |
| if( nPtPos ) |
| --nPtPos; |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->previousWord( |
| pTxtNd->GetTxt(), nPtStart, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos, 1 ) ), |
| nWordType ).startPos; |
| |
| if( nPtPos < pTxtNd->GetTxt().Len() ) |
| { |
| GetPoint()->nContent = nPtPos; |
| if( !IsSelOvr() ) |
| bRet = sal_True; |
| } |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::SelectWordWT( ViewShell* pViewShell, sal_Int16 nWordType, const Point* pPt ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| |
| sal_Bool bRet = sal_False; |
| sal_Bool bForward = sal_True; |
| DeleteMark(); |
| const SwRootFrm* pLayout = pViewShell->GetLayout(); |
| if( pPt && 0 != pLayout ) |
| { |
| // set the cursor to the layout position |
| Point aPt( *pPt ); |
| pLayout->GetCrsrOfst( GetPoint(), aPt ); |
| } //swmod 071107//swmod 071225 |
| |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| Boundary aBndry( pBreakIt->GetBreakIter()->getWordBoundary( |
| pTxtNd->GetTxt(), nPtPos, |
| pBreakIt->GetLocale( pTxtNd->GetLang( nPtPos ) ), |
| nWordType, |
| bForward )); |
| |
| if( aBndry.startPos != aBndry.endPos ) |
| { |
| GetPoint()->nContent = (xub_StrLen)aBndry.endPos; |
| if( !IsSelOvr() ) |
| { |
| SetMark(); |
| GetMark()->nContent = (xub_StrLen)aBndry.startPos; |
| if( !IsSelOvr() ) |
| bRet = sal_True; |
| } |
| } |
| } |
| |
| if( !bRet ) |
| { |
| DeleteMark(); |
| RestoreSavePos(); |
| } |
| return bRet; |
| } |
| |
| //----------------------------------------------------------------------------- |
| |
| static String lcl_MaskDeletedRedlines( const SwTxtNode* pTxtNd ) |
| { |
| String aRes; |
| if (pTxtNd) |
| { |
| //mask deleted redlines |
| String sNodeText(pTxtNd->GetTxt()); |
| const SwDoc& rDoc = *pTxtNd->GetDoc(); |
| const bool nShowChg = IDocumentRedlineAccess::IsShowChanges( rDoc.GetRedlineMode() ); |
| if ( nShowChg ) |
| { |
| sal_uInt16 nAct = rDoc.GetRedlinePos( *pTxtNd, USHRT_MAX ); |
| for ( ; nAct < rDoc.GetRedlineTbl().Count(); nAct++ ) |
| { |
| const SwRedline* pRed = rDoc.GetRedlineTbl()[ nAct ]; |
| if ( pRed->Start()->nNode > pTxtNd->GetIndex() ) |
| break; |
| |
| if( nsRedlineType_t::REDLINE_DELETE == pRed->GetType() ) |
| { |
| xub_StrLen nStart, nEnd; |
| pRed->CalcStartEnd( pTxtNd->GetIndex(), nStart, nEnd ); |
| |
| while ( nStart < nEnd && nStart < sNodeText.Len() ) |
| sNodeText.SetChar( nStart++, CH_TXTATR_INWORD ); |
| } |
| } |
| } |
| aRes = sNodeText; |
| } |
| return aRes; |
| } |
| |
| sal_Bool SwCursor::GoSentence( SentenceMoveType eMoveType ) |
| { |
| sal_Bool bRet = sal_False; |
| const SwTxtNode* pTxtNd = GetNode()->GetTxtNode(); |
| if( pTxtNd && pBreakIt->GetBreakIter().is() ) |
| { |
| String sNodeText( lcl_MaskDeletedRedlines( pTxtNd ) ); |
| |
| SwCrsrSaveState aSave( *this ); |
| xub_StrLen nPtPos = GetPoint()->nContent.GetIndex(); |
| switch ( eMoveType ) |
| { |
| case START_SENT: /* when modifying: see also ExpandToSentenceBorders below! */ |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfSentence( |
| sNodeText, |
| nPtPos, pBreakIt->GetLocale( |
| pTxtNd->GetLang( nPtPos ) )); |
| break; |
| case END_SENT: /* when modifying: see also ExpandToSentenceBorders below! */ |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfSentence( |
| sNodeText, |
| nPtPos, pBreakIt->GetLocale( |
| pTxtNd->GetLang( nPtPos ) )); |
| break; |
| case NEXT_SENT: |
| { |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfSentence( |
| sNodeText, |
| nPtPos, pBreakIt->GetLocale( |
| pTxtNd->GetLang( nPtPos ) )); |
| while (nPtPos != (sal_uInt16) -1 && ++nPtPos < sNodeText.Len() |
| && sNodeText.GetChar(nPtPos)== ' ' /*isWhiteSpace( aTxt.GetChar(nPtPos)*/ ) |
| ; |
| break; |
| } |
| case PREV_SENT: |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfSentence( |
| sNodeText, |
| nPtPos, pBreakIt->GetLocale( |
| pTxtNd->GetLang( nPtPos ) )); |
| if (nPtPos == 0) |
| return sal_False; // the previous sentence is not in this paragraph |
| if (nPtPos > 0) |
| nPtPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfSentence( |
| sNodeText, |
| nPtPos - 1, pBreakIt->GetLocale( |
| pTxtNd->GetLang( nPtPos ) )); |
| break; |
| } |
| |
| // it is allowed to place the PaM just behind the last |
| // character in the text thus <= ...Len |
| if( nPtPos <= pTxtNd->GetTxt().Len() ) |
| { |
| GetPoint()->nContent = nPtPos; |
| if( !IsSelOvr() ) |
| bRet = sal_True; |
| } |
| } |
| return bRet; |
| } |
| |
| |
| sal_Bool SwCursor::ExpandToSentenceBorders() |
| { |
| sal_Bool bRes = sal_False; |
| const SwTxtNode* pStartNd = Start()->nNode.GetNode().GetTxtNode(); |
| const SwTxtNode* pEndNd = End()->nNode.GetNode().GetTxtNode(); |
| if (pStartNd && pEndNd && pBreakIt->GetBreakIter().is()) |
| { |
| if (!HasMark()) |
| SetMark(); |
| |
| String sStartText( lcl_MaskDeletedRedlines( pStartNd ) ); |
| String sEndText( pStartNd == pEndNd? sStartText : lcl_MaskDeletedRedlines( pEndNd ) ); |
| |
| SwCrsrSaveState aSave( *this ); |
| xub_StrLen nStartPos = Start()->nContent.GetIndex(); |
| xub_StrLen nEndPos = End()->nContent.GetIndex(); |
| |
| nStartPos = (xub_StrLen)pBreakIt->GetBreakIter()->beginOfSentence( |
| sStartText, nStartPos, |
| pBreakIt->GetLocale( pStartNd->GetLang( nStartPos ) ) ); |
| nEndPos = (xub_StrLen)pBreakIt->GetBreakIter()->endOfSentence( |
| sEndText, nEndPos, |
| pBreakIt->GetLocale( pEndNd->GetLang( nEndPos ) ) ); |
| |
| // it is allowed to place the PaM just behind the last |
| // character in the text thus <= ...Len |
| bool bChanged = false; |
| if (nStartPos <= pStartNd->GetTxt().Len()) |
| { |
| GetMark()->nContent = nStartPos; |
| bChanged = true; |
| } |
| if (nEndPos <= pEndNd->GetTxt().Len()) |
| { |
| GetPoint()->nContent = nEndPos; |
| bChanged = true; |
| } |
| if (bChanged && !IsSelOvr()) |
| bRes = sal_True; |
| } |
| return bRes; |
| } |
| |
| |
| sal_Bool SwTableCursor::LeftRight( sal_Bool bLeft, sal_uInt16 nCnt, sal_uInt16 /*nMode*/, |
| sal_Bool /*bVisualAllowed*/, sal_Bool /*bSkipHidden*/, sal_Bool /*bInsertCrsr*/ ) |
| { |
| return bLeft ? GoPrevCell( nCnt ) |
| : GoNextCell( nCnt ); |
| } |
| |
| |
| // calculate cursor bidi level: extracted from LeftRight() |
| const SwCntntFrm* |
| SwCursor::DoSetBidiLevelLeftRight( |
| sal_Bool & io_rbLeft, sal_Bool bVisualAllowed, sal_Bool bInsertCrsr) |
| { |
| // calculate cursor bidi level |
| const SwCntntFrm* pSttFrm = NULL; |
| SwNode& rNode = GetPoint()->nNode.GetNode(); |
| |
| if( rNode.IsTxtNode() ) |
| { |
| const SwTxtNode& rTNd = *rNode.GetTxtNode(); |
| SwIndex& rIdx = GetPoint()->nContent; |
| xub_StrLen nPos = rIdx.GetIndex(); |
| |
| const SvtCTLOptions& rCTLOptions = SW_MOD()->GetCTLOptions(); |
| if ( bVisualAllowed && rCTLOptions.IsCTLFontEnabled() && |
| SvtCTLOptions::MOVEMENT_VISUAL == |
| rCTLOptions.GetCTLCursorMovement() ) |
| { |
| // for visual cursor travelling (used in bidi layout) |
| // we first have to convert the logic to a visual position |
| Point aPt; |
| pSttFrm = rTNd.getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| if( pSttFrm ) |
| { |
| sal_uInt8 nCrsrLevel = GetCrsrBidiLevel(); |
| sal_Bool bForward = ! io_rbLeft; |
| ((SwTxtFrm*)pSttFrm)->PrepareVisualMove( nPos, nCrsrLevel, |
| bForward, bInsertCrsr ); |
| rIdx = nPos; |
| SetCrsrBidiLevel( nCrsrLevel ); |
| io_rbLeft = ! bForward; |
| } |
| } |
| else |
| { |
| const SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo( rTNd ); |
| if ( pSI ) |
| { |
| const xub_StrLen nMoveOverPos = io_rbLeft ? |
| ( nPos ? nPos - 1 : 0 ) : |
| nPos; |
| SetCrsrBidiLevel( pSI->DirType( nMoveOverPos ) ); |
| } |
| } |
| } |
| return pSttFrm; |
| } |
| |
| sal_Bool SwCursor::LeftRight( sal_Bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, |
| sal_Bool bVisualAllowed,sal_Bool bSkipHidden, sal_Bool bInsertCrsr ) |
| { |
| // calculate cursor bidi level |
| SwNode& rNode = GetPoint()->nNode.GetNode(); |
| const SwCntntFrm* pSttFrm = // may side-effect bLeft! |
| DoSetBidiLevelLeftRight(bLeft, bVisualAllowed, bInsertCrsr); |
| |
| // kann der Cursor n-mal weiterverschoben werden ? |
| SwCrsrSaveState aSave( *this ); |
| SwMoveFn fnMove = bLeft ? fnMoveBackward : fnMoveForward; |
| |
| SwGoInDoc fnGo; |
| if ( bSkipHidden ) |
| fnGo = CRSR_SKIP_CELLS == nMode ? fnGoCntntCellsSkipHidden : fnGoCntntSkipHidden; |
| else |
| fnGo = CRSR_SKIP_CELLS == nMode ? fnGoCntntCells : fnGoCntnt; |
| |
| // ASSERT( not in covered cell ) |
| |
| while( nCnt ) |
| { |
| SwNodeIndex aOldNodeIdx( GetPoint()->nNode ); |
| |
| bool bSuccess = Move( fnMove, fnGo ); |
| if ( !bSuccess ) |
| break; |
| |
| // If we were located inside a covered cell but our position has been |
| // corrected, we check if the last move has moved the cursor to a different |
| // table cell. In this case we set the cursor to the stored covered position |
| // and redo the move: |
| if ( mnRowSpanOffset ) |
| { |
| const SwNode* pOldTabBoxSttNode = aOldNodeIdx.GetNode().FindTableBoxStartNode(); |
| const SwTableNode* pOldTabSttNode = pOldTabBoxSttNode ? pOldTabBoxSttNode->FindTableNode() : 0; |
| const SwNode* pNewTabBoxSttNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode(); |
| const SwTableNode* pNewTabSttNode = pNewTabBoxSttNode ? pNewTabBoxSttNode->FindTableNode() : 0; |
| |
| const bool bCellChanged = pOldTabSttNode && pNewTabSttNode && |
| pOldTabSttNode == pNewTabSttNode && |
| pOldTabBoxSttNode && pNewTabBoxSttNode && |
| pOldTabBoxSttNode != pNewTabBoxSttNode; |
| |
| if ( bCellChanged ) |
| { |
| // Set cursor to start/end of covered cell: |
| SwTableBox* pTableBox = pOldTabBoxSttNode->GetTblBox(); |
| const long nRowSpan = pTableBox->getRowSpan(); |
| if ( nRowSpan > 1 ) |
| { |
| pTableBox = & pTableBox->FindEndOfRowSpan( pOldTabSttNode->GetTable(), (sal_uInt16)(pTableBox->getRowSpan() + mnRowSpanOffset ) ); |
| SwNodeIndex& rPtIdx = GetPoint()->nNode; |
| SwNodeIndex aNewIdx( *pTableBox->GetSttNd() ); |
| rPtIdx = aNewIdx; |
| |
| GetDoc()->GetNodes().GoNextSection( &rPtIdx, sal_False, sal_False ); |
| SwCntntNode* pCntntNode = GetCntntNode(); |
| if ( pCntntNode ) |
| { |
| const xub_StrLen nTmpPos = bLeft ? pCntntNode->Len() : 0; |
| GetPoint()->nContent.Assign( pCntntNode, nTmpPos ); |
| |
| // Redo the move: |
| bSuccess = Move( fnMove, fnGo ); |
| if ( !bSuccess ) |
| break; |
| } |
| } |
| |
| mnRowSpanOffset = 0; |
| } |
| } |
| |
| // Check if I'm inside a covered cell. Correct cursor if necessary and |
| // store covered cell: |
| const SwNode* pTableBoxStartNode = GetPoint()->nNode.GetNode().FindTableBoxStartNode(); |
| if ( pTableBoxStartNode ) |
| { |
| const SwTableBox* pTableBox = pTableBoxStartNode->GetTblBox(); |
| if ( pTableBox->getRowSpan() < 1 ) |
| { |
| // Store the row span offset: |
| mnRowSpanOffset = pTableBox->getRowSpan(); |
| |
| // Move cursor to non-covered cell: |
| const SwTableNode* pTblNd = pTableBoxStartNode->FindTableNode(); |
| pTableBox = & pTableBox->FindStartOfRowSpan( pTblNd->GetTable(), USHRT_MAX ); |
| SwNodeIndex& rPtIdx = GetPoint()->nNode; |
| SwNodeIndex aNewIdx( *pTableBox->GetSttNd() ); |
| rPtIdx = aNewIdx; |
| |
| GetDoc()->GetNodes().GoNextSection( &rPtIdx, sal_False, sal_False ); |
| SwCntntNode* pCntntNode = GetCntntNode(); |
| if ( pCntntNode ) |
| { |
| const xub_StrLen nTmpPos = bLeft ? pCntntNode->Len() : 0; |
| GetPoint()->nContent.Assign( pCntntNode, nTmpPos ); |
| } |
| } |
| } |
| |
| --nCnt; |
| } |
| |
| // here come some special rules for visual cursor travelling |
| if ( pSttFrm ) |
| { |
| SwNode& rTmpNode = GetPoint()->nNode.GetNode(); |
| if ( &rTmpNode != &rNode && rTmpNode.IsTxtNode() ) |
| { |
| Point aPt; |
| const SwCntntFrm* pEndFrm = ((SwTxtNode&)rTmpNode).getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| if ( pEndFrm ) |
| { |
| if ( ! pEndFrm->IsRightToLeft() != ! pSttFrm->IsRightToLeft() ) |
| { |
| if ( ! bLeft ) |
| pEndFrm->RightMargin( this ); |
| else |
| pEndFrm->LeftMargin( this ); |
| } |
| } |
| } |
| } |
| |
| return 0 == nCnt && !IsInProtectTable( sal_True ) && |
| !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | |
| nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); |
| } |
| |
| // calculate cursor bidi level: extracted from UpDown() |
| void SwCursor::DoSetBidiLevelUpDown() |
| { |
| SwNode& rNode = GetPoint()->nNode.GetNode(); |
| if ( rNode.IsTxtNode() ) |
| { |
| const SwScriptInfo* pSI = |
| SwScriptInfo::GetScriptInfo( (SwTxtNode&)rNode ); |
| if ( pSI ) |
| { |
| SwIndex& rIdx = GetPoint()->nContent; |
| xub_StrLen nPos = rIdx.GetIndex(); |
| |
| if( nPos && nPos < ((SwTxtNode&)rNode).GetTxt().Len() ) |
| { |
| const sal_uInt8 nCurrLevel = pSI->DirType( nPos ); |
| const sal_uInt8 nPrevLevel = pSI->DirType( nPos - 1 ); |
| |
| if ( nCurrLevel % 2 != nPrevLevel % 2 ) |
| { |
| // set cursor level to the lower of the two levels |
| SetCrsrBidiLevel( Min( nCurrLevel, nPrevLevel ) ); |
| } |
| else |
| SetCrsrBidiLevel( nCurrLevel ); |
| } |
| } |
| } |
| } |
| |
| sal_Bool SwCursor::UpDown( sal_Bool bUp, sal_uInt16 nCnt, |
| Point* pPt, long nUpDownX ) |
| { |
| SwTableCursor* pTblCrsr = dynamic_cast<SwTableCursor*>(this); |
| sal_Bool bAdjustTableCrsr = sal_False; |
| |
| // vom Tabellen Crsr Point/Mark in der gleichen Box ?? |
| // dann stelle den Point an den Anfang der Box |
| if( pTblCrsr && GetNode( sal_True )->StartOfSectionNode() == |
| GetNode( sal_False )->StartOfSectionNode() ) |
| { |
| if ( End() != GetPoint() ) |
| Exchange(); |
| bAdjustTableCrsr = sal_True; |
| } |
| |
| sal_Bool bRet = sal_False; |
| Point aPt; |
| if( pPt ) |
| aPt = *pPt; |
| SwCntntFrm* pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| |
| if( pFrm ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| |
| if( !pPt ) |
| { |
| SwRect aTmpRect; |
| pFrm->GetCharRect( aTmpRect, *GetPoint() ); |
| aPt = aTmpRect.Pos(); |
| |
| nUpDownX = pFrm->IsVertical() ? |
| aPt.Y() - pFrm->Frm().Top() : |
| aPt.X() - pFrm->Frm().Left(); |
| } |
| |
| // Bei Fussnoten ist auch die Bewegung in eine andere Fussnote erlaubt. |
| // aber keine Selection!! |
| const sal_Bool bChkRange = pFrm->IsInFtn() && !HasMark() |
| ? sal_False : sal_True; |
| const SwPosition aOldPos( *GetPoint() ); |
| sal_Bool bInReadOnly = IsReadOnlyAvailable(); |
| |
| if ( bAdjustTableCrsr && !bUp ) |
| { |
| // Special case: We have a table cursor but the start box |
| // has more than one paragraph. If we want to go down, we have to |
| // set the point to the last frame in the table box. This is |
| // only necessary if we do not already have a table selection |
| const SwStartNode* pTblNd = GetNode( sal_True )->FindTableBoxStartNode(); |
| ASSERT( pTblNd, "pTblCrsr without SwTableNode?" ) |
| |
| if ( pTblNd ) // safety first |
| { |
| const SwNode* pEndNd = pTblNd->EndOfSectionNode(); |
| GetPoint()->nNode = *pEndNd; |
| pTblCrsr->Move( fnMoveBackward, fnGoNode ); |
| pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| } |
| } |
| |
| while( nCnt && |
| (bUp ? pFrm->UnitUp( this, nUpDownX, bInReadOnly ) |
| : pFrm->UnitDown( this, nUpDownX, bInReadOnly ) ) && |
| CheckNodesRange( aOldPos.nNode, GetPoint()->nNode, bChkRange )) |
| { |
| pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| --nCnt; |
| } |
| |
| if( !nCnt && !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | |
| nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ) ) // die gesamte Anzahl durchlaufen ? |
| { |
| if( !pTblCrsr ) |
| { |
| // dann versuche den Cursor auf die Position zu setzen, |
| // auf halber Heohe vom Char-Rectangle |
| pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| SwCrsrMoveState eTmpState( MV_UPDOWN ); |
| eTmpState.bSetInReadOnly = bInReadOnly; |
| SwRect aTmpRect; |
| pFrm->GetCharRect( aTmpRect, *GetPoint(), &eTmpState ); |
| if ( pFrm->IsVertical() ) |
| { |
| aPt.X() = aTmpRect.Center().X(); |
| pFrm->Calc(); |
| aPt.Y() = pFrm->Frm().Top() + nUpDownX; |
| } |
| else |
| { |
| aPt.Y() = aTmpRect.Center().Y(); |
| pFrm->Calc(); |
| aPt.X() = pFrm->Frm().Left() + nUpDownX; |
| } |
| pFrm->GetCrsrOfst( GetPoint(), aPt, &eTmpState ); |
| } |
| bRet = !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); |
| } |
| else |
| *GetPoint() = aOldPos; |
| |
| DoSetBidiLevelUpDown(); // calculate cursor bidi level |
| } |
| |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::LeftRightMargin( sal_Bool bLeft, sal_Bool bAPI ) |
| { |
| Point aPt; |
| SwCntntFrm * pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| |
| // calculate cursor bidi level |
| if ( pFrm ) |
| SetCrsrBidiLevel( pFrm->IsRightToLeft() ? 1 : 0 ); |
| |
| SwCrsrSaveState aSave( *this ); |
| return pFrm |
| && (bLeft ? pFrm->LeftMargin( this ) : pFrm->RightMargin( this, bAPI ) ) |
| && !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); |
| } |
| |
| sal_Bool SwCursor::IsAtLeftRightMargin( sal_Bool bLeft, sal_Bool bAPI ) const |
| { |
| sal_Bool bRet = sal_False; |
| Point aPt; |
| SwCntntFrm * pFrm = GetCntntNode()->getLayoutFrm( GetDoc()->GetCurrentLayout(), &aPt, GetPoint() ); |
| if( pFrm ) |
| { |
| SwPaM aPam( *GetPoint() ); |
| if( !bLeft && aPam.GetPoint()->nContent.GetIndex() ) |
| aPam.GetPoint()->nContent--; |
| bRet = (bLeft ? pFrm->LeftMargin( &aPam ) |
| : pFrm->RightMargin( &aPam, bAPI )) |
| && *aPam.GetPoint() == *GetPoint(); |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::SttEndDoc( sal_Bool bStt ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| |
| // Springe beim Selektieren nie ueber Section-Grenzen !! |
| // kann der Cursor weiterverschoben werden ? |
| SwMoveFn fnMove = bStt ? fnMoveBackward : fnMoveForward; |
| sal_Bool bRet = (!HasMark() || !IsNoCntnt() ) && |
| Move( fnMove, fnGoDoc ) && |
| !IsInProtectTable( sal_True ) && |
| !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | |
| nsSwCursorSelOverFlags::SELOVER_CHANGEPOS | |
| nsSwCursorSelOverFlags::SELOVER_ENABLEREVDIREKTION ); |
| |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::GoPrevNextCell( sal_Bool bNext, sal_uInt16 nCnt ) |
| { |
| const SwTableNode* pTblNd = GetPoint()->nNode.GetNode().FindTableNode(); |
| if( !pTblNd ) |
| return sal_False; |
| |
| // liegt vor dem StartNode der Cell ein weiterer EndNode, dann |
| // gibt es auch eine vorherige Celle |
| SwCrsrSaveState aSave( *this ); |
| SwNodeIndex& rPtIdx = GetPoint()->nNode; |
| |
| while( nCnt-- ) |
| { |
| const SwNode* pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode(); |
| const SwTableBox* pTableBox = pTableBoxStartNode->GetTblBox(); |
| |
| // Check if we have to move the cursor to a covered cell before |
| // proceeding: |
| if ( mnRowSpanOffset ) |
| { |
| if ( pTableBox->getRowSpan() > 1 ) |
| { |
| pTableBox = & pTableBox->FindEndOfRowSpan( pTblNd->GetTable(), (sal_uInt16)(pTableBox->getRowSpan() + mnRowSpanOffset) ); |
| SwNodeIndex aNewIdx( *pTableBox->GetSttNd() ); |
| rPtIdx = aNewIdx; |
| pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode(); |
| } |
| mnRowSpanOffset = 0; |
| } |
| |
| const SwNode* pTmpNode = bNext ? |
| pTableBoxStartNode->EndOfSectionNode() : |
| pTableBoxStartNode; |
| |
| SwNodeIndex aCellIdx( *pTmpNode, bNext ? 1 : -1 ); |
| if( (bNext && !aCellIdx.GetNode().IsStartNode()) || |
| (!bNext && !aCellIdx.GetNode().IsEndNode()) ) |
| return sal_False; |
| |
| rPtIdx = bNext ? aCellIdx : SwNodeIndex(*aCellIdx.GetNode().StartOfSectionNode()); |
| |
| pTableBoxStartNode = rPtIdx.GetNode().FindTableBoxStartNode(); |
| pTableBox = pTableBoxStartNode->GetTblBox(); |
| if ( pTableBox->getRowSpan() < 1 ) |
| { |
| mnRowSpanOffset = pTableBox->getRowSpan(); |
| // move cursor to non-covered cell: |
| pTableBox = & pTableBox->FindStartOfRowSpan( pTblNd->GetTable(), USHRT_MAX ); |
| SwNodeIndex aNewIdx( *pTableBox->GetSttNd() ); |
| rPtIdx = aNewIdx; |
| } |
| } |
| |
| rPtIdx++; |
| if( !rPtIdx.GetNode().IsCntntNode() ) |
| GetDoc()->GetNodes().GoNextSection( &rPtIdx, sal_True, sal_False ); |
| GetPoint()->nContent.Assign( GetCntntNode(), 0 ); |
| |
| return !IsInProtectTable( sal_True ); |
| } |
| |
| sal_Bool SwTableCursor::GotoTable( const String& /*rName*/ ) |
| { |
| return sal_False; // invalid action |
| } |
| |
| sal_Bool SwCursor::GotoTable( const String& rName ) |
| { |
| sal_Bool bRet = sal_False; |
| if ( !HasMark() ) |
| { |
| SwTable* pTmpTbl = SwTable::FindTable( GetDoc()->FindTblFmtByName( rName ) ); |
| if( pTmpTbl ) |
| { |
| // eine Tabelle im normalen NodesArr |
| SwCrsrSaveState aSave( *this ); |
| GetPoint()->nNode = *pTmpTbl->GetTabSortBoxes()[ 0 ]-> |
| GetSttNd()->FindTableNode(); |
| Move( fnMoveForward, fnGoCntnt ); |
| bRet = !IsSelOvr(); |
| } |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::GotoTblBox( const String& rName ) |
| { |
| sal_Bool bRet = sal_False; |
| const SwTableNode* pTblNd = GetPoint()->nNode.GetNode().FindTableNode(); |
| if( pTblNd ) |
| { |
| // erfrage die Box, mit dem Nanen |
| const SwTableBox* pTblBox = pTblNd->GetTable().GetTblBox( rName ); |
| if( pTblBox && pTblBox->GetSttNd() && |
| ( !pTblBox->GetFrmFmt()->GetProtect().IsCntntProtected() || |
| IsReadOnlyAvailable() ) ) |
| { |
| SwCrsrSaveState aSave( *this ); |
| GetPoint()->nNode = *pTblBox->GetSttNd(); |
| Move( fnMoveForward, fnGoCntnt ); |
| bRet = !IsSelOvr(); |
| } |
| } |
| return bRet; |
| } |
| |
| sal_Bool SwCursor::MovePara(SwWhichPara fnWhichPara, SwPosPara fnPosPara ) |
| { |
| //JP 28.8.2001: for optimization test something before |
| const SwNode* pNd = &GetPoint()->nNode.GetNode(); |
| bool bShortCut = false; |
| if ( fnWhichPara == fnParaCurr ) |
| { |
| // --> FME 2005-02-21 #i41048# |
| // If fnWhichPara == fnParaCurr, (*fnWhichPara)( *this, fnPosPara ) |
| // can already move the cursor to a different text node. In this case |
| // we better check if IsSelOvr(). |
| const SwCntntNode* pCntntNd = pNd->GetCntntNode(); |
| if ( pCntntNd ) |
| { |
| const xub_StrLen nSttEnd = fnPosPara == fnMoveForward ? 0 : pCntntNd->Len(); |
| if ( GetPoint()->nContent.GetIndex() != nSttEnd ) |
| bShortCut = true; |
| } |
| // <-- |
| } |
| else |
| { |
| if ( pNd->IsTxtNode() && |
| pNd->GetNodes()[ pNd->GetIndex() + |
| (fnWhichPara == fnParaNext ? 1 : -1 ) ]->IsTxtNode() ) |
| bShortCut = true; |
| } |
| |
| if ( bShortCut ) |
| return (*fnWhichPara)( *this, fnPosPara ); |
| |
| // else we must use the SaveStructure, because the next/prev is not |
| // a same node type. |
| SwCrsrSaveState aSave( *this ); |
| return (*fnWhichPara)( *this, fnPosPara ) && |
| !IsInProtectTable( sal_True ) && |
| !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | |
| nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); |
| } |
| |
| |
| sal_Bool SwCursor::MoveSection( SwWhichSection fnWhichSect, |
| SwPosSection fnPosSect) |
| { |
| SwCrsrSaveState aSave( *this ); |
| return (*fnWhichSect)( *this, fnPosSect ) && |
| !IsInProtectTable( sal_True ) && |
| !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_TOGGLE | |
| nsSwCursorSelOverFlags::SELOVER_CHANGEPOS ); |
| } |
| |
| /* |
| sal_Bool MoveTable( SwWhichTable, SwPosTable ); |
| sal_Bool MoveColumn( SwWhichColumn, SwPosColumn ); |
| sal_Bool MoveRegion( SwWhichRegion, SwPosRegion ); |
| */ |
| |
| void SwCursor::RestoreSavePos() // Point auf die SavePos setzen |
| { |
| if( pSavePos ) |
| { |
| GetPoint()->nNode = pSavePos->nNode; |
| GetPoint()->nContent.Assign( GetCntntNode(), pSavePos->nCntnt ); |
| } |
| } |
| |
| |
| /* */ |
| |
| SwTableCursor::SwTableCursor( const SwPosition &rPos, SwPaM* pRing ) |
| : SwCursor( rPos, pRing, false ) |
| { |
| bParked = sal_False; |
| bChg = sal_False; |
| nTblPtNd = 0, nTblMkNd = 0; |
| nTblPtCnt = 0, nTblMkCnt = 0; |
| } |
| |
| SwTableCursor::~SwTableCursor() {} |
| |
| |
| sal_Bool lcl_SeekEntry( const SwSelBoxes& rTmp, const SwStartNode* pSrch, sal_uInt16& rFndPos ) |
| { |
| sal_uLong nIdx = pSrch->GetIndex(); |
| |
| sal_uInt16 nO = rTmp.Count(), nM, nU = 0; |
| if( nO > 0 ) |
| { |
| nO--; |
| while( nU <= nO ) |
| { |
| nM = nU + ( nO - nU ) / 2; |
| if( rTmp[ nM ]->GetSttNd() == pSrch ) |
| { |
| rFndPos = nM; |
| return sal_True; |
| } |
| else if( rTmp[ nM ]->GetSttIdx() < nIdx ) |
| nU = nM + 1; |
| else if( nM == 0 ) |
| return sal_False; |
| else |
| nO = nM - 1; |
| } |
| } |
| return sal_False; |
| } |
| |
| |
| SwCursor* SwTableCursor::MakeBoxSels( SwCursor* pAktCrsr ) |
| { |
| if( bChg ) // ??? |
| { |
| if( bParked ) |
| { |
| // wieder in den Inhalt schieben |
| Exchange(); |
| Move( fnMoveForward ); |
| Exchange(); |
| Move( fnMoveForward ); |
| bParked = sal_False; |
| } |
| |
| bChg = sal_False; |
| |
| // temp Kopie anlegen, damit alle Boxen, fuer die schon Cursor |
| // existieren, entfernt werden koennen. |
| SwSelBoxes aTmp; |
| aTmp.Insert( &aSelBoxes ); |
| |
| //Jetzt die Alten und die neuen abgleichen. |
| SwNodes& rNds = pAktCrsr->GetDoc()->GetNodes(); |
| sal_uInt16 nPos; |
| const SwStartNode* pSttNd; |
| SwPaM* pCur = pAktCrsr; |
| do { |
| sal_Bool bDel = sal_False; |
| pSttNd = pCur->GetPoint()->nNode.GetNode().FindTableBoxStartNode(); |
| if( !pCur->HasMark() || !pSttNd || |
| pSttNd != pCur->GetMark()->nNode.GetNode().FindTableBoxStartNode() ) |
| bDel = sal_True; |
| |
| else if( lcl_SeekEntry( aTmp, pSttNd, nPos )) |
| { |
| SwNodeIndex aIdx( *pSttNd, 1 ); |
| const SwNode* pNd = &aIdx.GetNode(); |
| if( !pNd->IsCntntNode() ) |
| pNd = rNds.GoNextSection( &aIdx, sal_True, sal_False ); |
| |
| SwPosition* pPos = pCur->GetMark(); |
| if( pNd != &pPos->nNode.GetNode() ) |
| pPos->nNode = *pNd; |
| pPos->nContent.Assign( (SwCntntNode*)pNd, 0 ); |
| |
| aIdx.Assign( *pSttNd->EndOfSectionNode(), - 1 ); |
| if( !( pNd = &aIdx.GetNode())->IsCntntNode() ) |
| pNd = rNds.GoPrevSection( &aIdx, sal_True, sal_False ); |
| |
| pPos = pCur->GetPoint(); |
| if( pNd != &pPos->nNode.GetNode() ) |
| pPos->nNode = *pNd; |
| pPos->nContent.Assign( (SwCntntNode*)pNd, ((SwCntntNode*)pNd)->Len() ); |
| |
| aTmp.Remove( nPos ); |
| } |
| else |
| bDel = sal_True; |
| |
| pCur = (SwPaM*)pCur->GetNext(); |
| if( bDel ) |
| { |
| SwPaM* pDel = (SwPaM*)pCur->GetPrev(); |
| /* |
| JP 20.07.98: der alte Code geht mit dem UNO-TableCrsr nicht |
| if( pDel == pAktCrsr ) |
| { |
| if( pAktCrsr->GetNext() == pAktCrsr ) |
| { |
| pAktCrsr->DeleteMark(); |
| break; // es gibt nichts mehr zu loeschen! |
| } |
| pAktCrsr = (SwCursor*)pDel->GetPrev(); |
| } |
| delete pDel; |
| */ |
| |
| if( pDel == pAktCrsr ) |
| pAktCrsr->DeleteMark(); |
| else |
| delete pDel; |
| } |
| } while ( pAktCrsr != pCur ); |
| |
| for( nPos = 0; nPos < aTmp.Count(); ++nPos ) |
| { |
| pSttNd = aTmp[ nPos ]->GetSttNd(); |
| |
| SwNodeIndex aIdx( *pSttNd, 1 ); |
| if( &aIdx.GetNodes() != &rNds ) |
| break; |
| const SwNode* pNd = &aIdx.GetNode(); |
| if( !pNd->IsCntntNode() ) |
| pNd = rNds.GoNextSection( &aIdx, sal_True, sal_False ); |
| |
| SwPaM* pNew; |
| if( pAktCrsr->GetNext() == pAktCrsr && !pAktCrsr->HasMark() ) |
| { |
| pNew = pAktCrsr; |
| pNew->GetPoint()->nNode = *pNd; |
| pNew->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 ); |
| } |
| else |
| { |
| pNew = pAktCrsr->Create( pAktCrsr ); |
| pNew->GetPoint()->nNode = *pNd; |
| pNew->GetPoint()->nContent.Assign( (SwCntntNode*)pNd, 0 ); |
| } |
| pNew->SetMark(); |
| |
| SwPosition* pPos = pNew->GetPoint(); |
| pPos->nNode.Assign( *pSttNd->EndOfSectionNode(), - 1 ); |
| if( !( pNd = &pPos->nNode.GetNode())->IsCntntNode() ) |
| pNd = rNds.GoPrevSection( &pPos->nNode, sal_True, sal_False ); |
| |
| pPos->nContent.Assign( (SwCntntNode*)pNd, ((SwCntntNode*)pNd)->Len() ); |
| } |
| } |
| return pAktCrsr; |
| } |
| |
| |
| void SwTableCursor::InsertBox( const SwTableBox& rTblBox ) |
| { |
| SwTableBox* pBox = (SwTableBox*)&rTblBox; |
| aSelBoxes.Insert( pBox ); |
| bChg = sal_True; |
| } |
| |
| bool SwTableCursor::NewTableSelection() |
| { |
| bool bRet = false; |
| const SwNode *pStart = GetCntntNode()->FindTableBoxStartNode(); |
| const SwNode *pEnd = GetCntntNode(sal_False)->FindTableBoxStartNode(); |
| if( pStart && pEnd ) |
| { |
| const SwTableNode *pTableNode = pStart->FindTableNode(); |
| if( pTableNode == pEnd->FindTableNode() && |
| pTableNode->GetTable().IsNewModel() ) |
| { |
| bRet = true; |
| SwSelBoxes aNew; |
| aNew.Insert( &aSelBoxes ); |
| pTableNode->GetTable().CreateSelection( pStart, pEnd, aNew, |
| SwTable::SEARCH_NONE, false ); |
| ActualizeSelection( aNew ); |
| } |
| } |
| return bRet; |
| } |
| |
| void SwTableCursor::ActualizeSelection( const SwSelBoxes &rNew ) |
| { |
| sal_uInt16 nOld = 0, nNew = 0; |
| while ( nOld < aSelBoxes.Count() && nNew < rNew.Count() ) |
| { |
| const SwTableBox* pPOld = *( aSelBoxes.GetData() + nOld ); |
| const SwTableBox* pPNew = *( rNew.GetData() + nNew ); |
| if( pPOld == pPNew ) |
| { // this box will stay |
| ++nOld; |
| ++nNew; |
| } |
| else if( pPOld->GetSttIdx() < pPNew->GetSttIdx() ) |
| DeleteBox( nOld ); // this box has to go |
| else |
| { |
| InsertBox( *pPNew ); // this is a new one |
| ++nOld; |
| ++nNew; |
| } |
| } |
| |
| while( nOld < aSelBoxes.Count() ) |
| DeleteBox( nOld ); // some more to delete |
| |
| for( ; nNew < rNew.Count(); ++nNew ) // some more to insert |
| InsertBox( **( rNew.GetData() + nNew ) ); |
| } |
| |
| sal_Bool SwTableCursor::IsCrsrMovedUpdt() |
| { |
| if( !IsCrsrMoved() ) |
| return sal_False; |
| |
| nTblMkNd = GetMark()->nNode.GetIndex(); |
| nTblPtNd = GetPoint()->nNode.GetIndex(); |
| nTblMkCnt = GetMark()->nContent.GetIndex(); |
| nTblPtCnt = GetPoint()->nContent.GetIndex(); |
| return sal_True; |
| } |
| |
| |
| // Parke den Tabellen-Cursor auf dem StartNode der Boxen. |
| void SwTableCursor::ParkCrsr() |
| { |
| // Index aus dem TextNode abmelden |
| SwNode* pNd = &GetPoint()->nNode.GetNode(); |
| if( !pNd->IsStartNode() ) |
| pNd = pNd->StartOfSectionNode(); |
| GetPoint()->nNode = *pNd; |
| GetPoint()->nContent.Assign( 0, 0 ); |
| |
| pNd = &GetMark()->nNode.GetNode(); |
| if( !pNd->IsStartNode() ) |
| pNd = pNd->StartOfSectionNode(); |
| GetMark()->nNode = *pNd; |
| GetMark()->nContent.Assign( 0, 0 ); |
| |
| bChg = sal_True; |
| bParked = sal_True; |
| } |
| |
| |
| sal_Bool SwTableCursor::HasReadOnlyBoxSel() const |
| { |
| sal_Bool bRet = sal_False; |
| for( sal_uInt16 n = aSelBoxes.Count(); n; ) |
| if( aSelBoxes[ --n ]->GetFrmFmt()->GetProtect().IsCntntProtected() ) |
| { |
| bRet = sal_True; |
| break; |
| } |
| return bRet; |
| } |
| |
| |