summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorDaniel Bankston <daniel.e.bankston@gmail.com>2012-05-24 06:05:15 -0500
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2012-06-01 19:40:08 +0200
commit119b7085ee77c7bd033059332766e66cdcc81fec (patch)
treece553c3ec4d50e131c82cb84477854173fd59cc2 /sc
parent656802c91a278d9c91f63071ed562e30ee4edc8c (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.cxx146
-rw-r--r--sc/source/filter/xml/xmlcelli.hxx7
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx16
-rw-r--r--sc/source/filter/xml/xmlsubti.hxx1
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; }