[Libreoffice-commits] core.git: sc/inc sc/source

Marco Cecchetti marco.cecchetti at collabora.com
Fri Feb 10 18:20:30 UTC 2017


 sc/inc/address.hxx            |    2 
 sc/source/ui/view/tabview.cxx |  290 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 243 insertions(+), 49 deletions(-)

New commits:
commit e530c7c4bcaaeb99cecd6f3c2c303db2a114b555
Author: Marco Cecchetti <marco.cecchetti at collabora.com>
Date:   Wed Nov 30 14:13:15 2016 +0100

    LOK - Calc: Increase the row limit to 10.000 rows.
    
    Change-Id: I2702b1e654dff816c8d66e82464ea578473dba60

diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index 05f62b4..4876b58 100644
--- a/sc/inc/address.hxx
+++ b/sc/inc/address.hxx
@@ -71,7 +71,7 @@ const SCCOL       MAXCOL         = MAXCOLCOUNT - 1;
 const SCTAB       MAXTAB         = MAXTABCOUNT - 1;
 const SCCOLROW    MAXCOLROW      = MAXROW;
 // Maximun tiled rendering values
-const SCROW       MAXTILEDROW    = 1000;
+const SCROW       MAXTILEDROW    = 10000;
 // Limit the initial tab count to prevent users to set the count too high,
 // which could cause the memory usage of blank documents to exceed the
 // available system memory.
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 3cabc92..39a417f 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -44,6 +44,9 @@
 #include "AccessibilityHints.hxx"
 #include "appoptio.hxx"
 #include "attrib.hxx"
+#include <comphelper/lok.hxx>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
+#include <sfx2/lokhelper.hxx>
 
 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
 
@@ -2307,82 +2310,273 @@ OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
     if (!pDoc)
         return OUString();
 
-    SCCOL nEndCol = 0;
+    if (rRectangle.IsEmpty())
+        return OUString();
+
+    rtl::OUStringBuffer aBuffer(256);
+    aBuffer.append("{ \"commandName\": \".uno:ViewRowColumnHeaders\",\n");
+
+    SCROW nStartRow = 0;
     SCROW nEndRow = 0;
-    pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow);
+    SCCOL nStartCol = 0;
+    SCCOL nEndCol = 0;
 
-    rtl::OUStringBuffer aBuffer(256 + (50 * nEndRow) + (50 * nEndCol));
+    /// *** start collecting ROWS ***
 
-    aBuffer.append("{ \"commandName\": \".uno:ViewRowColumnHeaders\",\n");
-    aBuffer.append("\"rows\": [\n");
+    /// 1) compute start and end rows
 
-    long nTotal = 0;
     long nTotalPixels = 0;
+    if (rRectangle.Top() < rRectangle.Bottom())
+    {
+        long nUpperBoundPx = rRectangle.Top() / TWIPS_PER_PIXEL;
+        long nLowerBoundPx = rRectangle.Bottom() / TWIPS_PER_PIXEL;
+        nEndRow = MAXTILEDROW;
+        for (SCROW nRow = 0; nRow <= MAXTILEDROW; ++nRow)
+        {
+            if (nTotalPixels > nLowerBoundPx)
+            {
+                nEndRow = nRow; // first row below the rectangle
+                break;
+            }
+
+            const sal_uInt16 nSize = pDoc->GetRowHeight(nRow, aViewData.GetTabNo());
+            const long nSizePx = ScViewData::ToPixel(nSize, 1.0 / TWIPS_PER_PIXEL);
+
+            nTotalPixels += nSizePx;
+
+            if (nTotalPixels < nUpperBoundPx)
+            {
+                nStartRow = nRow; // last row above the rectangle
+                continue;
+            }
+        }
+
+        nStartRow -= 1;
+        nEndRow += 2;
+
+        if (nStartRow < 0) nStartRow = 0;
+        if (nEndRow > MAXTILEDROW) nEndRow = MAXTILEDROW;
+    }
+
+    aBuffer.ensureCapacity( aBuffer.getCapacity() + (50 * (nEndRow - nStartRow + 1)) );
+
+
+    long nVisibleRows = nEndRow - nStartRow;
+    if (nVisibleRows < 25)
+        nVisibleRows = 25;
+
+
+    /// 2) if we are approaching current max tiled row, signal a size changed event
+    ///    and invalidate the involved area
+
+    if (nEndRow > aViewData.GetMaxTiledRow() - nVisibleRows)
+    {
+        ScDocShell* pDocSh = aViewData.GetDocShell();
+        ScModelObj* pModelObj = pDocSh ? ScModelObj::getImplementation( pDocSh->GetModel() ) : nullptr;
+        Size aOldSize(0, 0);
+        if (pModelObj)
+            aOldSize = pModelObj->getDocumentSize();
+
+        aViewData.SetMaxTiledRow(std::min(std::max(nEndRow, aViewData.GetMaxTiledRow()) + nVisibleRows, (long)(MAXTILEDROW)));
+
+        Size aNewSize(0, 0);
+        if (pModelObj)
+            aNewSize = pModelObj->getDocumentSize();
+
+        if (pDocSh)
+        {
+            // Provide size in the payload, so clients don't have to
+            // call lok::Document::getDocumentSize().
+            std::stringstream ss;
+            ss << aNewSize.Width() << ", " << aNewSize.Height();
+            OString sSize = ss.str().c_str();
+            aViewData.GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, sSize.getStr());
+
+            // New area extended to the bottom of the sheet after last row
+            // excluding overlapping area with aNewColArea
+            Rectangle aNewRowArea(0, aOldSize.getHeight(), aOldSize.getWidth(), aNewSize.getHeight());
+
+            // Only invalidate if spreadsheet extended to the bottom
+            if (aNewRowArea.getHeight())
+            {
+                SfxLokHelper::notifyInvalidation(aViewData.GetViewShell(), aNewRowArea.toString());
+            }
+        }
+    }
+
+
+    /// 3) create string data for rows
+
+    aBuffer.append("\"rows\": [\n");
+
     bool bFirstRow = true;
-    for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
+    if (nStartRow  == 0 && nStartRow != nEndRow)
+    {
+        aBuffer.append("{ \"text\": \"").append("0").append("\", ");
+        aBuffer.append("\"size\": \"").append(OUString::number(0)).append("\" }");
+        bFirstRow = false;
+    }
+
+    nTotalPixels = 0;
+    for (SCROW nRow = 0; nRow < nEndRow; ++nRow)
     {
         // nSize will be 0 for hidden rows.
         const sal_uInt16 nSize = pDoc->GetRowHeight(nRow, aViewData.GetTabNo());
-        const long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTY());
-        const OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow);
+        const long nSizePx = ScViewData::ToPixel(nSize, 1.0 / TWIPS_PER_PIXEL);
+        nTotalPixels += nSizePx;
+
+        if (nRow < nStartRow)
+            continue;
 
-        bool bSkip = false;
-        if (!rRectangle.IsEmpty())
+        OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow);
+
+        if (!bFirstRow)
+        {
+            aBuffer.append(", ");
+        }
+        else
         {
-            long nTop = std::max(rRectangle.Top(), nTotal);
-            long nBottom = std::min(rRectangle.Bottom(), nTotal + nSize);
-            if (nBottom < nTop)
-                // They do not intersect.
-                bSkip = true;
+            aText = OUString::number(nStartRow + 1);
         }
-        if (!bSkip)
+
+        aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
+        aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
+        bFirstRow = false;
+    }
+
+    aBuffer.append("]");
+    ///  end collecting ROWS
+
+
+    aBuffer.append(",\n");
+
+    /// *** start collecting COLS ***
+
+    /// 1) compute start and end columns
+
+    nTotalPixels = 0;
+    if (rRectangle.Left() < rRectangle.Right())
+    {
+        long nLeftBoundPx = rRectangle.Left() / TWIPS_PER_PIXEL;
+        long nRightBoundPx = rRectangle.Right() / TWIPS_PER_PIXEL;
+        nEndCol = MAXCOL;
+        for (SCCOL nCol = 0; nCol <= MAXCOL; ++nCol)
         {
-            if (!bFirstRow)
-                aBuffer.append(", ");
+            if (nTotalPixels > nRightBoundPx)
+            {
+                nEndCol = nCol;
+                break;
+            }
+
+            const sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo());
+            const long nSizePx = ScViewData::ToPixel(nSize, 1.0 / TWIPS_PER_PIXEL);
+            nTotalPixels += nSizePx;
+            if (nTotalPixels < nLeftBoundPx)
+            {
+                nStartCol = nCol;
+                continue;
+            }
+        }
+
+        nStartCol -= 1;
+        nEndCol += 2;
+
+        if (nStartCol < 0) nStartCol = 0;
+        if (nEndCol > MAXCOL) nEndCol = MAXCOL;
+    }
 
-            aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
-            aBuffer.append("\"size\": \"").append(OUString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY())).append("\" }");
-            bFirstRow = false;
+    aBuffer.ensureCapacity( aBuffer.getCapacity() + (50 * (nEndCol - nStartCol + 1)) );
+
+    long nVisibleCols = nEndCol - nStartCol;
+    if (nVisibleCols < 10)
+        nVisibleCols = 10;
+
+
+    /// 2) if we are approaching current max tiled column, signal a size changed event
+    ///    and invalidate the involved area
+
+    if (nEndCol > aViewData.GetMaxTiledCol() - nVisibleCols)
+    {
+        ScDocShell* pDocSh = aViewData.GetDocShell();
+        ScModelObj* pModelObj = pDocSh ? ScModelObj::getImplementation( pDocSh->GetModel() ) : nullptr;
+        Size aOldSize(0, 0);
+        if (pModelObj)
+            aOldSize = pModelObj->getDocumentSize();
+
+        aViewData.SetMaxTiledCol(std::min(std::max(nEndCol, aViewData.GetMaxTiledCol()) + nVisibleCols, (long)(MAXCOL)));
+
+        Size aNewSize(0, 0);
+        if (pModelObj)
+            aNewSize = pModelObj->getDocumentSize();
+
+        if (pDocSh)
+        {
+            // Provide size in the payload, so clients don't have to
+            // call lok::Document::getDocumentSize().
+            std::stringstream ss;
+            ss << aNewSize.Width() << ", " << aNewSize.Height();
+            OString sSize = ss.str().c_str();
+            aViewData.GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_DOCUMENT_SIZE_CHANGED, sSize.getStr());
+
+            // New area extended to the right of the sheet after last column
+            // including overlapping area with aNewRowArea
+            Rectangle aNewColArea(aOldSize.getWidth(), 0, aNewSize.getWidth(), aNewSize.getHeight());
+
+            // Only invalidate if spreadsheet extended to the bottom
+            if (aNewColArea.getWidth())
+            {
+                SfxLokHelper::notifyInvalidation(aViewData.GetViewShell(), aNewColArea.toString());
+            }
         }
-        nTotal += nSize;
-        nTotalPixels += nSizePixels;
     }
 
-    aBuffer.append("],\n\"columns\":\n[");
 
-    nTotal = 0;
+    /// 3) create string data for columns
+
+    aBuffer.append("\"columns\": [\n");
+
+    bool bFirstCol = true;
+    if (nStartCol  == 0 && nStartCol != nEndCol )
+    {
+        aBuffer.append("{ \"text\": \"").append("0").append("\", ");
+        aBuffer.append("\"size\": \"").append(OUString::number(0)).append("\" }");
+        bFirstCol = false;
+    }
+
     nTotalPixels = 0;
-    bFirstRow = true;
-    for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol)
+    for (SCCOL nCol = 0; nCol < nEndCol; ++nCol)
     {
+        // nSize will be 0 for hidden columns.
         const sal_uInt16 nSize = pDoc->GetColWidth(nCol, aViewData.GetTabNo());
-        const long nSizePixels = ScViewData::ToPixel(nSize, aViewData.GetPPTX());
-        const OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol);
+        const long nSizePx = ScViewData::ToPixel(nSize, 1.0 / TWIPS_PER_PIXEL);
+        nTotalPixels += nSizePx;
+
+        if (nCol < nStartCol)
+            continue;
 
-        bool bSkip = false;
-        if (!rRectangle.IsEmpty())
+        OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol);
+
+        if (!bFirstCol)
         {
-            long nLeft = std::max(rRectangle.Left(), nTotal);
-            long nRight = std::min(rRectangle.Right(), nTotal + nSize);
-            if (nRight < nLeft)
-                // They do not intersect.
-                bSkip = true;
+            aBuffer.append(", ");
         }
-        if (!bSkip)
+        else
         {
-            if (!bFirstRow)
-                aBuffer.append(", ");
-
-            aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
-            aBuffer.append("\"size\": \"").append(OUString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX())).append("\" }");
-            bFirstRow = false;
+            aText = OUString::number(nStartCol + 1);
         }
-        nTotal += nSize;
-        nTotalPixels += nSizePixels;
+
+        aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
+        aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
+        bFirstCol = false;
     }
 
-    aBuffer.append("]\n}");
-    return aBuffer.makeStringAndClear();
+    aBuffer.append("]");
+    ///  end collecting COLs
+
+    aBuffer.append("\n}");
+    OUString sRet = aBuffer.makeStringAndClear();
+
+    return sRet;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list