Rebased ref, commits from common ancestor: commit c8612129fc641ee68381f0d364ab7a770a3d9c5d Author: Sarper Akdemir <sarper.akde...@allotropia.de> AuthorDate: Fri Jun 7 21:18:47 2024 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Sat Jun 8 10:21:18 2024 +0200
[WIP] make notes pane searchable Change-Id: I8133c6a74861e783ab1a23f51ac5faf362a0f512 diff --git a/sd/inc/Outliner.hxx b/sd/inc/Outliner.hxx index 8d00cfbbba9c..94f83c0753e3 100644 --- a/sd/inc/Outliner.hxx +++ b/sd/inc/Outliner.hxx @@ -201,6 +201,7 @@ private: /// Returns the current outline view OutlinerView* getOutlinerView(); + OutlinerView* lclGetNotesPaneOutliner(); /// Specifies whether to search and replace, to spell check or to do a /// text conversion. diff --git a/sd/sdi/NotesPanelView.sdi b/sd/sdi/NotesPanelView.sdi index 2fca90c56fdc..933ef9922401 100644 --- a/sd/sdi/NotesPanelView.sdi +++ b/sd/sdi/NotesPanelView.sdi @@ -492,10 +492,14 @@ interface NotesPanelView ExecMethod = FuTemporary ; StateMethod = GetMenuState ; ] + FID_SEARCH_NOW // ole : ?, status : ? + [ + ExecMethod = Execute ; + StateMethod = GetState ; + GroupId = SfxGroupId::Document ; + ] } -include "drtxtob.sdi" - shell NotesPanelViewShell { import NotesPanelView; diff --git a/sd/sdi/drviewsh.sdi b/sd/sdi/drviewsh.sdi index 84fa9bfa8471..ac7e44ab1a37 100644 --- a/sd/sdi/drviewsh.sdi +++ b/sd/sdi/drviewsh.sdi @@ -203,6 +203,12 @@ interface ImpressEditView : DrawView ExecMethod = FuTemporary ; StateMethod = GetMenuState ; ] + FID_SEARCH_NOW + [ + ExecMethod = Execute ; + StateMethod = GetState ; + GroupId = SfxGroupId::Document ; + ] } shell DrawViewShell diff --git a/sd/source/ui/inc/OutlinerIteratorImpl.hxx b/sd/source/ui/inc/OutlinerIteratorImpl.hxx index 84b11e47b636..bb44cf6029a5 100644 --- a/sd/source/ui/inc/OutlinerIteratorImpl.hxx +++ b/sd/source/ui/inc/OutlinerIteratorImpl.hxx @@ -193,13 +193,15 @@ protected: */ void SetPage (sal_Int32 nPageIndex); + /// Iterator of all objects on the current page. + std::optional<SdrObjListIter> moObjectIterator; + + /// Pointer to the page associated with the current page index. May be NULL. + SdPage* mpPage; + private: /// Indicates whether a page changed occurred on switching to current page. bool mbPageChangeOccurred; - /// Pointer to the page associated with the current page index. May be NULL. - SdPage* mpPage; - /// Iterator of all objects on the current page. - std::optional<SdrObjListIter> moObjectIterator; // Don't use this operator. ViewIteratorImpl& operator= (const ViewIteratorImpl&) = delete; diff --git a/sd/source/ui/view/NotesPanelViewShell.cxx b/sd/source/ui/view/NotesPanelViewShell.cxx index 46c8fc144e78..f7d5f28a31db 100644 --- a/sd/source/ui/view/NotesPanelViewShell.cxx +++ b/sd/source/ui/view/NotesPanelViewShell.cxx @@ -44,6 +44,7 @@ #include <futhes.hxx> #include <memory> #include <sdabstdlg.hxx> +#include <sdmod.hxx> #include <sdpage.hxx> #include <sdresid.hxx> #include <sfx2/bindings.hxx> @@ -1333,15 +1334,49 @@ void NotesPanelViewShell::FuSupport(SfxRequest& rReq) void NotesPanelViewShell::Execute(SfxRequest& rReq) { - bool bForwardCall = true; - switch (rReq.GetSlot()) { + case FID_SEARCH_NOW: + { + const SfxItemSet* pReqArgs = rReq.GetArgs(); + + sd::View* pView = nullptr; + if (auto pMainViewSh = GetViewShellBase().GetMainViewShell()) + pView = pMainViewSh->GetView(); + + if (pReqArgs) + { + if (pView) + { + rtl::Reference<FuSearch>& xFuSearch + = pView->getSearchContext().getFunctionSearch(); + + if (!xFuSearch.is()) + { + xFuSearch = rtl::Reference<FuSearch>(FuSearch::createPtr( + this, this->GetActiveWindow(), pView, GetDoc(), rReq)); + + 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); + } + } + } + rReq.Done(); + } + break; + case SID_SEARCH_ITEM: // Forward this request to the common (old) code of the // document shell. GetDocSh()->Execute(rReq); - bForwardCall = false; break; case SID_SPELL_DIALOG: @@ -1357,16 +1392,12 @@ void NotesPanelViewShell::Execute(SfxRequest& rReq) pViewFrame->GetBindings().Invalidate(SID_SPELL_DIALOG); rReq.Done(); - bForwardCall = false; } break; default: break; } - - if (bForwardCall) - TextObjectBar::ExecuteImpl(this, mpView, rReq, nullptr); } void NotesPanelViewShell::MouseButtonUp(const MouseEvent& rMEvt, ::sd::Window* pWin) diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx index aaf4cc6a8160..727cef1a7f9f 100644 --- a/sd/source/ui/view/Outliner.cxx +++ b/sd/source/ui/view/Outliner.cxx @@ -49,10 +49,12 @@ #include <DrawViewShell.hxx> #include <OutlineView.hxx> #include <OutlineViewShell.hxx> +#include <NotesPanelView.hxx> #include <drawdoc.hxx> #include <DrawDocShell.hxx> #include <drawview.hxx> #include <ViewShellBase.hxx> +#include <ViewShellManager.hxx> #include <SpellDialogChildWindow.hxx> #include <framework/FrameworkHelper.hxx> #include <svx/svxids.hrc> @@ -62,6 +64,7 @@ #include <comphelper/scopeguard.hxx> #include <VectorGraphicSearchContext.hxx> #include <fusearch.hxx> +#include <sdpage.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -896,6 +899,14 @@ bool SdOutliner::SearchAndReplaceOnce(std::vector<sd::SearchSelection>* pSelecti if (mpSearchItem->GetCommand() != SvxSearchCmd::REPLACE_ALL) { nMatchCount = getOutlinerView()->StartSearchAndReplace(*mpSearchItem); + if (nMatchCount && maCurrentPosition.mePageKind == PageKind::Notes) + { + if(auto pOutl = lclGetNotesPaneOutliner()) + { + pOutl->SetSelection(getOutlinerView()->GetSelection()); + } + } + // notes->outliner } } @@ -915,16 +926,26 @@ bool SdOutliner::SearchAndReplaceOnce(std::vector<sd::SearchSelection>* pSelecti // Now that the mbEndOfSearch flag guards this block the // following assertion and return should not be // necessary anymore. - DBG_ASSERT(GetEditEngine().HasView(&getOutlinerView()->GetEditView() ), - "SearchAndReplace without valid view!" ); - if ( ! GetEditEngine().HasView( &getOutlinerView()->GetEditView() ) ) + // DBG_ASSERT(GetEditEngine().HasView(&getOutlinerView()->GetEditView() ), + // "SearchAndReplace without valid view!" ); + // if ( ! GetEditEngine().HasView( &getOutlinerView()->GetEditView() ) ) + // { + // mpDrawDocument->GetDocSh()->SetWaitCursor( false ); + // return true; + // } + + // notes->outliner + if (meMode == SEARCH) { - mpDrawDocument->GetDocSh()->SetWaitCursor( false ); - return true; + auto nMatch = getOutlinerView()->StartSearchAndReplace(*mpSearchItem); + if (nMatch && maCurrentPosition.mePageKind == PageKind::Notes) + { + if(auto pOutl = lclGetNotesPaneOutliner()) + { + pOutl->SetSelection(getOutlinerView()->GetSelection()); + } + } } - - if (meMode == SEARCH) - getOutlinerView()->StartSearchAndReplace(*mpSearchItem); } } } @@ -972,10 +993,24 @@ void SdOutliner::DetectChange() std::shared_ptr<sd::DrawViewShell> pDrawViewShell ( std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell)); + std::shared_ptr<sd::ViewShell> pFakeShell{}; + sd::ViewShellBase* pBase = getViewShellBase(); + if(auto pViewShellManager = pBase->GetViewShellManager()) + pFakeShell = pViewShellManager->GetOverridingMainShell(); + auto bViewChanged = false; + + if( !pFakeShell && pDrawViewShell ) + bViewChanged = (aPosition.meEditMode != pDrawViewShell->GetEditMode() || aPosition.mePageKind != pDrawViewShell->GetPageKind()); + else if (pFakeShell) + { + auto pPage = pFakeShell->getCurrentPage(); + auto ePageKind = pPage ? pPage->GetPageKind() : PageKind::Standard; + auto eEditMode = EditMode::Page; + bViewChanged = (aPosition.meEditMode != eEditMode || aPosition.mePageKind != ePageKind); + } + // Detect whether the view has been switched from the outside. - if (pDrawViewShell != nullptr - && (aPosition.meEditMode != pDrawViewShell->GetEditMode() - || aPosition.mePageKind != pDrawViewShell->GetPageKind())) + if( bViewChanged ) { // Either the edit mode or the page kind has changed. SetStatusEventHdl(Link<EditStatus&,void>()); @@ -1180,6 +1215,23 @@ bool isValidVectorGraphicObject(const sd::outliner::IteratorPosition& rPosition) } // end anonymous namespace +OutlinerView* SdOutliner::lclGetNotesPaneOutliner() +{ + // request the notes pane + std::shared_ptr<sd::ViewShell> pViewShell(mpWeakViewShell.lock()); + sd::ViewShellBase& rBase = pViewShell->GetViewShellBase(); + + sd::framework::FrameworkHelper::Instance(rBase)->RequestView( + sd::framework::FrameworkHelper::msNotesPanelViewURL, + sd::framework::FrameworkHelper::msBottomImpressPaneURL); + + auto pInstance = sd::framework::FrameworkHelper::Instance(rBase); + pInstance->RequestSynchronousUpdate(); + + std::shared_ptr<sd::ViewShell> pNotesPaneShell(pInstance->GetViewShell(sd::framework::FrameworkHelper::msBottomImpressPaneURL)); + + return static_cast<sd::NotesPanelView*>(pNotesPaneShell->GetView())->GetOutlinerView(); +} /** The main purpose of this method is to iterate over all shape objects of the search area (current selection, current view, or whole document) @@ -1526,12 +1578,20 @@ void SdOutliner::PrepareSearchAndReplace() EnterEditMode(false); - mpDrawDocument->GetDocSh()->SetWaitCursor( false ); - // Start search at the right end of the current object's text - // depending on the search direction. + mpDrawDocument->GetDocSh()->SetWaitCursor(false); + OutlinerView* pOutlinerView = getOutlinerView(); if (pOutlinerView != nullptr) + { pOutlinerView->SetSelection (GetSearchStartPosition ()); + if (lclIsValidTextObject(maCurrentPosition) && maCurrentPosition.mePageKind == PageKind::Notes) + { + if (auto pOutl = lclGetNotesPaneOutliner()) + { + pOutl->SetSelection(getOutlinerView()->GetSelection()); + } + } + } } void SdOutliner::SetViewMode (PageKind ePageKind) @@ -1640,7 +1700,7 @@ void SdOutliner::EnterEditMode (bool bGrabFocus) return; pViewShell->GetDispatcher()->ExecuteList( - SID_TEXTEDIT, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, {&aItem}); + SID_TEXTEDIT, SfxCallMode::SYNCHRON | SfxCallMode::RECORD, { &aItem }); if (mpView->IsTextEdit()) { @@ -1659,8 +1719,45 @@ void SdOutliner::EnterEditMode (bool bGrabFocus) // Turn on the edit mode for the text object. SetUpdateLayout(true); - mpView->SdrBeginTextEdit(mpSearchSpellTextObj, pPV, mpWindow, true, this, - pOutlinerView, true, true, bGrabFocus); + if(maCurrentPosition.mePageKind != PageKind::Notes) + { + std::shared_ptr<sd::ViewShell> pFakeShell{}; + sd::ViewShellBase* pBase = getViewShellBase(); + if(auto pViewShellManager = pBase->GetViewShellManager()) + pFakeShell = pViewShellManager->GetOverridingMainShell(); + + if(pFakeShell) + bGrabFocus=true; + mpView->SdrBeginTextEdit(mpSearchSpellTextObj, pPV, mpWindow, true, this, + pOutlinerView, true, true, bGrabFocus); + + // likely only one or two of these is enough + getViewShellBase()->GetMainViewShell()->GetParentWindow()->GrabFocus(); + getViewShellBase()->GetMainViewShell()->GetContentWindow()->Activate(); + getViewShellBase()->GetMainViewShell()->GetContentWindow()->GrabFocus(); + getViewShellBase()->GetMainViewShell()->GetContentWindow()->GetFocus(); + } + else + { + sd::ViewShellBase& rBase = pViewShell->GetViewShellBase(); + + sd::framework::FrameworkHelper::Instance(rBase)->RequestView( + sd::framework::FrameworkHelper::msNotesPanelViewURL, + sd::framework::FrameworkHelper::msBottomImpressPaneURL); + + auto pInstance = sd::framework::FrameworkHelper::Instance(rBase); + pInstance->RequestSynchronousUpdate(); + + std::shared_ptr<sd::ViewShell> pNotesPaneShell(pInstance->GetViewShell(sd::framework::FrameworkHelper::msBottomImpressPaneURL)); + if(pNotesPaneShell) + { + // likely only one or two of these is enough + pNotesPaneShell->GetParentWindow()->GrabFocus(); + pNotesPaneShell->GetContentWindow()->Activate(); + pNotesPaneShell->GetContentWindow()->GrabFocus(); + pNotesPaneShell->GetContentWindow()->GetFocus(); + } + } mbFoundObject = true; } @@ -1732,8 +1829,24 @@ bool SdOutliner::HandleFailedSearch() SdrObject* SdOutliner::SetObject ( const sd::outliner::IteratorPosition& rPosition) { - SetViewMode (rPosition.mePageKind); - SetPage (rPosition.meEditMode, static_cast<sal_uInt16>(rPosition.mnPageIndex)); + if(rPosition.mePageKind == PageKind::Notes) + { + std::shared_ptr<sd::ViewShell> pViewShell (mpWeakViewShell.lock()); + std::shared_ptr<sd::DrawViewShell> pDrawViewShell( + std::dynamic_pointer_cast<sd::DrawViewShell>(pViewShell)); + + if(pDrawViewShell->GetEditMode() != EditMode::Page || pDrawViewShell->GetCurPagePos() != rPosition.mnPageIndex) + SetPage(EditMode::Page, static_cast<sal_uInt16>(rPosition.mnPageIndex)); + + mnText = rPosition.mnText; + return rPosition.mxObject.get().get(); + } + else + { + SetViewMode(rPosition.mePageKind); + SetPage(rPosition.meEditMode, static_cast<sal_uInt16>(rPosition.mnPageIndex)); + } + mnText = rPosition.mnText; return rPosition.mxObject.get().get(); } diff --git a/sd/source/ui/view/OutlinerIterator.cxx b/sd/source/ui/view/OutlinerIterator.cxx index a7cd6cf66bf2..99ec0b33fbf0 100644 --- a/sd/source/ui/view/OutlinerIterator.cxx +++ b/sd/source/ui/view/OutlinerIterator.cxx @@ -28,6 +28,8 @@ #include <DrawViewShell.hxx> #include <sdpage.hxx> #include <utility> +#include <ViewShellBase.hxx> +#include <ViewShellManager.hxx> namespace sd::outliner { @@ -149,6 +151,7 @@ Iterator OutlinerContainer::current() Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation) { + auto pFakeShell = dynamic_cast<sd::ViewShellBase*>(SfxViewShell::Current())->GetViewShellManager()->GetOverridingMainShell(); // Decide on certain features of the outliner which kind of iterator to // use. if (mpOutliner->mbRestrictSearchToSelection) @@ -156,6 +159,7 @@ Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation) return CreateSelectionIterator ( mpOutliner->maMarkListCopy, mpOutliner->mpDrawDocument, + pFakeShell ? pFakeShell : mpOutliner->mpWeakViewShell.lock(), mpOutliner->mbDirectionIsForward, aLocation); @@ -163,6 +167,7 @@ Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation) // Search in the whole document. return CreateDocumentIterator ( mpOutliner->mpDrawDocument, + pFakeShell ? pFakeShell : mpOutliner->mpWeakViewShell.lock(), mpOutliner->mbDirectionIsForward, aLocation); @@ -258,7 +263,8 @@ Iterator OutlinerContainer::CreateDocumentIterator ( } else { - ePageKind = PageKind::Standard; + auto pPage = rpViewShell->getCurrentPage(); + ePageKind = pPage ? pPage->GetPageKind() : PageKind::Standard; eEditMode = EditMode::Page; } break; @@ -609,9 +615,8 @@ void ViewIteratorImpl::GotoNextText() void ViewIteratorImpl::SetPage (sal_Int32 nPageIndex) { - mbPageChangeOccurred = (maPosition.mnPageIndex!=nPageIndex); - if (mbPageChangeOccurred) - { + // if (mbPageChangeOccurred) + // { maPosition.mnPageIndex = nPageIndex; sal_Int32 nPageCount; @@ -639,7 +644,7 @@ void ViewIteratorImpl::SetPage (sal_Int32 nPageIndex) } else mpPage = nullptr; - } + // } // Set up object list iterator. if (mpPage != nullptr) @@ -720,7 +725,72 @@ void DocumentIteratorImpl::GotoNextText() bool bSetToOnePastLastPage = false; bool bViewChanged = false; - ViewIteratorImpl::GotoNextText(); + // ViewIteratorImpl::GotoNextText(); + + SdrTextObj* pTextObj = DynCastSdrTextObj( maPosition.mxObject.get().get() ); + if( pTextObj ) + { + if (mbDirectionIsForward) + { + ++maPosition.mnText; + if( maPosition.mnText < pTextObj->getTextCount() ) + return; + } + else + { + --maPosition.mnText; + if( maPosition.mnText >= 0 ) + return; + } + } + + if (moObjectIterator && moObjectIterator->IsMore()) + maPosition.mxObject = moObjectIterator->Next(); + else + maPosition.mxObject = nullptr; + + if (!maPosition.mxObject.get().is() ) + { + if(maPosition.mePageKind == PageKind::Standard) + { + maPosition.mePageKind = PageKind::Notes; + if (mbDirectionIsForward) + SetPage (maPosition.mnPageIndex); + else + SetPage(maPosition.mnPageIndex); + } + else if (maPosition.mePageKind == PageKind::Notes) + { + maPosition.mePageKind = PageKind::Standard; + if (mbDirectionIsForward) + SetPage (maPosition.mnPageIndex+1); + else + SetPage(maPosition.mnPageIndex - 1); + } + else + { + if (mbDirectionIsForward) + SetPage (maPosition.mnPageIndex+1); + else + SetPage(maPosition.mnPageIndex - 1); + } + + if (mpPage != nullptr) + moObjectIterator.emplace( mpPage, SdrIterMode::DeepNoGroups, !mbDirectionIsForward ); + if (moObjectIterator && moObjectIterator->IsMore()) + maPosition.mxObject = moObjectIterator->Next(); + else + maPosition.mxObject = nullptr; + } + + maPosition.mnText = 0; + if( !mbDirectionIsForward && maPosition.mxObject.get().is() ) + { + pTextObj = DynCastSdrTextObj( maPosition.mxObject.get().get() ); + if( pTextObj ) + maPosition.mnText = pTextObj->getTextCount() - 1; + } + if (mbDirectionIsForward) { @@ -743,7 +813,7 @@ void DocumentIteratorImpl::GotoNextText() { maPosition.meEditMode = EditMode::Page; if (maPosition.mePageKind == PageKind::Standard) - maPosition.mePageKind = PageKind::Notes; + maPosition.mePageKind = PageKind::Handout; else if (maPosition.mePageKind == PageKind::Notes) maPosition.mePageKind = PageKind::Handout; SetPage (0); diff --git a/sd/source/ui/view/drviews7.cxx b/sd/source/ui/view/drviews7.cxx index c9aeab96349b..f181b72db41c 100644 --- a/sd/source/ui/view/drviews7.cxx +++ b/sd/source/ui/view/drviews7.cxx @@ -1920,6 +1920,7 @@ void DrawViewShell::GetState (SfxItemSet& rSet) { switch (nWhich) { + case FID_SEARCH_NOW: case SID_SEARCH_ITEM: case SID_SEARCH_OPTIONS: // Forward this request to the common (old) code of the @@ -1945,27 +1946,33 @@ void DrawViewShell::Execute (SfxRequest& rReq) switch (rReq.GetSlot()) { + case FID_SEARCH_NOW: + // Forward this request to the common (old) code of the + // document shell. + GetDocSh()->Execute(rReq); + break; + case SID_SEARCH_ITEM: // Forward this request to the common (old) code of the // document shell. - GetDocSh()->Execute (rReq); - break; + GetDocSh()->Execute(rReq); + break; case SID_SPELL_DIALOG: { SfxViewFrame* pViewFrame = GetViewFrame(); if (rReq.GetArgs() != nullptr) - pViewFrame->SetChildWindow (SID_SPELL_DIALOG, - static_cast<const SfxBoolItem&>(rReq.GetArgs()-> - Get(SID_SPELL_DIALOG)).GetValue()); + pViewFrame->SetChildWindow( + SID_SPELL_DIALOG, + static_cast<const SfxBoolItem&>(rReq.GetArgs()->Get(SID_SPELL_DIALOG)) + .GetValue()); else pViewFrame->ToggleChildWindow(SID_SPELL_DIALOG); pViewFrame->GetBindings().Invalidate(SID_SPELL_DIALOG); - rReq.Ignore (); + rReq.Ignore(); } break; - default: SAL_WARN("sd", "DrawViewShell::Execute(): can not handle slot " << rReq.GetSlot()); break;