[Libreoffice-commits] core.git: Branch 'private/kohei/xlsx-import-speedup' - 3 commits - sc/qa sc/source
Kohei Yoshida
kohei.yoshida at collabora.com
Mon Nov 4 19:56:27 CET 2013
dev/null |binary
sc/qa/unit/data/xls/data-table/mortgage.xls |binary
sc/qa/unit/data/xlsx/data-table/multi-table.xlsx |binary
sc/qa/unit/data/xlsx/data-table/one-variable.xlsx |binary
sc/qa/unit/subsequent_filters-test.cxx | 95 ++++++++++++++++
sc/source/filter/inc/sheetdatabuffer.hxx | 5
sc/source/filter/oox/sheetdatabuffer.cxx | 124 +++++++++++-----------
7 files changed, 160 insertions(+), 64 deletions(-)
New commits:
commit 380d36f32a6980c770c52e30d54a153a447549bf
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Nov 4 13:57:34 2013 -0500
Two new test cases for importing data tables from XLSX.
Change-Id: I87da806612ae50fe1d64b851c5180ff1792752cb
diff --git a/sc/qa/unit/data/xlsx/data-table/multi-table.xlsx b/sc/qa/unit/data/xlsx/data-table/multi-table.xlsx
new file mode 100644
index 0000000..c2bf488
Binary files /dev/null and b/sc/qa/unit/data/xlsx/data-table/multi-table.xlsx differ
diff --git a/sc/qa/unit/data/xlsx/data-table/one-variable.xlsx b/sc/qa/unit/data/xlsx/data-table/one-variable.xlsx
new file mode 100644
index 0000000..7ff098b2
Binary files /dev/null and b/sc/qa/unit/data/xlsx/data-table/one-variable.xlsx differ
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 2361f9f..6662dcd 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -108,6 +108,8 @@ public:
void testRepeatedColumnsODS();
void testDataValidityODS();
void testDataTableMortgageXLS();
+ void testDataTableOneVarXLSX();
+ void testDataTableMultiTableXLSX();
void testDataBarODS();
void testDataBarXLSX();
@@ -171,6 +173,8 @@ public:
CPPUNIT_TEST(testRepeatedColumnsODS);
CPPUNIT_TEST(testDataValidityODS);
CPPUNIT_TEST(testDataTableMortgageXLS);
+ CPPUNIT_TEST(testDataTableOneVarXLSX);
+ CPPUNIT_TEST(testDataTableMultiTableXLSX);
CPPUNIT_TEST(testBrokenQuotesCSV);
CPPUNIT_TEST(testCellValueXLSX);
CPPUNIT_TEST(testControlImport);
@@ -1073,6 +1077,8 @@ void ScFiltersTest::testDataValidityODS()
void ScFiltersTest::testDataTableMortgageXLS()
{
ScDocShellRef xDocSh = loadDoc("data-table/mortgage.", XLS);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
+
ScFormulaOptions aOptions;
aOptions.SetFormulaSepArg(",");
aOptions.SetFormulaSepArrayCol(",");
@@ -1121,6 +1127,87 @@ void ScFiltersTest::testDataTableMortgageXLS()
xDocSh->DoClose();
}
+void ScFiltersTest::testDataTableOneVarXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("data-table/one-variable.", XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
+
+ ScFormulaOptions aOptions;
+ aOptions.SetFormulaSepArg(",");
+ aOptions.SetFormulaSepArrayCol(",");
+ aOptions.SetFormulaSepArrayRow(";");
+ xDocSh->SetFormulaOptions(aOptions);
+
+ ScDocument* pDoc = xDocSh->GetDocument();
+
+ // Right now, we have a bug that prevents Calc from re-calculating these
+ // cells automatically upon file load. We can remove this call if/when we
+ // fix the aforementioned bug.
+ pDoc->CalcAll();
+
+ // B5:B11 should have multiple operations formula cells. Just check the
+ // top and bottom cells.
+
+ if (!checkFormula(*pDoc, ScAddress(1,4,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A5)"))
+ CPPUNIT_FAIL("Wrong formula!");
+
+ CPPUNIT_ASSERT_EQUAL(2.0, pDoc->GetValue(ScAddress(1,4,0)));
+
+ if (!checkFormula(*pDoc, ScAddress(1,10,0), "MULTIPLE.OPERATIONS(B$4,$A$2,$A11)"))
+ CPPUNIT_FAIL("Wrong formula!");
+
+ CPPUNIT_ASSERT_EQUAL(14.0, pDoc->GetValue(ScAddress(1,10,0)));
+
+ // Likewise, E5:I5 should have multiple operations formula cells. Just
+ // check the left- and right-most cells.
+
+ if (!checkFormula(*pDoc, ScAddress(4,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,E$4)"))
+ CPPUNIT_FAIL("Wrong formula!");
+
+ CPPUNIT_ASSERT_EQUAL(10.0, pDoc->GetValue(ScAddress(4,4,0)));
+
+ if (!checkFormula(*pDoc, ScAddress(8,4,0), "MULTIPLE.OPERATIONS($D5,$B$2,I$4)"))
+ CPPUNIT_FAIL("Wrong formula!");
+
+ CPPUNIT_ASSERT_EQUAL(50.0, pDoc->GetValue(ScAddress(8,4,0)));
+
+ xDocSh->DoClose();
+}
+
+void ScFiltersTest::testDataTableMultiTableXLSX()
+{
+ ScDocShellRef xDocSh = loadDoc("data-table/multi-table.", XLSX);
+ CPPUNIT_ASSERT_MESSAGE("Failed to load the document.", xDocSh.Is());
+
+ ScFormulaOptions aOptions;
+ aOptions.SetFormulaSepArg(",");
+ aOptions.SetFormulaSepArrayCol(",");
+ aOptions.SetFormulaSepArrayRow(";");
+ xDocSh->SetFormulaOptions(aOptions);
+
+ ScDocument* pDoc = xDocSh->GetDocument();
+
+ // Right now, we have a bug that prevents Calc from re-calculating these
+ // cells automatically upon file load. We can remove this call if/when we
+ // fix the aforementioned bug.
+ pDoc->CalcAll();
+
+ // B4:M15 should have multiple operations formula cells. We'll just check
+ // the top-left and bottom-right ones.
+
+ if (!checkFormula(*pDoc, ScAddress(1,3,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A4,$D$1,B$3)"))
+ CPPUNIT_FAIL("Wrong formula!");
+
+ CPPUNIT_ASSERT_EQUAL(1.0, pDoc->GetValue(ScAddress(1,3,0)));
+
+ if (!checkFormula(*pDoc, ScAddress(12,14,0), "MULTIPLE.OPERATIONS($A$3,$E$1,$A15,$D$1,M$3)"))
+ CPPUNIT_FAIL("Wrong formula!");
+
+ CPPUNIT_ASSERT_EQUAL(144.0, pDoc->GetValue(ScAddress(12,14,0)));
+
+ xDocSh->DoClose();
+}
+
void ScFiltersTest::testBrokenQuotesCSV()
{
const OUString aFileNameBase("fdo48621_broken_quotes.");
commit ed39603f8eb27fc5d03eab00dbc4ed175d0ff9d6
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Nov 4 13:27:44 2013 -0500
Create data-table directory and move the test file into it.
Change-Id: I1007525a7d2e1135f0388975f9cb7b0cef9b3142
diff --git a/sc/qa/unit/data/xls/data-table-mortgage.xls b/sc/qa/unit/data/xls/data-table/mortgage.xls
similarity index 100%
rename from sc/qa/unit/data/xls/data-table-mortgage.xls
rename to sc/qa/unit/data/xls/data-table/mortgage.xls
diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx
index 4083993..2361f9f 100644
--- a/sc/qa/unit/subsequent_filters-test.cxx
+++ b/sc/qa/unit/subsequent_filters-test.cxx
@@ -107,7 +107,7 @@ public:
void testMergedCellsODS();
void testRepeatedColumnsODS();
void testDataValidityODS();
- void testDataTableXLS();
+ void testDataTableMortgageXLS();
void testDataBarODS();
void testDataBarXLSX();
@@ -170,7 +170,7 @@ public:
CPPUNIT_TEST(testMergedCellsODS);
CPPUNIT_TEST(testRepeatedColumnsODS);
CPPUNIT_TEST(testDataValidityODS);
- CPPUNIT_TEST(testDataTableXLS);
+ CPPUNIT_TEST(testDataTableMortgageXLS);
CPPUNIT_TEST(testBrokenQuotesCSV);
CPPUNIT_TEST(testCellValueXLSX);
CPPUNIT_TEST(testControlImport);
@@ -1070,9 +1070,9 @@ void ScFiltersTest::testDataValidityODS()
xDocSh->DoClose();
}
-void ScFiltersTest::testDataTableXLS()
+void ScFiltersTest::testDataTableMortgageXLS()
{
- ScDocShellRef xDocSh = loadDoc("data-table-mortgage.", XLS);
+ ScDocShellRef xDocSh = loadDoc("data-table/mortgage.", XLS);
ScFormulaOptions aOptions;
aOptions.SetFormulaSepArg(",");
aOptions.SetFormulaSepArrayCol(",");
commit d81441dc3b235a5fd0366ef6ad0d3e6885ff70b0
Author: Kohei Yoshida <kohei.yoshida at collabora.com>
Date: Mon Nov 4 11:50:18 2013 -0500
Import data tables from xlsx via ScDocumentImport.
Change-Id: Id3d526720f99b7557476915beab35b429ec97c1d
diff --git a/sc/source/filter/inc/sheetdatabuffer.hxx b/sc/source/filter/inc/sheetdatabuffer.hxx
index 192f359..ceb3a80 100644
--- a/sc/source/filter/inc/sheetdatabuffer.hxx
+++ b/sc/source/filter/inc/sheetdatabuffer.hxx
@@ -176,9 +176,8 @@ private:
const ::com::sun::star::table::CellRangeAddress& rRange,
const ApiTokenSequence& rTokens ) const;
/** Inserts the passed table operation into the sheet. */
- void finalizeTableOperation(
- const ::com::sun::star::table::CellRangeAddress& rRange,
- const DataTableModel& rModel ) const;
+ void finalizeTableOperation(
+ const ::com::sun::star::table::CellRangeAddress& rRange, const DataTableModel& rModel );
/** Writes all cell formatting attributes to the passed cell range list. (depreciates writeXfIdRangeProperties) */
void applyCellMerging( const ::com::sun::star::table::CellRangeAddress& rRange );
diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx
index 7f9c8e4..ebc7dca 100644
--- a/sc/source/filter/oox/sheetdatabuffer.cxx
+++ b/sc/source/filter/oox/sheetdatabuffer.cxx
@@ -50,6 +50,8 @@
#include "document.hxx"
#include "scitems.hxx"
#include "formulacell.hxx"
+#include "paramisc.hxx"
+#include "documentimport.hxx"
namespace oox {
namespace xls {
@@ -563,71 +565,79 @@ void SheetDataBuffer::finalizeArrayFormula( const CellRangeAddress& rRange, cons
xTokens->setArrayTokens( rTokens );
}
-void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel ) const
+void SheetDataBuffer::finalizeTableOperation( const CellRangeAddress& rRange, const DataTableModel& rModel )
{
+ if (rModel.mbRef1Deleted)
+ return;
+
+ if (rModel.maRef1.isEmpty())
+ return;
+
+ if (rRange.StartColumn <= 0 || rRange.StartRow <= 0)
+ return;
+
sal_Int16 nSheet = getSheetIndex();
- bool bOk = false;
- if( !rModel.mbRef1Deleted && !rModel.maRef1.isEmpty() && (rRange.StartColumn > 0) && (rRange.StartRow > 0) )
+
+ CellAddress aRef1;
+ if (!getAddressConverter().convertToCellAddress(aRef1, rModel.maRef1, nSheet, true))
+ return;
+
+ ScDocumentImport& rDoc = getDocImport();
+ ScTabOpParam aParam;
+
+ ScRange aScRange;
+ ScUnoConversion::FillScRange(aScRange, rRange);
+
+ if (rModel.mb2dTable)
{
- CellRangeAddress aOpRange = rRange;
- CellAddress aRef1;
- if( getAddressConverter().convertToCellAddress( aRef1, rModel.maRef1, nSheet, true ) ) try
- {
- if( rModel.mb2dTable )
- {
- CellAddress aRef2;
- if( !rModel.mbRef2Deleted && getAddressConverter().convertToCellAddress( aRef2, rModel.maRef2, nSheet, true ) )
- {
- // API call expects input values inside operation range
- --aOpRange.StartColumn;
- --aOpRange.StartRow;
- // formula range is top-left cell of operation range
- CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow, aOpRange.StartColumn, aOpRange.StartRow );
- // set multiple operation
- Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW );
- xMultOp->setTableOperation( aFormulaRange, TableOperationMode_BOTH, aRef2, aRef1 );
- bOk = true;
- }
- }
- else if( rModel.mbRowTable )
- {
- // formula range is column to the left of operation range
- CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn - 1, aOpRange.StartRow, aOpRange.StartColumn - 1, aOpRange.EndRow );
- // API call expects input values (top row) inside operation range
- --aOpRange.StartRow;
- // set multiple operation
- Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW );
- xMultOp->setTableOperation( aFormulaRange, TableOperationMode_ROW, aRef1, aRef1 );
- bOk = true;
- }
- else
- {
- // formula range is row above operation range
- CellRangeAddress aFormulaRange( nSheet, aOpRange.StartColumn, aOpRange.StartRow - 1, aOpRange.EndColumn, aOpRange.StartRow - 1 );
- // API call expects input values (left column) inside operation range
- --aOpRange.StartColumn;
- // set multiple operation
- Reference< XMultipleOperation > xMultOp( getCellRange( aOpRange ), UNO_QUERY_THROW );
- xMultOp->setTableOperation( aFormulaRange, TableOperationMode_COLUMN, aRef1, aRef1 );
- bOk = true;
- }
- }
- catch( Exception& )
- {
- }
+ // Two-variable data table.
+ if (rModel.mbRef2Deleted)
+ return;
+
+ if (rModel.maRef2.isEmpty())
+ return;
+
+ CellAddress aRef2;
+ if (!getAddressConverter().convertToCellAddress(aRef2, rModel.maRef2, nSheet, true))
+ return;
+
+ aParam.meMode = ScTabOpParam::Both;
+
+ aParam.aRefFormulaCell.Set(rRange.StartColumn-1, rRange.StartRow-1, nSheet, false, false, false);
+ aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+
+ aScRange.aStart.IncRow(-1);
+ aScRange.aStart.IncCol(-1);
+
+ // Ref1 is row input cell and Ref2 is column input cell.
+ aParam.aRefRowCell.Set(aRef1.Column, aRef1.Row, aRef1.Sheet, false, false, false);
+ aParam.aRefColCell.Set(aRef2.Column, aRef2.Row, aRef2.Sheet, false, false, false);
+ rDoc.setTableOpCells(aScRange, aParam);
+
+ return;
}
- // on error: fill cell range with #REF! error codes
- if( !bOk ) try
+ // One-variable data table.
+
+ if (rModel.mbRowTable)
{
- Reference< XCellRangeData > xCellRangeData( getCellRange( rRange ), UNO_QUERY_THROW );
- size_t nWidth = static_cast< size_t >( rRange.EndColumn - rRange.StartColumn + 1 );
- size_t nHeight = static_cast< size_t >( rRange.EndRow - rRange.StartRow + 1 );
- Matrix< Any > aErrorCells( nWidth, nHeight, Any( getFormulaParser().convertErrorToFormula( BIFF_ERR_REF ) ) );
- xCellRangeData->setDataArray( ContainerHelper::matrixToSequenceSequence( aErrorCells ) );
+ // One-variable row input cell (horizontal).
+ aParam.meMode = ScTabOpParam::Row;
+ aParam.aRefRowCell.Set(aRef1.Column, aRef1.Row, aRef1.Sheet, false, false, false);
+ aParam.aRefFormulaCell.Set(rRange.StartColumn-1, rRange.StartRow, nSheet, false, true, false);
+ aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+ aScRange.aStart.IncRow(-1);
+ rDoc.setTableOpCells(aScRange, aParam);
}
- catch( Exception& )
+ else
{
+ // One-variable column input cell (vertical).
+ aParam.meMode = ScTabOpParam::Column;
+ aParam.aRefColCell.Set(aRef1.Column, aRef1.Row, aRef1.Sheet, false, false, false);
+ aParam.aRefFormulaCell.Set(rRange.StartColumn, rRange.StartRow-1, nSheet, true, false, false);
+ aParam.aRefFormulaEnd = aParam.aRefFormulaCell;
+ aScRange.aStart.IncCol(-1);
+ rDoc.setTableOpCells(aScRange, aParam);
}
}
More information about the Libreoffice-commits
mailing list