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