sd: Make search bound to a view - to allow independent searching

Before if two windows are open, the search is not independent
because Outline class is not independent for a view (because of
FuSearch which remembers the view from when the it was created
and then an instance is stored in the DocShell).
This creates a SearchContext class stored on a View, which stores
the actual View bound FuSearch instance, fix us the calls.

Also move the VectorGraphicSearchContext back into Outline::Impl,
because it doesn't need to be bound to the view anymore.

Change-Id: I6a5ce71efafa378845eee4ac9574e2e4301138d2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101224
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
diff --git a/sd/source/ui/docshell/docshel3.cxx b/sd/source/ui/docshell/docshel3.cxx
index 667a5a9..8ae543c 100644
--- a/sd/source/ui/docshell/docshel3.cxx
+++ b/sd/source/ui/docshell/docshel3.cxx
@@ -166,30 +166,37 @@ void DrawDocShell::Execute( SfxRequest& rReq )

        case FID_SEARCH_OFF:
        {
            if( dynamic_cast< FuSearch* >(mxDocShellFunction.get()) )
            if (mpViewShell)
            {
                // End Search&Replace in all docshells
                SfxObjectShell* pFirstShell = SfxObjectShell::GetFirst();
                SfxObjectShell* pShell = pFirstShell;

                while (pShell)
                sd::View* pView = mpViewShell->GetView();
                if (pView)
                {
                    if( dynamic_cast< const DrawDocShell *>( pShell ) !=  nullptr)
                    {
                        static_cast<DrawDocShell*>(pShell)->CancelSearching();
                    }
                    auto& rFunctionContext = pView->getSearchContext();
                    rtl::Reference<FuSearch>& xFuSearch(rFunctionContext.getFunctionSearch());

                    pShell = SfxObjectShell::GetNext(*pShell);

                    if (pShell == pFirstShell)
                    if (xFuSearch.is())
                    {
                        pShell = nullptr;
                        // End Search&Replace in all docshells
                        SfxObjectShell* pFirstShell = SfxObjectShell::GetFirst();
                        SfxObjectShell* pShell = pFirstShell;

                        while (pShell)
                        {
                            auto pDrawDocShell = dynamic_cast<DrawDocShell*>(pShell);
                            if (pDrawDocShell)
                                pDrawDocShell->CancelSearching();

                            pShell = SfxObjectShell::GetNext(*pShell);

                            if (pShell == pFirstShell)
                                pShell = nullptr;
                        }

                        rFunctionContext.resetSearchFunction();
                        Invalidate();
                        rReq.Done();
                    }
                }

                SetDocShellFunction(nullptr);
                Invalidate();
                rReq.Done();
            }
        }
        break;
@@ -198,23 +205,30 @@ void DrawDocShell::Execute( SfxRequest& rReq )
        {
            const SfxItemSet* pReqArgs = rReq.GetArgs();

            if ( pReqArgs )
            if (pReqArgs && mpViewShell)
            {
                rtl::Reference< FuSearch > xFuSearch( dynamic_cast< FuSearch* >( GetDocShellFunction().get() ) );

                if( !xFuSearch.is() && mpViewShell )
                sd::View* pView = mpViewShell->GetView();
                if (pView)
                {
                    ::sd::View* pView = mpViewShell->GetView();
                    SetDocShellFunction( FuSearch::Create( mpViewShell, mpViewShell->GetActiveWindow(), pView, mpDoc, rReq ) );
                    xFuSearch.set( dynamic_cast< FuSearch* >( GetDocShellFunction().get() ) );
                }
                    rtl::Reference<FuSearch> & xFuSearch = pView->getSearchContext().getFunctionSearch();

                if( xFuSearch.is() )
                {
                    const SvxSearchItem& rSearchItem = pReqArgs->Get(SID_SEARCH_ITEM);
                    if (!xFuSearch.is())
                    {
                        xFuSearch = rtl::Reference<FuSearch>(
                            FuSearch::createPtr(mpViewShell,
                                                mpViewShell->GetActiveWindow(),
                                                pView, mpDoc, rReq));

                    SD_MOD()->SetSearchItem(std::unique_ptr<SvxSearchItem>(rSearchItem.Clone()));
                    xFuSearch->SearchAndReplace(&rSearchItem);
                        pView->getSearchContext().setSearchFunction(xFuSearch);
                    }

                    if (xFuSearch.is())
                    {
                        const SvxSearchItem& rSearchItem = pReqArgs->Get(SID_SEARCH_ITEM);

                        SD_MOD()->SetSearchItem(std::unique_ptr<SvxSearchItem>(rSearchItem.Clone()));
                        xFuSearch->SearchAndReplace(&rSearchItem);
                    }
                }
            }

@@ -425,14 +439,6 @@ void DrawDocShell::Execute( SfxRequest& rReq )
    }
}

void DrawDocShell::SetDocShellFunction( const rtl::Reference<FuPoor>& xFunction )
{
    if( mxDocShellFunction.is() )
        mxDocShellFunction->Dispose();

    mxDocShellFunction = xFunction;
}

} // end of namespace sd

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/docshell/docshell.cxx b/sd/source/ui/docshell/docshell.cxx
index 86fa919..f0c1a0a 100644
--- a/sd/source/ui/docshell/docshell.cxx
+++ b/sd/source/ui/docshell/docshell.cxx
@@ -164,7 +164,15 @@ DrawDocShell::~DrawDocShell()

    mbInDestruction = true;

    SetDocShellFunction(nullptr);
    if (mpViewShell)
    {
        auto* pView = mpViewShell->GetView();
        if (pView)
        {
            auto & pSearchContext = pView->getSearchContext();
            pSearchContext.resetSearchFunction();
        }
    }

    mpFontList.reset();

@@ -373,9 +381,14 @@ void DrawDocShell::UpdateTablePointers()

void DrawDocShell::CancelSearching()
{
    if( dynamic_cast<FuSearch*>( mxDocShellFunction.get() ) )
    if (mpViewShell)
    {
        SetDocShellFunction(nullptr);
        auto* pView = mpViewShell->GetView();
        if (pView)
        {
            auto & pSearchContext = pView->getSearchContext();
            pSearchContext.resetSearchFunction();
        }
    }
}

diff --git a/sd/source/ui/func/fusearch.cxx b/sd/source/ui/func/fusearch.cxx
index 08eee2d..8e07d5b 100644
--- a/sd/source/ui/func/fusearch.cxx
+++ b/sd/source/ui/func/fusearch.cxx
@@ -57,13 +57,18 @@ FuSearch::FuSearch (
{
}

rtl::Reference<FuPoor> FuSearch::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
FuSearch* FuSearch::createPtr(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq)
{
    rtl::Reference<FuPoor> xFunc( new FuSearch( pViewSh, pWin, pView, pDoc, rReq ) );
    FuSearch* xFunc( new FuSearch( pViewSh, pWin, pView, pDoc, rReq ) );
    xFunc->DoExecute(rReq);
    return xFunc;
}

rtl::Reference<FuPoor> FuSearch::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq )
{
    return rtl::Reference<FuPoor>(createPtr(pViewSh, pWin, pView, pDoc, rReq));
}

void FuSearch::DoExecute( SfxRequest& )
{
    mpViewShell->GetViewFrame()->GetBindings().Invalidate( SidArraySpell );
diff --git a/sd/source/ui/inc/DrawDocShell.hxx b/sd/source/ui/inc/DrawDocShell.hxx
index a8d6dd3..d6639c7 100644
--- a/sd/source/ui/inc/DrawDocShell.hxx
+++ b/sd/source/ui/inc/DrawDocShell.hxx
@@ -106,8 +106,6 @@ public:

    sd::ViewShell* GetViewShell() { return mpViewShell; }
    ::sd::FrameView* GetFrameView();
    const rtl::Reference<FuPoor>& GetDocShellFunction() const { return mxDocShellFunction; }
    void SetDocShellFunction( const rtl::Reference<FuPoor>& xFunction );

    SdDrawDocument*         GetDoc() { return mpDoc;}
    DocumentType            GetDocumentType() const { return meDocType; }
@@ -211,7 +209,6 @@ protected:
    VclPtr<SfxPrinter>      mpPrinter;
    ::sd::ViewShell*        mpViewShell;
    std::unique_ptr<FontList> mpFontList;
    rtl::Reference<FuPoor> mxDocShellFunction;
    DocumentType            meDocType;
    SfxStyleFamily          mnStyleFamily;
    o3tl::span<sal_uInt16 const>
diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx
index d7da6fc..4693ce3 100644
--- a/sd/source/ui/inc/View.hxx
+++ b/sd/source/ui/inc/View.hxx
@@ -27,9 +27,9 @@
#include <svx/fmview.hxx>
#include <svx/svdpage.hxx>
#include <vcl/idle.hxx>
#include <VectorGraphicSearchContext.hxx>

#include "smarttag.hxx"
#include "fusearch.hxx"

class SdDrawDocument;
class SdPage;
@@ -67,6 +67,30 @@ public:
    void End();
};

class SearchContext
{
private:
    rtl::Reference<FuSearch> maFunctionSearch;

public:
    rtl::Reference<FuSearch>& getFunctionSearch()
    {
        return maFunctionSearch;
    }

    void setSearchFunction(rtl::Reference<FuSearch> const & xFunction)
    {
        resetSearchFunction();
        maFunctionSearch = xFunction;
    }

    void resetSearchFunction()
    {
        if (maFunctionSearch.is())
            maFunctionSearch->Dispose();
    }
};

class SAL_DLLPUBLIC_RTTI View : public FmFormView
{
public:
@@ -218,8 +242,7 @@ public:
    void SetAuthor(const OUString& rAuthor) { m_sAuthor = rAuthor; }
    const OUString& GetAuthor() const { return m_sAuthor; }

    VectorGraphicSearchContext& getVectorGraphicSearchContext() { return aVectorGraphicSearchContext; }

    SearchContext& getSearchContext() { return maSearchContext; }
protected:
    DECL_LINK( OnParagraphInsertedHdl, ::Outliner::ParagraphHdlParam, void );
    DECL_LINK( OnParagraphRemovingHdl, ::Outliner::ParagraphHdlParam, void );
@@ -253,8 +276,7 @@ protected:
private:
    ::std::unique_ptr<ViewClipboard> mpClipboard;
    OutlinerMasterViewFilter maMasterViewFilter;

    VectorGraphicSearchContext aVectorGraphicSearchContext;
    SearchContext maSearchContext;

    OUString m_sAuthor;
};
diff --git a/sd/source/ui/inc/fusearch.hxx b/sd/source/ui/inc/fusearch.hxx
index 310e42a..e9dcb254 100644
--- a/sd/source/ui/inc/fusearch.hxx
+++ b/sd/source/ui/inc/fusearch.hxx
@@ -32,6 +32,8 @@ class FuSearch final : public FuPoor
public:

    static rtl::Reference<FuPoor> Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq );
    static FuSearch* createPtr(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq);

    virtual void DoExecute( SfxRequest& rReq ) override;

    void SearchAndReplace( const SvxSearchItem* pSearchItem );
diff --git a/sd/source/ui/unoidl/DrawController.cxx b/sd/source/ui/unoidl/DrawController.cxx
index d908066..201e0e7 100644
--- a/sd/source/ui/unoidl/DrawController.cxx
+++ b/sd/source/ui/unoidl/DrawController.cxx
@@ -142,9 +142,9 @@ void SAL_CALL DrawController::dispose()
    if ( pViewShell )
    {
        pViewShell->DeactivateCurrentFunction();
        DrawDocShell* pDocShell = pViewShell->GetDocSh();
        if ( pDocShell != nullptr )
            pDocShell->SetDocShellFunction(nullptr);
        auto* pView = pViewShell->GetView();
        if (pView)
            pView->getSearchContext().resetSearchFunction();
    }
    pViewShell.reset();

diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx
index 98fd0bd..b1e44ca 100644
--- a/sd/source/ui/view/Outliner.cxx
+++ b/sd/source/ui/view/Outliner.cxx
@@ -99,6 +99,8 @@ public:
    */
    void ReleaseOutlinerView();

    sd::VectorGraphicSearchContext& getVectorGraphicSearchContext() { return maVectorGraphicSearchContext; }

private:
    /** Flag that specifies whether we own the outline view pointed to by
        <member>mpOutlineView</member> and thus have to
@@ -112,6 +114,8 @@ private:
        <member>mbOwnOutlineView</member> distinguishes between both cases.
    */
    OutlinerView* mpOutlineView;

    sd::VectorGraphicSearchContext maVectorGraphicSearchContext;
};

namespace
@@ -607,6 +611,8 @@ bool SdOutliner::SearchAndReplaceAll()
            mnStartPageIndex = sal_uInt16(-1);
            return true;
        }
        // Reset the iterator back to the beginning
        maObjectIterator = sd::outliner::OutlinerContainer(this).begin();

        // Search/replace until the end of the document is reached.
        bool bFoundMatch;
@@ -724,7 +730,7 @@ void SdOutliner::sendLOKSearchResultCallback(std::shared_ptr<sd::ViewShell> & pV
                                             std::vector<sd::SearchSelection>* pSelections)
{
    std::vector<::tools::Rectangle> aLogicRects;
    auto& rVectorGraphicSearchContext = pViewShell->GetView()->getVectorGraphicSearchContext();
    auto& rVectorGraphicSearchContext = mpImpl->getVectorGraphicSearchContext();
    if (rVectorGraphicSearchContext.mbCurrentIsVectorGraphic)
    {
        basegfx::B2DRectangle aSelectionHMM = getPDFSelection(rVectorGraphicSearchContext.mpVectorGraphicSearch, mpObj);
@@ -815,7 +821,7 @@ bool SdOutliner::SearchAndReplaceOnce(std::vector<sd::SearchSelection>* pSelecti
        mpView = pViewShell->GetView();
        mpWindow = pViewShell->GetActiveWindow();
        pOutlinerView->SetWindow(mpWindow);
        auto& rVectorGraphicSearchContext = mpView->getVectorGraphicSearchContext();
        auto& rVectorGraphicSearchContext = mpImpl->getVectorGraphicSearchContext();
        if (nullptr != dynamic_cast<const sd::DrawViewShell*>(pViewShell.get()))
        {
            sal_uLong nMatchCount = 0;
@@ -1172,7 +1178,7 @@ void SdOutliner::ProvideNextTextObject()
    mbFoundObject = false;

    // reset the vector search
    auto& rVectorGraphicSearchContext = mpView->getVectorGraphicSearchContext();
    auto& rVectorGraphicSearchContext = mpImpl->getVectorGraphicSearchContext();
    rVectorGraphicSearchContext.reset();

    mpView->UnmarkAllObj (mpView->GetSdrPageView());