sd/source/ui/framework/module/ToolBarModule.cxx | 28 +++++++---- sd/source/ui/inc/OutlinerIteratorImpl.hxx | 3 - sd/source/ui/view/NotesPanelView.cxx | 5 + sd/source/ui/view/Outliner.cxx | 36 +++++++++----- sd/source/ui/view/OutlinerIterator.cxx | 61 +++++++++++------------- sd/source/ui/view/ViewShellManager.cxx | 4 - sd/source/ui/view/viewshel.cxx | 3 - 7 files changed, 79 insertions(+), 61 deletions(-)
New commits: commit 60c00a1d12fe531dbec8c285eaf8bfa02684be3c Author: Sarper Akdemir <sarper.akde...@allotropia.de> AuthorDate: Mon Jun 10 10:40:27 2024 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Wed Jun 19 20:32:53 2024 +0200 fix crashers from various notes pane patches namely: - Fix crash on search initated from notes pane on the OutlineView - fix potential crashers from b3010f4a6739cf69e9027bf16b3c9265554ea9ce [WIP] introduce overridingshells & fix notespane (side/tool)bar interactions - fix potential crashers from 5b736cdfb0d7cbee445e2b6b4e0f6d112581350b [WIP] make notes pane searchable - tdf#33603: fix crash on repeated view mode changes while notes pane is on - fix crash on opening impress from start center Change-Id: Idcdadfea0dbf97fb60dfe5ad53b281a8696882a9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169208 Tested-by: allotropia jenkins <jenk...@allotropia.de> Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/sd/source/ui/framework/module/ToolBarModule.cxx b/sd/source/ui/framework/module/ToolBarModule.cxx index 8df154c0602e..2aa0ffdb9132 100644 --- a/sd/source/ui/framework/module/ToolBarModule.cxx +++ b/sd/source/ui/framework/module/ToolBarModule.cxx @@ -105,7 +105,7 @@ void SAL_CALL ToolBarModule::notifyConfigurationChange ( // since EventMultiplexer isn't available when the ToolBarModule is // initialized, subscribing the event listener hacked here. - if (!mbListeningEventMultiplexer) + if (!mbListeningEventMultiplexer && mpBase) { mpBase->GetEventMultiplexer()->AddEventListener( LINK(this, ToolBarModule, EventMultiplexerListener)); @@ -145,21 +145,23 @@ void SAL_CALL ToolBarModule::notifyConfigurationChange ( void ToolBarModule::HandlePaneViewShellFocused(const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId) { + if(!mpBase) + return; + std::shared_ptr<FrameworkHelper> pFrameworkHelper (FrameworkHelper::Instance(*mpBase)); std::shared_ptr<ViewShell> pViewShell = pFrameworkHelper->GetViewShell(pFrameworkHelper->GetView(rxResourceId)); + + if(mpBase->GetMainViewShell() == pViewShell) + { + mpBase->GetViewShellManager()->RemoveOverridingMainShell(); + return; + } + switch(pViewShell->GetShellType()) { - // TODO: refactor this bit into something that doesn't hardcode on the viewshell types. - // i remember having some trivial ideas on this -> check notes. - case sd::ViewShell::ST_IMPRESS: - case sd::ViewShell::ST_DRAW: - case sd::ViewShell::ST_OUTLINE: - // mainviewshells. - mpBase->GetViewShellManager()->RemoveOverridingMainShell(); - break; + // shells that override mainviewshell functionality when used in a pane case ViewShell::ST_NOTESPANEL: - // shells that override mainviewshell functionality. mpBase->GetViewShellManager()->SetOverridingMainShell(pViewShell); UpdateToolbars(pViewShell.get()); break; @@ -213,8 +215,14 @@ void ToolBarModule::UpdateToolbars(ViewShell* pViewShell) // no longer visible. This is done before the old view shell is // destroyed in order to avoid unnecessary updates of those tool // bars. + if (!mpBase) + return; + std::shared_ptr<ToolBarManager> pToolBarManager (mpBase->GetToolBarManager()); + if(!pToolBarManager) + return; + if (pViewShell) { pToolBarManager->MainViewShellChanged(*pViewShell); diff --git a/sd/source/ui/inc/OutlinerIteratorImpl.hxx b/sd/source/ui/inc/OutlinerIteratorImpl.hxx index bb44cf6029a5..a84d17e1cd15 100644 --- a/sd/source/ui/inc/OutlinerIteratorImpl.hxx +++ b/sd/source/ui/inc/OutlinerIteratorImpl.hxx @@ -200,9 +200,6 @@ protected: SdPage* mpPage; private: - /// Indicates whether a page changed occurred on switching to current page. - bool mbPageChangeOccurred; - // Don't use this operator. ViewIteratorImpl& operator= (const ViewIteratorImpl&) = delete; }; diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx index cc14a32b9bec..9175913136af 100644 --- a/sd/source/ui/view/NotesPanelView.cxx +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -197,7 +197,12 @@ void NotesPanelView::onUpdateStyleSettings(bool bForceUpdate /* = false */) void NotesPanelView::onResize() { ::sd::Window* pWin = mrNotesPanelViewShell.GetActiveWindow(); + if (!pWin) + return; + OutlinerView* pOutlinerView = GetOutlinerView(); + if (!pOutlinerView) + return; Size aOutputSize = pWin->PixelToLogic(pWin->GetOutputSizePixel()); diff --git a/sd/source/ui/view/Outliner.cxx b/sd/source/ui/view/Outliner.cxx index 727cef1a7f9f..ca5581108bd3 100644 --- a/sd/source/ui/view/Outliner.cxx +++ b/sd/source/ui/view/Outliner.cxx @@ -906,7 +906,6 @@ bool SdOutliner::SearchAndReplaceOnce(std::vector<sd::SearchSelection>* pSelecti pOutl->SetSelection(getOutlinerView()->GetSelection()); } } - // notes->outliner } } @@ -923,6 +922,8 @@ bool SdOutliner::SearchAndReplaceOnce(std::vector<sd::SearchSelection>* pSelecti // text object. maLastValidPosition = maCurrentPosition; + // there's a possible crasher here due to replace not working. + // Now that the mbEndOfSearch flag guards this block the // following assertion and return should not be // necessary anymore. @@ -993,20 +994,26 @@ 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; + std::shared_ptr<sd::ViewShell> pOverridingViewShell{}; + if(sd::ViewShellBase* pBase = getViewShellBase()) + { + if (const std::shared_ptr<sd::ViewShellManager>& pViewShellManager = pBase->GetViewShellManager()) + pOverridingViewShell = pViewShellManager->GetOverridingMainShell(); + } - if( !pFakeShell && pDrawViewShell ) - bViewChanged = (aPosition.meEditMode != pDrawViewShell->GetEditMode() || aPosition.mePageKind != pDrawViewShell->GetPageKind()); - else if (pFakeShell) + bool bViewChanged = false; + + if( pDrawViewShell ) { - auto pPage = pFakeShell->getCurrentPage(); - auto ePageKind = pPage ? pPage->GetPageKind() : PageKind::Standard; - auto eEditMode = EditMode::Page; - bViewChanged = (aPosition.meEditMode != eEditMode || aPosition.mePageKind != ePageKind); + if( !pOverridingViewShell ) + bViewChanged = (aPosition.meEditMode != pDrawViewShell->GetEditMode() || aPosition.mePageKind != pDrawViewShell->GetPageKind()); + else + { + auto pPage = pOverridingViewShell->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. @@ -1230,6 +1237,9 @@ OutlinerView* SdOutliner::lclGetNotesPaneOutliner() std::shared_ptr<sd::ViewShell> pNotesPaneShell(pInstance->GetViewShell(sd::framework::FrameworkHelper::msBottomImpressPaneURL)); + if(!pNotesPaneShell) + return nullptr; + return static_cast<sd::NotesPanelView*>(pNotesPaneShell->GetView())->GetOutlinerView(); } diff --git a/sd/source/ui/view/OutlinerIterator.cxx b/sd/source/ui/view/OutlinerIterator.cxx index 99ec0b33fbf0..95bfa0968b02 100644 --- a/sd/source/ui/view/OutlinerIterator.cxx +++ b/sd/source/ui/view/OutlinerIterator.cxx @@ -151,7 +151,11 @@ Iterator OutlinerContainer::current() Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation) { - auto pFakeShell = dynamic_cast<sd::ViewShellBase*>(SfxViewShell::Current())->GetViewShellManager()->GetOverridingMainShell(); + std::shared_ptr<sd::ViewShell> pOverridingShell{}; + if (auto pBase = dynamic_cast<sd::ViewShellBase*>(SfxViewShell::Current())) + if (auto pViewShellManager = pBase->GetViewShellManager()) + pOverridingShell = pViewShellManager->GetOverridingMainShell(); + // Decide on certain features of the outliner which kind of iterator to // use. if (mpOutliner->mbRestrictSearchToSelection) @@ -159,7 +163,7 @@ Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation) return CreateSelectionIterator ( mpOutliner->maMarkListCopy, mpOutliner->mpDrawDocument, - pFakeShell ? pFakeShell : + pOverridingShell ? pOverridingShell : mpOutliner->mpWeakViewShell.lock(), mpOutliner->mbDirectionIsForward, aLocation); @@ -167,7 +171,7 @@ Iterator OutlinerContainer::CreateIterator (IteratorLocation aLocation) // Search in the whole document. return CreateDocumentIterator ( mpOutliner->mpDrawDocument, - pFakeShell ? pFakeShell : + pOverridingShell ? pOverridingShell : mpOutliner->mpWeakViewShell.lock(), mpOutliner->mbDirectionIsForward, aLocation); @@ -516,7 +520,6 @@ ViewIteratorImpl::ViewIteratorImpl ( const std::weak_ptr<ViewShell>& rpViewShellWeak, bool bDirectionIsForward) : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward), - mbPageChangeOccurred(false), mpPage(nullptr) { SetPage (nPageIndex); @@ -530,7 +533,6 @@ ViewIteratorImpl::ViewIteratorImpl ( PageKind ePageKind, EditMode eEditMode) : IteratorImplBase (pDocument, rpViewShellWeak, bDirectionIsForward, ePageKind, eEditMode), - mbPageChangeOccurred(false), mpPage(nullptr) { SetPage (nPageIndex); @@ -615,36 +617,33 @@ void ViewIteratorImpl::GotoNextText() void ViewIteratorImpl::SetPage (sal_Int32 nPageIndex) { - // if (mbPageChangeOccurred) - // { - maPosition.mnPageIndex = nPageIndex; + maPosition.mnPageIndex = nPageIndex; - sal_Int32 nPageCount; + sal_Int32 nPageCount; + if (maPosition.meEditMode == EditMode::Page) + nPageCount = mpDocument->GetSdPageCount(maPosition.mePageKind); + else + nPageCount = mpDocument->GetMasterSdPageCount( + maPosition.mePageKind); + + // Get page pointer. Here we have three cases: regular pages, + // master pages and invalid page indices. The later ones are not + // errors but the effect of the iterator advancing to the next page + // and going past the last one. This dropping of the rim at the far + // side is detected here and has to be reacted to by the caller. + if (nPageIndex>=0 && nPageIndex < nPageCount) + { if (maPosition.meEditMode == EditMode::Page) - nPageCount = mpDocument->GetSdPageCount(maPosition.mePageKind); - else - nPageCount = mpDocument->GetMasterSdPageCount( + mpPage = mpDocument->GetSdPage ( + static_cast<sal_uInt16>(nPageIndex), maPosition.mePageKind); - - // Get page pointer. Here we have three cases: regular pages, - // master pages and invalid page indices. The later ones are not - // errors but the effect of the iterator advancing to the next page - // and going past the last one. This dropping of the rim at the far - // side is detected here and has to be reacted to by the caller. - if (nPageIndex>=0 && nPageIndex < nPageCount) - { - if (maPosition.meEditMode == EditMode::Page) - mpPage = mpDocument->GetSdPage ( - static_cast<sal_uInt16>(nPageIndex), - maPosition.mePageKind); - else - mpPage = mpDocument->GetMasterSdPage ( - static_cast<sal_uInt16>(nPageIndex), - maPosition.mePageKind); - } else - mpPage = nullptr; - // } + mpPage = mpDocument->GetMasterSdPage ( + static_cast<sal_uInt16>(nPageIndex), + maPosition.mePageKind); + } + else + mpPage = nullptr; // Set up object list iterator. if (mpPage != nullptr) diff --git a/sd/source/ui/view/ViewShellManager.cxx b/sd/source/ui/view/ViewShellManager.cxx index 5bd26aadb104..f158e32e3296 100644 --- a/sd/source/ui/view/ViewShellManager.cxx +++ b/sd/source/ui/view/ViewShellManager.cxx @@ -816,10 +816,8 @@ void ViewShellManager::Implementation::UpdateShellStack() mpTopShell = mrBase.GetSubShell(0); if (mpTopShell!=nullptr && pUndoManager!=nullptr && mpTopShell->GetUndoManager()==nullptr) mpTopShell->SetUndoManager(pUndoManager); - // Make the new top-most ViewShell BroadcastContextForActivation... (need a - // way to make-sure this is a viewshell ;-) ) - + // Only broadcast context for activation on the top-most ViewShell if (mpTopViewShell && bTopViewShellChanged) mpTopViewShell->BroadcastContextForActivation(true); diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 5b597db789b8..a150cc97fd8f 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -452,7 +452,8 @@ void ViewShell::BroadcastContextForActivation(const bool bIsActivated) EventMultiplexerEventId::FocusShifted, nullptr, getFrameworkResourceIdForShell()); } - SfxShell::BroadcastContextForActivation(bIsActivated); + if(GetDispatcher()) + SfxShell::BroadcastContextForActivation(bIsActivated); } void ViewShell::Shutdown()