desktop/source/lib/init.cxx | 6 ++++ include/vcl/jsdialog/executor.hxx | 3 ++ sc/source/ui/navipi/navipi.cxx | 9 ++++++ sd/source/ui/dlg/navigatr.cxx | 8 +++++ sd/source/ui/view/drviews2.cxx | 29 ++++++--------------- sfx2/source/sidebar/Deck.cxx | 2 - sfx2/source/view/viewfrm.cxx | 10 ------- sw/source/uibase/utlui/navipi.cxx | 6 ++++ vcl/inc/jsdialog/enabled.hxx | 1 vcl/inc/jsdialog/jsdialogbuilder.hxx | 10 +++---- vcl/jsdialog/enabled.cxx | 16 +++++++++-- vcl/jsdialog/executor.cxx | 10 +++++++ vcl/jsdialog/jsdialogbuilder.cxx | 47 +++++++++++++++++++++++------------ vcl/jsdialog/jsdialogregister.cxx | 3 +- vcl/source/window/builder.cxx | 4 ++ 15 files changed, 107 insertions(+), 57 deletions(-)
New commits: commit 519a0d93ac1d4a9b8aa50dc0a30f924bb4a608d4 Author: Darshan-upadhyay1110 <darshan.upadh...@collabora.com> AuthorDate: Tue Mar 11 19:16:55 2025 +0530 Commit: Szymon Kłos <szymon.k...@collabora.com> CommitDate: Tue May 20 15:07:01 2025 +0200 Detach navigator from sidebar for online When online calls navigator send the json for just the navigator not the whole sidebar Create helper functions for sending full updates for navigator and siderbar to encapsulate magic strings all into executor.cxx Handle case for navigator entries on click. User will get specific navigation category entires onDemand when get the click event.Added `Navigator` option init.cxx same as we have for `sidebar` to handle events like `expand`,`select` etc... Above change credits of the patch goes to Nick Wingate (nick.wing...@collabora.com) What changes i did (Darshan): - We did not need ExpandEntireNavigator in content.cxx. As we will expand the navigator entries on demand when user clicks on the heading. - And the next thing i have added is we need to detach navigator for other apps as well.( impress, writer, calc & draw) - Small fix in SID_NAVIGATOR req handling(sd/source/ui/view/drviews2.cxx). Before we were not handling the incoming request properly after toggle window for SID_NAVIGATOR. - Solved conflicts on cherry pick for branch 25.04 Signed-off-by: Darshan-upadhyay1110 <darshan.upadh...@collabora.com> Change-Id: Ibbd2d224bce62e70e100c52085271f154e12c275 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183296 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Szymon Kłos <szymon.k...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184251 Tested-by: Jenkins diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx index 841ac22346db..268ea05974e3 100644 --- a/desktop/source/lib/init.cxx +++ b/desktop/source/lib/init.cxx @@ -5106,6 +5106,8 @@ static void lcl_sendDialogEvent(unsigned long long int nWindowId, const char* pA if (jsdialog::ExecuteAction(sCurrentShellId + "sidebar", sControlId, aMap)) return; + if (jsdialog::ExecuteAction(sCurrentShellId + "navigator", sControlId, aMap)) + return; if (jsdialog::ExecuteAction(sCurrentShellId + "notebookbar", sControlId, aMap)) return; if (jsdialog::ExecuteAction(sCurrentShellId + "formulabar", sControlId, aMap)) @@ -5116,6 +5118,9 @@ static void lcl_sendDialogEvent(unsigned long long int nWindowId, const char* pA // these dialogs are created with WindowId "0" if (!SfxViewShell::Current() && jsdialog::ExecuteAction(u"0"_ustr, sControlId, aMap)) return; + + // force resend - used in mobile-wizard + jsdialog::SendSidebarForView(nCurrentShellId); } catch (std::out_of_range& e) { @@ -5123,6 +5128,7 @@ static void lcl_sendDialogEvent(unsigned long long int nWindowId, const char* pA assert(false); } catch (...) {} + } diff --git a/include/vcl/jsdialog/executor.hxx b/include/vcl/jsdialog/executor.hxx index f6816c3a4eca..f776507dcbbd 100644 --- a/include/vcl/jsdialog/executor.hxx +++ b/include/vcl/jsdialog/executor.hxx @@ -148,6 +148,9 @@ namespace jsdialog // type used to store key-value pairs to put in the generated messages typedef std::unordered_map<OString, OUString> ActionDataMap; +VCL_DLLPUBLIC void SendNavigatorForView(const sal_uInt64 nShellId); +VCL_DLLPUBLIC void SendSidebarForView(const sal_uInt64 nShellId); + /// execute action on a widget VCL_DLLPUBLIC bool ExecuteAction(const OUString& nWindowId, const OUString& rWidget, const StringMap& rData); diff --git a/sc/source/ui/navipi/navipi.cxx b/sc/source/ui/navipi/navipi.cxx index b228745a3f9f..938418bdd068 100644 --- a/sc/source/ui/navipi/navipi.cxx +++ b/sc/source/ui/navipi/navipi.cxx @@ -41,6 +41,8 @@ #include <navsett.hxx> #include <markdata.hxx> +#include <vcl/jsdialog/executor.hxx> + #include <com/sun/star/uno/Reference.hxx> using namespace com::sun::star; @@ -334,6 +336,13 @@ ScNavigatorDlg::ScNavigatorDlg(SfxBindings* pB, weld::Widget* pParent, SfxNaviga , nCurRow(0) , nCurTab(0) { + + if (comphelper::LibreOfficeKit::isActive()) + { + sal_uInt64 nShellId = reinterpret_cast<sal_uInt64>(SfxViewShell::Current()); + jsdialog::SendNavigatorForView(nShellId); + } + UpdateInitShow(); UpdateSheetLimits(); diff --git a/sd/source/ui/dlg/navigatr.cxx b/sd/source/ui/dlg/navigatr.cxx index cd1eda46e92e..01e8edc544bc 100644 --- a/sd/source/ui/dlg/navigatr.cxx +++ b/sd/source/ui/dlg/navigatr.cxx @@ -48,6 +48,8 @@ #include <DrawViewShell.hxx> #include <utility> +#include <vcl/jsdialog/executor.hxx> + #include <vcl/commandevent.hxx> #include <comphelper/lok.hxx> @@ -69,6 +71,12 @@ SdNavigatorWin::SdNavigatorWin(weld::Widget* pParent, SfxBindings* pInBindings, , meDragType ( NAVIGATOR_DRAGTYPE_EMBEDDED ) , mpBindings ( pInBindings ) { + if (comphelper::LibreOfficeKit::isActive()) + { + sal_uInt64 nShellId = reinterpret_cast<sal_uInt64>(SfxViewShell::Current()); + jsdialog::SendNavigatorForView(nShellId); + } + mxTlbObjects->SetViewFrame( mpBindings->GetDispatcher()->GetFrame() ); mxTlbObjects->connect_row_activated(LINK(this, SdNavigatorWin, ClickObjectHdl)); diff --git a/sd/source/ui/view/drviews2.cxx b/sd/source/ui/view/drviews2.cxx index a01c2b135960..78ec12e62f22 100644 --- a/sd/source/ui/view/drviews2.cxx +++ b/sd/source/ui/view/drviews2.cxx @@ -3990,27 +3990,16 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq) case SID_NAVIGATOR: { - if (comphelper::LibreOfficeKit::isActive()) - { - GetViewFrame()->ShowChildWindow(SID_SIDEBAR); - OUString panelId = u"SdNavigatorPanel"_ustr; - ::sfx2::sidebar::Sidebar::TogglePanel( - panelId, GetViewFrame()->GetFrame().GetFrameInterface()); - - Cancel(); - rReq.Done(); - } else { - if ( rReq.GetArgs() ) - GetViewFrame()->SetChildWindow(SID_NAVIGATOR, - static_cast<const SfxBoolItem&>(rReq.GetArgs()-> - Get(SID_NAVIGATOR)).GetValue()); - else - GetViewFrame()->ToggleChildWindow( SID_NAVIGATOR ); + if ( rReq.GetArgs() ) + GetViewFrame()->SetChildWindow(SID_NAVIGATOR, + static_cast<const SfxBoolItem&>(rReq.GetArgs()-> + Get(SID_NAVIGATOR)).GetValue()); + else + GetViewFrame()->ToggleChildWindow( SID_NAVIGATOR ); - GetViewFrame()->GetBindings().Invalidate(SID_NAVIGATOR); - Cancel(); - rReq.Ignore (); - } + GetViewFrame()->GetBindings().Invalidate(SID_NAVIGATOR); + Cancel(); + rReq.Ignore (); } break; diff --git a/sfx2/source/sidebar/Deck.cxx b/sfx2/source/sidebar/Deck.cxx index 587824cbf5ec..2db1569be919 100644 --- a/sfx2/source/sidebar/Deck.cxx +++ b/sfx2/source/sidebar/Deck.cxx @@ -41,7 +41,7 @@ void Deck::LOKSendSidebarFullUpdate() if (comphelper::LibreOfficeKit::isActive()) { sal_uInt64 nShellId = reinterpret_cast<sal_uInt64>(SfxViewShell::Current()); - jsdialog::SendFullUpdate(OUString::number(nShellId) + "sidebar", u"Panel"_ustr); + jsdialog::SendSidebarForView(nShellId); } } diff --git a/sfx2/source/view/viewfrm.cxx b/sfx2/source/view/viewfrm.cxx index ba07d0cd654e..51bdd0adee7c 100644 --- a/sfx2/source/view/viewfrm.cxx +++ b/sfx2/source/view/viewfrm.cxx @@ -3584,16 +3584,6 @@ void SfxViewFrame::ChildWindowExecute( SfxRequest &rReq ) rReq.Done(); return; } - if (nSID == SID_NAVIGATOR) - { - if (comphelper::LibreOfficeKit::isActive()) - { - ShowChildWindow(SID_SIDEBAR); - ::sfx2::sidebar::Sidebar::ShowDeck(u"NavigatorDeck", this, true); - rReq.Done(); - return; - } - } bool bHasChild = HasChildWindow(nSID); bool bShow = pShowItem ? pShowItem->GetValue() : !bHasChild; diff --git a/sw/source/uibase/utlui/navipi.cxx b/sw/source/uibase/utlui/navipi.cxx index d96e25bf0fdc..85bbb1eb56d9 100644 --- a/sw/source/uibase/utlui/navipi.cxx +++ b/sw/source/uibase/utlui/navipi.cxx @@ -53,6 +53,7 @@ #include <swcont.hxx> #include <content.hxx> +#include <vcl/jsdialog/executor.hxx> using namespace ::com::sun::star::uno; using namespace ::com::sun::star::frame; @@ -450,6 +451,11 @@ SwNavigationPI::SwNavigationPI(weld::Widget* pParent, , m_bGlobalMode(false) { InitContentFunctionsToolbar(); + if (comphelper::LibreOfficeKit::isActive()) + { + sal_uInt64 nShellId = reinterpret_cast<sal_uInt64>(SfxViewShell::Current()); + jsdialog::SendNavigatorForView(nShellId); + } m_xContainer->connect_container_focus_changed(LINK(this, SwNavigationPI, SetFocusChildHdl)); diff --git a/vcl/inc/jsdialog/enabled.hxx b/vcl/inc/jsdialog/enabled.hxx index fc61a9dba8fc..eedf83f69a21 100644 --- a/vcl/inc/jsdialog/enabled.hxx +++ b/vcl/inc/jsdialog/enabled.hxx @@ -21,6 +21,7 @@ bool isBuilderEnabledForMenu(std::u16string_view rUIFile); bool isBuilderEnabledForSidebar(std::u16string_view rUIFile); bool isBuilderEnabledForAddressInput(std::u16string_view rUIFile); bool isBuilderEnabledForFormulabar(std::u16string_view rUIFile); +bool isBuilderEnabledForNavigator(std::u16string_view rUIFile); bool isInterimBuilderEnabledForNotebookbar(std::u16string_view rUIFile); } diff --git a/vcl/inc/jsdialog/jsdialogbuilder.hxx b/vcl/inc/jsdialog/jsdialogbuilder.hxx index dc545f21dfe9..89db0cb8c508 100644 --- a/vcl/inc/jsdialog/jsdialogbuilder.hxx +++ b/vcl/inc/jsdialog/jsdialogbuilder.hxx @@ -92,7 +92,8 @@ class JSInstanceBuilder final : public SalInstanceBuilder, public JSDialogSender void initializeDialogSender(); void initializePopupSender(); - void initializeSidebarSender(sal_uInt64 nLOKWindowId, const std::u16string_view& rUIFile); + void initializeSidebarSender(sal_uInt64 nLOKWindowId, const std::u16string_view& rUIFile, + const std::u16string_view& sTypeOfJSON); void initializeNotebookbarSender(sal_uInt64 nLOKWindowId); void initializeFormulabarSender(sal_uInt64 nLOKWindowId, const std::u16string_view& sTypeOfJSON, vcl::Window* pVclParent); @@ -147,10 +148,9 @@ public: CreateNotebookbarBuilder(vcl::Window* pParent, const OUString& rUIRoot, const OUString& rUIFile, const css::uno::Reference<css::frame::XFrame>& rFrame, sal_uInt64 nWindowId = 0); - static std::unique_ptr<JSInstanceBuilder> CreateSidebarBuilder(weld::Widget* pParent, - const OUString& rUIRoot, - const OUString& rUIFile, - sal_uInt64 nLOKWindowId = 0); + static std::unique_ptr<JSInstanceBuilder> + CreateSidebarBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile, + const OUString& jsonType, sal_uInt64 nLOKWindowId = 0); static std::unique_ptr<JSInstanceBuilder> CreatePopupBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile); diff --git a/vcl/jsdialog/enabled.cxx b/vcl/jsdialog/enabled.cxx index 4afc5e430ca8..f3ee41f98a68 100644 --- a/vcl/jsdialog/enabled.cxx +++ b/vcl/jsdialog/enabled.cxx @@ -392,7 +392,6 @@ constexpr auto SidebarList = frozen::make_unordered_set<std::u16string_view>({ // scalc { u"modules/scalc/ui/functionpanel.ui" }, - { u"modules/scalc/ui/navigatorpanel.ui" }, { u"modules/scalc/ui/sidebaralignment.ui" }, { u"modules/scalc/ui/sidebarcellappearance.ui" }, { u"modules/scalc/ui/sidebarnumberformat.ui" }, @@ -410,7 +409,6 @@ constexpr auto SidebarList { u"modules/simpress/ui/masterpagepanel.ui" }, { u"modules/simpress/ui/masterpagepanelall.ui" }, { u"modules/simpress/ui/masterpagepanelrecent.ui" }, - { u"modules/simpress/ui/navigatorpanel.ui" }, { u"modules/simpress/ui/sidebarslidebackground.ui" }, { u"modules/simpress/ui/slidetransitionspanel.ui" }, { u"modules/simpress/ui/tabledesignpanel.ui" }, @@ -420,7 +418,6 @@ constexpr auto SidebarList // swriter { u"modules/swriter/ui/a11ycheckissuespanel.ui" }, { u"modules/swriter/ui/managechangessidebar.ui" }, - { u"modules/swriter/ui/navigatorpanel.ui" }, { u"modules/swriter/ui/pagefooterpanel.ui" }, { u"modules/swriter/ui/pageformatpanel.ui" }, { u"modules/swriter/ui/pageheaderpanel.ui" }, @@ -451,6 +448,14 @@ constexpr auto SidebarList { u"svx/ui/sidebartextpanel.ui" } }); +// ========== NAVIGATOR ================================================= // +constexpr auto NavigatorList + = frozen::make_unordered_set<std::u16string_view>({ + { u"modules/swriter/ui/navigatorpanel.ui"}, + { u"modules/scalc/ui/navigatorpanel.ui"}, + { u"modules/simpress/ui/navigatorpanel.ui"} +}); + // ========== NOTEBOOKBAR ================================================= // constexpr auto NotebookbarList @@ -567,6 +572,11 @@ bool isBuilderEnabledForSidebar(std::u16string_view rUIFile) } +bool isBuilderEnabledForNavigator(std::u16string_view rUIFile) +{ + return isInMap(NavigatorList, rUIFile); +} + bool isInterimBuilderEnabledForNotebookbar(std::u16string_view rUIFile) { return isInMap(NotebookbarList, rUIFile); diff --git a/vcl/jsdialog/executor.cxx b/vcl/jsdialog/executor.cxx index 176c0c60f006..4fd740fb8f56 100644 --- a/vcl/jsdialog/executor.cxx +++ b/vcl/jsdialog/executor.cxx @@ -91,6 +91,16 @@ StringMap jsonToStringMap(const char* pJSON) return aArgs; } +void SendNavigatorForView(const sal_uInt64 nShellId) +{ + jsdialog::SendFullUpdate(OUString::number(nShellId) + "navigator", "NavigatorPanel"); +} + +void SendSidebarForView(const sal_uInt64 nShellId) +{ + jsdialog::SendFullUpdate(OUString::number(nShellId) + "sidebar", "Panel"); +} + void SendFullUpdate(const OUString& nWindowId, const OUString& rWidget) { auto aWidgetMap = JSInstanceBuilder::Widgets().Find(nWindowId); diff --git a/vcl/jsdialog/jsdialogbuilder.cxx b/vcl/jsdialog/jsdialogbuilder.cxx index d783732a876f..d2a6dfb0cd8a 100644 --- a/vcl/jsdialog/jsdialogbuilder.cxx +++ b/vcl/jsdialog/jsdialogbuilder.cxx @@ -29,6 +29,7 @@ #include <tools/stream.hxx> #include <vcl/cvtgrf.hxx> #include <wizdlg.hxx> +#include <jsdialog/enabled.hxx> namespace { @@ -178,32 +179,41 @@ void JSInstanceBuilder::initializePopupSender() } void JSInstanceBuilder::initializeSidebarSender(sal_uInt64 nLOKWindowId, - const std::u16string_view& rUIFile) + const std::u16string_view& rUIFile, + const std::u16string_view& sTypeOfJSON) { - m_sTypeOfJSON = "sidebar"; + m_sTypeOfJSON = sTypeOfJSON; m_nWindowId = nLOKWindowId; vcl::Window* pRoot = m_xBuilder->get_widget_root(); m_aParentDialog = pRoot->GetParentWithLOKNotifier(); - if (rUIFile == u"sfx/ui/panel.ui") - { - // builder for Panel, get SidebarDockingWindow as m_aContentWindow - m_aContentWindow = pRoot; - for (int i = 0; i < 7 && m_aContentWindow; i++) - m_aContentWindow = m_aContentWindow->GetParent(); - } - else + bool bIsSidebarPanel = (rUIFile == u"sfx/ui/panel.ui"); + bool bIsNavigatorPanel = jsdialog::isBuilderEnabledForNavigator(rUIFile); + + // builder for Panel, PanelLayout, and DockingWindow + // get SidebarDockingWindow, or SwNavigatorWin as m_aContentWindow + // PanelLayout : 9 levels up from pRoot + // Panel : 7 levels up from pRoot + // DockingWindow: 3 levels up from pRoot + unsigned nLevelsUp = 9; + if (bIsSidebarPanel) + nLevelsUp = 7; + else if (bIsNavigatorPanel) + nLevelsUp = 3; + + if (nLevelsUp > 0) { // embedded fragments cannot send close message for whole sidebar if (rUIFile == u"modules/simpress/ui/customanimationfragment.ui") m_bCanClose = false; - // builder for PanelLayout, get SidebarDockingWindow as m_aContentWindow m_aContentWindow = pRoot; - for (int i = 0; i < 9 && m_aContentWindow; i++) + for (unsigned i = 0; i < nLevelsUp && m_aContentWindow; i++) + { m_aContentWindow = m_aContentWindow->GetParent(); + } } InsertWindowToMap(getMapIdFromWindowId()); @@ -285,7 +295,7 @@ JSInstanceBuilder::JSInstanceBuilder(weld::Widget* pParent, vcl::Window* pVclPar break; case JSInstanceBuilder::Type::Sidebar: - initializeSidebarSender(nLOKWindowId, rUIFile); + initializeSidebarSender(nLOKWindowId, rUIFile, sTypeOfJSON); break; case JSInstanceBuilder::Type::Notebookbar: @@ -325,10 +335,12 @@ std::unique_ptr<JSInstanceBuilder> JSInstanceBuilder::CreateNotebookbarBuilder( std::unique_ptr<JSInstanceBuilder> JSInstanceBuilder::CreateSidebarBuilder(weld::Widget* pParent, const OUString& rUIRoot, const OUString& rUIFile, + const OUString& jsonType, sal_uInt64 nLOKWindowId) { return std::make_unique<JSInstanceBuilder>(pParent, nullptr, rUIRoot, rUIFile, - JSInstanceBuilder::Type::Sidebar, nLOKWindowId); + JSInstanceBuilder::Type::Sidebar, nLOKWindowId, + jsonType); } std::unique_ptr<JSInstanceBuilder> JSInstanceBuilder::CreatePopupBuilder(weld::Widget* pParent, @@ -528,8 +540,11 @@ std::unique_ptr<weld::Container> JSInstanceBuilder::weld_container(const OUStrin if (pParent) jsdialog::SendFullUpdate(sId, pParent->get_id()); - // this is nested builder, don't close parent dialog on destroy (eg. single tab page is closed) - m_bCanClose = false; + // Navigator is currently just a panellayout but we treat it as its own dialog in online + // this is a hack to get it to close atm but probably need a better solution + if (id != u"NavigatorPanel") + // this is nested builder, don't close parent dialog on destroy (eg. single tab page is closed) + m_bCanClose = false; m_bIsNestedBuilder = true; } diff --git a/vcl/jsdialog/jsdialogregister.cxx b/vcl/jsdialog/jsdialogregister.cxx index e10f020432f0..8f064107e528 100644 --- a/vcl/jsdialog/jsdialogregister.cxx +++ b/vcl/jsdialog/jsdialogregister.cxx @@ -15,7 +15,8 @@ JSInstanceBuilder::JSDialogRegister JSInstanceBuilder::m_aWidgetRegister; OUString JSInstanceBuilder::getMapIdFromWindowId() const { if (m_sTypeOfJSON == "sidebar" || m_sTypeOfJSON == "notebookbar" - || m_sTypeOfJSON == "formulabar" || m_sTypeOfJSON == "addressinputfield") + || m_sTypeOfJSON == "formulabar" || m_sTypeOfJSON == "addressinputfield" + || m_sTypeOfJSON == "navigator") { return OUString::number(m_nWindowId) + m_sTypeOfJSON; } diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 21734bd4d248..edf562bd01f8 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -190,11 +190,13 @@ std::unique_ptr<weld::Builder> Application::CreateBuilder(weld::Widget* pParent, if (comphelper::LibreOfficeKit::isActive() && !jsdialog::isIgnored(rUIFile)) { if (jsdialog::isBuilderEnabledForSidebar(rUIFile)) - return JSInstanceBuilder::CreateSidebarBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, nLOKWindowId); + return JSInstanceBuilder::CreateSidebarBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, "sidebar", nLOKWindowId); else if (jsdialog::isBuilderEnabledForPopup(rUIFile)) return JSInstanceBuilder::CreatePopupBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile); else if (jsdialog::isBuilderEnabledForMenu(rUIFile)) return JSInstanceBuilder::CreateMenuBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile); + else if (jsdialog::isBuilderEnabledForNavigator(rUIFile)) + return JSInstanceBuilder::CreateSidebarBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile, "navigator", nLOKWindowId); else if (jsdialog::isBuilderEnabled(rUIFile, bMobile)) return JSInstanceBuilder::CreateDialogBuilder(pParent, AllSettings::GetUIRootDir(), rUIFile); else