[Libreoffice-commits] core.git: desktop/qa sc/inc sc/source
Marco Cecchetti
marco.cecchetti at collabora.com
Mon Feb 13 20:08:04 UTC 2017
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.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: Ie91e4caf33d3b31df4c3de8dc6e78e223dc1e4b3
Reviewed-on: https://gerrit.libreoffice.org/34216
Tested-by: Jenkins <ci at libreoffice.org>
Reviewed-by: Marco Cecchetti <mrcekets at 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: */
More information about the Libreoffice-commits
mailing list