diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-12-14 12:05:55 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2019-12-14 13:34:41 +0100 |
commit | f6064b13586aa8681907b69e4f43643251f9b803 (patch) | |
tree | 3aad0584727cf24503213d12c2a25029961d79c6 | |
parent | 9c90c5e4740763d116d1354d1e4315d338a92140 (diff) |
sc: rowcol: convert mark data
with this patch I can finally load a 3201 column document
Change-Id: I880d485b3f628836e7aed92c276e660466a3b19c
Reviewed-on: https://gerrit.libreoffice.org/85139
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | compilerplugins/clang/refcounting.cxx | 3 | ||||
-rw-r--r-- | sc/inc/address.hxx | 14 | ||||
-rw-r--r-- | sc/inc/document.hxx | 22 | ||||
-rw-r--r-- | sc/inc/markmulti.hxx | 9 | ||||
-rw-r--r-- | sc/inc/sheetlimits.hxx | 66 | ||||
-rw-r--r-- | sc/qa/unit/mark_test.cxx | 3 | ||||
-rw-r--r-- | sc/source/core/data/documen2.cxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/markdata.cxx | 8 | ||||
-rw-r--r-- | sc/source/core/data/markmulti.cxx | 41 |
9 files changed, 113 insertions, 55 deletions
diff --git a/compilerplugins/clang/refcounting.cxx b/compilerplugins/clang/refcounting.cxx index 168d775b28d2..531039d74cdc 100644 --- a/compilerplugins/clang/refcounting.cxx +++ b/compilerplugins/clang/refcounting.cxx @@ -252,6 +252,9 @@ bool containsSalhelperReferenceObjectSubclass(const clang::Type* pType0) { pRecordDecl = pRecordDecl->getCanonicalDecl(); } if (pRecordDecl) { + // for performance reasons we sometimes allocate temporaries on the stack + if (loplugin::DeclCheck(pRecordDecl).Struct("ScSheetLimits").GlobalNamespace()) + return false; const ClassTemplateSpecializationDecl* pTemplate = dyn_cast<ClassTemplateSpecializationDecl>(pRecordDecl); if (pTemplate) { auto const dc = loplugin::DeclCheck(pTemplate); diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx index 2109d582f67b..79af2eab6ca8 100644 --- a/sc/inc/address.hxx +++ b/sc/inc/address.hxx @@ -70,6 +70,8 @@ const SCROW MAXROW = MAXROWCOUNT - 1; const SCCOL MAXCOL = MAXCOLCOUNT - 1; const SCTAB MAXTAB = MAXTABCOUNT - 1; const SCCOLROW MAXCOLROW = MAXROW; +const SCROW MAXROW_JUMBO = 16 * 1000 * 1000; +const SCCOL MAXCOL_JUMBO = 16384; // Maximum tiled rendering values const SCROW MAXTILEDROW = 500000; // Limit the initial tab count to prevent users to set the count too high, @@ -90,13 +92,13 @@ const SCROW MAXROW_30 = 8191; [[nodiscard]] inline bool ValidCol( SCCOL nCol, SCCOL nMaxCol ) { - assert(nMaxCol == MAXCOL); // temporary to debug jumbo sheets work + assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work return nCol >= 0 && nCol <= nMaxCol; } [[nodiscard]] inline bool ValidRow( SCROW nRow, SCROW nMaxRow) { - assert(nMaxRow == MAXROW); // temporary to debug jumbo sheets work + assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work return nRow >= 0 && nRow <= nMaxRow; } @@ -112,25 +114,25 @@ const SCROW MAXROW_30 = 8191; [[nodiscard]] inline bool ValidColRow( SCCOL nCol, SCROW nRow, SCCOL nMaxCol, SCROW nMaxRow ) { - assert(nMaxRow == MAXROW); // temporary to debug jumbo sheets work + assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow); } [[nodiscard]] inline bool ValidColRowTab( SCCOL nCol, SCROW nRow, SCTAB nTab, SCCOL nMaxCol, SCROW nMaxRow ) { - assert(nMaxRow == MAXROW); // temporary to debug jumbo sheets work + assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work return ValidCol(nCol,nMaxCol) && ValidRow(nRow,nMaxRow) && ValidTab( nTab); } [[nodiscard]] inline SCCOL SanitizeCol( SCCOL nCol, SCCOL nMaxCol ) { - assert(nMaxCol == MAXCOL); // temporary to debug jumbo sheets work + assert(nMaxCol == MAXCOL || nMaxCol == MAXCOL_JUMBO); // temporary to debug jumbo sheets work return nCol < 0 ? 0 : (nCol > nMaxCol ? nMaxCol : nCol); } [[nodiscard]] inline SCROW SanitizeRow( SCROW nRow, SCROW nMaxRow ) { - assert(nMaxRow == MAXROW); // temporary to debug jumbo sheets work + assert(nMaxRow == MAXROW || nMaxRow == MAXROW_JUMBO); // temporary to debug jumbo sheets work return nRow < 0 ? 0 : (nRow > nMaxRow ? nMaxRow : nRow); } diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 94c9b2820c17..5355300047d4 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -20,7 +20,6 @@ #ifndef INCLUDED_SC_INC_DOCUMENT_HXX #define INCLUDED_SC_INC_DOCUMENT_HXX -#include <salhelper/simplereferenceobject.hxx> #include <vcl/idle.hxx> #include <vcl/errcode.hxx> #include <com/sun/star/uno/Reference.hxx> @@ -37,6 +36,7 @@ #include "typedstrdata.hxx" #include "calcmacros.hxx" #include "calcconfig.hxx" +#include "sheetlimits.hxx" #include <o3tl/deleter.hxx> #include <o3tl/sorted_vector.hxx> #include <svl/hint.hxx> @@ -198,6 +198,7 @@ class BitmapEx; class ScColumnsRange; struct ScFilterEntries; typedef o3tl::sorted_vector<sal_uInt32> ScCondFormatIndexes; +struct ScSheetLimits; namespace sc { @@ -281,25 +282,6 @@ const sal_uInt8 SC_DDE_ENGLISH = 1; const sal_uInt8 SC_DDE_TEXT = 2; const sal_uInt8 SC_DDE_IGNOREMODE = 255; /// For usage in FindDdeLink() only! -// Because some stuff needs this info, and those objects lifetimes sometimes exceeds the lifetime -// of the ScDocument. -struct ScSheetLimits : public salhelper::SimpleReferenceObject -{ - const SCCOL mnMaxCol; /// Maximum addressable column - const SCROW mnMaxRow; /// Maximum addressable row - - ScSheetLimits(SCCOL nMaxCol, SCROW nMaxRow) : mnMaxCol(nMaxCol), mnMaxRow(nMaxRow) {} - - [[nodiscard]] bool ValidCol(SCCOL nCol) const { return ::ValidCol(nCol, mnMaxCol); } - [[nodiscard]] bool ValidRow(SCROW nRow) const { return ::ValidRow(nRow, mnMaxRow); } - [[nodiscard]] bool ValidColRow(SCCOL nCol, SCROW nRow) const { return ::ValidColRow(nCol, nRow, mnMaxCol, mnMaxRow); } - [[nodiscard]] bool ValidColRowTab(SCCOL nCol, SCROW nRow, SCTAB nTab) const { return ::ValidColRowTab(nCol, nRow, nTab, mnMaxCol, mnMaxRow); } - [[nodiscard]] bool ValidRange(const ScRange& rRange) const { return ::ValidRange(rRange, mnMaxCol, mnMaxRow); } - [[nodiscard]] bool ValidAddress(const ScAddress& rAddress) const { return ::ValidAddress(rAddress, mnMaxCol, mnMaxRow); } - [[nodiscard]] SCCOL SanitizeCol( SCCOL nCol ) const { return ::SanitizeCol(nCol, mnMaxCol); } - [[nodiscard]] SCROW SanitizeRow( SCROW nRow ) const { return ::SanitizeRow(nRow, mnMaxRow); } -}; - // During threaded calculation fields being mutated are kept in this struct struct ScDocumentThreadSpecific { diff --git a/sc/inc/markmulti.hxx b/sc/inc/markmulti.hxx index ac43e73cbdd5..d74634088bf3 100644 --- a/sc/inc/markmulti.hxx +++ b/sc/inc/markmulti.hxx @@ -26,6 +26,7 @@ #include <vector> class ScRangeList; +struct ScSheetLimits; class ScMultiSel { @@ -54,16 +55,16 @@ public: bool IsAllMarked( SCCOL nCol, SCROW nStartRow, SCROW nEndRow ) const; bool HasEqualRowsMarked( SCCOL nCol1, SCCOL nCol2 ) const; SCROW GetNextMarked( SCCOL nCol, SCROW nRow, bool bUp ) const; - void SetMarkArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow, bool bMark ); - void Set( ScRangeList const & ); + void SetMarkArea( const ScSheetLimits& rLimits, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow, bool bMark ); + void Set( const ScSheetLimits& rLimits, ScRangeList const & ); bool IsRowMarked( SCROW nRow ) const; bool IsRowRangeMarked( SCROW nStartRow, SCROW nEndRow ) const; bool IsEmpty() const { return ( aMultiSelContainer.empty() && !aRowSel.HasMarks() ); } ScMarkArray GetMarkArray( SCCOL nCol ) const; void Clear(); - void MarkAllCols( SCROW nStartRow, SCROW nEndRow ); + void MarkAllCols( const ScSheetLimits& rLimits, SCROW nStartRow, SCROW nEndRow ); bool HasAnyMarks() const; - void ShiftCols(SCCOL nStartCol, long nColOffset); + void ShiftCols(const ScSheetLimits& rLimits, SCCOL nStartCol, long nColOffset); void ShiftRows(SCROW nStartRow, long nRowOffset); // For faster access from within ScMarkData, instead of creating diff --git a/sc/inc/sheetlimits.hxx b/sc/inc/sheetlimits.hxx new file mode 100644 index 000000000000..ad9541983a5b --- /dev/null +++ b/sc/inc/sheetlimits.hxx @@ -0,0 +1,66 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_SC_INC_SHEETLIMITS_HXX +#define INCLUDED_SC_INC_SHEETLIMITS_HXX + +#include <salhelper/simplereferenceobject.hxx> + +// Because some stuff needs this info, and those objects lifetimes sometimes exceeds the lifetime +// of the ScDocument. +struct ScSheetLimits : public salhelper::SimpleReferenceObject +{ + const SCCOL mnMaxCol; /// Maximum addressable column + const SCROW mnMaxRow; /// Maximum addressable row + + ScSheetLimits(SCCOL nMaxCol, SCROW nMaxRow) + : mnMaxCol(nMaxCol) + , mnMaxRow(nMaxRow){} + + [[nodiscard]] bool ValidCol(SCCOL nCol) const + { + return ::ValidCol(nCol, mnMaxCol); + } + [[nodiscard]] bool ValidRow(SCROW nRow) const { return ::ValidRow(nRow, mnMaxRow); } + [[nodiscard]] bool ValidColRow(SCCOL nCol, SCROW nRow) const + { + return ::ValidColRow(nCol, nRow, mnMaxCol, mnMaxRow); + } + [[nodiscard]] bool ValidColRowTab(SCCOL nCol, SCROW nRow, SCTAB nTab) const + { + return ::ValidColRowTab(nCol, nRow, nTab, mnMaxCol, mnMaxRow); + } + [[nodiscard]] bool ValidRange(const ScRange& rRange) const + { + return ::ValidRange(rRange, mnMaxCol, mnMaxRow); + } + [[nodiscard]] bool ValidAddress(const ScAddress& rAddress) const + { + return ::ValidAddress(rAddress, mnMaxCol, mnMaxRow); + } + [[nodiscard]] SCCOL SanitizeCol(SCCOL nCol) const { return ::SanitizeCol(nCol, mnMaxCol); } + [[nodiscard]] SCROW SanitizeRow(SCROW nRow) const { return ::SanitizeRow(nRow, mnMaxRow); } + + // equivalent of MAXROWCOUNT in address.hxx + SCROW GetMaxRowCount() const { return mnMaxRow + 1; } +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/qa/unit/mark_test.cxx b/sc/qa/unit/mark_test.cxx index 8177d4444170..b362b6164aec 100644 --- a/sc/qa/unit/mark_test.cxx +++ b/sc/qa/unit/mark_test.cxx @@ -260,7 +260,8 @@ void Test::testMultiMark( const MultiMarkTestData& rMarksData ) for ( const auto& rAreaTestData : rMarksData.aMarks ) { - aMultiSel.SetMarkArea( rAreaTestData.aRange.aStart.Col(), rAreaTestData.aRange.aEnd.Col(), + aMultiSel.SetMarkArea( ScSheetLimits(MAXCOL, MAXROW), + rAreaTestData.aRange.aStart.Col(), rAreaTestData.aRange.aEnd.Col(), rAreaTestData.aRange.aStart.Row(), rAreaTestData.aRange.aEnd.Row(), rAreaTestData.bMark ); aMark.SetMultiMarkArea( rAreaTestData.aRange, rAreaTestData.bMark ); diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index af09ab3f21c7..c87dab365084 100644 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -172,7 +172,7 @@ ScDocument::ScDocument( ScDocumentMode eMode, SfxObjectShell* pDocShell ) : const ScDefaultsOptions& rOpt = SC_MOD()->GetDefaultsOptions(); if (rOpt.GetInitJumboSheets()) { - mxSheetLimits = new ScSheetLimits(16384, 16 * 1000 * 1000); + mxSheetLimits = new ScSheetLimits(MAXCOL_JUMBO, MAXROW_JUMBO); } maPreviewSelection = { MaxRow(), MaxCol() }; aCurTextWidthCalcPos = { MaxCol(), 0, 0 }; diff --git a/sc/source/core/data/markdata.cxx b/sc/source/core/data/markdata.cxx index b698183ac0a0..3d730065dd2f 100644 --- a/sc/source/core/data/markdata.cxx +++ b/sc/source/core/data/markdata.cxx @@ -23,6 +23,8 @@ #include <markmulti.hxx> #include <rangelst.hxx> #include <segmenttree.hxx> +#include <sheetlimits.hxx> +#include <document.hxx> #include <columnspanset.hxx> #include <fstalgorithm.hxx> #include <unordered_map> @@ -104,7 +106,7 @@ void ScMarkData::SetMultiMarkArea( const ScRange& rRange, bool bMark, bool bSetu PutInOrder( nStartRow, nEndRow ); PutInOrder( nStartCol, nEndCol ); - aMultiSel.SetMarkArea( nStartCol, nEndCol, nStartRow, nEndRow, bMark ); + aMultiSel.SetMarkArea( ScSheetLimits(mnMaxCol, mnMaxRow), nStartCol, nEndCol, nStartRow, nEndRow, bMark ); if ( bMultiMarked ) // Update aMultiRange { @@ -336,7 +338,7 @@ ScMarkData::ScMarkData(SCROW nMaxRow, SCCOL nMaxCol, const ScRangeList& rList) bMultiMarked = true; aMultiRange = rList.Combine(); - aMultiSel.Set( rList ); + aMultiSel.Set( ScSheetLimits(mnMaxCol, mnMaxRow), rList ); } @@ -612,7 +614,7 @@ void ScMarkData::ShiftCols(const ScDocument* pDoc, SCCOL nStartCol, long nColOff } else if (bMultiMarked) { - aMultiSel.ShiftCols(nStartCol, nColOffset); + aMultiSel.ShiftCols(pDoc->GetSheetLimits(), nStartCol, nColOffset); aMultiRange.IncColIfNotLessThan(pDoc, nStartCol, nColOffset); } } diff --git a/sc/source/core/data/markmulti.cxx b/sc/source/core/data/markmulti.cxx index 1c8c38cc3584..b98872aaf0ec 100644 --- a/sc/source/core/data/markmulti.cxx +++ b/sc/source/core/data/markmulti.cxx @@ -21,6 +21,7 @@ #include <markarr.hxx> #include <rangelst.hxx> #include <segmenttree.hxx> +#include <sheetlimits.hxx> #include <sal/log.hxx> #include <o3tl/sorted_vector.hxx> @@ -162,18 +163,18 @@ SCROW ScMultiSel::GetNextMarked( SCCOL nCol, SCROW nRow, bool bUp ) const return ( bUp ? nRow2 : nRow1 ); } -void ScMultiSel::MarkAllCols( SCROW nStartRow, SCROW nEndRow ) +void ScMultiSel::MarkAllCols( const ScSheetLimits& rLimits, SCROW nStartRow, SCROW nEndRow ) { - aMultiSelContainer.resize(MAXCOL+1, ScMarkArray(mnMaxRow)); - for ( SCCOL nCol = MAXCOL; nCol >= 0; --nCol ) + aMultiSelContainer.resize(rLimits.mnMaxCol+1, ScMarkArray(mnMaxRow)); + for ( SCCOL nCol = rLimits.mnMaxCol; nCol >= 0; --nCol ) { aMultiSelContainer[nCol].SetMarkArea( nStartRow, nEndRow, true ); } } -void ScMultiSel::SetMarkArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow, bool bMark ) +void ScMultiSel::SetMarkArea( const ScSheetLimits& rLimits, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow, bool bMark ) { - if ( nStartCol == 0 && nEndCol == MAXCOL ) + if ( nStartCol == 0 && nEndCol == rLimits.mnMaxCol ) { aRowSel.SetMarkArea( nStartRow, nEndRow, bMark ); if ( !bMark ) @@ -199,23 +200,23 @@ void ScMultiSel::SetMarkArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, S else { nBeg = aRowSel.GetNextMarked( nStartRow, false ); - if ( nBeg != MAXROWCOUNT ) + if ( nBeg != rLimits.GetMaxRowCount() ) nLast = aRowSel.GetMarkEnd( nBeg, false ); } - if ( nBeg != MAXROWCOUNT && nLast >= nEndRow ) - MarkAllCols( nBeg, nEndRow ); + if ( nBeg != rLimits.GetMaxRowCount() && nLast >= nEndRow ) + MarkAllCols( rLimits, nBeg, nEndRow ); else { - while ( nBeg != MAXROWCOUNT && nLast < nEndRow ) + while ( nBeg != rLimits.GetMaxRowCount() && nLast < nEndRow ) { - MarkAllCols( nBeg, nLast ); + MarkAllCols( rLimits, nBeg, nLast ); nBeg = aRowSel.GetNextMarked( nLast + 1, false ); - if ( nBeg != MAXROWCOUNT ) + if ( nBeg != rLimits.GetMaxRowCount() ) nLast = aRowSel.GetMarkEnd( nBeg, false ); } - if ( nBeg != MAXROWCOUNT && nLast >= nEndRow ) - MarkAllCols( nBeg, nEndRow ); + if ( nBeg != rLimits.GetMaxRowCount() && nLast >= nEndRow ) + MarkAllCols( rLimits, nBeg, nEndRow ); } aRowSel.SetMarkArea( nStartRow, nEndRow, false ); @@ -231,7 +232,7 @@ void ScMultiSel::SetMarkArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, S optimised init-from-range-list. Specifically this is optimised for cases where we have very large data columns with lots and lots of ranges. */ -void ScMultiSel::Set( ScRangeList const & rList ) +void ScMultiSel::Set( const ScSheetLimits& rLimits, ScRangeList const & rList ) { Clear(); if (rList.size() == 0) @@ -245,7 +246,7 @@ void ScMultiSel::Set( ScRangeList const & rList ) return lhs.aStart.Row() < rhs.aStart.Row(); }); - std::vector<std::vector<ScMarkEntry>> aMarkEntriesPerCol(MAXCOL+1); + std::vector<std::vector<ScMarkEntry>> aMarkEntriesPerCol(rLimits.mnMaxCol+1); SCCOL nMaxCol = -1; int i = 0; @@ -257,7 +258,7 @@ void ScMultiSel::Set( ScRangeList const & rList ) SCROW nEndRow = rRange.aEnd.Row(); assert( nEndRow >= nStartRow && "this method assumes the input data has ranges with endrow>=startrow"); assert( nEndCol >= nStartCol && "this method assumes the input data has ranges with endcol>=startcol"); - if ( nStartCol == 0 && nEndCol == MAXCOL ) + if ( nStartCol == 0 && nEndCol == rLimits.mnMaxCol ) aRowSel.SetMarkArea( nStartRow, nEndRow, /*bMark*/true ); else { @@ -326,9 +327,9 @@ bool ScMultiSel::HasAnyMarks() const return false; } -void ScMultiSel::ShiftCols(SCCOL nStartCol, long nColOffset) +void ScMultiSel::ShiftCols(const ScSheetLimits& rLimits, SCCOL nStartCol, long nColOffset) { - if (nStartCol > MAXCOL) + if (nStartCol > rLimits.mnMaxCol) return; ScMultiSel aNewMultiSel(*this); @@ -351,8 +352,8 @@ void ScMultiSel::ShiftCols(SCCOL nStartCol, long nColOffset) nDestCol += nColOffset; if (nDestCol < 0) nDestCol = 0; - else if (nDestCol > MAXCOL) - nDestCol = MAXCOL; + else if (nDestCol > rLimits.mnMaxCol) + nDestCol = rLimits.mnMaxCol; } if (nDestCol >= static_cast<SCCOL>(aMultiSelContainer.size())) aMultiSelContainer.resize(nDestCol, ScMarkArray(mnMaxRow)); |