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