sc/source/ui/inc/gridwin.hxx   |    7 +++
 sc/source/ui/view/gridwin.cxx  |    6 +++
 sc/source/ui/view/gridwin4.cxx |   73 +++++++++++++++++++++++++++++++++++++++++
 sc/source/ui/view/tabview5.cxx |   11 ++++++
 4 files changed, 97 insertions(+)

New commits:
commit 129c680f02564c8bee93930dec9f2ad80980cc1c
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Wed Aug 18 23:42:45 2021 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Sat Nov 6 00:58:02 2021 +0100

    Do not count pages for initial page breaks, tdf#124983 follow-up
    
    Use a loaded page size or leave it. Otherwise the previous
    implementation could had lead to tremendous waiting time blocking
    everything on large data without. See source code comment.
    
    Also trigger updating page breaks only for one grid window, not
    multiple repeating everything all over.
    
    Remove bSetup parameter that does nothing but either doing something or
    nothing, check in caller instead.
    
    Move member variables to where they belong.
    
    Change-Id: I5efc321e5bc5af075a77631aa9d94b0c50ae6b6b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120689
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121845
    Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de>
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 5ebb26241d10..e9363a1f96d2 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -190,6 +190,8 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, 
public DropTargetHel
 
     RfCorner                aRFSelectedCorned;
 
+    Timer                   maShowPageBreaksTimer;
+
     bool                    bEEMouse:1;               // Edit Engine has mouse
     bool                    bDPMouse:1;               // DataPilot D&D (new 
Pivot table)
     bool                    bRFMouse:1;               // RangeFinder drag
@@ -200,6 +202,7 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, 
public DropTargetHel
     bool                    bNeedsRepaint:1;
     bool                    bAutoMarkVisible:1;
     bool                    bListValButton:1;
+    bool                    bInitialPageBreaks:1;
 
     DECL_LINK( PopupModeEndHdl, FloatingWindow*, void );
     DECL_LINK( PopupSpellingHdl, SpellCallbackInfo&, void );
@@ -288,6 +291,8 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, 
public DropTargetHel
 
     void            GetSelectionRects( ::std::vector< tools::Rectangle >& 
rPixelRects );
 
+    void            SetupInitialPageBreaks(const ScDocument& rDoc, SCTAB nTab);
+    DECL_LINK(InitiatePageBreaksTimer, Timer*, void);
 
 protected:
     virtual void    PrePaint(vcl::RenderContext& rRenderContext) override;
@@ -462,6 +467,8 @@ public:
 
     void updateLOKValListButton(bool bVisible, const ScAddress& rPos) const;
 
+    void initiatePageBreaks();
+
 protected:
     void ImpCreateOverlayObjects();
     void ImpDestroyOverlayObjects();
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 99e5ca53eec1..15ae09b7f31c 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -482,6 +482,10 @@ ScGridWindow::ScGridWindow( vcl::Window* pParent, 
ScViewData* pData, ScSplitPos
 
     SetDigitLanguage( SC_MOD()->GetOptDigitLanguage() );
     EnableRTL( false );
+
+    bInitialPageBreaks = true;
+    maShowPageBreaksTimer.SetInvokeHandler(LINK(this, ScGridWindow, 
InitiatePageBreaksTimer));
+    maShowPageBreaksTimer.SetTimeout(1);
 }
 
 ScGridWindow::~ScGridWindow()
@@ -491,6 +495,8 @@ ScGridWindow::~ScGridWindow()
 
 void ScGridWindow::dispose()
 {
+    maShowPageBreaksTimer.Stop();
+
     ImpDestroyOverlayObjects();
 
     mpFilterBox.disposeAndClear();
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index 9426c8842bf0..aa7ad1312acc 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -1055,6 +1055,28 @@ void ScGridWindow::DrawContent(OutputDevice &rDevice, 
const ScTableInfo& rTableI
 
     if (mpNoteMarker)
         mpNoteMarker->Draw(); // Above the cursor, in drawing map mode
+
+    if (bPage && bInitialPageBreaks)
+        SetupInitialPageBreaks(rDoc, nTab);
+}
+
+
+void ScGridWindow::SetupInitialPageBreaks(const ScDocument& rDoc, SCTAB nTab)
+{
+    // tdf#124983, if option LibreOfficeDev Calc/View/Visual Aids/Page breaks
+    // is enabled, breaks should be visible. If the document is opened the 
first
+    // time, the breaks are not calculated yet, so for this initialization
+    // a timer will be triggered here.
+    std::set<SCCOL> aColBreaks;
+    std::set<SCROW> aRowBreaks;
+    rDoc.GetAllColBreaks(aColBreaks, nTab, true, false);
+    rDoc.GetAllRowBreaks(aRowBreaks, nTab, true, false);
+    if (aColBreaks.size() == 0 || aRowBreaks.size() == 0)
+    {
+        maShowPageBreaksTimer.SetPriority(TaskPriority::DEFAULT_IDLE);
+        maShowPageBreaksTimer.Start();
+    }
+    bInitialPageBreaks = false;
 }
 
 namespace
@@ -2005,4 +2027,55 @@ void ScGridWindow::DataChanged( const DataChangedEvent& 
rDCEvt )
     }
 }
 
+void ScGridWindow::initiatePageBreaks()
+{
+    bInitialPageBreaks = true;
+}
+
+IMPL_LINK(ScGridWindow, InitiatePageBreaksTimer, Timer*, pTimer, void)
+{
+    if (pTimer == &maShowPageBreaksTimer)
+    {
+        const ScViewOptions& rOpts = pViewData->GetOptions();
+        const bool bPage = rOpts.GetOption(VOPT_PAGEBREAKS);
+        // tdf#124983, if option LibreOfficeDev Calc/View/Visual Aids/Page
+        // breaks is enabled, breaks should be visible. If the document is
+        // opened the first time or a tab is activated the first time, the
+        // breaks are not calculated yet, so this initialization is done here.
+        if (bPage)
+        {
+            const SCTAB nCurrentTab = pViewData->GetTabNo();
+            ScDocument* pDoc = pViewData->GetDocument();
+            const Size aPageSize = pDoc->GetPageSize(nCurrentTab);
+            // Do not attempt to calculate a page size here if it is empty if
+            // that involves counting pages.
+            // An earlier implementation did
+            //   ScPrintFunc(pDocSh, pDocSh->GetPrinter(), nCurrentTab);
+            //   rDoc.SetPageSize(nCurrentTab, rDoc.GetPageSize(nCurrentTab));
+            // which resulted in tremendous waiting times after having loaded
+            // larger documents i.e. imported from CSV, in which UI is entirely
+            // blocked. All time is spent under ScPrintFunc::CountPages() in
+            // ScTable::ExtendPrintArea() in the loop that calls
+            // MaybeAddExtraColumn() to do stuff for each text string content
+            // cell (each row in each column). Maybe that can be optimized, or
+            // obtaining page size without that overhead would be possible, but
+            // as is calling that from here is a no-no so this is a quick
+            // disable things.
+            if (aPageSize.Width()>0&&aPageSize.Height())
+            {
+                ScDocShell* pDocSh = pViewData->GetDocShell();
+                const bool bModified = pDocSh->IsModified();
+                // Even setting the same size sets page size valid, so
+                // UpdatePageBreaks() actually does something.
+                pDoc->SetPageSize( nCurrentTab, aPageSize);
+                pDoc->UpdatePageBreaks(nCurrentTab);
+                pDocSh->PostPaint(0, 0, nCurrentTab, pDoc->MaxCol(), 
pDoc->MaxRow(), nCurrentTab, PaintPartFlags::Grid);
+                pDocSh->SetModified(bModified);
+            }
+        }
+
+        Invalidate();
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx
index b075b748f0e3..635b40e97ab5 100644
--- a/sc/source/ui/view/tabview5.cxx
+++ b/sc/source/ui/view/tabview5.cxx
@@ -315,6 +315,17 @@ void ScTabView::TabChanged( bool bSameTabButMoved )
         }
     }
 
+    for (int i = 0; i < 4; i++)
+    {
+        if (pGridWin[i])
+        {
+            pGridWin[i]->initiatePageBreaks();
+            // Trigger calculating page breaks only once.
+            break;
+        }
+    }
+
+
     if (comphelper::LibreOfficeKit::isActive())
     {
         ScDocShell* pDocSh = GetViewData().GetDocShell();

Reply via email to