From fb33ed13f4f83f92de7d5276271ab0f95458e90b Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Fri, 16 Feb 2024 12:00:24 +0100 Subject: cool#8270 sw lok: fix bad statusbar pagenum string on async binding update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is similar to commit 51d8a2ef54751403fa707816e27ddb4e7faa8231 (cool#7492 sfx2 lok: fix bad view id / statusbar string on async binding update, 2024-01-08), but here the problem was that the async job tried to get the current view from the model, which is not correct. Fix the buggy page number string in the status bar by requesting callers of SwViewShell::GetFirstLastVisPageNumbers() to provide the view, given that SwViewShell itself doesn't have access to SwView, only the SwWrtShell subclass would have that. (cherry picked from commit ce350b840ce806c4060f9fdbd67fa4c95c82edf5) Change-Id: I7e10c05d2429ea2771d6c3e46ac9ce77c0eb2bbe Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163512 Tested-by: Jenkins CollaboraOffice Reviewed-by: Caolán McNamara --- sw/inc/viewsh.hxx | 4 +- sw/qa/extras/tiledrendering/tiledrendering.cxx | 64 ++++++++++++++++++++++++++ sw/source/core/view/viewsh.cxx | 7 +-- sw/source/uibase/uiview/view2.cxx | 2 +- sw/source/uibase/uiview/viewmdi.cxx | 2 +- 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx index 2ef93801deeb..0da1aabbf35e 100644 --- a/sw/inc/viewsh.hxx +++ b/sw/inc/viewsh.hxx @@ -106,6 +106,8 @@ struct SwVisiblePageNumbers OUString sFirstCustomVirt, sLastCustomVirt; }; +class SwView; + class SW_DLLPUBLIC SwViewShell : public sw::Ring { friend void SetOutDev( SwViewShell *pSh, OutputDevice *pOut ); @@ -603,7 +605,7 @@ public: bool isOutputToWindow() const; void OnGraphicArrived(const SwRect&); - void GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers); + void GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers, SwView& rView); virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; }; diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx index 86072c2045c3..97b93d652993 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -53,6 +54,7 @@ #include #include #include +#include #include #include @@ -63,6 +65,7 @@ #include #include #include +#include #include #include #include @@ -772,6 +775,7 @@ namespace { boost::property_tree::ptree m_aRedlineTableModified; /// Post-it / annotation payload. boost::property_tree::ptree m_aComment; + std::vector m_aStateChanges; TestLokCallbackWrapper m_callbackWrapper; ViewCallback(SfxViewShell* pViewShell = nullptr, std::function const & rBeforeInstallFunc = {}) @@ -935,6 +939,11 @@ namespace { m_aComment = m_aComment.get_child("comment"); } break; + case LOK_CALLBACK_STATE_CHANGED: + { + m_aStateChanges.push_back(pPayload); + break; + } } } }; @@ -4208,6 +4217,61 @@ CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testSwitchingChartToDarkMode) CPPUNIT_ASSERT(nBlackPixels > nWhitePixels); } +CPPUNIT_TEST_FIXTURE(SwTiledRenderingTest, testStatusBarPageNumber) +{ + // Given a document with 2 pages, first view on page 1, second view on page 2: + SwXTextDocument* pXTextDocument = createDoc(); + int nView1 = SfxLokHelper::getView(); + SwWrtShell* pWrtShell1 = pXTextDocument->GetDocShell()->GetWrtShell(); + pWrtShell1->InsertPageBreak(); + SwRootFrame* pLayout = pWrtShell1->getIDocumentLayoutAccess().GetCurrentLayout(); + SwFrame* pPage1 = pLayout->GetLower(); + CPPUNIT_ASSERT(pPage1); + SwFrame* pPage2 = pPage1->GetNext(); + CPPUNIT_ASSERT(pPage2); + SfxLokHelper::createView(); + int nView2 = SfxLokHelper::getView(); + pXTextDocument->initializeForTiledRendering(uno::Sequence()); + SfxLokHelper::setView(nView1); + ViewCallback aView1; + pWrtShell1->SttEndDoc(/*bStt=*/true); + pWrtShell1->Insert("start"); + pWrtShell1->GetView().SetVisArea(pPage1->getFrameArea().SVRect()); + SfxLokHelper::setView(nView2); + ViewCallback aView2; + SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell(); + pWrtShell2->SttEndDoc(/*bStt=*/false); + pWrtShell2->Insert("end"); + pWrtShell2->GetView().SetVisArea(pPage2->getFrameArea().SVRect()); + { + // Listen to StatePageNumber changes in view 2: + SfxViewFrame* pFrame = pWrtShell2->GetView().GetViewFrame(); + SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool(pFrame); + uno::Reference xParser(util::URLTransformer::create(m_xContext)); + util::URL aCommandURL; + aCommandURL.Complete = ".uno:StatePageNumber"; + xParser->parseStrict(aCommandURL); + const SfxSlot* pSlot = rSlotPool.GetUnoSlot(aCommandURL.Path); + pFrame->GetBindings().GetDispatch(pSlot, aCommandURL, false); + } + aView2.m_aStateChanges.clear(); + + // When deleting a character in view 2 and processing jobs with view 1 set to active: + pWrtShell2->DelLeft(); + SfxLokHelper::setView(nView1); + pWrtShell2->GetView().GetViewFrame()->GetBindings().GetTimer().Invoke(); + // Once more to hit the pImpl->bMsgDirty = false case in SfxBindings::NextJob_Impl(). + pWrtShell2->GetView().GetViewFrame()->GetBindings().GetTimer().Invoke(); + + // Then maks sure the page number in view 2 is correct: + CPPUNIT_ASSERT_EQUAL(static_cast(1), aView2.m_aStateChanges.size()); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: .uno:StatePageNumber=Page 2 of 2 + // - Actual : .uno:StatePageNumber=Page 1 of 2 + // i.e. view 2 got the page number of view 1. + CPPUNIT_ASSERT_EQUAL(OString(".uno:StatePageNumber=Page 2 of 2"), aView2.m_aStateChanges[0]); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index 670925ea192e..006fa433ac2e 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -2842,12 +2842,9 @@ SwPostItMgr* SwViewShell::GetPostItMgr() return nullptr; } -void SwViewShell::GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers) +void SwViewShell::GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers, SwView& rView) { - SwView* pView = GetDoc()->GetDocShell() ? GetDoc()->GetDocShell()->GetView() : nullptr; - if (!pView) - return; - SwRect rViewVisArea(pView->GetVisArea()); + SwRect rViewVisArea(rView.GetVisArea()); vcl::RenderContext* pRenderContext = GetOut(); const SwPageFrame* pPageFrame = Imp()->GetFirstVisPage(pRenderContext); SwRect rPageRect = pPageFrame->getFrameArea(); diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx index ac4e03ebcfad..5405e64a2624 100644 --- a/sw/source/uibase/uiview/view2.cxx +++ b/sw/source/uibase/uiview/view2.cxx @@ -1668,7 +1668,7 @@ void SwView::StateStatusLine(SfxItemSet &rSet) OUString aPageStr; SwVisiblePageNumbers aVisiblePageNumbers; - m_pWrtShell->GetFirstLastVisPageNumbers(aVisiblePageNumbers); + m_pWrtShell->GetFirstLastVisPageNumbers(aVisiblePageNumbers, m_pWrtShell->GetView()); // convert to strings and define references OUString sFirstPhy = OUString::number(aVisiblePageNumbers.nFirstPhy); diff --git a/sw/source/uibase/uiview/viewmdi.cxx b/sw/source/uibase/uiview/viewmdi.cxx index 0201fe69c63e..c2df5f67c380 100644 --- a/sw/source/uibase/uiview/viewmdi.cxx +++ b/sw/source/uibase/uiview/viewmdi.cxx @@ -347,7 +347,7 @@ IMPL_LINK( SwView, MoveNavigationHdl, void*, p, void ) { tools::Long nYPos; SwVisiblePageNumbers aVisiblePageNumbers; - rSh.GetFirstLastVisPageNumbers(aVisiblePageNumbers); + rSh.GetFirstLastVisPageNumbers(aVisiblePageNumbers, rSh.GetView()); if ((bNext && aVisiblePageNumbers.nLastPhy + 1 > rSh.GetPageCnt()) || (!bNext && aVisiblePageNumbers.nFirstPhy == 1)) { -- cgit