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());