1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27
28 // INCLUDE ---------------------------------------------------------------
29 #include "xmlsubti.hxx"
30 #include "global.hxx"
31 #include "xmlstyli.hxx"
32 #include "xmlimprt.hxx"
33 #include "document.hxx"
34 #include "markdata.hxx"
35 #include "XMLConverter.hxx"
36 #include "docuno.hxx"
37 #include "cellsuno.hxx"
38 #include "XMLStylesImportHelper.hxx"
39 #include "sheetdata.hxx"
40 #include "tabprotection.hxx"
41 #include <svx/svdpage.hxx>
42
43 #include <xmloff/xmltkmap.hxx>
44 #include <xmloff/nmspmap.hxx>
45 #include <xmloff/xmluconv.hxx>
46 #include <xmloff/xmlerror.hxx>
47 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
48 #include <com/sun/star/util/XMergeable.hpp>
49 #include <com/sun/star/sheet/XSheetCellRange.hpp>
50 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
51 #include <com/sun/star/sheet/CellInsertMode.hpp>
52 #include <com/sun/star/sheet/XCellRangeMovement.hpp>
53 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
54 #include <com/sun/star/container/XNamed.hpp>
55 #include <com/sun/star/util/XProtectable.hpp>
56 #include <com/sun/star/sheet/XArrayFormulaRange.hpp>
57
58 #include <memory>
59
60 using ::std::auto_ptr;
61
62 //------------------------------------------------------------------
63
64 using namespace com::sun::star;
65
ScMyTableData(sal_Int32 nSheet,sal_Int32 nCol,sal_Int32 nRow)66 ScMyTableData::ScMyTableData(sal_Int32 nSheet, sal_Int32 nCol, sal_Int32 nRow)
67 : nColsPerCol(nDefaultColCount, 1),
68 nRealCols(nDefaultColCount + 1, 0),
69 nRowsPerRow(nDefaultRowCount, 1),
70 nRealRows(nDefaultRowCount + 1, 0),
71 nChangedCols()
72 {
73 aTableCellPos.Sheet = sal::static_int_cast<sal_Int16>( nSheet );
74 aTableCellPos.Column = nCol;
75 aTableCellPos.Row = nRow;
76
77 for (sal_Int32 i = 0; i < 3; ++i)
78 nRealCols[i] = i;
79 for (sal_Int32 j = 0; j < 3; ++j)
80 nRealRows[j] = j;
81
82 nSpannedCols = 1;
83 nColCount = 0;
84 nSubTableSpanned = 1;
85 }
86
~ScMyTableData()87 ScMyTableData::~ScMyTableData()
88 {
89 }
90
AddRow()91 void ScMyTableData::AddRow()
92 {
93 ++aTableCellPos.Row;
94 if (static_cast<sal_uInt32>(aTableCellPos.Row) >= nRowsPerRow.size())
95 {
96 nRowsPerRow.resize(nRowsPerRow.size() + nDefaultRowCount, 1);
97 nRealRows.resize(nRowsPerRow.size() + nDefaultRowCount + 1, 0);
98 }
99 nRealRows[aTableCellPos.Row + 1] = nRealRows[aTableCellPos.Row] + nRowsPerRow[aTableCellPos.Row];
100 }
101
AddColumn()102 void ScMyTableData::AddColumn()
103 {
104 ++aTableCellPos.Column;
105 if (static_cast<sal_uInt32>(aTableCellPos.Column) >= nColsPerCol.size())
106 {
107 nColsPerCol.resize(nColsPerCol.size() + nDefaultColCount, 1);
108 nRealCols.resize(nColsPerCol.size() + nDefaultColCount + 1, 0);
109 }
110 nRealCols[aTableCellPos.Column + 1] = nRealCols[aTableCellPos.Column] + nColsPerCol[aTableCellPos.Column];
111 }
112
GetRealCols(const sal_Int32 nIndex,const sal_Bool) const113 sal_Int32 ScMyTableData::GetRealCols(const sal_Int32 nIndex, const sal_Bool /* bIsNormal */) const
114 {
115 return (nIndex < 0) ? 0 : nRealCols[nIndex];
116 }
117
GetChangedCols(const sal_Int32 nFromIndex,const sal_Int32 nToIndex) const118 sal_Int32 ScMyTableData::GetChangedCols(const sal_Int32 nFromIndex, const sal_Int32 nToIndex) const
119 {
120 ScMysalIntList::const_iterator i(nChangedCols.begin());
121 ScMysalIntList::const_iterator endi(nChangedCols.end());
122 while ((i != endi) && ((*i < nToIndex) && !(*i >= nFromIndex)))
123 ++i;
124 if (i == endi)
125 return -1;
126 else
127 if ((*i >= nFromIndex) && (*i < nToIndex))
128 return *i;
129 else
130 return -1;
131 }
132
SetChangedCols(const sal_Int32 nValue)133 void ScMyTableData::SetChangedCols(const sal_Int32 nValue)
134 {
135 ScMysalIntList::iterator i(nChangedCols.begin());
136 ScMysalIntList::iterator endi(nChangedCols.end());
137 while ((i != endi) && (*i < nValue))
138 {
139 ++i;
140 }
141 if ((i == endi) || (*i != nValue))
142 nChangedCols.insert(i, nValue);
143 }
144
145 /*******************************************************************************************************************************/
146
ScMyTables(ScXMLImport & rTempImport)147 ScMyTables::ScMyTables(ScXMLImport& rTempImport)
148 : rImport(rTempImport),
149 aResizeShapes(rTempImport),
150 nCurrentColStylePos(0),
151 nCurrentDrawPage( -1 ),
152 nCurrentXShapes( -1 ),
153 nTableCount( 0 ),
154 nCurrentSheet( -1 )
155 {
156 aTableVec.resize(nDefaultTabCount, NULL);
157 }
158
~ScMyTables()159 ScMyTables::~ScMyTables()
160 {
161 ScMyTableData* pTable;
162 while (nTableCount > 0)
163 {
164 pTable = aTableVec[nTableCount - 1];
165 delete pTable;
166 aTableVec[nTableCount - 1] = NULL;
167 --nTableCount;
168 }
169 }
170
NewSheet(const rtl::OUString & sTableName,const rtl::OUString & sStyleName,const sal_Bool bTempProtection,const rtl::OUString & sTempPassword)171 void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString& sStyleName,
172 const sal_Bool bTempProtection, const rtl::OUString& sTempPassword)
173 {
174 if (rImport.GetModel().is())
175 {
176 nCurrentColStylePos = 0;
177 sCurrentSheetName = sTableName;
178 ScMyTableData* aTable;
179 while (nTableCount > 0)
180 {
181 aTable = aTableVec[nTableCount - 1];
182 delete aTable;
183 aTableVec[nTableCount - 1] = NULL;
184 --nTableCount;
185 }
186 ++nCurrentSheet;
187
188 bProtection = bTempProtection;
189 sPassword = sTempPassword;
190 uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( rImport.GetModel(), uno::UNO_QUERY );
191 if ( xSpreadDoc.is() )
192 {
193 uno::Reference <sheet::XSpreadsheets> xSheets(xSpreadDoc->getSheets());
194 if (xSheets.is())
195 {
196 if (nCurrentSheet > 0)
197 {
198 try
199 {
200 xSheets->insertNewByName(sTableName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
201 }
202 catch ( uno::RuntimeException& )
203 {
204 ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
205 if (pDoc)
206 {
207 rImport.LockSolarMutex();
208 String sTabName(String::CreateFromAscii("Table"));
209 pDoc->CreateValidTabName(sTabName);
210 rtl::OUString sOUTabName(sTabName);
211 xSheets->insertNewByName(sOUTabName, sal::static_int_cast<sal_Int16>(nCurrentSheet));
212 rImport.UnlockSolarMutex();
213 }
214 }
215 }
216 uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
217 if ( xIndex.is() )
218 {
219 xCurrentSheet.set(xIndex->getByIndex(nCurrentSheet), uno::UNO_QUERY);
220 if ( xCurrentSheet.is() )
221 {
222 xCurrentCellRange.set(xCurrentSheet, uno::UNO_QUERY);
223 if (!(nCurrentSheet > 0))
224 {
225 uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
226 if ( xNamed.is() )
227 try
228 {
229 xNamed->setName(sTableName);
230 }
231 catch ( uno::RuntimeException& )
232 {
233 ScDocument *pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
234 if (pDoc)
235 {
236 rImport.LockSolarMutex();
237 String sTabName(String::CreateFromAscii("Table"));
238 pDoc->CreateValidTabName(sTabName);
239 rtl::OUString sOUTabName(sTabName);
240 xNamed->setName(sOUTabName);
241 rImport.UnlockSolarMutex();
242 }
243 }
244 }
245 rImport.SetTableStyle(sStyleName);
246
247 if ( sStyleName.getLength() )
248 {
249 // #i57869# All table style properties for all sheets are now applied here,
250 // before importing the contents.
251 // This is needed for the background color.
252 // Sheet visibility has special handling in ScDocFunc::SetTableVisible to
253 // allow hiding the first sheet.
254 // RTL layout is only remembered, not actually applied, so the shapes can
255 // be loaded before mirroring.
256
257 uno::Reference <beans::XPropertySet> xProperties(xCurrentSheet, uno::UNO_QUERY);
258 if (xProperties.is())
259 {
260 XMLTableStylesContext *pStyles = (XMLTableStylesContext *)rImport.GetAutoStyles();
261 if (pStyles)
262 {
263 XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
264 XML_STYLE_FAMILY_TABLE_TABLE, sStyleName, sal_True);
265 if (pStyle)
266 {
267 pStyle->FillPropertySet(xProperties);
268
269 ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rImport.GetModel())->GetSheetSaveData();
270 pSheetData->AddTableStyle( sStyleName, ScAddress( 0, 0, (SCTAB)nCurrentSheet ) );
271 }
272 }
273 }
274 }
275 }
276
277 }
278 }
279 }
280 }
281
282 NewTable(1);
283 }
284
IsMerged(const uno::Reference<table::XCellRange> & xCellRange,const sal_Int32 nCol,const sal_Int32 nRow,table::CellRangeAddress & aCellAddress) const285 sal_Bool ScMyTables::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow,
286 table::CellRangeAddress& aCellAddress) const
287 {
288 uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
289 if (xMergeable.is())
290 {
291 uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xMergeable, uno::UNO_QUERY);
292 uno::Reference<sheet::XSpreadsheet> xTable(xMergeSheetCellRange->getSpreadsheet());
293 uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor(xTable->createCursorByRange(xMergeSheetCellRange));
294 if (xMergeSheetCursor.is())
295 {
296 xMergeSheetCursor->collapseToMergedArea();
297 uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY);
298 if (xMergeCellAddress.is())
299 {
300 aCellAddress = xMergeCellAddress->getRangeAddress();
301 if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol &&
302 aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow)
303 return sal_False;
304 else
305 return sal_True;
306 }
307 }
308 }
309 return sal_False;
310 }
311
UnMerge()312 void ScMyTables::UnMerge()
313 {
314 if ( xCurrentCellRange.is() )
315 {
316 table::CellRangeAddress aCellAddress;
317 if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
318 {
319 //unmerge
320 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
321 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
322 if (xMergeable.is())
323 xMergeable->merge(sal_False);
324 }
325 }
326 }
327
DoMerge(sal_Int32 nCount)328 void ScMyTables::DoMerge(sal_Int32 nCount)
329 {
330 if ( xCurrentCellRange.is() )
331 {
332 table::CellRangeAddress aCellAddress;
333 if (IsMerged(xCurrentCellRange, GetRealCellPos().Column, GetRealCellPos().Row, aCellAddress))
334 {
335 //unmerge
336 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
337 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
338 if (xMergeable.is())
339 xMergeable->merge(sal_False);
340 }
341
342 //merge
343 uno::Reference <table::XCellRange> xMergeCellRange;
344 if (nCount == -1)
345 xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
346 aCellAddress.EndColumn
347 + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) - 1,
348 aCellAddress.EndRow
349 + aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) - 1));
350 else
351 xMergeCellRange.set(xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
352 aCellAddress.StartColumn
353 + nCount - 1,
354 aCellAddress.EndRow));
355 uno::Reference <util::XMergeable> xMergeable (xMergeCellRange, uno::UNO_QUERY);
356 if (xMergeable.is())
357 xMergeable->merge(sal_True);
358 }
359 }
360
InsertRow()361 void ScMyTables::InsertRow()
362 {
363 if ( xCurrentCellRange.is() )
364 {
365 table::CellRangeAddress aCellAddress;
366 sal_Int32 nRow(GetRealCellPos().Row);
367 for (sal_Int32 j = 0; j < GetRealCellPos().Column - aTableVec[nTableCount - 1]->GetColumn() - 1; ++j)
368 {
369 if (IsMerged(xCurrentCellRange, j, nRow - 1, aCellAddress))
370 {
371 //unmerge
372 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
373 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
374 if (xMergeable.is())
375 xMergeable->merge(sal_False);
376 }
377
378 //merge
379 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
380 aCellAddress.EndColumn, aCellAddress.EndRow + 1), uno::UNO_QUERY);
381 if (xMergeable.is())
382 xMergeable->merge(sal_True);
383 j += aCellAddress.EndColumn - aCellAddress.StartColumn;
384 }
385 rImport.GetStylesImportHelper()->InsertRow(nRow, nCurrentSheet, rImport.GetDocument());
386 }
387 }
388
NewRow()389 void ScMyTables::NewRow()
390 {
391 if (nTableCount > 1)
392 if (aTableVec[nTableCount - 1]->GetRealRows(aTableVec[nTableCount - 1]->GetRow()) >
393 aTableVec[nTableCount - 2]->GetRowsPerRow(aTableVec[nTableCount - 2]->GetRow()) - 1)
394 {
395 if (GetRealCellPos().Column > 0)
396 InsertRow();
397 for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--)
398 {
399 sal_Int32 nRow = aTableVec[i - 1]->GetRow();
400 aTableVec[i - 1]->SetRowsPerRow(nRow,
401 aTableVec[i - 1]->GetRowsPerRow(nRow) + 1);
402 aTableVec[i - 1]->SetRealRows(nRow + 1,
403 aTableVec[i - 1]->GetRealRows(nRow)
404 + aTableVec[i - 1]->GetRowsPerRow(nRow));
405 }
406 }
407 }
408
AddRow()409 void ScMyTables::AddRow()
410 {
411 aTableVec[nTableCount - 1]->AddRow();
412 aTableVec[nTableCount - 1]->SetFirstColumn();
413 sal_Int32 nRow = aTableVec[nTableCount - 1]->GetRow();
414 if (nRow > 0)
415 NewRow();
416 aTableVec[nTableCount - 1]->SetRealRows(nRow + 1,
417 aTableVec[nTableCount - 1]->GetRealRows(nRow)
418 + aTableVec[nTableCount - 1]->GetRowsPerRow(nRow));
419 }
420
SetRowStyle(const rtl::OUString & rCellStyleName)421 void ScMyTables::SetRowStyle(const rtl::OUString& rCellStyleName)
422 {
423 rImport.GetStylesImportHelper()->SetRowStyle(rCellStyleName);
424 }
425
InsertColumn()426 void ScMyTables::InsertColumn()
427 {
428 if ( xCurrentCellRange.is() )
429 {
430 table::CellRangeAddress aCellAddress;
431 sal_Int32 nCol(GetRealCellPos().Column);
432 for (sal_Int32 j = 0; j <= GetRealCellPos().Row - aTableVec[nTableCount - 1]->GetRow() - 1; ++j)
433 {
434 table::CellRangeAddress aTempCellAddress;
435 if (IsMerged(xCurrentCellRange, nCol - 1, j, aCellAddress))
436 {
437 //unmerge
438 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
439 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
440 if (xMergeable.is())
441 xMergeable->merge(sal_False);
442 aTempCellAddress = aCellAddress;
443 aTempCellAddress.StartColumn = aTempCellAddress.EndColumn + 1;
444 aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
445 }
446 else
447 {
448 aTempCellAddress = aCellAddress;
449 aTempCellAddress.StartColumn += 1;
450 aTempCellAddress.EndColumn = aTempCellAddress.StartColumn;
451 }
452
453 //insert Cell
454 sheet::CellInsertMode aCellInsertMode(sheet::CellInsertMode_RIGHT);
455 uno::Reference <sheet::XCellRangeMovement> xCellRangeMovement (xCurrentSheet, uno::UNO_QUERY);
456 xCellRangeMovement->insertCells(aTempCellAddress, aCellInsertMode);
457
458 //merge
459 uno::Reference <util::XMergeable> xMergeable (xCurrentCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
460 aCellAddress.EndColumn + 1, aCellAddress.EndRow), uno::UNO_QUERY);
461 if (xMergeable.is())
462 xMergeable->merge(sal_True);
463 j += aCellAddress.EndRow - aCellAddress.StartRow;
464 }
465 rImport.GetStylesImportHelper()->InsertCol(nCol, nCurrentSheet, rImport.GetDocument());
466 }
467 }
468
NewColumn(sal_Bool bIsCovered)469 void ScMyTables::NewColumn(sal_Bool bIsCovered)
470 {
471 if (!bIsCovered)
472 {
473 sal_Int32 nColCount(aTableVec[nTableCount - 1]->GetColCount());
474 sal_Int32 nSpannedCols(aTableVec[nTableCount - 1]->GetSpannedCols());
475 if ( (nSpannedCols > nColCount) &&
476 (aTableVec[nTableCount - 1]->GetRow() == 0) &&
477 (aTableVec[nTableCount - 1]->GetColumn() == 0) )
478 {
479 if (nColCount > 0)
480 {
481 sal_Int32 FirstColsSpanned(nSpannedCols / nColCount);
482 sal_Int32 LastColSpanned(FirstColsSpanned
483 + (nSpannedCols % nColCount));
484 for (sal_Int32 i = 0; i < nColCount - 1; ++i)
485 {
486 aTableVec[nTableCount - 1]->SetColsPerCol(i, FirstColsSpanned);
487 aTableVec[nTableCount - 1]->SetRealCols(i + 1,
488 aTableVec[nTableCount - 1]->GetRealCols(i)
489 + FirstColsSpanned);
490 }
491 aTableVec[nTableCount - 1]->SetColsPerCol(nColCount - 1, LastColSpanned);
492 aTableVec[nTableCount - 1]->SetRealCols(nColCount - 1 + 1,
493 aTableVec[nTableCount - 1]->GetRealCols(nColCount - 1)
494 + LastColSpanned);
495 }
496 }
497 if (aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn()) > nSpannedCols - 1)
498 {
499 if ( aTableVec[nTableCount - 1]->GetRow() == 0)
500 {
501 InsertColumn();
502 for (sal_Int16 i = sal::static_int_cast<sal_Int16>(nTableCount - 1); i > 0; i--)
503 {
504 sal_Int32 nColPos = aTableVec[i - 1]->GetColumn() +
505 aTableVec[i]->GetSpannedCols() - 1;
506 aTableVec[i - 1]->SetColsPerCol(nColPos,
507 aTableVec[i - 1]->GetColsPerCol(nColPos) +
508 aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()));
509 aTableVec[i - 1]->SetRealCols(nColPos + 1,
510 aTableVec[i - 1]->GetRealCols(nColPos)
511 + aTableVec[i - 1]->GetColsPerCol(nColPos));
512 aTableVec[i - 1]->SetChangedCols(nColPos);
513 }
514 }
515 }
516 }
517 }
518
AddColumn(sal_Bool bIsCovered)519 void ScMyTables::AddColumn(sal_Bool bIsCovered)
520 {
521 aTableVec[nTableCount - 1]->AddColumn();
522 if (aTableVec[nTableCount - 1]->GetSubTableSpanned() > 1)
523 aTableVec[nTableCount - 1]->SetSubTableSpanned(aTableVec[nTableCount - 1]->GetSubTableSpanned() - 1);
524 else
525 {
526 NewColumn(bIsCovered);
527 // if (!bIsCovered)
528 aTableVec[nTableCount - 1]->SetRealCols(aTableVec[nTableCount - 1]->GetColumn() + 1,
529 aTableVec[nTableCount - 1]->GetRealCols(aTableVec[nTableCount - 1]->GetColumn())
530 + aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()));
531 if ((!bIsCovered) || (bIsCovered &&
532 (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1)))
533 {
534 if ((aTableVec[nTableCount - 1]->GetRowsPerRow(aTableVec[nTableCount - 1]->GetRow()) > 1) ||
535 (aTableVec[nTableCount - 1]->GetColsPerCol(aTableVec[nTableCount - 1]->GetColumn()) > 1))
536 DoMerge();
537 }
538 }
539 }
540
NewTable(sal_Int32 nTempSpannedCols)541 void ScMyTables::NewTable(sal_Int32 nTempSpannedCols)
542 {
543 ++nTableCount;
544 if (static_cast<sal_uInt32>(nTableCount) >= aTableVec.size())
545 aTableVec.resize(aTableVec.size() + nDefaultTabCount);
546 ScMyTableData* aTable(new ScMyTableData(nCurrentSheet));
547 if (nTableCount > 1)
548 {
549 ScMyTableData* pTableData = aTableVec[nTableCount - 2];
550 const sal_Int32 nCol(pTableData->GetColumn());
551 const sal_Int32 nColCount(pTableData->GetColCount());
552 const sal_Int32 nColsPerCol(pTableData->GetColsPerCol(nCol));
553 sal_Int32 nSpannedCols(pTableData->GetSpannedCols());
554 sal_Int32 nTemp(nSpannedCols - nColCount);
555 sal_Int32 nTemp2(nCol - (nColCount - 1));
556 if ((nTemp > 0) && (nTemp2 == 0))
557 nTempSpannedCols *= (nTemp + 1);
558 else
559 if (nColsPerCol > 1)
560 nTempSpannedCols *= nColsPerCol;
561
562 sal_Int32 nToMerge;
563 if (nSpannedCols > nColCount)
564 nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol + nSpannedCols - nColCount);
565 else
566 nToMerge = pTableData->GetChangedCols(nCol, nCol + nColsPerCol);
567 if (nToMerge > nCol)
568 nTempSpannedCols += nToMerge;
569 }
570 aTable->SetSpannedCols(nTempSpannedCols);
571 aTableVec[nTableCount - 1] = aTable;
572 if (nTableCount > 1)
573 {
574 aTableVec[nTableCount - 2]->SetSubTableSpanned(aTable->GetSpannedCols());
575 UnMerge();
576 }
577 }
578
UpdateRowHeights()579 void ScMyTables::UpdateRowHeights()
580 {
581 if (rImport.GetModel().is())
582 {
583 rImport.LockSolarMutex();
584 // update automatic row heights
585
586 // For sheets with any kind of shapes (including notes),
587 // update row heights immediately (before setting the positions).
588 // For sheets without shapes, set "pending" flag
589 // and update row heights when a sheet is shown.
590 // The current sheet (from view settings) is always updated immediately.
591
592 ScDocument* pDoc = ScXMLConverter::GetScDocument(rImport.GetModel());
593 if (pDoc)
594 {
595 SCTAB nCount = pDoc->GetTableCount();
596 ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
597
598 SCTAB nVisible = static_cast<SCTAB>( rImport.GetVisibleSheet() );
599
600 ScMarkData aUpdateSheets;
601 for (SCTAB nTab=0; nTab<nCount; ++nTab)
602 {
603 const SdrPage* pPage = pDrawLayer ? pDrawLayer->GetPage(nTab) : NULL;
604 if ( nTab == nVisible || ( pPage && pPage->GetObjCount() != 0 ) )
605 aUpdateSheets.SelectTable( nTab, sal_True );
606 else
607 pDoc->SetPendingRowHeights( nTab, sal_True );
608 }
609
610 if (aUpdateSheets.GetSelectCount())
611 {
612 pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results)
613 // #i114839# make sure the output factor is valid for UpdateAllRowHeights
614 ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets, true);
615 pDoc->LockStreamValid( false );
616 }
617 }
618
619 rImport.UnlockSolarMutex();
620 }
621 }
622
DeleteTable()623 void ScMyTables::DeleteTable()
624 {
625 rImport.LockSolarMutex();
626
627 nCurrentColStylePos = 0;
628 if (nTableCount > 0)
629 {
630 ScMyTableData* aTable = aTableVec[nTableCount - 1];
631 delete aTable;
632 aTableVec[nTableCount - 1] = NULL;
633 nTableCount--;
634 }
635 if (nTableCount == 0) // only set the styles if all subtables are importet and the table is finished
636 {
637 rImport.GetStylesImportHelper()->SetStylesToRanges();
638 rImport.SetStylesToRangesFinished();
639 }
640
641 //#i48793#; has to be set before protection
642 if (!aMatrixRangeList.empty())
643 {
644 ScMyMatrixRangeList::iterator aItr = aMatrixRangeList.begin();
645 ScMyMatrixRangeList::iterator aEndItr = aMatrixRangeList.end();
646 while(aItr != aEndItr)
647 {
648 SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
649 ++aItr;
650 }
651 aMatrixRangeList.clear();
652 }
653
654 if (rImport.GetDocument() && bProtection)
655 {
656 uno::Sequence<sal_Int8> aPass;
657 SvXMLUnitConverter::decodeBase64(aPass, sPassword);
658 auto_ptr<ScTableProtection> pProtect(new ScTableProtection);
659 pProtect->setProtected(bProtection);
660 pProtect->setPasswordHash(aPass, PASSHASH_OOO);
661 rImport.GetDocument()->SetTabProtection(static_cast<SCTAB>(nCurrentSheet), pProtect.get());
662 }
663
664 rImport.UnlockSolarMutex();
665
666 //#95582#; find out whether it was possible to set the sheet name
667 // test it here, because if it is a linked table the name is changed by importing
668 // the linking informations
669 uno::Reference < container::XNamed > xNamed(xCurrentSheet, uno::UNO_QUERY );
670 if ( xNamed.is() )
671 {
672 rtl::OUString sCurrentName(xNamed->getName());
673 if (sCurrentName != sCurrentSheetName && rImport.GetDocument())
674 {
675 rImport.GetDocument()->RenameTab( static_cast<SCTAB>(nCurrentSheet),
676 sCurrentSheetName, sal_False, sal_True);
677
678 /* rtl::OUString sErrorMessage(RTL_CONSTASCII_USTRINGPARAM("Could not create a table with the name "));
679 sErrorMessage += sCurrentSheetName;
680 sErrorMessage += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(". The new name is "));
681 sErrorMessage += sCurrentName;
682 uno::Sequence<rtl::OUString> aSeq(1);
683 aSeq[0] = sErrorMessage;
684 uno::Reference<xml::sax::XLocator> xLocator;
685 rImport.SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rtl::OUString(), xLocator);*/
686 }
687 }
688 }
689
GetRealCellPos()690 table::CellAddress ScMyTables::GetRealCellPos()
691 {
692 sal_Int32 nRow(0);
693 sal_Int32 nCol(0);
694 for (sal_Int32 i = 0; i < nTableCount; ++i)
695 {
696 ScMyTableData* pTableData = aTableVec[i];
697 nCol += pTableData->GetRealCols(pTableData->GetColumn());
698 nRow += pTableData->GetRealRows(pTableData->GetRow());
699 }
700 aRealCellPos.Row = nRow;
701 aRealCellPos.Column = nCol;
702 aRealCellPos.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
703 return aRealCellPos;
704 }
705
AddColCount(sal_Int32 nTempColCount)706 void ScMyTables::AddColCount(sal_Int32 nTempColCount)
707 {
708 aTableVec[nTableCount - 1]->SetColCount(aTableVec[nTableCount - 1]->GetColCount() + nTempColCount);
709 }
710
AddColStyle(const sal_Int32 nRepeat,const rtl::OUString & rCellStyleName)711 void ScMyTables::AddColStyle(const sal_Int32 nRepeat, const rtl::OUString& rCellStyleName)
712 {
713 DBG_ASSERT(nTableCount == 1, "not possible to use default styles on columns in subtables");
714 rImport.GetStylesImportHelper()->AddColumnStyle(rCellStyleName, nCurrentColStylePos, nRepeat);
715 nCurrentColStylePos += nRepeat;
716 }
717
GetCurrentXDrawPage()718 uno::Reference< drawing::XDrawPage > ScMyTables::GetCurrentXDrawPage()
719 {
720 if( (nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is() )
721 {
722 uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier( xCurrentSheet, uno::UNO_QUERY );
723 if( xDrawPageSupplier.is() )
724 xDrawPage.set(xDrawPageSupplier->getDrawPage());
725 nCurrentDrawPage = sal::static_int_cast<sal_Int16>(nCurrentSheet);
726 }
727 return xDrawPage;
728 }
729
GetCurrentXShapes()730 uno::Reference< drawing::XShapes > ScMyTables::GetCurrentXShapes()
731 {
732 if( (nCurrentSheet != nCurrentXShapes) || !xShapes.is() )
733 {
734 xShapes.set(GetCurrentXDrawPage(), uno::UNO_QUERY);
735 rImport.GetShapeImport()->startPage(xShapes);
736 rImport.GetShapeImport()->pushGroupForSorting ( xShapes );
737 nCurrentXShapes = sal::static_int_cast<sal_Int16>(nCurrentSheet);
738 return xShapes;
739 }
740 else
741 return xShapes;
742 }
743
HasDrawPage()744 sal_Bool ScMyTables::HasDrawPage()
745 {
746 return !((nCurrentSheet != nCurrentDrawPage) || !xDrawPage.is());
747 }
748
HasXShapes()749 sal_Bool ScMyTables::HasXShapes()
750 {
751 return !((nCurrentSheet != nCurrentXShapes) || !xShapes.is());
752 }
753
AddShape(uno::Reference<drawing::XShape> & rShape,rtl::OUString * pRangeList,table::CellAddress & rStartAddress,table::CellAddress & rEndAddress,sal_Int32 nEndX,sal_Int32 nEndY)754 void ScMyTables::AddShape(uno::Reference <drawing::XShape>& rShape,
755 rtl::OUString* pRangeList,
756 table::CellAddress& rStartAddress, table::CellAddress& rEndAddress,
757 sal_Int32 nEndX, sal_Int32 nEndY)
758 {
759 aResizeShapes.AddShape(rShape, pRangeList, rStartAddress, rEndAddress, nEndX, nEndY);
760 }
761
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)762 void ScMyTables::AddMatrixRange(
763 sal_Int32 nStartColumn, sal_Int32 nStartRow, sal_Int32 nEndColumn, sal_Int32 nEndRow,
764 const rtl::OUString& rFormula, const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
765 {
766 DBG_ASSERT(nEndRow >= nStartRow, "wrong row order");
767 DBG_ASSERT(nEndColumn >= nStartColumn, "wrong column order");
768 table::CellRangeAddress aRange;
769 aRange.StartColumn = nStartColumn;
770 aRange.StartRow = nStartRow;
771 aRange.EndColumn = nEndColumn;
772 aRange.EndRow = nEndRow;
773 aRange.Sheet = sal::static_int_cast<sal_Int16>(nCurrentSheet);
774 ScMatrixRange aMRange(aRange, rFormula, rFormulaNmsp, eGrammar);
775 aMatrixRangeList.push_back(aMRange);
776 }
777
IsPartOfMatrix(sal_Int32 nColumn,sal_Int32 nRow)778 sal_Bool ScMyTables::IsPartOfMatrix(sal_Int32 nColumn, sal_Int32 nRow)
779 {
780 sal_Bool bResult(sal_False);
781 if (!aMatrixRangeList.empty())
782 {
783 ScMyMatrixRangeList::iterator aItr(aMatrixRangeList.begin());
784 ScMyMatrixRangeList::iterator aEndItr(aMatrixRangeList.end());
785 sal_Bool bReady(sal_False);
786 while(!bReady && aItr != aEndItr)
787 {
788 if (nCurrentSheet > aItr->aRange.Sheet)
789 {
790 DBG_ERROR("should never happen, because the list should be cleared in DeleteTable");
791 aItr = aMatrixRangeList.erase(aItr);
792 }
793 else if ((nRow > aItr->aRange.EndRow) && (nColumn > aItr->aRange.EndColumn))
794 {
795 SetMatrix(aItr->aRange, aItr->sFormula, aItr->sFormulaNmsp, aItr->eGrammar);
796 aItr = aMatrixRangeList.erase(aItr);
797 }
798 else if (nColumn < aItr->aRange.StartColumn)
799 bReady = sal_True;
800 else if (nColumn >= aItr->aRange.StartColumn && nColumn <= aItr->aRange.EndColumn && nRow >= aItr->aRange.StartRow && nRow <= aItr->aRange.EndRow)
801 {
802 bReady = sal_True;
803 bResult = sal_True;
804 }
805 else
806 ++aItr;
807 }
808 }
809 return bResult;
810 }
811
SetMatrix(const table::CellRangeAddress & rRange,const rtl::OUString & rFormula,const rtl::OUString & rFormulaNmsp,const formula::FormulaGrammar::Grammar eGrammar)812 void ScMyTables::SetMatrix(const table::CellRangeAddress& rRange, const rtl::OUString& rFormula,
813 const rtl::OUString& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar)
814 {
815 uno::Reference <table::XCellRange> xMatrixCellRange(
816 GetCurrentXCellRange()->getCellRangeByPosition(rRange.StartColumn, rRange.StartRow,
817 rRange.EndColumn, rRange.EndRow));
818 if (xMatrixCellRange.is())
819 {
820 uno::Reference <sheet::XArrayFormulaRange> xArrayFormulaRange(xMatrixCellRange, uno::UNO_QUERY);
821 if (xArrayFormulaRange.is())
822 {
823 ScCellRangeObj* pCellRangeObj =
824 static_cast<ScCellRangeObj*>(ScCellRangesBase::getImplementation(
825 xMatrixCellRange));
826 if (pCellRangeObj)
827 pCellRangeObj->SetArrayFormulaWithGrammar( rFormula, rFormulaNmsp, eGrammar);
828 }
829 }
830 }
831