xref: /AOO41X/main/sc/source/filter/xml/xmlsubti.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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 hapen, 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