diff options
Diffstat (limited to 'sc/source/filter/xml/xmlsubti.cxx')
-rw-r--r-- | sc/source/filter/xml/xmlsubti.cxx | 831 |
1 files changed, 831 insertions, 0 deletions
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx new file mode 100644 index 000000000000..0e7f7b221152 --- /dev/null +++ b/sc/source/filter/xml/xmlsubti.cxx @@ -0,0 +1,831 @@ +/* -*- 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 "xmlsubti.hxx" +#include "global.hxx" +#include "xmlstyli.hxx" +#include "xmlimprt.hxx" +#include "document.hxx" +#include "markdata.hxx" +#include "XMLConverter.hxx" +#include "docuno.hxx" +#include "cellsuno.hxx" +#include "XMLStylesImportHelper.hxx" +#include "sheetdata.hxx" +#include "tabprotection.hxx" +#include <svx/svdpage.hxx> + +#include <xmloff/xmltkmap.hxx> +#include <xmloff/nmspmap.hxx> +#include <xmloff/xmluconv.hxx> +#include <xmloff/xmlerror.hxx> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/util/XMergeable.hpp> +#include <com/sun/star/sheet/XSheetCellRange.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> +#include <com/sun/star/sheet/CellInsertMode.hpp> +#include <com/sun/star/sheet/XCellRangeMovement.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/util/XProtectable.hpp> +#include <com/sun/star/sheet/XArrayFormulaRange.hpp> + +#include <memory> + +using ::std::auto_ptr; + +//------------------------------------------------------------------ + +using namespace com::sun::star; + +ScMyTableData::ScMyTableData(sal_Int32 nSheet, sal_Int32 nCol, sal_Int32 nRow) + : nColsPerCol(nDefaultColCount, 1), + nRealCols(nDefaultColCount + 1, 0), + nRowsPerRow(nDefaultRowCount, 1), + nRealRows(nDefaultRowCount + 1, 0), + nChangedCols() +{ + aTableCellPos.Sheet = sal::static_int_cast<sal_Int16>( nSheet ); + aTableCellPos.Column = nCol; + aTableCellPos.Row = nRow; + + for (sal_Int32 i = 0; i < 3; ++i) + nRealCols[i] = i; + for (sal_Int32 j = 0; j < 3; ++j) + nRealRows[j] = j; + + nSpannedCols = 1; + nColCount = 0; + nSubTableSpanned = 1; +} + +ScMyTableData::~ScMyTableData() +{ +} + +void ScMyTableData::AddRow() +{ + ++aTableCellPos.Row; + if (static_cast<sal_uInt32>(aTableCellPos.Row) >= nRowsPerRow.size()) + { + nRowsPerRow.resize(nRowsPerRow.size() + nDefaultRowCount, 1); + nRealRows.resize(nRowsPerRow.size() + nDefaultRowCount + 1, 0); + } + nRealRows[aTableCellPos.Row + 1] = nRealRows[aTableCellPos.Row] + nRowsPerRow[aTableCellPos.Row]; +} + +void ScMyTableData::AddColumn() +{ + ++aTableCellPos.Column; + if (static_cast<sal_uInt32>(aTableCellPos.Column) >= nColsPerCol.size()) + { + nColsPerCol.resize(nColsPerCol.size() + nDefaultColCount, 1); + nRealCols.resize(nColsPerCol.size() + nDefaultColCount + 1, 0); + } + nRealCols[aTableCellPos.Column + 1] = nRealCols[aTableCellPos.Column] + nColsPerCol[aTableCellPos.Column]; +} + +sal_Int32 ScMyTableData::GetRealCols(const sal_Int32 nIndex, const sal_Bool /* bIsNormal */) const +{ + return (nIndex < 0) ? 0 : nRealCols[nIndex]; +} + +sal_Int32 ScMyTableData::GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const +{ + ScMysalIntList::const_iterator i(nChangedCols.begin()); + ScMysalIntList::const_iterator endi(nChangedCols.end()); + while ((i != endi) && ((*i < nToIndex) && !(*i >= nFromIndex))) + ++i; + if (i == endi) + return -1; + else + if ((*i >= nFromIndex) && (*i < nToIndex)) + return *i; + else + return -1; +} + +void ScMyTableData::SetChangedCols(const sal_Int32 nValue) +{ + ScMysalIntList::iterator i(nChangedCols.begin()); + ScMysalIntList::iterator endi(nChangedCols.end()); + while ((i != endi) && (*i < nValue)) + { + ++i; + } + if ((i == endi) || (*i != nValue)) + nChangedCols.insert(i, nValue); +} + +/*******************************************************************************************************************************/ + +ScXMLTabProtectionData::ScXMLTabProtectionData() : + meHash1(PASSHASH_SHA1), + meHash2(PASSHASH_UNSPECIFIED), + mbProtected(false), + mbSelectProtectedCells(true), + mbSelectUnprotectedCells(true) +{ +} + +ScMyTables::ScMyTables(ScXMLImport& rTempImport) + : rImport(rTempImport), + aFixupOLEs(rTempImport), + nCurrentColStylePos(0), + nCurrentDrawPage( -1 ), + nCurrentXShapes( -1 ), + nCurrentSheet( -1 ) +{ +} + +ScMyTables::~ScMyTables() +{ +} + +void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName, + const ScXMLTabProtectionData& rProtectData) +{ + if (rImport.GetModel().is()) + { + nCurrentColStylePos = 0; + sCurrentSheetName = sTableName; + maTables.clear(); + ++nCurrentSheet; + + maProtectionData = rProtectData; + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY ); + if ( xSpreadDoc.is() ) + { + uno::Reference <sheet::XSpreadsheets> xSheets(xSpreadDoc->getSheets()); + if (xSheets.is()) + { + if (nCurrentSheet > 0) + { + try + { + xSheets->insertNewByName(sTableName, sal::static_int_cast<sal_Int16>(nCurrentSheet)); + } + catch ( uno::RuntimeException& ) + { + ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel()); + if (pDoc) + { + ScXMLImport::MutexGuard aGuard(rImport); + String sTabName(String::CreateFromAscii("Table")); + pDoc->CreateValidTabName(sTabName); + rtl::OUString sOUTabName(sTabName); + xSheets->insertNewByName(sOUTabName, sal::static_int_cast<sal_Int16>(nCurrentSheet)); + } + } + } + uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY ); + if ( xIndex.is() ) + { + xCurrentSheet.set(xIndex->getByIndex(nCurrentSheet), uno::UNO_QUERY); + if ( xCurrentSheet.is() ) + { + xCurrentCellRange.set(xCurrentSheet, uno::UNO_QUERY); + if (!(nCurrentSheet > 0)) + { + uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY ); + if ( xNamed.is() ) + try + { + xNamed->setName(sTableName); + } + catch ( uno::RuntimeException& ) + { + ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel()); + if (pDoc) + { + ScXMLImport::MutexGuard aGuard(rImport); + String sTabName(String::CreateFromAscii("Table")); + pDoc->CreateValidTabName(sTabName); + rtl::OUString sOUTabName(sTabName); + xNamed->setName(sOUTabName); + } + } + } + rImport.SetTableStyle(sStyleName); + + if ( sStyleName.getLength() ) + { + // #i57869# All table style properties for all sheets are now applied here, + // before importing the contents. + // This is needed for the background color. + // Sheet visibility has special handling in ScDocFunc::SetTableVisible to + // allow hiding the first sheet. + // RTL layout is only remembered, not actually applied, so the shapes can + // be loaded before mirroring. + + uno::Reference <beans::XPropertySet> xProperties(xCurrentSheet, uno::UNO_QUERY); + if (xProperties.is()) + { + XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rImport.GetAutoStyles(); + if (pStyles) + { + XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext( + XML_STYLE_FAMILY_TABLE_TABLE, sStyleName, sal_True); + if (pStyle) + { + pStyle->FillPropertySet(xProperties); + + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rImport.GetModel())->GetSheetSaveData(); + pSheetData->AddTableStyle( sStyleName, ScAddress( 0, 0, (SCTAB)nCurrentSheet ) ); + } + } + } + } + } + + } + } + } + } + + NewTable(1); +} + +sal_Bool ScMyTables::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow, + table::CellRangeAddress& aCellAddress) const +{ + uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY); + if (xMergeable.is()) + { + uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xMergeable, uno::UNO_QUERY); + uno::Reference<sheet::XSpreadsheet> xTable(xMergeSheetCellRange->getSpreadsheet()); + uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor(xTable->createCursorByRange(xMergeSheetCellRange)); + if (xMergeSheetCursor.is()) + { + xMergeSheetCursor->collapseToMergedArea(); + uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY); + if (xMergeCellAddress.is()) + { + aCellAddress = xMergeCellAddress->getRangeAddress(); + if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol && + aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow) + return false; + else + return sal_True; + } + } + } + return false; +} + +void ScMyTables::UnMerge() +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(false); + } + } +} + +void ScMyTables::DoMerge(sal_Int32 nCount) +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(false); + } + + //merge + uno::Reference <table::XCellRange> xMergeCellRange; + if (nCount == -1) + { + const ScMyTableData& r = maTables.back(); + xMergeCellRange.set( + xCurrentCellRange->getCellRangeByPosition( + aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn + r.GetColsPerCol(r.GetColumn()) - 1, + aCellAddress.EndRow + r.GetRowsPerRow(r.GetRow()) - 1)); + } + else + xMergeCellRange.set( + xCurrentCellRange->getCellRangeByPosition( + aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.StartColumn + nCount - 1, + aCellAddress.EndRow)); + + uno::Reference <util::XMergeable> xMergeable (xMergeCellRange, uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_True); + } +} + +void ScMyTables::InsertRow() +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + sal_Int32 nRow(GetRealCellPos().Row); + const ScMyTableData& rTab = maTables.back(); + for (sal_Int32 j = 0; j < GetRealCellPos().Column - rTab.GetColumn() - 1; ++j) + { + if (IsMerged(xCurrentCellRange, j, nRow - 1, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(false); + } + + //merge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow + 1), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_True); + j += aCellAddress.EndColumn - aCellAddress.StartColumn; + } + rImport.GetStylesImportHelper()->InsertRow(nRow, nCurrentSheet, rImport.GetDocument()); + } +} + +void ScMyTables::NewRow() +{ + size_t n = maTables.size(); + if (n <= 1) + return; + + if (maTables[n-1].GetRealRows(maTables[n-1].GetRow()) > + maTables[n-2].GetRowsPerRow(maTables[n-2].GetRow()) - 1) + { + if (GetRealCellPos().Column > 0) + InsertRow(); + + for (size_t i = n - 1; i > 0; --i) + { + sal_Int32 nRow = maTables[i-1].GetRow(); + maTables[i-1].SetRowsPerRow( + nRow, + maTables[i-1].GetRowsPerRow(nRow) + 1); + + maTables[i-1].SetRealRows( + nRow + 1, + maTables[i-1].GetRealRows(nRow) + maTables[i-1].GetRowsPerRow(nRow)); + } + } +} + +void ScMyTables::AddRow() +{ + ScMyTableData& rTab = maTables.back(); + rTab.AddRow(); + rTab.SetFirstColumn(); + sal_Int32 nRow = rTab.GetRow(); + if (nRow > 0) + NewRow(); + + rTab.SetRealRows( + nRow + 1, rTab.GetRealRows(nRow) + rTab.GetRowsPerRow(nRow)); +} + +void ScMyTables::SetRowStyle(const rtl::OUString& rCellStyleName) +{ + rImport.GetStylesImportHelper()->SetRowStyle(rCellStyleName); +} + +void ScMyTables::InsertColumn() +{ + if ( xCurrentCellRange.is() ) + { + table::CellRangeAddress aCellAddress; + sal_Int32 nCol(GetRealCellPos().Column); + sal_Int32 n = GetRealCellPos().Row - maTables.back().GetRow() - 1; + for (sal_Int32 j = 0; j <= n; ++j) + { + table::CellRangeAddress aTempCellAddress; + if (IsMerged(xCurrentCellRange, nCol - 1, j, aCellAddress)) + { + //unmerge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(false); + aTempCellAddress = aCellAddress; + aTempCellAddress.StartColumn = aTempCellAddress.EndColumn + 1; + aTempCellAddress.EndColumn = aTempCellAddress.StartColumn; + } + else + { + aTempCellAddress = aCellAddress; + aTempCellAddress.StartColumn += 1; + aTempCellAddress.EndColumn = aTempCellAddress.StartColumn; + } + + //insert Cell + sheet::CellInsertMode aCellInsertMode(sheet::CellInsertMode_RIGHT); + uno::Reference <sheet::XCellRangeMovement> xCellRangeMovement (xCurrentSheet, uno::UNO_QUERY); + xCellRangeMovement->insertCells(aTempCellAddress, aCellInsertMode); + + //merge + uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, + aCellAddress.EndColumn + 1, aCellAddress.EndRow), uno::UNO_QUERY); + if (xMergeable.is()) + xMergeable->merge(sal_True); + j += aCellAddress.EndRow - aCellAddress.StartRow; + } + rImport.GetStylesImportHelper()->InsertCol(nCol, nCurrentSheet, rImport.GetDocument()); + } +} + +void ScMyTables::NewColumn(sal_Bool bIsCovered) +{ + if (bIsCovered) + return; + + ScMyTableData& rLastTab = maTables.back(); + sal_Int32 nColCount = rLastTab.GetColCount(); + sal_Int32 nSpannedCols = rLastTab.GetSpannedCols(); + if ( (nSpannedCols > nColCount) && + (rLastTab.GetRow() == 0) && + (rLastTab.GetColumn() == 0) ) + { + if (nColCount > 0) + { + sal_Int32 FirstColsSpanned(nSpannedCols / nColCount); + sal_Int32 LastColSpanned(FirstColsSpanned + + (nSpannedCols % nColCount)); + for (sal_Int32 i = 0; i < nColCount - 1; ++i) + { + rLastTab.SetColsPerCol(i, FirstColsSpanned); + rLastTab.SetRealCols(i + 1, rLastTab.GetRealCols(i) + FirstColsSpanned); + } + rLastTab.SetColsPerCol(nColCount - 1, LastColSpanned); + rLastTab.SetRealCols( + nColCount, rLastTab.GetRealCols(nColCount - 1) + LastColSpanned); + } + } + if (rLastTab.GetRealCols(rLastTab.GetColumn()) > nSpannedCols - 1) + { + if (rLastTab.GetRow() == 0) + { + InsertColumn(); + size_t n = maTables.size(); + for (size_t i = n - 1; i > 0; --i) + { + sal_Int32 nColPos = + maTables[i-1].GetColumn() + maTables[i].GetSpannedCols() - 1; + + maTables[i-1].SetColsPerCol(nColPos, + maTables[i-1].GetColsPerCol(nColPos) + + rLastTab.GetColsPerCol(rLastTab.GetColumn())); + + maTables[i-1].SetRealCols( + nColPos + 1, + maTables[i-1].GetRealCols(nColPos) + maTables[i-1].GetColsPerCol(nColPos)); + + maTables[i-1].SetChangedCols(nColPos); + } + } + } +} + +void ScMyTables::AddColumn(sal_Bool bIsCovered) +{ + ScMyTableData& rLastTab = maTables.back(); + rLastTab.AddColumn(); + if (rLastTab.GetSubTableSpanned() > 1) + rLastTab.SetSubTableSpanned(rLastTab.GetSubTableSpanned() - 1); + else + { + NewColumn(bIsCovered); + sal_Int32 nCol = rLastTab.GetColumn(); + sal_Int32 nRow = rLastTab.GetRow(); + rLastTab.SetRealCols( + nCol + 1, rLastTab.GetRealCols(nCol) + rLastTab.GetColsPerCol(nCol)); + + if ((!bIsCovered) || (bIsCovered && (rLastTab.GetColsPerCol(nCol) > 1))) + { + if ((rLastTab.GetRowsPerRow(nRow) > 1) || (rLastTab.GetColsPerCol(nCol) > 1)) + DoMerge(); + } + } +} + +void ScMyTables::NewTable(sal_Int32 nTempSpannedCols) +{ + maTables.push_back(new ScMyTableData(nCurrentSheet)); + + if (maTables.size() > 1) + { + ScMyTableData& rFirstTab = maTables.front(); + + const sal_Int32 nCol = rFirstTab.GetColumn(); + const sal_Int32 nColCount = rFirstTab.GetColCount(); + const sal_Int32 nColsPerCol = rFirstTab.GetColsPerCol(nCol); + + sal_Int32 nSpannedCols = rFirstTab.GetSpannedCols(); + sal_Int32 nTemp = nSpannedCols - nColCount; + sal_Int32 nTemp2 = nCol - nColCount + 1; + if ((nTemp > 0) && (nTemp2 == 0)) + nTempSpannedCols *= nTemp + 1; + else + if (nColsPerCol > 1) + nTempSpannedCols *= nColsPerCol; + + sal_Int32 nToMerge; + if (nSpannedCols > nColCount) + nToMerge = rFirstTab.GetChangedCols(nCol, nCol + nColsPerCol + nSpannedCols - nColCount); + else + nToMerge = rFirstTab.GetChangedCols(nCol, nCol + nColsPerCol); + if (nToMerge > nCol) + nTempSpannedCols += nToMerge; + } + + ScMyTableData& rNewTab = maTables.back(); + rNewTab.SetSpannedCols(nTempSpannedCols); + + size_t n = maTables.size(); + if (n > 1) + { + maTables[n-2].SetSubTableSpanned(rNewTab.GetSpannedCols()); + UnMerge(); + } +} + +void ScMyTables::UpdateRowHeights() +{ + if (rImport.GetModel().is()) + { + ScXMLImport::MutexGuard aGuard(rImport); + + // update automatic row heights + + // For sheets with any kind of shapes (including notes), + // update row heights immediately (before setting the positions). + // For sheets without shapes, set "pending" flag + // and update row heights when a sheet is shown. + // The current sheet (from view settings) is always updated immediately. + + ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel()); + if (pDoc) + { + SCTAB nCount = pDoc->GetTableCount(); + ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer(); + + SCTAB nVisible = static_cast<SCTAB>( rImport.GetVisibleSheet() ); + + ScMarkData aUpdateSheets; + for (SCTAB nTab=0; nTab<nCount; ++nTab) + { + const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL; + if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) ) + aUpdateSheets.SelectTable( nTab, sal_True ); + else + pDoc->SetPendingRowHeights( nTab, sal_True ); + } + + if (aUpdateSheets.GetSelectCount()) + { + pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results) + ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets); + pDoc->LockStreamValid( false ); + } + } + } +} + +void ScMyTables::DeleteTable() +{ + ScXMLImport::MutexGuard aGuard(rImport); + + nCurrentColStylePos = 0; + if (!maTables.empty()) + maTables.pop_back(); + + if (maTables.empty()) // only set the styles if all subtables are importet and the table is finished + { + rImport.GetStylesImportHelper()->SetStylesToRanges(); + rImport.SetStylesToRangesFinished(); + } + + //#i48793#; has to be set before protection + if (!aMatrixRangeList.empty()) + { + ScMyMatrixRangeList::iterator aItr = aMatrixRangeList.begin(); + ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end(); + while(aItr != aEndItr) + { + SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar); + ++aItr; + } + aMatrixRangeList.clear(); + } + + if (rImport.GetDocument() && maProtectionData.mbProtected) + { + uno::Sequence<sal_Int8> aHash; + SvXMLUnitConverter::decodeBase64(aHash, maProtectionData.maPassword); + + auto_ptr<ScTableProtection> pProtect(new ScTableProtection); + pProtect->setProtected(maProtectionData.mbProtected); + pProtect->setPasswordHash(aHash, maProtectionData.meHash1, maProtectionData.meHash2); + pProtect->setOption(ScTableProtection::SELECT_LOCKED_CELLS, maProtectionData.mbSelectProtectedCells); + pProtect->setOption(ScTableProtection::SELECT_UNLOCKED_CELLS, maProtectionData.mbSelectUnprotectedCells); + rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get()); + } + + //#95582#; find out whether it was possible to set the sheet name + // test it here, because if it is a linked table the name is changed by importing + // the linking informations + uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY ); + if ( xNamed.is() ) + { + rtl::OUString sCurrentName(xNamed->getName()); + if (sCurrentName != sCurrentSheetName && rImport.GetDocument()) + { + rImport.GetDocument()->RenameTab( static_cast<SCTAB>(nCurrentSheet), + sCurrentSheetName, false, sal_True); + } + } +} + +table::CellAddress ScMyTables::GetRealCellPos() +{ + 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()); + } + + aRealCellPos.Row = nRow; + aRealCellPos.Column = nCol; + aRealCellPos.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet); + return aRealCellPos; +} + +void ScMyTables::AddColCount(sal_Int32 nTempColCount) +{ + ScMyTableData& rLastTab = maTables.back(); + rLastTab.SetColCount(rLastTab.GetColCount() + nTempColCount); +} + +void ScMyTables::AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName) +{ + DBG_ASSERT(maTables.size() == 1, "not possible to use default styles on columns in subtables"); + rImport.GetStylesImportHelper()->AddColumnStyle(rCellStyleName, nCurrentColStylePos, nRepeat); + nCurrentColStylePos += nRepeat; +} + +uno::Reference< drawing::XDrawPage > ScMyTables::GetCurrentXDrawPage() +{ + if( (nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is() ) + { + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier( xCurrentSheet, uno::UNO_QUERY ); + if( xDrawPageSupplier.is() ) + xDrawPage.set(xDrawPageSupplier->getDrawPage()); + nCurrentDrawPage = sal::static_int_cast<sal_Int16>(nCurrentSheet); + } + return xDrawPage; +} + +uno::Reference< drawing::XShapes > ScMyTables::GetCurrentXShapes() +{ + if( (nCurrentSheet != nCurrentXShapes) || !xShapes.is() ) + { + xShapes.set(GetCurrentXDrawPage(), uno::UNO_QUERY); + rImport.GetShapeImport()->startPage(xShapes); + rImport.GetShapeImport()->pushGroupForSorting ( xShapes ); + nCurrentXShapes = sal::static_int_cast<sal_Int16>(nCurrentSheet); + return xShapes; + } + else + return xShapes; +} + +sal_Bool ScMyTables::HasDrawPage() +{ + return !((nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is()); +} + +sal_Bool ScMyTables::HasXShapes() +{ + return !((nCurrentSheet != nCurrentXShapes) || !xShapes.is()); +} + +void ScMyTables::AddOLE(uno::Reference <drawing::XShape>& rShape, + const rtl::OUString &rRangeList) +{ + aFixupOLEs.AddOLE(rShape, rRangeList); +} + +void ScMyTables::AddMatrixRange( + sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow, + const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar) +{ + DBG_ASSERT(nEndRow >= nStartRow, "wrong row order"); + DBG_ASSERT(nEndColumn >= nStartColumn, "wrong column order"); + table::CellRangeAddress aRange; + aRange.StartColumn = nStartColumn; + aRange.StartRow = nStartRow; + aRange.EndColumn = nEndColumn; + aRange.EndRow = nEndRow; + aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet); + ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar); + aMatrixRangeList.push_back(aMRange); +} + +sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow) +{ + sal_Bool bResult(false); + if (!aMatrixRangeList.empty()) + { + ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin()); + ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end()); + sal_Bool bReady(false); + while(!bReady && aItr != aEndItr) + { + if (nCurrentSheet > aItr->aRange.Sheet) + { + OSL_FAIL("should never hapen, because the list should be cleared in DeleteTable"); + aItr = aMatrixRangeList.erase(aItr); + } + else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn)) + { + SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar); + aItr = aMatrixRangeList.erase(aItr); + } + else if (nColumn < aItr->aRange.StartColumn) + bReady = sal_True; + else if (nColumn >= aItr->aRange.StartColumn && nColumn <= aItr->aRange.EndColumn && nRow >= aItr->aRange.StartRow && nRow <= aItr->aRange.EndRow) + { + bReady = sal_True; + bResult = sal_True; + } + else + ++aItr; + } + } + return bResult; +} + +void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula, + const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar) +{ + uno::Reference <table::XCellRange> xMatrixCellRange( + GetCurrentXCellRange()->getCellRangeByPosition(rRange.StartColumn, rRange.StartRow, + rRange.EndColumn, rRange.EndRow)); + if (xMatrixCellRange.is()) + { + uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange(xMatrixCellRange, uno::UNO_QUERY); + if (xArrayFormulaRange.is()) + { + ScCellRangeObj* pCellRangeObj = + static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation( + xMatrixCellRange)); + if (pCellRangeObj) + pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar); + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |