diff options
author | Daniel Bankston <daniel.e.bankston@gmail.com> | 2012-05-24 06:05:15 -0500 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2012-06-01 19:40:08 +0200 |
commit | 119b7085ee77c7bd033059332766e66cdcc81fec (patch) | |
tree | ce553c3ec4d50e131c82cb84477854173fd59cc2 /sc | |
parent | 656802c91a278d9c91f63071ed562e30ee4edc8c (diff) |
Convert ODS import merge methods to use direct Sc calls
During ODS import, ScXMLTableRowCellContext::DoMerge() and
ScXMLTableRowCellContext::IsMerged() are used to handle merged cells.
These methods now use direct Sc calls instead of UNO calls.
Change-Id: Ie9a0cd743aca67ee8bc841c2c2133ad67444efca
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/filter/xml/xmlcelli.cxx | 146 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlcelli.hxx | 7 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlsubti.cxx | 16 | ||||
-rw-r--r-- | sc/source/filter/xml/xmlsubti.hxx | 1 |
4 files changed, 117 insertions, 53 deletions
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx index dcab78274672..cd74d739d73f 100644 --- a/sc/source/filter/xml/xmlcelli.cxx +++ b/sc/source/filter/xml/xmlcelli.cxx @@ -41,6 +41,9 @@ #include "unonames.hxx" #include "postit.hxx" #include "sheetdata.hxx" +#include "cellmergeoption.hxx" +#include "docsh.hxx" +#include "docfunc.hxx" #include "XMLTableShapeImportHelper.hxx" #include "XMLTextPContext.hxx" @@ -450,68 +453,109 @@ SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPr return pContext; } -bool ScXMLTableRowCellContext::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow, - table::CellRangeAddress& aCellAddress) const +namespace { - table::CellAddress aCell; // don't need to set the sheet, because every sheet can contain the same count of cells. - aCell.Column = nCol; - aCell.Row = nRow; - if (CellExists(aCell)) + static bool lcl_ScCellExists( const ScAddress& rScAddress ) { - uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY); - uno::Reference<sheet::XSpreadsheet> xTable (xMergeSheetCellRange->getSpreadsheet()); - uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor (xTable->createCursorByRange(xMergeSheetCellRange)); - if (xMergeSheetCursor.is()) + return( rScAddress.Col() <= MAXCOL && rScAddress.Row() <= MAXROW ); + } + + static ScRange lcl_ScGetCellRangeByPosition( const ScRange& rScRange, const SCCOL nLeft, const SCROW nTop, const SCCOL nRight, const SCROW nBottom ) + throw( lang::IndexOutOfBoundsException ) + { + if( nLeft >= 0 && nTop >= 0 && nRight >= 0 && nBottom >= 0 ) { - xMergeSheetCursor->collapseToMergedArea(); - uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY); - if (xMergeCellAddress.is()) + SCCOL nStartX = rScRange.aStart.Col() + nLeft; + SCROW nStartY = rScRange.aStart.Row() + nTop; + SCCOL nEndX = rScRange.aStart.Col() + nRight; + SCROW nEndY = rScRange.aStart.Row() + nBottom; + + if( nStartX <= nEndX && nEndX <= rScRange.aEnd.Col() && + nStartY <= nEndY && nEndY <= rScRange.aEnd.Row() ) { - aCellAddress = xMergeCellAddress->getRangeAddress(); - if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol && - aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow) - return false; - else - return true; + return ScRange( nStartX, nStartY, rScRange.aStart.Tab(), nEndX, nEndY, rScRange.aEnd.Tab() ); } } + throw lang::IndexOutOfBoundsException(); + } + + static ScRange lcl_ScGetCellRangeByPosition( const ScRange& rScRange, const ScAddress& rScCell ) throw( lang::IndexOutOfBoundsException ) + { + try + { + return lcl_ScGetCellRangeByPosition( rScRange, rScCell.Col(), rScCell.Row(), rScCell.Col(), rScCell.Row() ); + } + catch( lang::IndexOutOfBoundsException & ) { throw; } + } + + static void lcl_ScMerge( ScDocShell* pDocSh, const ScRange& rScRange, const bool bMerge ) + { + if( pDocSh ) + { + ScCellMergeOption aMergeOption( + rScRange.aStart.Col(), rScRange.aStart.Row(), + rScRange.aEnd.Col(), rScRange.aEnd.Row(), false + ); + aMergeOption.maTabs.insert( rScRange.aStart.Tab() ); + if ( bMerge ) + pDocSh->GetDocFunc().MergeCells( aMergeOption, false, true, true ); + else + pDocSh->GetDocFunc().UnmergeCells( aMergeOption, true, true ); + } + } +} + +bool ScXMLTableRowCellContext::IsMerged( const ScRange& rScRange, const ScAddress& rScCell, ScRange& rScCellRange ) const +{ + if( lcl_ScCellExists(rScCell) ) + { + ScDocument* pDoc = rXMLImport.GetDocument(); + rScCellRange = lcl_ScGetCellRangeByPosition( rScRange, rScCell ); + pDoc->ExtendOverlapped( rScCellRange ); + pDoc->ExtendMerge( rScCellRange ); + rScCellRange.Justify(); + if( rScCellRange.aStart.Col() == rScCell.Col() && rScCellRange.aEnd.Col() == rScCell.Col() && + rScCellRange.aStart.Row() == rScCell.Row() && rScCellRange.aEnd.Row() == rScCell.Row() ) + return false; + else + return true; } return false; } -void ScXMLTableRowCellContext::DoMerge(const com::sun::star::table::CellAddress& aCellPos, - const sal_Int32 nCols, const sal_Int32 nRows) +void ScXMLTableRowCellContext::DoMerge( const ScAddress& rScCellPos, const sal_Int32 nCols, const sal_Int32 nRows ) { - if (CellExists(aCellPos)) + if( lcl_ScCellExists(rScCellPos) ) { - uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange()); - if ( xCellRange.is() ) + ScRange aScCellRange; + SCTAB nCurrentSheet = GetScImport().GetTables().GetCurrentSheet(); + ScRange aScRange( 0, 0, nCurrentSheet, MAXCOL, MAXROW, nCurrentSheet ); //the whole sheet + ScDocShell* pDocSh = static_cast< ScDocShell* >( rXMLImport.GetDocument()->GetDocumentShell() ); + // Stored merge range may actually be of a larger extend than what + // we support, in which case getCellRangeByPosition() throws + // IndexOutOfBoundsException. Do nothing then. ??? + try { - // Stored merge range may actually be of a larger extend than what - // we support, in which case getCellRangeByPosition() throws - // IndexOutOfBoundsException. Do nothing then. - try - { - table::CellRangeAddress aCellAddress; - if (IsMerged(xCellRange, aCellPos.Column, aCellPos.Row, aCellAddress)) - { - //unmerge - uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, - aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); - if (xMergeable.is()) - xMergeable->merge(false); - } - - //merge - uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, - aCellAddress.EndColumn + nCols, aCellAddress.EndRow + nRows), uno::UNO_QUERY); - if (xMergeable.is()) - xMergeable->merge(true); - } - catch ( lang::IndexOutOfBoundsException & ) + if( IsMerged(aScRange, rScCellPos, aScCellRange) ) { - OSL_FAIL("ScXMLTableRowCellContext::DoMerge: range to be merged larger than what we support"); + //unmerge + ScRange aScMergeRange( + lcl_ScGetCellRangeByPosition( aScRange, aScCellRange.aStart.Col(), aScCellRange.aStart.Row(), + aScCellRange.aEnd.Col(), aScCellRange.aEnd.Row() ) + ); + lcl_ScMerge( pDocSh, aScMergeRange, false ); } + + //merge + ScRange aScMergeRange( + lcl_ScGetCellRangeByPosition( aScRange, aScCellRange.aStart.Col(), aScCellRange.aStart.Row(), + aScCellRange.aEnd.Col() + nCols, aScCellRange.aEnd.Row() + nRows ) + ); + lcl_ScMerge( pDocSh, aScMergeRange, true ); + } + catch( lang::IndexOutOfBoundsException & ) + { + OSL_FAIL("ScXMLTableRowCellContext::DoMerge: range to be merged larger than what we support"); } } } @@ -783,11 +827,17 @@ void ScXMLTableRowCellContext::EndElement() table::CellAddress aCellPos = rTables.GetRealCellPos(); if (aCellPos.Column > 0 && nRepeatedRows > 1) aCellPos.Row -= (nRepeatedRows - 1); + + //duplicated for now + ScAddress aScCellPos = rTables.GetRealScCellPos(); + if (aScCellPos.Col() > 0 && nRepeatedRows > 1) + aScCellPos.SetRow( aScCellPos.Row() - (nRepeatedRows - 1) ); + uno::Reference<table::XCellRange> xCellRange(rTables.GetCurrentXCellRange()); if (xCellRange.is()) { if (bIsMerged) - DoMerge(aCellPos, nMergedCols - 1, nMergedRows - 1); + DoMerge(aScCellPos, nMergedCols - 1, nMergedRows - 1); if ( !pOUFormula ) { ::boost::optional< rtl::OUString > pOUText; diff --git a/sc/source/filter/xml/xmlcelli.hxx b/sc/source/filter/xml/xmlcelli.hxx index 7a518eaa3f89..4f8b4f9d4303 100644 --- a/sc/source/filter/xml/xmlcelli.hxx +++ b/sc/source/filter/xml/xmlcelli.hxx @@ -82,11 +82,8 @@ class ScXMLTableRowCellContext : public SvXMLImportContext sal_Int16 GetCellType(const rtl::OUString& sOUValue) const; - bool IsMerged (const com::sun::star::uno::Reference <com::sun::star::table::XCellRange>& xCellRange, - const sal_Int32 nCol, const sal_Int32 nRow, - com::sun::star::table::CellRangeAddress& aCellAddress) const; - void DoMerge(const com::sun::star::table::CellAddress& aCellPos, - const sal_Int32 nCols, const sal_Int32 nRows); + bool IsMerged(const ScRange& rScRange, const ScAddress& rScCell, ScRange& rScCellAddress) const; + void DoMerge(const ScAddress& rScCellPos, const sal_Int32 nCols, const sal_Int32 nRows); void SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet); void SetCellProperties(const com::sun::star::uno::Reference<com::sun::star::table::XCellRange>& xCellRange, diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx index aead6b718a4c..ec633bfd70c3 100644 --- a/sc/source/filter/xml/xmlsubti.cxx +++ b/sc/source/filter/xml/xmlsubti.cxx @@ -40,6 +40,7 @@ #include "XMLStylesImportHelper.hxx" #include "sheetdata.hxx" #include "tabprotection.hxx" +#include "convuno.hxx" #include <svx/svdpage.hxx> #include <sax/tools/converter.hxx> @@ -684,6 +685,21 @@ table::CellAddress ScMyTables::GetRealCellPos() return aRealCellPos; } +//placeholder; needs more work +const ScAddress ScMyTables::GetRealScCellPos() const +{ + sal_Int32 nRow = 0; + sal_Int32 nCol = 0; + size_t n = maTables.size(); + for (size_t i = 0; i < n; ++i) + { + const ScMyTableData& rTab = maTables[i]; + nCol += rTab.GetRealCols(rTab.GetColumn()); + nRow += rTab.GetRealRows(rTab.GetRow()); + } + return ScAddress( static_cast<SCCOL>(nCol), static_cast<SCCOL>(nRow), nCurrentSheet ); +} + void ScMyTables::AddColCount(sal_Int32 nTempColCount) { pCurrentTab->SetColCount(pCurrentTab->GetColCount() + nTempColCount); diff --git a/sc/source/filter/xml/xmlsubti.hxx b/sc/source/filter/xml/xmlsubti.hxx index cf37bcfc8896..4fa41cb0d5b5 100644 --- a/sc/source/filter/xml/xmlsubti.hxx +++ b/sc/source/filter/xml/xmlsubti.hxx @@ -171,6 +171,7 @@ public: { return ScMyOLEFixer::IsOLE(rShape); } void DeleteTable(); com::sun::star::table::CellAddress GetRealCellPos(); + const ScAddress GetRealScCellPos() const; void AddColCount(sal_Int32 nTempColCount); void AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName); ScXMLTabProtectionData& GetCurrentProtectionData() { return maProtectionData; } |