diff options
author | Luboš Luňák <l.lunak@collabora.com> | 2022-03-10 15:03:25 +0100 |
---|---|---|
committer | Luboš Luňák <l.lunak@collabora.com> | 2022-03-11 10:09:03 +0100 |
commit | dddee125cc32f1ad5228e598a7de04e9654e65c1 (patch) | |
tree | 19c35052c83886c8807fa6d7d45d333b2e57eeac | |
parent | 69b5f0b6579c6574a8fe68ab2a64208ec767db55 (diff) |
load ods/xlsx with full row attributes without allocating all columns
If there's e.g. an entire row bold, it's enough to set default
attribute for unallocated columns.
This also reverts the workaround from commit 297ab561c6754, as it's
no longer necessary.
Change-Id: I0b208709aeaff1c0d59da2410926876715cfe642
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/131320
Tested-by: Jenkins
Reviewed-by: Luboš Luňák <l.lunak@collabora.com>
-rw-r--r-- | compilerplugins/clang/redundantfcast.cxx | 3 | ||||
-rw-r--r-- | sc/inc/attarray.hxx | 4 | ||||
-rw-r--r-- | sc/inc/column.hxx | 7 | ||||
-rw-r--r-- | sc/inc/documentimport.hxx | 9 | ||||
-rw-r--r-- | sc/inc/table.hxx | 1 | ||||
-rw-r--r-- | sc/qa/unit/subsequent_export_test2.cxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/documentimport.cxx | 17 | ||||
-rw-r--r-- | sc/source/core/data/table2.cxx | 31 | ||||
-rw-r--r-- | sc/source/filter/excel/xistyle.cxx | 17 | ||||
-rw-r--r-- | sc/source/filter/oox/sheetdatabuffer.cxx | 16 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlcoli.cxx | 1 |
11 files changed, 93 insertions, 17 deletions
diff --git a/compilerplugins/clang/redundantfcast.cxx b/compilerplugins/clang/redundantfcast.cxx index ac768caf276e..be9565c9fbe8 100644 --- a/compilerplugins/clang/redundantfcast.cxx +++ b/compilerplugins/clang/redundantfcast.cxx @@ -329,7 +329,8 @@ public: if (fn == SRCDIR "/bridges/source/jni_uno/jni_bridge.cxx") return false; // TODO constructing a temporary to pass to a && param - if (fn == SRCDIR "/sc/source/ui/view/viewfunc.cxx") + if (fn == SRCDIR "/sc/source/ui/view/viewfunc.cxx" + || fn == SRCDIR "/sc/source/core/data/table2.cxx") return false; // tdf#145203: FIREBIRD cannot create a table if (fn == SRCDIR "/connectivity/source/drivers/firebird/DatabaseMetaData.cxx") diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index c08da494c142..8153b441ffe6 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -82,6 +82,10 @@ struct ScAttrEntry { SCROW nEndRow; const ScPatternAttr* pPattern; + bool operator==( const ScAttrEntry& other ) const + { + return nEndRow == other.nEndRow && pPattern == other.pPattern; + } }; class ScAttrArray diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 2cf4bdd66573..b6fde6801a2f 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -140,6 +140,8 @@ public: return static_cast<const T&>(GetAttr(nRow, sal_uInt16(nWhich), nStartRow, nEndRow)); } + void SetAttrEntries(std::vector<ScAttrEntry> && vNewData); + const ScPatternAttr* GetPattern( SCROW nRow ) const; const ScPatternAttr* GetMostUsedPattern( SCROW nStartRow, SCROW nEndRow ) const; SCROW ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray, bool* const pIsChanged, @@ -1009,4 +1011,9 @@ inline void ScColumn::SetPatternArea( SCROW nStartRow, SCROW nEndRow, pAttrArray->SetPatternArea( nStartRow, nEndRow, &rPatAttr, true/*bPutToPool*/ ); } +inline void ScColumnData::SetAttrEntries(std::vector<ScAttrEntry> && vNewData) +{ + pAttrArray->SetAttrEntries( std::move( vNewData )); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/documentimport.hxx b/sc/inc/documentimport.hxx index a80053b6ff80..2ffc75d67b82 100644 --- a/sc/inc/documentimport.hxx +++ b/sc/inc/documentimport.hxx @@ -53,6 +53,11 @@ public: ~Attrs(); Attrs& operator=( Attrs const & ) = delete; // MSVC2015 workaround Attrs( Attrs const & ) = delete; // MSVC2015 workaround + bool operator==(const Attrs& other) const + { + return mvData == other.mvData && mbLatinNumFmtOnly == other.mbLatinNumFmtOnly; + } + Attrs& operator=( Attrs&& attrs ) = default; }; ScDocumentImport() = delete; @@ -115,11 +120,11 @@ public: void fillDownCells(const ScAddress& rPos, SCROW nFillSize); /** - * Set an array of cell attributes to specified column. This call + * Set an array of cell attributes to specified range of columns. This call * transfers the ownership of the ScAttrEntry array from the caller to the * column. */ - void setAttrEntries( SCTAB nTab, SCCOL nCol, Attrs&& rAttrs ); + void setAttrEntries( SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, Attrs&& rAttrs ); void setRowsVisible(SCTAB nTab, SCROW nRowStart, SCROW nRowEnd, bool bVisible); diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index e7d91a5cad97..532f6cf10124 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -736,6 +736,7 @@ public: void ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScPatternAttr& rAttr, ScEditDataArray* pDataArray = nullptr, bool* const pIsChanged = nullptr ); + void SetAttrEntries( SCCOL nStartCol, SCCOL nEndCol, std::vector<ScAttrEntry> && vNewData); void SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr ); const ScPatternAttr* SetPattern( SCCOL nCol, SCROW nRow, std::unique_ptr<ScPatternAttr> ); diff --git a/sc/qa/unit/subsequent_export_test2.cxx b/sc/qa/unit/subsequent_export_test2.cxx index 9db733b8f5d1..0ed29cae605c 100644 --- a/sc/qa/unit/subsequent_export_test2.cxx +++ b/sc/qa/unit/subsequent_export_test2.cxx @@ -3082,7 +3082,7 @@ void ScExportTest2::testWholeRowBold() ScDocShellRef xDocSh2 = saveAndReload(*xDocSh1, FORMAT_ODS); CPPUNIT_ASSERT(xDocSh2.is()); pDoc = &xDocSh2->GetDocument(); - // TODO CPPUNIT_ASSERT_EQUAL(SCCOL(INITIALCOLCOUNT), pDoc->GetAllocatedColumnsCount(0)); + CPPUNIT_ASSERT_EQUAL(SCCOL(INITIALCOLCOUNT), pDoc->GetAllocatedColumnsCount(0)); vcl::Font aFont; pDoc->GetPattern(pDoc->MaxCol(), 1, 0)->GetFont(aFont, SC_AUTOCOL_RAW); CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight()); @@ -3090,7 +3090,7 @@ void ScExportTest2::testWholeRowBold() ScDocShellRef xDocSh3 = saveAndReload(*xDocSh2, FORMAT_XLSX); CPPUNIT_ASSERT(xDocSh3.is()); pDoc = &xDocSh3->GetDocument(); - // TODO CPPUNIT_ASSERT_EQUAL(SCCOL(INITIALCOLCOUNT), pDoc->GetAllocatedColumnsCount(0)); + CPPUNIT_ASSERT_EQUAL(SCCOL(INITIALCOLCOUNT), pDoc->GetAllocatedColumnsCount(0)); pDoc->GetPattern(pDoc->MaxCol(), 1, 0)->GetFont(aFont, SC_AUTOCOL_RAW); CPPUNIT_ASSERT_EQUAL_MESSAGE("font should be bold", WEIGHT_BOLD, aFont.GetWeight()); diff --git a/sc/source/core/data/documentimport.cxx b/sc/source/core/data/documentimport.cxx index d47d50a4cb35..87a14416925b 100644 --- a/sc/source/core/data/documentimport.cxx +++ b/sc/source/core/data/documentimport.cxx @@ -593,21 +593,20 @@ void ScDocumentImport::fillDownCells(const ScAddress& rPos, SCROW nFillSize) } } -void ScDocumentImport::setAttrEntries( SCTAB nTab, SCCOL nCol, Attrs&& rAttrs ) +void ScDocumentImport::setAttrEntries( SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, Attrs&& rAttrs ) { ScTable* pTab = mpImpl->mrDoc.FetchTable(nTab); if (!pTab) return; - ScColumn* pCol = pTab->FetchColumn(nCol); - if (!pCol) - return; - - ColAttr* pColAttr = mpImpl->getColAttr(nTab, nCol); - if (pColAttr) - pColAttr->mbLatinNumFmtOnly = rAttrs.mbLatinNumFmtOnly; + for(SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol ) + { + ColAttr* pColAttr = mpImpl->getColAttr(nTab, nCol); + if (pColAttr) + pColAttr->mbLatinNumFmtOnly = rAttrs.mbLatinNumFmtOnly; + } - pCol->pAttrArray->SetAttrEntries(std::move(rAttrs.mvData)); + pTab->SetAttrEntries( nColStart, nColEnd, std::move( rAttrs.mvData )); } void ScDocumentImport::setRowsVisible(SCTAB nTab, SCROW nRowStart, SCROW nRowEnd, bool bVisible) diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index fa7a73ad3d00..59444b7bb61e 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2816,6 +2816,37 @@ void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, CreateColumnIfNotExists(i).ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray, pIsChanged); } +void ScTable::SetAttrEntries( SCCOL nStartCol, SCCOL nEndCol, std::vector<ScAttrEntry> && vNewData) +{ + if (!ValidCol(nStartCol) || !ValidCol(nEndCol)) + return; + if ( nEndCol == rDocument.MaxCol() ) + { + if ( nStartCol < aCol.size() ) + { + // If we would like set all columns to same attrs, then change only attrs for not existing columns + nEndCol = aCol.size() - 1; + for (SCCOL i = nStartCol; i <= nEndCol; i++) + aCol[i].SetAttrEntries( std::vector<ScAttrEntry>(vNewData)); + aDefaultColData.SetAttrEntries(std::move(vNewData)); + } + else + { + CreateColumnIfNotExists( nStartCol - 1 ); + aDefaultColData.SetAttrEntries(std::move(vNewData)); + } + } + else + { + CreateColumnIfNotExists( nEndCol ); + for (SCCOL i = nStartCol; i < nEndCol; i++) // all but last need a copy + aCol[i].SetAttrEntries( std::vector<ScAttrEntry>(vNewData)); + aCol[nEndCol].SetAttrEntries( std::move(vNewData)); + } +} + + + void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange& rRange, const ScPatternAttr& rPattern, SvNumFormatType nNewType ) { diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx index 4161d47a94df..c556b51ec602 100644 --- a/sc/source/filter/excel/xistyle.cxx +++ b/sc/source/filter/excel/xistyle.cxx @@ -1989,6 +1989,9 @@ void XclImpXFRangeBuffer::Finalize() // apply patterns XclImpXFBuffer& rXFBuffer = GetXFBuffer(); + ScDocumentImport::Attrs aPendingAttrParam; + SCCOL pendingColStart = -1; + SCCOL pendingColEnd = -1; SCCOL nScCol = 0; for( const auto& rxColumn : maColumns ) { @@ -2026,10 +2029,22 @@ void XclImpXFRangeBuffer::Finalize() ScDocumentImport::Attrs aAttrParam; aAttrParam.mvData.swap(aAttrs); aAttrParam.mbLatinNumFmtOnly = false; // when unsure, set it to false. - rDocImport.setAttrEntries(nScTab, nScCol, std::move(aAttrParam)); + + // Compress setting the attributes, set the same set in one call. + if( pendingColStart != -1 && pendingColEnd == nScCol - 1 && aAttrParam == aPendingAttrParam ) + ++pendingColEnd; + else + { + if( pendingColStart != -1 ) + rDocImport.setAttrEntries(nScTab, pendingColStart, pendingColEnd, std::move(aPendingAttrParam)); + pendingColStart = pendingColEnd = nScCol; + aPendingAttrParam = std::move( aAttrParam ); + } } ++nScCol; } + if( pendingColStart != -1 ) + rDocImport.setAttrEntries(nScTab, pendingColStart, pendingColEnd, std::move(aPendingAttrParam)); // insert hyperlink cells for( const auto& [rXclRange, rUrl] : maHyperlinks ) diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index b4d6158f66fe..6dbec9e6bd9d 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -482,6 +482,9 @@ void SheetDataBuffer::finalizeImport() ScDocument& rDoc = rDocImport.getDoc(); StylesBuffer& rStyles = getStyles(); + ScDocumentImport::Attrs aPendingAttrParam; + SCCOL pendingColStart = -1; + SCCOL pendingColEnd = -1; for ( const auto& [rCol, rRowStyles] : maStylesPerColumn ) { SCCOL nScCol = static_cast< SCCOL >( rCol ); @@ -529,8 +532,19 @@ void SheetDataBuffer::finalizeImport() aAttrParam.mvData.swap(aAttrs.maAttrs); aAttrParam.mbLatinNumFmtOnly = aAttrs.mbLatinNumFmtOnly; - rDocImport.setAttrEntries(getSheetIndex(), nScCol, std::move(aAttrParam)); + // Compress setting the attributes, set the same set in one call. + if( pendingColStart != -1 && pendingColEnd == nScCol - 1 && aAttrParam == aPendingAttrParam ) + ++pendingColEnd; + else + { + if( pendingColStart != -1 ) + rDocImport.setAttrEntries(getSheetIndex(), pendingColStart, pendingColEnd, std::move(aPendingAttrParam)); + pendingColStart = pendingColEnd = nScCol; + aPendingAttrParam = std::move( aAttrParam ); + } } + if( pendingColStart != -1 ) + rDocImport.setAttrEntries(getSheetIndex(), pendingColStart, pendingColEnd, std::move(aPendingAttrParam)); // merge all cached merged ranges and update right/bottom cell borders for( const auto& rMergedRange : maMergedRanges ) diff --git a/sc/source/filter/xml/xmlcoli.cxx b/sc/source/filter/xml/xmlcoli.cxx index 00514f830305..502690fe2f03 100644 --- a/sc/source/filter/xml/xmlcoli.cxx +++ b/sc/source/filter/xml/xmlcoli.cxx @@ -93,7 +93,6 @@ void SAL_CALL ScXMLTableColContext::endFastElement( sal_Int32 /*nElement*/ ) nLastColumn = pDoc->MaxCol(); if (nCurrentColumn > pDoc->MaxCol()) nCurrentColumn = pDoc->MaxCol(); - pDoc->CreateColumnIfNotExists(nSheet, nLastColumn); uno::Reference<table::XColumnRowRange> xColumnRowRange (xSheet->getCellRangeByPosition(nCurrentColumn, 0, nLastColumn, 0), uno::UNO_QUERY); if (xColumnRowRange.is()) { |