Rebased ref, commits from common ancestor: commit 17f99f2040bd39c39936e1101260f9c3cbf09e1b Author: Sarper Akdemir <sarper.akde...@allotropia.de> AuthorDate: Fri Jun 7 21:18:47 2024 +0200 Commit: Sarper Akdemir <sarper.akde...@allotropia.de> CommitDate: Fri Jun 7 21:33:13 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..c6a092f5d562 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,43 @@ 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)); + + // 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 +1827,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; commit 4eddad1303486d794587cfab5f93d01a3c3073de Author: Sarper Akdemir <sarper.akde...@allotropia.de> AuthorDate: Fri Jun 7 21:14:44 2024 +0200 Commit: Sarper Akdemir <sarper.akde...@allotropia.de> CommitDate: Fri Jun 7 21:33:12 2024 +0200 [WIP] introduce overridingshells & fix notespane (side/tool)bar interactions Change-Id: Icc9721d7f54097025bc9dc7ef7069aed856e6d96 diff --git a/framework/source/services/ContextChangeEventMultiplexer.cxx b/framework/source/services/ContextChangeEventMultiplexer.cxx index 1cf4a670cf5a..73afc51e2181 100644 --- a/framework/source/services/ContextChangeEventMultiplexer.cxx +++ b/framework/source/services/ContextChangeEventMultiplexer.cxx @@ -25,6 +25,7 @@ #include <com/sun/star/ui/XContextChangeEventMultiplexer.hpp> #include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp> #include <com/sun/star/uno/XComponentContext.hpp> +#include <sfx2/viewsh.hxx> #include <comphelper/compbase.hxx> #include <cppuhelper/supportsservice.hxx> diff --git a/include/sfx2/shell.hxx b/include/sfx2/shell.hxx index b454547970a5..358658292a73 100644 --- a/include/sfx2/shell.hxx +++ b/include/sfx2/shell.hxx @@ -455,7 +455,7 @@ public: defined with an earlier call to SetContextName(). When <FALSE/> then broadcast the 'default' context. */ - void BroadcastContextForActivation (const bool bIsActivated); + virtual void BroadcastContextForActivation (const bool bIsActivated); /** Enabled or disable the context broadcaster. Returns the old state. */ diff --git a/sd/sdi/NotesPanelView.sdi b/sd/sdi/NotesPanelView.sdi index b54addb52b8c..2fca90c56fdc 100644 --- a/sd/sdi/NotesPanelView.sdi +++ b/sd/sdi/NotesPanelView.sdi @@ -499,5 +499,4 @@ include "drtxtob.sdi" shell NotesPanelViewShell { import NotesPanelView; - import TextObjectBar; } diff --git a/sd/source/ui/framework/module/ToolBarModule.cxx b/sd/source/ui/framework/module/ToolBarModule.cxx index de7f3e583126..8df154c0602e 100644 --- a/sd/source/ui/framework/module/ToolBarModule.cxx +++ b/sd/source/ui/framework/module/ToolBarModule.cxx @@ -18,10 +18,17 @@ */ #include "ToolBarModule.hxx" +#include "ViewShell.hxx" #include <ViewShellBase.hxx> +#include <ViewShellManager.hxx> #include <DrawController.hxx> +#include <EventMultiplexer.hxx> #include <comphelper/servicehelper.hxx> #include <framework/FrameworkHelper.hxx> +#include <vcl/EnumContext.hxx> + +#include <com/sun/star/frame/XController.hpp> +#include <comphelper/processfactory.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -76,6 +83,9 @@ ToolBarModule::ToolBarModule ( ToolBarModule::~ToolBarModule() { + if (mpBase && mbListeningEventMultiplexer) + mpBase->GetEventMultiplexer()->RemoveEventListener( + LINK(this, ToolBarModule, EventMultiplexerListener)); } void ToolBarModule::disposing(std::unique_lock<std::mutex>&) @@ -93,6 +103,16 @@ void SAL_CALL ToolBarModule::notifyConfigurationChange ( if (!mxConfigurationController.is()) return; + // since EventMultiplexer isn't available when the ToolBarModule is + // initialized, subscribing the event listener hacked here. + if (!mbListeningEventMultiplexer) + { + mpBase->GetEventMultiplexer()->AddEventListener( + LINK(this, ToolBarModule, EventMultiplexerListener)); + mbListeningEventMultiplexer = true; + } + + sal_Int32 nEventType = 0; rEvent.UserData >>= nEventType; switch (nEventType) @@ -123,6 +143,32 @@ void SAL_CALL ToolBarModule::notifyConfigurationChange ( } } +void ToolBarModule::HandlePaneViewShellFocused(const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId) +{ + std::shared_ptr<FrameworkHelper> pFrameworkHelper (FrameworkHelper::Instance(*mpBase)); + std::shared_ptr<ViewShell> pViewShell = pFrameworkHelper->GetViewShell(pFrameworkHelper->GetView(rxResourceId)); + + 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; + case ViewShell::ST_NOTESPANEL: + // shells that override mainviewshell functionality. + mpBase->GetViewShellManager()->SetOverridingMainShell(pViewShell); + UpdateToolbars(pViewShell.get()); + break; + default: + break; + } + mpToolBarManagerLock.reset(); +} + void ToolBarModule::HandleUpdateStart() { // Lock the ToolBarManager and tell it to lock the ViewShellManager as @@ -149,23 +195,11 @@ void ToolBarModule::HandleUpdateEnd() std::shared_ptr<ToolBarManager> pToolBarManager (mpBase->GetToolBarManager()); std::shared_ptr<FrameworkHelper> pFrameworkHelper ( FrameworkHelper::Instance(*mpBase)); - ViewShell* pViewShell - = pFrameworkHelper->GetViewShell(FrameworkHelper::msCenterPaneURL).get(); - if (pViewShell != nullptr) - { - pToolBarManager->MainViewShellChanged(*pViewShell); - pToolBarManager->SelectionHasChanged( - *pViewShell, - *pViewShell->GetView()); - pToolBarManager->PreUpdate(); - } - else - { - pToolBarManager->MainViewShellChanged(); - pToolBarManager->PreUpdate(); - } - } + auto pViewShell + = pFrameworkHelper->GetViewShell(FrameworkHelper::msCenterPaneURL); + UpdateToolbars(pViewShell.get()); + } // Releasing the update lock of the ToolBarManager will let the // ToolBarManager with the help of the ViewShellManager take care of // updating tool bars and view shell with the minimal amount of @@ -173,6 +207,29 @@ void ToolBarModule::HandleUpdateEnd() mpToolBarManagerLock.reset(); } +void ToolBarModule::UpdateToolbars(ViewShell* pViewShell) +{ + // Update the set of visible tool bars and deactivate those that are + // no longer visible. This is done before the old view shell is + // destroyed in order to avoid unnecessary updates of those tool + // bars. + std::shared_ptr<ToolBarManager> pToolBarManager (mpBase->GetToolBarManager()); + + if (pViewShell) + { + pToolBarManager->MainViewShellChanged(*pViewShell); + pToolBarManager->SelectionHasChanged( + *pViewShell, + *pViewShell->GetView()); + pToolBarManager->PreUpdate(); + } + else + { + pToolBarManager->MainViewShellChanged(); + pToolBarManager->PreUpdate(); + } +} + void SAL_CALL ToolBarModule::disposing (const lang::EventObject& rEvent) { if (mxConfigurationController.is() @@ -184,6 +241,27 @@ void SAL_CALL ToolBarModule::disposing (const lang::EventObject& rEvent) } } +IMPL_LINK(ToolBarModule, EventMultiplexerListener, sd::tools::EventMultiplexerEvent&, rEvent, + void) +{ + if (!mpBase) + return; + + switch(rEvent.meEventId) + { + case EventMultiplexerEventId::FocusShifted: + { + uno::Reference<drawing::framework::XResourceId> xResourceId{ rEvent.mxUserData, + UNO_QUERY }; + if (xResourceId.is()) + HandlePaneViewShellFocused(xResourceId); + break; + } + default: + break; + } +} + } // end of namespace sd::framework /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/ui/framework/module/ToolBarModule.hxx b/sd/source/ui/framework/module/ToolBarModule.hxx index bf0c017ef981..f245e88f8562 100644 --- a/sd/source/ui/framework/module/ToolBarModule.hxx +++ b/sd/source/ui/framework/module/ToolBarModule.hxx @@ -20,20 +20,34 @@ #pragma once #include <ToolBarManager.hxx> +#include <tools/link.hxx> #include <com/sun/star/drawing/framework/XConfigurationChangeListener.hpp> +#include <com/sun/star/ui/XContextChangeEventListener.hpp> #include <comphelper/compbase.hxx> #include <o3tl/deleter.hxx> #include <rtl/ref.hxx> #include <memory> -namespace com::sun::star::drawing::framework { class XConfigurationController; } -namespace com::sun::star::frame { class XController; } +namespace com::sun::star::drawing::framework +{ +class XConfigurationController; +class XResourceId; +} +namespace com::sun::star::frame +{ +class XController; +} namespace sd { class DrawController; class ViewShellBase; } +namespace sd::tools +{ +class EventMultiplexerEvent; +} + namespace sd::framework { typedef comphelper::WeakComponentImplHelper < @@ -73,9 +87,20 @@ private: ViewShellBase* mpBase; std::unique_ptr<ToolBarManager::UpdateLock, o3tl::default_delete<ToolBarManager::UpdateLock>> mpToolBarManagerLock; bool mbMainViewSwitchUpdatePending; + bool mbListeningEventMultiplexer = false; + + /** Update toolbars via ToolbarManager + + @param pViewShell may be nullptr + */ + void UpdateToolbars(ViewShell* pViewShell); void HandleUpdateStart(); void HandleUpdateEnd(); + void HandlePaneViewShellFocused( + const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId); + + DECL_LINK(EventMultiplexerListener, ::sd::tools::EventMultiplexerEvent&, void); }; } // end of namespace sd::framework diff --git a/sd/source/ui/inc/EventMultiplexer.hxx b/sd/source/ui/inc/EventMultiplexer.hxx index d6d79d11b279..7de135d45fff 100644 --- a/sd/source/ui/inc/EventMultiplexer.hxx +++ b/sd/source/ui/inc/EventMultiplexer.hxx @@ -22,6 +22,7 @@ #include <sal/config.h> #include <rtl/ref.hxx> +#include <com/sun/star/uno/XInterface.hpp> template <typename Arg, typename Ret> class Link; @@ -112,6 +113,10 @@ enum class EventMultiplexerEventId /** Edit mode was (or is being) switched to master mode. */ EditModeMaster, + + /** Focus shifted between views. + */ + FocusShifted, }; namespace sd::tools @@ -121,8 +126,10 @@ class EventMultiplexerEvent public: EventMultiplexerEventId meEventId; const void* mpUserData; + css::uno::Reference<css::uno::XInterface> mxUserData; - EventMultiplexerEvent(EventMultiplexerEventId eEventId, const void* pUserData); + EventMultiplexerEvent(EventMultiplexerEventId eEventId, const void* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData = {}); }; /** This convenience class makes it easy to listen to various events that @@ -160,7 +167,8 @@ public: @param pUserData Some data sent to the listeners along with the event. */ - void MultiplexEvent(EventMultiplexerEventId eEventId, void const* pUserData); + void MultiplexEvent(EventMultiplexerEventId eEventId, void const* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData = {}); private: class Implementation; diff --git a/sd/source/ui/inc/ToolBarManager.hxx b/sd/source/ui/inc/ToolBarManager.hxx index da5325cf693c..a5cebb377f5c 100644 --- a/sd/source/ui/inc/ToolBarManager.hxx +++ b/sd/source/ui/inc/ToolBarManager.hxx @@ -178,10 +178,13 @@ public: The group is used for the actual tool bars. @param nToolBarId Id of the tool bar shell. + @param bAddBar + Add the toolbar itself with the shell. When false only adds the shell. */ void AddToolBarShell ( ToolBarGroup eGroup, - ShellId nToolBarId); + ShellId nToolBarId, + bool bAddBar = true); /** Remove the tool bar with the given name from the specified group. If the tool bar is not visible then nothing happens. diff --git a/sd/source/ui/inc/ViewShell.hxx b/sd/source/ui/inc/ViewShell.hxx index 9e5e8e068160..fd9eccadc0e6 100644 --- a/sd/source/ui/inc/ViewShell.hxx +++ b/sd/source/ui/inc/ViewShell.hxx @@ -522,6 +522,7 @@ protected: virtual void Activate(bool IsMDIActivate) override; virtual void Deactivate(bool IsMDIActivate) override; + virtual void BroadcastContextForActivation (const bool bIsActivated) override; virtual void SetZoomFactor( const Fraction &rZoomX, const Fraction &rZoomY ); diff --git a/sd/source/ui/inc/ViewShellManager.hxx b/sd/source/ui/inc/ViewShellManager.hxx index c4011c52d5fd..329cb20d174e 100644 --- a/sd/source/ui/inc/ViewShellManager.hxx +++ b/sd/source/ui/inc/ViewShellManager.hxx @@ -79,6 +79,10 @@ public: */ void ActivateViewShell(ViewShell* pViewShell); + void RemoveOverridingMainShell(); + void SetOverridingMainShell(std::shared_ptr<ViewShell> pViewShell); + std::shared_ptr<ViewShell> GetOverridingMainShell(); + /** Activate the given shell which is not a view shell. For view shells use the ActivateViewShell() method. */ diff --git a/sd/source/ui/tools/EventMultiplexer.cxx b/sd/source/ui/tools/EventMultiplexer.cxx index 59cf49569d92..68b871ca6a14 100644 --- a/sd/source/ui/tools/EventMultiplexer.cxx +++ b/sd/source/ui/tools/EventMultiplexer.cxx @@ -132,7 +132,8 @@ private: void CallListeners ( EventMultiplexerEventId eId, - void const * pUserData = nullptr); + void const * pUserData = nullptr, + const css::uno::Reference<css::uno::XInterface>& xUserData = {}); DECL_LINK(SlideSorterSelectionChangeListener, LinkParamNone*, void); }; @@ -173,11 +174,10 @@ void EventMultiplexer::RemoveEventListener ( mpImpl->RemoveEventListener(rCallback); } -void EventMultiplexer::MultiplexEvent( - EventMultiplexerEventId eEventId, - void const * pUserData ) +void EventMultiplexer::MultiplexEvent(EventMultiplexerEventId eEventId, void const* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData) { - EventMultiplexerEvent aEvent(eEventId, pUserData); + EventMultiplexerEvent aEvent(eEventId, pUserData, xUserData); mpImpl->CallListeners(aEvent); } @@ -621,11 +621,11 @@ void EventMultiplexer::Implementation::Notify ( } } -void EventMultiplexer::Implementation::CallListeners ( - EventMultiplexerEventId eId, - void const * pUserData) +void EventMultiplexer::Implementation::CallListeners( + EventMultiplexerEventId eId, void const* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData) { - EventMultiplexerEvent aEvent(eId, pUserData); + EventMultiplexerEvent aEvent(eId, pUserData, xUserData); CallListeners(aEvent); } @@ -647,9 +647,11 @@ IMPL_LINK_NOARG(EventMultiplexer::Implementation, SlideSorterSelectionChangeList EventMultiplexerEvent::EventMultiplexerEvent ( EventMultiplexerEventId eEventId, - const void* pUserData) + const void* pUserData, + const css::uno::Reference<css::uno::XInterface>& xUserData) : meEventId(eEventId), - mpUserData(pUserData) + mpUserData(pUserData), + mxUserData(xUserData) { } diff --git a/sd/source/ui/view/NotesPanelView.cxx b/sd/source/ui/view/NotesPanelView.cxx index 3a4d4df4b0ac..cc14a32b9bec 100644 --- a/sd/source/ui/view/NotesPanelView.cxx +++ b/sd/source/ui/view/NotesPanelView.cxx @@ -18,6 +18,7 @@ #include <sdpage.hxx> #include <DrawViewShell.hxx> #include <DrawDocShell.hxx> +#include <ToolBarManager.hxx> #include <Window.hxx> #include <drawdoc.hxx> #include <sdmod.hxx> diff --git a/sd/source/ui/view/NotesPanelViewShell.cxx b/sd/source/ui/view/NotesPanelViewShell.cxx index 74698092dd2d..46c8fc144e78 100644 --- a/sd/source/ui/view/NotesPanelViewShell.cxx +++ b/sd/source/ui/view/NotesPanelViewShell.cxx @@ -310,7 +310,6 @@ void NotesPanelViewShell::Activate(bool bIsMDIActivate) } ViewShell::Activate(bIsMDIActivate); - SfxShell::BroadcastContextForActivation(true); if (bIsMDIActivate) { diff --git a/sd/source/ui/view/ToolBarManager.cxx b/sd/source/ui/view/ToolBarManager.cxx index 7dd95c962499..0348237c0d38 100644 --- a/sd/source/ui/view/ToolBarManager.cxx +++ b/sd/source/ui/view/ToolBarManager.cxx @@ -17,12 +17,14 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include "NotesPanelViewShell.hxx" #include <ToolBarManager.hxx> #include <DrawViewShell.hxx> #include <EventMultiplexer.hxx> #include <ViewShellBase.hxx> #include <ViewShellManager.hxx> +#include <framework/FrameworkHelper.hxx> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/frame/XLayoutManager.hpp> @@ -157,6 +159,8 @@ public: const std::shared_ptr<ViewShell>& rpMainViewShell, const std::shared_ptr<ViewShellManager>& rpManager); + void SetActiveViewShell(std::shared_ptr<ViewShell>& rpMainViewShell); + private: class ShellDescriptor {public: @@ -178,6 +182,8 @@ private: things easier and does not waste too much memory. */ GroupedShellList maCurrentList; + + std::shared_ptr<ViewShell> pCurrentActiveShell; }; /** This class concentrates the knowledge about when to show what tool bars @@ -256,7 +262,7 @@ public: void ResetToolBars (ToolBarGroup eGroup); void ResetAllToolBars(); void AddToolBar (ToolBarGroup eGroup, const OUString& rsToolBarName); - void AddToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId); + void AddToolBarShell (ToolBarGroup eGroup, ShellId nToolBarId, bool bAddBar = true); void RemoveToolBar (ToolBarGroup eGroup, const OUString& rsToolBarName); /** Release all tool bar shells and the associated framework tool bars. @@ -387,12 +393,13 @@ void ToolBarManager::AddToolBar ( void ToolBarManager::AddToolBarShell ( ToolBarGroup eGroup, - ShellId nToolBarId) + ShellId nToolBarId, + bool bAddBar) { if (mpImpl != nullptr) { UpdateLock aLock (shared_from_this()); - mpImpl->AddToolBarShell(eGroup,nToolBarId); + mpImpl->AddToolBarShell(eGroup,nToolBarId,bAddBar); } } @@ -621,13 +628,23 @@ void ToolBarManager::Implementation::RemoveToolBar ( void ToolBarManager::Implementation::AddToolBarShell ( ToolBarGroup eGroup, - ShellId nToolBarId) + ShellId nToolBarId, + bool bAddBar) { ViewShell* pMainViewShell = mrBase.GetMainViewShell().get(); if (pMainViewShell != nullptr) { maToolBarShellList.AddShellId(eGroup,nToolBarId); - GetToolBarRules().SubShellAdded(eGroup, nToolBarId); + if (bAddBar) + { + GetToolBarRules().SubShellAdded(eGroup, nToolBarId); + } + else + { + mbPostUpdatePending = true; + if (mnLockCount == 0) + PostUpdate(); + } } } @@ -958,6 +975,11 @@ void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType) ToolBarManager::msViewerToolBar); break; + case ::sd::ViewShell::ST_NOTESPANEL: + mpToolBarManager->AddToolBarShell(ToolBarManager::ToolBarGroup::Permanent, + ToolbarId::Draw_Text_Toolbox_Sd); + break; + case ::sd::ViewShell::ST_DRAW: mpToolBarManager->AddToolBar( ToolBarManager::ToolBarGroup::Permanent, @@ -993,7 +1015,6 @@ void ToolBarRules::MainViewShellChanged (ViewShell::ShellType nShellType) ToolBarManager::msSlideSorterObjectBar); break; - case ViewShell::ST_NOTESPANEL: case ViewShell::ST_NONE: case ViewShell::ST_PRESENTATION: case ViewShell::ST_SIDEBAR: @@ -1347,6 +1368,9 @@ void ToolBarShellList::UpdateShells ( if (rpMainViewShell == nullptr) return; + const std::shared_ptr<ViewShell>& pCurrentMainViewShell + = rpManager->GetOverridingMainShell() ? rpManager->GetOverridingMainShell() : rpMainViewShell; + GroupedShellList aList; // Deactivate shells that are in maCurrentList, but not in @@ -1357,7 +1381,7 @@ void ToolBarShellList::UpdateShells ( for (const auto& rShell : aList) { SAL_INFO("sd.view", __func__ << ": deactivating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId)); - rpManager->DeactivateSubShell(*rpMainViewShell, rShell.mnId); + rpManager->DeactivateSubShell(*pCurrentMainViewShell, rShell.mnId); } // Activate shells that are in maNewList, but not in @@ -1369,7 +1393,7 @@ void ToolBarShellList::UpdateShells ( for (const auto& rShell : aList) { SAL_INFO("sd.view", __func__ << ": activating tool bar shell " << static_cast<sal_uInt32>(rShell.mnId)); - rpManager->ActivateSubShell(*rpMainViewShell, rShell.mnId); + rpManager->ActivateSubShell(*pCurrentMainViewShell, rShell.mnId); } // The maNewList now reflects the current state and thus is made diff --git a/sd/source/ui/view/ViewShellManager.cxx b/sd/source/ui/view/ViewShellManager.cxx index db2ee5f8f158..5bd26aadb104 100644 --- a/sd/source/ui/view/ViewShellManager.cxx +++ b/sd/source/ui/view/ViewShellManager.cxx @@ -113,6 +113,9 @@ public: void SetFormShell (const ViewShell* pViewShell, FmFormShell* pFormShell, bool bAbove); void ActivateSubShell (const SfxShell& rParentShell, ShellId nId); void DeactivateSubShell (const SfxShell& rParentShell, ShellId nId); + void RemoveOverridingMainShell(); + void SetOverridingShell(std::shared_ptr<ViewShell> pViewShell); + std::shared_ptr<ViewShell> GetOverridingShell(); void MoveToTop (const SfxShell& rParentShell); SfxShell* GetShell (ShellId nId) const; SfxShell* GetTopShell() const; @@ -189,6 +192,7 @@ private: SfxShell* mpTopShell; SfxShell* mpTopViewShell; + std::shared_ptr<ViewShell> mpOverridingShell; void UpdateShellStack(); @@ -260,6 +264,26 @@ void ViewShellManager::DeactivateViewShell (const ViewShell* pShell) mpImpl->DeactivateViewShell(*pShell); } + +void ViewShellManager::RemoveOverridingMainShell() +{ + if(mbValid) + mpImpl->RemoveOverridingMainShell(); +} + +void ViewShellManager::SetOverridingMainShell(std::shared_ptr<ViewShell> pViewShell) +{ + if(mbValid) + mpImpl->SetOverridingShell(pViewShell); +} + +std::shared_ptr<ViewShell> ViewShellManager::GetOverridingMainShell() +{ + if(mbValid) + return mpImpl->GetOverridingShell(); + return {}; +} + void ViewShellManager::SetFormShell ( const ViewShell* pParentShell, FmFormShell* pFormShell, @@ -570,6 +594,21 @@ void ViewShellManager::Implementation::DeactivateSubShell ( DestroySubShell(aDescriptor); } +std::shared_ptr<ViewShell> ViewShellManager::Implementation::GetOverridingShell() +{ + return mpOverridingShell; +} + +void ViewShellManager::Implementation::RemoveOverridingMainShell() +{ + mpOverridingShell.reset(); +} + +void ViewShellManager::Implementation::SetOverridingShell(std::shared_ptr<ViewShell> pViewShell) +{ + mpOverridingShell = pViewShell; +} + void ViewShellManager::Implementation::MoveToTop (const SfxShell& rShell) { ::osl::MutexGuard aGuard (maMutex); @@ -711,10 +750,12 @@ void ViewShellManager::Implementation::UpdateShellStack() // 1. Create the missing shells. CreateShells(); + SfxShell* pPreviousTopViewShell = mpTopViewShell; // Update the pointer to the top-most active view shell. mpTopViewShell = (maActiveViewShells.empty()) ? nullptr : maActiveViewShells.begin()->mpShell; + bool bTopViewShellChanged = mpTopViewShell != pPreviousTopViewShell; // 2. Create the internal target stack. ShellStack aTargetStack; @@ -775,6 +816,12 @@ 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 ;-) ) + + + if (mpTopViewShell && bTopViewShellChanged) + mpTopViewShell->BroadcastContextForActivation(true); // Finally tell an invocation of this method on a higher level that it can (has // to) abort and return immediately. @@ -1071,6 +1118,7 @@ void ViewShellManager::Implementation::Shutdown() mrBase.RemoveSubShell (); maShellFactories.clear(); + mpOverridingShell.reset(); } #if OSL_DEBUG_LEVEL >= 2 @@ -1113,9 +1161,12 @@ void ViewShellManager::Implementation::Deactivate (SfxShell* pShell) { pView->SdrEndTextEdit(); pView->UnmarkAll(); + + // dispatch synchronously, otherwise it might execute while another + // ViewShell is active! pViewShell->GetViewFrame()->GetDispatcher()->Execute( SID_OBJECT_SELECT, - SfxCallMode::ASYNCHRON); + SfxCallMode::SYNCHRON); } } diff --git a/sd/source/ui/view/drtxtob.cxx b/sd/source/ui/view/drtxtob.cxx index 6a68541aed45..ed5744b17e96 100644 --- a/sd/source/ui/view/drtxtob.cxx +++ b/sd/source/ui/view/drtxtob.cxx @@ -55,6 +55,7 @@ #include <DrawDocShell.hxx> #include <DrawViewShell.hxx> #include <OutlineViewShell.hxx> +#include <NotesPanelViewShell.hxx> #include <Window.hxx> #include <OutlineView.hxx> #include <Outliner.hxx> @@ -452,7 +453,9 @@ void TextObjectBar::GetAttrStateImpl(ViewShell* mpViewShell, ::sd::View* mpView, rSet.Put( aAttrSet, false ); // <- sal_False, so DontCare-Status gets acquired // these are disabled in outline-mode - if (!mpViewShell || dynamic_cast< const DrawViewShell *>( mpViewShell ) == nullptr) + if (!mpViewShell + || !(dynamic_cast<const DrawViewShell*>(mpViewShell) + || dynamic_cast<const NotesPanelViewShell*>(mpViewShell))) { rSet.DisableItem( SID_ATTR_PARA_ADJUST_LEFT ); rSet.DisableItem( SID_ATTR_PARA_ADJUST_RIGHT ); diff --git a/sd/source/ui/view/outlnvsh.cxx b/sd/source/ui/view/outlnvsh.cxx index 718b28514e60..9c3b77d65a3d 100644 --- a/sd/source/ui/view/outlnvsh.cxx +++ b/sd/source/ui/view/outlnvsh.cxx @@ -318,7 +318,7 @@ void OutlineViewShell::Activate( bool bIsMDIActivate ) } ViewShell::Activate( bIsMDIActivate ); - SfxShell::BroadcastContextForActivation(true); + BroadcastContextForActivation(true); pOlView->SetLinks(); pOlView->ConnectToApplication(); diff --git a/sd/source/ui/view/viewshel.cxx b/sd/source/ui/view/viewshel.cxx index 9f49e4ca45a6..5b597db789b8 100644 --- a/sd/source/ui/view/viewshel.cxx +++ b/sd/source/ui/view/viewshel.cxx @@ -17,6 +17,8 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <framework/FrameworkHelper.hxx> +#include <framework/ViewShellWrapper.hxx> #include <memory> #include <ViewShell.hxx> #include <ViewShellImplementation.hxx> @@ -58,6 +60,7 @@ #include <SlideSorterViewShell.hxx> #include <ViewShellManager.hxx> #include <FormShellManager.hxx> +#include <EventMultiplexer.hxx> #include <svx/extrusionbar.hxx> #include <svx/fontworkbar.hxx> #include <svx/svdoutl.hxx> @@ -90,6 +93,12 @@ #include <sdmod.hxx> #include <AccessibleDocumentViewBase.hxx> +#include <com/sun/star/drawing/framework/XControllerManager.hpp> +#include <com/sun/star/drawing/framework/XConfigurationController.hpp> +#include <com/sun/star/drawing/framework/XConfiguration.hpp> +#include <com/sun/star/drawing/framework/XView.hpp> +#include <com/sun/star/frame/XFrame.hpp> + using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::presentation; @@ -392,6 +401,60 @@ void ViewShell::Deactivate(bool bIsMDIActivate) SfxShell::Deactivate(bIsMDIActivate); } +void ViewShell::BroadcastContextForActivation(const bool bIsActivated) +{ + auto getFrameworkResourceIdForShell = [&]() -> uno::Reference<drawing::framework::XResourceId> const + { + Reference<::css::drawing::framework::XControllerManager> xControllerManager( + GetViewShellBase().GetController(), UNO_QUERY); + if (!xControllerManager.is()) + return {}; + + Reference<::css::drawing::framework::XConfigurationController> xConfigurationController( + xControllerManager->getConfigurationController(), UNO_QUERY); + if (!xConfigurationController.is()) + return {}; + + Reference<::css::drawing::framework::XConfiguration> xConfiguration( + xConfigurationController->getCurrentConfiguration(), UNO_QUERY); + if (!xConfiguration.is()) + return {}; + + auto aResIdsIndirect + = xConfiguration->getResources({}, "", drawing::framework::AnchorBindingMode_INDIRECT); + + for (const uno::Reference<drawing::framework::XResourceId>& rResId : aResIdsIndirect) + { + auto pFrameworkHelper = framework::FrameworkHelper::Instance(GetViewShellBase()); + + uno::Reference<drawing::framework::XView> xView; + if (rResId->getResourceURL().match(framework::FrameworkHelper::msViewURLPrefix)) + { + xView.set(xConfigurationController->getResource(rResId), UNO_QUERY); + + if (xView.is()) + { + auto pViewShellWrapper + = dynamic_cast<framework::ViewShellWrapper*>(xView.get()); + if (pViewShellWrapper->GetViewShell().get() == this) + { + return rResId; + } + } + } + } + return {}; + }; + + if (bIsActivated) + { + GetViewShellBase().GetEventMultiplexer()->MultiplexEvent( + EventMultiplexerEventId::FocusShifted, nullptr, getFrameworkResourceIdForShell()); + } + + SfxShell::BroadcastContextForActivation(bIsActivated); +} + void ViewShell::Shutdown() { Exit (); diff --git a/svx/source/sidebar/ContextChangeEventMultiplexer.cxx b/svx/source/sidebar/ContextChangeEventMultiplexer.cxx index dd44e706aeec..2026f317f031 100644 --- a/svx/source/sidebar/ContextChangeEventMultiplexer.cxx +++ b/svx/source/sidebar/ContextChangeEventMultiplexer.cxx @@ -26,7 +26,6 @@ #include <comphelper/lok.hxx> #include <comphelper/processfactory.hxx> #include <sfx2/lokhelper.hxx> -#include <sfx2/viewsh.hxx> using namespace css; using namespace css::uno;