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