xref: /AOO41X/main/sc/source/filter/xml/XMLExportIterator.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 
29 // INCLUDE ---------------------------------------------------------------
30 #include "XMLExportIterator.hxx"
31 #include <com/sun/star/text/XSimpleText.hpp>
32 #include <com/sun/star/sheet/XCellAddressable.hpp>
33 #include <com/sun/star/sheet/CellFlags.hpp>
34 #include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp>
35 #include <com/sun/star/container/XEnumerationAccess.hpp>
36 #include <tools/debug.hxx>
37 #include <xmloff/xmlnmspe.hxx>
38 #include "dociter.hxx"
39 #include "convuno.hxx"
40 #include "xmlexprt.hxx"
41 #include "XMLExportSharedData.hxx"
42 #include "XMLStylesExportHelper.hxx"
43 #include "document.hxx"
44 
45 #include <algorithm>
46 
47 using ::rtl::OUString;
48 using namespace ::com::sun::star;
49 
50 //==============================================================================
51 
ScMyIteratorBase()52 ScMyIteratorBase::ScMyIteratorBase()
53 {
54 }
55 
~ScMyIteratorBase()56 ScMyIteratorBase::~ScMyIteratorBase()
57 {
58 }
59 
UpdateAddress(table::CellAddress & rCellAddress)60 void ScMyIteratorBase::UpdateAddress( table::CellAddress& rCellAddress )
61 {
62     table::CellAddress aNewAddr( rCellAddress );
63     if( GetFirstAddress( aNewAddr ) )
64     {
65         if( (aNewAddr.Sheet == rCellAddress.Sheet) &&
66             ((aNewAddr.Row < rCellAddress.Row) ||
67             ((aNewAddr.Row == rCellAddress.Row) && (aNewAddr.Column < rCellAddress.Column))) )
68             rCellAddress = aNewAddr;
69     }
70 }
71 
72 
73 //==============================================================================
74 
operator <(const ScMyShape & aShape) const75 sal_Bool ScMyShape::operator<(const ScMyShape& aShape) const
76 {
77     if( aAddress.Tab() != aShape.aAddress.Tab() )
78         return (aAddress.Tab() < aShape.aAddress.Tab());
79     else if( aAddress.Row() != aShape.aAddress.Row() )
80         return (aAddress.Row() < aShape.aAddress.Row());
81     else
82         return (aAddress.Col() < aShape.aAddress.Col());
83 }
84 
ScMyShapesContainer()85 ScMyShapesContainer::ScMyShapesContainer()
86     : aShapeList()
87 {
88 }
89 
~ScMyShapesContainer()90 ScMyShapesContainer::~ScMyShapesContainer()
91 {
92 }
93 
AddNewShape(const ScMyShape & aShape)94 void ScMyShapesContainer::AddNewShape( const ScMyShape& aShape )
95 {
96     aShapeList.push_back(aShape);
97 }
98 
GetFirstAddress(table::CellAddress & rCellAddress)99 sal_Bool ScMyShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
100 {
101     sal_Int32 nTable(rCellAddress.Sheet);
102     if( !aShapeList.empty() )
103     {
104         ScUnoConversion::FillApiAddress( rCellAddress, aShapeList.begin()->aAddress );
105         return (nTable == rCellAddress.Sheet);
106     }
107     return sal_False;
108 }
109 
SetCellData(ScMyCell & rMyCell)110 void ScMyShapesContainer::SetCellData( ScMyCell& rMyCell )
111 {
112     rMyCell.aShapeList.clear();
113     ScAddress aAddress;
114     ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
115 
116     ScMyShapeList::iterator aItr(aShapeList.begin());
117     ScMyShapeList::iterator aEndItr(aShapeList.end());
118     while( (aItr != aEndItr) && (aItr->aAddress == aAddress) )
119     {
120         rMyCell.aShapeList.push_back(*aItr);
121         aItr = aShapeList.erase(aItr);
122     }
123     rMyCell.bHasShape = !rMyCell.aShapeList.empty();
124 }
125 
SkipTable(SCTAB nSkip)126 void ScMyShapesContainer::SkipTable(SCTAB nSkip)
127 {
128     ScMyShapeList::iterator aItr = aShapeList.begin();
129     while( (aItr != aShapeList.end()) && (aItr->aAddress.Tab() == nSkip) )
130         aItr = aShapeList.erase(aItr);
131 }
132 
Sort()133 void ScMyShapesContainer::Sort()
134 {
135     aShapeList.sort();
136 }
137 
operator <(const ScMyNoteShape & aNote) const138 sal_Bool ScMyNoteShape::operator<(const ScMyNoteShape& aNote) const
139 {
140     if( aPos.Tab() != aNote.aPos.Tab() )
141         return (aPos.Tab() < aNote.aPos.Tab());
142     else if( aPos.Row() != aNote.aPos.Row() )
143         return (aPos.Row() < aNote.aPos.Row());
144     else
145         return (aPos.Col() < aNote.aPos.Col());
146 }
147 
ScMyNoteShapesContainer()148 ScMyNoteShapesContainer::ScMyNoteShapesContainer()
149     : aNoteShapeList()
150 {
151 }
152 
~ScMyNoteShapesContainer()153 ScMyNoteShapesContainer::~ScMyNoteShapesContainer()
154 {
155 }
156 
AddNewNote(const ScMyNoteShape & aNote)157 void ScMyNoteShapesContainer::AddNewNote( const ScMyNoteShape& aNote )
158 {
159     aNoteShapeList.push_back(aNote);
160 }
161 
GetFirstAddress(table::CellAddress & rCellAddress)162 sal_Bool ScMyNoteShapesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
163 {
164     sal_Int16 nTable = rCellAddress.Sheet;
165     if( !aNoteShapeList.empty() )
166     {
167         ScUnoConversion::FillApiAddress( rCellAddress, aNoteShapeList.begin()->aPos );
168         return (nTable == rCellAddress.Sheet);
169     }
170     return sal_False;
171 }
172 
SetCellData(ScMyCell & rMyCell)173 void ScMyNoteShapesContainer::SetCellData( ScMyCell& rMyCell )
174 {
175     rMyCell.xNoteShape.clear();
176     ScAddress aAddress;
177     ScUnoConversion::FillScAddress( aAddress, rMyCell.aCellAddress );
178 
179     ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
180     while( (aItr != aNoteShapeList.end()) && (aItr->aPos == aAddress) )
181     {
182         rMyCell.xNoteShape = aItr->xShape;
183         aItr = aNoteShapeList.erase(aItr);
184     }
185 }
186 
SkipTable(SCTAB nSkip)187 void ScMyNoteShapesContainer::SkipTable(SCTAB nSkip)
188 {
189     ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
190     while( (aItr != aNoteShapeList.end()) && (aItr->aPos.Tab() == nSkip) )
191         aItr = aNoteShapeList.erase(aItr);
192 }
193 
Sort()194 void ScMyNoteShapesContainer::Sort()
195 {
196     aNoteShapeList.sort();
197 }
198 
199 //==============================================================================
200 
operator <(const ScMyMergedRange & aRange) const201 sal_Bool ScMyMergedRange::operator<(const ScMyMergedRange& aRange) const
202 {
203     if( aCellRange.Sheet != aRange.aCellRange.Sheet )
204         return (aCellRange.Sheet < aRange.aCellRange.Sheet);
205     else if( aCellRange.StartRow != aRange.aCellRange.StartRow )
206         return (aCellRange.StartRow < aRange.aCellRange.StartRow);
207     else
208         return (aCellRange.StartColumn < aRange.aCellRange.StartColumn);
209 }
210 
211 
ScMyMergedRangesContainer()212 ScMyMergedRangesContainer::ScMyMergedRangesContainer()
213     : aRangeList()
214 {
215 }
216 
~ScMyMergedRangesContainer()217 ScMyMergedRangesContainer::~ScMyMergedRangesContainer()
218 {
219 }
220 
AddRange(const table::CellRangeAddress aMergedRange)221 void ScMyMergedRangesContainer::AddRange(const table::CellRangeAddress aMergedRange)
222 {
223     sal_Int32 nStartRow(aMergedRange.StartRow);
224     sal_Int32 nEndRow(aMergedRange.EndRow);
225 
226     ScMyMergedRange aRange;
227     aRange.bIsFirst = sal_True;
228     aRange.aCellRange = aMergedRange;
229     aRange.aCellRange.EndRow = nStartRow;
230     aRange.nRows = nEndRow - nStartRow + 1;
231     aRangeList.push_back( aRange );
232 
233     aRange.bIsFirst = sal_False;
234     aRange.nRows = 0;
235     for( sal_Int32 nRow = nStartRow + 1; nRow <= nEndRow; ++nRow )
236     {
237         aRange.aCellRange.StartRow = aRange.aCellRange.EndRow = nRow;
238         aRangeList.push_back(aRange);
239     }
240 }
241 
GetFirstAddress(table::CellAddress & rCellAddress)242 sal_Bool ScMyMergedRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
243 {
244     sal_Int32 nTable(rCellAddress.Sheet);
245     if( !aRangeList.empty() )
246     {
247         ScUnoConversion::FillApiStartAddress( rCellAddress, aRangeList.begin()->aCellRange );
248         return (nTable == rCellAddress.Sheet);
249     }
250     return sal_False;
251 }
252 
SetCellData(ScMyCell & rMyCell)253 void ScMyMergedRangesContainer::SetCellData( ScMyCell& rMyCell )
254 {
255     rMyCell.bIsMergedBase = rMyCell.bIsCovered = sal_False;
256     ScMyMergedRangeList::iterator aItr(aRangeList.begin());
257     if( aItr != aRangeList.end() )
258     {
259         table::CellAddress aFirstAddress;
260         ScUnoConversion::FillApiStartAddress( aFirstAddress, aItr->aCellRange );
261         if( aFirstAddress == rMyCell.aCellAddress )
262         {
263             rMyCell.aMergeRange = aItr->aCellRange;
264             if (aItr->bIsFirst)
265                 rMyCell.aMergeRange.EndRow = rMyCell.aMergeRange.StartRow + aItr->nRows - 1;
266             rMyCell.bIsMergedBase = aItr->bIsFirst;
267             rMyCell.bIsCovered = !aItr->bIsFirst;
268             if( aItr->aCellRange.StartColumn < aItr->aCellRange.EndColumn )
269             {
270                 ++(aItr->aCellRange.StartColumn);
271                 aItr->bIsFirst = sal_False;
272             }
273             else
274                 aRangeList.erase(aItr);
275         }
276     }
277 }
278 
SkipTable(SCTAB nSkip)279 void ScMyMergedRangesContainer::SkipTable(SCTAB nSkip)
280 {
281     ScMyMergedRangeList::iterator aItr = aRangeList.begin();
282     while( (aItr != aRangeList.end()) && (aItr->aCellRange.Sheet == nSkip) )
283         aItr = aRangeList.erase(aItr);
284 }
285 
Sort()286 void ScMyMergedRangesContainer::Sort()
287 {
288     aRangeList.sort();
289 }
290 
291 //==============================================================================
292 
Compare(const ScMyAreaLink & rAreaLink) const293 sal_Bool ScMyAreaLink::Compare( const ScMyAreaLink& rAreaLink ) const
294 {
295     return  (GetRowCount() == rAreaLink.GetRowCount()) &&
296             (sFilter == rAreaLink.sFilter) &&
297             (sFilterOptions == rAreaLink.sFilterOptions) &&
298             (sURL == rAreaLink.sURL) &&
299             (sSourceStr == rAreaLink.sSourceStr);
300 }
301 
operator <(const ScMyAreaLink & rAreaLink) const302 sal_Bool ScMyAreaLink::operator<(const ScMyAreaLink& rAreaLink ) const
303 {
304     if( aDestRange.Sheet != rAreaLink.aDestRange.Sheet )
305         return (aDestRange.Sheet < rAreaLink.aDestRange.Sheet);
306     else if( aDestRange.StartRow != rAreaLink.aDestRange.StartRow )
307         return (aDestRange.StartRow < rAreaLink.aDestRange.StartRow);
308     else
309         return (aDestRange.StartColumn < rAreaLink.aDestRange.StartColumn);
310 }
311 
ScMyAreaLinksContainer()312 ScMyAreaLinksContainer::ScMyAreaLinksContainer() :
313     aAreaLinkList()
314 {
315 }
316 
~ScMyAreaLinksContainer()317 ScMyAreaLinksContainer::~ScMyAreaLinksContainer()
318 {
319 }
320 
GetFirstAddress(table::CellAddress & rCellAddress)321 sal_Bool ScMyAreaLinksContainer::GetFirstAddress( table::CellAddress& rCellAddress )
322 {
323     sal_Int32 nTable(rCellAddress.Sheet);
324     if( !aAreaLinkList.empty() )
325     {
326         ScUnoConversion::FillApiStartAddress( rCellAddress, aAreaLinkList.begin()->aDestRange );
327         return (nTable == rCellAddress.Sheet);
328     }
329     return sal_False;
330 }
331 
SetCellData(ScMyCell & rMyCell)332 void ScMyAreaLinksContainer::SetCellData( ScMyCell& rMyCell )
333 {
334     rMyCell.bHasAreaLink = sal_False;
335     ScMyAreaLinkList::iterator aItr(aAreaLinkList.begin());
336     if( aItr != aAreaLinkList.end() )
337     {
338         table::CellAddress aAddress;
339         ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
340         if( aAddress == rMyCell.aCellAddress )
341         {
342             rMyCell.bHasAreaLink = sal_True;
343             rMyCell.aAreaLink = *aItr;
344             aItr = aAreaLinkList.erase( aItr );
345             sal_Bool bFound = sal_True;
346             while (aItr != aAreaLinkList.end() && bFound)
347             {
348                 ScUnoConversion::FillApiStartAddress( aAddress, aItr->aDestRange );
349                 if (aAddress == rMyCell.aCellAddress)
350                 {
351                     DBG_ERROR("more than one linked range on one cell");
352                     aItr = aAreaLinkList.erase( aItr );
353                 }
354                 else
355                     bFound = sal_False;
356             }
357         }
358     }
359 }
360 
SkipTable(SCTAB nSkip)361 void ScMyAreaLinksContainer::SkipTable(SCTAB nSkip)
362 {
363     ScMyAreaLinkList::iterator aItr = aAreaLinkList.begin();
364     while( (aItr != aAreaLinkList.end()) && (aItr->aDestRange.Sheet == nSkip) )
365         aItr = aAreaLinkList.erase(aItr);
366 }
367 
Sort()368 void ScMyAreaLinksContainer::Sort()
369 {
370     aAreaLinkList.sort();
371 }
372 
373 //==============================================================================
374 
ScMyCellRangeAddress(const table::CellRangeAddress & rRange)375 ScMyCellRangeAddress::ScMyCellRangeAddress(const table::CellRangeAddress& rRange)
376     : table::CellRangeAddress(rRange)
377 {
378 }
379 
operator <(const ScMyCellRangeAddress & rRange) const380 sal_Bool ScMyCellRangeAddress::operator<(const ScMyCellRangeAddress& rRange ) const
381 {
382     if( Sheet != rRange.Sheet )
383         return (Sheet < rRange.Sheet);
384     else if( StartRow != rRange.StartRow )
385         return (StartRow < rRange.StartRow);
386     else
387         return (StartColumn < rRange.StartColumn);
388 }
389 
ScMyEmptyDatabaseRangesContainer()390 ScMyEmptyDatabaseRangesContainer::ScMyEmptyDatabaseRangesContainer()
391     : aDatabaseList()
392 {
393 }
394 
~ScMyEmptyDatabaseRangesContainer()395 ScMyEmptyDatabaseRangesContainer::~ScMyEmptyDatabaseRangesContainer()
396 {
397 }
398 
AddNewEmptyDatabaseRange(const table::CellRangeAddress & aCellRange)399 void ScMyEmptyDatabaseRangesContainer::AddNewEmptyDatabaseRange(const table::CellRangeAddress& aCellRange)
400 {
401     sal_Int32 nStartRow(aCellRange.StartRow);
402     sal_Int32 nEndRow(aCellRange.EndRow);
403     ScMyCellRangeAddress aRange( aCellRange );
404     for( sal_Int32 nRow = nStartRow; nRow <= nEndRow; ++nRow )
405     {
406         aRange.StartRow = aRange.EndRow = nRow;
407         aDatabaseList.push_back( aRange );
408     }
409 }
410 
GetFirstAddress(table::CellAddress & rCellAddress)411 sal_Bool ScMyEmptyDatabaseRangesContainer::GetFirstAddress( table::CellAddress& rCellAddress )
412 {
413     sal_Int32 nTable(rCellAddress.Sheet);
414     if( !aDatabaseList.empty() )
415     {
416         ScUnoConversion::FillApiStartAddress( rCellAddress, *(aDatabaseList.begin()) );
417         return (nTable == rCellAddress.Sheet);
418     }
419     return sal_False;
420 }
421 
SetCellData(ScMyCell & rMyCell)422 void ScMyEmptyDatabaseRangesContainer::SetCellData( ScMyCell& rMyCell )
423 {
424     rMyCell.bHasEmptyDatabase = sal_False;
425     ScMyEmptyDatabaseRangeList::iterator aItr(aDatabaseList.begin());
426     if( aItr != aDatabaseList.end() )
427     {
428         table::CellAddress aFirstAddress;
429         ScUnoConversion::FillApiStartAddress( aFirstAddress, *aItr );
430         if( aFirstAddress == rMyCell.aCellAddress )
431         {
432             rMyCell.bHasEmptyDatabase = sal_True;
433             if( aItr->StartColumn < aItr->EndColumn )
434                 ++(aItr->StartColumn);
435             else
436                 aDatabaseList.erase(aItr);
437         }
438     }
439 }
440 
SkipTable(SCTAB nSkip)441 void ScMyEmptyDatabaseRangesContainer::SkipTable(SCTAB nSkip)
442 {
443     ScMyEmptyDatabaseRangeList::iterator aItr = aDatabaseList.begin();
444     while( (aItr != aDatabaseList.end()) && (aItr->Sheet == nSkip) )
445         aItr = aDatabaseList.erase(aItr);
446 }
447 
Sort()448 void ScMyEmptyDatabaseRangesContainer::Sort()
449 {
450     aDatabaseList.sort();
451 }
452 
453 //==============================================================================
454 
operator <(const ScMyDetectiveObj & rDetObj) const455 sal_Bool ScMyDetectiveObj::operator<( const ScMyDetectiveObj& rDetObj) const
456 {
457     if( aPosition.Sheet != rDetObj.aPosition.Sheet )
458         return (aPosition.Sheet < rDetObj.aPosition.Sheet);
459     else if( aPosition.Row != rDetObj.aPosition.Row )
460         return (aPosition.Row < rDetObj.aPosition.Row);
461     else
462         return (aPosition.Column < rDetObj.aPosition.Column);
463 }
464 
ScMyDetectiveObjContainer()465 ScMyDetectiveObjContainer::ScMyDetectiveObjContainer() :
466     aDetectiveObjList()
467 {
468 }
469 
~ScMyDetectiveObjContainer()470 ScMyDetectiveObjContainer::~ScMyDetectiveObjContainer()
471 {
472 }
473 
AddObject(ScDetectiveObjType eObjType,const SCTAB nSheet,const ScAddress & rPosition,const ScRange & rSourceRange,sal_Bool bHasError)474 void ScMyDetectiveObjContainer::AddObject( ScDetectiveObjType eObjType, const SCTAB nSheet,
475                                             const ScAddress& rPosition, const ScRange& rSourceRange,
476                                             sal_Bool bHasError )
477 {
478     if( (eObjType == SC_DETOBJ_ARROW) ||
479         (eObjType == SC_DETOBJ_FROMOTHERTAB) ||
480         (eObjType == SC_DETOBJ_TOOTHERTAB) ||
481         (eObjType == SC_DETOBJ_CIRCLE) )
482     {
483         ScMyDetectiveObj aDetObj;
484         aDetObj.eObjType = eObjType;
485         if( eObjType == SC_DETOBJ_TOOTHERTAB )
486             ScUnoConversion::FillApiAddress( aDetObj.aPosition, rSourceRange.aStart );
487         else
488             ScUnoConversion::FillApiAddress( aDetObj.aPosition, rPosition );
489         ScUnoConversion::FillApiRange( aDetObj.aSourceRange, rSourceRange );
490 
491         // #111064#; take the sheet where the object is found and not the sheet given in the ranges, because they are not always true
492         if (eObjType != SC_DETOBJ_FROMOTHERTAB)
493         {
494             // if the ObjType == SC_DETOBJ_FROMOTHERTAB then the SourceRange is not used and so it has not to be tested and changed
495             DBG_ASSERT(aDetObj.aPosition.Sheet == aDetObj.aSourceRange.Sheet, "It seems to be possible to have different sheets");
496             aDetObj.aSourceRange.Sheet = nSheet;
497         }
498         aDetObj.aPosition.Sheet = nSheet;
499 
500         aDetObj.bHasError = bHasError;
501         aDetectiveObjList.push_back( aDetObj );
502     }
503 }
504 
GetFirstAddress(table::CellAddress & rCellAddress)505 sal_Bool ScMyDetectiveObjContainer::GetFirstAddress( table::CellAddress& rCellAddress )
506 {
507     sal_Int32 nTable(rCellAddress.Sheet);
508     if( !aDetectiveObjList.empty() )
509     {
510         rCellAddress = aDetectiveObjList.begin()->aPosition;
511         return (nTable == rCellAddress.Sheet);
512     }
513     return sal_False;
514 }
515 
SetCellData(ScMyCell & rMyCell)516 void ScMyDetectiveObjContainer::SetCellData( ScMyCell& rMyCell )
517 {
518     rMyCell.aDetectiveObjVec.clear();
519     ScMyDetectiveObjList::iterator aItr(aDetectiveObjList.begin());
520     ScMyDetectiveObjList::iterator aEndItr(aDetectiveObjList.end());
521     while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
522     {
523         rMyCell.aDetectiveObjVec.push_back( *aItr );
524         aItr = aDetectiveObjList.erase( aItr );
525     }
526     rMyCell.bHasDetectiveObj = (rMyCell.aDetectiveObjVec.size() != 0);
527 }
528 
SkipTable(SCTAB nSkip)529 void ScMyDetectiveObjContainer::SkipTable(SCTAB nSkip)
530 {
531     ScMyDetectiveObjList::iterator aItr = aDetectiveObjList.begin();
532     while( (aItr != aDetectiveObjList.end()) && (aItr->aPosition.Sheet == nSkip) )
533         aItr = aDetectiveObjList.erase(aItr);
534 }
535 
Sort()536 void ScMyDetectiveObjContainer::Sort()
537 {
538     aDetectiveObjList.sort();
539 }
540 
541 //==============================================================================
542 
operator <(const ScMyDetectiveOp & rDetOp) const543 sal_Bool ScMyDetectiveOp::operator<( const ScMyDetectiveOp& rDetOp) const
544 {
545     if( aPosition.Sheet != rDetOp.aPosition.Sheet )
546         return (aPosition.Sheet < rDetOp.aPosition.Sheet);
547     else if( aPosition.Row != rDetOp.aPosition.Row )
548         return (aPosition.Row < rDetOp.aPosition.Row);
549     else
550         return (aPosition.Column < rDetOp.aPosition.Column);
551 }
552 
ScMyDetectiveOpContainer()553 ScMyDetectiveOpContainer::ScMyDetectiveOpContainer() :
554     aDetectiveOpList()
555 {
556 }
557 
~ScMyDetectiveOpContainer()558 ScMyDetectiveOpContainer::~ScMyDetectiveOpContainer()
559 {
560 }
561 
AddOperation(ScDetOpType eOpType,const ScAddress & rPosition,sal_uInt32 nIndex)562 void ScMyDetectiveOpContainer::AddOperation( ScDetOpType eOpType, const ScAddress& rPosition, sal_uInt32 nIndex )
563 {
564     ScMyDetectiveOp aDetOp;
565     aDetOp.eOpType = eOpType;
566     ScUnoConversion::FillApiAddress( aDetOp.aPosition, rPosition );
567     aDetOp.nIndex = nIndex;
568     aDetectiveOpList.push_back( aDetOp );
569 }
570 
GetFirstAddress(table::CellAddress & rCellAddress)571 sal_Bool ScMyDetectiveOpContainer::GetFirstAddress( table::CellAddress& rCellAddress )
572 {
573     sal_Int32 nTable(rCellAddress.Sheet);
574     if( !aDetectiveOpList.empty() )
575     {
576         rCellAddress = aDetectiveOpList.begin()->aPosition;
577         return (nTable == rCellAddress.Sheet);
578     }
579     return sal_False;
580 }
581 
SetCellData(ScMyCell & rMyCell)582 void ScMyDetectiveOpContainer::SetCellData( ScMyCell& rMyCell )
583 {
584     rMyCell.aDetectiveOpVec.clear();
585     ScMyDetectiveOpList::iterator aItr(aDetectiveOpList.begin());
586     ScMyDetectiveOpList::iterator aEndItr(aDetectiveOpList.end());
587     while( (aItr != aEndItr) && (aItr->aPosition == rMyCell.aCellAddress) )
588     {
589         rMyCell.aDetectiveOpVec.push_back( *aItr );
590         aItr = aDetectiveOpList.erase( aItr );
591     }
592     rMyCell.bHasDetectiveOp = (rMyCell.aDetectiveOpVec.size() != 0);
593 }
594 
SkipTable(SCTAB nSkip)595 void ScMyDetectiveOpContainer::SkipTable(SCTAB nSkip)
596 {
597     ScMyDetectiveOpList::iterator aItr = aDetectiveOpList.begin();
598     while( (aItr != aDetectiveOpList.end()) && (aItr->aPosition.Sheet == nSkip) )
599         aItr = aDetectiveOpList.erase(aItr);
600 }
601 
Sort()602 void ScMyDetectiveOpContainer::Sort()
603 {
604     aDetectiveOpList.sort();
605 }
606 
607 //==============================================================================
608 
ScMyCell()609 ScMyCell::ScMyCell() :
610     aShapeList(),
611     aDetectiveObjVec(),
612     nValidationIndex(-1),
613     pBaseCell(NULL),
614     bIsAutoStyle( sal_False ),
615     bHasShape( sal_False ),
616     bIsMergedBase( sal_False ),
617     bIsCovered( sal_False ),
618     bHasAreaLink( sal_False ),
619     bHasEmptyDatabase( sal_False ),
620     bHasDetectiveObj( sal_False ),
621     bHasDetectiveOp( sal_False ),
622     bIsEditCell( sal_False ),
623     bKnowWhetherIsEditCell( sal_False ),
624     bHasStringValue( sal_False ),
625     bHasDoubleValue( sal_False ),
626     bHasXText( sal_False ),
627     bIsMatrixBase( sal_False ),
628     bIsMatrixCovered( sal_False ),
629     bHasAnnotation( sal_False )
630 {
631 }
632 
~ScMyCell()633 ScMyCell::~ScMyCell()
634 {
635 }
636 
637 //==============================================================================
638 
operator <(const ScMyExportAnnotation & rAnno) const639 sal_Bool ScMyExportAnnotation::operator<(const ScMyExportAnnotation& rAnno) const
640 {
641     if( aCellAddress.Row != rAnno.aCellAddress.Row )
642         return (aCellAddress.Row < rAnno.aCellAddress.Row);
643     else
644         return (aCellAddress.Column < rAnno.aCellAddress.Column);
645 }
646 
647 
ScMyNotEmptyCellsIterator(ScXMLExport & rTempXMLExport)648 ScMyNotEmptyCellsIterator::ScMyNotEmptyCellsIterator(ScXMLExport& rTempXMLExport)
649     : pShapes(NULL),
650     pNoteShapes(NULL),
651     pEmptyDatabaseRanges(NULL),
652     pMergedRanges(NULL),
653     pAreaLinks(NULL),
654     pDetectiveObj(NULL),
655     pDetectiveOp(NULL),
656     rExport(rTempXMLExport),
657     pCellItr(NULL),
658     nCurrentTable(SCTAB_MAX)
659 {
660 }
661 
~ScMyNotEmptyCellsIterator()662 ScMyNotEmptyCellsIterator::~ScMyNotEmptyCellsIterator()
663 {
664     Clear();
665 }
666 
Clear()667 void ScMyNotEmptyCellsIterator::Clear()
668 {
669     if (pCellItr)
670         delete pCellItr;
671     if (!aAnnotations.empty())
672     {
673         DBG_ERROR("not all Annotations saved");
674         aAnnotations.clear();
675     }
676     pCellItr = NULL;
677     pShapes = NULL;
678     pNoteShapes = NULL;
679     pMergedRanges = NULL;
680     pAreaLinks = NULL;
681     pEmptyDatabaseRanges = NULL;
682     pDetectiveObj = NULL;
683     pDetectiveOp = NULL;
684     nCurrentTable = SCTAB_MAX;
685 }
686 
UpdateAddress(table::CellAddress & rAddress)687 void ScMyNotEmptyCellsIterator::UpdateAddress( table::CellAddress& rAddress )
688 {
689     if( pCellItr->ReturnNext( nCellCol, nCellRow ) )
690     {
691         rAddress.Column = nCellCol;
692         rAddress.Row = nCellRow;
693     }
694 }
695 
SetCellData(ScMyCell & rMyCell,table::CellAddress & rAddress)696 void ScMyNotEmptyCellsIterator::SetCellData( ScMyCell& rMyCell, table::CellAddress& rAddress )
697 {
698     rMyCell.aCellAddress = rAddress;
699     rMyCell.bHasStringValue = sal_False;
700     rMyCell.bHasDoubleValue = sal_False;
701     rMyCell.bHasXText = sal_False;
702     rMyCell.bKnowWhetherIsEditCell = sal_False;
703     rMyCell.bIsEditCell = sal_False;
704     if( (nCellCol == rAddress.Column) && (nCellRow == rAddress.Row) )
705         pCellItr->GetNext( nCellCol, nCellRow );
706 }
707 
SetMatrixCellData(ScMyCell & rMyCell)708 void ScMyNotEmptyCellsIterator::SetMatrixCellData( ScMyCell& rMyCell )
709 {
710     rMyCell.bIsMatrixCovered = sal_False;
711     rMyCell.bIsMatrixBase = sal_False;
712 
713     sal_Bool bIsMatrixBase(sal_False);
714 
715     ScAddress aScAddress;
716     ScUnoConversion::FillScAddress( aScAddress, rMyCell.aCellAddress );
717     CellType eCalcType = rExport.GetDocument()->GetCellType( aScAddress );
718     switch (eCalcType)
719     {
720         case CELLTYPE_VALUE:
721             rMyCell.nType = table::CellContentType_VALUE;
722             break;
723         case CELLTYPE_STRING:
724         case CELLTYPE_EDIT:
725             rMyCell.nType = table::CellContentType_TEXT;
726             break;
727         case CELLTYPE_FORMULA:
728             rMyCell.nType = table::CellContentType_FORMULA;
729             break;
730         default:
731             rMyCell.nType = table::CellContentType_EMPTY;
732     }
733 
734     if (rMyCell.nType == table::CellContentType_FORMULA)
735         if( rExport.IsMatrix( aScAddress, rMyCell.aMatrixRange, bIsMatrixBase ) )
736         {
737             rMyCell.bIsMatrixBase = bIsMatrixBase;
738             rMyCell.bIsMatrixCovered = !bIsMatrixBase;
739         }
740 }
741 
HasAnnotation(ScMyCell & aCell)742 void ScMyNotEmptyCellsIterator::HasAnnotation(ScMyCell& aCell)
743 {
744     aCell.bHasAnnotation = sal_False;
745     if (!aAnnotations.empty())
746     {
747         ScMyExportAnnotationList::iterator aItr(aAnnotations.begin());
748         if ((aCell.aCellAddress.Column == aItr->aCellAddress.Column) &&
749             (aCell.aCellAddress.Row == aItr->aCellAddress.Row))
750         {
751             aCell.xAnnotation.set(aItr->xAnnotation);
752             uno::Reference<text::XSimpleText> xSimpleText(aCell.xAnnotation, uno::UNO_QUERY);
753             if (aCell.xAnnotation.is() && xSimpleText.is())
754             {
755                 aCell.sAnnotationText = xSimpleText->getString();
756                 if (aCell.sAnnotationText.getLength())
757                     aCell.bHasAnnotation = sal_True;
758             }
759             aAnnotations.erase(aItr);
760         }
761     }
762 
763     // test - bypass the API
764     // if (xCellRange.is())
765     //  aCell.xCell.set(xCellRange->getCellByPosition(aCell.aCellAddress.Column, aCell.aCellAddress.Row));
766 }
767 
SetCurrentTable(const SCTAB nTable,uno::Reference<sheet::XSpreadsheet> & rxTable)768 void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable,
769     uno::Reference<sheet::XSpreadsheet>& rxTable)
770 {
771     DBG_ASSERT(aAnnotations.empty(), "not all Annotations saved");
772     aLastAddress.Row = 0;
773     aLastAddress.Column = 0;
774     aLastAddress.Sheet = nTable;
775     if (nCurrentTable != nTable)
776     {
777         nCurrentTable = nTable;
778         if (pCellItr)
779             delete pCellItr;
780         pCellItr = new ScHorizontalCellIterator(rExport.GetDocument(), nCurrentTable, 0, 0,
781             static_cast<SCCOL>(rExport.GetSharedData()->GetLastColumn(nCurrentTable)), static_cast<SCROW>(rExport.GetSharedData()->GetLastRow(nCurrentTable)));
782         xTable.set(rxTable);
783         xCellRange.set(xTable, uno::UNO_QUERY);
784         uno::Reference<sheet::XSheetAnnotationsSupplier> xSheetAnnotationsSupplier (xTable, uno::UNO_QUERY);
785         if (xSheetAnnotationsSupplier.is())
786         {
787             uno::Reference<container::XEnumerationAccess> xAnnotationAccess ( xSheetAnnotationsSupplier->getAnnotations(), uno::UNO_QUERY);
788             if (xAnnotationAccess.is())
789             {
790                 uno::Reference<container::XEnumeration> xAnnotations(xAnnotationAccess->createEnumeration());
791                 if (xAnnotations.is())
792                 {
793                     while (xAnnotations->hasMoreElements())
794                     {
795                         ScMyExportAnnotation aAnnotation;
796                         aAnnotation.xAnnotation.set(xAnnotations->nextElement(), uno::UNO_QUERY);
797                         if (aAnnotation.xAnnotation.is())
798                         {
799                             aAnnotation.aCellAddress = aAnnotation.xAnnotation->getPosition();
800                             aAnnotations.push_back(aAnnotation);
801                         }
802                     }
803                     if (!aAnnotations.empty())
804                         aAnnotations.sort();
805                 }
806             }
807         }
808     }
809 }
810 
SkipTable(SCTAB nSkip)811 void ScMyNotEmptyCellsIterator::SkipTable(SCTAB nSkip)
812 {
813     // Skip entries for a sheet that is copied instead of saving normally.
814     // Cells (including aAnnotations) are handled separately in SetCurrentTable.
815 
816     if( pShapes )
817         pShapes->SkipTable(nSkip);
818     if( pNoteShapes )
819         pNoteShapes->SkipTable(nSkip);
820     if( pEmptyDatabaseRanges )
821         pEmptyDatabaseRanges->SkipTable(nSkip);
822     if( pMergedRanges )
823         pMergedRanges->SkipTable(nSkip);
824     if( pAreaLinks )
825         pAreaLinks->SkipTable(nSkip);
826     if( pDetectiveObj )
827         pDetectiveObj->SkipTable(nSkip);
828     if( pDetectiveOp )
829         pDetectiveOp->SkipTable(nSkip);
830 }
831 
GetNext(ScMyCell & aCell,ScFormatRangeStyles * pCellStyles)832 sal_Bool ScMyNotEmptyCellsIterator::GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles)
833 {
834     table::CellAddress  aAddress( nCurrentTable, MAXCOL + 1, MAXROW + 1 );
835 
836     UpdateAddress( aAddress );
837     if( pShapes )
838         pShapes->UpdateAddress( aAddress );
839     if( pNoteShapes )
840         pNoteShapes->UpdateAddress( aAddress );
841     if( pEmptyDatabaseRanges )
842         pEmptyDatabaseRanges->UpdateAddress( aAddress );
843     if( pMergedRanges )
844         pMergedRanges->UpdateAddress( aAddress );
845     if( pAreaLinks )
846         pAreaLinks->UpdateAddress( aAddress );
847     if( pDetectiveObj )
848         pDetectiveObj->UpdateAddress( aAddress );
849     if( pDetectiveOp )
850         pDetectiveOp->UpdateAddress( aAddress );
851 
852     sal_Bool bFoundCell((aAddress.Column <= MAXCOL) && (aAddress.Row <= MAXROW));
853     if( bFoundCell )
854     {
855         SetCellData( aCell, aAddress );
856         if( pShapes )
857             pShapes->SetCellData( aCell );
858         if( pNoteShapes )
859             pNoteShapes->SetCellData( aCell );
860         if( pEmptyDatabaseRanges )
861             pEmptyDatabaseRanges->SetCellData( aCell );
862         if( pMergedRanges )
863             pMergedRanges->SetCellData( aCell );
864         if( pAreaLinks )
865             pAreaLinks->SetCellData( aCell );
866         if( pDetectiveObj )
867             pDetectiveObj->SetCellData( aCell );
868         if( pDetectiveOp )
869             pDetectiveOp->SetCellData( aCell );
870 
871         HasAnnotation( aCell );
872         SetMatrixCellData( aCell );
873         sal_Bool bIsAutoStyle;
874         // Ranges before the previous cell are not needed by ExportFormatRanges anymore and can be removed
875         sal_Int32 nRemoveBeforeRow = aLastAddress.Row;
876         aCell.nStyleIndex = pCellStyles->GetStyleNameIndex(aCell.aCellAddress.Sheet,
877             aCell.aCellAddress.Column, aCell.aCellAddress.Row,
878             bIsAutoStyle, aCell.nValidationIndex, aCell.nNumberFormat, nRemoveBeforeRow);
879         aLastAddress = aCell.aCellAddress;
880         aCell.bIsAutoStyle = bIsAutoStyle;
881 
882         //#102799#; if the cell is in a DatabaseRange which should saved empty, the cell should have the type empty
883         if (aCell.bHasEmptyDatabase)
884             aCell.nType = table::CellContentType_EMPTY;
885     }
886     return bFoundCell;
887 }
888 
889