summaryrefslogtreecommitdiff
path: root/sc/source/filter/xml/XMLExportIterator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/xml/XMLExportIterator.cxx')
-rw-r--r--sc/source/filter/xml/XMLExportIterator.cxx895
1 files changed, 895 insertions, 0 deletions
diff --git a/sc/source/filter/xml/XMLExportIterator.cxx b/sc/source/filter/xml/XMLExportIterator.cxx
new file mode 100644
index 000000000000..d990bf035038
--- /dev/null
+++ b/sc/source/filter/xml/XMLExportIterator.cxx
@@ -0,0 +1,895 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+#include "XMLExportIterator.hxx"
+#include <com/sun/star/text/XSimpleText.hpp>
+#include <com/sun/star/sheet/XCellAddressable.hpp>
+#include <com/sun/star/sheet/CellFlags.hpp>
+#include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <tools/debug.hxx>
+#include <xmloff/xmlnmspe.hxx>
+#include "dociter.hxx"
+#include "convuno.hxx"
+#include "xmlexprt.hxx"
+#include "XMLExportSharedData.hxx"
+#include "XMLStylesExportHelper.hxx"
+#include "document.hxx"
+
+#include <algorithm>
+
+using ::rtl::OUString;
+using namespace ::com::sun::star;
+
+//==============================================================================
+
+ScMyIteratorBase::ScMyIteratorBase()
+{
+}
+
+ScMyIteratorBase::~ScMyIteratorBase()
+{
+}
+
+void ScMyIteratorBase::UpdateAddress( table::CellAddress& rCellAddress )
+{
+ table::CellAddress aNewAddr( rCellAddress );
+ if( GetFirstAddress( aNewAddr ) )
+ {
+ if( (aNewAddr.Sheet == rCellAddress.Sheet) &&
+ ((aNewAddr.Row < rCellAddress.Row) ||
+ ((aNewAddr.Row == rCellAddress.Row) && (aNewAddr.Column < rCellAddress.Column))) )
+ rCellAddress = aNewAddr;
+ }
+}
+
+
+//==============================================================================
+
+sal_Bool ScMyShape::operator<(const ScMyShape& aShape) const
+{
+ if( aAddress.Tab() != aShape.aAddress.Tab() )
+ return (aAddress.Tab() < aShape.aAddress.Tab());
+ else if( aAddress.Row() != aShape.aAddress.Row() )
+ return (aAddress.Row() < aShape.aAddress.Row());
+ else
+ return (aAddress.Col() < aShape.aAddress.Col());
+}
+
+ScMyShapesContainer::ScMyShapesContainer()
+ : aShapeList()
+{
+}
+
+ScMyShapesContainer::~ScMyShapesContainer()
+{
+}
+
+void ScMyShapesContainer::AddNewShape( const ScMyShape& aShape )
+{
+ aShapeList.push_back(aShape);
+}
+
+sal_Bool ScMyShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aShapeList.empty() )
+ {
+ ScUnoConversion::FillApiAddress( rCellAddress, aShapeList.begin()->aAddress );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyShapesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aShapeList.clear();
+ ScAddress aAddress;
+ ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
+
+ ScMyShapeList::iterator aItr(aShapeList.begin());
+ ScMyShapeList::iterator aEndItr(aShapeList.end());
+ while( (aItr != aEndItr) && (aItr->aAddress == aAddress) )
+ {
+ rMyCell.aShapeList.push_back(*aItr);
+ aItr = aShapeList.erase(aItr);
+ }
+ rMyCell.bHasShape = !rMyCell.aShapeList.empty();
+}
+
+void ScMyShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyShapeList::iterator aItr = aShapeList.begin();
+ while( (aItr != aShapeList.end()) && (aItr->aAddress.Tab() == nSkip) )
+ aItr = aShapeList.erase(aItr);
+}
+
+void ScMyShapesContainer::Sort()
+{
+ aShapeList.sort();
+}
+
+sal_Bool ScMyNoteShape::operator<(const ScMyNoteShape& aNote) const
+{
+ if( aPos.Tab() != aNote.aPos.Tab() )
+ return (aPos.Tab() < aNote.aPos.Tab());
+ else if( aPos.Row() != aNote.aPos.Row() )
+ return (aPos.Row() < aNote.aPos.Row());
+ else
+ return (aPos.Col() < aNote.aPos.Col());
+}
+
+ScMyNoteShapesContainer::ScMyNoteShapesContainer()
+ : aNoteShapeList()
+{
+}
+
+ScMyNoteShapesContainer::~ScMyNoteShapesContainer()
+{
+}
+
+void ScMyNoteShapesContainer::AddNewNote( const ScMyNoteShape& aNote )
+{
+ aNoteShapeList.push_back(aNote);
+}
+
+sal_Bool ScMyNoteShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int16 nTable = rCellAddress.Sheet;
+ if( !aNoteShapeList.empty() )
+ {
+ ScUnoConversion::FillApiAddress( rCellAddress, aNoteShapeList.begin()->aPos );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyNoteShapesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.xNoteShape.clear();
+ ScAddress aAddress;
+ ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
+
+ ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
+ while( (aItr != aNoteShapeList.end()) && (aItr->aPos == aAddress) )
+ {
+ rMyCell.xNoteShape = aItr->xShape;
+ aItr = aNoteShapeList.erase(aItr);
+ }
+}
+
+void ScMyNoteShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
+ while( (aItr != aNoteShapeList.end()) && (aItr->aPos.Tab() == nSkip) )
+ aItr = aNoteShapeList.erase(aItr);
+}
+
+void ScMyNoteShapesContainer::Sort()
+{
+ aNoteShapeList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyMergedRange::operator<(const ScMyMergedRange& aRange) const
+{
+ if( aCellRange.Sheet != aRange.aCellRange.Sheet )
+ return (aCellRange.Sheet < aRange.aCellRange.Sheet);
+ else if( aCellRange.StartRow != aRange.aCellRange.StartRow )
+ return (aCellRange.StartRow < aRange.aCellRange.StartRow);
+ else
+ return (aCellRange.StartColumn < aRange.aCellRange.StartColumn);
+}
+
+
+ScMyMergedRangesContainer::ScMyMergedRangesContainer()
+ : aRangeList()
+{
+}
+
+ScMyMergedRangesContainer::~ScMyMergedRangesContainer()
+{
+}
+
+void ScMyMergedRangesContainer::AddRange(const table::CellRangeAddress aMergedRange)
+{
+ sal_Int32 nStartRow(aMergedRange.StartRow);
+ sal_Int32 nEndRow(aMergedRange.EndRow);
+
+ ScMyMergedRange aRange;
+ aRange.bIsFirst = sal_True;
+ aRange.aCellRange = aMergedRange;
+ aRange.aCellRange.EndRow = nStartRow;
+ aRange.nRows = nEndRow - nStartRow + 1;
+ aRangeList.push_back( aRange );
+
+ aRange.bIsFirst = false;
+ aRange.nRows = 0;
+ for( sal_Int32 nRow = nStartRow + 1; nRow <= nEndRow; ++nRow )
+ {
+ aRange.aCellRange.StartRow = aRange.aCellRange.EndRow = nRow;
+ aRangeList.push_back(aRange);
+ }
+}
+
+sal_Bool ScMyMergedRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aRangeList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, aRangeList.begin()->aCellRange );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyMergedRangesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bIsMergedBase = rMyCell.bIsCovered = false;
+ ScMyMergedRangeList::iterator aItr(aRangeList.begin());
+ if( aItr != aRangeList.end() )
+ {
+ table::CellAddress aFirstAddress;
+ ScUnoConversion::FillApiStartAddress( aFirstAddress, aItr->aCellRange );
+ if( aFirstAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.aMergeRange = aItr->aCellRange;
+ if (aItr->bIsFirst)
+ rMyCell.aMergeRange.EndRow = rMyCell.aMergeRange.StartRow + aItr->nRows - 1;
+ rMyCell.bIsMergedBase = aItr->bIsFirst;
+ rMyCell.bIsCovered = !aItr->bIsFirst;
+ if( aItr->aCellRange.StartColumn < aItr->aCellRange.EndColumn )
+ {
+ ++(aItr->aCellRange.StartColumn);
+ aItr->bIsFirst = false;
+ }
+ else
+ aRangeList.erase(aItr);
+ }
+ }
+}
+
+void ScMyMergedRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyMergedRangeList::iterator aItr = aRangeList.begin();
+ while( (aItr != aRangeList.end()) && (aItr->aCellRange.Sheet == nSkip) )
+ aItr = aRangeList.erase(aItr);
+}
+
+void ScMyMergedRangesContainer::Sort()
+{
+ aRangeList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyAreaLink::Compare( const ScMyAreaLink& rAreaLink ) const
+{
+ return (GetRowCount() == rAreaLink.GetRowCount()) &&
+ (sFilter == rAreaLink.sFilter) &&
+ (sFilterOptions == rAreaLink.sFilterOptions) &&
+ (sURL == rAreaLink.sURL) &&
+ (sSourceStr == rAreaLink.sSourceStr);
+}
+
+sal_Bool ScMyAreaLink::operator<(const ScMyAreaLink& rAreaLink ) const
+{
+ if( aDestRange.Sheet != rAreaLink.aDestRange.Sheet )
+ return (aDestRange.Sheet < rAreaLink.aDestRange.Sheet);
+ else if( aDestRange.StartRow != rAreaLink.aDestRange.StartRow )
+ return (aDestRange.StartRow < rAreaLink.aDestRange.StartRow);
+ else
+ return (aDestRange.StartColumn < rAreaLink.aDestRange.StartColumn);
+}
+
+ScMyAreaLinksContainer::ScMyAreaLinksContainer() :
+ aAreaLinkList()
+{
+}
+
+ScMyAreaLinksContainer::~ScMyAreaLinksContainer()
+{
+}
+
+sal_Bool ScMyAreaLinksContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aAreaLinkList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, aAreaLinkList.begin()->aDestRange );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyAreaLinksContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bHasAreaLink = false;
+ ScMyAreaLinkList::iterator aItr(aAreaLinkList.begin());
+ if( aItr != aAreaLinkList.end() )
+ {
+ table::CellAddress aAddress;
+ ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
+ if( aAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.bHasAreaLink = sal_True;
+ rMyCell.aAreaLink = *aItr;
+ aItr = aAreaLinkList.erase( aItr );
+ sal_Bool bFound = sal_True;
+ while (aItr != aAreaLinkList.end() && bFound)
+ {
+ ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
+ if (aAddress == rMyCell.aCellAddress)
+ {
+ OSL_FAIL("more than one linked range on one cell");
+ aItr = aAreaLinkList.erase( aItr );
+ }
+ else
+ bFound = false;
+ }
+ }
+ }
+}
+
+void ScMyAreaLinksContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyAreaLinkList::iterator aItr = aAreaLinkList.begin();
+ while( (aItr != aAreaLinkList.end()) && (aItr->aDestRange.Sheet == nSkip) )
+ aItr = aAreaLinkList.erase(aItr);
+}
+
+void ScMyAreaLinksContainer::Sort()
+{
+ aAreaLinkList.sort();
+}
+
+//==============================================================================
+
+ScMyCellRangeAddress::ScMyCellRangeAddress(const table::CellRangeAddress& rRange)
+ : table::CellRangeAddress(rRange)
+{
+}
+
+sal_Bool ScMyCellRangeAddress::operator<(const ScMyCellRangeAddress& rRange ) const
+{
+ if( Sheet != rRange.Sheet )
+ return (Sheet < rRange.Sheet);
+ else if( StartRow != rRange.StartRow )
+ return (StartRow < rRange.StartRow);
+ else
+ return (StartColumn < rRange.StartColumn);
+}
+
+ScMyEmptyDatabaseRangesContainer::ScMyEmptyDatabaseRangesContainer()
+ : aDatabaseList()
+{
+}
+
+ScMyEmptyDatabaseRangesContainer::~ScMyEmptyDatabaseRangesContainer()
+{
+}
+
+void ScMyEmptyDatabaseRangesContainer::AddNewEmptyDatabaseRange(const table::CellRangeAddress& aCellRange)
+{
+ sal_Int32 nStartRow(aCellRange.StartRow);
+ sal_Int32 nEndRow(aCellRange.EndRow);
+ ScMyCellRangeAddress aRange( aCellRange );
+ for( sal_Int32 nRow = nStartRow; nRow <= nEndRow; ++nRow )
+ {
+ aRange.StartRow = aRange.EndRow = nRow;
+ aDatabaseList.push_back( aRange );
+ }
+}
+
+sal_Bool ScMyEmptyDatabaseRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDatabaseList.empty() )
+ {
+ ScUnoConversion::FillApiStartAddress( rCellAddress, *(aDatabaseList.begin()) );
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyEmptyDatabaseRangesContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bHasEmptyDatabase = false;
+ ScMyEmptyDatabaseRangeList::iterator aItr(aDatabaseList.begin());
+ if( aItr != aDatabaseList.end() )
+ {
+ table::CellAddress aFirstAddress;
+ ScUnoConversion::FillApiStartAddress( aFirstAddress, *aItr );
+ if( aFirstAddress == rMyCell.aCellAddress )
+ {
+ rMyCell.bHasEmptyDatabase = sal_True;
+ if( aItr->StartColumn < aItr->EndColumn )
+ ++(aItr->StartColumn);
+ else
+ aDatabaseList.erase(aItr);
+ }
+ }
+}
+
+void ScMyEmptyDatabaseRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyEmptyDatabaseRangeList::iterator aItr = aDatabaseList.begin();
+ while( (aItr != aDatabaseList.end()) && (aItr->Sheet == nSkip) )
+ aItr = aDatabaseList.erase(aItr);
+}
+
+void ScMyEmptyDatabaseRangesContainer::Sort()
+{
+ aDatabaseList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyDetectiveObj::operator<( const ScMyDetectiveObj& rDetObj) const
+{
+ if( aPosition.Sheet != rDetObj.aPosition.Sheet )
+ return (aPosition.Sheet < rDetObj.aPosition.Sheet);
+ else if( aPosition.Row != rDetObj.aPosition.Row )
+ return (aPosition.Row < rDetObj.aPosition.Row);
+ else
+ return (aPosition.Column < rDetObj.aPosition.Column);
+}
+
+ScMyDetectiveObjContainer::ScMyDetectiveObjContainer() :
+ aDetectiveObjList()
+{
+}
+
+ScMyDetectiveObjContainer::~ScMyDetectiveObjContainer()
+{
+}
+
+void ScMyDetectiveObjContainer::AddObject( ScDetectiveObjType eObjType, const SCTAB nSheet,
+ const ScAddress& rPosition, const ScRange& rSourceRange,
+ sal_Bool bHasError )
+{
+ if( (eObjType == SC_DETOBJ_ARROW) ||
+ (eObjType == SC_DETOBJ_FROMOTHERTAB) ||
+ (eObjType == SC_DETOBJ_TOOTHERTAB) ||
+ (eObjType == SC_DETOBJ_CIRCLE) )
+ {
+ ScMyDetectiveObj aDetObj;
+ aDetObj.eObjType = eObjType;
+ if( eObjType == SC_DETOBJ_TOOTHERTAB )
+ ScUnoConversion::FillApiAddress( aDetObj.aPosition, rSourceRange.aStart );
+ else
+ ScUnoConversion::FillApiAddress( aDetObj.aPosition, rPosition );
+ ScUnoConversion::FillApiRange( aDetObj.aSourceRange, rSourceRange );
+
+ // #111064#; take the sheet where the object is found and not the sheet given in the ranges, because they are not always true
+ if (eObjType != SC_DETOBJ_FROMOTHERTAB)
+ {
+ // if the ObjType == SC_DETOBJ_FROMOTHERTAB then the SourceRange is not used and so it has not to be tested and changed
+ DBG_ASSERT(aDetObj.aPosition.Sheet == aDetObj.aSourceRange.Sheet, "It seems to be possible to have different sheets");
+ aDetObj.aSourceRange.Sheet = nSheet;
+ }
+ aDetObj.aPosition.Sheet = nSheet;
+
+ aDetObj.bHasError = bHasError;
+ aDetectiveObjList.push_back( aDetObj );
+ }
+}
+
+sal_Bool ScMyDetectiveObjContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDetectiveObjList.empty() )
+ {
+ rCellAddress = aDetectiveObjList.begin()->aPosition;
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyDetectiveObjContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aDetectiveObjVec.clear();
+ ScMyDetectiveObjList::iterator aItr(aDetectiveObjList.begin());
+ ScMyDetectiveObjList::iterator aEndItr(aDetectiveObjList.end());
+ while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
+ {
+ rMyCell.aDetectiveObjVec.push_back( *aItr );
+ aItr = aDetectiveObjList.erase( aItr );
+ }
+ rMyCell.bHasDetectiveObj = (rMyCell.aDetectiveObjVec.size() != 0);
+}
+
+void ScMyDetectiveObjContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveObjList::iterator aItr = aDetectiveObjList.begin();
+ while( (aItr != aDetectiveObjList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveObjList.erase(aItr);
+}
+
+void ScMyDetectiveObjContainer::Sort()
+{
+ aDetectiveObjList.sort();
+}
+
+//==============================================================================
+
+sal_Bool ScMyDetectiveOp::operator<( const ScMyDetectiveOp& rDetOp) const
+{
+ if( aPosition.Sheet != rDetOp.aPosition.Sheet )
+ return (aPosition.Sheet < rDetOp.aPosition.Sheet);
+ else if( aPosition.Row != rDetOp.aPosition.Row )
+ return (aPosition.Row < rDetOp.aPosition.Row);
+ else
+ return (aPosition.Column < rDetOp.aPosition.Column);
+}
+
+ScMyDetectiveOpContainer::ScMyDetectiveOpContainer() :
+ aDetectiveOpList()
+{
+}
+
+ScMyDetectiveOpContainer::~ScMyDetectiveOpContainer()
+{
+}
+
+void ScMyDetectiveOpContainer::AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex )
+{
+ ScMyDetectiveOp aDetOp;
+ aDetOp.eOpType = eOpType;
+ ScUnoConversion::FillApiAddress( aDetOp.aPosition, rPosition );
+ aDetOp.nIndex = nIndex;
+ aDetectiveOpList.push_back( aDetOp );
+}
+
+sal_Bool ScMyDetectiveOpContainer::GetFirstAddress( table::CellAddress& rCellAddress )
+{
+ sal_Int32 nTable(rCellAddress.Sheet);
+ if( !aDetectiveOpList.empty() )
+ {
+ rCellAddress = aDetectiveOpList.begin()->aPosition;
+ return (nTable == rCellAddress.Sheet);
+ }
+ return false;
+}
+
+void ScMyDetectiveOpContainer::SetCellData( ScMyCell& rMyCell )
+{
+ rMyCell.aDetectiveOpVec.clear();
+ ScMyDetectiveOpList::iterator aItr(aDetectiveOpList.begin());
+ ScMyDetectiveOpList::iterator aEndItr(aDetectiveOpList.end());
+ while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
+ {
+ rMyCell.aDetectiveOpVec.push_back( *aItr );
+ aItr = aDetectiveOpList.erase( aItr );
+ }
+ rMyCell.bHasDetectiveOp = (rMyCell.aDetectiveOpVec.size() != 0);
+}
+
+void ScMyDetectiveOpContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveOpList::iterator aItr = aDetectiveOpList.begin();
+ while( (aItr != aDetectiveOpList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveOpList.erase(aItr);
+}
+
+void ScMyDetectiveOpContainer::Sort()
+{
+ aDetectiveOpList.sort();
+}
+
+//==============================================================================
+
+ScMyCell::ScMyCell() :
+ aShapeList(),
+ aDetectiveObjVec(),
+ fValue(0.0),
+ nValidationIndex(-1),
+ pBaseCell(NULL),
+ bIsAutoStyle( false ),
+ bHasShape( false ),
+ bIsMergedBase( false ),
+ bIsCovered( false ),
+ bHasAreaLink( false ),
+ bHasEmptyDatabase( false ),
+ bHasDetectiveObj( false ),
+ bHasDetectiveOp( false ),
+ bIsEditCell( false ),
+ bKnowWhetherIsEditCell( false ),
+ bHasStringValue( false ),
+ bHasDoubleValue( false ),
+ bHasXText( false ),
+ bIsMatrixBase( false ),
+ bIsMatrixCovered( false ),
+ bHasAnnotation( false )
+{
+}
+
+ScMyCell::~ScMyCell()
+{
+}
+
+//==============================================================================
+
+sal_Bool ScMyExportAnnotation::operator<(const ScMyExportAnnotation& rAnno) const
+{
+ if( aCellAddress.Row != rAnno.aCellAddress.Row )
+ return (aCellAddress.Row < rAnno.aCellAddress.Row);
+ else
+ return (aCellAddress.Column < rAnno.aCellAddress.Column);
+}
+
+
+ScMyNotEmptyCellsIterator::ScMyNotEmptyCellsIterator(ScXMLExport& rTempXMLExport)
+ : pShapes(NULL),
+ pNoteShapes(NULL),
+ pEmptyDatabaseRanges(NULL),
+ pMergedRanges(NULL),
+ pAreaLinks(NULL),
+ pDetectiveObj(NULL),
+ pDetectiveOp(NULL),
+ rExport(rTempXMLExport),
+ pCellItr(NULL),
+ nCurrentTable(SCTAB_MAX)
+{
+}
+
+ScMyNotEmptyCellsIterator::~ScMyNotEmptyCellsIterator()
+{
+ Clear();
+}
+
+void ScMyNotEmptyCellsIterator::Clear()
+{
+ if (pCellItr)
+ delete pCellItr;
+ if (!aAnnotations.empty())
+ {
+ OSL_FAIL("not all Annotations saved");
+ aAnnotations.clear();
+ }
+ pCellItr = NULL;
+ pShapes = NULL;
+ pNoteShapes = NULL;
+ pMergedRanges = NULL;
+ pAreaLinks = NULL;
+ pEmptyDatabaseRanges = NULL;
+ pDetectiveObj = NULL;
+ pDetectiveOp = NULL;
+ nCurrentTable = SCTAB_MAX;
+}
+
+void ScMyNotEmptyCellsIterator::UpdateAddress( table::CellAddress& rAddress )
+{
+ if( pCellItr->ReturnNext( nCellCol, nCellRow ) )
+ {
+ rAddress.Column = nCellCol;
+ rAddress.Row = nCellRow;
+ }
+}
+
+void ScMyNotEmptyCellsIterator::SetCellData( ScMyCell& rMyCell, table::CellAddress& rAddress )
+{
+ rMyCell.aCellAddress = rAddress;
+ rMyCell.bHasStringValue = false;
+ rMyCell.bHasDoubleValue = false;
+ rMyCell.bHasXText = false;
+ rMyCell.bKnowWhetherIsEditCell = false;
+ rMyCell.bIsEditCell = false;
+ if( (nCellCol == rAddress.Column) && (nCellRow == rAddress.Row) )
+ pCellItr->GetNext( nCellCol, nCellRow );
+}
+
+void ScMyNotEmptyCellsIterator::SetMatrixCellData( ScMyCell& rMyCell )
+{
+ rMyCell.bIsMatrixCovered = false;
+ rMyCell.bIsMatrixBase = false;
+
+ sal_Bool bIsMatrixBase(false);
+
+ ScAddress aScAddress;
+ ScUnoConversion::FillScAddress( aScAddress, rMyCell.aCellAddress );
+ CellType eCalcType = rExport.GetDocument()->GetCellType( aScAddress );
+ switch (eCalcType)
+ {
+ case CELLTYPE_VALUE:
+ rMyCell.nType = table::CellContentType_VALUE;
+ break;
+ case CELLTYPE_STRING:
+ case CELLTYPE_EDIT:
+ rMyCell.nType = table::CellContentType_TEXT;
+ break;
+ case CELLTYPE_FORMULA:
+ rMyCell.nType = table::CellContentType_FORMULA;
+ break;
+ default:
+ rMyCell.nType = table::CellContentType_EMPTY;
+ }
+
+ if (rMyCell.nType == table::CellContentType_FORMULA)
+ if( rExport.IsMatrix( aScAddress, rMyCell.aMatrixRange, bIsMatrixBase ) )
+ {
+ rMyCell.bIsMatrixBase = bIsMatrixBase;
+ rMyCell.bIsMatrixCovered = !bIsMatrixBase;
+ }
+}
+
+void ScMyNotEmptyCellsIterator::HasAnnotation(ScMyCell& aCell)
+{
+ aCell.bHasAnnotation = false;
+ if (!aAnnotations.empty())
+ {
+ ScMyExportAnnotationList::iterator aItr(aAnnotations.begin());
+ if ((aCell.aCellAddress.Column == aItr->aCellAddress.Column) &&
+ (aCell.aCellAddress.Row == aItr->aCellAddress.Row))
+ {
+ aCell.xAnnotation.set(aItr->xAnnotation);
+ uno::Reference<text::XSimpleText> xSimpleText(aCell.xAnnotation, uno::UNO_QUERY);
+ if (aCell.xAnnotation.is() && xSimpleText.is())
+ {
+ aCell.sAnnotationText = xSimpleText->getString();
+ if (aCell.sAnnotationText.getLength())
+ aCell.bHasAnnotation = sal_True;
+ }
+ aAnnotations.erase(aItr);
+ }
+ }
+
+ // test - bypass the API
+ // if (xCellRange.is())
+ // aCell.xCell.set(xCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row));
+}
+
+void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable,
+ uno::Reference<sheet::XSpreadsheet>& rxTable)
+{
+ DBG_ASSERT(aAnnotations.empty(), "not all Annotations saved");
+ aLastAddress.Row = 0;
+ aLastAddress.Column = 0;
+ aLastAddress.Sheet = nTable;
+ if (nCurrentTable != nTable)
+ {
+ nCurrentTable = nTable;
+ if (pCellItr)
+ delete pCellItr;
+ pCellItr = new ScHorizontalCellIterator(rExport.GetDocument(), nCurrentTable, 0, 0,
+ static_cast<SCCOL>(rExport.GetSharedData()->GetLastColumn(nCurrentTable)), static_cast<SCROW>(rExport.GetSharedData()->GetLastRow(nCurrentTable)));
+ xTable.set(rxTable);
+ xCellRange.set(xTable, uno::UNO_QUERY);
+ uno::Reference<sheet::XSheetAnnotationsSupplier> xSheetAnnotationsSupplier (xTable, uno::UNO_QUERY);
+ if (xSheetAnnotationsSupplier.is())
+ {
+ uno::Reference<container::XEnumerationAccess> xAnnotationAccess ( xSheetAnnotationsSupplier->getAnnotations(), uno::UNO_QUERY);
+ if (xAnnotationAccess.is())
+ {
+ uno::Reference<container::XEnumeration> xAnnotations(xAnnotationAccess->createEnumeration());
+ if (xAnnotations.is())
+ {
+ while (xAnnotations->hasMoreElements())
+ {
+ ScMyExportAnnotation aAnnotation;
+ aAnnotation.xAnnotation.set(xAnnotations->nextElement(), uno::UNO_QUERY);
+ if (aAnnotation.xAnnotation.is())
+ {
+ aAnnotation.aCellAddress = aAnnotation.xAnnotation->getPosition();
+ aAnnotations.push_back(aAnnotation);
+ }
+ }
+ if (!aAnnotations.empty())
+ aAnnotations.sort();
+ }
+ }
+ }
+ }
+}
+
+void ScMyNotEmptyCellsIterator::SkipTable(SCTAB nSkip)
+{
+ // Skip entries for a sheet that is copied instead of saving normally.
+ // Cells (including aAnnotations) are handled separately in SetCurrentTable.
+
+ if( pShapes )
+ pShapes->SkipTable(nSkip);
+ if( pNoteShapes )
+ pNoteShapes->SkipTable(nSkip);
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->SkipTable(nSkip);
+ if( pMergedRanges )
+ pMergedRanges->SkipTable(nSkip);
+ if( pAreaLinks )
+ pAreaLinks->SkipTable(nSkip);
+ if( pDetectiveObj )
+ pDetectiveObj->SkipTable(nSkip);
+ if( pDetectiveOp )
+ pDetectiveOp->SkipTable(nSkip);
+}
+
+sal_Bool ScMyNotEmptyCellsIterator::GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles)
+{
+ table::CellAddress aAddress( nCurrentTable, MAXCOL + 1, MAXROW + 1 );
+
+ UpdateAddress( aAddress );
+ if( pShapes )
+ pShapes->UpdateAddress( aAddress );
+ if( pNoteShapes )
+ pNoteShapes->UpdateAddress( aAddress );
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->UpdateAddress( aAddress );
+ if( pMergedRanges )
+ pMergedRanges->UpdateAddress( aAddress );
+ if( pAreaLinks )
+ pAreaLinks->UpdateAddress( aAddress );
+ if( pDetectiveObj )
+ pDetectiveObj->UpdateAddress( aAddress );
+ if( pDetectiveOp )
+ pDetectiveOp->UpdateAddress( aAddress );
+
+ sal_Bool bFoundCell((aAddress.Column <= MAXCOL) && (aAddress.Row <= MAXROW));
+ if( bFoundCell )
+ {
+ SetCellData( aCell, aAddress );
+ if( pShapes )
+ pShapes->SetCellData( aCell );
+ if( pNoteShapes )
+ pNoteShapes->SetCellData( aCell );
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->SetCellData( aCell );
+ if( pMergedRanges )
+ pMergedRanges->SetCellData( aCell );
+ if( pAreaLinks )
+ pAreaLinks->SetCellData( aCell );
+ if( pDetectiveObj )
+ pDetectiveObj->SetCellData( aCell );
+ if( pDetectiveOp )
+ pDetectiveOp->SetCellData( aCell );
+
+ HasAnnotation( aCell );
+ SetMatrixCellData( aCell );
+ sal_Bool bIsAutoStyle;
+ // Ranges before the previous cell are not needed by ExportFormatRanges anymore and can be removed
+ sal_Int32 nRemoveBeforeRow = aLastAddress.Row;
+ aCell.nStyleIndex = pCellStyles->GetStyleNameIndex(aCell.aCellAddress.Sheet,
+ aCell.aCellAddress.Column, aCell.aCellAddress.Row,
+ bIsAutoStyle, aCell.nValidationIndex, aCell.nNumberFormat, nRemoveBeforeRow);
+ aLastAddress = aCell.aCellAddress;
+ aCell.bIsAutoStyle = bIsAutoStyle;
+
+ //#102799#; if the cell is in a DatabaseRange which should saved empty, the cell should have the type empty
+ if (aCell.bHasEmptyDatabase)
+ aCell.nType = table::CellContentType_EMPTY;
+ }
+ return bFoundCell;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */