/* -*- 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 .
*/
// If Point or Mark is within the Cursor range, we need to remove the old // range. Take note that Point does not belong to the range anymore.
pTmp = pTmp->GetNext(); delete pTmpDel; // Remove old range
pTmpDel = nullptr;
}
}
// SwCursorShell
/** * Add a copy of current cursor, append it after current, and collapse current cursor. * @return - Returns a newly created copy of current cursor.
*/
SwPaM * SwCursorShell::CreateCursor()
{ // don't create new Cursor with active table Selection
assert(!IsTableMode());
// ensure that m_pCurrentCursor is valid; if it's invalid it would be // copied to pNew and then pNew would be deleted in UpdateCursor() below
ClearUpCursors();
// New cursor as copy of current one. Add to the ring. // Links point to previously created one, ie forward.
SwShellCursor* pNew = new SwShellCursor( *m_pCurrentCursor );
// Hide PaM logically, to avoid undoing the inverting from // copied PaM (#i75172#)
pNew->swapContent(*m_pCurrentCursor);
/** * Delete current Cursor, making the following one the current. * Note, this function does not delete anything if there is no other cursor. * @return - returns true if there was another cursor and we deleted one.
*/ void SwCursorShell::DestroyCursor()
{ // don't delete Cursor with active table Selection
assert(!IsTableMode());
// Is there a next one? Don't do anything if not. if(!m_pCurrentCursor->IsMultiSelection()) return;
/** * Create and return a new shell cursor. * Simply returns the current shell cursor if there is no selection * (HasSelection()).
*/
SwCursor & SwCursorShell::CreateNewShellCursor()
{ if (HasSelection())
{
(void) CreateCursor(); // n.b. returns old cursor
} return *GetCursor();
}
/** * Return the current shell cursor * @return - returns current `SwPaM` shell cursor
*/
SwCursor & SwCursorShell::GetCurrentShellCursor()
{ return *GetCursor();
}
// Update all invalid numberings before the last action if( 1 == mnStartAction )
GetDoc()->UpdateNumRule();
// #i76923#: Don't show the cursor in the SwViewShell::EndAction() - call. // Only the UpdateCursor shows the cursor. bool bSavSVCursorVis = m_bSVCursorVis;
m_bSVCursorVis = false;
SwViewShell::EndAction( bIdleEnd ); // have SwViewShell go first
// 1. CASE: Cursor is in front of label. A move to the right // will simply reset the bInFrontOfLabel flag:
SwShellCursor* pShellCursor = getShellCursor( true ); if ( !bLeft && pShellCursor->IsInFrontOfLabel() )
{
SetInFrontOfLabel( false );
bRet = true;
} // 2. CASE: Cursor is at beginning of numbered paragraph. A move // to the left will simply set the bInFrontOfLabel flag: elseif (bLeft
&& pShellCursor->GetPoint()->GetNode().IsTextNode()
&& static_cast<SwTextFrame const*>(
pShellCursor->GetPoint()->GetNode().GetTextNode()->getLayoutFrame(GetLayout())
)->MapModelToViewPos(*pShellCursor->GetPoint()) == TextFrameIndex(0)
&& !pShellCursor->IsInFrontOfLabel()
&& !pShellCursor->HasMark()
&& nullptr != (pTextNd = sw::GetParaPropsNode(*GetLayout(), pShellCursor->GetPoint()->GetNode()))
&& pTextNd->HasVisibleNumberingOrBullet())
{
SetInFrontOfLabel( true );
bRet = true;
} // 3. CASE: Regular cursor move. Reset the bInFrontOfLabel flag: else
{ constbool bSkipHidden = !GetViewOptions()->IsShowHiddenChar(); // #i107447# // To avoid loop the reset of <bInFrontOfLabel> flag is no longer // reflected in the return value <bRet>. constbool bResetOfInFrontOfLabel = SetInFrontOfLabel( false );
bRet = pShellCursor->LeftRight( bLeft, nCnt, nMode, bVisualAllowed,
bSkipHidden, !IsOverwriteCursor(),
GetLayout(),
GetViewOptions()->IsFieldName()); if ( !bRet && bLeft && bResetOfInFrontOfLabel )
{ // undo reset of <bInFrontOfLabel> flag
SetInFrontOfLabel( true );
}
}
// Writer redraws the "marked" list with the field shading, if there // is no field shading then the marked list would be redrawn for no // visually identifiable reason, so skip the mark if field shadings // are disabled. constbool bVisuallyMarked(GetViewOptions()->IsFieldShadings()); if (bVisuallyMarked)
{ if ( !m_sMarkedListId.isEmpty() )
mxDoc->MarkListLevel( m_sMarkedListId, m_nMarkedListLevel, false );
if ( !sListId.isEmpty() )
mxDoc->MarkListLevel( sListId, nListLevel, true );
}
const SwTableNode* SwCursorShell::IsCursorInTable() const
{ if (m_pTableCursor && m_pTableCursor->GetSelectedBoxesCount())
{ // find the table that has the selected boxes return m_pTableCursor->GetSelectedBoxes()[0]->GetSttNd()->FindTableNode();
} return m_pCurrentCursor->GetPointNode().FindTableNode();
}
// fun cases to consider: // * outermost table // - into para => SA/ESA // - into prev/next table => continue... // - no prev/next => done // * inner table // - into containing cell => SA/ESA // - into prev/next of containing cell // + into para // + into table nested in prev/next cell // - out of table -> as above // => iterate in one direction until a node is reached that is a parent or a sibling of a parent of the current table // - parent reached => SA/ESA depending // - not in parent but in *prev/next* sibling of outer cell => TrySelectOuterTable // - not in parent but in *prev/next* sibling of outer table => TrySelectOuterTable // => select-all cannot select a sequence of table with no para at same level; only 1 table // - no parent, no prev/next => TrySelectOuterTable
// manually select boxes of pOuterTable
SwNodeIndex firstCell(*pOuterTable, +1);
SwNodeIndex lastCell(*rNodes[pOuterTable->EndOfSectionIndex()-1]->StartOfSectionNode());
SwSelBoxes aNew;
pOuterTable->GetTable().CreateSelection(&firstCell.GetNode(), &lastCell.GetNode(),
aNew, SwTable::SEARCH_NONE, false); // set table cursor to 1st / last content which may be in inner table
SwContentNode* const pStart = SwNodes::GoNext(&firstCell);
assert(pStart); // must at least find the previous point node
lastCell = *lastCell.GetNode().EndOfSectionNode();
SwContentNode *const pEnd = SwNodes::GoPrevious(&lastCell);
assert(pEnd); // must at least find the previous point node delete m_pTableCursor;
m_pTableCursor = new SwShellTableCursor(*this, SwPosition(*pStart, 0), Point(),
SwPosition(*pEnd, 0), Point());
m_pTableCursor->ActualizeSelection( aNew );
m_pTableCursor->IsCursorMovedUpdate(); // clear this so GetCursor() doesn't recreate our SwSelBoxes
// this will update m_pCurrentCursor based on m_pTableCursor
UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY);
bool SwCursorShell::MoveStartText()
{
SwPosition const old(*m_pCurrentCursor->GetPoint());
SwStartNode const*const pStartNode(FindParentText(*getShellCursor(false)));
assert(pStartNode);
SwTableNode const*const pTable(pStartNode->FindTableNode());
m_pCurrentCursor->GetPoint()->Assign(*pStartNode);
SwNodes::GoNext(m_pCurrentCursor->GetPoint()); while (auto* pFoundTable = m_pCurrentCursor->GetPoint()->GetNode().FindTableNode())
{ if (pFoundTable == pTable) break; if (pTable && pTable->GetIndex() >= pFoundTable->GetIndex()) break; if (!MoveOutOfTable()) break;
}
UpdateCursor(SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE|SwCursorShell::READONLY); return old != *m_pCurrentCursor->GetPoint();
}
// select all inside the current XText, with table or hidden para at start/end void SwCursorShell::ExtendedSelectAll(bool bFootnotes)
{ // find common ancestor node of both ends of cursor
SwStartNode const*const pStartNode(FindParentText(*getShellCursor(false)));
assert(pStartNode); if (IsTableMode())
{ // convert m_pTableCursor to m_pCurrentCursor after determining pStartNode
TableCursorToCursor();
}
SwNodes& rNodes = GetDoc()->GetNodes();
m_pCurrentCursor->Normalize(true);
SwPosition* pPos = m_pCurrentCursor->GetPoint();
pPos->Assign(bFootnotes ? rNodes.GetEndOfPostIts() : static_cast<SwNode const&>(*pStartNode));
SwNodes::GoNext(pPos);
pPos = m_pCurrentCursor->GetMark();
pPos->Assign(bFootnotes ? rNodes.GetEndOfContent() : static_cast<SwNode const&>(*pStartNode->EndOfSectionNode()));
SwContentNode* pCNd = SwNodes::GoPrevious( pPos ); if (pCNd)
pPos->AssignEndIndex(*pCNd);
}
statictypename SwCursorShell::StartsWith StartsWith(SwStartNode const& rStart)
{ for (auto i = rStart.GetIndex() + 1; i < rStart.EndOfSectionIndex(); ++i)
{
SwNode const& rNode(*rStart.GetNodes()[i]); switch (rNode.GetNodeType())
{ case SwNodeType::Section: if (rNode.GetSectionNode()->GetSection().IsHidden()) return SwCursorShell::StartsWith::HiddenSection; continue; case SwNodeType::Table: return SwCursorShell::StartsWith::Table; case SwNodeType::Text: if (rNode.GetTextNode()->IsHidden())
{ return SwCursorShell::StartsWith::HiddenPara;
} return SwCursorShell::StartsWith::None; default: return SwCursorShell::StartsWith::None;
}
} return SwCursorShell::StartsWith::None;
}
statictypename SwCursorShell::StartsWith EndsWith(SwStartNode const& rStart)
{ for (auto i = rStart.EndOfSectionIndex() - 1; rStart.GetIndex() < i; --i)
{
SwNode const& rNode(*rStart.GetNodes()[i]); switch (rNode.GetNodeType())
{ case SwNodeType::End: if (auto pStartNode = rNode.StartOfSectionNode(); pStartNode->IsTableNode())
{ return SwCursorShell::StartsWith::Table;
} elseif (pStartNode->IsSectionNode())
{ if (pStartNode->GetSectionNode()->GetSection().IsHidden()) return SwCursorShell::StartsWith::HiddenSection;
} //TODO buggy SwUndoRedline in testTdf137503? assert(rNode.StartOfSectionNode()->IsSectionNode()); break; case SwNodeType::Text: if (rNode.GetTextNode()->IsHidden())
{ return SwCursorShell::StartsWith::HiddenPara;
} return SwCursorShell::StartsWith::None; default: return SwCursorShell::StartsWith::None;
}
} return SwCursorShell::StartsWith::None;
}
// return the node that is the start of the extended selection (to include table // or section start nodes; looks like extending for end nodes is not required)
SwCursorShell::ExtendedSelection SwCursorShell::ExtendedSelectedAll() const
{ if (m_pTableCursor)
{ return {};
}
// tdf#133990 ensure directly containing section is included in SwUndoDelete while (pStartNode->IsSectionNode()
&& pStartNode->GetIndex() == pStartNode->StartOfSectionNode()->GetIndex() + 1
&& pStartNode->EndOfSectionNode()->GetIndex() + 1 == pStartNode->StartOfSectionNode()->EndOfSectionNode()->GetIndex())
{
pStartNode = pStartNode->StartOfSectionNode();
}
// pStartNode is the node that fully contains the selection - the first // node of the selection is the first node inside pStartNode return ::std::make_pair(rNodes[pStartNode->GetIndex() + 1], tablesAtEnd);
}
typename SwCursorShell::StartsWith SwCursorShell::StartsWith_()
{
SwShellCursor const*const pShellCursor = getShellCursor(false); // first, check if this is invalid; ExtendedSelectAll(true) may result in // a) an ordinary selection that is valid // b) a selection that is extended // c) a selection that is invalid and will cause FindParentText to loop
SwNode const& rEndOfExtras(GetDoc()->GetNodes().GetEndOfExtras()); if (pShellCursor->Start()->nNode.GetIndex() <= rEndOfExtras.GetIndex()
&& rEndOfExtras.GetIndex() < pShellCursor->End()->nNode.GetIndex())
{ return StartsWith::None; // *very* extended, no ExtendedSelectedAll handling!
}
SwStartNode const*const pStartNode(FindParentText(*pShellCursor)); if (autoconst ret = ::StartsWith(*pStartNode); ret != StartsWith::None)
{ return ret;
} if (autoconst ret = ::EndsWith(*pStartNode); ret != StartsWith::None)
{ return ret;
} return StartsWith::None;
}
// never jump of section borders at selection if( !m_pCurrentCursor->HasMark() || !m_pCurrentCursor->IsNoContent() )
{
SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
CurrShell aCurr( this );
// sw_redlinehide: this should work for all cases: GoCurrPara, GoNextPara, GoPrevPara staticbool IsAtStartOrEndOfFrame(SwCursorShell const*const pShell,
SwShellCursor const*const pShellCursor, SwMoveFnCollection const& fnPosPara)
{
SwContentNode *const pCNode = pShellCursor->GetPointContentNode();
assert(pCNode); // surely can't have moved otherwise?
std::pair<Point, bool> tmp(pShellCursor->GetPtPos(), false);
SwContentFrame const*const pFrame = pCNode->getLayoutFrame(
pShell->GetLayout(), pShellCursor->GetPoint(), &tmp); if (!pFrame || !pFrame->IsTextFrame())
{ returnfalse;
}
SwTextFrame const& rTextFrame(static_cast<SwTextFrame const&>(*pFrame));
TextFrameIndex const ix(rTextFrame.MapModelToViewPos(*pShellCursor->GetPoint())); if (&fnParaStart == &fnPosPara)
{ return ix == TextFrameIndex(0);
} else
{
assert(&fnParaEnd == &fnPosPara); return ix == TextFrameIndex(rTextFrame.GetText().getLength());
}
}
bool SwCursorShell::MovePara(SwWhichPara fnWhichPara, SwMoveFnCollection const & fnPosPara )
{
SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
SwShellCursor* pTmpCursor = getShellCursor( true ); bool bRet = pTmpCursor->MovePara( fnWhichPara, fnPosPara ); if( bRet )
{ //keep going until we get something visible, i.e. skip //over hidden paragraphs, don't get stuck at the start //which is what SwCursorShell::UpdateCursorPos will reset //the position to if we pass it a position in an //invisible hidden paragraph field while (isInHiddenFrame(pTmpCursor)
|| !IsAtStartOrEndOfFrame(this, pTmpCursor, fnPosPara))
{ if (!pTmpCursor->MovePara(fnWhichPara, fnPosPara)) break;
}
int SwCursorShell::SetCursor(const Point& rLPt, bool bOnlyText, bool bBlock, bool bFieldInfo, ScrollSizeMode eScrollSizeMode)
{
CurrShell aCurr( this );
SwShellCursor* pCursor = getShellCursor( bBlock );
SwPosition aPos( *pCursor->GetPoint() );
Point aPt( rLPt );
Point & rCurrentCursorPt = pCursor->GetPtPos();
SwCursorMoveState aTmpState( IsTableMode() ? CursorMoveState::TableSel :
bOnlyText ? CursorMoveState::SetOnlyText : CursorMoveState::NONE );
aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
aTmpState.m_bFieldInfo = bFieldInfo; // always set cursor at field-start if point is over field
aTmpState.m_bPosMatchesBounds = bFieldInfo; // always set cursor at character-start if over char
if( CursorMoveState::RightMargin == aTmpState.m_eState )
m_eMvState = CursorMoveState::RightMargin; // is the new position in header or footer?
SwFrame* pFrame = lcl_IsInHeaderFooter( aPos.GetNode(), aPt ); if( IsTableMode() && !pFrame && aPos.GetNode().StartOfSectionNode() ==
pCursor->GetPoint()->GetNode().StartOfSectionNode() ) // same table column and not in header/footer -> back return bRet;
if( m_pBlockCursor && bBlock )
{
m_pBlockCursor->setEndPoint( rLPt ); if( !pCursor->HasMark() )
m_pBlockCursor->setStartPoint( rLPt ); elseif( !m_pBlockCursor->getStartPoint() )
m_pBlockCursor->setStartPoint( pCursor->GetMkPos() );
} if( !pCursor->HasMark() )
{ // is at the same position and if in header/footer -> in the same if( aPos == *pCursor->GetPoint() &&
bOldInFrontOfLabel == bNewInFrontOfLabel )
{ if( pFrame )
{ if( pFrame->getFrameArea().Contains( rCurrentCursorPt )) return bRet;
} elseif( aPos.GetNode().IsContentNode() )
{ // in the same frame?
std::pair<Point, bool> tmp(m_aCharRect.Pos(), false);
SwFrame* pOld = static_cast<SwContentNode&>(aPos.GetNode()).getLayoutFrame(
GetLayout(), nullptr, &tmp);
tmp.first = aPt;
SwFrame* pNew = static_cast<SwContentNode&>(aPos.GetNode()).getLayoutFrame(
GetLayout(), nullptr, &tmp); if( pNew == pOld ) return bRet;
}
}
} else
{ // SSelection over not allowed sections or if in header/footer -> different if( !CheckNodesRange( aPos.GetNode(), pCursor->GetMark()->GetNode(), true )
|| ( pFrame && !pFrame->getFrameArea().Contains( pCursor->GetMkPos() ) )) return bRet;
// is at same position but not in header/footer if( aPos == *pCursor->GetPoint() ) return bRet;
}
SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
SwCursorSaveState aSaveState( *pCursor );
// #i41424# Only update the marked number levels if necessary // Force update of marked number levels if necessary. if ( bNewInFrontOfLabel || bOldInFrontOfLabel )
m_pCurrentCursor->SetInFrontOfLabel_( !bNewInFrontOfLabel );
SetInFrontOfLabel( bNewInFrontOfLabel );
void SwCursorShell::NormalizePam(bool bPointFirst)
{
SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
m_pCurrentCursor->Normalize(bPointFirst);
}
void SwCursorShell::SwapPam()
{
SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
m_pCurrentCursor->Exchange();
}
//TODO: provide documentation /** Search in the selected area for a Selection that covers the given point.
It checks if a Selection exists but does not move the current cursor.
@param rPt The point to search at. @param bTstHit ???
*/ bool SwCursorShell::TestCurrPam( const Point & rPt, bool bTstHit )
{
CurrShell aCurr( this );
// check if the SPoint is in a table selection if( m_pTableCursor ) return m_pTableCursor->Contains( rPt );
SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed // search position <rPt> in document
SwPosition aPtPos( *m_pCurrentCursor->GetPoint() );
Point aPt( rPt );
SwCursorMoveState aTmpState( CursorMoveState::NONE );
aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
aTmpState.m_bPosMatchesBounds = true; // treat last half of character same as first half if ( !GetLayout()->GetModelPositionForViewPoint( &aPtPos, aPt, &aTmpState ) && bTstHit ) returnfalse;
// search in all selections for this position
SwShellCursor* pCmp = m_pCurrentCursor; // keep the pointer on cursor do
{ if (pCmp->HasMark() && *pCmp->Start() <= aPtPos && *pCmp->End() > aPtPos) returntrue; // return without update
pCmp = pCmp->GetNext();
} while (m_pCurrentCursor != pCmp); returnfalse;
}
void SwCursorShell::KillPams()
{ // Does any exist for deletion? if( !m_pTableCursor && !m_pBlockCursor && !m_pCurrentCursor->IsMultiSelection() ) return;
void SwCursorShell::GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum, bool bAtCursorPos, constbool bCalcFrame )
{
CurrShell aCurr( this ); // page number: first visible page or the one at the cursor const SwContentFrame* pCFrame; const SwPageFrame *pPg = nullptr;
if( !bAtCursorPos || nullptr == (pCFrame = GetCurrFrame( bCalcFrame )) ||
nullptr == (pPg = pCFrame->FindPageFrame()) )
{
pPg = Imp()->GetFirstVisPage(GetOut()); while( pPg && pPg->IsEmptyPage() )
pPg = static_cast<const SwPageFrame *>(pPg->GetNext());
} // pPg has to exist with a default of 1 for the special case "Writerstart"
rnPhyNum = pPg? pPg->GetPhyPageNum() : 1;
rnVirtNum = pPg? pPg->GetVirtPageNum() : 1;
}
sal_uInt16 SwCursorShell::GetPageNumSeqNonEmpty()
{
CurrShell aCurr(this); // page number: first visible page or the one at the cursor const SwContentFrame* pCFrame = GetCurrFrame(/*bCalcFrame*/true); const SwPageFrame* pPg = nullptr;
while( pPg && pPg->IsEmptyPage() )
pPg = static_cast<const SwPageFrame *>(pPg->GetPrev());
}
} // pPg has to exist with a default of 1 for the special case "Writerstart" return pPg ? pPg->GetPhyPageNum() : USHRT_MAX;
}
sal_uInt16 SwCursorShell::GetPageCnt()
{
CurrShell aCurr( this ); // return number of pages return GetLayout()->GetPageNum();
}
if( !ActionPend() )
{ // so that right/bottom borders will not be cropped
pCurrentCursor->Invalidate( VisArea() );
pCurrentCursor->Show(nullptr);
} else
pCurrentCursor->Invalidate( aRect );
}
if (SwPostItMgr* pPostItMgr = GetPostItMgr())
{ // No point in showing the cursor for Writer text when there is an // active annotation edit. if (bVis)
bVis = !pPostItMgr->HasActiveSidebarWin();
}
if( m_bSVCursorVis && bVis ) // also show SV cursor again
m_pVisibleCursor->Show(); #if ENABLE_YRS for (autoconst& it : m_PeerCursors)
{ if (it.second->m_pCurrentCursor && it.second->m_bSVCursorVis)
{
it.second->m_pVisibleCursor->Show();
}
} #endif
}
void SwCursorShell::VisPortChgd( const SwRect & rRect )
{
CurrShell aCurr( this ); bool bVis; // switch off all cursors when scrolling
// if a cursor is visible then hide the SV cursor
bVis = m_pVisibleCursor->IsVisible(); if( bVis )
m_pVisibleCursor->Hide();
// For not having problems with the SV cursor, Update() is called for the // Window in SwViewShell::VisPo... // During painting no selections should be shown, thus the call is encapsulated. <- TODO: old artefact?
SwViewShell::VisPortChgd( rRect ); // move area
if( m_bSVCursorVis && bVis ) // show SV cursor again
m_pVisibleCursor->Show();
if( m_nCursorMove )
m_bInCMvVisportChgd = true;
m_bVisPortChgd = false;
}
/** Set the cursor back into content.
This should only be called if the cursor was moved (e.g. when deleting a text frame). The new position is calculated from its current position in the layout.
*/ void SwCursorShell::UpdateCursorPos()
{
CurrShell aCurr( this );
++mnStartAction;
SwShellCursor* pShellCursor = getShellCursor( true );
Size aOldSz( GetDocSize() );
if (isInHiddenFrame(pShellCursor) && !ExtendedSelectedAll())
{ // kde45196-1.html: try to get to a non-hidden paragraph, there must // be one in the document body while (isInHiddenFrame(pShellCursor))
{ if (!pShellCursor->MovePara(GoNextPara, fnParaStart))
{ break;
}
} while (isInHiddenFrame(pShellCursor))
{ if (!pShellCursor->MovePara(GoPrevPara, fnParaStart))
{ break;
}
} if (isInHiddenFrame(pShellCursor))
{
SwCursorMoveState aTmpState(CursorMoveState::SetOnlyText);
aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
GetLayout()->GetModelPositionForViewPoint(pShellCursor->GetPoint(),
pShellCursor->GetPtPos(), &aTmpState);
pShellCursor->DeleteMark();
}
} auto* pDoc = GetDoc(); if (pDoc)
{
pDoc->getGrammarContact()->updateCursorPosition(*m_pCurrentCursor->GetPoint());
pDoc->getOnlineAccessibilityCheck()->update(*m_pCurrentCursor->GetPoint());
}
// #i65475# - if Point/Mark in hidden sections, move them out staticbool lcl_CheckHiddenSection( SwPosition& rPos )
{ bool bOk = true; const SwSectionNode* pSectNd = rPos.GetNode().FindSectionNode(); if( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
{ const SwNode* pFrameNd =
rPos.GetNodes().FindPrvNxtFrameNode( *pSectNd, pSectNd->EndOfSectionNode() );
bOk = pFrameNd != nullptr;
SAL_WARN_IF(!bOk, "sw.core", "found no Node with Frames");
rPos.Assign( *(bOk ? pFrameNd : pSectNd) );
} return bOk;
}
/// Try to set the cursor to the next visible content node. staticvoid lcl_CheckHiddenPara( SwPosition& rPos )
{
SwNodeIndex aTmp( rPos.GetNode() );
SwTextNode* pTextNd = aTmp.GetNode().GetTextNode(); while( pTextNd && pTextNd->HasHiddenCharAttribute( true ) )
{
SwContentNode* pContent = SwNodes::GoNext(&aTmp); if ( pContent && pContent->IsTextNode() )
pTextNd = pContent->GetTextNode(); else
pTextNd = nullptr;
}
if ( pTextNd )
rPos.Assign( *pTextNd, 0 );
}
#if !ENABLE_WASM_STRIP_ACCESSIBILITY namespace {
// #i27301# - helper class that notifies the accessibility about invalid text // selections in its destructor class SwNotifyAccAboutInvalidTextSelections
{ private:
SwCursorShell& mrCursorSh;
if (ActionPend())
{ if ( eFlags & SwCursorShell::READONLY )
m_bIgnoreReadonly = true; return; // if not then no update
}
if (m_bNeedLayoutOnCursorUpdate)
{ // A previous spell check skipped a word that had a spelling error, because that word // had cursor. Now schedule the idle to call SwViewShell::LayoutIdle, to repeat the // spell check, in the hope that the cursor has left the word.
m_aLayoutIdle.Start();
m_bNeedLayoutOnCursorUpdate = false;
}
if( eFlags & SwCursorShell::CHKRANGE ) // check all cursor moves for
CheckRange( m_pCurrentCursor ); // overlapping ranges
if( !bIdleEnd )
CheckTableBoxContent();
// If the current cursor is in a table and point/mark in different boxes, // then the table mode is active (also if it is already active: m_pTableCursor)
SwPaM* pTstCursor = getShellCursor( true );
--> --------------------
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.