| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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); |
| } |
| |
| /*******************************************************************************************************************************/ |
| |
| ScMyTables::ScMyTables(ScXMLImport& rTempImport) |
| : rImport(rTempImport), |
| aResizeShapes(rTempImport), |
| nCurrentColStylePos(0), |
| nCurrentDrawPage( -1 ), |
| nCurrentXShapes( -1 ), |
| nTableCount( 0 ), |
| nCurrentSheet( -1 ) |
| { |
| aTableVec.resize(nDefaultTabCount, NULL); |
| } |
| |
| ScMyTables::~ScMyTables() |
| { |
| ScMyTableData* pTable; |
| while (nTableCount > 0) |
| { |
| pTable = aTableVec[nTableCount - 1]; |
| delete pTable; |
| aTableVec[nTableCount - 1] = NULL; |
| --nTableCount; |
| } |
| } |
| |
| void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName, |
| const sal_Bool bTempProtection, const rtl::OUString& sTempPassword) |
| { |
| if (rImport.GetModel().is()) |
| { |
| nCurrentColStylePos = 0; |
| sCurrentSheetName = sTableName; |
| ScMyTableData* aTable; |
| while (nTableCount > 0) |
| { |
| aTable = aTableVec[nTableCount - 1]; |
| delete aTable; |
| aTableVec[nTableCount - 1] = NULL; |
| --nTableCount; |
| } |
| ++nCurrentSheet; |
| |
| bProtection = bTempProtection; |
| sPassword = sTempPassword; |
| 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) |
| { |
| rImport.LockSolarMutex(); |
| String sTabName(String::CreateFromAscii("Table")); |
| pDoc->CreateValidTabName(sTabName); |
| rtl::OUString sOUTabName(sTabName); |
| xSheets->insertNewByName(sOUTabName, sal::static_int_cast<sal_Int16>(nCurrentSheet)); |
| rImport.UnlockSolarMutex(); |
| } |
| } |
| } |
| 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) |
| { |
| rImport.LockSolarMutex(); |
| String sTabName(String::CreateFromAscii("Table")); |
| pDoc->CreateValidTabName(sTabName); |
| rtl::OUString sOUTabName(sTabName); |
| xNamed->setName(sOUTabName); |
| rImport.UnlockSolarMutex(); |
| } |
| } |
| } |
| 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 sal_False; |
| else |
| return sal_True; |
| } |
| } |
| } |
| return sal_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(sal_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(sal_False); |
| } |
| |
| //merge |
| uno::Reference <table::XCellRange> xMergeCellRange; |
| if (nCount == -1) |
| xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow, |
| aCellAddress.EndColumn |
| + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) - 1, |
| aCellAddress.EndRow |
| + aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->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); |
| for (sal_Int32 j = 0; j < GetRealCellPos().Column - aTableVec[nTableCount - 1]->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(sal_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() |
| { |
| if (nTableCount > 1) |
| if (aTableVec[nTableCount - 1]->GetRealRows(aTableVec[nTableCount - 1]->GetRow()) > |
| aTableVec[nTableCount - 2]->GetRowsPerRow(aTableVec[nTableCount - 2]->GetRow()) - 1) |
| { |
| if (GetRealCellPos().Column > 0) |
| InsertRow(); |
| for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--) |
| { |
| sal_Int32 nRow = aTableVec[i - 1]->GetRow(); |
| aTableVec[i - 1]->SetRowsPerRow(nRow, |
| aTableVec[i - 1]->GetRowsPerRow(nRow) + 1); |
| aTableVec[i - 1]->SetRealRows(nRow + 1, |
| aTableVec[i - 1]->GetRealRows(nRow) |
| + aTableVec[i - 1]->GetRowsPerRow(nRow)); |
| } |
| } |
| } |
| |
| void ScMyTables::AddRow() |
| { |
| aTableVec[nTableCount - 1]->AddRow(); |
| aTableVec[nTableCount - 1]->SetFirstColumn(); |
| sal_Int32 nRow = aTableVec[nTableCount - 1]->GetRow(); |
| if (nRow > 0) |
| NewRow(); |
| aTableVec[nTableCount - 1]->SetRealRows(nRow + 1, |
| aTableVec[nTableCount - 1]->GetRealRows(nRow) |
| + aTableVec[nTableCount - 1]->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); |
| for (sal_Int32 j = 0; j <= GetRealCellPos().Row - aTableVec[nTableCount - 1]->GetRow() - 1; ++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(sal_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) |
| { |
| sal_Int32 nColCount(aTableVec[nTableCount - 1]->GetColCount()); |
| sal_Int32 nSpannedCols(aTableVec[nTableCount - 1]->GetSpannedCols()); |
| if ( (nSpannedCols > nColCount) && |
| (aTableVec[nTableCount - 1]->GetRow() == 0) && |
| (aTableVec[nTableCount - 1]->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) |
| { |
| aTableVec[nTableCount - 1]->SetColsPerCol(i, FirstColsSpanned); |
| aTableVec[nTableCount - 1]->SetRealCols(i + 1, |
| aTableVec[nTableCount - 1]->GetRealCols(i) |
| + FirstColsSpanned); |
| } |
| aTableVec[nTableCount - 1]->SetColsPerCol(nColCount - 1, LastColSpanned); |
| aTableVec[nTableCount - 1]->SetRealCols(nColCount - 1 + 1, |
| aTableVec[nTableCount - 1]->GetRealCols(nColCount - 1) |
| + LastColSpanned); |
| } |
| } |
| if (aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn()) > nSpannedCols - 1) |
| { |
| if ( aTableVec[nTableCount - 1]->GetRow() == 0) |
| { |
| InsertColumn(); |
| for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--) |
| { |
| sal_Int32 nColPos = aTableVec[i - 1]->GetColumn() + |
| aTableVec[i]->GetSpannedCols() - 1; |
| aTableVec[i - 1]->SetColsPerCol(nColPos, |
| aTableVec[i - 1]->GetColsPerCol(nColPos) + |
| aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn())); |
| aTableVec[i - 1]->SetRealCols(nColPos + 1, |
| aTableVec[i - 1]->GetRealCols(nColPos) |
| + aTableVec[i - 1]->GetColsPerCol(nColPos)); |
| aTableVec[i - 1]->SetChangedCols(nColPos); |
| } |
| } |
| } |
| } |
| } |
| |
| void ScMyTables::AddColumn(sal_Bool bIsCovered) |
| { |
| aTableVec[nTableCount - 1]->AddColumn(); |
| if (aTableVec[nTableCount - 1]->GetSubTableSpanned() > 1) |
| aTableVec[nTableCount - 1]->SetSubTableSpanned(aTableVec[nTableCount - 1]->GetSubTableSpanned() - 1); |
| else |
| { |
| NewColumn(bIsCovered); |
| // if (!bIsCovered) |
| aTableVec[nTableCount - 1]->SetRealCols(aTableVec[nTableCount - 1]->GetColumn() + 1, |
| aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn()) |
| + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn())); |
| if ((!bIsCovered) || (bIsCovered && |
| (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1))) |
| { |
| if ((aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) > 1) || |
| (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1)) |
| DoMerge(); |
| } |
| } |
| } |
| |
| void ScMyTables::NewTable(sal_Int32 nTempSpannedCols) |
| { |
| ++nTableCount; |
| if (static_cast<sal_uInt32>(nTableCount) >= aTableVec.size()) |
| aTableVec.resize(aTableVec.size() + nDefaultTabCount); |
| ScMyTableData* aTable(new ScMyTableData(nCurrentSheet)); |
| if (nTableCount > 1) |
| { |
| ScMyTableData* pTableData = aTableVec[nTableCount - 2]; |
| const sal_Int32 nCol(pTableData->GetColumn()); |
| const sal_Int32 nColCount(pTableData->GetColCount()); |
| const sal_Int32 nColsPerCol(pTableData->GetColsPerCol(nCol)); |
| sal_Int32 nSpannedCols(pTableData->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 = pTableData->GetChangedCols(nCol, nCol + nColsPerCol + nSpannedCols - nColCount); |
| else |
| nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol); |
| if (nToMerge > nCol) |
| nTempSpannedCols += nToMerge; |
| } |
| aTable->SetSpannedCols(nTempSpannedCols); |
| aTableVec[nTableCount - 1] = aTable; |
| if (nTableCount > 1) |
| { |
| aTableVec[nTableCount - 2]->SetSubTableSpanned(aTable->GetSpannedCols()); |
| UnMerge(); |
| } |
| } |
| |
| void ScMyTables::UpdateRowHeights() |
| { |
| if (rImport.GetModel().is()) |
| { |
| rImport.LockSolarMutex(); |
| // 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) |
| // #i114839# make sure the output factor is valid for UpdateAllRowHeights |
| ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets, true); |
| pDoc->LockStreamValid( false ); |
| } |
| } |
| |
| rImport.UnlockSolarMutex(); |
| } |
| } |
| |
| void ScMyTables::DeleteTable() |
| { |
| rImport.LockSolarMutex(); |
| |
| nCurrentColStylePos = 0; |
| if (nTableCount > 0) |
| { |
| ScMyTableData* aTable = aTableVec[nTableCount - 1]; |
| delete aTable; |
| aTableVec[nTableCount - 1] = NULL; |
| nTableCount--; |
| } |
| if (nTableCount == 0) // 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() && bProtection) |
| { |
| uno::Sequence<sal_Int8> aPass; |
| SvXMLUnitConverter::decodeBase64(aPass, sPassword); |
| auto_ptr<ScTableProtection> pProtect(new ScTableProtection); |
| pProtect->setProtected(bProtection); |
| pProtect->setPasswordHash(aPass, PASSHASH_OOO); |
| rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get()); |
| } |
| |
| rImport.UnlockSolarMutex(); |
| |
| //#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, sal_False, sal_True); |
| |
| /* rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Could not create a table with the name ")); |
| sErrorMessage += sCurrentSheetName; |
| sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(". The new name is ")); |
| sErrorMessage += sCurrentName; |
| uno::Sequence<rtl::OUString> aSeq(1); |
| aSeq[0] = sErrorMessage; |
| uno::Reference<xml::sax::XLocator> xLocator; |
| rImport.SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rtl::OUString(), xLocator);*/ |
| } |
| } |
| } |
| |
| table::CellAddress ScMyTables::GetRealCellPos() |
| { |
| sal_Int32 nRow(0); |
| sal_Int32 nCol(0); |
| for (sal_Int32 i = 0; i < nTableCount; ++i) |
| { |
| ScMyTableData* pTableData = aTableVec[i]; |
| nCol += pTableData->GetRealCols(pTableData->GetColumn()); |
| nRow += pTableData->GetRealRows(pTableData->GetRow()); |
| } |
| aRealCellPos.Row = nRow; |
| aRealCellPos.Column = nCol; |
| aRealCellPos.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet); |
| return aRealCellPos; |
| } |
| |
| void ScMyTables::AddColCount(sal_Int32 nTempColCount) |
| { |
| aTableVec[nTableCount - 1]->SetColCount(aTableVec[nTableCount - 1]->GetColCount() + nTempColCount); |
| } |
| |
| void ScMyTables::AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName) |
| { |
| DBG_ASSERT(nTableCount == 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::AddShape(uno::Reference <drawing::XShape>& rShape, |
| rtl::OUString* pRangeList, |
| table::CellAddress& rStartAddress, table::CellAddress& rEndAddress, |
| sal_Int32 nEndX, sal_Int32 nEndY) |
| { |
| aResizeShapes.AddShape(rShape, pRangeList, rStartAddress, rEndAddress, nEndX, nEndY); |
| } |
| |
| 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(sal_False); |
| if (!aMatrixRangeList.empty()) |
| { |
| ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin()); |
| ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end()); |
| sal_Bool bReady(sal_False); |
| while(!bReady && aItr != aEndItr) |
| { |
| if (nCurrentSheet > aItr->aRange.Sheet) |
| { |
| DBG_ERROR("should never happen, 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); |
| } |
| } |
| } |