Update ooo320-m1
[ooovba.git] / sc / source / filter / xml / xmlsubti.cxx
blob1e368595e28cc8224a52a5ebb1170a932608c63f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmlsubti.cxx,v $
10 * $Revision: 1.50.30.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
35 // INCLUDE ---------------------------------------------------------------
36 #include "xmlsubti.hxx"
37 #include "global.hxx"
38 #include "xmlstyli.hxx"
39 #include "xmlimprt.hxx"
40 #include "document.hxx"
41 #include "markdata.hxx"
42 #include "XMLConverter.hxx"
43 #include "docuno.hxx"
44 #include "cellsuno.hxx"
45 #include "XMLStylesImportHelper.hxx"
46 #include "sheetdata.hxx"
47 #include "tabprotection.hxx"
48 #include <svx/svdpage.hxx>
50 #include <xmloff/xmltkmap.hxx>
51 #include <xmloff/nmspmap.hxx>
52 #include <xmloff/xmluconv.hxx>
53 #include <xmloff/xmlerror.hxx>
54 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
55 #include <com/sun/star/util/XMergeable.hpp>
56 #include <com/sun/star/sheet/XSheetCellRange.hpp>
57 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
58 #include <com/sun/star/sheet/CellInsertMode.hpp>
59 #include <com/sun/star/sheet/XCellRangeMovement.hpp>
60 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
61 #include <com/sun/star/container/XNamed.hpp>
62 #include <com/sun/star/util/XProtectable.hpp>
63 #include <com/sun/star/sheet/XArrayFormulaRange.hpp>
65 #include <memory>
67 using ::std::auto_ptr;
69 //------------------------------------------------------------------
71 using namespace com::sun::star;
73 ScMyTableData::ScMyTableData(sal_Int32 nSheet, sal_Int32 nCol, sal_Int32 nRow)
74 : nColsPerCol(nDefaultColCount, 1),
75 nRealCols(nDefaultColCount + 1, 0),
76 nRowsPerRow(nDefaultRowCount, 1),
77 nRealRows(nDefaultRowCount + 1, 0),
78 nChangedCols()
80 aTableCellPos.Sheet = sal::static_int_cast<sal_Int16>( nSheet );
81 aTableCellPos.Column = nCol;
82 aTableCellPos.Row = nRow;
84 for (sal_Int32 i = 0; i < 3; ++i)
85 nRealCols[i] = i;
86 for (sal_Int32 j = 0; j < 3; ++j)
87 nRealRows[j] = j;
89 nSpannedCols = 1;
90 nColCount = 0;
91 nSubTableSpanned = 1;
94 ScMyTableData::~ScMyTableData()
98 void ScMyTableData::AddRow()
100 ++aTableCellPos.Row;
101 if (static_cast<sal_uInt32>(aTableCellPos.Row) >= nRowsPerRow.size())
103 nRowsPerRow.resize(nRowsPerRow.size() + nDefaultRowCount, 1);
104 nRealRows.resize(nRowsPerRow.size() + nDefaultRowCount + 1, 0);
106 nRealRows[aTableCellPos.Row + 1] = nRealRows[aTableCellPos.Row] + nRowsPerRow[aTableCellPos.Row];
109 void ScMyTableData::AddColumn()
111 ++aTableCellPos.Column;
112 if (static_cast<sal_uInt32>(aTableCellPos.Column) >= nColsPerCol.size())
114 nColsPerCol.resize(nColsPerCol.size() + nDefaultColCount, 1);
115 nRealCols.resize(nColsPerCol.size() + nDefaultColCount + 1, 0);
117 nRealCols[aTableCellPos.Column + 1] = nRealCols[aTableCellPos.Column] + nColsPerCol[aTableCellPos.Column];
120 sal_Int32 ScMyTableData::GetRealCols(const sal_Int32 nIndex, const sal_Bool /* bIsNormal */) const
122 return (nIndex < 0) ? 0 : nRealCols[nIndex];
125 sal_Int32 ScMyTableData::GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const
127 ScMysalIntList::const_iterator i(nChangedCols.begin());
128 ScMysalIntList::const_iterator endi(nChangedCols.end());
129 while ((i != endi) && ((*i < nToIndex) && !(*i >= nFromIndex)))
130 ++i;
131 if (i == endi)
132 return -1;
133 else
134 if ((*i >= nFromIndex) && (*i < nToIndex))
135 return *i;
136 else
137 return -1;
140 void ScMyTableData::SetChangedCols(const sal_Int32 nValue)
142 ScMysalIntList::iterator i(nChangedCols.begin());
143 ScMysalIntList::iterator endi(nChangedCols.end());
144 while ((i != endi) && (*i < nValue))
146 ++i;
148 if ((i == endi) || (*i != nValue))
149 nChangedCols.insert(i, nValue);
152 /*******************************************************************************************************************************/
154 ScXMLTabProtectionData::ScXMLTabProtectionData() :
155 meHash1(PASSHASH_SHA1),
156 meHash2(PASSHASH_UNSPECIFIED),
157 mbProtected(false),
158 mbSelectProtectedCells(true),
159 mbSelectUnprotectedCells(true)
163 ScMyTables::ScMyTables(ScXMLImport& rTempImport)
164 : rImport(rTempImport),
165 aResizeShapes(rTempImport),
166 nCurrentColStylePos(0),
167 nCurrentDrawPage( -1 ),
168 nCurrentXShapes( -1 ),
169 nTableCount( 0 ),
170 nCurrentSheet( -1 )
172 aTableVec.resize(nDefaultTabCount, NULL);
175 ScMyTables::~ScMyTables()
177 ScMyTableData* pTable;
178 while (nTableCount > 0)
180 pTable = aTableVec[nTableCount - 1];
181 delete pTable;
182 aTableVec[nTableCount - 1] = NULL;
183 --nTableCount;
187 void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName,
188 const ScXMLTabProtectionData& rProtectData)
190 if (rImport.GetModel().is())
192 nCurrentColStylePos = 0;
193 sCurrentSheetName = sTableName;
194 ScMyTableData* aTable;
195 while (nTableCount > 0)
197 aTable = aTableVec[nTableCount - 1];
198 delete aTable;
199 aTableVec[nTableCount - 1] = NULL;
200 --nTableCount;
202 ++nCurrentSheet;
204 maProtectionData = rProtectData;
205 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY );
206 if ( xSpreadDoc.is() )
208 uno::Reference <sheet::XSpreadsheets> xSheets(xSpreadDoc->getSheets());
209 if (xSheets.is())
211 if (nCurrentSheet > 0)
215 xSheets->insertNewByName(sTableName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
217 catch ( uno::RuntimeException& )
219 ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
220 if (pDoc)
222 rImport.LockSolarMutex();
223 String sTabName(String::CreateFromAscii("Table"));
224 pDoc->CreateValidTabName(sTabName);
225 rtl::OUString sOUTabName(sTabName);
226 xSheets->insertNewByName(sOUTabName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
227 rImport.UnlockSolarMutex();
231 uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
232 if ( xIndex.is() )
234 xCurrentSheet.set(xIndex->getByIndex(nCurrentSheet), uno::UNO_QUERY);
235 if ( xCurrentSheet.is() )
237 xCurrentCellRange.set(xCurrentSheet, uno::UNO_QUERY);
238 if (!(nCurrentSheet > 0))
240 uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
241 if ( xNamed.is() )
244 xNamed->setName(sTableName);
246 catch ( uno::RuntimeException& )
248 ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
249 if (pDoc)
251 rImport.LockSolarMutex();
252 String sTabName(String::CreateFromAscii("Table"));
253 pDoc->CreateValidTabName(sTabName);
254 rtl::OUString sOUTabName(sTabName);
255 xNamed->setName(sOUTabName);
256 rImport.UnlockSolarMutex();
260 rImport.SetTableStyle(sStyleName);
262 if ( sStyleName.getLength() )
264 // #i57869# All table style properties for all sheets are now applied here,
265 // before importing the contents.
266 // This is needed for the background color.
267 // Sheet visibility has special handling in ScDocFunc::SetTableVisible to
268 // allow hiding the first sheet.
269 // RTL layout is only remembered, not actually applied, so the shapes can
270 // be loaded before mirroring.
272 uno::Reference <beans::XPropertySet> xProperties(xCurrentSheet, uno::UNO_QUERY);
273 if (xProperties.is())
275 XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rImport.GetAutoStyles();
276 if (pStyles)
278 XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
279 XML_STYLE_FAMILY_TABLE_TABLE, sStyleName, sal_True);
280 if (pStyle)
282 pStyle->FillPropertySet(xProperties);
284 ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rImport.GetModel())->GetSheetSaveData();
285 pSheetData->AddTableStyle( sStyleName, ScAddress( 0, 0, (SCTAB)nCurrentSheet ) );
297 NewTable(1);
300 sal_Bool ScMyTables::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow,
301 table::CellRangeAddress& aCellAddress) const
303 uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
304 if (xMergeable.is())
306 uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xMergeable, uno::UNO_QUERY);
307 uno::Reference<sheet::XSpreadsheet> xTable(xMergeSheetCellRange->getSpreadsheet());
308 uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor(xTable->createCursorByRange(xMergeSheetCellRange));
309 if (xMergeSheetCursor.is())
311 xMergeSheetCursor->collapseToMergedArea();
312 uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY);
313 if (xMergeCellAddress.is())
315 aCellAddress = xMergeCellAddress->getRangeAddress();
316 if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol &&
317 aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow)
318 return sal_False;
319 else
320 return sal_True;
324 return sal_False;
327 void ScMyTables::UnMerge()
329 if ( xCurrentCellRange.is() )
331 table::CellRangeAddress aCellAddress;
332 if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
334 //unmerge
335 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
336 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
337 if (xMergeable.is())
338 xMergeable->merge(sal_False);
343 void ScMyTables::DoMerge(sal_Int32 nCount)
345 if ( xCurrentCellRange.is() )
347 table::CellRangeAddress aCellAddress;
348 if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
350 //unmerge
351 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
352 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
353 if (xMergeable.is())
354 xMergeable->merge(sal_False);
357 //merge
358 uno::Reference <table::XCellRange> xMergeCellRange;
359 if (nCount == -1)
360 xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
361 aCellAddress.EndColumn
362 + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) - 1,
363 aCellAddress.EndRow
364 + aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) - 1));
365 else
366 xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
367 aCellAddress.StartColumn
368 + nCount - 1,
369 aCellAddress.EndRow));
370 uno::Reference <util::XMergeable> xMergeable (xMergeCellRange, uno::UNO_QUERY);
371 if (xMergeable.is())
372 xMergeable->merge(sal_True);
376 void ScMyTables::InsertRow()
378 if ( xCurrentCellRange.is() )
380 table::CellRangeAddress aCellAddress;
381 sal_Int32 nRow(GetRealCellPos().Row);
382 for (sal_Int32 j = 0; j < GetRealCellPos().Column - aTableVec[nTableCount - 1]->GetColumn() - 1; ++j)
384 if (IsMerged(xCurrentCellRange, j, nRow - 1, aCellAddress))
386 //unmerge
387 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
388 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
389 if (xMergeable.is())
390 xMergeable->merge(sal_False);
393 //merge
394 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
395 aCellAddress.EndColumn, aCellAddress.EndRow + 1), uno::UNO_QUERY);
396 if (xMergeable.is())
397 xMergeable->merge(sal_True);
398 j += aCellAddress.EndColumn - aCellAddress.StartColumn;
400 rImport.GetStylesImportHelper()->InsertRow(nRow, nCurrentSheet, rImport.GetDocument());
404 void ScMyTables::NewRow()
406 if (nTableCount > 1)
407 if (aTableVec[nTableCount - 1]->GetRealRows(aTableVec[nTableCount - 1]->GetRow()) >
408 aTableVec[nTableCount - 2]->GetRowsPerRow(aTableVec[nTableCount - 2]->GetRow()) - 1)
410 if (GetRealCellPos().Column > 0)
411 InsertRow();
412 for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--)
414 sal_Int32 nRow = aTableVec[i - 1]->GetRow();
415 aTableVec[i - 1]->SetRowsPerRow(nRow,
416 aTableVec[i - 1]->GetRowsPerRow(nRow) + 1);
417 aTableVec[i - 1]->SetRealRows(nRow + 1,
418 aTableVec[i - 1]->GetRealRows(nRow)
419 + aTableVec[i - 1]->GetRowsPerRow(nRow));
424 void ScMyTables::AddRow()
426 aTableVec[nTableCount - 1]->AddRow();
427 aTableVec[nTableCount - 1]->SetFirstColumn();
428 sal_Int32 nRow = aTableVec[nTableCount - 1]->GetRow();
429 if (nRow > 0)
430 NewRow();
431 aTableVec[nTableCount - 1]->SetRealRows(nRow + 1,
432 aTableVec[nTableCount - 1]->GetRealRows(nRow)
433 + aTableVec[nTableCount - 1]->GetRowsPerRow(nRow));
436 void ScMyTables::SetRowStyle(const rtl::OUString& rCellStyleName)
438 rImport.GetStylesImportHelper()->SetRowStyle(rCellStyleName);
441 void ScMyTables::InsertColumn()
443 if ( xCurrentCellRange.is() )
445 table::CellRangeAddress aCellAddress;
446 sal_Int32 nCol(GetRealCellPos().Column);
447 for (sal_Int32 j = 0; j <= GetRealCellPos().Row - aTableVec[nTableCount - 1]->GetRow() - 1; ++j)
449 table::CellRangeAddress aTempCellAddress;
450 if (IsMerged(xCurrentCellRange, nCol - 1, j, aCellAddress))
452 //unmerge
453 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
454 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
455 if (xMergeable.is())
456 xMergeable->merge(sal_False);
457 aTempCellAddress = aCellAddress;
458 aTempCellAddress.StartColumn = aTempCellAddress.EndColumn + 1;
459 aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
461 else
463 aTempCellAddress = aCellAddress;
464 aTempCellAddress.StartColumn += 1;
465 aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
468 //insert Cell
469 sheet::CellInsertMode aCellInsertMode(sheet::CellInsertMode_RIGHT);
470 uno::Reference <sheet::XCellRangeMovement> xCellRangeMovement (xCurrentSheet, uno::UNO_QUERY);
471 xCellRangeMovement->insertCells(aTempCellAddress, aCellInsertMode);
473 //merge
474 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
475 aCellAddress.EndColumn + 1, aCellAddress.EndRow), uno::UNO_QUERY);
476 if (xMergeable.is())
477 xMergeable->merge(sal_True);
478 j += aCellAddress.EndRow - aCellAddress.StartRow;
480 rImport.GetStylesImportHelper()->InsertCol(nCol, nCurrentSheet, rImport.GetDocument());
484 void ScMyTables::NewColumn(sal_Bool bIsCovered)
486 if (!bIsCovered)
488 sal_Int32 nColCount(aTableVec[nTableCount - 1]->GetColCount());
489 sal_Int32 nSpannedCols(aTableVec[nTableCount - 1]->GetSpannedCols());
490 if ( (nSpannedCols > nColCount) &&
491 (aTableVec[nTableCount - 1]->GetRow() == 0) &&
492 (aTableVec[nTableCount - 1]->GetColumn() == 0) )
494 if (nColCount > 0)
496 sal_Int32 FirstColsSpanned(nSpannedCols / nColCount);
497 sal_Int32 LastColSpanned(FirstColsSpanned
498 + (nSpannedCols % nColCount));
499 for (sal_Int32 i = 0; i < nColCount - 1; ++i)
501 aTableVec[nTableCount - 1]->SetColsPerCol(i, FirstColsSpanned);
502 aTableVec[nTableCount - 1]->SetRealCols(i + 1,
503 aTableVec[nTableCount - 1]->GetRealCols(i)
504 + FirstColsSpanned);
506 aTableVec[nTableCount - 1]->SetColsPerCol(nColCount - 1, LastColSpanned);
507 aTableVec[nTableCount - 1]->SetRealCols(nColCount - 1 + 1,
508 aTableVec[nTableCount - 1]->GetRealCols(nColCount - 1)
509 + LastColSpanned);
512 if (aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn()) > nSpannedCols - 1)
514 if ( aTableVec[nTableCount - 1]->GetRow() == 0)
516 InsertColumn();
517 for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--)
519 sal_Int32 nColPos = aTableVec[i - 1]->GetColumn() +
520 aTableVec[i]->GetSpannedCols() - 1;
521 aTableVec[i - 1]->SetColsPerCol(nColPos,
522 aTableVec[i - 1]->GetColsPerCol(nColPos) +
523 aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()));
524 aTableVec[i - 1]->SetRealCols(nColPos + 1,
525 aTableVec[i - 1]->GetRealCols(nColPos)
526 + aTableVec[i - 1]->GetColsPerCol(nColPos));
527 aTableVec[i - 1]->SetChangedCols(nColPos);
534 void ScMyTables::AddColumn(sal_Bool bIsCovered)
536 aTableVec[nTableCount - 1]->AddColumn();
537 if (aTableVec[nTableCount - 1]->GetSubTableSpanned() > 1)
538 aTableVec[nTableCount - 1]->SetSubTableSpanned(aTableVec[nTableCount - 1]->GetSubTableSpanned() - 1);
539 else
541 NewColumn(bIsCovered);
542 // if (!bIsCovered)
543 aTableVec[nTableCount - 1]->SetRealCols(aTableVec[nTableCount - 1]->GetColumn() + 1,
544 aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn())
545 + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()));
546 if ((!bIsCovered) || (bIsCovered &&
547 (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1)))
549 if ((aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) > 1) ||
550 (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1))
551 DoMerge();
556 void ScMyTables::NewTable(sal_Int32 nTempSpannedCols)
558 ++nTableCount;
559 if (static_cast<sal_uInt32>(nTableCount) >= aTableVec.size())
560 aTableVec.resize(aTableVec.size() + nDefaultTabCount);
561 ScMyTableData* aTable(new ScMyTableData(nCurrentSheet));
562 if (nTableCount > 1)
564 ScMyTableData* pTableData = aTableVec[nTableCount - 2];
565 const sal_Int32 nCol(pTableData->GetColumn());
566 const sal_Int32 nColCount(pTableData->GetColCount());
567 const sal_Int32 nColsPerCol(pTableData->GetColsPerCol(nCol));
568 sal_Int32 nSpannedCols(pTableData->GetSpannedCols());
569 sal_Int32 nTemp(nSpannedCols - nColCount);
570 sal_Int32 nTemp2(nCol - (nColCount - 1));
571 if ((nTemp > 0) && (nTemp2 == 0))
572 nTempSpannedCols *= (nTemp + 1);
573 else
574 if (nColsPerCol > 1)
575 nTempSpannedCols *= nColsPerCol;
577 sal_Int32 nToMerge;
578 if (nSpannedCols > nColCount)
579 nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol + nSpannedCols - nColCount);
580 else
581 nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol);
582 if (nToMerge > nCol)
583 nTempSpannedCols += nToMerge;
585 aTable->SetSpannedCols(nTempSpannedCols);
586 aTableVec[nTableCount - 1] = aTable;
587 if (nTableCount > 1)
589 aTableVec[nTableCount - 2]->SetSubTableSpanned(aTable->GetSpannedCols());
590 UnMerge();
594 void ScMyTables::UpdateRowHeights()
596 if (rImport.GetModel().is())
598 rImport.LockSolarMutex();
599 // update automatic row heights
601 // For sheets with any kind of shapes (including notes),
602 // update row heights immediately (before setting the positions).
603 // For sheets without shapes, set "pending" flag
604 // and update row heights when a sheet is shown.
605 // The current sheet (from view settings) is always updated immediately.
607 ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
608 if (pDoc)
610 SCTAB nCount = pDoc->GetTableCount();
611 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
613 SCTAB nVisible = static_cast<SCTAB>( rImport.GetVisibleSheet() );
615 ScMarkData aUpdateSheets;
616 for (SCTAB nTab=0; nTab<nCount; ++nTab)
618 const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL;
619 if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) )
620 aUpdateSheets.SelectTable( nTab, TRUE );
621 else
622 pDoc->SetPendingRowHeights( nTab, TRUE );
625 if (aUpdateSheets.GetSelectCount())
627 pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results)
628 ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
629 pDoc->LockStreamValid( false );
633 rImport.UnlockSolarMutex();
637 void ScMyTables::DeleteTable()
639 rImport.LockSolarMutex();
641 nCurrentColStylePos = 0;
642 if (nTableCount > 0)
644 ScMyTableData* aTable = aTableVec[nTableCount - 1];
645 delete aTable;
646 aTableVec[nTableCount - 1] = NULL;
647 nTableCount--;
649 if (nTableCount == 0) // only set the styles if all subtables are importet and the table is finished
651 rImport.GetStylesImportHelper()->SetStylesToRanges();
652 rImport.SetStylesToRangesFinished();
655 //#i48793#; has to be set before protection
656 if (!aMatrixRangeList.empty())
658 ScMyMatrixRangeList::iterator aItr = aMatrixRangeList.begin();
659 ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end();
660 while(aItr != aEndItr)
662 SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
663 ++aItr;
665 aMatrixRangeList.clear();
668 if (rImport.GetDocument() && maProtectionData.mbProtected)
670 uno::Sequence<sal_Int8> aHash;
671 SvXMLUnitConverter::decodeBase64(aHash, maProtectionData.maPassword);
673 auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
674 pProtect->setProtected(maProtectionData.mbProtected);
675 pProtect->setPasswordHash(aHash, maProtectionData.meHash1, maProtectionData.meHash2);
676 pProtect->setOption(ScTableProtection::SELECT_LOCKED_CELLS, maProtectionData.mbSelectProtectedCells);
677 pProtect->setOption(ScTableProtection::SELECT_UNLOCKED_CELLS, maProtectionData.mbSelectUnprotectedCells);
678 rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get());
681 rImport.UnlockSolarMutex();
683 //#95582#; find out whether it was possible to set the sheet name
684 // test it here, because if it is a linked table the name is changed by importing
685 // the linking informations
686 uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
687 if ( xNamed.is() )
689 rtl::OUString sCurrentName(xNamed->getName());
690 if (sCurrentName != sCurrentSheetName && rImport.GetDocument())
692 rImport.GetDocument()->RenameTab( static_cast<SCTAB>(nCurrentSheet),
693 sCurrentSheetName, sal_False, sal_True);
695 /* rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Could not create a table with the name "));
696 sErrorMessage += sCurrentSheetName;
697 sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(". The new name is "));
698 sErrorMessage += sCurrentName;
699 uno::Sequence<rtl::OUString> aSeq(1);
700 aSeq[0] = sErrorMessage;
701 uno::Reference<xml::sax::XLocator> xLocator;
702 rImport.SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rtl::OUString(), xLocator);*/
707 table::CellAddress ScMyTables::GetRealCellPos()
709 sal_Int32 nRow(0);
710 sal_Int32 nCol(0);
711 for (sal_Int32 i = 0; i < nTableCount; ++i)
713 ScMyTableData* pTableData = aTableVec[i];
714 nCol += pTableData->GetRealCols(pTableData->GetColumn());
715 nRow += pTableData->GetRealRows(pTableData->GetRow());
717 aRealCellPos.Row = nRow;
718 aRealCellPos.Column = nCol;
719 aRealCellPos.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
720 return aRealCellPos;
723 void ScMyTables::AddColCount(sal_Int32 nTempColCount)
725 aTableVec[nTableCount - 1]->SetColCount(aTableVec[nTableCount - 1]->GetColCount() + nTempColCount);
728 void ScMyTables::AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName)
730 DBG_ASSERT(nTableCount == 1, "not possible to use default styles on columns in subtables");
731 rImport.GetStylesImportHelper()->AddColumnStyle(rCellStyleName, nCurrentColStylePos, nRepeat);
732 nCurrentColStylePos += nRepeat;
735 uno::Reference< drawing::XDrawPage > ScMyTables::GetCurrentXDrawPage()
737 if( (nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is() )
739 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier( xCurrentSheet, uno::UNO_QUERY );
740 if( xDrawPageSupplier.is() )
741 xDrawPage.set(xDrawPageSupplier->getDrawPage());
742 nCurrentDrawPage = sal::static_int_cast<sal_Int16>(nCurrentSheet);
744 return xDrawPage;
747 uno::Reference< drawing::XShapes > ScMyTables::GetCurrentXShapes()
749 if( (nCurrentSheet != nCurrentXShapes) || !xShapes.is() )
751 xShapes.set(GetCurrentXDrawPage(), uno::UNO_QUERY);
752 rImport.GetShapeImport()->startPage(xShapes);
753 rImport.GetShapeImport()->pushGroupForSorting ( xShapes );
754 nCurrentXShapes = sal::static_int_cast<sal_Int16>(nCurrentSheet);
755 return xShapes;
757 else
758 return xShapes;
761 sal_Bool ScMyTables::HasDrawPage()
763 return !((nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is());
766 sal_Bool ScMyTables::HasXShapes()
768 return !((nCurrentSheet != nCurrentXShapes) || !xShapes.is());
771 void ScMyTables::AddShape(uno::Reference <drawing::XShape>& rShape,
772 rtl::OUString* pRangeList,
773 table::CellAddress& rStartAddress, table::CellAddress& rEndAddress,
774 sal_Int32 nEndX, sal_Int32 nEndY)
776 aResizeShapes.AddShape(rShape, pRangeList, rStartAddress, rEndAddress, nEndX, nEndY);
779 void ScMyTables::AddMatrixRange(
780 sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow,
781 const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
783 DBG_ASSERT(nEndRow >= nStartRow, "wrong row order");
784 DBG_ASSERT(nEndColumn >= nStartColumn, "wrong column order");
785 table::CellRangeAddress aRange;
786 aRange.StartColumn = nStartColumn;
787 aRange.StartRow = nStartRow;
788 aRange.EndColumn = nEndColumn;
789 aRange.EndRow = nEndRow;
790 aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
791 ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar);
792 aMatrixRangeList.push_back(aMRange);
795 sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
797 sal_Bool bResult(sal_False);
798 if (!aMatrixRangeList.empty())
800 ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin());
801 ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end());
802 sal_Bool bReady(sal_False);
803 while(!bReady && aItr != aEndItr)
805 if (nCurrentSheet > aItr->aRange.Sheet)
807 DBG_ERROR("should never hapen, because the list should be cleared in DeleteTable");
808 aItr = aMatrixRangeList.erase(aItr);
810 else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn))
812 SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
813 aItr = aMatrixRangeList.erase(aItr);
815 else if (nColumn < aItr->aRange.StartColumn)
816 bReady = sal_True;
817 else if (nColumn >= aItr->aRange.StartColumn && nColumn <= aItr->aRange.EndColumn && nRow >= aItr->aRange.StartRow && nRow <= aItr->aRange.EndRow)
819 bReady = sal_True;
820 bResult = sal_True;
822 else
823 ++aItr;
826 return bResult;
829 void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula,
830 const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
832 uno::Reference <table::XCellRange> xMatrixCellRange(
833 GetCurrentXCellRange()->getCellRangeByPosition(rRange.StartColumn, rRange.StartRow,
834 rRange.EndColumn, rRange.EndRow));
835 if (xMatrixCellRange.is())
837 uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange(xMatrixCellRange, uno::UNO_QUERY);
838 if (xArrayFormulaRange.is())
840 ScCellRangeObj* pCellRangeObj =
841 static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation(
842 xMatrixCellRange));
843 if (pCellRangeObj)
844 pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar);