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

Quelle  textsh1.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 <sal/config.h>

#include <config_features.h>

#include <com/sun/star/i18n/WordType.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XThesaurus.hpp>
#include <com/sun/star/text/XContentControlsSupplier.hpp>

#include <hintids.hxx>
#include <cmdid.h>
#include <comphelper/lok.hxx>
#include <comphelper/propertysequence.hxx>

#include <i18nutil/unicode.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <svtools/langtab.hxx>
#include <svl/numformat.hxx>
#include <svl/slstitm.hxx>
#include <svl/stritem.hxx>
#include <sfx2/htmlmode.hxx>
#include <svl/whiter.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/namedcolor.hxx>
#include <sfx2/viewfrm.hxx>
#include <vcl/unohelp2.hxx>
#include <vcl/weld.hxx>
#include <sfx2/lokhelper.hxx>
#include <sfx2/request.hxx>
#include <svl/eitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/tstpitem.hxx>
#include <editeng/brushitem.hxx>
#include <editeng/svxacorr.hxx>
#include <svl/cjkoptions.hxx>
#include <svl/ctloptions.hxx>
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentSettingAccess.hxx>
#include <charfmt.hxx>
#include <svx/SmartTagItem.hxx>
#include <svx/xflgrit.hxx>
#include <svx/xflhtit.hxx>
#include <svx/xfillit0.hxx>
#include <fmtinfmt.hxx>
#include <wrtsh.hxx>
#include <wview.hxx>
#include <swmodule.hxx>
#include <viewopt.hxx>
#include <uitool.hxx>
#include <textsh.hxx>
#include <IMark.hxx>
#include <swdtflvr.hxx>
#include <swundo.hxx>
#include <reffld.hxx>
#include <textcontentcontrol.hxx>
#include <txatbase.hxx>
#include <docsh.hxx>
#include <inputwin.hxx>
#include <chrdlgmodes.hxx>
#include <fmtcol.hxx>
#include <cellatr.hxx>
#include <edtwin.hxx>
#include <fldmgr.hxx>
#include <ndtxt.hxx>
#include <strings.hrc>
#include <paratr.hxx>
#include <vcl/svapp.hxx>
#include <sfx2/app.hxx>
#include <breakit.hxx>
#include <SwSmartTagMgr.hxx>
#include <editeng/acorrcfg.hxx>
#include <swabstdlg.hxx>
#include <sfx2/sfxdlg.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/linguistic2/ProofreadingResult.hpp>
#include <com/sun/star/linguistic2/XDictionary.hpp>
#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
#include <editeng/unolingu.hxx>
#include <doc.hxx>
#include <drawdoc.hxx>
#include <view.hxx>
#include <pam.hxx>
#include <sfx2/objface.hxx>
#include <langhelper.hxx>
#include <uiitems.hxx>
#include <svx/nbdtmgfact.hxx>
#include <svx/nbdtmg.hxx>
#include <SwRewriter.hxx>
#include <svx/drawitem.hxx>
#include <numrule.hxx>
#include <memory>
#include <xmloff/odffields.hxx>
#include <bookmark.hxx>
#include <linguistic/misc.hxx>
#include <comphelper/sequenceashashmap.hxx>
#include <comphelper/scopeguard.hxx>
#include <authfld.hxx>
#include <config_wasm_strip.h>
#if HAVE_FEATURE_CURL && !ENABLE_WASM_STRIP_EXTRA
#include <officecfg/Office/Common.hxx>
#include <officecfg/Office/Linguistic.hxx>
#include <svl/visitem.hxx>
#include <translatelangselect.hxx>
#endif // HAVE_FEATURE_CURL && ENABLE_WASM_STRIP_EXTRA
#include <translatehelper.hxx>
#include <IDocumentContentOperations.hxx>
#include <IDocumentUndoRedo.hxx>
#include <fmtcntnt.hxx>
#include <fmtrfmrk.hxx>
#include <cntfrm.hxx>
#include <flyfrm.hxx>
#include <unoprnms.hxx>
#include <boost/property_tree/json_parser.hpp>
#include <formatcontentcontrol.hxx>
#include <rtl/uri.hxx>
#include <unotxdoc.hxx>
#include <sax/tools/converter.hxx>

#include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
#include <com/sun/star/chart2/XInternalDataProvider.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart/XChartDocument.hpp>
#include <com/sun/star/chart/XChartDataArray.hpp>
#include <com/sun/star/chart2/XTitle.hpp>
#include <com/sun/star/chart2/XTitled.hpp>
#include <com/sun/star/chart/ChartDataRowSource.hpp>
#include <com/sun/star/util/XModifiable.hpp>

#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
#include <com/sun/star/chart2/XChartTypeContainer.hpp>
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/util/XCloneable.hpp>

#include <com/sun/star/util/SearchAlgorithms2.hpp>
#include <com/sun/star/document/XDocumentProperties2.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>

#include <com/sun/star/beans/XPropertyAccess.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>

using namespace ::com::sun::star;
using namespace com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace com::sun::star::style;
using namespace svx::sidebar;

static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell &rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel,
                                bool bSelectionPut, bool bApplyToParagraph, SfxRequest *pReq);

static void sw_CharDialog(SwWrtShell& rWrtSh, bool bUseDialog, bool bApplyToParagraph,
                          sal_uInt16 nSlot, const SfxItemSet* pArgs, SfxRequest* pReq)
{
    FieldUnit eMetric = ::GetDfltMetric(dynamic_cast<SwWebView*>( &rWrtSh.GetView()) != nullptr );
    SwModule::get()->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast<sal_uInt16>(eMetric)));
    auto pCoreSet = std::make_shared<SfxItemSetFixed<
            RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
            RES_TXTATR_INETFMT, RES_TXTATR_INETFMT,
            RES_BACKGROUND, RES_SHADOW,
            SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
            SID_HTML_MODE, SID_HTML_MODE,
            SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, SID_ATTR_CHAR_WIDTH_FIT_TO_LINE,
            FN_PARAM_SELECTION, FN_PARAM_SELECTION>> ( rWrtSh.GetView().GetPool() );
    rWrtSh.GetCurAttr(*pCoreSet);

    bool bSel = rWrtSh.HasSelection();
    bool bSelectionPut = false;
    if(bSel || rWrtSh.IsInWord())
    {
        if(!bSel)
        {
            rWrtSh.StartAction();
            rWrtSh.Push();
            if(!rWrtSh.SelectTextAttr( RES_TXTATR_INETFMT ))
                rWrtSh.SelWrd();
        }
        pCoreSet->Put(SfxStringItem(FN_PARAM_SELECTION, rWrtSh.GetSelText()));
        bSelectionPut = true;
        if(!bSel)
        {
            rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
            rWrtSh.EndAction();
        }
    }
    pCoreSet->Put(SfxUInt16Item(SID_ATTR_CHAR_WIDTH_FIT_TO_LINE, rWrtSh.GetScalingOfSelectedText()));

    ::ConvertAttrCharToGen(*pCoreSet);

    // Setting the BoxInfo
    ::PrepareBoxInfo(*pCoreSet, rWrtSh);

    pCoreSet->Put(SfxUInt16Item(SID_HTML_MODE, ::GetHtmlMode(rWrtSh.GetView().GetDocShell())));
    VclPtr<SfxAbstractTabDialog> pDlg;
    if ( bUseDialog && GetActiveView() )
    {
        SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
        pDlg.reset(pFact->CreateSwCharDlg(rWrtSh.GetView().GetFrameWeld(), rWrtSh.GetView(), *pCoreSet, SwCharDlgMode::Std));

        if (nSlot == SID_CHAR_DLG_EFFECT)
            pDlg->SetCurPageId(u"fonteffects"_ustr);
        else if (nSlot == SID_CHAR_DLG_POSITION)
            pDlg->SetCurPageId(u"position"_ustr);
        else if (nSlot == SID_CHAR_DLG_FOR_PARAGRAPH)
            pDlg->SetCurPageId(u"font"_ustr);
        else if (pReq)
        {
            const SfxStringItem* pItem = (*pReq).GetArg<SfxStringItem>(FN_PARAM_1);
            if (pItem)
                pDlg->SetCurPageId(pItem->GetValue());
        }
    }

    if (bUseDialog)
    {
        std::shared_ptr<SfxRequest> pRequest;
        if (pReq)
        {
            pRequest = std::make_shared<SfxRequest>(*pReq);
            pReq->Ignore(); // the 'old' request is not relevant any more
        }
        pDlg->StartExecuteAsync([pDlg, &rWrtSh, pCoreSet=std::move(pCoreSet), bSel,
                                 bSelectionPut, bApplyToParagraph,
                                 pRequest=std::move(pRequest)](sal_Int32 nResult){
            if (nResult == RET_OK)
            {
                sw_CharDialogResult(pDlg->GetOutputItemSet(), rWrtSh, pCoreSet, bSel, bSelectionPut,
                                    bApplyToParagraph, pRequest.get());
            }
            pDlg->disposeOnce();
        });
    }
    else if (pArgs)
    {
        sw_CharDialogResult(pArgs, rWrtSh, pCoreSet, bSel, bSelectionPut, bApplyToParagraph, pReq);
    }
}

static void sw_CharDialogResult(const SfxItemSet* pSet, SwWrtShell& rWrtSh, std::shared_ptr<SfxItemSet> const & pCoreSet, bool bSel,
                                bool bSelectionPut, bool bApplyToParagraph, SfxRequest* pReq)
{
    SfxItemSet aTmpSet( *pSet );
    ::ConvertAttrGenToChar(aTmpSet, *pCoreSet);

    const bool bWasLocked = rWrtSh.IsViewLocked();
    if (bApplyToParagraph)
    {
        rWrtSh.StartAction();
        rWrtSh.LockView(true);
        rWrtSh.Push();
        SwLangHelper::SelectCurrentPara(rWrtSh);
    }

    const SfxStringItem* pSelectionItem;
    bool bInsert = false;
    sal_Int32 nInsert = 0;

    // The old item is for unknown reasons back in the set again.
    if( !bSelectionPut && (pSelectionItem = aTmpSet.GetItemIfSet(FN_PARAM_SELECTION, false)) )
    {
        const OUString& sInsert = pSelectionItem->GetValue();
        bInsert = !sInsert.isEmpty();
        if(bInsert)
        {
            nInsert = sInsert.getLength();
            rWrtSh.StartAction();
            rWrtSh.Insert( sInsert );
            rWrtSh.SetMark();
            rWrtSh.ExtendSelection(false, sInsert.getLength());
            SfxRequest aReq(rWrtSh.GetView().GetViewFrame(), FN_INSERT_STRING);
            aReq.AppendItem( SfxStringItem( FN_INSERT_STRING, sInsert ) );
            aReq.Done();
            SfxRequest aReq1(rWrtSh.GetView().GetViewFrame(), FN_CHAR_LEFT);
            aReq1.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nInsert) );
            aReq1.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, true) );
            aReq1.Done();
        }
    }
    aTmpSet.ClearItem(FN_PARAM_SELECTION);

    SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl();
    if(bSel && rWrtSh.IsSelFullPara() && pColl && pColl->IsAutoUpdateOnDirectFormat())
    {
        rWrtSh.AutoUpdatePara(pColl, aTmpSet);
    }
    else
        rWrtSh.SetAttrSet( aTmpSet );
    if (pReq)
        pReq->Done(aTmpSet);
    if(bInsert)
    {
        SfxRequest aReq1(rWrtSh.GetView().GetViewFrame(), FN_CHAR_RIGHT);
        aReq1.AppendItem( SfxInt32Item(FN_PARAM_MOVE_COUNT, nInsert) );
        aReq1.AppendItem( SfxBoolItem(FN_PARAM_MOVE_SELECTION, false) );
        aReq1.Done();
        rWrtSh.SwapPam();
        rWrtSh.ClearMark();
        rWrtSh.DontExpandFormat();
        rWrtSh.EndAction();
    }

    if (bApplyToParagraph)
    {
        rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
        rWrtSh.LockView(bWasLocked);
        rWrtSh.EndAction();
    }
}


static void sw_ParagraphDialogResult(SfxItemSet* pSet, SwWrtShell &rWrtSh, SfxRequest& ;rReq, SwPaM* pPaM)
{
    if (!pSet)
        return;

    rReq.Done( *pSet );
    ::SfxToSwPageDescAttr( rWrtSh, *pSet );
    // #i56253#
    // enclose all undos.
    // Thus, check conditions, if actions will be performed.
    const bool bUndoNeeded( pSet->Count() ||
            SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART) ||
            SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) );
    if ( bUndoNeeded )
    {
        rWrtSh.StartUndo( SwUndoId::INSATTR );
    }
    if( pSet->Count() )
    {
        rWrtSh.StartAction();
        if ( const SfxStringItem* pDropTextItem = pSet->GetItemIfSet(FN_DROP_TEXT, false) )
        {
            if ( !pDropTextItem->GetValue().isEmpty() )
                rWrtSh.ReplaceDropText(pDropTextItem->GetValue(), pPaM);
        }
        rWrtSh.SetAttrSet(*pSet, SetAttrMode::DEFAULT, pPaM);
        rWrtSh.EndAction();
        SwTextFormatColl* pColl = rWrtSh.GetPaMTextFormatColl(pPaM);
        if(pColl && pColl->IsAutoUpdateOnDirectFormat())
        {
            rWrtSh.AutoUpdatePara(pColl, *pSet, pPaM);
        }
    }

    if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART) )
    {
        //SetNumRuleStart(true) restarts the numbering at the value
        //that is defined at the starting point of the numbering level
        //otherwise the SetNodeNumStart() value determines the start
        //if it's set to something different than USHRT_MAX

        bool bStart = static_cast<const SfxBoolItem&>(pSet->Get(FN_NUMBER_NEWSTART)).GetValue();

        // Default value for restart value has to be USHRT_MAX
        // in order to indicate that the restart value of the list
        // style has to be used on restart.
        sal_uInt16 nNumStart = USHRT_MAX;
        if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) )
        {
            nNumStart = pSet->Get(FN_NUMBER_NEWSTART_AT).GetValue();
        }
        rWrtSh.SetNumRuleStart(bStart, pPaM);
        rWrtSh.SetNodeNumStart(nNumStart);
    }
    else if( SfxItemState::SET == pSet->GetItemState(FN_NUMBER_NEWSTART_AT) )
    {
        rWrtSh.SetNodeNumStart(pSet->Get(FN_NUMBER_NEWSTART_AT).GetValue());
        rWrtSh.SetNumRuleStart(false, pPaM);
    }
    // #i56253#
    if ( bUndoNeeded )
    {
        rWrtSh.EndUndo( SwUndoId::INSATTR );
    }
}

namespace {

void InsertBreak(SwWrtShell& rWrtSh,
                 sal_uInt16 nKind,
                 ::std::optional<sal_uInt16> oPageNumber,
                 const UIName& rTemplateName, std::optional<SwLineBreakClear> oClear)
{
    switch ( nKind )
    {
        case 1 :
            rWrtSh.InsertLineBreak(oClear);
            break;
        case 2 :
            rWrtSh.InsertColumnBreak(); break;
        case 3 :
        {
            rWrtSh.StartAllAction();
            if( !rTemplateName.isEmpty() )
                rWrtSh.InsertPageBreak( &rTemplateName, oPageNumber );
            else
                rWrtSh.InsertPageBreak();
            rWrtSh.EndAllAction();
        }
    }
}

OUString GetLocalURL(const SwWrtShell& rSh)
{
    SwField* pField = rSh.GetCurField();
    if (!pField)
    {
        return OUString();
    }

    if (pField->GetTyp()->Which() != SwFieldIds::TableOfAuthorities)
    {
        return OUString();
    }

    const auto& rAuthorityField = *static_cast<const SwAuthorityField*>(pField);
    SwAuthEntry* pAuthEntry = rAuthorityField.GetAuthEntry();
    if (!pAuthEntry)
    {
        return OUString();
    }

    const OUString& rLocalURL = pAuthEntry->GetAuthorField(AUTH_FIELD_LOCAL_URL);
    return rLocalURL;
}

void UpdateSections(const SfxRequest& rReq, SwWrtShell& rWrtSh)
{
    OUString aSectionNamePrefix;
    const SfxStringItem* pSectionNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
    if (pSectionNamePrefix)
    {
        aSectionNamePrefix = pSectionNamePrefix->GetValue();
    }

    uno::Sequence<beans::PropertyValues> aSections;
    const SfxUnoAnyItem* pSections = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2);
    if (pSections)
    {
        pSections->GetValue() >>= aSections;
    }

    rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_SECTIONS, nullptr);
    rWrtSh.StartAction();

    SwDoc* pDoc = rWrtSh.GetDoc();
    sal_Int32 nSectionIndex = 0;
    const SwSectionFormats& rFormats = pDoc->GetSections();
    IDocumentContentOperations& rIDCO = pDoc->getIDocumentContentOperations();
    for (size_t i = 0; i < rFormats.size(); ++i)
    {
        const SwSectionFormat* pFormat = rFormats[i];
        if (!pFormat->GetName().toString().startsWith(aSectionNamePrefix))
        {
            continue;
        }

        if (nSectionIndex >= aSections.getLength())
        {
            break;
        }

        comphelper::SequenceAsHashMap aMap(aSections[nSectionIndex++]);
        UIName aSectionName( aMap[u"RegionName"_ustr].get<OUString>() );
        if (aSectionName != pFormat->GetName())
        {
            const_cast<SwSectionFormat*>(pFormat)->SetFormatName(aSectionName, /*bBroadcast=*/true);
            SwSectionData aSectionData(*pFormat->GetSection());
            aSectionData.SetSectionName(aSectionName);
            pDoc->UpdateSection(i, aSectionData);
        }

        const SwFormatContent& rContent = pFormat->GetContent();
        const SwNodeIndex* pContentNodeIndex = rContent.GetContentIdx();
        if (pContentNodeIndex)
        {
            SwPaM aSectionStart(SwPosition{*pContentNodeIndex});
            aSectionStart.Move(fnMoveForward, GoInContent);
            SwPaM* pCursorPos = rWrtSh.GetCursor();
            *pCursorPos = aSectionStart;
            rWrtSh.EndOfSection(/*bSelect=*/true);
            rIDCO.DeleteAndJoin(*pCursorPos);
            rWrtSh.EndSelect();

            OUString aSectionText = aMap[u"Content"_ustr].get<OUString>();
            SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aSectionText.toUtf8());
        }
    }

    rWrtSh.EndAction();
    rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_SECTIONS, nullptr);
}

void DeleteSections(const SfxRequest& rReq, SwWrtShell& rWrtSh)
{
    OUString aSectionNamePrefix;
    const SfxStringItem* pSectionNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
    if (pSectionNamePrefix)
    {
        aSectionNamePrefix = pSectionNamePrefix->GetValue();
    }

    rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_SECTIONS, nullptr);
    rWrtSh.StartAction();
    comphelper::ScopeGuard g(
        [&rWrtSh]
        {
            rWrtSh.EndAction();
            rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_SECTIONS, nullptr);
        });

    SwDoc* pDoc = rWrtSh.GetDoc();
    std::vector<SwSectionFormat*> aRemovals;
    for (SwSectionFormat* pFormat : pDoc->GetSections())
        if (aSectionNamePrefix.isEmpty() || pFormat->GetName().toString().startsWith(aSectionNamePrefix))
            aRemovals.push_back(pFormat);

    for (const auto& pFormat : aRemovals)
    {
        // Just delete the format, not the content of the section.
        pDoc->DelSectionFormat(pFormat);
    }
}

void DeleteContentControl( const SwWrtShell& rWrtSh )
{
    SwTextContentControl* pTextContentControl = rWrtSh.CursorInsideContentControl();
    if (pTextContentControl) {
        const SwFormatContentControl& rFormatContentControl = pTextContentControl->GetContentControl();
        const std::shared_ptr<SwContentControl>& pContentControl = rFormatContentControl.GetContentControl();
        pContentControl->SetReadWrite(true);
        pTextContentControl->Delete(true);
    }
}


void UpdateBookmarks(const SfxRequest& rReq, SwWrtShell& rWrtSh)
{
    if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
    {
        return;
    }

    OUString aBookmarkNamePrefix;
    const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
    if (pBookmarkNamePrefix)
    {
        aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue();
    }

    uno::Sequence<beans::PropertyValues> aBookmarks;
    const SfxUnoAnyItem* pBookmarks = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2);
    if (pBookmarks)
    {
        pBookmarks->GetValue() >>= aBookmarks;
    }

    rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARKS, nullptr);
    rWrtSh.StartAction();

    IDocumentMarkAccess& rIDMA = *rWrtSh.GetDoc()->getIDocumentMarkAccess();
    sal_Int32 nBookmarkIndex = 0;
    bool bSortMarks = false;
    for (auto it = rIDMA.getBookmarksBegin(); it != rIDMA.getBookmarksEnd(); ++it)
    {
        sw::mark::Bookmark* pMark = *it;
        assert(pMark);
        if (!pMark->GetName().toString().startsWith(aBookmarkNamePrefix))
        {
            continue;
        }

        if (aBookmarks.getLength() <= nBookmarkIndex)
        {
            continue;
        }

        comphelper::SequenceAsHashMap aMap(aBookmarks[nBookmarkIndex++]);
        if (aMap[u"Bookmark"_ustr].get<OUString>() != pMark->GetName())
        {
            rIDMA.renameMark(pMark, SwMarkName(aMap[u"Bookmark"_ustr].get<OUString>()));
        }

        OUString aBookmarkText = aMap[u"BookmarkText"_ustr].get<OUString>();

        // Insert markers to remember where the paste positions are.
        SwPaM aMarkers(pMark->GetMarkEnd());
        IDocumentContentOperations& rIDCO = rWrtSh.GetDoc()->getIDocumentContentOperations();
        bool bSuccess = rIDCO.InsertString(aMarkers, u"XY"_ustr);
        if (bSuccess)
        {
            SwPaM aPasteEnd(pMark->GetMarkEnd());
            aPasteEnd.Move(fnMoveForward, GoInContent);

            // Paste HTML content.
            SwPaM* pCursorPos = rWrtSh.GetCursor();
            *pCursorPos = aPasteEnd;
            SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aBookmarkText.toUtf8());

            // Update the bookmark to point to the new content.
            SwPaM aPasteStart(pMark->GetMarkEnd());
            aPasteStart.Move(fnMoveForward, GoInContent);
            SwPaM aStartMarker(pMark->GetMarkStart(), *aPasteStart.GetPoint());
            SwPaM aEndMarker(*aPasteEnd.GetPoint(), *aPasteEnd.GetPoint());
            aEndMarker.GetMark()->AdjustContent(1);
            pMark->SetMarkPos(*aPasteStart.GetPoint());
            pMark->SetOtherMarkPos(*aPasteEnd.GetPoint());
            bSortMarks = true;

            // Remove markers. the start marker includes the old content as well.
            rIDCO.DeleteAndJoin(aStartMarker);
            rIDCO.DeleteAndJoin(aEndMarker);
        }
    }
    if (bSortMarks)
    {
        rIDMA.assureSortedMarkContainers();
    }

    rWrtSh.EndAction();
    rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARKS, nullptr);
}

void UpdateBookmark(const SfxRequest& rReq, SwWrtShell& rWrtSh)
{
    if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
    {
        return;
    }

    OUString aBookmarkNamePrefix;
    const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
    if (pBookmarkNamePrefix)
    {
        aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue();
    }

    uno::Sequence<beans::PropertyValue> aBookmark;
    const SfxUnoAnyItem* pBookmarks = rReq.GetArg<SfxUnoAnyItem>(FN_PARAM_2);
    if (pBookmarks)
    {
        pBookmarks->GetValue() >>= aBookmark;
    }

    IDocumentMarkAccess& rIDMA = *rWrtSh.GetDoc()->getIDocumentMarkAccess();
    SwPosition& rCursor = *rWrtSh.GetCursor()->GetPoint();
    sw::mark::Bookmark* pBookmark = rIDMA.getOneInnermostBookmarkFor(rCursor);
    if (!pBookmark || !pBookmark->GetName().toString().startsWith(aBookmarkNamePrefix))
    {
        return;
    }

    SwRewriter aRewriter;
    aRewriter.AddRule(UndoArg1, pBookmark->GetName());
    rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::UPDATE_BOOKMARK, &aRewriter);
    rWrtSh.StartAction();
    comphelper::ScopeGuard g(
        [&rWrtSh, &aRewriter]
        {
            rWrtSh.EndAction();
            rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::UPDATE_BOOKMARK, &aRewriter);
        });


    comphelper::SequenceAsHashMap aMap(aBookmark);
    if (aMap[u"Bookmark"_ustr].get<OUString>() != pBookmark->GetName())
    {
        rIDMA.renameMark(pBookmark, SwMarkName(aMap[u"Bookmark"_ustr].get<OUString>()));
    }

    // Insert markers to remember where the paste positions are.
    SwPaM aMarkers(pBookmark->GetMarkEnd());
    IDocumentContentOperations& rIDCO = rWrtSh.GetDoc()->getIDocumentContentOperations();
    if (!rIDCO.InsertString(aMarkers, u"XY"_ustr))
    {
        return;
    }

    SwPaM aPasteEnd(pBookmark->GetMarkEnd());
    aPasteEnd.Move(fnMoveForward, GoInContent);

    OUString aBookmarkText = aMap[u"BookmarkText"_ustr].get<OUString>();

    // Paste HTML content.
    SwPaM* pCursorPos = rWrtSh.GetCursor();
    *pCursorPos = aPasteEnd;
    SwTranslateHelper::PasteHTMLToPaM(rWrtSh, pCursorPos, aBookmarkText.toUtf8());

    // Update the bookmark to point to the new content.
    SwPaM aPasteStart(pBookmark->GetMarkEnd());
    aPasteStart.Move(fnMoveForward, GoInContent);
    SwPaM aStartMarker(pBookmark->GetMarkStart(), *aPasteStart.GetPoint());
    SwPaM aEndMarker(*aPasteEnd.GetPoint(), *aPasteEnd.GetPoint());
    aEndMarker.GetMark()->AdjustContent(1);
    pBookmark->SetMarkPos(*aPasteStart.GetPoint());
    pBookmark->SetOtherMarkPos(*aPasteEnd.GetPoint());

    // Remove markers. the start marker includes the old content as well.
    rIDCO.DeleteAndJoin(aStartMarker);
    rIDCO.DeleteAndJoin(aEndMarker);
    rIDMA.assureSortedMarkContainers();
}

void DeleteBookmarks(const SfxRequest& rReq, SwWrtShell& rWrtSh)
{
    if (rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
    {
        return;
    }

    OUString aBookmarkNamePrefix;
    const SfxStringItem* pBookmarkNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
    if (pBookmarkNamePrefix)
    {
        aBookmarkNamePrefix = pBookmarkNamePrefix->GetValue();
    }

    rWrtSh.GetDoc()->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_BOOKMARKS, nullptr);
    rWrtSh.StartAction();
    comphelper::ScopeGuard g(
        [&rWrtSh]
        {
            rWrtSh.EndAction();
            rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_BOOKMARKS, nullptr);
        });

    IDocumentMarkAccess* pMarkAccess = rWrtSh.GetDoc()->getIDocumentMarkAccess();
    std::vector<sw::mark::MarkBase*> aRemovals;
    for (auto it = pMarkAccess->getBookmarksBegin(); it != pMarkAccess->getBookmarksEnd(); ++it)
    {
        sw::mark::Bookmark* pBookmark = *it;
        assert(pBookmark);

        if (!aBookmarkNamePrefix.isEmpty())
        {
            if (!pBookmark->GetName().toString().startsWith(aBookmarkNamePrefix))
            {
                continue;
            }
        }

        aRemovals.push_back(pBookmark);
    }

    for (const auto& pMark : aRemovals)
    {
        pMarkAccess->deleteMark(pMark);
    }
}

void DeleteFields(const SfxRequest& rReq, SwWrtShell& rWrtSh)
{
    const SfxStringItem* pTypeName = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
    if (!pTypeName || pTypeName->GetValue() != "SetRef")
    {
        // This is implemented so far only for reference marks.
        return;
    }

    OUString aNamePrefix;
    const SfxStringItem* pNamePrefix = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
    if (pNamePrefix)
    {
        aNamePrefix = pNamePrefix->GetValue();
    }

    SwDoc* pDoc = rWrtSh.GetDoc();
    pDoc->GetIDocumentUndoRedo().StartUndo(SwUndoId::DELETE_FIELDS, nullptr);
    rWrtSh.StartAction();
    comphelper::ScopeGuard g(
        [&rWrtSh]
        {
            rWrtSh.EndAction();
            rWrtSh.GetDoc()->GetIDocumentUndoRedo().EndUndo(SwUndoId::DELETE_FIELDS, nullptr);
        });

    std::vector<const SwFormatRefMark*> aRemovals;
    for (sal_uInt16 i = 0; i < pDoc->GetRefMarks(); ++i)
    {
        const SwFormatRefMark* pRefMark = pDoc->GetRefMark(i);
        if (!aNamePrefix.isEmpty())
        {
            if (!pRefMark->GetRefName().toString().startsWith(aNamePrefix))
            {
                continue;
            }
        }

        aRemovals.push_back(pRefMark);
    }

    for (const auto& pMark : aRemovals)
    {
        pDoc->DeleteFormatRefMark(pMark);
    }
}

void lcl_LogWarning(std::string sWarning)
{
    LOK_WARN("sw.transform",  sWarning);
}

bool lcl_ChangeChartColumnCount(const uno::Reference<chart2::XChartDocument>& xChartDoc, sal_Int32 nId,
                                bool bInsert, bool bResize = false)
{
    uno::Reference<chart2::XDiagram> xDiagram = xChartDoc->getFirstDiagram();
    if (!xDiagram.is())
        return false;
    uno::Reference<chart2::XCoordinateSystemContainer> xCooSysContainer(xDiagram, uno::UNO_QUERY);
    if (!xCooSysContainer.is())
        return false;
    uno::Sequence<uno::Reference<chart2::XCoordinateSystem>> xCooSysSequence(
        xCooSysContainer->getCoordinateSystems());
    if (xCooSysSequence.getLength() <= 0)
        return false;
    uno::Reference<chart2::XChartTypeContainer> xChartTypeContainer(xCooSysSequence[0],
                                                                    uno::UNO_QUERY);
    if (!xChartTypeContainer.is())
        return false;
    uno::Sequence<uno::Reference<chart2::XChartType>> xChartTypeSequence(
        xChartTypeContainer->getChartTypes());
    if (xChartTypeSequence.getLength() <= 0)
        return false;
    uno::Reference<chart2::XDataSeriesContainer> xDSContainer(xChartTypeSequence[0],
                                                              uno::UNO_QUERY);
    if (!xDSContainer.is())
        return false;

    uno::Reference<chart2::XInternalDataProvider> xIDataProvider(xChartDoc->getDataProvider(),
                                                                 uno::UNO_QUERY);
    if (!xIDataProvider.is())
        return false;

    uno::Sequence<uno::Reference<chart2::XDataSeries>> aSeriesSeq(xDSContainer->getDataSeries());

    int nSeriesCount = aSeriesSeq.getLength();

    if (bResize)
    {
        // Resize is actually some inserts, or deletes
        if (nId > nSeriesCount)
        {
            bInsert = true;
        }
        else if (nId < nSeriesCount)
        {
            bInsert = false;
        }
        else
        {
            // Resize to the same size. No change needed
            return true;
        }
    }

    // insert or delete
    if (bInsert)
    {
        // insert
        if (nId > nSeriesCount && !bResize)
            return false;

        int nInsertCount = bResize ? nId - nSeriesCount : 1;

        // call dialog code
        if (bResize)
        {
            for (int i = 0; i < nInsertCount; i++)
            {
                xIDataProvider->insertDataSeries(nSeriesCount);
            }
            return true;
        }

        xIDataProvider->insertDataSeries(nId);
    }
    else
    {
        // delete 1 or more columns
        if (nId >= nSeriesCount)
            return false;
        int nDeleteCount = bResize ? nSeriesCount - nId : 1;
        for (int i = 0; i < nDeleteCount; i++)
        {
            xDSContainer->removeDataSeries(aSeriesSeq[nId]);
        }
    }
    return true;
}

bool lcl_ResizeChartColumns(const uno::Reference<chart2::XChartDocument>& xChartDoc, sal_Int32 nSize)
{
    return lcl_ChangeChartColumnCount(xChartDoc, nSize, falsetrue);
}

bool lcl_InsertChartColumns(const uno::Reference<chart2::XChartDocument>& xChartDoc, sal_Int32 nId)
{
    return lcl_ChangeChartColumnCount(xChartDoc, nId, true);
}

bool lcl_DeleteChartColumns(const uno::Reference<chart2::XChartDocument>& xChartDoc, sal_Int32 nId)
{
    return lcl_ChangeChartColumnCount(xChartDoc, nId, false);
}
}

static bool AddWordToWordbook(const uno::Reference<linguistic2::XDictionary>& xDictionary, SwWrtShell &rWrtSh)
{
    if (!xDictionary)
        return false;

    SwRect aToFill;
    uno::Reference<linguistic2::XSpellAlternatives>  xSpellAlt(rWrtSh.GetCorrection(nullptr, aToFill));
    if (!xSpellAlt.is())
        return false;

    OUString sWord = xSpellAlt->getWord();
    linguistic::DictionaryError nAddRes = linguistic::AddEntryToDic(xDictionary, sWord, false, OUString());
    if (linguistic::DictionaryError::NONE != nAddRes && xDictionary.is() && !xDictionary->getEntry(sWord).is())
    {
        SvxDicError(rWrtSh.GetView().GetFrameWeld(), nAddRes);
        return false;
    }
    return true;
}

void SwTextShell::Execute(SfxRequest &rReq)
{
    bool bUseDialog = true;
    const SfxItemSet *pArgs = rReq.GetArgs();
    SwWrtShell& rWrtSh = GetShell();
    const SfxPoolItem* pItem = nullptr;
    const sal_uInt16 nSlot = rReq.GetSlot();
    if(pArgs)
        pArgs->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), false, &pItem);
    switch( nSlot )
    {
        case SID_UNICODE_NOTATION_TOGGLE:
        {
            tools::Long nMaxUnits = 256;
            sal_Int32 nSelLength = rWrtSh.GetSelText().getLength();
            if( rWrtSh.IsSelection() && !rWrtSh.IsMultiSelection() && (nSelLength < nMaxUnits) )
                nMaxUnits = nSelLength;

            tools::Long index = 0;
            ToggleUnicodeCodepoint aToggle;
            while( nMaxUnits-- && aToggle.AllowMoreInput(rWrtSh.GetChar(true, index-1)) )
                --index;

            OUString sReplacement = aToggle.ReplacementString();
            if( !sReplacement.isEmpty() )
            {
                if (rWrtSh.HasReadonlySel() && !rWrtSh.CursorInsideInputField())
                {
                    // Only break if there's something to do; don't nag with the dialog otherwise
                    rWrtSh.InfoReadOnlyDialog(false);
                    break;
                }
                OUString stringToReplace = aToggle.StringToReplace();
                SwRewriter aRewriter;
                aRewriter.AddRule( UndoArg1, stringToReplace );
                aRewriter.AddRule( UndoArg2, SwResId(STR_YIELDS) );
                aRewriter.AddRule( UndoArg3, sReplacement );
                rWrtSh.StartUndo(SwUndoId::REPLACE, &aRewriter);
                rWrtSh.GetCursor()->Normalize(false);

                rWrtSh.ClearMark();
                if( rWrtSh.IsInSelect() )  // cancel any in-progress keyboard selection as well
                    rWrtSh.EndSelect();
                // Select exactly what was chosen for replacement
                rWrtSh.GetCursor()->SetMark();
                rWrtSh.GetCursor()->GetPoint()->AdjustContent(-stringToReplace.getLength());
                rWrtSh.DelLeft();
                rWrtSh.Insert2( sReplacement );
                rWrtSh.EndUndo(SwUndoId::REPLACE, &aRewriter);
            }
        }
        break;

        case SID_LANGUAGE_STATUS:
        {
            // get the language
            OUString aNewLangText;
            const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(SID_LANGUAGE_STATUS);
            if (pItem2)
                aNewLangText = pItem2->GetValue();

            //!! Remember the view frame right now...
            //!! (call to GetView().GetViewFrame() will break if the
            //!! SwTextShell got destroyed meanwhile.)
            SfxViewFrame& rViewFrame = GetView().GetViewFrame();

            if (aNewLangText == "*")
            {
                // open the dialog "Tools/Options/Languages and Locales - General"
                // to set the documents default language
                SfxAbstractDialogFactory* pFact = SfxAbstractDialogFactory::Create();
                ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateVclDialog(GetView().GetFrameWeld(), SID_LANGUAGE_OPTIONS));
                pDlg->Execute();
            }
            else
            {
                //!! We have to use StartAction / EndAction bracketing in
                //!! order to prevent possible destruction of the SwTextShell
                //!! due to the selection changes coming below.
                rWrtSh.StartAction();
                // prevent view from jumping because of (temporary) selection changes
                rWrtSh.LockView( true );

                // setting the new language...
                if (!aNewLangText.isEmpty())
                {
                    static constexpr OUString aSelectionLangPrefix(u"Current_"_ustr);
                    static constexpr OUString aParagraphLangPrefix(u"Paragraph_"_ustr);
                    static constexpr OUString aDocumentLangPrefix(u"Default_"_ustr);

                    SfxItemSetFixed<RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
                                    RES_CHRATR_CJK_LANGUAGE, RES_CHRATR_CJK_LANGUAGE,
                                    RES_CHRATR_CTL_LANGUAGE, RES_CHRATR_CTL_LANGUAGE,
                                    RES_CHRATR_SCRIPT_HINT, RES_CHRATR_SCRIPT_HINT>
                        aCoreSet(GetPool());

                    sal_Int32 nPos = 0;
                    bool bForSelection = true;
                    bool bForParagraph = false;
                    if (-1 != (nPos = aNewLangText.indexOf( aSelectionLangPrefix )))
                    {
                        // ... for the current selection
                        aNewLangText = aNewLangText.replaceAt(nPos, aSelectionLangPrefix.getLength(), u"");
                        bForSelection = true;
                    }
                    else if (-1 != (nPos = aNewLangText.indexOf(aParagraphLangPrefix)))
                    {
                        // ... for the current paragraph language
                        aNewLangText = aNewLangText.replaceAt(nPos, aParagraphLangPrefix.getLength(), u"");
                        bForSelection = true;
                        bForParagraph = true;
                    }
                    else if (-1 != (nPos = aNewLangText.indexOf(aDocumentLangPrefix)))
                    {
                        // ... as default document language
                        aNewLangText = aNewLangText.replaceAt(nPos, aDocumentLangPrefix.getLength(), u"");
                        bForSelection = false;
                    }

                    if (bForParagraph || !bForSelection)
                    {
                        rWrtSh.Push(); // save selection for later restoration
                        rWrtSh.ClearMark(); // fdo#67796: invalidate table crsr
                    }

                    if (bForParagraph)
                        SwLangHelper::SelectCurrentPara( rWrtSh );

                    if (!bForSelection) // document language to be changed...
                    {
                        rWrtSh.SelAll();
                        rWrtSh.ExtendedSelectAll();
                    }

                    rWrtSh.StartUndo( ( !bForParagraph && !bForSelection ) ? SwUndoId::SETDEFTATTR : SwUndoId::EMPTY );
                    if (aNewLangText == "LANGUAGE_NONE")
                        SwLangHelper::SetLanguage_None( rWrtSh, bForSelection, aCoreSet );
                    else if (aNewLangText == "RESET_LANGUAGES")
                        SwLangHelper::ResetLanguages( rWrtSh );
                    else
                        SwLangHelper::SetLanguage( rWrtSh, aNewLangText, bForSelection, aCoreSet );
                    rWrtSh.EndUndo();

                    if (bForParagraph || !bForSelection)
                    {
                        rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent); // restore selection...
                    }
                }

                rWrtSh.LockView( false );
                rWrtSh.EndAction();
            }

            // invalidate slot to get the new language displayed
            rViewFrame.GetBindings().Invalidate( nSlot );

            rReq.Done();
            break;
        }

        case SID_THES:
        {
            // replace word/selection with text from selected sub menu entry
            OUString aReplaceText;
            const SfxStringItem* pItem2 = rReq.GetArg(FN_PARAM_THES_WORD_REPLACE);
            if (pItem2)
                aReplaceText = pItem2->GetValue();
            if (!aReplaceText.isEmpty())
            {
                SwView &rView2 = rWrtSh.GetView();
                const bool bSelection = rWrtSh.HasSelection();
                const OUString aLookUpText = rView2.GetThesaurusLookUpText( bSelection );
                rView2.InsertThesaurusSynonym( aReplaceText, aLookUpText, bSelection );
            }
        }
        break;

        case SID_CHARMAP:
        {
            InsertSymbol( rReq );
        }
        break;
        case FN_INSERT_FOOTNOTE:
        case FN_INSERT_ENDNOTE:
        {
            OUString aStr;
            const SfxStringItem* pFont = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
            const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(nSlot);
            if ( pNameItem )
                aStr = pNameItem->GetValue();
            bool bFont = pFont && !pFont->GetValue().isEmpty();
            rWrtSh.StartUndo( SwUndoId::UI_INSERT_FOOTNOTE );
            rWrtSh.InsertFootnote( aStr, nSlot == FN_INSERT_ENDNOTE, !bFont );
            if ( bFont )
            {
                rWrtSh.Left( SwCursorSkipMode::Chars, true, 1, false );
                SfxItemSetFixed<RES_CHRATR_FONT, RES_CHRATR_FONT> aSet( rWrtSh.GetAttrPool() );
                rWrtSh.GetCurAttr( aSet );
                rWrtSh.SetAttrSet( aSet, SetAttrMode::DONTEXPAND );
                rWrtSh.ResetSelect(nullptr, false, ScrollSizeMode::ScrollSizeDefault);
                rWrtSh.EndSelect();
                rWrtSh.GotoFootnoteText();
            }
            rWrtSh.EndUndo( SwUndoId::UI_INSERT_FOOTNOTE );
            rReq.Done();
        }
        break;
        case FN_INSERT_FOOTNOTE_DLG:
        {
            SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
            VclPtr<AbstractInsFootNoteDlg> pDlg(pFact->CreateInsFootNoteDlg(
                GetView().GetFrameWeld(), rWrtSh));
            pDlg->SetHelpId(GetStaticInterface()->GetSlot(nSlot)->GetCommand());
            pDlg->StartExecuteAsync(
                [this, pDlg] (sal_Int32 nResult)->void
                {
                    if ( nResult == RET_OK )
                    {
                        pDlg->Apply();
                        const sal_uInt16 nId = pDlg->IsEndNote() ? FN_INSERT_ENDNOTE : FN_INSERT_FOOTNOTE;
                        SfxRequest aReq(GetView().GetViewFrame(), nId);
                        if ( !pDlg->GetStr().isEmpty() )
                            aReq.AppendItem( SfxStringItem( nId, pDlg->GetStr() ) );
                        if ( !pDlg->GetFontName().isEmpty() )
                            aReq.AppendItem( SfxStringItem( FN_PARAM_1, pDlg->GetFontName() ) );
                        ExecuteSlot( aReq );
                    }
                    pDlg->disposeOnce();
                }
            );
            rReq.Ignore();
        }
        break;
        case FN_FORMAT_FOOTNOTE_DLG:
        case FN_FORMAT_CURRENT_FOOTNOTE_DLG:
        {
            GetView().ExecFormatFootnote();
            break;
        }
        case SID_INSERTDOC:
        {
            GetView().ExecuteInsertDoc( rReq, pItem );
            break;
        }
        case FN_FORMAT_RESET:
        {
            // Assure the folded outline button does not remain after resetting
            // RES_PARATTR_OUTLINELEVEL and that folded outline content that becomes unfolded due to
            // RES_PARATR_GRABBAG "OutlineContentVisibleAttr" being reset is shown for outlines set by
            // a style.
            MakeAllOutlineContentTemporarilyVisible a(rWrtSh.GetDoc());

            // #i78856, reset all attributes but not the language attributes
            // (for this build an array of all relevant attributes and
            // remove the languages from that)
            o3tl::sorted_vector<sal_uInt16> aAttribs;

            static constexpr std::pair<sal_uInt16, sal_uInt16> aResetableSetRange[] = {
                // tdf#40496: we don't want to change writing direction, so exclude RES_FRAMEDIR:
                { RES_FRMATR_BEGIN, RES_FRAMEDIR - 1 },
                { RES_FRAMEDIR + 1, RES_FRMATR_END - 1 },
                { RES_CHRATR_BEGIN, RES_CHRATR_LANGUAGE - 1 },
                { RES_CHRATR_LANGUAGE + 1, RES_CHRATR_CJK_LANGUAGE - 1 },
                { RES_CHRATR_CJK_LANGUAGE + 1, RES_CHRATR_CTL_LANGUAGE - 1 },
                { RES_CHRATR_CTL_LANGUAGE + 1, RES_CHRATR_END - 1 },
                { RES_PARATR_BEGIN, RES_PARATR_END - 1 },
                { RES_PARATR_LIST_AUTOFMT, RES_PARATR_LIST_AUTOFMT },
                { RES_TXTATR_UNKNOWN_CONTAINER, RES_TXTATR_UNKNOWN_CONTAINER },
                { RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END - 1 },
            };
            for (const auto& [nBegin, nEnd] : aResetableSetRange)
            {
                for (sal_uInt16 i = nBegin; i <= nEnd; ++i)
                    aAttribs.insert( i );
            }

            // also clear the direct formatting flag inside SwTableBox(es)
            if (SwFEShell* pFEShell = GetView().GetDocShell()->GetFEShell())
                pFEShell->UpdateTableStyleFormatting(nullptr, true);

            // tdf#160801 fix crash by delaying resetting of attributes
            // Calling SwWrtShell::ResetAttr() will sometimes delete the
            // current SwTextShell instance so call it after clearing the
            // direct formatting flag.
            rWrtSh.ResetAttr( aAttribs );

            rReq.Done();
            break;
        }
        case FN_INSERT_BREAK_DLG:
        {
            if ( pItem )
            {
                ::std::optional<sal_uInt16> oPageNumber;
                std::optional<SwLineBreakClear> oClear;
                UIName aTemplateName;
                sal_uInt16 nKind = static_cast<const SfxInt16Item*>(pItem)->GetValue();
                const SfxStringItem* pTemplate = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
                const SfxUInt16Item* pNumber = rReq.GetArg<SfxUInt16Item>(FN_PARAM_2);
                const SfxBoolItem* pIsNumberFilled = rReq.GetArg<SfxBoolItem>(FN_PARAM_3);
                if ( pTemplate )
                    aTemplateName = UIName(pTemplate->GetValue());
                if ( pNumber && pIsNumberFilled && pIsNumberFilled->GetValue() )
                    oPageNumber = pNumber->GetValue();

                InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName, oClear);
            }
            else
            {
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();

                std::shared_ptr<AbstractSwBreakDlg> pAbstractDialog(pFact->CreateSwBreakDlg(GetView().GetFrameWeld(), rWrtSh));
                std::shared_ptr<weld::DialogController> pDialogController(pAbstractDialog->getDialogController());

                weld::DialogController::runAsync(pDialogController,
                    [pAbstractDialog=std::move(pAbstractDialog), &rWrtSh] (sal_Int32 nResult) {
                        if( RET_OK == nResult )
                        {
                            sal_uInt16 nKind = pAbstractDialog->GetKind();
                            OUString aTemplateName = pAbstractDialog->GetTemplateName();
                            ::std::optional<sal_uInt16> oPageNumber = pAbstractDialog->GetPageNumber();
                            std::optional<SwLineBreakClear> oClear = pAbstractDialog->GetClear();

                            InsertBreak(rWrtSh, nKind, oPageNumber, UIName(aTemplateName), oClear);
                        }
                    });
            }

            break;
        }
        case FN_INSERT_BOOKMARK:
        {
            const SfxStringItem* pBookmarkText = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
            SwPaM* pCursorPos = rWrtSh.GetCursor();
            if ( pItem )
            {
                rWrtSh.StartAction();
                OUString sName = static_cast<const SfxStringItem*>(pItem)->GetValue();

                if (pBookmarkText)
                {
                    OUString aBookmarkText = pBookmarkText->GetValue();
                    // Split node to remember where the start position is.
                    bool bSuccess = rWrtSh.GetDoc()->getIDocumentContentOperations().SplitNode(
                        *pCursorPos->GetPoint(), /*bChkTableStart=*/false);
                    if (bSuccess)
                    {
                        SwPaM aBookmarkPam(*pCursorPos->GetPoint());
                        aBookmarkPam.Move(fnMoveBackward, GoInContent);

                        // Paste HTML content.
                        SwTranslateHelper::PasteHTMLToPaM(
                            rWrtSh, pCursorPos, aBookmarkText.toUtf8());
                        if (pCursorPos->GetPoint()->GetContentIndex() == 0)
                        {
                            // The paste created a last empty text node, remove it.
                            SwPaM aPam(*pCursorPos->GetPoint());
                            aPam.SetMark();
                            aPam.Move(fnMoveBackward, GoInContent);
                            rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(aPam);
                        }

                        // Undo the above SplitNode().
                        aBookmarkPam.SetMark();
                        aBookmarkPam.Move(fnMoveForward, GoInContent);
                        rWrtSh.GetDoc()->getIDocumentContentOperations().DeleteAndJoin(
                            aBookmarkPam);
                        *aBookmarkPam.GetMark() = *pCursorPos->GetPoint();
                        *pCursorPos = aBookmarkPam;
                    }
                }

                rWrtSh.SetBookmark( vcl::KeyCode(), SwMarkName(sName) );
                if (pBookmarkText)
                {
                    pCursorPos->DeleteMark();
                }
                rWrtSh.EndAction();
                break;
            }
            [[fallthrough]];
        }
        case FN_EDIT_BOOKMARK:
        {
            ::std::optional<OUString> oName;
            if (pItem)
            {
                oName.emplace(static_cast<const SfxStringItem*>(pItem)->GetValue());
            }
            {
                SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
                ScopedVclPtr<VclAbstractDialog> pDlg(pFact->CreateSwInsertBookmarkDlg(GetView().GetFrameWeld(), rWrtSh, oName ? &*oName : nullptr));
                VclAbstractDialog::AsyncContext aContext;
                aContext.maEndDialogFn = [](sal_Int32){};
                pDlg->StartExecuteAsync(aContext);
            }

            break;
        }
        case FN_UPDATE_BOOKMARKS:
        {
            // This updates all bookmarks in the document that match the conditions specified in
            // rReq.
            UpdateBookmarks(rReq, rWrtSh);
            break;
        }
        case FN_UPDATE_BOOKMARK:
        {
            // This updates the bookmark under the cursor.
            UpdateBookmark(rReq, rWrtSh);
            break;
        }
        case FN_DELETE_BOOKMARK:
        {
            // This deletes a bookmark with the specified name.
            if (pItem && !rWrtSh.getIDocumentSettingAccess().get(DocumentSettingId::PROTECT_BOOKMARKS))
            {
                IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess();
                pMarkAccess->deleteMark(pMarkAccess->findMark(SwMarkName(static_cast<const SfxStringItem*>(pItem)->GetValue())), false);
            }
            break;
        }
        case FN_DELETE_BOOKMARKS:
        {
            // This deletes all bookmarks in the document matching a specified prefix.
            DeleteBookmarks(rReq, rWrtSh);
            break;
        }
        case FN_DELETE_FIELDS:
        {
            // This deletes all fields in the document matching a specified type & prefix.
            DeleteFields(rReq, rWrtSh);
            break;
        }
        case FN_UPDATE_SECTIONS:
        {
            UpdateSections(rReq, rWrtSh);
            break;
        }
        case FN_DELETE_SECTIONS:
        {
            // This deletes all sections in the document matching a specified prefix. Note that the
            // section is deleted, but not its contents.
            DeleteSections(rReq, rWrtSh);
            break;
        }
        case FN_DELETE_CONTENT_CONTROL:
        {
            DeleteContentControl( rWrtSh );
            break;
        }
        case FN_SET_REMINDER:
        {
            // collect and sort navigator reminder names
            IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess();
            std::vector< SwMarkName > vNavMarkNames;
            for(auto ppMark = pMarkAccess->getAllMarksBegin();
                ppMark != pMarkAccess->getAllMarksEnd();
                ++ppMark)
            {
                if( IDocumentMarkAccess::GetType(**ppMark) == IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER )
                    vNavMarkNames.push_back((*ppMark)->GetName());
            }
            std::sort(vNavMarkNames.begin(), vNavMarkNames.end());

            // we are maxed out so delete the first one
            // this assumes that IDocumentMarkAccess generates Names in ascending order
            if(vNavMarkNames.size() == MAX_MARKS)
                pMarkAccess->deleteMark(pMarkAccess->findMark(vNavMarkNames[0]), false);

            rWrtSh.SetBookmark(vcl::KeyCode(), SwMarkName(), IDocumentMarkAccess::MarkType::NAVIGATOR_REMINDER);
            SwView::SetActMark(vNavMarkNames.size() < MAX_MARKS ? vNavMarkNames.size() : MAX_MARKS-1);

            break;
        }
        case FN_AUTOFORMAT_REDLINE_APPLY:
        {
            SvxSwAutoFormatFlags aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
            // This must always be false for the postprocessing.
            aFlags.bAFormatByInput = false;
            aFlags.bWithRedlining = true;
            rWrtSh.AutoFormat( &aFlags, false );
            aFlags.bWithRedlining = false;

            SfxViewFrame& rVFrame = GetView().GetViewFrame();
            if (rVFrame.HasChildWindow(FN_REDLINE_ACCEPT))
                rVFrame.ToggleChildWindow(FN_REDLINE_ACCEPT);

            SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
            auto xRequest = std::make_shared<SfxRequest>(rReq);
            rReq.Ignore(); // the 'old' request is not relevant any more
            VclPtr<AbstractSwModalRedlineAcceptDlg> pDlg(pFact->CreateSwModalRedlineAcceptDlg(GetView().GetEditWin().GetFrameWeld()));
            pDlg->StartExecuteAsync(
                [pDlg, xRequest=std::move(xRequest)] (sal_Int32 /*nResult*/)->void
                {
                    pDlg->disposeOnce();
                    xRequest->Done();
                }
            );
        }
        break;

        case FN_AUTOFORMAT_APPLY:
        {
            SvxSwAutoFormatFlags aFlags(SvxAutoCorrCfg::Get().GetAutoCorrect()->GetSwFlags());
            // This must always be false for the postprocessing.
            aFlags.bAFormatByInput = false;
            rWrtSh.AutoFormat( &aFlags, false );
            rReq.Done();
        }
        break;
        case FN_AUTOFORMAT_AUTO:
        {
            SvxAutoCorrCfg& rACfg = SvxAutoCorrCfg::Get();
            bool bSet = pItem ? static_cast<const SfxBoolItem*>(pItem)->GetValue() : !rACfg.IsAutoFormatByInput();
            if( bSet != rACfg.IsAutoFormatByInput() )
            {
                rACfg.SetAutoFormatByInput( bSet );
                rACfg.Commit();
                GetView().GetViewFrame().GetBindings().Invalidate( nSlot );
                if ( !pItem )
                    rReq.AppendItem( SfxBoolItem( GetPool().GetWhichIDFromSlotID(nSlot), bSet ) );
                rReq.Done();
            }
        }
        break;
        case FN_AUTO_CORRECT:
        {
            // At first set to blank as default.
            rWrtSh.AutoCorrect( *SvxAutoCorrCfg::Get().GetAutoCorrect(), ' ' );
            rReq.Done();
        }
        break;
        case FN_TABLE_SORT_DIALOG:
        case FN_SORTING_DLG:
        {
            SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
            VclPtr<AbstractSwSortDlg> pDlg(pFact->CreateSwSortingDialog(GetView().GetFrameWeld(), rWrtSh));
            auto xRequest = std::make_shared<SfxRequest>(rReq);
            rReq.Ignore(); // the 'old' request is not relevant any more
            pDlg->StartExecuteAsync(
                [pDlg, xRequest=std::move(xRequest)] (sal_Int32 nResult)->void
                {
                    if (nResult == RET_OK)
                        pDlg->Apply();
                    pDlg->disposeOnce();
                    xRequest->Done();
                }
            );
        }
        break;
        case FN_NUMBERING_OUTLINE_DLG:
        {
            GetView().ExecNumberingOutline(GetPool());
            rReq.Done();
        }
            break;
        case FN_CALCULATE:
            {
                rtl::Reference<SwTransferable> pTransfer = new SwTransferable( rWrtSh );
                pTransfer->CalculateAndCopy();
                rReq.Done();
            }
            break;
        case FN_GOTO_REFERENCE:
        {
            SwField *pField = rWrtSh.GetCurField();
            if(pField && pField->GetTypeId() == SwFieldTypesEnum::GetRef)
            {
                rWrtSh.StartAllAction();
                rWrtSh.SwCursorShell::GotoRefMark( static_cast<SwGetRefField*>(pField)->GetSetRefName(),
                                    static_cast<SwGetRefField*>(pField)->GetSubType(),
                                    static_cast<SwGetRefField*>(pField)->GetSeqNo(),
                                    static_cast<SwGetRefField*>(pField)->GetFlags() );
                rWrtSh.EndAllAction();
                rReq.Done();
            }
        }
            break;
        case FN_EDIT_FORMULA:
        {
            const sal_uInt16 nId = SwInputChild::GetChildWindowId();
            SfxViewFrame& rVFrame = GetView().GetViewFrame();
            if(pItem)
            {
                //if the ChildWindow is active it has to be removed
                if( rVFrame.HasChildWindow( nId ) )
                {
                    rVFrame.ToggleChildWindow( nId );
                    rVFrame.GetBindings().InvalidateAll( true );
                }

                OUString sFormula(static_cast<const SfxStringItem*>(pItem)->GetValue());
                SwFieldMgr aFieldMgr;
                rWrtSh.StartAllAction();
                bool bDelSel = rWrtSh.HasSelection();
                if( bDelSel )
                {
                    rWrtSh.StartUndo( SwUndoId::START );
                    rWrtSh.DelRight();
                }
                else
                {
                    rWrtSh.EnterStdMode();
                }

                if( !bDelSel && aFieldMgr.GetCurField() && SwFieldTypesEnum::Formel == aFieldMgr.GetCurTypeId() )
                    aFieldMgr.UpdateCurField( aFieldMgr.GetCurField()->GetFormat(), OUString(), sFormula );
                else if( !sFormula.isEmpty() )
                {
                    if( rWrtSh.IsCursorInTable() )
                    {
                        SfxItemSetFixed<RES_BOXATR_FORMULA, RES_BOXATR_FORMULA> aSet( rWrtSh.GetAttrPool() );
                        aSet.Put( SwTableBoxFormula( sFormula ));
                        rWrtSh.SetTableBoxFormulaAttrs( aSet );
                        rWrtSh.UpdateTable();
                    }
                    else
                    {
                        SvNumberFormatter* pFormatter = rWrtSh.GetNumberFormatter();
                        const sal_uInt32 nSysNumFormat = pFormatter->GetFormatIndex( NF_NUMBER_STANDARD, LANGUAGE_SYSTEM);
                        SwInsertField_Data aData(SwFieldTypesEnum::Formel, nsSwGetSetExpType::GSE_FORMULA, OUString(), sFormula, nSysNumFormat);
                        aFieldMgr.InsertField(aData);
                    }
                }

                if( bDelSel )
                    rWrtSh.EndUndo( SwUndoId::END );
                rWrtSh.EndAllAction();
                rReq.Done();
            }
            else
            {
                rWrtSh.EndAllTableBoxEdit();
                rVFrame.ToggleChildWindow( nId );
                if( !rVFrame.HasChildWindow( nId ) )
                    rVFrame.GetBindings().InvalidateAll( true );
                rReq.Ignore();
            }
        }

        break;
        case FN_TABLE_UNSET_READ_ONLY:
        {
            rWrtSh.UnProtectTables();
        }
        break;
        case SID_EDIT_HYPERLINK:
        {
            if (!rWrtSh.HasSelection())
            {
                SfxItemSetFixed<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT> aSet(GetPool());
                rWrtSh.GetCurAttr(aSet);
                if (SfxItemState::SET > aSet.GetItemState(RES_TXTATR_INETFMT))
                {
                    // Didn't find a hyperlink to edit yet.

                    // If the cursor is just before an unselected hyperlink,
                    // the dialog will not know that it should edit that hyperlink,
                    // so in this case, first select it so the dialog will find the hyperlink.
                    // The dialog would leave the hyperlink selected anyway after a successful edit
                    // (although it isn't normally selected after a cancel, but oh well).
                    if (!rWrtSh.SelectTextAttr(RES_TXTATR_INETFMT))
                        break;
                }
            }

            GetView().GetViewFrame().SetChildWindow(SID_HYPERLINK_DIALOG, true);
        }
        break;
        case SID_REMOVE_HYPERLINK:
        {
            bool bSel = rWrtSh.HasSelection();
            if(!bSel)
            {
                rWrtSh.StartAction();
                rWrtSh.Push();
                if(!rWrtSh.SelectTextAttr( RES_TXTATR_INETFMT ))
                    rWrtSh.SelWrd();
            }
            //now remove the attribute
            rWrtSh.ResetAttr({ RES_TXTATR_INETFMT });
            if(!bSel)
            {
                rWrtSh.Pop(SwCursorShell::PopMode::DeleteCurrent);
                rWrtSh.EndAction();
            }
        }
        break;
        case SID_ATTR_BRUSH_CHAR :
        case SID_ATTR_CHAR_SCALEWIDTH :
        case SID_ATTR_CHAR_ROTATED :
        case FN_TXTATR_INET :
        {
            const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID( nSlot );
            if ( pArgs && pArgs->GetItemState( nWhich ) == SfxItemState::SET )
                bUseDialog = false;
            [[fallthrough]];
        }
        case SID_CHAR_DLG:
        case SID_CHAR_DLG_EFFECT:
        case SID_CHAR_DLG_POSITION:
        {
            sw_CharDialog(rWrtSh, bUseDialog, /*ApplyToParagraph*/false, nSlot, pArgs, &rReq);
        }
        break;
        case SID_CHAR_DLG_FOR_PARAGRAPH:
        {
            sw_CharDialog(rWrtSh, /*UseDialog*/true, /*ApplyToParagraph*/true, nSlot, pArgs, &rReq);
        }
        break;
        case SID_ATTR_LRSPACE :
        case SID_ATTR_ULSPACE :
        case SID_ATTR_BRUSH :
        case SID_PARA_VERTALIGN :
        case SID_ATTR_PARA_NUMRULE :
        case SID_ATTR_PARA_REGISTER :
        case SID_ATTR_PARA_PAGENUM :
        case FN_FORMAT_LINENUMBER :
        case FN_NUMBER_NEWSTART :
        case FN_NUMBER_NEWSTART_AT :
        case FN_FORMAT_DROPCAPS :
        case FN_DROP_TEXT:
        case SID_ATTR_PARA_LRSPACE:
        {
            const sal_uInt16 nWhich = GetPool().GetWhichIDFromSlotID( nSlot );
            if ( pArgs && pArgs->GetItemState( nWhich ) == SfxItemState::SET )
                bUseDialog = false;
            [[fallthrough]];
        }
        case SID_PARA_DLG:
        {
            SwPaM* pPaM = nullptr;

            if ( pArgs )
            {
                const SwPaMItem* pPaMItem = pArgs->GetItemIfSet( GetPool().GetWhichIDFromSlotID( FN_PARAM_PAM ), false );
                if ( pPaMItem )
                    pPaM = pPaMItem->GetValue( );
            }

            if ( !pPaM )
                pPaM = rWrtSh.GetCursor();

            FieldUnit eMetric = ::GetDfltMetric( dynamic_cast<SwWebView*>( &GetView()) != nullptr );
            SwModule* mod = SwModule::get();
            mod->PutItem(SfxUInt16Item(SID_ATTR_METRIC, static_cast<sal_uInt16>(eMetric)));

            bool bApplyCharUnit = ::HasCharUnit( dynamic_cast<SwWebView*>( &GetView()) != nullptr  );
            mod->PutItem(SfxBoolItem(SID_ATTR_APPLYCHARUNIT, bApplyCharUnit));

            SfxItemSetFixed<
                    RES_PARATR_BEGIN, RES_FRMATR_END - 1,
                    // FillAttribute support:
                    XATTR_FILL_FIRST, XATTR_FILL_LAST,
                    // Includes SID_ATTR_TABSTOP_POS:
                    SID_ATTR_TABSTOP_DEFAULTS, SID_ATTR_TABSTOP_OFFSET,
                    SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_INNER,
                    SID_ATTR_PARA_MODEL, SID_ATTR_PARA_KEEP,
                    // Items to hand over XPropertyList things like XColorList,
                    // XHatchList, XGradientList, and XBitmapList to the Area
                    // TabPage:
                    SID_COLOR_TABLE, SID_PATTERN_LIST,
                    SID_HTML_MODE, SID_HTML_MODE,
                    SID_ATTR_PARA_PAGENUM, SID_ATTR_PARA_PAGENUM,
                    FN_PARAM_1, FN_PARAM_1,
                    FN_NUMBER_NEWSTART, FN_NUMBER_NEWSTART_AT,
                    FN_DROP_TEXT, FN_DROP_CHAR_STYLE_NAME>  aCoreSet( GetPool() );

            // get also the list level indent values merged as LR-SPACE item, if needed.
            rWrtSh.GetPaMAttr( pPaM, aCoreSet, true );

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

--> maximum size reached

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

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.21 Sekunden  (vorverarbeitet)  ¤

*© 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.