/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; void SwEditShell::Insert( sal_Unicode c, bool bOnlyCurrCursor ) { StartAllAction(); for(SwPaM& rPaM : GetCursor()->GetRingContainer()) { const bool bSuccess = GetDoc()->getIDocumentContentOperations().InsertString(rPaM, OUString(c)); OSL_ENSURE( bSuccess, "Doc->Insert() failed." ); SaveTableBoxContent( rPaM.GetPoint() ); if( bOnlyCurrCursor ) break; } EndAllAction(); } void SwEditShell::Insert2(const OUString &rStr, const bool bForceExpandHints ) { StartAllAction(); { const SwInsertFlags nInsertFlags = bForceExpandHints ? (SwInsertFlags::FORCEHINTEXPAND | SwInsertFlags::EMPTYEXPAND) : SwInsertFlags::EMPTYEXPAND; for(SwPaM& rCurrentCursor : getShellCursor( true )->GetRingContainer()) { //OPT: GetSystemCharSet const bool bSuccess = GetDoc()->getIDocumentContentOperations().InsertString(rCurrentCursor, rStr, nInsertFlags); OSL_ENSURE( bSuccess, "Doc->Insert() failed." ); if (bSuccess) { GetDoc()->UpdateRsid( rCurrentCursor, rStr.getLength() ); // Set paragraph rsid if beginning of paragraph SwTextNode *const pTextNode = rCurrentCursor.GetPoint()->nNode.GetNode().GetTextNode(); if( pTextNode && pTextNode->Len() == 1) GetDoc()->UpdateParRsid( pTextNode ); } SaveTableBoxContent( rCurrentCursor.GetPoint() ); } } // calculate cursor bidi level SwCursor* pTmpCursor = GetCursor_(); const bool bDoNotSetBidiLevel = ! pTmpCursor || ( dynamic_cast(pTmpCursor) != nullptr ); if ( ! bDoNotSetBidiLevel ) { SwNode& rNode = pTmpCursor->GetPoint()->nNode.GetNode(); if ( rNode.IsTextNode() ) { SwIndex& rIdx = pTmpCursor->GetPoint()->nContent; sal_Int32 nPrevPos = rIdx.GetIndex(); if ( nPrevPos ) --nPrevPos; SwTextFrame const* pFrame; SwScriptInfo *const pSI = SwScriptInfo::GetScriptInfo( static_cast(rNode), &pFrame, true); sal_uInt8 nLevel = 0; if ( ! pSI ) { // seems to be an empty paragraph. Point aPt; std::pair const tmp(aPt, false); pFrame = static_cast( static_cast(rNode).getLayoutFrame( GetLayout(), pTmpCursor->GetPoint(), &tmp)); SwScriptInfo aScriptInfo; aScriptInfo.InitScriptInfo(static_cast(rNode), pFrame->GetMergedPara(), pFrame->IsRightToLeft()); TextFrameIndex const iPrevPos(pFrame->MapModelToView( &static_cast(rNode), nPrevPos)); nLevel = aScriptInfo.DirType( iPrevPos ); } else { if (TextFrameIndex(COMPLETE_STRING) != pSI->GetInvalidityA()) { // mystery why this doesn't use the other overload? pSI->InitScriptInfo(static_cast(rNode), pFrame->GetMergedPara()); } TextFrameIndex const iPrevPos(pFrame->MapModelToView( &static_cast(rNode), nPrevPos)); nLevel = pSI->DirType(iPrevPos); } pTmpCursor->SetCursorBidiLevel( nLevel ); } } SetInFrontOfLabel( false ); // #i27615# EndAllAction(); } void SwEditShell::Overwrite(const OUString &rStr) { StartAllAction(); for(SwPaM& rPaM : GetCursor()->GetRingContainer()) { if( !GetDoc()->getIDocumentContentOperations().Overwrite(rPaM, rStr ) ) { OSL_FAIL( "Doc->getIDocumentContentOperations().Overwrite(Str) failed." ); } SaveTableBoxContent( rPaM.GetPoint() ); } EndAllAction(); } void SwEditShell::SplitNode( bool bAutoFormat, bool bCheckTableStart ) { StartAllAction(); GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr); for(SwPaM& rPaM : GetCursor()->GetRingContainer()) { // Here, a table cell becomes a normal text cell. GetDoc()->ClearBoxNumAttrs( rPaM.GetPoint()->nNode ); GetDoc()->getIDocumentContentOperations().SplitNode( *rPaM.GetPoint(), bCheckTableStart ); } GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr); if( bAutoFormat ) AutoFormatBySplitNode(); ClearTableBoxContent(); EndAllAction(); } bool SwEditShell::AppendTextNode() { bool bRet = false; StartAllAction(); GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr); for(SwPaM& rPaM : GetCursor()->GetRingContainer()) { GetDoc()->ClearBoxNumAttrs( rPaM.GetPoint()->nNode ); bRet = GetDoc()->getIDocumentContentOperations().AppendTextNode( *rPaM.GetPoint()) || bRet; } GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr); ClearTableBoxContent(); EndAllAction(); return bRet; } // the returned SwGrfNode pointer is used in GetGraphic() and GetGraphicSize() SwGrfNode * SwEditShell::GetGrfNode_() const { SwGrfNode *pGrfNode = nullptr; SwPaM* pCursor = GetCursor(); if( !pCursor->HasMark() || pCursor->GetPoint()->nNode == pCursor->GetMark()->nNode ) pGrfNode = pCursor->GetPoint()->nNode.GetNode().GetGrfNode(); return pGrfNode; } // returns a Graphic pointer if CurrentCursor->GetPoint() points to a SwGrfNode and // GetMark is not set or points to the same Graphic const Graphic* SwEditShell::GetGraphic( bool bWait ) const { SwGrfNode* pGrfNode = GetGrfNode_(); const Graphic* pGrf( nullptr ); if ( pGrfNode ) { pGrf = &(pGrfNode->GetGrf(bWait && GraphicType::Default == pGrfNode->GetGrf().GetType())); } return pGrf; } bool SwEditShell::IsLinkedGrfSwapOut() const { SwGrfNode *pGrfNode = GetGrfNode_(); return pGrfNode && pGrfNode->IsLinkedFile() && GraphicType::Default == pGrfNode->GetGrfObj().GetType(); } const GraphicObject* SwEditShell::GetGraphicObj() const { SwGrfNode* pGrfNode = GetGrfNode_(); return pGrfNode ? &(pGrfNode->GetGrfObj()) : nullptr; } const GraphicAttr* SwEditShell::GetGraphicAttr( GraphicAttr& rGA ) const { SwGrfNode* pGrfNode = GetGrfNode_(); const SwFrame* pFrame = GetCurrFrame(false); return pGrfNode ? &(pGrfNode->GetGraphicAttr( rGA, pFrame )) : nullptr; } GraphicType SwEditShell::GetGraphicType() const { SwGrfNode *pGrfNode = GetGrfNode_(); return pGrfNode ? pGrfNode->GetGrfObj().GetType() : GraphicType::NONE; } // returns the size of a graphic in if CurrentCursor->GetPoint() points to a SwGrfNode and // GetMark is not set or points to the same graphic bool SwEditShell::GetGrfSize(Size& rSz) const { SwNoTextNode* pNoTextNd; SwPaM* pCurrentCursor = GetCursor(); if( ( !pCurrentCursor->HasMark() || pCurrentCursor->GetPoint()->nNode == pCurrentCursor->GetMark()->nNode ) && nullptr != ( pNoTextNd = pCurrentCursor->GetNode().GetNoTextNode() ) ) { rSz = pNoTextNd->GetTwipSize(); return true; } return false; } /// Read again if graphic is not OK and replace old one void SwEditShell::ReRead( const OUString& rGrfName, const OUString& rFltName, const Graphic* pGraphic ) { StartAllAction(); mxDoc->getIDocumentContentOperations().ReRead( *GetCursor(), rGrfName, rFltName, pGraphic ); EndAllAction(); } /// Returns the name and the filter name of a graphic if the pointer is on a graphic. /// If a String-pointer is != 0 then return corresponding name. void SwEditShell::GetGrfNms( OUString* pGrfName, OUString* pFltName, const SwFlyFrameFormat* pFormat ) const { OSL_ENSURE( pGrfName || pFltName, "No parameters" ); if( pFormat ) SwDoc::GetGrfNms( *pFormat, pGrfName, pFltName ); else { SwGrfNode *pGrfNode = GetGrfNode_(); if( pGrfNode && pGrfNode->IsLinkedFile() ) pGrfNode->GetFileFilterNms( pGrfName, pFltName ); } } const tools::PolyPolygon *SwEditShell::GetGraphicPolygon() const { SwNoTextNode *pNd = GetCursor()->GetNode().GetNoTextNode(); return pNd->HasContour(); } void SwEditShell::SetGraphicPolygon( const tools::PolyPolygon *pPoly ) { SwNoTextNode *pNd = GetCursor()->GetNode().GetNoTextNode(); StartAllAction(); pNd->SetContour( pPoly ); SwFlyFrame *pFly = static_cast(pNd->getLayoutFrame(GetLayout())->GetUpper()); const SwFormatSurround &rSur = pFly->GetFormat()->GetSurround(); pFly->GetFormat()->NotifyClients( &rSur, &rSur ); GetDoc()->getIDocumentState().SetModified(); EndAllAction(); } void SwEditShell::ClearAutomaticContour() { SwNoTextNode *pNd = GetCursor()->GetNode().GetNoTextNode(); OSL_ENSURE( pNd, "is no NoTextNode!" ); if( pNd->HasAutomaticContour() ) { StartAllAction(); pNd->SetContour( nullptr ); SwFlyFrame *pFly = static_cast(pNd->getLayoutFrame(GetLayout())->GetUpper()); const SwFormatSurround &rSur = pFly->GetFormat()->GetSurround(); pFly->GetFormat()->NotifyClients( &rSur, &rSur ); GetDoc()->getIDocumentState().SetModified(); EndAllAction(); } } /** Get OLE object at pointer. * * Returns a pointer to a SvInPlaceObjectRef if CurrentCursor->GetPoint() points to a SwOLENode and * GetMark is not set or points to the same object reference. Gets this pointer from the Doc * if the object should be searched by name. */ svt::EmbeddedObjectRef& SwEditShell::GetOLEObject() const { OSL_ENSURE( CNT_OLE == GetCntType(), "GetOLEObj: no OLENode." ); OSL_ENSURE( !GetCursor()->HasMark() || (GetCursor()->HasMark() && GetCursor()->GetPoint()->nNode == GetCursor()->GetMark()->nNode), "GetOLEObj: no OLENode." ); SwOLENode *pOLENode = GetCursor()->GetNode().GetOLENode(); OSL_ENSURE( pOLENode, "GetOLEObj: no OLENode." ); SwOLEObj& rOObj = pOLENode->GetOLEObj(); return rOObj.GetObject(); } bool SwEditShell::HasOLEObj( const OUString &rName ) const { SwStartNode *pStNd; SwNodeIndex aIdx( *GetNodes().GetEndOfAutotext().StartOfSectionNode(), 1 ); while ( nullptr != (pStNd = aIdx.GetNode().GetStartNode()) ) { ++aIdx; SwNode& rNd = aIdx.GetNode(); if( rNd.IsOLENode() && rName == static_cast(rNd).GetChartTableName() && static_cast(rNd).getLayoutFrame( GetLayout() ) ) return true; aIdx.Assign( *pStNd->EndOfSectionNode(), + 1 ); } return false; } void SwEditShell::SetChartName( const OUString &rName ) { SwOLENode *pONd = GetCursor()->GetNode().GetOLENode(); OSL_ENSURE( pONd, "ChartNode not found" ); pONd->SetChartTableName( rName ); } void SwEditShell::UpdateCharts( const OUString &rName ) { GetDoc()->UpdateCharts( rName ); } /// change table name void SwEditShell::SetTableName( SwFrameFormat& rTableFormat, const OUString &rNewName ) { GetDoc()->SetTableName( rTableFormat, rNewName ); } /// request current word OUString SwEditShell::GetCurWord() const { const SwPaM& rPaM = *GetCursor(); const SwTextNode* pNd = rPaM.GetNode().GetTextNode(); if (!pNd) { return OUString(); } SwTextFrame const*const pFrame(static_cast(pNd->getLayoutFrame(GetLayout()))); if (pFrame) { return pFrame->GetCurWord(*rPaM.GetPoint()); } return OUString(); } void SwEditShell::UpdateDocStat( ) { StartAllAction(); GetDoc()->getIDocumentStatistics().UpdateDocStat( false, true ); EndAllAction(); } const SwDocStat& SwEditShell::GetUpdatedDocStat() { StartAllAction(); const SwDocStat &rRet = GetDoc()->getIDocumentStatistics().GetUpdatedDocStat( false, true ); EndAllAction(); return rRet; } /// get the reference of a given name in the Doc const SwFormatRefMark* SwEditShell::GetRefMark( const OUString& rName ) const { return GetDoc()->GetRefMark( rName ); } /// get the names of all references in a Doc sal_uInt16 SwEditShell::GetRefMarks( std::vector* pStrings ) const { return GetDoc()->GetRefMarks( pStrings ); } OUString SwEditShell::GetDropText( const sal_Int32 nChars ) const { /* * pb: made changes for #i74939# * * always return a string even though there is a selection */ OUString aText; SwPaM* pCursor = GetCursor(); if ( IsMultiSelection() ) { // if a multi selection exists, search for the first line // -> it is the cursor with the lowest index sal_uLong nIndex = pCursor->GetMark()->nNode.GetIndex(); bool bPrev = true; SwPaM* pLast = pCursor; SwPaM* pTemp = pCursor; while ( bPrev ) { SwPaM* pPrev2 = pTemp->GetPrev(); bPrev = ( pPrev2 && pPrev2 != pLast ); if ( bPrev ) { pTemp = pPrev2; sal_uLong nTemp = pPrev2->GetMark()->nNode.GetIndex(); if ( nTemp < nIndex ) { nIndex = nTemp; pCursor = pPrev2; } } } } SwTextNode const*const pTextNd = pCursor->GetNode(false).GetTextNode(); if( pTextNd ) { SwTextFrame const*const pTextFrame(static_cast( pTextNd->getLayoutFrame(GetLayout()))); SAL_WARN_IF(!pTextFrame, "sw.core", "GetDropText cursor has no frame?"); if (pTextFrame) { TextFrameIndex const nDropLen(pTextFrame->GetDropLen(TextFrameIndex(nChars))); aText = pTextFrame->GetText().copy(0, sal_Int32(nDropLen)); } } return aText; } void SwEditShell::ReplaceDropText( const OUString &rStr, SwPaM* pPaM ) { SwPaM* pCursor = pPaM ? pPaM : GetCursor(); if( !(pCursor->GetPoint()->nNode == pCursor->GetMark()->nNode && pCursor->GetNode().GetTextNode()->IsTextNode()) ) return; StartAllAction(); const SwNodeIndex& rNd = pCursor->GetPoint()->nNode; SwPaM aPam( rNd, rStr.getLength(), rNd, 0 ); SwTextFrame const*const pTextFrame(static_cast( rNd.GetNode().GetTextNode()->getLayoutFrame(GetLayout()))); if (pTextFrame) { *aPam.GetPoint() = pTextFrame->MapViewToModelPos(TextFrameIndex(0)); *aPam.GetMark() = pTextFrame->MapViewToModelPos(TextFrameIndex( std::min(rStr.getLength(), pTextFrame->GetText().getLength()))); } if( !GetDoc()->getIDocumentContentOperations().Overwrite( aPam, rStr ) ) { OSL_FAIL( "Doc->getIDocumentContentOperations().Overwrite(Str) failed." ); } EndAllAction(); } OUString SwEditShell::Calculate() { OUStringBuffer aFormel; // the final formula SwCalc aCalc( *GetDoc() ); const CharClass& rCC = GetAppCharClass(); for(SwPaM& rCurrentPaM : GetCursor()->GetNext()->GetRingContainer()) { SwTextNode* pTextNd = rCurrentPaM.GetNode().GetTextNode(); if(pTextNd) { const SwPosition *pStart = rCurrentPaM.Start(), *pEnd = rCurrentPaM.End(); const sal_Int32 nStt = pStart->nContent.GetIndex(); OUString aStr = pTextNd->GetExpandText(GetLayout(), nStt, pEnd->nContent.GetIndex() - nStt); aStr = rCC.lowercase( aStr ); bool bValidFields = false; sal_Int32 nPos = 0; while( nPos < aStr.getLength() ) { sal_Unicode ch = aStr[ nPos++ ]; if( rCC.isLetter( aStr, nPos-1 ) || ch == '_' ) { sal_Int32 nTmpStt = nPos-1; while( nPos < aStr.getLength() && 0 != ( ch = aStr[ nPos++ ]) && (rCC.isLetterNumeric( aStr, nPos - 1 ) || ch == '_'|| ch == '.' )) ; if( nPos < aStr.getLength() ) --nPos; OUString sVar = aStr.copy( nTmpStt, nPos - nTmpStt ); if( !::FindOperator( sVar ) && (aCalc.GetVarTable().Find(sVar) || aCalc.VarLook( sVar )) ) { if( !bValidFields ) { GetDoc()->getIDocumentFieldsAccess().FieldsToCalc( aCalc, pStart->nNode.GetIndex(), pStart->nContent.GetIndex() ); bValidFields = true; } aFormel.append("(").append(aCalc.GetStrResult( aCalc.VarLook( sVar )->nValue )).append(")"); } else aFormel.append(sVar); } else aFormel.append(ch); } } } return aCalc.GetStrResult( aCalc.Calculate(aFormel.makeStringAndClear()) ); } sfx2::LinkManager& SwEditShell::GetLinkManager() { return mxDoc->getIDocumentLinksAdministration().GetLinkManager(); } void *SwEditShell::GetIMapInventor() const { // The node on which the cursor points should be sufficient as a unique identifier return static_cast(&(GetCursor()->GetNode())); } // #i73788# Graphic SwEditShell::GetIMapGraphic() const { // returns always a graphic if the cursor is in a Fly CurrShell aCurr( const_cast(this) ); Graphic aRet; SwPaM* pCursor = GetCursor(); if ( !pCursor->HasMark() ) { SwNode& rNd =pCursor->GetNode(); if( rNd.IsGrfNode() ) { SwGrfNode & rGrfNode(static_cast(rNd)); aRet = rGrfNode.GetGrf(GraphicType::Default == rGrfNode.GetGrf().GetType()); } else if ( rNd.IsOLENode() ) { if (const Graphic* pGraphic = static_cast(rNd).GetGraphic()) aRet = *pGraphic; } else { SwFlyFrame* pFlyFrame = rNd.GetContentNode()->getLayoutFrame( GetLayout() )->FindFlyFrame(); if(pFlyFrame) aRet = pFlyFrame->GetFormat()->MakeGraphic(); } } return aRet; } bool SwEditShell::InsertURL( const SwFormatINetFormat& rFormat, const OUString& rStr, bool bKeepSelection ) { // URL and hint text (directly or via selection) necessary if( rFormat.GetValue().isEmpty() || ( rStr.isEmpty() && !HasSelection() ) ) return false; StartAllAction(); GetDoc()->GetIDocumentUndoRedo().StartUndo( SwUndoId::UI_INSERT_URLTXT, nullptr); bool bInsText = true; if( !rStr.isEmpty() ) { SwPaM* pCursor = GetCursor(); if( pCursor->HasMark() && *pCursor->GetPoint() != *pCursor->GetMark() ) { // Selection existent, multi selection? bool bDelText = true; if( !pCursor->IsMultiSelection() ) { // simple selection -> check the text const OUString sText(comphelper::string::stripEnd(GetSelText(), ' ')); if( sText == rStr ) bDelText = bInsText = false; } else if( rFormat.GetValue() == rStr ) // Are Name and URL equal? bDelText = bInsText = false; if( bDelText ) Delete(); } else if( pCursor->IsMultiSelection() && rFormat.GetValue() == rStr ) bInsText = false; if( bInsText ) { Insert2( rStr ); SetMark(); ExtendSelection( false, rStr.getLength() ); } } else bInsText = false; SetAttrItem( rFormat ); if (bInsText && !IsCursorPtAtEnd()) SwapPam(); if(!bKeepSelection) ClearMark(); if( bInsText ) DontExpandFormat(); GetDoc()->GetIDocumentUndoRedo().EndUndo( SwUndoId::UI_INSERT_URLTXT, nullptr ); EndAllAction(); return true; } void SwEditShell::GetINetAttrs( SwGetINetAttrs& rArr ) { rArr.clear(); const SwCharFormats* pFormats = GetDoc()->GetCharFormats(); for( auto n = pFormats->size(); 1 < n; ) { SwIterator aIter(*(*pFormats)[--n]); for( SwTextINetFormat* pFnd = aIter.First(); pFnd; pFnd = aIter.Next() ) { SwTextNode const*const pTextNd(pFnd->GetpTextNode()); SwTextFrame const*const pFrame(pTextNd ? static_cast(pTextNd->getLayoutFrame(GetLayout())) : nullptr); if (nullptr != pTextNd && nullptr != pFrame && pTextNd->GetNodes().IsDocNodes() // check it's not fully deleted && pFrame->MapModelToView(pTextNd, pFnd->GetStart()) != pFrame->MapModelToView(pTextNd, *pFnd->GetEnd())) { SwTextINetFormat& rAttr = *pFnd; OUString sText( pTextNd->GetExpandText(GetLayout(), rAttr.GetStart(), *rAttr.GetEnd() - rAttr.GetStart()) ); sText = sText.replaceAll("\x0a", ""); sText = comphelper::string::strip(sText, ' '); if( !sText.isEmpty() ) { rArr.emplace_back(sText, rAttr); } } } } } /// If the cursor is in an INetAttribute then it will be deleted completely (incl. hint text, the /// latter is needed for drag & drop) void SwEditShell::DelINetAttrWithText() { bool bRet = SelectTextAttr( RES_TXTATR_INETFMT, false ); if( bRet ) DeleteSel( *GetCursor() ); } /// Set the DontExpand flag at the text character attributes bool SwEditShell::DontExpandFormat() { bool bRet = false; if( !IsTableMode() && GetDoc()->DontExpandFormat( *GetCursor()->GetPoint() )) { bRet = true; CallChgLnk(); } return bRet; } SvNumberFormatter* SwEditShell::GetNumberFormatter() { return GetDoc()->GetNumberFormatter(); } bool SwEditShell::ConvertFieldsToText() { StartAllAction(); bool bRet = GetDoc()->ConvertFieldsToText(*GetLayout()); EndAllAction(); return bRet; } void SwEditShell::SetNumberingRestart() { StartAllAction(); Push(); // iterate over all text contents - body, frames, header, footer, footnote text SwPaM* pCursor = GetCursor(); for(int i = 0; i < 2; i++) { if(!i) MakeFindRange(SwDocPositions::Start, SwDocPositions::End, pCursor); // body content else MakeFindRange(SwDocPositions::OtherStart, SwDocPositions::OtherEnd, pCursor); // extra content SwPosition* pSttPos = pCursor->Start(), *pEndPos = pCursor->End(); sal_uLong nCurrNd = pSttPos->nNode.GetIndex(); sal_uLong nEndNd = pEndPos->nNode.GetIndex(); if( nCurrNd <= nEndNd ) { SwContentFrame* pContentFrame; bool bGoOn = true; // iterate over all paragraphs while( bGoOn ) { SwNode* pNd = GetDoc()->GetNodes()[ nCurrNd ]; switch( pNd->GetNodeType() ) { case SwNodeType::Text: pContentFrame = static_cast(pNd)->getLayoutFrame( GetLayout() ); if( nullptr != pContentFrame ) { // skip hidden frames - ignore protection! if( !static_cast(pContentFrame)->IsHiddenNow() ) { // if the node is numbered and the starting value of the numbering equals the // start value of the numbering rule then set this value as hard starting value // get the node num // OD 2005-11-09 SwTextNode* pTextNd( pNd->GetTextNode() ); SwNumRule* pNumRule( pTextNd->GetNumRule() ); // sw_redlinehide: not sure what this should do, only called from mail-merge bool bIsNodeNum = ( pNumRule && pTextNd->GetNum() && ( pTextNd->HasNumber() || pTextNd->HasBullet() ) && pTextNd->IsCountedInList() && !pTextNd->IsListRestart() ); if (bIsNodeNum) { int nListLevel = pTextNd->GetActualListLevel(); if (nListLevel < 0) nListLevel = 0; if (nListLevel >= MAXLEVEL) nListLevel = MAXLEVEL - 1; bIsNodeNum = pTextNd->GetNum()->GetNumber() == pNumRule->Get( static_cast(nListLevel) ).GetStart(); } if (bIsNodeNum) { // now set the start value as attribute SwPosition aCurrentNode(*pNd); GetDoc()->SetNumRuleStart( aCurrentNode ); } } } break; case SwNodeType::Section: // skip hidden sections - ignore protection! if(static_cast(pNd)->GetSection().IsHidden() ) nCurrNd = pNd->EndOfSectionIndex(); break; default: break; } bGoOn = nCurrNd < nEndNd; ++nCurrNd; } } } Pop(PopMode::DeleteCurrent); EndAllAction(); } sal_uInt16 SwEditShell::GetLineCount() { sal_uInt16 nRet = 0; CalcLayout(); SwPaM* pPam = GetCursor(); SwNodeIndex& rPtIdx = pPam->GetPoint()->nNode; SwNodeIndex aStart( rPtIdx ); SwContentNode* pCNd; SwContentFrame *pContentFrame = nullptr; aStart = 0; while( nullptr != ( pCNd = GetDoc()->GetNodes().GoNextSection( &aStart, true, false )) ) { if( nullptr != ( pContentFrame = pCNd->getLayoutFrame( GetLayout() ) ) && pContentFrame->IsTextFrame() ) { SwTextFrame *const pFrame(static_cast(pContentFrame)); nRet = nRet + pFrame->GetLineCount(TextFrameIndex(COMPLETE_STRING)); if (GetLayout()->IsHideRedlines()) { if (auto const*const pMerged = pFrame->GetMergedPara()) { aStart = *pMerged->pLastNode; } } } } return nRet; } tools::Long SwEditShell::CompareDoc( const SwDoc& rDoc ) { StartAllAction(); tools::Long nRet = GetDoc()->CompareDoc( rDoc ); EndAllAction(); return nRet; } tools::Long SwEditShell::MergeDoc( const SwDoc& rDoc ) { StartAllAction(); tools::Long nRet = GetDoc()->MergeDoc( rDoc ); EndAllAction(); return nRet; } const SwFootnoteInfo& SwEditShell::GetFootnoteInfo() const { return GetDoc()->GetFootnoteInfo(); } void SwEditShell::SetFootnoteInfo(const SwFootnoteInfo& rInfo) { StartAllAction(); CurrShell aCurr( this ); GetDoc()->SetFootnoteInfo(rInfo); CallChgLnk(); EndAllAction(); } const SwEndNoteInfo& SwEditShell::GetEndNoteInfo() const { return GetDoc()->GetEndNoteInfo(); } void SwEditShell::SetEndNoteInfo(const SwEndNoteInfo& rInfo) { StartAllAction(); CurrShell aCurr( this ); GetDoc()->SetEndNoteInfo(rInfo); EndAllAction(); } const SwLineNumberInfo& SwEditShell::GetLineNumberInfo() const { return GetDoc()->GetLineNumberInfo(); } void SwEditShell::SetLineNumberInfo(const SwLineNumberInfo& rInfo) { StartAllAction(); CurrShell aCurr( this ); GetDoc()->SetLineNumberInfo(rInfo); AddPaintRect( GetLayout()->getFrameArea() ); EndAllAction(); } sal_uInt16 SwEditShell::GetLinkUpdMode() const { return getIDocumentSettingAccess().getLinkUpdateMode( false ); } void SwEditShell::SetLinkUpdMode( sal_uInt16 nMode ) { getIDocumentSettingAccess().setLinkUpdateMode( nMode ); } // Interface for TextInputData - (for text input of japanese/chinese characters) void SwEditShell::CreateExtTextInput(LanguageType eInputLanguage) { SwExtTextInput* pRet = GetDoc()->CreateExtTextInput( *GetCursor() ); pRet->SetLanguage(eInputLanguage); pRet->SetOverwriteCursor( SwCursorShell::IsOverwriteCursor() ); } OUString SwEditShell::DeleteExtTextInput( bool bInsText ) { const SwPosition& rPos = *GetCursor()->GetPoint(); SwExtTextInput* pDel = GetDoc()->GetExtTextInput( rPos.nNode.GetNode(), rPos.nContent.GetIndex() ); if( !pDel ) { //JP 25.10.2001: under UNIX the cursor is moved before the Input- // Engine event comes in. So take any - normally there // exist only one at the time. -- Task 92016 pDel = GetDoc()->GetExtTextInput(); } OUString sRet; if( pDel ) { OUString sTmp; SwUnoCursorHelper::GetTextFromPam(*pDel, sTmp); sRet = sTmp; CurrShell aCurr( this ); StartAllAction(); pDel->SetInsText( bInsText ); SetOverwriteCursor( pDel->IsOverwriteCursor() ); const SwPosition aPos( *pDel->GetPoint() ); GetDoc()->DeleteExtTextInput( pDel ); // In this case, the "replace" function did not set the cursor // to the original position. Therefore we have to do this manually. if ( ! bInsText && IsOverwriteCursor() ) *GetCursor()->GetPoint() = aPos; EndAllAction(); } return sRet; } void SwEditShell::SetExtTextInputData( const CommandExtTextInputData& rData ) { SwPaM* pCurrentCursor = GetCursor(); const SwPosition& rPos = *pCurrentCursor->GetPoint(); SwExtTextInput* pInput = GetDoc()->GetExtTextInput( rPos.nNode.GetNode() ); if( !pInput ) return; StartAllAction(); CurrShell aCurr( this ); if( !rData.IsOnlyCursorChanged() ) pInput->SetInputData( rData ); // position cursor const SwPosition& rStt = *pInput->Start(); const sal_Int32 nNewCursorPos = rStt.nContent.GetIndex() + rData.GetCursorPos(); // ugly but works ShowCursor(); const sal_Int32 nDiff = nNewCursorPos - rPos.nContent.GetIndex(); if( nDiff != 0) { bool bLeft = nDiff < 0; sal_Int32 nMaxGuard = std::abs(nDiff); while (true) { auto nOldPos = pCurrentCursor->GetPoint()->nContent.GetIndex(); if (bLeft) Left(1, CRSR_SKIP_CHARS); else Right(1, CRSR_SKIP_CHARS); auto nNewPos = pCurrentCursor->GetPoint()->nContent.GetIndex(); // expected success if (nNewPos == nNewCursorPos) break; if (nNewPos == nOldPos) { // if there was no movement, we have failed for some reason SAL_WARN("sw.core", "IM cursor move failed"); break; } if (--nMaxGuard == 0) { // if it takes more cursor moves than there are utf-16 chars to move past // something has probably gone wrong SAL_WARN("sw.core", "IM abandoning cursor positioning"); break; } } } SetOverwriteCursor( rData.IsCursorOverwrite() ); EndAllAction(); if( !rData.IsCursorVisible() ) // must be called after the EndAction HideCursor(); } void SwEditShell::TransliterateText( TransliterationFlags nType ) { utl::TransliterationWrapper aTrans( ::comphelper::getProcessComponentContext(), nType ); StartAllAction(); CurrShell aCurr( this ); SwPaM* pCursor = GetCursor(); if( pCursor->GetNext() != pCursor ) { GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr); for(const SwPaM& rPaM : GetCursor()->GetRingContainer()) { if( rPaM.HasMark() ) GetDoc()->getIDocumentContentOperations().TransliterateText( rPaM, aTrans ); } GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr); } else GetDoc()->getIDocumentContentOperations().TransliterateText( *pCursor, aTrans ); EndAllAction(); } void SwEditShell::CountWords( SwDocStat& rStat ) const { for(const SwPaM& rPaM : GetCursor()->GetRingContainer()) { if( rPaM.HasMark() ) SwDoc::CountWords( rPaM, rStat ); } } void SwEditShell::ApplyViewOptions( const SwViewOption &rOpt ) { SwCursorShell::StartAction(); SwViewShell::ApplyViewOptions( rOpt ); SwEditShell::EndAction(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */