summaryrefslogtreecommitdiffstats
path: root/sw/source/core/edit/editsh.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/edit/editsh.cxx')
-rw-r--r--sw/source/core/edit/editsh.cxx1056
1 files changed, 1056 insertions, 0 deletions
diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
new file mode 100644
index 000000000..0b932fba1
--- /dev/null
+++ b/sw/source/core/edit/editsh.cxx
@@ -0,0 +1,1056 @@
+/* -*- 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 <hintids.hxx>
+#include <vcl/commandevent.hxx>
+#include <unotools/charclass.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <unotools/transliterationwrapper.hxx>
+#include <fmtsrnd.hxx>
+#include <fmtinfmt.hxx>
+#include <txtinet.hxx>
+#include <frmfmt.hxx>
+#include <charfmt.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <IDocumentSettingAccess.hxx>
+#include <IDocumentLinksAdministration.hxx>
+#include <IDocumentFieldsAccess.hxx>
+#include <IDocumentStatistics.hxx>
+#include <IDocumentState.hxx>
+#include <docary.hxx>
+#include <editsh.hxx>
+#include <frame.hxx>
+#include <cntfrm.hxx>
+#include <pam.hxx>
+#include <ndtxt.hxx>
+#include <flyfrm.hxx>
+#include <swundo.hxx>
+#include <calc.hxx>
+#include <ndgrf.hxx>
+#include <ndole.hxx>
+#include <txtfrm.hxx>
+#include <rootfrm.hxx>
+#include <extinput.hxx>
+#include <scriptinfo.hxx>
+#include <unocrsrhelper.hxx>
+#include <section.hxx>
+#include <numrule.hxx>
+#include <SwNodeNum.hxx>
+#include <unocrsr.hxx>
+#include <calbck.hxx>
+
+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<SwUnoCursor*>(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<SwTextNode&>(rNode), &pFrame, true);
+
+ sal_uInt8 nLevel = 0;
+ if ( ! pSI )
+ {
+ // seems to be an empty paragraph.
+ Point aPt;
+ std::pair<Point, bool> const tmp(aPt, false);
+ pFrame = static_cast<SwTextFrame*>(
+ static_cast<SwTextNode&>(rNode).getLayoutFrame(
+ GetLayout(), pTmpCursor->GetPoint(), &tmp));
+
+ SwScriptInfo aScriptInfo;
+ aScriptInfo.InitScriptInfo(static_cast<SwTextNode&>(rNode),
+ pFrame->GetMergedPara(), pFrame->IsRightToLeft());
+ TextFrameIndex const iPrevPos(pFrame->MapModelToView(
+ &static_cast<SwTextNode&>(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<SwTextNode&>(rNode), pFrame->GetMergedPara());
+ }
+ TextFrameIndex const iPrevPos(pFrame->MapModelToView(
+ &static_cast<SwTextNode&>(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 <rSz> 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<SwFlyFrame*>(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<SwFlyFrame*>(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<SwOLENode&>(rNd).GetChartTableName() &&
+ static_cast<SwOLENode&>(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<SwTextFrame*>(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<OUString>* 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<SwTextFrame const*>(
+ 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() )
+ {
+ StartAllAction();
+
+ const SwNodeIndex& rNd = pCursor->GetPoint()->nNode;
+ SwPaM aPam( rNd, rStr.getLength(), rNd, 0 );
+ SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(
+ 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<void*>(&(GetCursor()->GetNode()));
+}
+
+// #i73788#
+Graphic SwEditShell::GetIMapGraphic() const
+{
+ // returns always a graphic if the cursor is in a Fly
+ SET_CURR_SHELL( const_cast<SwEditShell*>(this) );
+ Graphic aRet;
+ SwPaM* pCursor = GetCursor();
+ if ( !pCursor->HasMark() )
+ {
+ SwNode& rNd =pCursor->GetNode();
+ if( rNd.IsGrfNode() )
+ {
+ SwGrfNode & rGrfNode(static_cast<SwGrfNode&>(rNd));
+ aRet = rGrfNode.GetGrf(GraphicType::Default == rGrfNode.GetGrf().GetType());
+ }
+ else if ( rNd.IsOLENode() )
+ {
+ if (const Graphic* pGraphic = static_cast<SwOLENode&>(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<SwTextINetFormat,SwCharFormat> 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<SwTextFrame const*>(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:
+ if( nullptr != ( pContentFrame = static_cast<SwTextNode*>(pNd)->getLayoutFrame( GetLayout() )) )
+ {
+ // skip hidden frames - ignore protection!
+ if( !static_cast<SwTextFrame*>(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<sal_uInt16>(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<SwSectionNode*>(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<SwTextFrame*>(pContentFrame));
+ nRet = nRet + pFrame->GetLineCount(TextFrameIndex(COMPLETE_STRING));
+ if (GetLayout()->IsHideRedlines())
+ {
+ if (auto const*const pMerged = pFrame->GetMergedPara())
+ {
+ aStart = *pMerged->pLastNode;
+ }
+ }
+ }
+ }
+ return nRet;
+}
+
+long SwEditShell::CompareDoc( const SwDoc& rDoc )
+{
+ StartAllAction();
+ long nRet = GetDoc()->CompareDoc( rDoc );
+ EndAllAction();
+ return nRet;
+}
+
+long SwEditShell::MergeDoc( const SwDoc& rDoc )
+{
+ StartAllAction();
+ long nRet = GetDoc()->MergeDoc( rDoc );
+ EndAllAction();
+ return nRet;
+}
+
+const SwFootnoteInfo& SwEditShell::GetFootnoteInfo() const
+{
+ return GetDoc()->GetFootnoteInfo();
+}
+
+void SwEditShell::SetFootnoteInfo(const SwFootnoteInfo& rInfo)
+{
+ StartAllAction();
+ SET_CURR_SHELL( this );
+ GetDoc()->SetFootnoteInfo(rInfo);
+ CallChgLnk();
+ EndAllAction();
+}
+
+const SwEndNoteInfo& SwEditShell::GetEndNoteInfo() const
+{
+ return GetDoc()->GetEndNoteInfo();
+}
+
+void SwEditShell::SetEndNoteInfo(const SwEndNoteInfo& rInfo)
+{
+ StartAllAction();
+ SET_CURR_SHELL( this );
+ GetDoc()->SetEndNoteInfo(rInfo);
+ EndAllAction();
+}
+
+const SwLineNumberInfo& SwEditShell::GetLineNumberInfo() const
+{
+ return GetDoc()->GetLineNumberInfo();
+}
+
+void SwEditShell::SetLineNumberInfo(const SwLineNumberInfo& rInfo)
+{
+ StartAllAction();
+ SET_CURR_SHELL( 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;
+ SET_CURR_SHELL( 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 )
+{
+ const SwPosition& rPos = *GetCursor()->GetPoint();
+ SwExtTextInput* pInput = GetDoc()->GetExtTextInput( rPos.nNode.GetNode() );
+ if( !pInput )
+ return;
+
+ StartAllAction();
+ SET_CURR_SHELL( 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( 0 > nDiff )
+ Left( -nDiff, CRSR_SKIP_CHARS );
+ else if( 0 < nDiff )
+ Right( nDiff, CRSR_SKIP_CHARS );
+
+ 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();
+ SET_CURR_SHELL( 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: */