summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuboš Luňák <l.lunak@collabora.com>2022-03-10 15:03:25 +0100
committerLuboš Luňák <l.lunak@collabora.com>2022-03-11 10:09:03 +0100
commitdddee125cc32f1ad5228e598a7de04e9654e65c1 (patch)
tree19c35052c83886c8807fa6d7d45d333b2e57eeac
parent69b5f0b6579c6574a8fe68ab2a64208ec767db55 (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.cxx3
-rw-r--r--sc/inc/attarray.hxx4
-rw-r--r--sc/inc/column.hxx7
-rw-r--r--sc/inc/documentimport.hxx9
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/qa/unit/subsequent_export_test2.cxx4
-rw-r--r--sc/source/core/data/documentimport.cxx17
-rw-r--r--sc/source/core/data/table2.cxx31
-rw-r--r--sc/source/filter/excel/xistyle.cxx17
-rw-r--r--sc/source/filter/oox/sheetdatabuffer.cxx16
-rw-r--r--sc/source/filter/xml/xmlcoli.cxx1
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())
{