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(-)

New commits:
commit 990b975757a46169245edcd2db34d635394a2009
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Feb 16 12:00:24 2024 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Fri Feb 16 16:45:10 2024 +0100

    cool#8270 sw lok: fix bad statusbar pagenum string on async binding update
    
    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/+/163489
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index 66eec0f5060e..fcd697124046 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<SwViewShell>
 {
     friend void SetOutDev( SwViewShell *pSh, OutputDevice *pOut );
@@ -595,7 +597,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 8dccfeb9271a..94b203ef3d48 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -22,6 +22,7 @@
 #include <com/sun/star/text/XTextField.hpp>
 #include <com/sun/star/text/AuthorDisplayFormat.hpp>
 #include <com/sun/star/datatransfer/XTransferable2.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
 
 #include <test/helper/transferable.hxx>
 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
@@ -54,6 +55,7 @@
 #include <comphelper/processfactory.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <test/lokcallback.hxx>
+#include <sfx2/msgpool.hxx>
 
 #include <drawdoc.hxx>
 #include <ndtxt.hxx>
@@ -64,6 +66,7 @@
 #include <redline.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <IDocumentRedlineAccess.hxx>
+#include <IDocumentLayoutAccess.hxx>
 #include <flddat.hxx>
 #include <basesh.hxx>
 #include <unotxdoc.hxx>
@@ -777,6 +780,7 @@ namespace {
         boost::property_tree::ptree m_aRedlineTableModified;
         /// Post-it / annotation payload.
         boost::property_tree::ptree m_aComment;
+        std::vector<OString> m_aStateChanges;
         TestLokCallbackWrapper m_callbackWrapper;
 
         ViewCallback(SfxViewShell* pViewShell = nullptr, 
std::function<void(ViewCallback&)> const & rBeforeInstallFunc = {})
@@ -940,6 +944,11 @@ namespace {
                         m_aComment = m_aComment.get_child("comment");
                     }
                     break;
+                case LOK_CALLBACK_STATE_CHANGED:
+                    {
+                        m_aStateChanges.push_back(pPayload);
+                        break;
+                    }
             }
         }
     };
@@ -4165,6 +4174,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<beans::PropertyValue>());
+    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& rFrame = pWrtShell2->GetView().GetViewFrame();
+        SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool(&rFrame);
+        uno::Reference<util::XURLTransformer> 
xParser(util::URLTransformer::create(m_xContext));
+        util::URL aCommandURL;
+        aCommandURL.Complete = ".uno:StatePageNumber";
+        xParser->parseStrict(aCommandURL);
+        const SfxSlot* pSlot = rSlotPool.GetUnoSlot(aCommandURL.Path);
+        rFrame.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<size_t>(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(".uno:StatePageNumber=Page 2 of 2"_ostr, 
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 7a322ed7a45f..b353ecebbffe 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -2773,12 +2773,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 a6a6975e984c..a9658fe92ab7 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -1750,7 +1750,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 f07c25e2dfc1..d0ef1ba29dc0 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))
             {

Reply via email to