desktop/qa/desktop_lib/test_desktop_lib.cxx |   76 +++++--
 sc/inc/address.hxx                          |    2 
 sc/source/ui/view/tabview.cxx               |  290 +++++++++++++++++++++++-----
 3 files changed, 300 insertions(+), 68 deletions(-)

New commits:
commit eb399d69aa5ad0c04affb830a522c5c1f130813f
Author: Marco Cecchetti <marco.cecche...@collabora.com>
Date:   Wed Nov 30 14:13:15 2016 +0100

    LOK - Calc: Increase the row limit to 10.000 rows.
    
    Change-Id: Ie91e4caf33d3b31df4c3de8dc6e78e223dc1e4b3
    Reviewed-on: https://gerrit.libreoffice.org/34216
    Tested-by: Jenkins <c...@libreoffice.org>
    Reviewed-by: Marco Cecchetti <mrcek...@gmail.com>

diff --git a/desktop/qa/desktop_lib/test_desktop_lib.cxx 
b/desktop/qa/desktop_lib/test_desktop_lib.cxx
index 5ea5632..0574fec 100644
--- a/desktop/qa/desktop_lib/test_desktop_lib.cxx
+++ b/desktop/qa/desktop_lib/test_desktop_lib.cxx
@@ -592,46 +592,79 @@ void DesktopLOKTest::testRowColumnHeaders()
 
     pDocument->pClass->initializeForRendering(pDocument, nullptr);
 
+    long nWidth = 0;
+    long nHeight = 0;
+    pDocument->m_pDocumentClass->getDocumentSize(pDocument, &nWidth, &nHeight);
+    long nX = rtl::math::round(nWidth / 4.0);
+    long nY = rtl::math::round(nHeight / 4.0);
+    nWidth = rtl::math::round(nWidth / 2.0);
+    nHeight = rtl::math::round(nHeight / 2.0);
+
+    std::stringstream aPayload;
+    aPayload << ".uno:ViewRowColumnHeaders?x=" << nX << "&y=" << nY << 
"&width=" << nWidth << "&height=" << nHeight;
+
     boost::property_tree::ptree aTree;
-    char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, 
".uno:ViewRowColumnHeaders");
+    char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, 
aPayload.str().c_str());
     std::stringstream aStream(pJSON);
     free(pJSON);
+
     CPPUNIT_ASSERT(!aStream.str().empty());
 
     boost::property_tree::read_json(aStream, aTree);
     sal_Int32 nPrevious = 0;
+    bool bFirstHeader = true;
+    bool bNotEnoughHeaders = true;
     for (boost::property_tree::ptree::value_type& rValue : 
aTree.get_child("rows"))
     {
         sal_Int32 nSize = 
OString(rValue.second.get<std::string>("size").c_str()).toInt32();
-        CPPUNIT_ASSERT(nSize > 0);
         OString aText(rValue.second.get<std::string>("text").c_str());
-        if (!nPrevious)
-            // This failed, as the first item did not contain the text of the 
first row.
-            CPPUNIT_ASSERT_EQUAL(OString("1"), aText);
+
+        if (bFirstHeader)
+        {
+            CPPUNIT_ASSERT(nSize <= nY);
+            CPPUNIT_ASSERT_EQUAL(OString("11"), aText);
+            bFirstHeader = false;
+        }
         else
         {
-            // Make sure that size is absolute: the first two items have the 
same relative size.
+            CPPUNIT_ASSERT(nSize > 0);
             CPPUNIT_ASSERT(nPrevious < nSize);
-            break;
+            if (nSize > nY + nHeight)
+            {
+                bNotEnoughHeaders = false;
+                break;
+            }
         }
         nPrevious = nSize;
     }
+    CPPUNIT_ASSERT(!bNotEnoughHeaders);
 
     nPrevious = 0;
+    bFirstHeader = true;
+    bNotEnoughHeaders = true;
     for (boost::property_tree::ptree::value_type& rValue : 
aTree.get_child("columns"))
     {
         sal_Int32 nSize = 
OString(rValue.second.get<std::string>("size").c_str()).toInt32();
-        CPPUNIT_ASSERT(nSize > 0);
         OString aText(rValue.second.get<std::string>("text").c_str());
-        if (!nPrevious)
-            CPPUNIT_ASSERT_EQUAL(OString("A"), aText);
+        if (bFirstHeader)
+        {
+            CPPUNIT_ASSERT(nSize <= nX);
+            CPPUNIT_ASSERT_EQUAL(OString("4"), aText);
+            bFirstHeader = false;
+        }
         else
         {
+            CPPUNIT_ASSERT(nSize > 0);
             CPPUNIT_ASSERT(nPrevious < nSize);
-            break;
+            if (nSize > nX + nWidth)
+            {
+                bNotEnoughHeaders = false;
+                break;
+            }
         }
         nPrevious = nSize;
     }
+    CPPUNIT_ASSERT(!bNotEnoughHeaders);
 }
 
 void DesktopLOKTest::testHiddenRowHeaders()
@@ -640,29 +673,34 @@ void DesktopLOKTest::testHiddenRowHeaders()
 
     pDocument->pClass->initializeForRendering(pDocument, nullptr);
 
+    long nX = 0;
+    long nY = 0;
+    long nWidth = 0;
+    long nHeight = 0;
+    pDocument->m_pDocumentClass->getDocumentSize(pDocument, &nWidth, &nHeight);
+
+    std::stringstream aPayload;
+    aPayload << ".uno:ViewRowColumnHeaders?x=" << nX << "&y=" << nY << 
"&width=" << nWidth << "&height=" << nHeight;
+
     boost::property_tree::ptree aTree;
-    char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, 
".uno:ViewRowColumnHeaders");
+    char* pJSON = pDocument->m_pDocumentClass->getCommandValues(pDocument, 
aPayload.str().c_str());
     std::stringstream aStream(pJSON);
     free(pJSON);
     CPPUNIT_ASSERT(!aStream.str().empty());
 
     boost::property_tree::read_json(aStream, aTree);
     sal_Int32 nPrevious = 0;
-    bool bFirst = true;
+    sal_Int32 nIndex = 0;
     for (boost::property_tree::ptree::value_type& rValue : 
aTree.get_child("rows"))
     {
         sal_Int32 nSize = 
OString(rValue.second.get<std::string>("size").c_str()).toInt32();
-        CPPUNIT_ASSERT(nSize > 0);
 
-        if (bFirst)
-            bFirst = false;
-        else
+        if (nIndex++ == 2)
         {
-            // nSize was 509, nPrevious was 254, i.e. hidden row wasn't 
reported as 0 height.
+            // nSize was 510, nPrevious was 255, i.e. hidden row wasn't 
reported as 0 height.
             CPPUNIT_ASSERT_EQUAL(nPrevious, nSize);
             break;
         }
-
         nPrevious = nSize;
     }
 }
diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index dc1e066..c3f5888 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: */
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to