Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sw/source/uibase/wrtsh/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 100 kB image not shown  

Quelle  wrtsh1.cxx   Sprache: C

 
/* -*- 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 <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/embed/EmbedMisc.hpp>
#include <com/sun/star/embed/EmbedStates.hpp>
#include <com/sun/star/embed/EmbedVerbs.hpp>
#include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/lang/XInitialization.hpp>

#include <hintids.hxx>
#include <sot/exchange.hxx>
#include <svx/xfillit0.hxx>
#include <svx/hdft.hxx>
#include <svx/svdview.hxx>
#include <svl/itemiter.hxx>
#include <tools/bigint.hxx>
#include <svtools/insdlg.hxx>
#include <sfx2/ipclient.hxx>
#include <editeng/editeng.hxx>
#include <editeng/editobj.hxx>
#include <editeng/formatbreakitem.hxx>
#include <editeng/svxacorr.hxx>
#include <editeng/ulspitem.hxx>
#include <vcl/graph.hxx>
#include <unotools/charclass.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/random.hxx>
#include <svx/svxdlg.hxx>
#include <svx/extrusionbar.hxx>
#include <svx/fontworkbar.hxx>
#include <dialoghelp.hxx>
#include <frmfmt.hxx>
#include <fmtftn.hxx>
#include <fmthdft.hxx>
#include <fmtpdsc.hxx>
#include <txtfrm.hxx>
#include <wdocsh.hxx>
#include <swmodule.hxx>
#include <wrtsh.hxx>
#include <view.hxx>
#include <cmdid.h>
#include <pagedesc.hxx>
#include <frmmgr.hxx>
#include <swundo.hxx>
#include <swcli.hxx>
#include <poolfmt.hxx>
#include <postithelper.hxx>
#include <edtwin.hxx>
#include <fmtcol.hxx>
#include <swtable.hxx>
#include <viscrs.hxx>
#include <swdtflvr.hxx>
#include <doc.hxx>
#include <IDocumentSettingAccess.hxx>
#include <SwCapObjType.hxx>
#include <SwStyleNameMapper.hxx>
#include <sfx2/request.hxx>
#include <paratr.hxx>
#include <ndtxt.hxx>
#include <editeng/acorrcfg.hxx>
#include <IMark.hxx>
#include <sfx2/bindings.hxx>
#include <flyfrm.hxx>

// -> #111827#
#include <SwRewriter.hxx>
#include <strings.hrc>
// <- #111827#

#include <toolkit/helper/vclunohelper.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/uitest/logger.hxx>
#include <vcl/uitest/eventdescription.hxx>
#include <osl/diagnose.h>
#include <o3tl/unit_conversion.hxx>
#include <officecfg/Office/Common.hxx>

#include <PostItMgr.hxx>
#include <FrameControlsManager.hxx>
#include <fldmgr.hxx>
#include <docufld.hxx>
#include <IDocumentFieldsAccess.hxx>
#include <fmtfld.hxx>

#include <sfx2/msgpool.hxx>
#include <sfx2/msg.hxx>
#include <svtools/embedhlp.hxx>
#include <svtools/strings.hrc>
#include <svtools/svtresid.hxx>
#include <svx/postattr.hxx>
#include <comphelper/lok.hxx>
#include <comphelper/propertyvalue.hxx>
#include <svtools/optionsdrawinglayer.hxx>
#include <svl/numformat.hxx>
#include <svl/zformat.hxx>
#include <memory>

#include "../../core/crsr/callnk.hxx"
#include <frmtool.hxx>
#include <viewopt.hxx>

#include <IDocumentRedlineAccess.hxx>
#include <IDocumentUndoRedo.hxx>
#include <UndoInsert.hxx>
#include <UndoCore.hxx>
#include <formatlinebreak.hxx>
#include <formatcontentcontrol.hxx>
#include <textcontentcontrol.hxx>

using namespace sw::mark;
using namespace com::sun::star;
namespace {

void collectUIInformation(const OUString& rAction, const OUString& aParameters)
{
    EventDescription aDescription;
    aDescription.aAction = rAction;
    aDescription.aParameters = {{"parameters", aParameters}};
    aDescription.aID = "writer_edit";
    aDescription.aKeyWord = "SwEditWinUIObject";
    aDescription.aParent = "MainWindow";
    UITestLogger::getInstance().logEvent(aDescription);
}

}

sal_uInt32 MakeAllOutlineContentTemporarilyVisible::nLock = 0;

static bool lcl_IsAllowed(const SwWrtShell* rSh)
{
    if (rSh->GetViewOptions()->IsShowOutlineContentVisibilityButton() && rSh->IsEndPara())
    {
        SwTextNode* pTextNode = rSh->GetCursor()->GetPointNode().GetTextNode();
        if (pTextNode && pTextNode->IsOutline())
        {
            // disallow if this is an outline node having folded content
            if (!pTextNode->GetAttrOutlineContentVisible())
                return false;
        }
    }
    return true;
}

#define BITFLD_INI_LIST \
        m_bClearMark = \
        m_bIns = true;\
        m_bAddMode = \
        m_bBlockMode = \
        m_bExtMode = \
        m_bInSelect = \
        m_bLayoutMode = \
        m_bSelWrd = \
        m_bSelLn = \
        m_bRetainSelection = false; \
        m_bIsInClickToEdit = false;

static SvxAutoCorrect* lcl_IsAutoCorr()
{
    SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get().GetAutoCorrect();
    if( pACorr && !pACorr->IsAutoCorrFlag( ACFlags::CapitalStartSentence | ACFlags::CapitalStartWord |
                            ACFlags::AddNonBrkSpace | ACFlags::ChgOrdinalNumber | ACFlags::TransliterateRTL |
                            ACFlags::ChgToEnEmDash | ACFlags::SetINetAttr | ACFlags::Autocorrect |
                            ACFlags::SetDOIAttr ))
        pACorr = nullptr;
    return pACorr;
}

void SwWrtShell::NoEdit(bool bHideCursor)
{
    if(bHideCursor)
        HideCursor();
}

void SwWrtShell::Edit()
{
    if (CanInsert())
    {
        ShowCursor();
    }
}

bool SwWrtShell::IsEndWrd()
{
    SwMvContext aMvContext(this);
    if(IsEndPara() && !IsSttPara())
        return true;

    return IsEndWord();
}

// Insert string
void SwWrtShell::InsertByWord( const OUString & rStr)
{
    if( rStr.isEmpty() )
        return;

    bool bDelim = GetAppCharClass().isLetterNumeric( rStr, 0 );
    sal_Int32 nPos = 0, nStt = 0;
    for( ; nPos < rStr.getLength(); nPos++ )
    {
        bool bTmpDelim = GetAppCharClass().isLetterNumeric( rStr, nPos );
        if( bTmpDelim != bDelim )
        {
            Insert( rStr.copy( nStt, nPos - nStt ));
            nStt = nPos;
        }
    }
    if( nStt != nPos )
        Insert( rStr.copy( nStt, nPos - nStt ));
}

void SwWrtShell::Insert( const OUString &rStr )
{
    ResetCursorStack();
    if( !CanInsert() )
        return;

    bool bStarted = false;
    bool bHasSel = HasSelection(),
         bCallIns = m_bIns /*|| bHasSel*/;
    bool bDeleted = false;

    if( bHasSel || ( !m_bIns && IsInHiddenRange(/*bSelect=*/true) ) )
    {
            // Only here parenthesizing, because the normal
            // insert is already in parentheses at Editshell.
        StartAllAction();

        SwRewriter aRewriter;

        aRewriter.AddRule(UndoArg1, GetCursorDescr());
        aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
        {
            OUString aTmpStr = SwResId(STR_START_QUOTE) +
                rStr + SwResId(STR_END_QUOTE);

            aRewriter.AddRule(UndoArg3, aTmpStr);
        }

        StartUndo(SwUndoId::REPLACE, &aRewriter);
        bStarted = true;
        Push();
        // let's interpret a selection within the same node as "replace"
        bDeleted = DelRight(GetCursor()->GetPoint()->GetNode() == GetCursor()->GetMark()->GetNode());
        Pop(SwCursorShell::PopMode::DeleteCurrent); // Restore selection (if tracking changes)
        NormalizePam(false); // tdf#127635 put point at the end of deletion
        ClearMark();
    }

    bCallIns ?
        SwEditShell::Insert2( rStr, bDeleted ) : SwEditShell::Overwrite( rStr );

    // Check whether node is content control
    SwTextContentControl* pTextContentControl = CursorInsideContentControl();
    if (pTextContentControl)
    {
        std::shared_ptr<SwContentControl> pContentControl =
            pTextContentControl->GetContentControl().GetContentControl();
        if (pContentControl)
        {
            // Set showingPlcHdr to false as node has been edited
            pContentControl->SetShowingPlaceHolder(false);
        }
    }

    if( bStarted )
    {
        EndUndo();
        EndAllAction();
    }
}

// Maximum height limit not possible, because the maximum height
// of the current frame can not be obtained.

void SwWrtShell::InsertGraphic( const OUString &rPath, const OUString &rFilter,
                                const Graphic &rGrf, SwFlyFrameAttrMgr *pFrameMgr,
                                RndStdIds nAnchorType )
{
    ResetCursorStack();
    if ( !CanInsert() )
        return;

    StartAllAction();

    SwRewriter aRewriter;
    aRewriter.AddRule(UndoArg1, SwResId(STR_GRAPHIC));

    StartUndo(SwUndoId::INSERT, &aRewriter);

    if ( HasSelection() )
        DelRight();
        // Inserted graphics in its own paragraph,
        // if at the end of a non-empty paragraph.
    //For i120928,avoid to split node

    EnterSelFrameMode();

    bool bSetGrfSize = true;
    bool bOwnMgr     = false;

    if ( !pFrameMgr )
    {
        bOwnMgr = true;
        pFrameMgr = new SwFlyFrameAttrMgr( truethis, Frmmgr_Type::GRF, nullptr );

        // CAUTION
        // GetAttrSet makes an adjustment
        // While pasting is a SwFrameSize present
        // because of the DEF-Framesize
        // These must be removed explicitly for the optimal size.
        pFrameMgr->DelAttr(RES_FRM_SIZE);

        if (nAnchorType != RndStdIds::FLY_AT_PARA)
            // Something other than at-para was requested.
            pFrameMgr->SetAnchor(nAnchorType);
    }
    else
    {
        Size aSz( pFrameMgr->GetSize() );
        if ( !aSz.Width() || !aSz.Height() )
        {
            aSz.setWidth(o3tl::toTwips(1, o3tl::Length::cm));
            aSz.setHeight(o3tl::toTwips(1, o3tl::Length::cm));
            pFrameMgr->SetSize( aSz );
        }
        else if ( aSz.Width() != DFLT_WIDTH && aSz.Height() != DFLT_HEIGHT )
            bSetGrfSize = false;

        pFrameMgr->SetHeightSizeType(SwFrameSize::Fixed);
    }

    // during change tracking, insert the image anchored as character
    // (to create an SwRangeRedline on its anchor point)
    if ( IsRedlineOn() && nAnchorType != RndStdIds::FLY_AS_CHAR )
        pFrameMgr->SetAnchor( RndStdIds::FLY_AS_CHAR );

    // Insert the graphic
    SwFEShell::Insert(rPath, rFilter, &rGrf, &pFrameMgr->GetAttrSet());
    if ( bOwnMgr )
        pFrameMgr->UpdateAttrMgr();

    if( bSetGrfSize )
    {
        Size aSizePixel = rGrf.GetSizePixel();
        Size aBound = GetGraphicDefaultSize();

        sal_Int32 nPreferredDPI = mxDoc->getIDocumentSettingAccess().getImagePreferredDPI();
        Size aGrfSize;

        if (nPreferredDPI > 0)
        {
            auto nWidth = o3tl::toTwips(aSizePixel.Width() / double(nPreferredDPI), o3tl::Length::in);
            auto nHeight = o3tl::toTwips(aSizePixel.Height() / double(nPreferredDPI), o3tl::Length::in);
            aGrfSize = Size(nWidth, nHeight);
        }
        else
        {
            GetGrfSize(aGrfSize);
        }

        // Add the margin attributes to GrfSize,
        // because these counts at the margin additionally
        aGrfSize.AdjustWidth(pFrameMgr->CalcWidthBorder() );
        aGrfSize.AdjustHeight(pFrameMgr->CalcHeightBorder() );

        const BigInt aTempWidth( aGrfSize.Width() );
        const BigInt aTempHeight( aGrfSize.Height());

        // Fit width if necessary, scale down the height proportional thereafter.
        if( aGrfSize.Width() > aBound.Width() )
        {
            aGrfSize.setWidth( aBound.Width() );
            aGrfSize.setHeight( BigInt(aBound.Width()) * aTempHeight / aTempWidth );
        }
        // Fit height if necessary, scale down the width proportional thereafter.
        if( aGrfSize.Height() > aBound.Height() )
        {
            aGrfSize.setHeight( aBound.Height() );
            aGrfSize.setWidth(  BigInt(aBound.Height()) * aTempWidth / aTempHeight );
        }
        pFrameMgr->SetSize( aGrfSize );
        pFrameMgr->UpdateFlyFrame();
    }
    if ( bOwnMgr )
        delete pFrameMgr;

    EndUndo();
    EndAllAction();
}

// Insert an OLE-Object into the CORE.
// if no object is transferred, then one will be created.

void SwWrtShell::InsertObject( const svt::EmbeddedObjectRef& xRef, SvGlobalName const *pName,
                               sal_uInt16 nSlotId )
{
    ResetCursorStack();
    if( !CanInsert() )
        return;

    if( !xRef.is() )
    {
        // temporary storage
        svt::EmbeddedObjectRef xObj;
        uno::Reference < embed::XStorage > xStor = comphelper::OStorageHelper::GetTemporaryStorage();
        bool bDoVerb = true;
        if ( pName )
        {
            comphelper::EmbeddedObjectContainer aCnt( xStor );
            OUString aName;
            // TODO/LATER: get aspect?
            xObj.Assign( aCnt.CreateEmbeddedObject( pName->GetByteSequence(), aName ), embed::Aspects::MSOLE_CONTENT );
        }
        else
        {
            SvObjectServerList aServerList;
            switch (nSlotId)
            {
                case SID_INSERT_OBJECT:
                {
                    if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
                    {
                        std::unique_ptr<weld::MessageDialog> xError(
                            Application::CreateMessageDialog(
                                nullptr, VclMessageType::Warning, VclButtonsType::Ok,
                                SvtResId(STR_WARNING_ACTIVE_CONTENT_DISABLED)));
                        xError->run();
                        break;
                    }
                    aServerList.FillInsertObjects();
                    aServerList.Remove( SwDocShell::Factory().GetClassId() );
                    [[fallthrough]];
                }

                // TODO/LATER: recording! Convert properties to items
                case SID_INSERT_FLOATINGFRAME:
                {
                    SfxSlotPool* pSlotPool = SwModule::get()->GetSlotPool();
                    const SfxSlot* pSlot = pSlotPool->GetSlot(nSlotId);
                    OUString aCmd = pSlot->GetCommand();
                    SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
                    ScopedVclPtr<SfxAbstractInsertObjectDialog> pDlg(pFact->CreateInsertObjectDialog(GetFrameWeld(mxDoc->GetDocShell()),
                                aCmd, xStor, &aServerList));
                    if (pDlg)
                    {
                        pDlg->Execute();
                        bDoVerb = pDlg->IsCreateNew();
                        OUString aIconMediaType;
                        uno::Reference< io::XInputStream > xIconMetaFile = pDlg->GetIconIfIconified( &aIconMediaType );
                        xObj.Assign( pDlg->GetObject(),
                                     xIconMetaFile.is() ? embed::Aspects::MSOLE_ICON : embed::Aspects::MSOLE_CONTENT );
                        if ( xIconMetaFile.is() )
                            xObj.SetGraphicStream( xIconMetaFile, aIconMediaType );
                    }

                    break;
                }

                default:
                    break;
            }
        }

        if ( xObj.is() )
        {
            if( InsertOleObject( xObj ) && bDoVerb )
            {
                SfxInPlaceClient* pClient = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin() );
                if ( !pClient )
                {
                    pClient = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj );
                    SetCheckForOLEInCaption( true );
                }

                if ( xObj.GetViewAspect() == embed::Aspects::MSOLE_ICON )
                {
                    SwRect aArea = GetAnyCurRect( CurRectType::FlyEmbeddedPrt, nullptr, xObj.GetObject() );
                    aArea.Pos() += GetAnyCurRect( CurRectType::FlyEmbedded, nullptr, xObj.GetObject() ).Pos();
                    MapMode aMapMode( MapUnit::MapTwip );
                    Size aSize = xObj.GetSize( &aMapMode );
                    aArea.Width( aSize.Width() );
                    aArea.Height( aSize.Height() );
                    RequestObjectResize( aArea, xObj.GetObject() );
                }
                else
                    CalcAndSetScale( xObj );

                //#50270# We don't need to handle error, this is handled by the
                //DoVerb in the SfxViewShell
                pClient->DoVerb(embed::EmbedVerbs::MS_OLEVERB_SHOW);

                // TODO/LATER: set document name - should be done in Client
            }
        }
    }
    else
    {
        if( HasSelection() )
            DelRight();
        InsertOleObject( xRef );
    }
}

// Insert object into the Core.
// From ClipBoard or Insert

bool SwWrtShell::InsertOleObject( const svt::EmbeddedObjectRef& xRef, SwFlyFrameFormat **pFlyFrameFormat )
{
    //tdf#125100 Ensure that ole object is initially shown as pictogram
    comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = mxDoc->GetDocShell()->getEmbeddedObjectContainer();
    bool bSaveUserAllowsLinkUpdate = rEmbeddedObjectContainer.getUserAllowsLinkUpdate();
    rEmbeddedObjectContainer.setUserAllowsLinkUpdate(true);

    ResetCursorStack();
    StartAllAction();

    StartUndo(SwUndoId::INSERT);

    //Some differences between StarMath and any other objects:
    //1. Selections should be deleted. For StarMath the Text should be
    //   passed to the Object
    //2. If the cursor is at the end of a non empty paragraph a paragraph
    //   break should be inserted. StarMath objects are character bound and
    //   no break should be inserted.
    //3. If an selection is passed to a StarMath object, this object should
    //   not be activated. false should be returned then.
    bool bStarMath = true;
    bool bActivate = true;

    // set parent to get correct VisArea(in case of object needing parent printer)
    uno::Reference < container::XChild > xChild( xRef.GetObject(), uno::UNO_QUERY );
    if ( xChild.is() )
        xChild->setParent( mxDoc->GetDocShell()->GetModel() );

    SvGlobalName aCLSID( xRef->getClassID() );
    bStarMath = ( SotExchange::IsMath( aCLSID ) != 0 );
    if( IsSelection() )
    {
        if( bStarMath )
        {
            OUString aMathData;
            GetSelectedText( aMathData, ParaBreakType::ToOnlyCR );

            if( !aMathData.isEmpty() && svt::EmbeddedObjectRef::TryRunningState( xRef.GetObject() ) )
            {
                uno::Reference < beans::XPropertySet > xSet( xRef->getComponent(), uno::UNO_QUERY );
                if ( xSet.is() )
                {
                    try
                    {
                        xSet->setPropertyValue(u"Formula"_ustr, uno::Any( aMathData ) );
                        bActivate = false;
                    }
                    catch (const uno::Exception&)
                    {
                    }
                }
            }
        }
        DelRight();
    }

    if ( !bStarMath )
        SwFEShell::SplitNode( falsefalse );

    EnterSelFrameMode();

    const SvGlobalName* pName = nullptr;
    SvGlobalName aObjClsId;
    if (xRef.is())
    {
        aObjClsId = SvGlobalName(xRef.GetObject()->getClassID());
        pName = &aObjClsId;
    }
    SwFlyFrameAttrMgr aFrameMgr( truethis, Frmmgr_Type::OLE, pName );
    aFrameMgr.SetHeightSizeType(SwFrameSize::Fixed);

    SwRect aBound;
    CalcBoundRect( aBound, aFrameMgr.GetAnchor() );

    //The Size should be suggested by the OLE server
    MapMode aMapMode( MapUnit::MapTwip );
    Size aSz = xRef.GetSize( &aMapMode );

    //Object size can be limited
    if ( aSz.Width() > aBound.Width() )
    {
        //Always limit proportional.
        aSz.setHeight( aSz.Height() * aBound.Width() / aSz.Width() );
        aSz.setWidth( aBound.Width() );
    }
    aFrameMgr.SetSize( aSz );
    SwFlyFrameFormat *pFormat = SwFEShell::InsertObject( xRef, &aFrameMgr.GetAttrSet() );

    // --> #i972#
    if ( bStarMath && mxDoc->getIDocumentSettingAccess().get( DocumentSettingId::MATH_BASELINE_ALIGNMENT ) )
        AlignFormulaToBaseline( xRef.GetObject() );

    if (pFlyFrameFormat)
        *pFlyFrameFormat = pFormat;

    if ( SotExchange::IsChart( aCLSID ) )
    {
        const uno::Reference< embed::XEmbeddedObject >& xEmbeddedObj = xRef.GetObject();
        if ( xEmbeddedObj.is() )
        {
            bool bDisableDataTableDialog = false;
            svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj );
            uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY );
            if ( xProps.is() &&
                 ( xProps->getPropertyValue(u"DisableDataTableDialog"_ustr) >>= bDisableDataTableDialog ) &&
                 bDisableDataTableDialog )
            {
                xProps->setPropertyValue(u"DisableDataTableDialog"_ustr,
                    uno::Any( false ) );
                xProps->setPropertyValue(u"DisableComplexChartTypes"_ustr,
                    uno::Any( false ) );
                uno::Reference< util::XModifiable > xModifiable( xProps, uno::UNO_QUERY );
                if ( xModifiable.is() )
                {
                    xModifiable->setModified( true );
                }
            }
        }
    }

    EndAllAction();
    GetView().AutoCaption(OLE_CAP, &aCLSID);

    SwRewriter aRewriter;

    if ( bStarMath )
        aRewriter.AddRule(UndoArg1, SwResId(STR_MATH_FORMULA));
    else if ( SotExchange::IsChart( aCLSID ) )
        aRewriter.AddRule(UndoArg1, SwResId(STR_CHART));
    else
        aRewriter.AddRule(UndoArg1, SwResId(STR_OLE));

    EndUndo(SwUndoId::INSERT, &aRewriter);

    rEmbeddedObjectContainer.setUserAllowsLinkUpdate(bSaveUserAllowsLinkUpdate);

    return bActivate;
}

// The current selected OLE object will be loaded with the
// verb into the server.
void SwWrtShell::LaunchOLEObj(sal_Int32 nVerb)
{
    if ( GetCntType() != CNT_OLE ||
         GetView().GetViewFrame().GetFrame().IsInPlace() )
        return;

    svt::EmbeddedObjectRef& xRef = GetOLEObject();
    OSL_ENSURE( xRef.is(), "OLE not found" );

    // LOK: we don't want to handle any other embedded objects than
    // charts, there are too many problems with eg. embedded spreadsheets
    // (like it creates a separate view for the calc sheet)
    if (comphelper::LibreOfficeKit::isActive())
    {
        const auto classId = xRef->getClassID();
        if (!SotExchange::IsChart(classId) && !SotExchange::IsMath(classId))
            return;
    }

    SfxInPlaceClient* pCli = GetView().FindIPClient( xRef.GetObject(), &GetView().GetEditWin() );
    if ( !pCli )
        pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xRef );

    uno::Reference<lang::XInitialization> xOLEInit(xRef.GetObject(), uno::UNO_QUERY);
    if (xOLEInit.is())
    {
        uno::Sequence<beans::PropertyValue> aArguments
            = { comphelper::makePropertyValue(u"ReadOnly"_ustr, pCli->IsProtected()) };
        xOLEInit->initialize({ uno::Any(aArguments) });
    }

    static_cast<SwOleClient*>(pCli)->SetInDoVerb( true );

    CalcAndSetScale( xRef );
    pCli->DoVerb( nVerb );

    static_cast<SwOleClient*>(pCli)->SetInDoVerb( false );
    CalcAndSetScale( xRef );
}

void SwWrtShell::MoveObjectIfActive( svt::EmbeddedObjectRef& xObj, const Point&&nbsp;rOffset )
{
    try
    {
        sal_Int32 nState = xObj->getCurrentState();
        if ( nState == css::embed::EmbedStates::INPLACE_ACTIVE
          || nState == css::embed::EmbedStates::UI_ACTIVE )
        {
            SfxInPlaceClient* pCli =
                GetView().FindIPClient( xObj.GetObject(), &(GetView().GetEditWin()) );
            if ( pCli )
            {
                tools::Rectangle aArea = pCli->GetObjArea();
                aArea += rOffset;
                pCli->SetObjArea( aArea );
            }
        }
    }
    catch (const uno::Exception&)
    {
    }
}

void SwWrtShell::CalcAndSetScale( svt::EmbeddedObjectRef& xObj,
                                  const SwRect *pFlyPrtRect,
                                  const SwRect *pFlyFrameRect,
                                  const bool bNoTextFramePrtAreaChanged )
{
    // Setting the scale of the client. This arises from the difference
    // between the VisArea of the object and the ObjArea.
    OSL_ENSURE( xObj.is(), "ObjectRef not valid" );

    sal_Int64 nAspect = xObj.GetViewAspect();
    if ( nAspect == embed::Aspects::MSOLE_ICON )
        return// the replacement image is completely controlled by container in this case

    sal_Int64 nMisc = 0;
    bool bLinkingChart = false;

    try
    {
        nMisc = xObj->getStatus( nAspect );

        // This can surely only be a non-active object, if desired they
        // get the new size set as VisArea (StarChart).
        if( embed::EmbedMisc::MS_EMBED_RECOMPOSEONRESIZE & nMisc )
        {
            // TODO/MBA: testing
            SwRect aRect( pFlyPrtRect ? *pFlyPrtRect
                        : GetAnyCurRect( CurRectType::FlyEmbeddedPrt, nullptr, xObj.GetObject() ));
            if( !aRect.IsEmpty() )
            {
                // TODO/LEAN: getMapUnit can switch object to running state
                // xObj.TryRunningState();

                MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );

                // TODO/LATER: needs complete VisArea?!
                Size aSize( OutputDevice::LogicToLogic(aRect.SVRect(), MapMode(MapUnit::MapTwip), MapMode(aUnit)).GetSize() );
                awt::Size aSz;
                aSz.Width = aSize.Width();
                aSz.Height = aSize.Height();

                // Action 'setVisualAreaSize' doesn't have to turn on the
                // modified state of the document, either.
                bool bModified = false;
                uno::Reference<util::XModifiable> xModifiable(xObj->getComponent(), uno::UNO_QUERY);
                if (xModifiable.is())
                    bModified = xModifiable->isModified();
                xObj->setVisualAreaSize( nAspect, aSz );
                xModifiable.set(xObj->getComponent(), uno::UNO_QUERY);
                if (xModifiable.is() && xModifiable->isModified() && !bModified)
                    xModifiable->setModified(bModified);

                // #i48419# - action 'UpdateReplacement' doesn't
                // have to change the modified state of the document.
                // This is only a workaround for the defect, that this action
                // modifies a document after load, because unnecessarily the
                // replacement graphic is updated, in spite of the fact that
                // nothing has been changed.
                // If the replacement graphic changes by this action, the document
                // will be already modified via other mechanisms.
                {
                    bool bResetEnableSetModified(false);
                    if ( GetDoc()->GetDocShell()->IsEnableSetModified() )
                    {
                        GetDoc()->GetDocShell()->EnableSetModified( false );
                        bResetEnableSetModified = true;
                    }

                    //#i79576# don't destroy chart replacement images on load
                    //#i79578# don't request a new replacement image for charts to often
                    //a chart sends a modified call to the framework if it was changed
                    //thus the replacement update is already handled elsewhere
                    if ( !SotExchange::IsChart( xObj->getClassID() ) )
                        xObj.UpdateReplacement();

                    if ( bResetEnableSetModified )
                    {
                        GetDoc()->GetDocShell()->EnableSetModified();
                    }
                }
            }

            // TODO/LATER: this is only a workaround,
            uno::Reference< chart2::XChartDocument > xChartDocument( xObj->getComponent(), uno::UNO_QUERY );
            bLinkingChart = ( xChartDocument.is() && !xChartDocument->hasInternalDataProvider() );
        }
    }
    catch (const uno::Exception&)
    {
        // TODO/LATER: handle the error
        return;
    }

    SfxInPlaceClient* pCli = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin() );
    if ( !pCli )
    {
        if ( (embed::EmbedMisc::EMBED_ACTIVATEIMMEDIATELY & nMisc)
             || bLinkingChart
             // --> OD #i117189# - refine condition for non-resizable objects
             // non-resizable objects need to be set the size back by this method
             || ( bNoTextFramePrtAreaChanged && nMisc & embed::EmbedMisc::EMBED_NEVERRESIZE ) )
        {
            pCli = new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj );
        }
        else
            return;
    }

    // TODO/LEAN: getMapUnit can switch object to running state
    // xObj.TryRunningState();

    awt::Size aSize;
    try
    {
        aSize = xObj->getVisualAreaSize( nAspect );
    }
    catch (const embed::NoVisualAreaSizeException&)
    {
        OSL_FAIL("Can't get visual area size!" );
        // the scaling will not be done
    }
    catch (const uno::Exception&)
    {
        // TODO/LATER: handle the error
        OSL_FAIL("Can't get visual area size!" );
        return;
    }

    Size _aVisArea( aSize.Width, aSize.Height );

    Fraction aScaleWidth( 1, 1 );
    Fraction aScaleHeight( 1, 1 );

    bool bUseObjectSize = false;

    // As long as there comes no reasonable size from the object,
    // nothing can be scaled.
    if( _aVisArea.Width() && _aVisArea.Height() )
    {
        const MapMode aTmp( MapUnit::MapTwip );
        MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
        _aVisArea = OutputDevice::LogicToLogic(_aVisArea, MapMode(aUnit), aTmp);
        Size aObjArea;
        if ( pFlyPrtRect )
            aObjArea = pFlyPrtRect->SSize();
        else
            aObjArea = GetAnyCurRect( CurRectType::FlyEmbeddedPrt, nullptr, xObj.GetObject() ).SSize();

        // differ the aObjArea and _aVisArea by 1 Pixel then set new VisArea
        tools::Long nX, nY;
        SwSelPaintRects::Get1PixelInLogic( *this, &nX, &nY );
        if( !( _aVisArea.Width() - nX <= aObjArea.Width() &&
               _aVisArea.Width() + nX >= aObjArea.Width() &&
               _aVisArea.Height()- nY <= aObjArea.Height()&&
               _aVisArea.Height()+ nY >= aObjArea.Height() ))
        {
            if ( nMisc & embed::EmbedMisc::EMBED_NEVERRESIZE )
            {
                // the object must not be scaled,
                // the size stored in object must be used for restoring
                bUseObjectSize = true;
            }
            else
            {
                aScaleWidth = Fraction( aObjArea.Width(),   _aVisArea.Width() );
                aScaleHeight = Fraction( aObjArea.Height(), _aVisArea.Height());
            }
        }
    }

    // Now is the favorable time to set the ObjArea.
    // The Scaling must be considered.
    SwRect aArea;
    if ( pFlyPrtRect )
    {
        aArea = *pFlyPrtRect;
        aArea += pFlyFrameRect->Pos();
    }
    else
    {
        aArea = GetAnyCurRect( CurRectType::FlyEmbeddedPrt, nullptr, xObj.GetObject() );
        aArea.Pos() += GetAnyCurRect( CurRectType::FlyEmbedded, nullptr, xObj.GetObject() ).Pos();
    }

    if ( bUseObjectSize )
    {
        // --> this moves non-resizable object so that when adding borders the baseline remains the same
        const SwFlyFrameFormat *pFlyFrameFormat = dynamic_castconst SwFlyFrameFormat * >( GetFlyFrameFormat() );
        OSL_ENSURE( pFlyFrameFormat, "Could not find fly frame." );
        if ( pFlyFrameFormat )
        {
            const Point &rPoint = pFlyFrameFormat->GetLastFlyFramePrtRectPos();
            SwRect aRect( pFlyPrtRect ? *pFlyPrtRect
                        : GetAnyCurRect( CurRectType::FlyEmbeddedPrt, nullptr, xObj.GetObject() ));
            aArea += rPoint - aRect.Pos(); // adjust area by diff of printing area position in order to keep baseline alignment correct.
        }
        aArea.Width ( _aVisArea.Width() );
        aArea.Height( _aVisArea.Height() );
        RequestObjectResize( aArea, xObj.GetObject() );
    }
    else
    {
        double nWidth(pCli->GetScaleWidth());
        double nHeight(pCli->GetScaleHeight());
        if (nWidth && nHeight)
        {
            aArea.Width ( aArea.Width()  / nWidth );
            aArea.Height( aArea.Height() / nHeight );
        }
    }

    pCli->SetObjAreaAndScale( aArea.SVRect(), aScaleWidth, aScaleHeight );
}

void SwWrtShell::ConnectObj( svt::EmbeddedObjectRef& xObj, const SwRect &rPrt,
                            const SwRect &rFrame )
{
    SfxInPlaceClient* pCli = GetView().FindIPClient( xObj.GetObject(), &GetView().GetEditWin());
    if ( !pCli )
        new SwOleClient( &GetView(), &GetView().GetEditWin(), xObj );
    CalcAndSetScale( xObj, &rPrt, &rFrame );
}

// Insert hard page break;
// Selections will be overwritten
void SwWrtShell::InsertPageBreak(const UIName *pPageDesc, const ::std::optional<sal_uInt16>& oPgNum )
{
    if (!lcl_IsAllowed(this))
        return;

    ResetCursorStack();
    if( CanInsert() )
    {
        SwActContext aActContext(this);
        StartUndo(SwUndoId::UI_INSERT_PAGE_BREAK);

        if ( !IsCursorInTable() )
        {
            if(HasSelection())
                DelRight();
            SwFEShell::SplitNode();
            // delete the numbered attribute of the last line if the last line is empty
            GetDoc()->ClearLineNumAttrs( *GetCursor()->GetPoint() );
        }

        const SwPageDesc *pDesc = pPageDesc
                                ? FindPageDescByName( *pPageDesc, true ) : nullptr;
        if( pDesc )
        {
            SwFormatPageDesc aDesc( pDesc );
            aDesc.SetNumOffset( oPgNum );
            SetAttrItem( aDesc );
        }
        else
            SetAttrItem( SvxFormatBreakItem(SvxBreak::PageBefore, RES_BREAK) );
        EndUndo(SwUndoId::UI_INSERT_PAGE_BREAK);
    }
    collectUIInformation(u"BREAK_PAGE"_ustr, u"parameter"_ustr);
}

// Insert enclosing characters
// Selections will be overwritten
void SwWrtShell::InsertEnclosingChars(const OUString& sStartStr, const OUString&&nbsp;sEndStr)
{
    if (!lcl_IsAllowed(this) || !CanInsert())
        return;
    StartAllAction();
    StartUndo();

    OUStringBuffer currentText, newText;
    bool dotsAdded = false;
    const OUString dots = SwResId(STR_LDOTS);
    for (SwPaM& rPaM : SwWrtShell::GetCursor()->GetRingContainer())
    {
        if (*rPaM.GetPoint() == *rPaM.GetMark())
            continue;
        if (newText.isEmpty())
        {
            OUString pamText = ShortenString(rPaM.GetText(), nUndoStringLength, dots)
                                   .replaceAll("\n"" ");
            currentText.append(pamText);
            newText.append(sStartStr + pamText + sEndStr);
        }
        else if (!dotsAdded)
        {
            dotsAdded = true;
            currentText.append(dots);
            newText.append(dots);
        }

        {
            SwPaM aLocalPam(rPaM, nullptr);
            aLocalPam.Normalize(); // point is at start now
            auto& contentOperations = SwViewShell::getIDocumentContentOperations();

            // To copy the formatting of the start of the range, insert the start string in two
            // phases: insert it after the first selected character; and then move it back
            SwPosition posStart = *aLocalPam.GetPoint();
            aLocalPam.GetPoint()->AdjustContent(+1);
            contentOperations.InsertString(aLocalPam, sStartStr);
            // Now aLocalPam's point is *after* the inserted string
            SwPaM insertedPaM(*aLocalPam.GetPoint());
            insertedPaM.SetMark();
            insertedPaM.GetPoint()->AdjustContent(-sStartStr.getLength());
            contentOperations.CopyRange(insertedPaM, posStart, SwCopyFlags::CopyAll);
            contentOperations.DeleteRange(insertedPaM);

            // No such problems with end string
            aLocalPam.Exchange(); // point is at end now
            contentOperations.InsertString(aLocalPam, sEndStr);
        }
        rPaM.Start()->AdjustContent(-sStartStr.getLength()); // now the selection includes insertion
    }

    SwRewriter aRewriter;
    aRewriter.AddRule(UndoArg1, currentText.makeStringAndClear());
    aRewriter.AddRule(UndoArg2, SwResId(STR_YIELDS));
    aRewriter.AddRule(UndoArg3, newText.makeStringAndClear());
    EndUndo(SwUndoId::UI_REPLACE, &aRewriter);

    EndAllAction();
}

// Insert hard page break;
// Selections will be overwritten

void SwWrtShell::InsertLineBreak(std::optional<SwLineBreakClear> oClear)
{
    if (!lcl_IsAllowed(this))
        return;

    ResetCursorStack();
    if( CanInsert() )
    {
        if(HasSelection())
            DelRight();

        const sal_Unicode cIns = 0x0A;
        SwLineBreakClear eClear = SwLineBreakClear::NONE;
        if (oClear.has_value())
        {
            eClear = *oClear;
        }
        SvxAutoCorrect* pACorr = lcl_IsAutoCorr();
        if (pACorr && eClear == SwLineBreakClear::NONE)
            AutoCorrect( *pACorr, cIns );
        else
        {
            if (eClear == SwLineBreakClear::NONE)
            {
                SwWrtShell::Insert(OUString(cIns));
            }
            else
            {
                SwFormatLineBreak aLineBreak(eClear);
                SetAttrItem(aLineBreak);
            }
        }
    }
}

// Insert hard column break;
// Selections will be overwritten

void SwWrtShell::InsertColumnBreak()
{
    if (!lcl_IsAllowed(this))
        return;

    SwActContext aActContext(this);
    ResetCursorStack();
    if( !CanInsert() )
        return;

    StartUndo(SwUndoId::UI_INSERT_COLUMN_BREAK);

    if ( !IsCursorInTable() )
    {
        if(HasSelection())
            DelRight();
        SwFEShell::SplitNode( falsefalse );
    }
    SetAttrItem(SvxFormatBreakItem(SvxBreak::ColumnBefore, RES_BREAK));

    EndUndo(SwUndoId::UI_INSERT_COLUMN_BREAK);
}

void SwWrtShell::InsertContentControl(SwContentControlType eType)
{
    if (!lcl_IsAllowed(this))
    {
        return;
    }

    ResetCursorStack();
    if (!CanInsert())
    {
        return;
    }

    auto pContentControl = std::make_shared<SwContentControl>(nullptr);

    // Make Random ID... check if it is unique
    // warning: possible infinite loop if there would be billions of content controls.
    SwContentControlManager& pManager = GetDoc()->GetContentControlManager();
    size_t nCCCount = pManager.GetCount();
    sal_Int32 nIdToCheck;
    nIdToCheck
        = comphelper::rng::uniform_uint_distribution(1, std::numeric_limits<sal_Int32>::max());
    size_t nIdx = 0;
    while (nIdx < nCCCount)
    {
        sal_Int32 nID
            = pManager.UnsortedGet(nIdx)->GetContentControl().GetContentControl()->GetId();
        if (nID == nIdToCheck)
        {
            nIdToCheck = comphelper::rng::uniform_uint_distribution(
                1, std::numeric_limits<sal_Int32>::max());
            nIdx = 0;
        }
        else
            nIdx++;
    }
    pContentControl->SetId(nIdToCheck);

    OUString aPlaceholder;
    switch (eType)
    {
        case SwContentControlType::RICH_TEXT:
        case SwContentControlType::PLAIN_TEXT:
        {
            pContentControl->SetShowingPlaceHolder(true);
            if (eType == SwContentControlType::PLAIN_TEXT)
            {
                pContentControl->SetPlainText(true);
            }
            if (!HasSelection())
            {
                aPlaceholder = SwResId(STR_CONTENT_CONTROL_PLACEHOLDER);
            }
            break;
        }
        case SwContentControlType::CHECKBOX:
        {
            pContentControl->SetCheckbox(true);
            // Ballot Box with X
            pContentControl->SetCheckedState(u"\u2612"_ustr);
            // Ballot Box
            pContentControl->SetUncheckedState(u"\u2610"_ustr);
            aPlaceholder = u"\u2610"_ustr;
            break;
        }
        case SwContentControlType::COMBO_BOX:
        case SwContentControlType::DROP_DOWN_LIST:
        {
            if (eType == SwContentControlType::COMBO_BOX)
            {
                pContentControl->SetComboBox(true);
            }
            else if (eType == SwContentControlType::DROP_DOWN_LIST)
            {
                pContentControl->SetDropDown(true);
            }

            pContentControl->SetShowingPlaceHolder(true);
            if (!HasSelection())
            {
                aPlaceholder = SwResId(STR_DROPDOWN_CONTENT_CONTROL_PLACEHOLDER);
            }
            SwContentControlListItem aListItem;
            aListItem.m_aValue = aPlaceholder;
            pContentControl->SetListItems({ std::move(aListItem) });
            break;
        }
        case SwContentControlType::PICTURE:
        {
            // Set up the picture content control.
            pContentControl->SetShowingPlaceHolder(true);
            pContentControl->SetPicture(true);

            // Create the placeholder bitmap.
            BitmapEx aBitmap(Size(1, 1), vcl::PixelFormat::N24_BPP);
            Color aColor = SvtOptionsDrawinglayer::getHilightColor();
            aColor.IncreaseLuminance(255 * 0.75);
            aBitmap.Erase(aColor);
            SwRewriter aRewriter;
            aRewriter.AddRule(UndoArg1, SwResId(STR_GRAPHIC_DEFNAME));
            StartUndo(SwUndoId::INSERT, &aRewriter);
            LockPaint(LockPaintReason::InsertGraphic);
            StartAction();
            InsertGraphic(OUString(), OUString(), aBitmap, nullptr, RndStdIds::FLY_AS_CHAR);

            // Set properties on the bitmap.
            SfxItemSetFixed<RES_FRM_SIZE, RES_FRM_SIZE> aSet(GetDoc()->GetAttrPool());
            GetFlyFrameAttr(aSet);
            SwFormatFrameSize aSize(SwFrameSize::Fixed, 3000, 3000);
            aSet.Put(aSize);
            SetFlyFrameAttr(aSet);
            SwFrameFormat* pFrameFormat = GetFlyFrameFormat();
            EndAction();
            UnlockPaint();
            EndUndo();

            // Go after the anchor position.
            UnSelectFrame();
            LeaveSelFrameMode();
            {
                SwCursor* pCursor = getShellCursor(true);
                pCursor->DeleteMark();
                const SwFormatAnchor& rFormatAnchor = pFrameFormat->GetAnchor();
                pCursor->GetPoint()->Assign( *rFormatAnchor.GetAnchorContentNode(), rFormatAnchor.GetAnchorContentOffset() + 1);
            }

            // Select before the anchor position.
            Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
            break;
        }
        case SwContentControlType::DATE:
        {
            pContentControl->SetShowingPlaceHolder(true);
            pContentControl->SetDate(true);
            SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
            sal_uInt32 nStandardFormat = pFormatter->GetStandardFormat(SvNumFormatType::DATE);
            const SvNumberformat* pFormat = pFormatter->GetEntry(nStandardFormat);
            pContentControl->SetDateFormat(pFormat->GetFormatstring());
            pContentControl->SetDateLanguage(LanguageTag(pFormat->GetLanguage()).getBcp47());
            if (!HasSelection())
            {
                aPlaceholder = SwResId(STR_DATE_CONTENT_CONTROL_PLACEHOLDER);
            }
            break;
        }
    }
    if (aPlaceholder.getLength())
    {
        Insert(aPlaceholder);
        Left(SwCursorSkipMode::Chars, /*bSelect=*/true, aPlaceholder.getLength(),
                /*bBasicCall=*/false);
    }

    const RedlineFlags oldRedlineFlags = getIDocumentRedlineAccess().GetRedlineFlags();
    getIDocumentRedlineAccess().SetRedlineFlags(RedlineFlags::Ignore);
    SwFormatContentControl aContentControl(pContentControl, RES_TXTATR_CONTENTCONTROL);
    SetAttrItem(aContentControl);
    getIDocumentRedlineAccess().SetRedlineFlags(oldRedlineFlags);
}

// Insert footnote
// rStr - optional footnote mark

void SwWrtShell::InsertFootnote(const OUString &rStr, bool bEndNote, bool bEdit )
{
    ResetCursorStack();
    if( !CanInsert() )
        return;

    if(HasSelection())
    {
        //collapse cursor to the end
        if(!IsCursorPtAtEnd())
            SwapPam();
        ClearMark();
    }
    SwPosition aPos = *GetCursor()->GetPoint();
    SwFormatFootnote aFootNote( bEndNote );
    if(!rStr.isEmpty())
        aFootNote.SetNumStr( rStr );

    SetAttrItem(aFootNote);

    if( bEdit )
    {
        // For editing the footnote text.
        Left(SwCursorSkipMode::Chars, false, 1, false );
        GotoFootnoteText();
    }
    m_aNavigationMgr.addEntry(aPos);
}

// tdf#141634
static bool lcl_FoldedOutlineNodeEndOfParaSplit(SwWrtShell *pThis)
{
    SwTextNode* pTextNode = pThis->GetCursor()->GetPointNode().GetTextNode();
    if (pTextNode && pTextNode->IsOutline())
    {
        if (!pTextNode->GetAttrOutlineContentVisible())
        {
            const SwNodes& rNodes = pThis->GetNodes();
            const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
            SwOutlineNodes::size_type nPos;
            (void) rOutlineNodes.Seek_Entry(pTextNode, &nPos);

            SwNode* pSttNd = rOutlineNodes[nPos];

            // determine end node of folded outline content
            SwNode* pEndNd = &rNodes.GetEndOfContent();
            if (rOutlineNodes.size() > nPos + 1)
                pEndNd = rOutlineNodes[nPos + 1];

            if (pThis->GetViewOptions()->IsTreatSubOutlineLevelsAsContent())
            {
                // get the next outline node after the folded outline content (iPos)
                // it is the next outline node with the same level or less
                int nLevel = pSttNd->GetTextNode()->GetAttrOutlineLevel();
                SwOutlineNodes::size_type iPos = nPos;
                while (++iPos < rOutlineNodes.size() &&
                       rOutlineNodes[iPos]->GetTextNode()->GetAttrOutlineLevel() > nLevel);

                // get the correct end node
                // the outline node may be in frames, headers, footers special section of doc model
                SwNode* pStartOfSectionNodeSttNd = pSttNd->StartOfSectionNode();
                while (pStartOfSectionNodeSttNd->StartOfSectionNode()
                       != pStartOfSectionNodeSttNd->StartOfSectionNode()->StartOfSectionNode())
                {
                    pStartOfSectionNodeSttNd = pStartOfSectionNodeSttNd->StartOfSectionNode();
                }
                pEndNd = pStartOfSectionNodeSttNd->EndOfSectionNode();

                if (iPos < rOutlineNodes.size())
                {
                    SwNode* pStartOfSectionNode = rOutlineNodes[iPos]->StartOfSectionNode();
                    while (pStartOfSectionNode->StartOfSectionNode()
                           != pStartOfSectionNode->StartOfSectionNode()->StartOfSectionNode())
                    {
                        pStartOfSectionNode = pStartOfSectionNode->StartOfSectionNode();
                    }
                    if (pStartOfSectionNodeSttNd == pStartOfSectionNode)
                        pEndNd = rOutlineNodes[iPos];
                }
            }

            // table, text box, header, footer
            if (pSttNd->GetTableBox() || pSttNd->GetIndex() < rNodes.GetEndOfExtras().GetIndex())
            {
                // insert before section end node
                if (pSttNd->EndOfSectionIndex() < pEndNd->GetIndex())
                {
                    SwNodeIndex aIdx(*pSttNd->EndOfSectionNode());
                    while (aIdx.GetNode().IsEndNode())
                        --aIdx;
                    ++aIdx;
                    pEndNd = &aIdx.GetNode();
                }
            }
            // if pSttNd isn't in table but pEndNd is then insert after table
            else if (pEndNd->GetTableBox())
            {
                pEndNd = pEndNd->FindTableNode();
                SwNodeIndex aIdx(*pEndNd, -1);
                // account for nested tables
                while (aIdx.GetNode().GetTableBox())
                {
                    pEndNd = aIdx.GetNode().FindTableNode();
                    aIdx.Assign(*pEndNd, -1);
                }
                aIdx.Assign(*pEndNd->EndOfSectionNode(), +1);
                pEndNd = &aIdx.GetNode();
            }
            // end node determined

            // now insert the new outline node
            SwDoc* pDoc = pThis->GetDoc();

            // insert at end of tablebox doesn't work correct without
            MakeAllOutlineContentTemporarilyVisible a(pDoc);

            SwTextNode* pNd = pDoc->GetNodes().MakeTextNode(*pEndNd, pTextNode->GetTextColl(), true);

            // if the outline level is not set in style then it is set in direct formatting
            if (!pTextNode->GetTextColl()->GetAttrOutlineLevel())
                pNd->SetAttrOutlineLevel(pTextNode->GetAttrOutlineLevel());

            (void) rOutlineNodes.Seek_Entry(pNd, &nPos);
            pThis->GotoOutline(nPos);

            if (pDoc->GetIDocumentUndoRedo().DoesUndo())
            {
                pDoc->GetIDocumentUndoRedo().ClearRedo();
                pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoInsert>(*pNd));
                pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoFormatColl>
                                                        (SwPaM(*pNd), pNd->GetTextColl(), truetrue));
            }

            pThis->SetModified();
            return true;
        }
    }
    return false;
}

// SplitNode; also, because
//                  - of deleting selected content;
//                  - of reset of the Cursorstack if necessary.

void SwWrtShell::SplitNode( bool bAutoFormat )
{
    ResetCursorStack();
    if( !CanInsert() )
        return;

    SwActContext aActContext(this);

    m_rView.GetEditWin().FlushInBuffer();
    StartUndo(SwUndoId::SPLITNODE);

    bool bHasSel = HasSelection();
    if (bHasSel)
        DelRight();

    bool bHandled = false;
    if (GetViewOptions()->IsShowOutlineContentVisibilityButton() && IsEndPara())
        bHandled = lcl_FoldedOutlineNodeEndOfParaSplit(this);

    if (!bHandled)
        SwFEShell::SplitNode( bAutoFormat );

    EndUndo(SwUndoId::SPLITNODE);
}

// Turn on numbering
// Parameter:   Optional specification of a name for the named list;
//              this indicates a position if it is possible to convert them
//              into a number and less than nMaxRules.

// To test the CharFormats at the numbering
// external void SetNumChrFormat( SwWrtShell*, SwNumRules& );

// -> #i40041#
// Preconditions (as far as OD has figured out):
// - <SwEditShell::HasNumber()> is false, if <bNum> is true
// - <SwEditShell::HasBullet()> is false, if <bNum> is false
// Behavior of method is determined by the current situation at the current
// cursor position in the document.
void SwWrtShell::NumOrBulletOn(bool bNum)
{
    StartUndo(SwUndoId::NUMORNONUM);

    const SwNumRule* pNumRule = GetNumRuleAtCurrCursorPos();

    // - activate outline rule respectively turning on outline rule for
    //   current text node. But, only for turning on a numbering (<bNum> == true).
    // - overwrite found numbering rule at current cursor position, if
    //   no numbering rule can be retrieved from the paragraph style.
    bool bContinueFoundNumRule( false );
    bool bActivateOutlineRule( false );
    int nActivateOutlineLvl( MAXLEVEL );    // only relevant, if <bActivateOutlineRule> == true
    SwTextFormatColl * pColl = GetCurTextFormatColl();
    if ( pColl )
    {
        // retrieve numbering rule at paragraph
        // style, which is found at current cursor position in the document.
        SwNumRule* pCollRule = mxDoc->FindNumRulePtr(pColl->GetNumRule().GetValue());
        // #125993# - The outline numbering rule isn't allowed
        // to be derived from a parent paragraph style to a derived one.
        // Thus check, if the found outline numbering rule is directly
        // set at the paragraph style <pColl>. If not, set <pCollRule> to NULL
        if ( pCollRule && pCollRule == GetDoc()->GetOutlineNumRule() )
        {
            const SwNumRule* pDirectCollRule =
                    mxDoc->FindNumRulePtr(pColl->GetNumRule( false ).GetValue());
            if ( !pDirectCollRule )
            {
                pCollRule = nullptr;
            }
        }

        if ( !pCollRule )
        {
            pNumRule = pCollRule;
        }
        // no activation or continuation of outline numbering in Writer/Web document
        else if ( bNum &&
                  !dynamic_cast<SwWebDocShell*>(GetDoc()->GetDocShell()) &&
                  pCollRule == GetDoc()->GetOutlineNumRule() )
        {
            if ( pNumRule == pCollRule )
            {
                // check, if text node at current cursor positioned is counted.
                // If not, let it been counted. Then it has to be checked,
                // of the outline numbering has to be activated or continued.
                SwTextNode const*const pTextNode = sw::GetParaPropsNode(
                        *GetLayout(), GetCursor()->GetPoint()->GetNode());
                if ( pTextNode && !pTextNode->IsCountedInList() )
                {
                    // check, if numbering of the outline level of the paragraph
                    // style is active. If not, activate this outline level.
                    nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
                    OSL_ENSURE( pColl->IsAssignedToListLevelOfOutlineStyle(),
                            " - paragraph style with outline rule, but no outline level" );
                    if ( pColl->IsAssignedToListLevelOfOutlineStyle() &&
                         pCollRule->Get( o3tl::narrowing<sal_uInt16>(nActivateOutlineLvl) ).GetNumberingType()
                            == SVX_NUM_NUMBER_NONE )
                    {
                        // activate outline numbering
                        bActivateOutlineRule = true;
                    }
                    else
                    {
                        // turning on outline numbering at current cursor position
                        bContinueFoundNumRule = true;
                    }
                }
                else
                {
                    // #i101234#
                    // activate outline numbering, because from the precondition
                    // it's known, that <SwEdit::HasNumber()> == false
                    bActivateOutlineRule = true;
                    nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
                }
            }
            else if ( !pNumRule )
            {
                // #i101234#
                // Check, if corresponding list level of the outline numbering
                // has already a numbering format set.
                nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
                if ( pCollRule->Get( o3tl::narrowing<sal_uInt16>(nActivateOutlineLvl) ).GetNumberingType()
                                == SVX_NUM_NUMBER_NONE )
                {
                    // activate outline numbering, because from the precondition
                    // it's known, that <SwEdit::HasNumber()> == false
                    bActivateOutlineRule = true;
                }
                else
                {
                    // turning on outline numbering at current cursor position
                    bContinueFoundNumRule = true;
                }
            }
            else
            {
                // check, if numbering of the outline level of the paragraph
                // style is active. If not, activate this outline level.
                nActivateOutlineLvl = pColl->GetAssignedOutlineStyleLevel();
                OSL_ENSURE( pColl->IsAssignedToListLevelOfOutlineStyle(),
                        " - paragraph style with outline rule, but no outline level" );
                if ( pColl->IsAssignedToListLevelOfOutlineStyle() &&
                     pCollRule->Get( o3tl::narrowing<sal_uInt16>(nActivateOutlineLvl) ).GetNumberingType()
                        == SVX_NUM_NUMBER_NONE )
                {
                    // activate outline numbering
                    bActivateOutlineRule = true;
                }
                else
                {
                    // turning on outline numbering at current cursor position
                    bContinueFoundNumRule = true;
                }
            }
            pNumRule = pCollRule;
        }
    }

    // Only automatic numbering/bullet rules should be changed.
    // Note: The outline numbering rule is also an automatic one. It's only
    //       changed, if it has to be activated.
    if ( pNumRule )
    {
        if ( !pNumRule->IsAutoRule() )
        {
            pNumRule = nullptr;
        }
        else if ( pNumRule == GetDoc()->GetOutlineNumRule() &&
                  !bActivateOutlineRule && !bContinueFoundNumRule )
        {
            pNumRule = nullptr;
        }
    }

    // Search for a previous numbering/bullet rule to continue it.
    OUString sContinuedListId;
    if ( !pNumRule )
    {
        pNumRule = GetDoc()->SearchNumRule( *GetCursor()->GetPoint(),
                                            false, bNum, false, 0,
                                            sContinuedListId, GetLayout() );
        bContinueFoundNumRule = pNumRule != nullptr;
    }

    if (pNumRule)
    {
        SwNumRule aNumRule(*pNumRule);

        // do not change found numbering/bullet rule, if it should only be continued.
        if ( !bContinueFoundNumRule )
        {
            SwTextNode const*const pTextNode = sw::GetParaPropsNode(
                    *GetLayout(), GetCursor()->GetPoint()->GetNode());

            if (pTextNode)
            {
                // use above retrieve outline level, if outline numbering has to be activated.
                int nLevel = bActivateOutlineRule
                              ? nActivateOutlineLvl
                              : pTextNode->GetActualListLevel();

                if (nLevel < 0)
                    nLevel = 0;

                if (nLevel >= MAXLEVEL)
                    nLevel = MAXLEVEL - 1;

                SwNumFormat aFormat(aNumRule.Get(o3tl::narrowing<sal_uInt16>(nLevel)));

                if (bNum)
                    aFormat.SetNumberingType(SVX_NUM_ARABIC);
                else
                {
                    // #i63395# Only apply user defined default bullet font
                    if ( numfunc::IsDefBulletFontUserDefined() )
                    {
                        const vcl::Font* pFnt = &numfunc::GetDefBulletFont();
                        aFormat.SetBulletFont( pFnt );
                    }
                    aFormat.SetBulletChar( numfunc::GetBulletChar(static_cast<sal_uInt8>(nLevel)));
                    aFormat.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
                    // #i93908# clear suffix for bullet lists
                    aFormat.SetListFormat(u""_ustr, u""_ustr, nLevel);
                }
                aNumRule.Set(o3tl::narrowing<sal_uInt16>(nLevel), aFormat);
            }
        }

        // reset indent attribute on applying list style
        SetCurNumRule( aNumRule, false, sContinuedListId, true );
    }
    else
    {
        // #i95907#
        const SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode(
                                    numfunc::GetDefaultPositionAndSpaceMode() );
        SwNumRule aNumRule( GetUniqueNumRuleName(), ePosAndSpaceMode );
        // Append the character template at the numbering.
        SwCharFormat* pChrFormat;
        SwDocShell* pDocSh = GetView().GetDocShell();

        if (bNum)
        {
            pChrFormat = GetCharFormatFromPool( RES_POOLCHR_NUM_LEVEL );
        }
        else
        {
            pChrFormat = GetCharFormatFromPool( RES_POOLCHR_BULLET_LEVEL );
        }

        const SwTextNode *const pTextNode = sw::GetParaPropsNode(*GetLayout(),
                GetCursor()->GetPoint()->GetNode());
        const SwTwips nWidthOfTabs = pTextNode
                                     ? pTextNode->GetWidthOfLeadingTabs()
                                     : 0;
        GetDoc()->getIDocumentContentOperations().RemoveLeadingWhiteSpace(*GetCursor());

        const bool bHtml = dynamic_cast<SwWebDocShell*>( pDocSh ) !=  nullptr;
        const bool bRightToLeft = IsInRightToLeftText();
        for( sal_uInt8 nLvl = 0; nLvl < MAXLEVEL; ++nLvl )
        {
            SwNumFormat aFormat( aNumRule.Get( nLvl ) );
            aFormat.SetCharFormat( pChrFormat );

            if (! bNum)
            {
                uno::Sequence<OUString> aBulletSymbols(
                    officecfg::Office::Common::BulletsNumbering::DefaultBullets::get());
                uno::Sequence<OUString> aBulletSymbolsFonts(
                    officecfg::Office::Common::BulletsNumbering::DefaultBulletsFonts::get());
                sal_Int32 nBulletSymbolIndex = nLvl < aBulletSymbols.getLength() ? nLvl : 0;
                aFormat.SetBulletChar(aBulletSymbols[nBulletSymbolIndex].toChar());
                vcl::Font aFont;
                sal_Int32 nBulletSymbolsFontIndex = nLvl < aBulletSymbolsFonts.getLength() ? nLvl : 0;
                aFont.SetFamilyName(aBulletSymbolsFonts[nBulletSymbolsFontIndex]);
                aFormat.SetBulletFont(&aFont);
                aFormat.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
                // #i93908# clear suffix for bullet lists
                aFormat.SetListFormat(u""_ustr, u""_ustr, nLvl);
            }

            // #i95907#
            if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
            {
                if(bHtml && nLvl)
                {
                    // 1/2" for HTML
                    aFormat.SetAbsLSpace(nLvl * 720);
                }
                else if ( nWidthOfTabs > 0 )
                {
                    aFormat.SetAbsLSpace(nWidthOfTabs + nLvl * 720);
                }
            }

            // #i38904#  Default alignment for
            // numbering/bullet should be rtl in rtl paragraph:
            if ( bRightToLeft )
            {
                aFormat.SetNumAdjust( SvxAdjust::Right );
            }

            aNumRule.Set( nLvl, aFormat );
        }

        // #i95907#
        if ( pTextNode &&
             ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
        {

            const SwTwips nTextNodeIndent = pTextNode->GetAdditionalIndentForStartingNewList();
            if ( ( nTextNodeIndent + nWidthOfTabs ) != 0 )
            {
                // #i111172#/fdo#85666
                // If text node is already inside a list, assure that the indents
                // are the same. Thus, adjust the indent change value by subtracting
                // indents of to be applied list style.
                SwTwips nIndentChange = nTextNodeIndent + nWidthOfTabs;
                if ( pTextNode->GetNumRule() )
                {
                    int nLevel = pTextNode->GetActualListLevel();

                    if (nLevel < 0)
                        nLevel = 0;

                    if (nLevel >= MAXLEVEL)
                        nLevel = MAXLEVEL - 1;

                    const SwNumFormat& aFormat( aNumRule.Get( nLevel ) );
                    if ( aFormat.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
                    {
                        nIndentChange -= aFormat.GetIndentAt() + aFormat.GetFirstLineIndent();
                    }
                }
                aNumRule.ChangeIndent( nIndentChange );
            }
        }
        // reset indent attribute on applying list style
        // start new list
        SetCurNumRule( aNumRule, true, OUString(), true );
    }

    EndUndo(SwUndoId::NUMORNONUM);
}
// <- #i40041#

void SwWrtShell::NumOn()
{
    NumOrBulletOn(true);
}

void SwWrtShell::NumOrBulletOff()
{
    const SwNumRule * pCurNumRule = GetNumRuleAtCurrCursorPos();

    if (!pCurNumRule)
        return;

    DelNumRules();

    // #126346# - Cursor can not be anymore in front of
    // a label, because numbering/bullet is switched off.
    SetInFrontOfLabel( false );
}
// <- #i29560#

// Request Default-Bulletlist

void SwWrtShell::BulletOn()
{
    NumOrBulletOn(false);
}

SelectionType SwWrtShell::GetSelectionType() const
{
    // ContentType cannot be determined within a Start-/EndAction.
    // Because there is no invalid value TEXT will be returned.
    // The value does not matter, it may be updated in EndAction anyway.

    if (ActionPend())
        return IsSelFrameMode() ? SelectionType::Frame : SelectionType::Text;

    SwView &_rView = const_cast<SwView&>(GetView());
    if (_rView.GetPostItMgr() && _rView.GetPostItMgr()->HasActiveSidebarWin() )
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=94 H=89 G=91

¤ Dauer der Verarbeitung: 0.33 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.