Blob Blame History Raw
From b9bafd8ec0d8725350c4f00bcb9e60d2b06b976c Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.co.uk>
Date: Tue, 3 Nov 2015 15:05:37 +0100
Subject: [PATCH 266/398] sc lok: allow requesting row headers only for a logic
 area

So that for large documents it's not needed to query all of them on
load, but (similar to tiled rendering itself) it's possible to query the
data that affects the visible area.

One catch is that the row sizes are relative, so there is a placeholder
row in case the visible area is not the top left corner, and
constructing its size needs special care. Normally the handed out twip
values have to be floored after twip->px conversion, but this one is
already rounded (as the total is a sum of px values, again becase of the
previous floor rule), so need to play the +0.5 trick to allow clients
always just flooring the logic conversion result they get.

Change-Id: I64a155582acdee7b2acc741d77a2c462409b91a8
(cherry picked from commit 75303695eb4bfe6c8fdea2cad0d3ed3f912f95c9)
---
 desktop/source/lib/init.cxx                        | 45 +++++++++++++++++++++-
 include/vcl/ITiledRenderable.hxx                   |  5 ++-
 .../qa/gtktiledviewer/gtktiledviewer.cxx           | 12 +++++-
 sc/inc/docuno.hxx                                  |  2 +-
 sc/source/ui/inc/tabview.hxx                       |  2 +-
 sc/source/ui/unoobj/docuno.cxx                     |  4 +-
 sc/source/ui/view/tabview.cxx                      | 36 ++++++++++++++---
 7 files changed, 92 insertions(+), 14 deletions(-)

diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 9ba26c414d8c..b9aeedd5e21c 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -1204,6 +1204,9 @@ static char* getStyles(LibreOfficeKitDocument* pThis, const char* pCommand)
 
 static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCommand)
 {
+    OString aCommand(pCommand);
+    static const OString aViewRowColumnHeaders(".uno:ViewRowColumnHeaders");
+
     if (!strcmp(pCommand, ".uno:CharFontName"))
     {
         return getFonts(pCommand);
@@ -1212,7 +1215,7 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
     {
         return getStyles(pThis, pCommand);
     }
-    else if (OString(pCommand) == ".uno:ViewRowColumnHeaders")
+    else if (aCommand.startsWith(aViewRowColumnHeaders))
     {
         ITiledRenderable* pDoc = getTiledRenderable(pThis);
         if (!pDoc)
@@ -1221,7 +1224,45 @@ static char* doc_getCommandValues(LibreOfficeKitDocument* pThis, const char* pCo
             return 0;
         }
 
-        OUString aHeaders = pDoc->getRowColumnHeaders();
+        Rectangle aRectangle;
+        if (aCommand.getLength() > aViewRowColumnHeaders.getLength())
+        {
+            // Command has parameters.
+            int nX = 0;
+            int nY = 0;
+            int nWidth = 0;
+            int nHeight = 0;
+            OString aArguments = aCommand.copy(aViewRowColumnHeaders.getLength() + 1);
+            sal_Int32 nParamIndex = 0;
+            do
+            {
+                OString aParamToken = aArguments.getToken(0, '&', nParamIndex);
+                sal_Int32 nIndex = 0;
+                OString aKey;
+                OString aValue;
+                do
+                {
+                    OString aToken = aParamToken.getToken(0, '=', nIndex);
+                    if (!aKey.getLength())
+                        aKey = aToken;
+                    else
+                        aValue = aToken;
+                }
+                while (nIndex >= 0);
+                if (aKey == "x")
+                    nX = aValue.toInt32();
+                else if (aKey == "y")
+                    nY = aValue.toInt32();
+                else if (aKey == "width")
+                    nWidth = aValue.toInt32();
+                else if (aKey == "height")
+                    nHeight = aValue.toInt32();
+            }
+            while (nParamIndex >= 0);
+            aRectangle = Rectangle(nX, nY, nX + nWidth, nY + nHeight);
+        }
+
+        OUString aHeaders = pDoc->getRowColumnHeaders(aRectangle);
         OString aString = OUStringToOString(aHeaders, RTL_TEXTENCODING_UTF8);
         char* pMemory = static_cast<char*>(malloc(aString.getLength() + 1));
         strcpy(pMemory, aString.getStr());
diff --git a/include/vcl/ITiledRenderable.hxx b/include/vcl/ITiledRenderable.hxx
index 48a13ffc1275..efa9bc272b40 100644
--- a/include/vcl/ITiledRenderable.hxx
+++ b/include/vcl/ITiledRenderable.hxx
@@ -150,8 +150,11 @@ public:
 
     /**
      * Get position and content of row/column headers of Calc documents.
+     *
+     * @param rRectangle - if not empty, then limit the output only to the area of this rectangle
+     * @return a JSON describing position/content of rows/columns
      */
-    virtual OUString getRowColumnHeaders()
+    virtual OUString getRowColumnHeaders(const Rectangle& /*rRectangle*/)
     {
         return OUString();
     }
diff --git a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
index 96a69fcf64f8..953eeb0f1db2 100644
--- a/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
+++ b/libreofficekit/qa/gtktiledviewer/gtktiledviewer.cxx
@@ -256,8 +256,16 @@ gboolean TiledRowColumnBar::docConfigureEvent(GtkWidget* pDocView, GdkEventConfi
     LibreOfficeKitDocument* pDocument = lok_doc_view_get_document(LOK_DOC_VIEW(pDocView));
     if (pDocument && pDocument->pClass->getDocumentType(pDocument) == LOK_DOCTYPE_SPREADSHEET)
     {
-        g_info("lok::Document::getCommandValues(.uno:ViewRowColumnHeaders)");
-        char* pValues = pDocument->pClass->getCommandValues(pDocument, ".uno:ViewRowColumnHeaders");
+        std::stringstream aCommand;
+        aCommand << ".uno:ViewRowColumnHeaders";
+        aCommand << "?x=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pColumnBar->m_nPositionPixel));
+        aCommand << "&width=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pColumnBar->m_nSizePixel));
+        aCommand << "&y=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pRowBar->m_nPositionPixel));
+        aCommand << "&height=" << int(lok_doc_view_pixel_to_twip(LOK_DOC_VIEW(pDocView), rWindow.m_pRowBar->m_nSizePixel));
+        std::stringstream ss;
+        ss << "lok::Document::getCommandValues(" << aCommand.str() << ")";
+        g_info(ss.str().c_str());
+        char* pValues = pDocument->pClass->getCommandValues(pDocument, aCommand.str().c_str());
         std::stringstream aStream(pValues);
         free(pValues);
         assert(!aStream.str().empty());
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index b4711c54c883..828fc1af7ea0 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -423,7 +423,7 @@ public:
     virtual bool isMimeTypeSupported() override;
 
     /// @see vcl::ITiledRenderable::getRowColumnHeaders().
-    virtual OUString getRowColumnHeaders() override;
+    virtual OUString getRowColumnHeaders(const Rectangle& rRectangle) override;
 };
 
 class ScDrawPagesObj : public cppu::WeakImplHelper2<
diff --git a/sc/source/ui/inc/tabview.hxx b/sc/source/ui/inc/tabview.hxx
index 5b0852041108..548742c6c22b 100644
--- a/sc/source/ui/inc/tabview.hxx
+++ b/sc/source/ui/inc/tabview.hxx
@@ -521,7 +521,7 @@ public:
     void ResetAutoSpell();
     void SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<editeng::MisspellRanges>* pRanges );
     /// @see ScModelObj::getRowColumnHeaders().
-    OUString getRowColumnHeaders();
+    OUString getRowColumnHeaders(const Rectangle& rRectangle);
 };
 
 #endif
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index 267798d4e949..1316fd73d328 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -873,7 +873,7 @@ bool ScModelObj::isMimeTypeSupported()
     return EditEngine::HasValidData(aDataHelper.GetTransferable());
 }
 
-OUString ScModelObj::getRowColumnHeaders()
+OUString ScModelObj::getRowColumnHeaders(const Rectangle& rRectangle)
 {
     ScViewData* pViewData = ScDocShell::GetViewData();
     if (!pViewData)
@@ -883,7 +883,7 @@ OUString ScModelObj::getRowColumnHeaders()
     if (!pTabView)
         return OUString();
 
-    return pTabView->getRowColumnHeaders();
+    return pTabView->getRowColumnHeaders(rRectangle);
 }
 
 void ScModelObj::initializeForTiledRendering()
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 2d886bca6003..1cb869cbd432 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -2303,7 +2303,7 @@ void ScTabView::SetAutoSpellData( SCCOL nPosX, SCROW nPosY, const std::vector<ed
     }
 }
 
-OUString ScTabView::getRowColumnHeaders()
+OUString ScTabView::getRowColumnHeaders(const Rectangle& rRectangle)
 {
     ScDocument* pDoc = aViewData.GetDocument();
     if (!pDoc)
@@ -2314,14 +2314,40 @@ OUString ScTabView::getRowColumnHeaders()
     pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow);
 
     boost::property_tree::ptree aRows;
+    long nTotal = 0;
+    long nTotalPixels = 0;
     for (SCROW nRow = 0; nRow <= nEndRow; ++nRow)
     {
-        boost::property_tree::ptree aRow;
         sal_uInt16 nSize = pDoc->GetOriginalHeight(nRow, aViewData.GetTabNo());
-        aRow.put("size", OString::number(nSize).getStr());
         OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow);
-        aRow.put("text", aText.toUtf8().getStr());
-        aRows.push_back(std::make_pair("", aRow));
+
+        bool bSkip = false;
+        if (!rRectangle.IsEmpty())
+        {
+            long nTop = std::max(rRectangle.Top(), nTotal);
+            long nBottom = std::min(rRectangle.Bottom(), nTotal + nSize);
+            if (nBottom < nTop)
+                // They do not intersect.
+                bSkip = true;
+        }
+        if (!bSkip)
+        {
+            if (aRows.empty())
+            {
+                // The sizes are relative sizes, so include the total skipped size before the real items.
+                boost::property_tree::ptree aRow;
+                // Client is required to floor(), rather than round() the sizes in general, so add 0.5 here to have rounding.
+                aRow.put("size", OString::number(long((nTotalPixels + 0.5) / aViewData.GetPPTY())).getStr());
+                aRow.put("text", "");
+                aRows.push_back(std::make_pair("", aRow));
+            }
+            boost::property_tree::ptree aRow;
+            aRow.put("size", OString::number(nSize).getStr());
+            aRow.put("text", aText.toUtf8().getStr());
+            aRows.push_back(std::make_pair("", aRow));
+        }
+        nTotal += nSize;
+        nTotalPixels += long(nSize * aViewData.GetPPTY());
     }
 
     boost::property_tree::ptree aCols;
-- 
2.12.0