summaryrefslogtreecommitdiff
path: root/sc/source/filter/xml/xmlsubti.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/xml/xmlsubti.cxx')
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx831
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: */