LOK - Calc: Increase the row limit to 10.000 rows.
Change-Id: Ie91e4caf33d3b31df4c3de8dc6e78e223dc1e4b3 Reviewed-on: https://gerrit.libreoffice.org/34216 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Marco Cecchetti <mrcekets@gmail.com>
This commit is contained in:
parent
1a1dbff33d
commit
eb399d69aa
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
SCROW nEndRow = 0;
|
||||
pDoc->GetTiledRenderingArea(aViewData.GetTabNo(), nEndCol, nEndRow);
|
||||
|
||||
rtl::OUStringBuffer aBuffer(256 + (50 * nEndRow) + (50 * nEndCol));
|
||||
if (rRectangle.IsEmpty())
|
||||
return OUString();
|
||||
|
||||
rtl::OUStringBuffer aBuffer(256);
|
||||
aBuffer.append("{ \"commandName\": \".uno:ViewRowColumnHeaders\",\n");
|
||||
|
||||
SCROW nStartRow = 0;
|
||||
SCROW nEndRow = 0;
|
||||
SCCOL nStartCol = 0;
|
||||
SCCOL nEndCol = 0;
|
||||
|
||||
/// *** start collecting ROWS ***
|
||||
|
||||
/// 1) compute start and end rows
|
||||
|
||||
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");
|
||||
|
||||
long nTotal = 0;
|
||||
long nTotalPixels = 0;
|
||||
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;
|
||||
|
||||
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 (!bFirstRow)
|
||||
aBuffer.append(", ");
|
||||
if (nRow < nStartRow)
|
||||
continue;
|
||||
|
||||
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
|
||||
aBuffer.append("\"size\": \"").append(OUString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTY())).append("\" }");
|
||||
bFirstRow = false;
|
||||
OUString aText = pRowBar[SC_SPLIT_BOTTOM]->GetEntryText(nRow);
|
||||
|
||||
if (!bFirstRow)
|
||||
{
|
||||
aBuffer.append(", ");
|
||||
}
|
||||
nTotal += nSize;
|
||||
nTotalPixels += nSizePixels;
|
||||
else
|
||||
{
|
||||
aText = OUString::number(nStartRow + 1);
|
||||
}
|
||||
|
||||
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
|
||||
aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
|
||||
bFirstRow = false;
|
||||
}
|
||||
|
||||
aBuffer.append("],\n\"columns\":\n[");
|
||||
aBuffer.append("]");
|
||||
/// end collecting ROWS
|
||||
|
||||
|
||||
aBuffer.append(",\n");
|
||||
|
||||
/// *** start collecting COLS ***
|
||||
|
||||
/// 1) compute start and end columns
|
||||
|
||||
nTotal = 0;
|
||||
nTotalPixels = 0;
|
||||
bFirstRow = true;
|
||||
for (SCCOL nCol = 0; nCol <= nEndCol; ++nCol)
|
||||
if (rRectangle.Left() < rRectangle.Right())
|
||||
{
|
||||
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);
|
||||
|
||||
bool bSkip = false;
|
||||
if (!rRectangle.IsEmpty())
|
||||
long nLeftBoundPx = rRectangle.Left() / TWIPS_PER_PIXEL;
|
||||
long nRightBoundPx = rRectangle.Right() / TWIPS_PER_PIXEL;
|
||||
nEndCol = MAXCOL;
|
||||
for (SCCOL nCol = 0; nCol <= MAXCOL; ++nCol)
|
||||
{
|
||||
long nLeft = std::max(rRectangle.Left(), nTotal);
|
||||
long nRight = std::min(rRectangle.Right(), nTotal + nSize);
|
||||
if (nRight < nLeft)
|
||||
// They do not intersect.
|
||||
bSkip = true;
|
||||
}
|
||||
if (!bSkip)
|
||||
{
|
||||
if (!bFirstRow)
|
||||
aBuffer.append(", ");
|
||||
if (nTotalPixels > nRightBoundPx)
|
||||
{
|
||||
nEndCol = nCol;
|
||||
break;
|
||||
}
|
||||
|
||||
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
|
||||
aBuffer.append("\"size\": \"").append(OUString::number((nTotalPixels + nSizePixels) / aViewData.GetPPTX())).append("\" }");
|
||||
bFirstRow = false;
|
||||
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;
|
||||
}
|
||||
}
|
||||
nTotal += nSize;
|
||||
nTotalPixels += nSizePixels;
|
||||
|
||||
nStartCol -= 1;
|
||||
nEndCol += 2;
|
||||
|
||||
if (nStartCol < 0) nStartCol = 0;
|
||||
if (nEndCol > MAXCOL) nEndCol = MAXCOL;
|
||||
}
|
||||
|
||||
aBuffer.append("]\n}");
|
||||
return aBuffer.makeStringAndClear();
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// 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;
|
||||
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 nSizePx = ScViewData::ToPixel(nSize, 1.0 / TWIPS_PER_PIXEL);
|
||||
nTotalPixels += nSizePx;
|
||||
|
||||
if (nCol < nStartCol)
|
||||
continue;
|
||||
|
||||
OUString aText = pColBar[SC_SPLIT_LEFT]->GetEntryText(nCol);
|
||||
|
||||
if (!bFirstCol)
|
||||
{
|
||||
aBuffer.append(", ");
|
||||
}
|
||||
else
|
||||
{
|
||||
aText = OUString::number(nStartCol + 1);
|
||||
}
|
||||
|
||||
aBuffer.append("{ \"text\": \"").append(aText).append("\", ");
|
||||
aBuffer.append("\"size\": \"").append(OUString::number(nTotalPixels * TWIPS_PER_PIXEL)).append("\" }");
|
||||
bFirstCol = false;
|
||||
}
|
||||
|
||||
aBuffer.append("]");
|
||||
/// end collecting COLs
|
||||
|
||||
aBuffer.append("\n}");
|
||||
OUString sRet = aBuffer.makeStringAndClear();
|
||||
|
||||
return sRet;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
Loading…
x
Reference in New Issue
Block a user