tdf#140257 duplicate entire PaM ring when making copy

tdf#134439, tdf#135636 are the motivation behind copying the PaM, but
multiselections require multiple PaMs

Change-Id: I9f95eb6c62ac0e61053298d4e4dbe386f5686275
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110681
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
diff --git a/sw/source/uibase/inc/basesh.hxx b/sw/source/uibase/inc/basesh.hxx
index b442613..6e924a6 100644
--- a/sw/source/uibase/inc/basesh.hxx
+++ b/sw/source/uibase/inc/basesh.hxx
@@ -24,10 +24,12 @@
#include <tools/link.hxx>
#include <sfx2/module.hxx>
#include <sfx2/shell.hxx>

#include <mdiexp.hxx>
#include <memory>
#include <set>
#include <vector>

class SwPaM;
class SwWrtShell;
class SwView;
class SfxItemSet;
@@ -110,6 +112,10 @@ public:
    static void    SetFrameMode( FlyMode eMode, SwWrtShell *pShell );  // with update!
    static void   SetFrameMode_( FlyMode eMode )   { eFrameMode = eMode; }
    static FlyMode  GetFrameMode()                 { return eFrameMode;  }

    // duplicate rOrig and rOrig's multi-selection Ring so the first element of the returned
    // vector can be used equivalently to rOrig to affect the same selections
    static std::shared_ptr<std::vector<std::unique_ptr<SwPaM>>> CopyPaMRing(SwPaM& rOrig);
};

#endif
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index e0af002..359dea0 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -3039,4 +3039,16 @@ void SwBaseShell::ExecField( SfxRequest const & rReq )
    }
}

std::shared_ptr<std::vector<std::unique_ptr<SwPaM>>> SwBaseShell::CopyPaMRing(SwPaM& rOrig)
{
    auto vCursors = std::make_shared<std::vector<std::unique_ptr<SwPaM>>>();
    vCursors->emplace_back(std::make_unique<SwPaM>(rOrig, nullptr));
    for (auto& rCursor : rOrig.GetRingContainer())
    {
        if (&rCursor != &rOrig)
            vCursors->emplace_back(std::make_unique<SwPaM>(rCursor, vCursors->front().get()));
    }
    return vCursors;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/tabsh.cxx b/sw/source/uibase/shells/tabsh.cxx
index 247d5b4..34d98f6 100644
--- a/sw/source/uibase/shells/tabsh.cxx
+++ b/sw/source/uibase/shells/tabsh.cxx
@@ -596,11 +596,11 @@ void SwTableShell::Execute(SfxRequest &rReq)
                auto pRequest = std::make_shared<SfxRequest>(rReq);
                rReq.Ignore(); // the 'old' request is not relevant any more

                auto xPaM(std::make_shared<SwPaM>(*rSh.GetCursor(), nullptr)); // tdf#135636 make a copy to use at later apply
                pDlg->StartExecuteAsync([pDlg, pRequest, pTableRep, &rBindings, &rSh, xPaM](sal_Int32 nResult){
                auto vCursors = CopyPaMRing(*rSh.GetCursor()); // tdf#135636 make a copy to use at later apply
                pDlg->StartExecuteAsync([pDlg, pRequest, pTableRep, &rBindings, &rSh, vCursors](sal_Int32 nResult){
                    if (RET_OK == nResult)
                    {
                        rSh.SetSelection(*xPaM); // tdf#135636 set the table selected at dialog launch as current selection
                        rSh.SetSelection(*vCursors->front()); // tdf#135636 set the table selected at dialog launch as current selection

                        const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();

diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx
index b7d3d60..a41c9e9 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -1079,8 +1079,8 @@ void SwTextShell::Execute(SfxRequest &rReq)
                auto pRequest = std::make_shared<SfxRequest>(rReq);
                rReq.Ignore(); // the 'old' request is not relevant any more

                auto xPaM(std::make_shared<SwPaM>(*pPaM, nullptr)); // tdf#134439 make a copy to use at later apply
                pDlg->StartExecuteAsync([pDlg, &rWrtSh, pRequest, nDefDist, xPaM](sal_Int32 nResult){
                auto vCursors = CopyPaMRing(*pPaM); // tdf#134439 make a copy to use at later apply
                pDlg->StartExecuteAsync([pDlg, &rWrtSh, pRequest, nDefDist, vCursors](sal_Int32 nResult){
                    if (nResult == RET_OK)
                    {
                        // Apply defaults if necessary.
@@ -1110,7 +1110,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
                            pSet->Put(SfxStringItem(FN_DROP_CHAR_STYLE_NAME, sCharStyleName));
                        }

                        sw_ParagraphDialogResult(pSet, rWrtSh, *pRequest, xPaM.get());
                        sw_ParagraphDialogResult(pSet, rWrtSh, *pRequest, vCursors->front().get());
                    }
                    pDlg->disposeOnce();
                });