1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "patattr.hxx"
22 #include "docpool.hxx"
23 #include "formulacell.hxx"
24 #include "document.hxx"
25 #include "drwlayer.hxx"
26 #include "olinetab.hxx"
27 #include "rechead.hxx"
28 #include "stlpool.hxx"
29 #include "attarray.hxx" // Iterator
30 #include "markdata.hxx"
31 #include "progress.hxx"
32 #include "dociter.hxx"
33 #include "conditio.hxx"
34 #include "chartlis.hxx"
35 #include "fillinfo.hxx"
36 #include "bcaslot.hxx"
38 #include "sheetevents.hxx"
39 #include "globstr.hrc"
40 #include "segmenttree.hxx"
41 #include "queryparam.hxx"
42 #include "queryentry.hxx"
44 #include "colorscale.hxx"
45 #include "tokenarray.hxx"
46 #include "clipcontext.hxx"
48 #include "scitems.hxx"
49 #include <editeng/boxitem.hxx>
50 #include "editeng/editobj.hxx"
51 #include <svl/poolcach.hxx>
52 #include <unotools/charclass.hxx>
54 #include <svl/PasswordHelper.hxx>
55 #include <unotools/transliterationwrapper.hxx>
57 // STATIC DATA -----------------------------------------------------------
59 sal_uInt16
ScTable::GetTextWidth(SCCOL nCol
, SCROW nRow
) const
61 return aCol
[nCol
].GetTextWidth(nRow
);
64 void ScTable::SetTextWidth(SCCOL nCol
, SCROW nRow
, sal_uInt16 nWidth
)
66 aCol
[nCol
].SetTextWidth(nRow
, nWidth
);
69 bool ScTable::SetOutlineTable( const ScOutlineTable
* pNewOutline
)
71 sal_uInt16 nOldSizeX
= 0;
72 sal_uInt16 nOldSizeY
= 0;
73 sal_uInt16 nNewSizeX
= 0;
74 sal_uInt16 nNewSizeY
= 0;
78 nOldSizeX
= pOutlineTable
->GetColArray()->GetDepth();
79 nOldSizeY
= pOutlineTable
->GetRowArray()->GetDepth();
85 pOutlineTable
= new ScOutlineTable( *pNewOutline
);
86 nNewSizeX
= pOutlineTable
->GetColArray()->GetDepth();
87 nNewSizeY
= pOutlineTable
->GetRowArray()->GetDepth();
92 return ( nNewSizeX
!= nOldSizeX
|| nNewSizeY
!= nOldSizeY
); // Groesse geaendert ?
96 void ScTable::StartOutlineTable()
99 pOutlineTable
= new ScOutlineTable
;
103 void ScTable::SetSheetEvents( const ScSheetEvents
* pNew
)
107 pSheetEvents
= new ScSheetEvents(*pNew
);
111 SetCalcNotification( false ); // discard notifications before the events were set
114 SetStreamValid(false);
118 void ScTable::SetCalcNotification( bool bSet
)
120 bCalcNotification
= bSet
;
124 bool ScTable::TestInsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCSIZE nSize
) const
128 if ( nStartCol
==0 && nEndCol
==MAXCOL
&& pOutlineTable
)
129 bTest
= pOutlineTable
->TestInsertRow(nSize
);
131 for (SCCOL i
=nStartCol
; (i
<=nEndCol
) && bTest
; i
++)
132 bTest
= aCol
[i
].TestInsertRow( nSize
);
138 void ScTable::InsertRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
)
140 if (nStartCol
==0 && nEndCol
==MAXCOL
)
142 if (mpRowHeights
&& pRowFlags
)
144 mpRowHeights
->insertSegment(nStartRow
, nSize
, false);
145 sal_uInt8 nNewFlags
= pRowFlags
->Insert( nStartRow
, nSize
);
146 // only copy manual size flag, clear all others
147 if (nNewFlags
&& (nNewFlags
!= CR_MANUALSIZE
))
148 pRowFlags
->SetValue( nStartRow
, nStartRow
+ nSize
- 1,
149 nNewFlags
& CR_MANUALSIZE
);
153 pOutlineTable
->InsertRow( nStartRow
, nSize
);
155 mpFilteredRows
->insertSegment(nStartRow
, nSize
, true);
156 mpHiddenRows
->insertSegment(nStartRow
, nSize
, true);
158 if (!maRowManualBreaks
.empty())
160 // Copy all breaks up to nStartRow (non-inclusive).
161 ::std::set
<SCROW
>::iterator itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
162 ::std::set
<SCROW
> aNewBreaks(maRowManualBreaks
.begin(), itr1
);
164 // Copy all breaks from nStartRow (inclusive) to the last element,
165 // but add nSize to each value.
166 ::std::set
<SCROW
>::iterator itr2
= maRowManualBreaks
.end();
167 for (; itr1
!= itr2
; ++itr1
)
168 aNewBreaks
.insert(static_cast<SCROW
>(*itr1
+ nSize
));
170 maRowManualBreaks
.swap(aNewBreaks
);
174 for (SCCOL j
=nStartCol
; j
<=nEndCol
; j
++)
175 aCol
[j
].InsertRow( nStartRow
, nSize
);
177 // Transfer those notes that will get shifted into another container.
178 ScNotes
aNotes(pDocument
);
179 ScNotes::iterator itr
= maNotes
.begin();
180 while( itr
!= maNotes
.end() )
182 SCCOL nCol
= itr
->first
.first
;
183 SCROW nRow
= itr
->first
.second
;
184 ScPostIt
* pPostIt
= itr
->second
;
187 if (nStartRow
<= nRow
&& nStartCol
<= nCol
&& nCol
<= nEndCol
)
189 aNotes
.insert(nCol
, nRow
+ nSize
, pPostIt
);
190 maNotes
.ReleaseNote(nCol
, nRow
);
194 // Re-insert the shifted notes.
195 itr
= aNotes
.begin();
196 while( itr
!= aNotes
.end() )
198 SCCOL nCol
= itr
->first
.first
;
199 SCROW nRow
= itr
->first
.second
;
200 ScPostIt
* pPostIt
= itr
->second
;
203 maNotes
.insert( nCol
, nRow
, pPostIt
);
204 aNotes
.ReleaseNote( nCol
, nRow
);
207 InvalidatePageBreaks();
210 // TODO: In the future we may want to check if the table has been
211 // really modified before setting the stream invalid.
212 SetStreamValid(false);
216 void ScTable::DeleteRow( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCSIZE nSize
,
219 if (nStartCol
==0 && nEndCol
==MAXCOL
)
222 pRowFlags
->Remove( nStartRow
, nSize
);
225 mpRowHeights
->removeSegment(nStartRow
, nStartRow
+nSize
);
228 if (pOutlineTable
->DeleteRow( nStartRow
, nSize
))
230 *pUndoOutline
= true;
232 mpFilteredRows
->removeSegment(nStartRow
, nStartRow
+nSize
);
233 mpHiddenRows
->removeSegment(nStartRow
, nStartRow
+nSize
);
235 if (!maRowManualBreaks
.empty())
237 // Erase all manual breaks between nStartRow and nStartRow + nSize - 1 (inclusive).
238 std::set
<SCROW
>::iterator itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
239 std::set
<SCROW
>::iterator itr2
= maRowManualBreaks
.upper_bound(static_cast<SCROW
>(nStartRow
+ nSize
- 1));
240 maRowManualBreaks
.erase(itr1
, itr2
);
242 // Copy all breaks from the 1st element up to nStartRow to the new container.
243 itr1
= maRowManualBreaks
.lower_bound(nStartRow
);
244 ::std::set
<SCROW
> aNewBreaks(maRowManualBreaks
.begin(), itr1
);
246 // Copy all breaks from nStartRow to the last element, but subtract each value by nSize.
247 itr2
= maRowManualBreaks
.end();
248 for (; itr1
!= itr2
; ++itr1
)
249 aNewBreaks
.insert(static_cast<SCROW
>(*itr1
- nSize
));
251 maRowManualBreaks
.swap(aNewBreaks
);
255 // Transfer those notes that will get shifted into another container.
256 ScNotes
aNotes(pDocument
);
257 ScNotes::iterator itr
= maNotes
.begin();
258 while( itr
!= maNotes
.end() )
260 SCCOL nCol
= itr
->first
.first
;
261 SCROW nRow
= itr
->first
.second
;
262 ScPostIt
* pPostIt
= itr
->second
;
265 if (nStartRow
<= nRow
&& nStartCol
<= nCol
&& nCol
<= nEndCol
)
267 SCROW nEndRow
= nStartRow
+ nSize
- 1; // last row of deleted region
270 // This note will get shifted.
271 aNotes
.insert(nCol
, nRow
- nSize
, pPostIt
);
272 maNotes
.ReleaseNote(nCol
, nRow
);
275 // Note is in the deleted area. Remove it.
276 maNotes
.erase(nCol
, nRow
);
280 // Re-insert the shifted notes.
281 itr
= aNotes
.begin();
282 while( itr
!= aNotes
.end() )
284 SCCOL nCol
= itr
->first
.first
;
285 SCROW nRow
= itr
->first
.second
;
286 ScPostIt
* pPostIt
= itr
->second
;
289 maNotes
.insert( nCol
, nRow
, pPostIt
);
290 aNotes
.ReleaseNote( nCol
, nRow
);
293 { // scope for bulk broadcast
294 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
295 for (SCCOL j
=nStartCol
; j
<=nEndCol
; j
++)
296 aCol
[j
].DeleteRow( nStartRow
, nSize
);
299 InvalidatePageBreaks();
302 // TODO: In the future we may want to check if the table has been
303 // really modified before setting the stream invalid.
304 SetStreamValid(false);
308 bool ScTable::TestInsertCol( SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
) const
312 if ( nStartRow
==0 && nEndRow
==MAXROW
&& pOutlineTable
)
313 bTest
= pOutlineTable
->TestInsertCol(nSize
);
315 if ( nSize
> static_cast<SCSIZE
>(MAXCOL
) )
318 for (SCCOL i
=MAXCOL
; (i
+static_cast<SCCOL
>(nSize
)>MAXCOL
) && bTest
; i
--)
319 bTest
= aCol
[i
].TestInsertCol(nStartRow
, nEndRow
);
325 void ScTable::InsertCol( SCCOL nStartCol
, SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
)
327 if (nStartRow
==0 && nEndRow
==MAXROW
)
329 if (pColWidth
&& pColFlags
)
331 memmove( &pColWidth
[nStartCol
+nSize
], &pColWidth
[nStartCol
],
332 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColWidth
[0]) );
333 memmove( &pColFlags
[nStartCol
+nSize
], &pColFlags
[nStartCol
],
334 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColFlags
[0]) );
337 pOutlineTable
->InsertCol( nStartCol
, nSize
);
339 mpHiddenCols
->insertSegment(nStartCol
, static_cast<SCCOL
>(nSize
), true);
340 mpFilteredCols
->insertSegment(nStartCol
, static_cast<SCCOL
>(nSize
), true);
342 if (!maColManualBreaks
.empty())
344 std::set
<SCCOL
>::reverse_iterator rit
= maColManualBreaks
.rbegin();
345 while (rit
!= maColManualBreaks
.rend())
348 if (nCol
< nStartCol
)
352 maColManualBreaks
.erase( (++rit
).base());
353 maColManualBreaks
.insert( static_cast<SCCOL
>( nCol
+ nSize
));
360 if ((nStartRow
== 0) && (nEndRow
== MAXROW
))
362 for (SCSIZE i
=0; i
< nSize
; i
++)
363 for (SCCOL nCol
= MAXCOL
; nCol
> nStartCol
; nCol
--)
364 aCol
[nCol
].SwapCol(aCol
[nCol
-1]);
368 for (SCSIZE i
=0; static_cast<SCCOL
>(i
+nSize
)+nStartCol
<= MAXCOL
; i
++)
369 aCol
[MAXCOL
- nSize
- i
].MoveTo(nStartRow
, nEndRow
, aCol
[MAXCOL
- i
]);
372 // Transfer those notes that will get shifted into another container.
373 ScNotes
aNotes(pDocument
);
374 ScNotes::iterator itr
= maNotes
.begin();
375 while( itr
!= maNotes
.end() )
377 SCCOL nCol
= itr
->first
.first
;
378 SCROW nRow
= itr
->first
.second
;
379 ScPostIt
* pPostIt
= itr
->second
;
382 if (nStartCol
<= nCol
&& nStartRow
<= nRow
&& nRow
<= nEndRow
)
384 aNotes
.insert(nCol
+ nSize
, nRow
, pPostIt
);
385 maNotes
.ReleaseNote(nCol
, nRow
);
389 // Re-insert the shifted notes.
390 itr
= aNotes
.begin();
391 while( itr
!= aNotes
.end() )
393 SCCOL nCol
= itr
->first
.first
;
394 SCROW nRow
= itr
->first
.second
;
395 ScPostIt
* pPostIt
= itr
->second
;
398 maNotes
.insert( nCol
, nRow
, pPostIt
);
399 aNotes
.ReleaseNote( nCol
, nRow
);
402 if (nStartCol
>0) // copy old attributes
404 sal_uInt16 nWhichArray
[3];
405 nWhichArray
[0] = ATTR_MERGE
;
406 nWhichArray
[1] = ATTR_CONDITIONAL
;
409 sc::CopyToDocContext
aCxt(*pDocument
);
410 for (SCSIZE i
=0; i
<nSize
; i
++)
412 aCol
[nStartCol
-1].CopyToColumn(aCxt
, nStartRow
, nEndRow
, IDF_ATTRIB
,
413 false, aCol
[nStartCol
+i
] );
414 aCol
[nStartCol
+i
].RemoveFlags( nStartRow
, nEndRow
,
415 SC_MF_HOR
| SC_MF_VER
| SC_MF_AUTO
);
416 aCol
[nStartCol
+i
].ClearItems( nStartRow
, nEndRow
, nWhichArray
);
420 InvalidatePageBreaks();
423 // TODO: In the future we may want to check if the table has been
424 // really modified before setting the stream invalid.
425 SetStreamValid(false);
429 void ScTable::DeleteCol( SCCOL nStartCol
, SCROW nStartRow
, SCROW nEndRow
, SCSIZE nSize
,
432 if (nStartRow
==0 && nEndRow
==MAXROW
)
434 if (pColWidth
&& pColFlags
)
436 memmove( &pColWidth
[nStartCol
], &pColWidth
[nStartCol
+nSize
],
437 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColWidth
[0]) );
438 memmove( &pColFlags
[nStartCol
], &pColFlags
[nStartCol
+nSize
],
439 (MAXCOL
- nStartCol
+ 1 - nSize
) * sizeof(pColFlags
[0]) );
442 if (pOutlineTable
->DeleteCol( nStartCol
, nSize
))
444 *pUndoOutline
= true;
446 SCCOL nRmSize
= nStartCol
+ static_cast<SCCOL
>(nSize
);
447 mpHiddenCols
->removeSegment(nStartCol
, nRmSize
);
448 mpFilteredCols
->removeSegment(nStartCol
, nRmSize
);
450 if (!maColManualBreaks
.empty())
452 std::set
<SCCOL
>::iterator it
= maColManualBreaks
.upper_bound( static_cast<SCCOL
>( nStartCol
+ nSize
- 1));
453 maColManualBreaks
.erase( maColManualBreaks
.lower_bound( nStartCol
), it
);
454 while (it
!= maColManualBreaks
.end())
457 maColManualBreaks
.erase( it
++);
458 maColManualBreaks
.insert( static_cast<SCCOL
>( nCol
- nSize
));
464 { // scope for bulk broadcast
465 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
466 for (SCSIZE i
= 0; i
< nSize
; i
++)
467 aCol
[nStartCol
+ i
].DeleteArea(nStartRow
, nEndRow
, IDF_ALL
);
470 if ((nStartRow
== 0) && (nEndRow
== MAXROW
))
472 for (SCSIZE i
=0; i
< nSize
; i
++)
473 for (SCCOL nCol
= nStartCol
; nCol
< MAXCOL
; nCol
++)
474 aCol
[nCol
].SwapCol(aCol
[nCol
+1]);
478 for (SCSIZE i
=0; static_cast<SCCOL
>(i
+nSize
)+nStartCol
<= MAXCOL
; i
++)
479 aCol
[nStartCol
+ nSize
+ i
].MoveTo(nStartRow
, nEndRow
, aCol
[nStartCol
+ i
]);
482 // Transfer those notes that will get shifted into another container.
483 ScNotes
aNotes(pDocument
);
484 ScNotes::iterator itr
= maNotes
.begin();
485 while( itr
!= maNotes
.end() )
487 SCCOL nCol
= itr
->first
.first
;
488 SCROW nRow
= itr
->first
.second
;
489 ScPostIt
* pPostIt
= itr
->second
;
492 if (nStartCol
<= nCol
&& nStartRow
<= nRow
&& nRow
<= nEndRow
)
494 SCCOL nEndCol
= nStartCol
+ nSize
- 1;
497 // This note will get shifted.
498 aNotes
.insert(nCol
- nSize
, nRow
, pPostIt
);
499 maNotes
.ReleaseNote(nCol
, nRow
);
502 // The note is in the deleted region. Remove it.
503 maNotes
.erase(nCol
, nRow
);
507 // Re-insert the shifted notes.
508 itr
= aNotes
.begin();
509 while( itr
!= aNotes
.end() )
511 SCCOL nCol
= itr
->first
.first
;
512 SCROW nRow
= itr
->first
.second
;
513 ScPostIt
* pPostIt
= itr
->second
;
516 maNotes
.insert( nCol
, nRow
, pPostIt
);
517 aNotes
.ReleaseNote( nCol
, nRow
);
520 InvalidatePageBreaks();
523 // TODO: In the future we may want to check if the table has been
524 // really modified before setting the stream invalid.
525 SetStreamValid(false);
529 void ScTable::DeleteArea(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, sal_uInt16 nDelFlag
)
531 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
532 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
533 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
535 { // scope for bulk broadcast
536 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
537 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
538 aCol
[i
].DeleteArea(nRow1
, nRow2
, nDelFlag
);
542 // Zellschutz auf geschuetzter Tabelle nicht setzen
545 if ( IsProtected() && (nDelFlag
& IDF_ATTRIB
) )
547 ScPatternAttr
aPattern(pDocument
->GetPool());
548 aPattern
.GetItemSet().Put( ScProtectionAttr( false ) );
549 ApplyPatternArea( nCol1
, nRow1
, nCol2
, nRow2
, aPattern
);
552 if( nDelFlag
& IDF_ATTRIB
)
553 mpCondFormatList
->DeleteArea( nCol1
, nRow1
, nCol2
, nRow2
);
556 if (nDelFlag
& IDF_NOTE
)
557 maNotes
.erase( nCol1
, nRow1
, nCol2
, nRow2
);
560 // TODO: In the future we may want to check if the table has been
561 // really modified before setting the stream invalid.
562 SetStreamValid(false);
566 void ScTable::DeleteSelection( sal_uInt16 nDelFlag
, const ScMarkData
& rMark
)
568 { // scope for bulk broadcast
569 ScBulkBroadcast
aBulkBroadcast( pDocument
->GetBASM());
570 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
571 aCol
[i
].DeleteSelection( nDelFlag
, rMark
);
574 ScRangeList aRangeList
;
575 rMark
.FillRangeListWithMarks(&aRangeList
, false);
577 for (size_t i
= 0; i
< aRangeList
.size(); ++i
)
579 ScRange
* pRange
= aRangeList
[i
];
580 if (nDelFlag
& IDF_NOTE
&& pRange
)
582 maNotes
.erase(pRange
->aStart
.Col(), pRange
->aStart
.Row(), pRange
->aEnd
.Col(), pRange
->aEnd
.Row(), nDelFlag
& IDF_NOCAPTIONS
);
585 if((nDelFlag
& IDF_ATTRIB
) && pRange
&& pRange
->aStart
.Tab() == nTab
)
586 mpCondFormatList
->DeleteArea( pRange
->aStart
.Col(), pRange
->aStart
.Row(), pRange
->aEnd
.Col(), pRange
->aEnd
.Row() );
590 // Zellschutz auf geschuetzter Tabelle nicht setzen
593 if ( IsProtected() && (nDelFlag
& IDF_ATTRIB
) )
595 ScDocumentPool
* pPool
= pDocument
->GetPool();
596 SfxItemSet
aSet( *pPool
, ATTR_PATTERN_START
, ATTR_PATTERN_END
);
597 aSet
.Put( ScProtectionAttr( false ) );
598 SfxItemPoolCache
aCache( pPool
, &aSet
);
599 ApplySelectionCache( &aCache
, rMark
);
603 // TODO: In the future we may want to check if the table has been
604 // really modified before setting the stream invalid.
605 SetStreamValid(false);
609 // pTable = Clipboard
610 void ScTable::CopyToClip(
611 sc::CopyToClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
614 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
617 //local range names need to be copied first for formula cells
618 if (!pTable
->mpRangeName
&& mpRangeName
)
619 pTable
->mpRangeName
= new ScRangeName(*mpRangeName
);
623 pTable
->pDocument
, nCol1
, nRow1
, nCol2
, nRow2
, rCxt
.isCloneNotes(), nTab
, pTable
->maNotes
);
627 for ( i
= nCol1
; i
<= nCol2
; i
++)
628 aCol
[i
].CopyToClip(rCxt
, nRow1
, nRow2
, pTable
->aCol
[i
]);
630 // copy widths/heights, and only "hidden", "filtered" and "manual" flags
631 // also for all preceding columns/rows, to have valid positions for drawing objects
633 if (pColWidth
&& pTable
->pColWidth
)
634 for (i
=0; i
<=nCol2
; i
++)
635 pTable
->pColWidth
[i
] = pColWidth
[i
];
637 pTable
->CopyColHidden(*this, 0, nCol2
);
638 pTable
->CopyColFiltered(*this, 0, nCol2
);
640 pTable
->SetAnonymousDBData(new ScDBData(*pDBDataNoName
));
643 if (pRowFlags
&& pTable
->pRowFlags
&& mpRowHeights
&& pTable
->mpRowHeights
)
645 pTable
->pRowFlags
->CopyFromAnded( *pRowFlags
, 0, nRow2
, CR_MANUALSIZE
);
646 pTable
->CopyRowHeight(*this, 0, nRow2
, 0);
649 pTable
->CopyRowHidden(*this, 0, nRow2
);
650 pTable
->CopyRowFiltered(*this, 0, nRow2
);
652 // ggf. Formeln durch Werte ersetzen
655 for (i
= nCol1
; i
<= nCol2
; i
++)
656 pTable
->aCol
[i
].RemoveProtected(nRow1
, nRow2
);
658 pTable
->mpCondFormatList
.reset(new ScConditionalFormatList(pTable
->pDocument
, *mpCondFormatList
));
662 void ScTable::CopyToClip(
663 sc::CopyToClipContext
& rCxt
, const ScRangeList
& rRanges
, ScTable
* pTable
)
665 ScRangeList
aRanges(rRanges
);
666 for ( size_t i
= 0, nListSize
= aRanges
.size(); i
< nListSize
; ++i
)
668 ScRange
* p
= aRanges
[ i
];
670 rCxt
, p
->aStart
.Col(), p
->aStart
.Row(), p
->aEnd
.Col(), p
->aEnd
.Row(), pTable
);
674 void ScTable::CopyStaticToDocument(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, ScTable
* pDestTab
)
679 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
681 ScColumn
& rSrcCol
= aCol
[i
];
682 ScColumn
& rDestCol
= pDestTab
->aCol
[i
];
683 rSrcCol
.CopyStaticToDocument(nRow1
, nRow2
, rDestCol
);
687 void ScTable::CopyCellToDocument(SCCOL nSrcCol
, SCROW nSrcRow
, SCCOL nDestCol
, SCROW nDestRow
, ScTable
& rDestTab
)
689 if (!ValidColRow(nSrcCol
, nSrcRow
) || !ValidColRow(nDestCol
, nDestRow
))
692 ScColumn
& rSrcCol
= aCol
[nSrcCol
];
693 ScColumn
& rDestCol
= rDestTab
.aCol
[nDestCol
];
694 rSrcCol
.CopyCellToDocument(nSrcRow
, nDestRow
, rDestCol
);
697 void ScTable::CopyConditionalFormat( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
698 SCsCOL nDx
, SCsROW nDy
, ScTable
* pTable
)
700 ScRange
aOldRange( nCol1
- nDx
, nRow1
- nDy
, pTable
->nTab
, nCol2
- nDx
, nRow2
- nDy
, pTable
->nTab
);
701 ScRange
aNewRange( nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
702 bool bSameDoc
= pDocument
== pTable
->pDocument
;
704 for(ScConditionalFormatList::const_iterator itr
= pTable
->mpCondFormatList
->begin(),
705 itrEnd
= pTable
->mpCondFormatList
->end(); itr
!= itrEnd
; ++itr
)
707 const ScRangeList
& rCondFormatRange
= itr
->GetRange();
708 if(!rCondFormatRange
.Intersects( aOldRange
))
711 ScRangeList aIntersectedRange
= rCondFormatRange
.GetIntersectedRange(aOldRange
);
712 ScConditionalFormat
* pNewFormat
= itr
->Clone(pDocument
);
714 pNewFormat
->AddRange(aIntersectedRange
);
715 pNewFormat
->UpdateReference(URM_COPY
, aNewRange
, nDx
, nDy
, nTab
- pTable
->nTab
, true);
718 for(ScConditionalFormatList::const_iterator itrCond
= mpCondFormatList
->begin();
719 itrCond
!= mpCondFormatList
->end(); ++itrCond
)
721 if(itrCond
->GetKey() > nMax
)
722 nMax
= itrCond
->GetKey();
724 pNewFormat
->SetKey(nMax
+ 1);
725 mpCondFormatList
->InsertNew(pNewFormat
);
729 for(size_t i
= 0, n
= pNewFormat
->size();
733 const ScFormatEntry
* pEntry
= pNewFormat
->GetEntry(i
);
734 if(pEntry
->GetType() == condformat::CONDITION
)
735 aStyleName
= static_cast<const ScCondFormatEntry
*>(pEntry
)->GetStyle();
736 else if(pEntry
->GetType() == condformat::DATE
)
737 aStyleName
= static_cast<const ScCondDateFormatEntry
*>(pEntry
)->GetStyleName();
739 if(!aStyleName
.isEmpty())
741 if(pDocument
->GetStyleSheetPool()->Find(aStyleName
, SFX_STYLE_FAMILY_PARA
))
744 pDocument
->GetStyleSheetPool()->CopyStyleFrom(
745 pTable
->pDocument
->GetStyleSheetPool(), aStyleName
, SFX_STYLE_FAMILY_PARA
);
750 pDocument
->AddCondFormatData( pNewFormat
->GetRange(), nTab
, pNewFormat
->GetKey() );
754 bool ScTable::InitColumnBlockPosition( sc::ColumnBlockPosition
& rBlockPos
, SCCOL nCol
)
759 return aCol
[nCol
].InitBlockPosition(rBlockPos
);
762 void ScTable::CopyFromClip(
763 sc::CopyFromClipContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
764 SCsCOL nDx
, SCsROW nDy
, ScTable
* pTable
)
772 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
774 for ( SCCOL i
= nCol1
; i
<= nCol2
; i
++)
775 aCol
[i
].CopyFromClip(rCxt
, nRow1
, nRow2
, nDy
, pTable
->aCol
[i
- nDx
]);
778 if (rCxt
.getInsertFlag() == IDF_ATTRIB
)
780 // make sure that there are no old references to the cond formats
781 sal_uInt16 nWhichArray
[2];
782 nWhichArray
[0] = ATTR_CONDITIONAL
;
784 for ( SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
785 aCol
[i
].ClearItems(nRow1
, nRow2
, nWhichArray
);
789 if (rCxt
.getInsertFlag() & (IDF_NOTE
|IDF_ADDNOTES
))
790 maNotes
.erase(nCol1
, nRow1
, nCol2
, nRow2
);
792 bool bAddNotes
= rCxt
.getInsertFlag() & (IDF_NOTE
| IDF_ADDNOTES
);
795 bool bCloneCaption
= (rCxt
.getInsertFlag() & IDF_NOCAPTIONS
) == 0;
796 maNotes
.CopyFromClip(pTable
->maNotes
, pDocument
, nCol1
, nRow1
, nCol2
, nRow2
, nDx
, nDy
, nTab
, bCloneCaption
);
800 if ((rCxt
.getInsertFlag() & IDF_ATTRIB
) != 0)
802 if (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pTable
->pColWidth
)
803 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
804 pColWidth
[i
] = pTable
->pColWidth
[i
-nDx
];
806 if (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pTable
->mpRowHeights
&&
807 pRowFlags
&& pTable
->pRowFlags
)
809 CopyRowHeight(*pTable
, nRow1
, nRow2
, -nDy
);
810 // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense
811 for (SCROW j
=nRow1
; j
<=nRow2
; j
++)
813 if ( pTable
->pRowFlags
->GetValue(j
-nDy
) & CR_MANUALSIZE
)
814 pRowFlags
->OrValue( j
, CR_MANUALSIZE
);
816 pRowFlags
->AndValue( j
, sal::static_int_cast
<sal_uInt8
>(~CR_MANUALSIZE
));
820 // Zellschutz auf geschuetzter Tabelle nicht setzen
821 if (IsProtected() && (rCxt
.getInsertFlag() & IDF_ATTRIB
))
823 ScPatternAttr
aPattern(pDocument
->GetPool());
824 aPattern
.GetItemSet().Put( ScProtectionAttr( false ) );
825 ApplyPatternArea( nCol1
, nRow1
, nCol2
, nRow2
, aPattern
);
828 // create deep copies for conditional formatting
829 CopyConditionalFormat( nCol1
, nRow1
, nCol2
, nRow2
, nDx
, nDy
, pTable
);
835 void ScTable::MixData(
836 sc::MixDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
837 sal_uInt16 nFunction
, bool bSkipEmpty
, const ScTable
* pSrcTab
)
839 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
840 aCol
[i
].MixData(rCxt
, nRow1
, nRow2
, nFunction
, bSkipEmpty
, pSrcTab
->aCol
[i
]);
844 // Markierung von diesem Dokument
845 void ScTable::MixMarked(
846 sc::MixDocContext
& rCxt
, const ScMarkData
& rMark
, sal_uInt16 nFunction
,
847 bool bSkipEmpty
, const ScTable
* pSrcTab
)
849 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
850 aCol
[i
].MixMarked(rCxt
, rMark
, nFunction
, bSkipEmpty
, pSrcTab
->aCol
[i
]);
854 void ScTable::TransposeClip( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
855 ScTable
* pTransClip
, sal_uInt16 nFlags
, bool bAsLink
)
857 bool bWasCut
= pDocument
->IsCutMode();
859 ScDocument
* pDestDoc
= pTransClip
->pDocument
;
861 for (SCCOL nCol
=nCol1
; nCol
<=nCol2
; nCol
++)
866 if ( bAsLink
&& nFlags
== IDF_ALL
)
868 // with IDF_ALL, also create links (formulas) for empty cells
870 for ( nRow
=nRow1
; nRow
<=nRow2
; nRow
++ )
872 // create simple formula, as in ScColumn::CreateRefCell
874 ScAddress
aDestPos( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
875 ScSingleRefData aRef
;
879 aRef
.InitFlags(); // -> all absolute
880 aRef
.SetFlag3D(true);
881 aRef
.CalcRelFromAbs( aDestPos
);
883 aArr
.AddSingleReference( aRef
);
885 ScBaseCell
* pNew
= new ScFormulaCell( pDestDoc
, aDestPos
, &aArr
);
886 pTransClip
->PutCell( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pNew
);
891 ScColumnIterator
aIter( &aCol
[nCol
], nRow1
, nRow2
);
892 while (aIter
.Next( nRow
, pCell
))
894 ScAddress
aDestPos( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
896 if ( bAsLink
) // Referenz erzeugen ?
898 pNew
= aCol
[nCol
].CreateRefCell( pDestDoc
, aDestPos
, aIter
.GetIndex(), nFlags
);
902 ScAddress
aOwnPos( nCol
, nRow
, nTab
);
903 if (pCell
->GetCellType() == CELLTYPE_FORMULA
)
905 pNew
= pCell
->Clone( *pDestDoc
, aDestPos
, SC_CLONECELL_STARTLISTENING
);
908 // bei Cut werden Referenzen spaeter per UpdateTranspose angepasst
911 ((ScFormulaCell
*)pNew
)->TransposeReference();
915 pNew
= pCell
->Clone( *pDestDoc
, aDestPos
);
918 pTransClip
->PutCell( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pNew
);
926 const ScPatternAttr
* pPattern
;
927 boost::scoped_ptr
<ScAttrIterator
> pAttrIter(aCol
[nCol
].CreateAttrIterator( nRow1
, nRow2
));
928 while ( (pPattern
= pAttrIter
->Next( nAttrRow1
, nAttrRow2
)) != 0 )
930 if ( !IsDefaultItem( pPattern
) )
932 const SfxItemSet
& rSet
= pPattern
->GetItemSet();
933 if ( rSet
.GetItemState( ATTR_MERGE
, false ) == SFX_ITEM_DEFAULT
&&
934 rSet
.GetItemState( ATTR_MERGE_FLAG
, false ) == SFX_ITEM_DEFAULT
&&
935 rSet
.GetItemState( ATTR_BORDER
, false ) == SFX_ITEM_DEFAULT
)
937 // no borders or merge items involved - use pattern as-is
938 for (nRow
= nAttrRow1
; nRow
<=nAttrRow2
; nRow
++)
939 pTransClip
->SetPattern( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), *pPattern
, true );
943 // transpose borders and merge values, remove merge flags (refreshed after pasting)
944 ScPatternAttr
aNewPattern( *pPattern
);
945 SfxItemSet
& rNewSet
= aNewPattern
.GetItemSet();
947 const SvxBoxItem
& rOldBox
= (const SvxBoxItem
&)rSet
.Get(ATTR_BORDER
);
948 if ( rOldBox
.GetTop() || rOldBox
.GetBottom() || rOldBox
.GetLeft() || rOldBox
.GetRight() )
950 SvxBoxItem
aNew( ATTR_BORDER
);
951 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_TOP
), BOX_LINE_LEFT
);
952 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_LEFT
), BOX_LINE_TOP
);
953 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_BOTTOM
), BOX_LINE_RIGHT
);
954 aNew
.SetLine( rOldBox
.GetLine( BOX_LINE_RIGHT
), BOX_LINE_BOTTOM
);
955 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_TOP
), BOX_LINE_LEFT
);
956 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_LEFT
), BOX_LINE_TOP
);
957 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_BOTTOM
), BOX_LINE_RIGHT
);
958 aNew
.SetDistance( rOldBox
.GetDistance( BOX_LINE_RIGHT
), BOX_LINE_BOTTOM
);
962 const ScMergeAttr
& rOldMerge
= (const ScMergeAttr
&)rSet
.Get(ATTR_MERGE
);
963 if (rOldMerge
.IsMerged())
964 rNewSet
.Put( ScMergeAttr( std::min(
965 static_cast<SCsCOL
>(rOldMerge
.GetRowMerge()),
966 static_cast<SCsCOL
>(MAXCOL
+1 - (nAttrRow2
-nRow1
))),
968 static_cast<SCsROW
>(rOldMerge
.GetColMerge()),
969 static_cast<SCsROW
>(MAXROW
+1 - (nCol
-nCol1
)))));
970 const ScMergeFlagAttr
& rOldFlag
= (const ScMergeFlagAttr
&)rSet
.Get(ATTR_MERGE_FLAG
);
971 if (rOldFlag
.IsOverlapped())
973 sal_Int16 nNewFlags
= rOldFlag
.GetValue() & ~( SC_MF_HOR
| SC_MF_VER
);
975 rNewSet
.Put( ScMergeFlagAttr( nNewFlags
) );
977 rNewSet
.ClearItem( ATTR_MERGE_FLAG
);
980 for (nRow
= nAttrRow1
; nRow
<=nAttrRow2
; nRow
++)
981 pTransClip
->SetPattern( static_cast<SCCOL
>(nRow
-nRow1
),
982 static_cast<SCROW
>(nCol
-nCol1
), aNewPattern
, true);
988 // fdo#68381 paste cell notes on Transpose
989 bool bCloneCaption
= true;
990 for (ScNotes::const_iterator itr
= maNotes
.begin(); itr
!= maNotes
.end(); ++itr
)
992 SCCOL nCol
= itr
->first
.first
;
993 SCROW nRow
= itr
->first
.second
;
994 if (nCol
>= nCol1
&& nCol
<= nCol2
&& nRow
>= nRow1
&& nRow
<= nRow2
)
996 ScAddress
aDestPos( static_cast<SCCOL
>(nRow
-nRow1
), static_cast<SCROW
>(nCol
-nCol1
), pTransClip
->nTab
);
997 pTransClip
->maNotes
.erase(aDestPos
);
998 pTransClip
->maNotes
.insert(aDestPos
, itr
->second
->Clone( ScAddress(nCol
, nRow
, nTab
), *pTransClip
->pDocument
, aDestPos
, bCloneCaption
));
1004 void ScTable::StartAllListeners()
1006 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1007 aCol
[i
].StartAllListeners();
1011 void ScTable::StartNeededListeners()
1013 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1014 aCol
[i
].StartNeededListeners();
1018 void ScTable::BroadcastInArea( SCCOL nCol1
, SCROW nRow1
,
1019 SCCOL nCol2
, SCROW nRow2
)
1021 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
1022 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
1023 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1024 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1025 aCol
[i
].BroadcastInArea( nRow1
, nRow2
);
1029 void ScTable::StartListeningInArea(
1030 sc::StartListeningContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
1032 if (nCol2
> MAXCOL
) nCol2
= MAXCOL
;
1033 if (nRow2
> MAXROW
) nRow2
= MAXROW
;
1034 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1035 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1036 aCol
[i
].StartListeningInArea(rCxt
, nRow1
, nRow2
);
1040 void ScTable::CopyToTable(
1041 sc::CopyToDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1042 sal_uInt16 nFlags
, bool bMarked
, ScTable
* pDestTab
, const ScMarkData
* pMarkData
,
1043 bool bAsLink
, bool bColRowFlags
)
1045 if (!ValidColRow(nCol1
, nRow1
) || !ValidColRow(nCol2
, nRow2
))
1049 for (SCCOL i
= nCol1
; i
<= nCol2
; i
++)
1050 aCol
[i
].CopyToColumn(rCxt
, nRow1
, nRow2
, nFlags
, bMarked
,
1051 pDestTab
->aCol
[i
], pMarkData
, bAsLink
);
1053 if (!bColRowFlags
) // Spaltenbreiten/Zeilenhoehen/Flags
1057 if (nFlags
& IDF_NOTE
)
1058 pDestTab
->maNotes
.erase(nCol1
, nRow1
, nCol2
, nRow2
);
1060 bool bAddNotes
= nFlags
& (IDF_NOTE
| IDF_ADDNOTES
);
1063 bool bCloneCaption
= (nFlags
& IDF_NOCAPTIONS
) == 0;
1064 pDestTab
->maNotes
.CopyFromClip(maNotes
, pDestTab
->pDocument
, nCol1
, nRow1
, nCol2
, nRow2
, 0, 0, pDestTab
->nTab
, bCloneCaption
);
1067 if(pDestTab
->pDocument
->IsUndo() && (nFlags
& IDF_ATTRIB
))
1069 pDestTab
->mpCondFormatList
.reset(new ScConditionalFormatList(pDestTab
->pDocument
, *mpCondFormatList
));
1074 ScDBData
* pNewDBData
= new ScDBData(*pDBDataNoName
);
1078 pNewDBData
->GetArea(aTab
, aCol1
, aRow1
, aCol2
, aRow2
);
1079 pNewDBData
->MoveTo(pDestTab
->nTab
, aCol1
, aRow1
, aCol2
, aRow2
);
1080 pDestTab
->SetAnonymousDBData(pNewDBData
);
1082 // Charts muessen beim Ein-/Ausblenden angepasst werden
1083 ScChartListenerCollection
* pCharts
= pDestTab
->pDocument
->GetChartListenerCollection();
1085 bool bFlagChange
= false;
1087 bool bWidth
= (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pDestTab
->pColWidth
);
1088 bool bHeight
= (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pDestTab
->mpRowHeights
);
1090 if (bWidth
|| bHeight
)
1094 for (SCCOL i
= nCol1
; i
<= nCol2
; ++i
)
1096 bool bThisHidden
= ColHidden(i
);
1097 bool bHiddenChange
= (pDestTab
->ColHidden(i
) != bThisHidden
);
1098 bool bChange
= bHiddenChange
|| (pDestTab
->pColWidth
[i
] != pColWidth
[i
]);
1099 pDestTab
->pColWidth
[i
] = pColWidth
[i
];
1100 pDestTab
->pColFlags
[i
] = pColFlags
[i
];
1101 pDestTab
->SetColHidden(i
, i
, bThisHidden
);
1102 //! Aenderungen zusammenfassen?
1103 if (bHiddenChange
&& pCharts
)
1104 pCharts
->SetRangeDirty(ScRange( i
, 0, nTab
, i
, MAXROW
, nTab
));
1109 pDestTab
->SetColManualBreaks( maColManualBreaks
);
1114 bool bChange
= pDestTab
->GetRowHeight(nRow1
, nRow2
) != GetRowHeight(nRow1
, nRow2
);
1119 pDestTab
->CopyRowHeight(*this, nRow1
, nRow2
, 0);
1120 pDestTab
->pRowFlags
->CopyFrom(*pRowFlags
, nRow1
, nRow2
);
1123 for (SCROW i
= nRow1
; i
<= nRow2
; ++i
)
1126 bool bHidden
= RowHidden(i
, NULL
, &nLastRow
);
1127 if (nLastRow
>= nRow2
)
1128 // the last row shouldn't exceed the upper bound the caller specified.
1131 bool bHiddenChanged
= pDestTab
->SetRowHidden(i
, nLastRow
, bHidden
);
1132 if (bHiddenChanged
&& pCharts
)
1133 // Hidden flags differ.
1134 pCharts
->SetRangeDirty(ScRange(0, i
, nTab
, MAXCOL
, nLastRow
, nTab
));
1139 // Jump to the last row of the identical flag segment.
1144 for (SCROW i
= nRow1
; i
<= nRow2
; ++i
)
1147 bool bFiltered
= RowFiltered(i
, NULL
, &nLastRow
);
1148 if (nLastRow
>= nRow2
)
1149 // the last row shouldn't exceed the upper bound the caller specified.
1151 pDestTab
->SetRowFiltered(i
, nLastRow
, bFiltered
);
1154 pDestTab
->SetRowManualBreaks( maRowManualBreaks
);
1159 pDestTab
->InvalidatePageBreaks();
1161 if(nFlags
& IDF_ATTRIB
)
1163 pDestTab
->mpCondFormatList
->DeleteArea(nCol1
, nRow1
, nCol2
, nRow2
);
1164 pDestTab
->CopyConditionalFormat(nCol1
, nRow1
, nCol2
, nRow2
, 0, 0, this);
1167 if(nFlags
& IDF_OUTLINE
) // also only when bColRowFlags
1168 pDestTab
->SetOutlineTable( pOutlineTable
);
1172 void ScTable::UndoToTable(
1173 sc::CopyToDocContext
& rCxt
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
,
1174 sal_uInt16 nFlags
, bool bMarked
, ScTable
* pDestTab
, const ScMarkData
* pMarkData
)
1176 if (ValidColRow(nCol1
, nRow1
) && ValidColRow(nCol2
, nRow2
))
1178 bool bWidth
= (nRow1
==0 && nRow2
==MAXROW
&& pColWidth
&& pDestTab
->pColWidth
);
1179 bool bHeight
= (nCol1
==0 && nCol2
==MAXCOL
&& mpRowHeights
&& pDestTab
->mpRowHeights
);
1181 for ( SCCOL i
= 0; i
<= MAXCOL
; i
++)
1183 if ( i
>= nCol1
&& i
<= nCol2
)
1184 aCol
[i
].UndoToColumn(rCxt
, nRow1
, nRow2
, nFlags
, bMarked
, pDestTab
->aCol
[i
], pMarkData
);
1186 aCol
[i
].CopyToColumn(rCxt
, 0, MAXROW
, IDF_FORMULA
, false, pDestTab
->aCol
[i
]);
1190 if (nFlags
& IDF_CONTENTS
)
1191 pDestTab
->maNotes
.erase(nCol1
, nRow1
, nCol2
, nRow2
);
1193 if (nFlags
& IDF_ATTRIB
)
1194 pDestTab
->mpCondFormatList
.reset(new ScConditionalFormatList(pDestTab
->pDocument
, *mpCondFormatList
));
1196 bool bAddNotes
= nFlags
& (IDF_NOTE
| IDF_ADDNOTES
);
1199 bool bCloneCaption
= (nFlags
& IDF_NOCAPTIONS
) == 0;
1200 pDestTab
->maNotes
.CopyFromClip(maNotes
, pDocument
, nCol1
, nRow1
, nCol2
, nRow2
, 0, 0, pDestTab
->nTab
, bCloneCaption
);
1203 if (bWidth
||bHeight
)
1207 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
1208 pDestTab
->pColWidth
[i
] = pColWidth
[i
];
1209 pDestTab
->SetColManualBreaks( maColManualBreaks
);
1213 pDestTab
->CopyRowHeight(*this, nRow1
, nRow2
, 0);
1214 pDestTab
->SetRowManualBreaks( maRowManualBreaks
);
1221 void ScTable::CopyUpdated( const ScTable
* pPosTab
, ScTable
* pDestTab
) const
1223 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1224 aCol
[i
].CopyUpdated( pPosTab
->aCol
[i
], pDestTab
->aCol
[i
] );
1226 // insert notes with captions
1227 for(ScNotes::iterator itr
= pDestTab
->maNotes
.begin(); itr
!= pDestTab
->maNotes
.end(); ++itr
)
1229 SCCOL nCol
= itr
->first
.first
;
1230 SCROW nRow
= itr
->first
.second
;
1231 ScPostIt
* pPostIt
= itr
->second
;
1233 pDestTab
->maNotes
.insert(nCol
, nRow
, pPostIt
->Clone( ScAddress(nCol
, nRow
, nTab
),*pDestTab
->pDocument
, ScAddress(nCol
, nRow
, pDestTab
->nTab
), true ));
1237 void ScTable::InvalidateTableArea()
1239 bTableAreaValid
= false;
1242 void ScTable::InvalidatePageBreaks()
1244 mbPageBreaksValid
= false;
1247 void ScTable::CopyScenarioTo( ScTable
* pDestTab
) const
1249 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1251 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1252 aCol
[i
].CopyScenarioTo( pDestTab
->aCol
[i
] );
1255 void ScTable::CopyScenarioFrom( const ScTable
* pSrcTab
)
1257 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1259 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1260 aCol
[i
].CopyScenarioFrom( pSrcTab
->aCol
[i
] );
1263 void ScTable::MarkScenarioIn( ScMarkData
& rDestMark
, sal_uInt16 nNeededBits
) const
1265 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1267 if ( ( nScenarioFlags
& nNeededBits
) != nNeededBits
) // alle Bits gesetzt?
1270 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1271 aCol
[i
].MarkScenarioIn( rDestMark
);
1274 bool ScTable::HasScenarioRange( const ScRange
& rRange
) const
1276 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1278 ScRange aTabRange
= rRange
;
1279 aTabRange
.aStart
.SetTab( nTab
);
1280 aTabRange
.aEnd
.SetTab( nTab
);
1282 const ScRangeList
* pList
= GetScenarioRanges();
1286 for ( size_t j
= 0, n
= pList
->size(); j
< n
; j
++ )
1288 const ScRange
* pR
= (*pList
)[j
];
1289 if ( pR
->Intersects( aTabRange
) )
1297 void ScTable::InvalidateScenarioRanges()
1299 delete pScenarioRanges
;
1300 pScenarioRanges
= NULL
;
1303 const ScRangeList
* ScTable::GetScenarioRanges() const
1305 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1307 if (!pScenarioRanges
)
1309 ((ScTable
*)this)->pScenarioRanges
= new ScRangeList
;
1311 MarkScenarioIn( aMark
, 0 ); // immer
1312 aMark
.FillRangeListWithMarks( pScenarioRanges
, false );
1314 return pScenarioRanges
;
1317 bool ScTable::TestCopyScenarioTo( const ScTable
* pDestTab
) const
1319 OSL_ENSURE( bScenario
, "bScenario == FALSE" );
1321 if (!pDestTab
->IsProtected())
1325 for (SCCOL i
=0; i
<=MAXCOL
&& bOk
; i
++)
1326 bOk
= aCol
[i
].TestCopyScenarioTo( pDestTab
->aCol
[i
] );
1330 void ScTable::PutCell( SCCOL nCol
, SCROW nRow
, ScBaseCell
* pCell
)
1332 if (ValidColRow(nCol
,nRow
))
1335 aCol
[nCol
].Insert( nRow
, pCell
);
1337 aCol
[nCol
].Delete( nRow
);
1342 void ScTable::PutCell( SCCOL nCol
, SCROW nRow
, sal_uLong nFormatIndex
, ScBaseCell
* pCell
)
1344 if (ValidColRow(nCol
,nRow
))
1347 aCol
[nCol
].Insert( nRow
, nFormatIndex
, pCell
);
1349 aCol
[nCol
].Delete( nRow
);
1354 void ScTable::PutCell( const ScAddress
& rPos
, ScBaseCell
* pCell
)
1357 aCol
[rPos
.Col()].Insert( rPos
.Row(), pCell
);
1359 aCol
[rPos
.Col()].Delete( rPos
.Row() );
1363 bool ScTable::SetString( SCCOL nCol
, SCROW nRow
, SCTAB nTabP
, const String
& rString
,
1364 ScSetStringParam
* pParam
)
1366 if (ValidColRow(nCol
,nRow
))
1367 return aCol
[nCol
].SetString(
1368 nRow
, nTabP
, rString
, pDocument
->GetAddressConvention(), pParam
);
1373 void ScTable::SetEditText( SCCOL nCol
, SCROW nRow
, EditTextObject
* pEditText
)
1375 if (!ValidColRow(nCol
, nRow
))
1381 aCol
[nCol
].SetEditText(nRow
, pEditText
);
1384 void ScTable::SetEditText( SCCOL nCol
, SCROW nRow
, const EditTextObject
& rEditText
, const SfxItemPool
* pEditPool
)
1386 if (!ValidColRow(nCol
, nRow
))
1389 aCol
[nCol
].SetEditText(nRow
, rEditText
, pEditPool
);
1392 void ScTable::SetEmptyCell( SCCOL nCol
, SCROW nRow
)
1394 if (!ValidColRow(nCol
, nRow
))
1397 aCol
[nCol
].Delete(nRow
);
1400 void ScTable::SetFormula(
1401 SCCOL nCol
, SCROW nRow
, const ScTokenArray
& rArray
, formula::FormulaGrammar::Grammar eGram
)
1403 if (!ValidColRow(nCol
, nRow
))
1406 aCol
[nCol
].SetFormula(nRow
, rArray
, eGram
);
1409 void ScTable::SetFormula(
1410 SCCOL nCol
, SCROW nRow
, const OUString
& rFormula
, formula::FormulaGrammar::Grammar eGram
)
1412 if (!ValidColRow(nCol
, nRow
))
1415 aCol
[nCol
].SetFormula(nRow
, rFormula
, eGram
);
1418 void ScTable::SetFormulaCell( SCCOL nCol
, SCROW nRow
, ScFormulaCell
* pCell
)
1420 if (!ValidColRow(nCol
, nRow
))
1426 aCol
[nCol
].SetFormulaCell(nRow
, pCell
);
1429 void ScTable::SetValue( SCCOL nCol
, SCROW nRow
, const double& rVal
)
1431 if (ValidColRow(nCol
, nRow
))
1432 aCol
[nCol
].SetValue( nRow
, rVal
);
1436 void ScTable::GetString( SCCOL nCol
, SCROW nRow
, OUString
& rString
) const
1438 if (ValidColRow(nCol
,nRow
))
1439 aCol
[nCol
].GetString( nRow
, rString
);
1441 rString
= OUString();
1444 const OUString
* ScTable::GetStringCell( SCCOL nCol
, SCROW nRow
) const
1446 if (!ValidColRow(nCol
,nRow
))
1449 return aCol
[nCol
].GetStringCell(nRow
);
1452 double* ScTable::GetValueCell( SCCOL nCol
, SCROW nRow
)
1454 if (!ValidColRow(nCol
,nRow
))
1457 return aCol
[nCol
].GetValueCell(nRow
);
1460 void ScTable::GetInputString( SCCOL nCol
, SCROW nRow
, OUString
& rString
) const
1462 if (ValidColRow(nCol
,nRow
))
1463 aCol
[nCol
].GetInputString( nRow
, rString
);
1465 rString
= OUString();
1469 double ScTable::GetValue( SCCOL nCol
, SCROW nRow
) const
1471 if (ValidColRow( nCol
, nRow
))
1472 return aCol
[nCol
].GetValue( nRow
);
1476 const EditTextObject
* ScTable::GetEditText( SCCOL nCol
, SCROW nRow
) const
1478 if (!ValidColRow(nCol
, nRow
))
1481 return aCol
[nCol
].GetEditText(nRow
);
1484 void ScTable::RemoveEditTextCharAttribs( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
)
1486 if (!ValidColRow(nCol
, nRow
))
1489 return aCol
[nCol
].RemoveEditTextCharAttribs(nRow
, rAttr
);
1492 void ScTable::GetFormula( SCCOL nCol
, SCROW nRow
, OUString
& rFormula
) const
1494 if (ValidColRow(nCol
,nRow
))
1495 aCol
[nCol
].GetFormula( nRow
, rFormula
);
1497 rFormula
= OUString();
1500 const ScTokenArray
* ScTable::GetFormulaTokens( SCCOL nCol
, SCROW nRow
) const
1502 if (!ValidColRow(nCol
, nRow
))
1505 return aCol
[nCol
].GetFormulaTokens(nRow
);
1508 const ScFormulaCell
* ScTable::GetFormulaCell( SCCOL nCol
, SCROW nRow
) const
1510 if (!ValidColRow(nCol
, nRow
))
1513 return aCol
[nCol
].GetFormulaCell(nRow
);
1516 ScFormulaCell
* ScTable::GetFormulaCell( SCCOL nCol
, SCROW nRow
)
1518 if (!ValidColRow(nCol
, nRow
))
1521 return aCol
[nCol
].GetFormulaCell(nRow
);
1524 ScNotes
* ScTable::GetNotes()
1530 void ScTable::InitializeNoteCaptions( bool bForced
)
1532 if( mxUninitNotes
.get() && (bForced
|| pDocument
->IsUndoEnabled()) )
1534 for( ScAddress2DVec::iterator aIt
= mxUninitNotes
->begin(), aEnd
= mxUninitNotes
->end(); aIt
!= aEnd
; ++aIt
)
1535 if( ScPostIt
* pNote
= maNotes
.findByAddress( aIt
->first
, aIt
->second
) )
1536 pNote
->GetOrCreateCaption( ScAddress( aIt
->first
, aIt
->second
, nTab
) );
1537 mxUninitNotes
.reset();
1541 CellType
ScTable::GetCellType( SCCOL nCol
, SCROW nRow
) const
1543 if (ValidColRow( nCol
, nRow
))
1544 return aCol
[nCol
].GetCellType( nRow
);
1545 return CELLTYPE_NONE
;
1549 ScBaseCell
* ScTable::GetCell( SCCOL nCol
, SCROW nRow
) const
1551 if (ValidColRow( nCol
, nRow
))
1552 return aCol
[nCol
].GetCell( nRow
);
1554 OSL_FAIL("GetCell: out of range");
1558 void ScTable::GetFirstDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
1562 while (aCol
[rCol
].IsEmptyData() && rCol
< MAXCOL
)
1565 while (nCol
<= MAXCOL
&& rRow
> 0)
1567 if (!aCol
[nCol
].IsEmptyData())
1568 rRow
= ::std::min( rRow
, aCol
[nCol
].GetFirstDataPos());
1573 void ScTable::GetLastDataPos(SCCOL
& rCol
, SCROW
& rRow
) const
1577 while (aCol
[rCol
].IsEmptyData() && (rCol
> 0))
1580 while (nCol
>= 0 && rRow
< MAXROW
)
1581 rRow
= ::std::max( rRow
, aCol
[nCol
--].GetLastDataPos());
1585 bool ScTable::HasData( SCCOL nCol
, SCROW nRow
) const
1587 if (ValidColRow(nCol
,nRow
))
1588 return aCol
[nCol
].HasDataAt( nRow
);
1594 bool ScTable::HasStringData( SCCOL nCol
, SCROW nRow
) const
1596 if (ValidColRow(nCol
,nRow
))
1597 return aCol
[nCol
].HasStringData( nRow
);
1603 bool ScTable::HasValueData( SCCOL nCol
, SCROW nRow
) const
1605 if (ValidColRow(nCol
,nRow
))
1606 return aCol
[nCol
].HasValueData( nRow
);
1612 bool ScTable::HasStringCells( SCCOL nStartCol
, SCROW nStartRow
,
1613 SCCOL nEndCol
, SCROW nEndRow
) const
1615 if ( ValidCol(nEndCol
) )
1616 for ( SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++ )
1617 if (aCol
[nCol
].HasStringCells(nStartRow
, nEndRow
))
1624 void ScTable::SetDirtyVar()
1626 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1627 aCol
[i
].SetDirtyVar();
1631 void ScTable::SetDirty()
1633 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1634 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1635 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1637 pDocument
->SetAutoCalc( bOldAutoCalc
);
1641 void ScTable::SetDirty( const ScRange
& rRange
)
1643 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1644 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1645 SCCOL nCol2
= rRange
.aEnd
.Col();
1646 for (SCCOL i
=rRange
.aStart
.Col(); i
<=nCol2
; i
++)
1647 aCol
[i
].SetDirty( rRange
);
1648 pDocument
->SetAutoCalc( bOldAutoCalc
);
1652 void ScTable::SetTableOpDirty( const ScRange
& rRange
)
1654 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1655 pDocument
->SetAutoCalc( false ); // no multiple recalculation
1656 SCCOL nCol2
= rRange
.aEnd
.Col();
1657 for (SCCOL i
=rRange
.aStart
.Col(); i
<=nCol2
; i
++)
1658 aCol
[i
].SetTableOpDirty( rRange
);
1659 pDocument
->SetAutoCalc( bOldAutoCalc
);
1663 void ScTable::SetDirtyAfterLoad()
1665 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1666 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1667 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1668 aCol
[i
].SetDirtyAfterLoad();
1669 pDocument
->SetAutoCalc( bOldAutoCalc
);
1673 void ScTable::SetDirtyIfPostponed()
1675 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1676 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1677 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
1678 aCol
[i
].SetDirtyIfPostponed();
1679 pDocument
->SetAutoCalc( bOldAutoCalc
);
1682 void ScTable::BroadcastRecalcOnRefMove()
1684 bool bOldAutoCalc
= pDocument
->GetAutoCalc();
1685 pDocument
->SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
1686 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1687 aCol
[i
].BroadcastRecalcOnRefMove();
1688 pDocument
->SetAutoCalc( bOldAutoCalc
);
1691 void ScTable::SetLoadingMedium(bool bLoading
)
1693 mpRowHeights
->enableTreeSearch(!bLoading
);
1697 void ScTable::CalcAll()
1699 for (SCCOL i
=0; i
<=MAXCOL
; i
++) aCol
[i
].CalcAll();
1703 void ScTable::CompileAll()
1705 for (SCCOL i
=0; i
<= MAXCOL
; i
++) aCol
[i
].CompileAll();
1707 if(mpCondFormatList
)
1708 mpCondFormatList
->CompileAll();
1712 void ScTable::CompileXML( ScProgress
& rProgress
)
1715 mpRangeName
->CompileUnresolvedXML();
1717 for (SCCOL i
=0; i
<= MAXCOL
; i
++)
1719 aCol
[i
].CompileXML( rProgress
);
1722 if(mpCondFormatList
)
1723 mpCondFormatList
->CompileXML();
1726 bool ScTable::CompileErrorCells(sal_uInt16 nErrCode
)
1728 bool bCompiled
= false;
1729 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1731 if (aCol
[i
].CompileErrorCells(nErrCode
))
1738 void ScTable::CalcAfterLoad()
1740 for (SCCOL i
=0; i
<= MAXCOL
; i
++) aCol
[i
].CalcAfterLoad();
1744 void ScTable::ResetChanged( const ScRange
& rRange
)
1746 SCCOL nStartCol
= rRange
.aStart
.Col();
1747 SCROW nStartRow
= rRange
.aStart
.Row();
1748 SCCOL nEndCol
= rRange
.aEnd
.Col();
1749 SCROW nEndRow
= rRange
.aEnd
.Row();
1751 for (SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
1752 aCol
[nCol
].ResetChanged(nStartRow
, nEndRow
);
1757 const SfxPoolItem
* ScTable::GetAttr( SCCOL nCol
, SCROW nRow
, sal_uInt16 nWhich
) const
1759 if (ValidColRow(nCol
,nRow
))
1760 return aCol
[nCol
].GetAttr( nRow
, nWhich
);
1765 sal_uInt32
ScTable::GetNumberFormat( const ScAddress
& rPos
) const
1767 return ValidColRow(rPos
.Col(),rPos
.Row()) ?
1768 aCol
[rPos
.Col()].GetNumberFormat( rPos
.Row() ) :
1772 sal_uInt32
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nRow
) const
1774 if (ValidColRow(nCol
,nRow
))
1775 return aCol
[nCol
].GetNumberFormat( nRow
);
1780 sal_uInt32
ScTable::GetNumberFormat( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
) const
1782 if (!ValidCol(nCol
) || !ValidRow(nStartRow
) || !ValidRow(nEndRow
))
1785 return aCol
[nCol
].GetNumberFormat(nStartRow
, nEndRow
);
1788 void ScTable::SetNumberFormat( SCCOL nCol
, SCROW nRow
, sal_uInt32 nNumberFormat
)
1790 if (!ValidColRow(nCol
, nRow
))
1793 aCol
[nCol
].SetNumberFormat(nRow
, nNumberFormat
);
1796 const ScPatternAttr
* ScTable::GetPattern( SCCOL nCol
, SCROW nRow
) const
1798 if (ValidColRow(nCol
,nRow
))
1799 return aCol
[nCol
].GetPattern( nRow
);
1802 OSL_FAIL("wrong column or row");
1803 return pDocument
->GetDefPattern(); // for safety
1808 const ScPatternAttr
* ScTable::GetMostUsedPattern( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
) const
1810 if ( ValidColRow( nCol
, nStartRow
) && ValidRow( nEndRow
) && (nStartRow
<= nEndRow
) )
1811 return aCol
[nCol
].GetMostUsedPattern( nStartRow
, nEndRow
);
1817 bool ScTable::HasAttrib( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, sal_uInt16 nMask
) const
1819 bool bFound
= false;
1820 for (SCCOL i
=nCol1
; i
<=nCol2
&& !bFound
; i
++)
1821 bFound
|= aCol
[i
].HasAttrib( nRow1
, nRow2
, nMask
);
1826 bool ScTable::HasAttribSelection( const ScMarkData
& rMark
, sal_uInt16 nMask
) const
1828 bool bFound
= false;
1829 for (SCCOL i
=0; i
<=MAXCOL
&& !bFound
; i
++)
1830 bFound
|= aCol
[i
].HasAttribSelection( rMark
, nMask
);
1835 bool ScTable::ExtendMerge( SCCOL nStartCol
, SCROW nStartRow
,
1836 SCCOL
& rEndCol
, SCROW
& rEndRow
,
1839 if (!(ValidCol(nStartCol
) && ValidCol(rEndCol
)))
1841 OSL_FAIL("ScTable::ExtendMerge: invalid column number");
1844 bool bFound
= false;
1845 SCCOL nOldEndX
= rEndCol
;
1846 SCROW nOldEndY
= rEndRow
;
1847 for (SCCOL i
=nStartCol
; i
<=nOldEndX
; i
++)
1848 bFound
|= aCol
[i
].ExtendMerge( i
, nStartRow
, nOldEndY
, rEndCol
, rEndRow
, bRefresh
);
1853 bool ScTable::IsBlockEmpty( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, bool bIgnoreNotes
) const
1855 if (!(ValidCol(nCol1
) && ValidCol(nCol2
)))
1857 OSL_FAIL("ScTable::IsBlockEmpty: invalid column number");
1861 for (SCCOL i
=nCol1
; i
<=nCol2
&& bEmpty
; i
++)
1863 bEmpty
= aCol
[i
].IsEmptyBlock( nRow1
, nRow2
);
1866 for (ScNotes::const_iterator itr
= maNotes
.begin(); itr
!= maNotes
.end() && bEmpty
; ++itr
)
1868 SCCOL nCol
= itr
->first
.first
;
1869 SCROW nRow
= itr
->first
.second
;
1871 if (nCol
>= nCol1
&& nCol
<= nCol2
&& nRow
>= nRow1
&& nRow
<= nRow2
)
1879 SCSIZE
ScTable::FillMaxRot( RowInfo
* pRowInfo
, SCSIZE nArrCount
, SCCOL nX1
, SCCOL nX2
,
1880 SCCOL nCol
, SCROW nAttrRow1
, SCROW nAttrRow2
, SCSIZE nArrY
,
1881 const ScPatternAttr
* pPattern
, const SfxItemSet
* pCondSet
)
1883 // Rueckgabe = neues nArrY
1885 sal_uInt8 nRotDir
= pPattern
->GetRotateDir( pCondSet
);
1886 if ( nRotDir
!= SC_ROTDIR_NONE
)
1889 if ( nCol
+1 < nX1
) // column to the left
1890 bHit
= ( nRotDir
!= SC_ROTDIR_LEFT
);
1891 else if ( nCol
> nX2
+1 ) // column to the right
1892 bHit
= ( nRotDir
!= SC_ROTDIR_RIGHT
); // SC_ROTDIR_STANDARD may now also be extended to the left
1896 double nFactor
= 0.0;
1899 long nRotVal
= ((const SfxInt32Item
&) pPattern
->
1900 GetItem( ATTR_ROTATE_VALUE
, pCondSet
)).GetValue();
1901 double nRealOrient
= nRotVal
* F_PI18000
; // 1/100 Grad
1902 double nCos
= cos( nRealOrient
);
1903 double nSin
= sin( nRealOrient
);
1905 //! zusaetzlich Faktor fuer unterschiedliche PPT X/Y !!!
1907 // bei SC_ROTDIR_LEFT kommt immer ein negativer Wert heraus,
1908 // wenn der Modus beruecksichtigt wird
1909 nFactor
= -fabs( nCos
/ nSin
);
1912 for ( SCROW nRow
= nAttrRow1
; nRow
<= nAttrRow2
; nRow
++ )
1914 if (!RowHidden(nRow
))
1916 bool bHitOne
= true;
1919 // reicht die gedrehte Zelle bis in den sichtbaren Bereich?
1921 SCCOL nTouchedCol
= nCol
;
1922 long nWidth
= static_cast<long>(mpRowHeights
->getValue(nRow
) * nFactor
);
1923 OSL_ENSURE(nWidth
<= 0, "Wrong direction");
1924 while ( nWidth
< 0 && nTouchedCol
> 0 )
1927 nWidth
+= GetColWidth( nTouchedCol
);
1929 if ( nTouchedCol
> nX2
)
1935 while ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
< nRow
)
1937 if ( nArrY
<nArrCount
&& pRowInfo
[nArrY
].nRowNo
== nRow
)
1938 pRowInfo
[nArrY
].nRotMaxCol
= nCol
;
1948 void ScTable::FindMaxRotCol( RowInfo
* pRowInfo
, SCSIZE nArrCount
, SCCOL nX1
, SCCOL nX2
)
1950 if ( !pColWidth
|| !mpRowHeights
|| !pColFlags
|| !pRowFlags
)
1952 OSL_FAIL( "Row/column info missing" );
1956 // nRotMaxCol ist auf SC_ROTMAX_NONE initialisiert, nRowNo ist schon gesetzt
1958 SCROW nY1
= pRowInfo
[0].nRowNo
;
1959 SCROW nY2
= pRowInfo
[nArrCount
-1].nRowNo
;
1961 for (SCCOL nCol
=0; nCol
<=MAXCOL
; nCol
++)
1963 if (!ColHidden(nCol
))
1966 ScDocAttrIterator
aIter( pDocument
, nTab
, nCol
, nY1
, nCol
, nY2
);
1968 SCROW nAttrRow1
, nAttrRow2
;
1969 const ScPatternAttr
* pPattern
= aIter
.GetNext( nAttrCol
, nAttrRow1
, nAttrRow2
);
1972 const SfxPoolItem
* pCondItem
;
1973 if ( pPattern
->GetItemSet().GetItemState( ATTR_CONDITIONAL
, true, &pCondItem
)
1976 // alle Formate durchgehen, damit die Zellen nicht einzeln
1977 // angeschaut werden muessen
1979 const std::vector
<sal_uInt32
>& rCondFormatData
= static_cast<const ScCondFormatItem
*>(pCondItem
)->GetCondFormatData();
1980 ScStyleSheetPool
* pStylePool
= pDocument
->GetStyleSheetPool();
1981 if (mpCondFormatList
&& pStylePool
&& !rCondFormatData
.empty())
1983 for(std::vector
<sal_uInt32
>::const_iterator itr
= rCondFormatData
.begin(), itrEnd
= rCondFormatData
.end();
1984 itr
!= itrEnd
; ++itr
)
1986 const ScConditionalFormat
* pFormat
= mpCondFormatList
->GetFormat(*itr
);
1989 size_t nEntryCount
= pFormat
->size();
1990 for (size_t nEntry
=0; nEntry
<nEntryCount
; nEntry
++)
1992 const ScFormatEntry
* pEntry
= pFormat
->GetEntry(nEntry
);
1993 if(pEntry
->GetType() != condformat::CONDITION
)
1996 String aStyleName
= static_cast<const ScCondFormatEntry
*>(pEntry
)->GetStyle();
1997 if (aStyleName
.Len())
1999 SfxStyleSheetBase
* pStyleSheet
=
2000 pStylePool
->Find( aStyleName
, SFX_STYLE_FAMILY_PARA
);
2003 FillMaxRot( pRowInfo
, nArrCount
, nX1
, nX2
,
2004 nCol
, nAttrRow1
, nAttrRow2
,
2005 nArrY
, pPattern
, &pStyleSheet
->GetItemSet() );
2006 // nArrY nicht veraendern
2015 nArrY
= FillMaxRot( pRowInfo
, nArrCount
, nX1
, nX2
,
2016 nCol
, nAttrRow1
, nAttrRow2
,
2017 nArrY
, pPattern
, NULL
);
2019 pPattern
= aIter
.GetNext( nAttrCol
, nAttrRow1
, nAttrRow2
);
2025 bool ScTable::HasBlockMatrixFragment( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
2027 // nix:0, mitte:1, unten:2, links:4, oben:8, rechts:16, offen:32
2030 if ( nCol1
== nCol2
)
2031 { // linke und rechte Spalte
2032 const sal_uInt16 n
= 4 | 16;
2033 nEdges
= aCol
[nCol1
].GetBlockMatrixEdges( nRow1
, nRow2
, n
);
2034 // nicht (4 und 16) oder 1 oder 32
2035 if ( nEdges
&& (((nEdges
& n
) != n
) || (nEdges
& 33)) )
2036 return true; // linke oder rechte Kante fehlt oder offen
2040 nEdges
= aCol
[nCol1
].GetBlockMatrixEdges( nRow1
, nRow2
, 4 );
2041 // nicht 4 oder 1 oder 32
2042 if ( nEdges
&& (((nEdges
& 4) != 4) || (nEdges
& 33)) )
2043 return true; // linke Kante fehlt oder offen
2045 nEdges
= aCol
[nCol2
].GetBlockMatrixEdges( nRow1
, nRow2
, 16 );
2046 // nicht 16 oder 1 oder 32
2047 if ( nEdges
&& (((nEdges
& 16) != 16) || (nEdges
& 33)) )
2048 return true; // rechte Kante fehlt oder offen
2051 if ( nRow1
== nRow2
)
2052 { // obere und untere Zeile
2054 const sal_uInt16 n
= 2 | 8;
2055 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2057 nEdges
= aCol
[i
].GetBlockMatrixEdges( nRow1
, nRow1
, n
);
2060 if ( (nEdges
& n
) != n
)
2061 return true; // obere oder untere Kante fehlt
2063 bOpen
= true; // linke Kante oeffnet, weitersehen
2065 return true; // es gibt was, was nicht geoeffnet wurde
2067 bOpen
= false; // rechte Kante schliesst
2071 return true; // es geht noch weiter
2077 // erst obere Zeile, dann untere Zeile
2078 for ( j
=0, nR
=nRow1
, n
=8; j
<2; j
++, nR
=nRow2
, n
=2 )
2081 for ( SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2083 nEdges
= aCol
[i
].GetBlockMatrixEdges( nR
, nR
, n
);
2086 // in oberere Zeile keine obere Kante bzw.
2087 // in unterer Zeile keine untere Kante
2088 if ( (nEdges
& n
) != n
)
2091 bOpen
= true; // linke Kante oeffnet, weitersehen
2093 return true; // es gibt was, was nicht geoeffnet wurde
2095 bOpen
= false; // rechte Kante schliesst
2099 return true; // es geht noch weiter
2106 bool ScTable::HasSelectionMatrixFragment( const ScMarkData
& rMark
) const
2108 bool bFound
= false;
2109 for (SCCOL i
=0; i
<=MAXCOL
&& !bFound
; i
++)
2110 bFound
|= aCol
[i
].HasSelectionMatrixFragment(rMark
);
2115 bool ScTable::IsBlockEditable( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
,
2116 SCROW nRow2
, bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
2118 if ( !ValidColRow( nCol2
, nRow2
) )
2120 OSL_FAIL("IsBlockEditable: invalid column or row");
2121 if (pOnlyNotBecauseOfMatrix
)
2122 *pOnlyNotBecauseOfMatrix
= false;
2126 bool bIsEditable
= true;
2128 bIsEditable
= false;
2129 else if ( IsProtected() && !pDocument
->IsScenario(nTab
) )
2131 bIsEditable
= !HasAttrib( nCol1
, nRow1
, nCol2
, nRow2
, HASATTR_PROTECTED
);
2134 // If Sheet is protected and cells are not protected then
2135 // check the active scenario protect flag if this range is
2136 // on the active scenario range. Note the 'copy back' must also
2137 // be set to apply protection.
2138 sal_uInt16 nScenTab
= nTab
+1;
2139 while(pDocument
->IsScenario(nScenTab
))
2141 ScRange
aEditRange(nCol1
, nRow1
, nScenTab
, nCol2
, nRow2
, nScenTab
);
2142 if(pDocument
->IsActiveScenario(nScenTab
) && pDocument
->HasScenarioRange(nScenTab
, aEditRange
))
2145 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
2146 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
2153 else if (pDocument
->IsScenario(nTab
))
2155 // Determine if the preceding sheet is protected
2156 SCTAB nActualTab
= nTab
;
2161 while(pDocument
->IsScenario(nActualTab
));
2163 if(pDocument
->IsTabProtected(nActualTab
))
2165 ScRange
aEditRange(nCol1
, nRow1
, nTab
, nCol2
, nRow2
, nTab
);
2166 if(pDocument
->HasScenarioRange(nTab
, aEditRange
))
2169 pDocument
->GetScenarioFlags(nTab
,nFlags
);
2170 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
2176 if ( HasBlockMatrixFragment( nCol1
, nRow1
, nCol2
, nRow2
) )
2178 bIsEditable
= false;
2179 if ( pOnlyNotBecauseOfMatrix
)
2180 *pOnlyNotBecauseOfMatrix
= true;
2182 else if ( pOnlyNotBecauseOfMatrix
)
2183 *pOnlyNotBecauseOfMatrix
= false;
2185 else if ( pOnlyNotBecauseOfMatrix
)
2186 *pOnlyNotBecauseOfMatrix
= false;
2191 bool ScTable::IsSelectionEditable( const ScMarkData
& rMark
,
2192 bool* pOnlyNotBecauseOfMatrix
/* = NULL */ ) const
2194 bool bIsEditable
= true;
2196 bIsEditable
= false;
2197 else if ( IsProtected() && !pDocument
->IsScenario(nTab
) )
2199 if((bIsEditable
= !HasAttribSelection( rMark
, HASATTR_PROTECTED
)) != false)
2201 // If Sheet is protected and cells are not protected then
2202 // check the active scenario protect flag if this area is
2203 // in the active scenario range.
2204 ScRangeList aRanges
;
2205 rMark
.FillRangeListWithMarks( &aRanges
, false );
2206 SCTAB nScenTab
= nTab
+1;
2207 while(pDocument
->IsScenario(nScenTab
) && bIsEditable
)
2209 if(pDocument
->IsActiveScenario(nScenTab
))
2211 for (size_t i
=0, nRange
= aRanges
.size(); (i
< nRange
) && bIsEditable
; i
++ )
2213 ScRange aRange
= *aRanges
[ i
];
2214 if(pDocument
->HasScenarioRange(nScenTab
, aRange
))
2217 pDocument
->GetScenarioFlags(nScenTab
,nFlags
);
2218 bIsEditable
= !((nFlags
& SC_SCENARIO_PROTECT
) && (nFlags
& SC_SCENARIO_TWOWAY
));
2226 else if (pDocument
->IsScenario(nTab
))
2228 // Determine if the preceding sheet is protected
2229 SCTAB nActualTab
= nTab
;
2234 while(pDocument
->IsScenario(nActualTab
));
2236 if(pDocument
->IsTabProtected(nActualTab
))
2238 ScRangeList aRanges
;
2239 rMark
.FillRangeListWithMarks( &aRanges
, false );
2240 for (size_t i
= 0, nRange
= aRanges
.size(); (i
< nRange
) && bIsEditable
; i
++)
2242 ScRange aRange
= *aRanges
[ i
];
2243 if(pDocument
->HasScenarioRange(nTab
, aRange
))
2246 pDocument
->GetScenarioFlags(nTab
,nFlags
);
2247 bIsEditable
= !(nFlags
& SC_SCENARIO_PROTECT
);
2254 if ( HasSelectionMatrixFragment( rMark
) )
2256 bIsEditable
= false;
2257 if ( pOnlyNotBecauseOfMatrix
)
2258 *pOnlyNotBecauseOfMatrix
= true;
2260 else if ( pOnlyNotBecauseOfMatrix
)
2261 *pOnlyNotBecauseOfMatrix
= false;
2263 else if ( pOnlyNotBecauseOfMatrix
)
2264 *pOnlyNotBecauseOfMatrix
= false;
2270 void ScTable::LockTable()
2276 void ScTable::UnlockTable()
2282 OSL_FAIL("UnlockTable without LockTable");
2287 void ScTable::MergeSelectionPattern( ScMergePatternState
& rState
, const ScMarkData
& rMark
, bool bDeep
) const
2289 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2290 aCol
[i
].MergeSelectionPattern( rState
, rMark
, bDeep
);
2294 void ScTable::MergePatternArea( ScMergePatternState
& rState
, SCCOL nCol1
, SCROW nRow1
,
2295 SCCOL nCol2
, SCROW nRow2
, bool bDeep
) const
2297 for (SCCOL i
=nCol1
; i
<=nCol2
; i
++)
2298 aCol
[i
].MergePatternArea( rState
, nRow1
, nRow2
, bDeep
);
2302 void ScTable::MergeBlockFrame( SvxBoxItem
* pLineOuter
, SvxBoxInfoItem
* pLineInner
, ScLineFlags
& rFlags
,
2303 SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
) const
2305 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2307 PutInOrder(nStartCol
, nEndCol
);
2308 PutInOrder(nStartRow
, nEndRow
);
2309 for (SCCOL i
=nStartCol
; i
<=nEndCol
; i
++)
2310 aCol
[i
].MergeBlockFrame( pLineOuter
, pLineInner
, rFlags
,
2311 nStartRow
, nEndRow
, (i
==nStartCol
), nEndCol
-i
);
2316 void ScTable::ApplyBlockFrame( const SvxBoxItem
* pLineOuter
, const SvxBoxInfoItem
* pLineInner
,
2317 SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
)
2319 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2321 PutInOrder(nStartCol
, nEndCol
);
2322 PutInOrder(nStartRow
, nEndRow
);
2323 for (SCCOL i
=nStartCol
; i
<=nEndCol
; i
++)
2324 aCol
[i
].ApplyBlockFrame( pLineOuter
, pLineInner
,
2325 nStartRow
, nEndRow
, (i
==nStartCol
), nEndCol
-i
);
2330 void ScTable::ApplyPattern( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
)
2332 if (ValidColRow(nCol
,nRow
))
2333 aCol
[nCol
].ApplyPattern( nRow
, rAttr
);
2337 void ScTable::ApplyPatternArea( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2338 const ScPatternAttr
& rAttr
, ScEditDataArray
* pDataArray
)
2340 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2342 PutInOrder(nStartCol
, nEndCol
);
2343 PutInOrder(nStartRow
, nEndRow
);
2344 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2345 aCol
[i
].ApplyPatternArea(nStartRow
, nEndRow
, rAttr
, pDataArray
);
2349 bool ScTable::SetAttrEntries(SCCOL nCol
, ScAttrEntry
* pData
, SCSIZE nSize
)
2351 if (!ValidCol(nCol
))
2354 return aCol
[nCol
].SetAttrEntries(pData
, nSize
);
2357 void ScTable::ApplyPatternIfNumberformatIncompatible( const ScRange
& rRange
,
2358 const ScPatternAttr
& rPattern
, short nNewType
)
2360 SCCOL nEndCol
= rRange
.aEnd
.Col();
2361 for ( SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= nEndCol
; nCol
++ )
2363 aCol
[nCol
].ApplyPatternIfNumberformatIncompatible( rRange
, rPattern
, nNewType
);
2367 void ScTable::AddCondFormatData( const ScRangeList
& rRange
, sal_uInt32 nIndex
)
2369 size_t n
= rRange
.size();
2370 for(size_t i
= 0; i
< n
; ++i
)
2372 const ScRange
* pRange
= rRange
[i
];
2373 SCCOL nColStart
= pRange
->aStart
.Col();
2374 SCCOL nColEnd
= pRange
->aEnd
.Col();
2375 SCROW nRowStart
= pRange
->aStart
.Row();
2376 SCROW nRowEnd
= pRange
->aEnd
.Row();
2377 for(SCCOL nCol
= nColStart
; nCol
<= nColEnd
; ++nCol
)
2379 aCol
[nCol
].AddCondFormat(nRowStart
, nRowEnd
, nIndex
);
2384 void ScTable::RemoveCondFormatData( const ScRangeList
& rRange
, sal_uInt32 nIndex
)
2386 size_t n
= rRange
.size();
2387 for(size_t i
= 0; i
< n
; ++i
)
2389 const ScRange
* pRange
= rRange
[i
];
2390 SCCOL nColStart
= pRange
->aStart
.Col();
2391 SCCOL nColEnd
= pRange
->aEnd
.Col();
2392 SCROW nRowStart
= pRange
->aStart
.Row();
2393 SCROW nRowEnd
= pRange
->aEnd
.Row();
2394 for(SCCOL nCol
= nColStart
; nCol
<= nColEnd
; ++nCol
)
2396 aCol
[nCol
].RemoveCondFormat(nRowStart
, nRowEnd
, nIndex
);
2403 void ScTable::ApplyStyle( SCCOL nCol
, SCROW nRow
, const ScStyleSheet
& rStyle
)
2405 if (ValidColRow(nCol
,nRow
))
2406 aCol
[nCol
].ApplyStyle( nRow
, rStyle
);
2410 void ScTable::ApplyStyleArea( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
, const ScStyleSheet
& rStyle
)
2412 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2414 PutInOrder(nStartCol
, nEndCol
);
2415 PutInOrder(nStartRow
, nEndRow
);
2416 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2417 aCol
[i
].ApplyStyleArea(nStartRow
, nEndRow
, rStyle
);
2422 void ScTable::ApplySelectionStyle(const ScStyleSheet
& rStyle
, const ScMarkData
& rMark
)
2424 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2425 aCol
[i
].ApplySelectionStyle( rStyle
, rMark
);
2429 void ScTable::ApplySelectionLineStyle( const ScMarkData
& rMark
,
2430 const ::editeng::SvxBorderLine
* pLine
, bool bColorOnly
)
2432 if ( bColorOnly
&& !pLine
)
2435 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2436 aCol
[i
].ApplySelectionLineStyle( rMark
, pLine
, bColorOnly
);
2440 const ScStyleSheet
* ScTable::GetStyle( SCCOL nCol
, SCROW nRow
) const
2442 if (ValidColRow(nCol
, nRow
))
2443 return aCol
[nCol
].GetStyle(nRow
);
2449 const ScStyleSheet
* ScTable::GetSelectionStyle( const ScMarkData
& rMark
, bool& rFound
) const
2456 const ScStyleSheet
* pStyle
= NULL
;
2457 const ScStyleSheet
* pNewStyle
;
2459 for (SCCOL i
=0; i
<=MAXCOL
&& bEqual
; i
++)
2460 if (rMark
.HasMultiMarks(i
))
2462 pNewStyle
= aCol
[i
].GetSelectionStyle( rMark
, bColFound
);
2466 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
2467 bEqual
= false; // unterschiedliche
2472 return bEqual
? pStyle
: NULL
;
2476 const ScStyleSheet
* ScTable::GetAreaStyle( bool& rFound
, SCCOL nCol1
, SCROW nRow1
,
2477 SCCOL nCol2
, SCROW nRow2
) const
2484 const ScStyleSheet
* pStyle
= NULL
;
2485 const ScStyleSheet
* pNewStyle
;
2487 for (SCCOL i
=nCol1
; i
<=nCol2
&& bEqual
; i
++)
2489 pNewStyle
= aCol
[i
].GetAreaStyle(bColFound
, nRow1
, nRow2
);
2493 if ( !pNewStyle
|| ( pStyle
&& pNewStyle
!= pStyle
) )
2494 bEqual
= false; // unterschiedliche
2499 return bEqual
? pStyle
: NULL
;
2503 bool ScTable::IsStyleSheetUsed( const ScStyleSheet
& rStyle
, bool bGatherAllStyles
) const
2505 bool bIsUsed
= false;
2507 for ( SCCOL i
=0; i
<=MAXCOL
; i
++ )
2509 if ( aCol
[i
].IsStyleSheetUsed( rStyle
, bGatherAllStyles
) )
2511 if ( !bGatherAllStyles
)
2521 void ScTable::StyleSheetChanged( const SfxStyleSheetBase
* pStyleSheet
, bool bRemoved
,
2523 double nPPTX
, double nPPTY
,
2524 const Fraction
& rZoomX
, const Fraction
& rZoomY
)
2526 ScFlatBoolRowSegments aUsedRows
;
2527 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
2528 aCol
[i
].FindStyleSheet(pStyleSheet
, aUsedRows
, bRemoved
);
2531 while (nRow
<= MAXROW
)
2533 ScFlatBoolRowSegments::RangeData aData
;
2534 if (!aUsedRows
.getRangeData(nRow
, aData
))
2538 SCROW nEndRow
= aData
.mnRow2
;
2540 SetOptimalHeight(nRow
, nEndRow
, 0, pDev
, nPPTX
, nPPTY
, rZoomX
, rZoomY
, false);
2547 bool ScTable::ApplyFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2550 bool bChanged
= false;
2551 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2552 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2553 bChanged
|= aCol
[i
].ApplyFlags(nStartRow
, nEndRow
, nFlags
);
2558 bool ScTable::RemoveFlags( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
2561 bool bChanged
= false;
2562 if (ValidColRow(nStartCol
, nStartRow
) && ValidColRow(nEndCol
, nEndRow
))
2563 for (SCCOL i
= nStartCol
; i
<= nEndCol
; i
++)
2564 bChanged
|= aCol
[i
].RemoveFlags(nStartRow
, nEndRow
, nFlags
);
2569 void ScTable::SetPattern( SCCOL nCol
, SCROW nRow
, const ScPatternAttr
& rAttr
, bool bPutToPool
)
2571 if (ValidColRow(nCol
,nRow
))
2572 aCol
[nCol
].SetPattern( nRow
, rAttr
, bPutToPool
);
2576 void ScTable::ApplyAttr( SCCOL nCol
, SCROW nRow
, const SfxPoolItem
& rAttr
)
2578 if (ValidColRow(nCol
,nRow
))
2579 aCol
[nCol
].ApplyAttr( nRow
, rAttr
);
2583 void ScTable::ApplySelectionCache( SfxItemPoolCache
* pCache
, const ScMarkData
& rMark
,
2584 ScEditDataArray
* pDataArray
)
2586 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2587 aCol
[i
].ApplySelectionCache( pCache
, rMark
, pDataArray
);
2591 void ScTable::ChangeSelectionIndent( bool bIncrement
, const ScMarkData
& rMark
)
2593 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2594 aCol
[i
].ChangeSelectionIndent( bIncrement
, rMark
);
2598 void ScTable::ClearSelectionItems( const sal_uInt16
* pWhich
, const ScMarkData
& rMark
)
2600 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
2601 aCol
[i
].ClearSelectionItems( pWhich
, rMark
);
2605 // Spaltenbreiten / Zeilenhoehen
2607 void ScTable::SetColWidth( SCCOL nCol
, sal_uInt16 nNewWidth
)
2609 if (ValidCol(nCol
) && pColWidth
)
2613 nNewWidth
= STD_COL_WIDTH
;
2616 if ( nNewWidth
!= pColWidth
[nCol
] )
2618 pColWidth
[nCol
] = nNewWidth
;
2619 InvalidatePageBreaks();
2624 OSL_FAIL("Invalid column number or no widths");
2628 void ScTable::SetColWidthOnly( SCCOL nCol
, sal_uInt16 nNewWidth
)
2630 if (!ValidCol(nCol
) || !pColWidth
)
2634 nNewWidth
= STD_COL_WIDTH
;
2636 if (nNewWidth
!= pColWidth
[nCol
])
2637 pColWidth
[nCol
] = nNewWidth
;
2640 void ScTable::SetRowHeight( SCROW nRow
, sal_uInt16 nNewHeight
)
2642 if (ValidRow(nRow
) && mpRowHeights
)
2646 OSL_FAIL("SetRowHeight: Row height zero");
2647 nNewHeight
= ScGlobal::nStdRowHeight
;
2650 sal_uInt16 nOldHeight
= mpRowHeights
->getValue(nRow
);
2651 if ( nNewHeight
!= nOldHeight
)
2653 mpRowHeights
->setValue(nRow
, nRow
, nNewHeight
);
2654 InvalidatePageBreaks();
2659 OSL_FAIL("Invalid row number or no heights");
2666 * Check if the new pixel size is different from the old size between
2669 bool lcl_pixelSizeChanged(
2670 ScFlatUInt16RowSegments
& rRowHeights
, SCROW nStartRow
, SCROW nEndRow
,
2671 sal_uInt16 nNewHeight
, double nPPTY
)
2673 long nNewPix
= static_cast<long>(nNewHeight
* nPPTY
);
2675 ScFlatUInt16RowSegments::ForwardIterator
aFwdIter(rRowHeights
);
2676 for (SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
2679 if (!aFwdIter
.getValue(nRow
, nHeight
))
2682 if (nHeight
!= nNewHeight
)
2684 bool bChanged
= (nNewPix
!= static_cast<long>(nHeight
* nPPTY
));
2689 // Skip ahead to the last position of the current range.
2690 nRow
= aFwdIter
.getLastPos();
2697 bool ScTable::SetRowHeightRange( SCROW nStartRow
, SCROW nEndRow
, sal_uInt16 nNewHeight
,
2698 double /* nPPTX */, double nPPTY
)
2700 bool bChanged
= false;
2701 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2705 OSL_FAIL("SetRowHeight: Row height zero");
2706 nNewHeight
= ScGlobal::nStdRowHeight
;
2709 bool bSingle
= false; // true = process every row for its own
2710 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
2712 if (pDrawLayer
->HasObjectsInRows( nTab
, nStartRow
, nEndRow
))
2717 ScFlatUInt16RowSegments::RangeData aData
;
2718 mpRowHeights
->getRangeData(nStartRow
, aData
);
2719 if (nNewHeight
== aData
.mnValue
&& nEndRow
<= aData
.mnRow2
)
2720 bSingle
= false; // no difference in this range
2724 if (nEndRow
-nStartRow
< 20)
2727 bChanged
= lcl_pixelSizeChanged(*mpRowHeights
, nStartRow
, nEndRow
, nNewHeight
, nPPTY
);
2729 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2733 SCROW nMid
= (nStartRow
+nEndRow
) / 2;
2734 if (SetRowHeightRange( nStartRow
, nMid
, nNewHeight
, 1.0, 1.0 ))
2736 if (SetRowHeightRange( nMid
+1, nEndRow
, nNewHeight
, 1.0, 1.0 ))
2743 bChanged
= lcl_pixelSizeChanged(*mpRowHeights
, nStartRow
, nEndRow
, nNewHeight
, nPPTY
);
2745 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2749 InvalidatePageBreaks();
2753 OSL_FAIL("Invalid row number or no heights");
2759 void ScTable::SetRowHeightOnly( SCROW nStartRow
, SCROW nEndRow
, sal_uInt16 nNewHeight
)
2761 if (!ValidRow(nStartRow
) || !ValidRow(nEndRow
) || !mpRowHeights
)
2765 nNewHeight
= ScGlobal::nStdRowHeight
;
2767 mpRowHeights
->setValue(nStartRow
, nEndRow
, nNewHeight
);
2770 void ScTable::SetManualHeight( SCROW nStartRow
, SCROW nEndRow
, bool bManual
)
2772 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && pRowFlags
)
2775 pRowFlags
->OrValue( nStartRow
, nEndRow
, CR_MANUALSIZE
);
2777 pRowFlags
->AndValue( nStartRow
, nEndRow
, sal::static_int_cast
<sal_uInt8
>(~CR_MANUALSIZE
));
2781 OSL_FAIL("Invalid row number or no column flags");
2786 sal_uInt16
ScTable::GetColWidth( SCCOL nCol
, bool bHiddenAsZero
) const
2788 OSL_ENSURE(ValidCol(nCol
),"wrong column number");
2790 if (ValidCol(nCol
) && pColFlags
&& pColWidth
)
2792 if (bHiddenAsZero
&& ColHidden(nCol
))
2795 return pColWidth
[nCol
];
2798 return (sal_uInt16
) STD_COL_WIDTH
;
2802 sal_uInt16
ScTable::GetOriginalWidth( SCCOL nCol
) const // immer die eingestellte
2804 OSL_ENSURE(ValidCol(nCol
),"wrong column number");
2806 if (ValidCol(nCol
) && pColWidth
)
2807 return pColWidth
[nCol
];
2809 return (sal_uInt16
) STD_COL_WIDTH
;
2813 sal_uInt16
ScTable::GetCommonWidth( SCCOL nEndCol
) const
2815 // get the width that is used in the largest continuous column range (up to nEndCol)
2817 if ( !ValidCol(nEndCol
) )
2819 OSL_FAIL("wrong column");
2823 sal_uInt16 nMaxWidth
= 0;
2824 sal_uInt16 nMaxCount
= 0;
2825 SCCOL nRangeStart
= 0;
2826 while ( nRangeStart
<= nEndCol
)
2828 // skip hidden columns
2829 while ( nRangeStart
<= nEndCol
&& ColHidden(nRangeStart
) )
2831 if ( nRangeStart
<= nEndCol
)
2833 sal_uInt16 nThisCount
= 0;
2834 sal_uInt16 nThisWidth
= pColWidth
[nRangeStart
];
2835 SCCOL nRangeEnd
= nRangeStart
;
2836 while ( nRangeEnd
<= nEndCol
&& pColWidth
[nRangeEnd
] == nThisWidth
)
2841 // skip hidden columns
2842 while ( nRangeEnd
<= nEndCol
&& ColHidden(nRangeEnd
) )
2846 if ( nThisCount
> nMaxCount
)
2848 nMaxCount
= nThisCount
;
2849 nMaxWidth
= nThisWidth
;
2852 nRangeStart
= nRangeEnd
; // next range
2860 sal_uInt16
ScTable::GetRowHeight( SCROW nRow
, SCROW
* pStartRow
, SCROW
* pEndRow
, bool bHiddenAsZero
) const
2862 OSL_ENSURE(ValidRow(nRow
),"Invalid row number");
2864 if (ValidRow(nRow
) && mpRowHeights
)
2866 if (bHiddenAsZero
&& RowHidden( nRow
, pStartRow
, pEndRow
))
2870 ScFlatUInt16RowSegments::RangeData aData
;
2871 if (!mpRowHeights
->getRangeData(nRow
, aData
))
2877 // TODO: What should we return in case the search fails?
2881 // If bHiddenAsZero, pStartRow and pEndRow were initialized to
2882 // boundaries of a non-hidden segment. Assume that the previous and
2883 // next segment are hidden then and limit the current height
2886 *pStartRow
= (bHiddenAsZero
? std::max( *pStartRow
, aData
.mnRow1
) : aData
.mnRow1
);
2888 *pEndRow
= (bHiddenAsZero
? std::min( *pEndRow
, aData
.mnRow2
) : aData
.mnRow2
);
2889 return aData
.mnValue
;
2898 return (sal_uInt16
) ScGlobal::nStdRowHeight
;
2903 sal_uLong
ScTable::GetRowHeight( SCROW nStartRow
, SCROW nEndRow
, bool bHiddenAsZero
) const
2905 OSL_ENSURE(ValidRow(nStartRow
) && ValidRow(nEndRow
),"wrong row number");
2907 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2909 sal_uLong nHeight
= 0;
2910 SCROW nRow
= nStartRow
;
2911 while (nRow
<= nEndRow
)
2913 SCROW nLastRow
= -1;
2914 if (!( ( RowHidden(nRow
, NULL
, &nLastRow
) ) && bHiddenAsZero
) )
2916 if (nLastRow
> nEndRow
)
2918 nHeight
+= mpRowHeights
->getSumValue(nRow
, nLastRow
);
2920 nRow
= nLastRow
+ 1;
2925 return (sal_uLong
) ((nEndRow
- nStartRow
+ 1) * ScGlobal::nStdRowHeight
);
2929 sal_uLong
ScTable::GetScaledRowHeight( SCROW nStartRow
, SCROW nEndRow
, double fScale
) const
2931 OSL_ENSURE(ValidRow(nStartRow
) && ValidRow(nEndRow
),"wrong row number");
2933 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && mpRowHeights
)
2935 sal_uLong nHeight
= 0;
2936 SCROW nRow
= nStartRow
;
2937 while (nRow
<= nEndRow
)
2939 SCROW nLastRow
= -1;
2940 if (!RowHidden(nRow
, NULL
, &nLastRow
))
2942 if (nLastRow
> nEndRow
)
2945 // #i117315# can't use getSumValue, because individual values must be rounded
2946 while (nRow
<= nLastRow
)
2948 ScFlatUInt16RowSegments::RangeData aData
;
2949 if (!mpRowHeights
->getRangeData(nRow
, aData
))
2950 return nHeight
; // shouldn't happen
2952 SCROW nSegmentEnd
= std::min( nLastRow
, aData
.mnRow2
);
2954 // round-down a single height value, multiply resulting (pixel) values
2955 sal_uLong nOneHeight
= static_cast<sal_uLong
>( aData
.mnValue
* fScale
);
2956 nHeight
+= nOneHeight
* ( nSegmentEnd
+ 1 - nRow
);
2958 nRow
= nSegmentEnd
+ 1;
2961 nRow
= nLastRow
+ 1;
2966 return (sal_uLong
) ((nEndRow
- nStartRow
+ 1) * ScGlobal::nStdRowHeight
* fScale
);
2970 sal_uInt16
ScTable::GetOriginalHeight( SCROW nRow
) const // non-0 even if hidden
2972 OSL_ENSURE(ValidRow(nRow
),"wrong row number");
2974 if (ValidRow(nRow
) && mpRowHeights
)
2975 return mpRowHeights
->getValue(nRow
);
2977 return (sal_uInt16
) ScGlobal::nStdRowHeight
;
2981 // Spalten-/Zeilen-Flags
2984 SCROW
ScTable::GetHiddenRowCount( SCROW nRow
) const
2986 if (!ValidRow(nRow
))
2989 SCROW nLastRow
= -1;
2990 if (!RowHidden(nRow
, NULL
, &nLastRow
) || !ValidRow(nLastRow
))
2993 return nLastRow
- nRow
+ 1;
2997 //! ShowRows / DBShowRows zusammenfassen
2999 void ScTable::ShowCol(SCCOL nCol
, bool bShow
)
3003 bool bWasVis
= !ColHidden(nCol
);
3004 if (bWasVis
!= bShow
)
3006 SetColHidden(nCol
, nCol
, !bShow
);
3008 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3010 pCharts
->SetRangeDirty(ScRange( nCol
, 0, nTab
, nCol
, MAXROW
, nTab
));
3015 OSL_FAIL("Invalid column number or no flags");
3020 void ScTable::ShowRow(SCROW nRow
, bool bShow
)
3022 if (ValidRow(nRow
) && pRowFlags
)
3024 bool bWasVis
= !RowHidden(nRow
);
3025 if (bWasVis
!= bShow
)
3027 SetRowHidden(nRow
, nRow
, !bShow
);
3029 SetRowFiltered(nRow
, nRow
, false);
3030 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3032 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
3034 InvalidatePageBreaks();
3039 OSL_FAIL("Invalid row number or no flags");
3044 void ScTable::DBShowRow(SCROW nRow
, bool bShow
)
3046 if (ValidRow(nRow
) && pRowFlags
)
3048 // Filter-Flag immer setzen, auch wenn Hidden unveraendert
3049 bool bChanged
= SetRowHidden(nRow
, nRow
, !bShow
);
3050 SetRowFiltered(nRow
, nRow
, !bShow
);
3054 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3056 pCharts
->SetRangeDirty(ScRange( 0, nRow
, nTab
, MAXCOL
, nRow
, nTab
));
3059 UpdateOutlineRow( nRow
, nRow
, bShow
);
3061 InvalidatePageBreaks();
3066 OSL_FAIL("Invalid row number or no flags");
3071 void ScTable::DBShowRows(SCROW nRow1
, SCROW nRow2
, bool bShow
)
3073 SCROW nStartRow
= nRow1
;
3074 while (nStartRow
<= nRow2
)
3077 bool bWasVis
= !RowHiddenLeaf(nStartRow
, NULL
, &nEndRow
);
3078 if (nEndRow
> nRow2
)
3081 bool bChanged
= ( bWasVis
!= bShow
);
3083 SetRowHidden(nStartRow
, nEndRow
, !bShow
);
3084 SetRowFiltered(nStartRow
, nEndRow
, !bShow
);
3088 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3090 pCharts
->SetRangeDirty(ScRange( 0, nStartRow
, nTab
, MAXCOL
, nEndRow
, nTab
));
3093 nStartRow
= nEndRow
+ 1;
3096 // #i12341# For Show/Hide rows, the outlines are updated separately from the outside.
3097 // For filtering, the changes aren't visible to the caller, so UpdateOutlineRow has
3100 UpdateOutlineRow( nRow1
, nRow2
, bShow
);
3104 void ScTable::ShowRows(SCROW nRow1
, SCROW nRow2
, bool bShow
)
3106 SCROW nStartRow
= nRow1
;
3108 // #i116164# if there are no drawing objects within the row range, a single HeightChanged call is enough
3109 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
3110 bool bHasObjects
= pDrawLayer
&& pDrawLayer
->HasObjectsInRows( nTab
, nRow1
, nRow2
);
3112 while (nStartRow
<= nRow2
)
3115 bool bWasVis
= !RowHiddenLeaf(nStartRow
, NULL
, &nEndRow
);
3116 if (nEndRow
> nRow2
)
3119 bool bChanged
= ( bWasVis
!= bShow
);
3121 SetRowHidden(nStartRow
, nEndRow
, !bShow
);
3123 SetRowFiltered(nStartRow
, nEndRow
, false);
3127 ScChartListenerCollection
* pCharts
= pDocument
->GetChartListenerCollection();
3129 pCharts
->SetRangeDirty(ScRange( 0, nStartRow
, nTab
, MAXCOL
, nEndRow
, nTab
));
3131 InvalidatePageBreaks();
3134 nStartRow
= nEndRow
+ 1;
3139 // #i116164# set the flags for the whole range at once
3140 SetRowHidden(nRow1
, nRow2
, !bShow
);
3142 SetRowFiltered(nRow1
, nRow2
, false);
3146 bool ScTable::IsDataFiltered(SCCOL nColStart
, SCROW nRowStart
, SCCOL nColEnd
, SCROW nRowEnd
) const
3148 for (SCROW i
= nRowStart
; i
<= nRowEnd
; ++i
)
3153 for (SCCOL i
= nColStart
; i
<= nColEnd
; ++i
)
3161 bool ScTable::IsDataFiltered(const ScRange
& rRange
) const
3163 return IsDataFiltered(rRange
.aStart
.Col(), rRange
.aStart
.Row(),
3164 rRange
.aEnd
.Col(), rRange
.aEnd
.Row());
3167 void ScTable::SetRowFlags( SCROW nRow
, sal_uInt8 nNewFlags
)
3169 if (ValidRow(nRow
) && pRowFlags
)
3170 pRowFlags
->SetValue( nRow
, nNewFlags
);
3173 OSL_FAIL("Invalid row number or no flags");
3178 void ScTable::SetRowFlags( SCROW nStartRow
, SCROW nEndRow
, sal_uInt8 nNewFlags
)
3180 if (ValidRow(nStartRow
) && ValidRow(nEndRow
) && pRowFlags
)
3181 pRowFlags
->SetValue( nStartRow
, nEndRow
, nNewFlags
);
3184 OSL_FAIL("Invalid row number(s) or no flags");
3189 sal_uInt8
ScTable::GetColFlags( SCCOL nCol
) const
3191 if (ValidCol(nCol
) && pColFlags
)
3192 return pColFlags
[nCol
];
3198 sal_uInt8
ScTable::GetRowFlags( SCROW nRow
) const
3200 if (ValidRow(nRow
) && pRowFlags
)
3201 return pRowFlags
->GetValue(nRow
);
3207 SCROW
ScTable::GetLastFlaggedRow() const
3209 SCROW nLastFound
= 0;
3212 SCROW nRow
= pRowFlags
->GetLastAnyBitAccess( 0, sal::static_int_cast
<sal_uInt8
>(CR_ALL
) );
3217 if (!maRowManualBreaks
.empty())
3218 nLastFound
= ::std::max(nLastFound
, *maRowManualBreaks
.rbegin());
3222 SCROW nRow
= mpHiddenRows
->findLastNotOf(false);
3224 nLastFound
= ::std::max(nLastFound
, nRow
);
3229 SCROW nRow
= mpFilteredRows
->findLastNotOf(false);
3231 nLastFound
= ::std::max(nLastFound
, nRow
);
3238 SCCOL
ScTable::GetLastChangedCol() const
3243 SCCOL nLastFound
= 0;
3244 for (SCCOL nCol
= 1; nCol
<= MAXCOL
; nCol
++)
3245 if ((pColFlags
[nCol
] & CR_ALL
) || (pColWidth
[nCol
] != STD_COL_WIDTH
))
3252 SCROW
ScTable::GetLastChangedRow() const
3257 SCROW nLastFlags
= GetLastFlaggedRow();
3259 // Find the last row position where the height is NOT the standard row
3261 // KOHEI: Test this to make sure it does what it's supposed to.
3262 SCROW nLastHeight
= mpRowHeights
->findLastNotOf(ScGlobal::nStdRowHeight
);
3263 if (!ValidRow(nLastHeight
))
3266 return std::max( nLastFlags
, nLastHeight
);
3270 bool ScTable::UpdateOutlineCol( SCCOL nStartCol
, SCCOL nEndCol
, bool bShow
)
3272 if (pOutlineTable
&& pColFlags
)
3274 ScBitMaskCompressedArray
< SCCOLROW
, sal_uInt8
> aArray( MAXCOL
, pColFlags
, MAXCOLCOUNT
);
3275 return pOutlineTable
->GetColArray()->ManualAction( nStartCol
, nEndCol
, bShow
, *this, true );
3282 bool ScTable::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, bool bShow
)
3284 if (pOutlineTable
&& pRowFlags
)
3285 return pOutlineTable
->GetRowArray()->ManualAction( nStartRow
, nEndRow
, bShow
, *this, false );
3291 void ScTable::ExtendHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
3293 // Column-wise expansion
3295 while (rX1
> 0 && ColHidden(rX1
-1))
3298 while (rX2
< MAXCOL
&& ColHidden(rX2
+1))
3301 // Row-wise expansion
3305 ScFlatBoolRowSegments::RangeData aData
;
3306 if (mpHiddenRows
->getRangeData(rY1
-1, aData
) && aData
.mbValue
)
3308 SCROW nStartRow
= aData
.mnRow1
;
3309 if (ValidRow(nStartRow
))
3316 if (RowHidden(rY2
+1, NULL
, &nEndRow
) && ValidRow(nEndRow
))
3322 void ScTable::StripHidden( SCCOL
& rX1
, SCROW
& rY1
, SCCOL
& rX2
, SCROW
& rY2
)
3324 while ( rX2
>rX1
&& ColHidden(rX2
) )
3326 while ( rX2
>rX1
&& ColHidden(rX1
) )
3331 ScFlatBoolRowSegments::RangeData aData
;
3332 if (mpHiddenRows
->getRangeData(rY2
, aData
) && aData
.mbValue
)
3334 SCROW nStartRow
= aData
.mnRow1
;
3335 if (ValidRow(nStartRow
) && nStartRow
>= rY1
)
3343 if (RowHidden(rY1
, NULL
, &nEndRow
) && ValidRow(nEndRow
) && nEndRow
<= rY2
)
3351 template< typename T
>
3352 short DiffSign( T a
, T b
)
3359 void ScTable::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
)
3361 bool bSizeChanged
= false;
3367 ScOutlineArray
* pArray
;
3371 StartOutlineTable();
3375 SCROW nCount
= nEndRow
-nStartRow
+1;
3376 bool* pUsed
= new bool[nCount
];
3377 for (i
=0; i
<nCount
; i
++)
3379 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3380 if (!aCol
[nCol
].IsEmptyData())
3381 aCol
[nCol
].FindUsed( nStartRow
, nEndRow
, pUsed
);
3383 pArray
= pOutlineTable
->GetRowArray();
3384 for (nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
3385 if (pUsed
[nRow
-nStartRow
])
3388 for (nCol
=nStartCol
; nCol
<=nEndCol
&& !bFound
; nCol
++)
3389 if (!aCol
[nCol
].IsEmptyData())
3391 pCell
= aCol
[nCol
].GetCell( nRow
);
3393 if ( pCell
->GetCellType() == CELLTYPE_FORMULA
)
3394 if (((ScFormulaCell
*)pCell
)->HasRefListExpressibleAsOneReference( aRef
))
3395 if ( aRef
.aStart
.Col() == nCol
&& aRef
.aEnd
.Col() == nCol
&&
3396 aRef
.aStart
.Tab() == nTab
&& aRef
.aEnd
.Tab() == nTab
&&
3397 DiffSign( aRef
.aStart
.Row(), nRow
) ==
3398 DiffSign( aRef
.aEnd
.Row(), nRow
) )
3400 if (pArray
->Insert( aRef
.aStart
.Row(), aRef
.aEnd
.Row(), bSizeChanged
))
3412 pArray
= pOutlineTable
->GetColArray();
3413 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3415 if (!aCol
[nCol
].IsEmptyData())
3418 ScColumnIterator
aIter( &aCol
[nCol
], nStartRow
, nEndRow
);
3419 while ( aIter
.Next( nRow
, pCell
) && !bFound
)
3421 if ( pCell
->GetCellType() == CELLTYPE_FORMULA
)
3422 if (((ScFormulaCell
*)pCell
)->HasRefListExpressibleAsOneReference( aRef
))
3423 if ( aRef
.aStart
.Row() == nRow
&& aRef
.aEnd
.Row() == nRow
&&
3424 aRef
.aStart
.Tab() == nTab
&& aRef
.aEnd
.Tab() == nTab
&&
3425 DiffSign( aRef
.aStart
.Col(), nCol
) ==
3426 DiffSign( aRef
.aEnd
.Col(), nCol
) )
3428 if (pArray
->Insert( aRef
.aStart
.Col(), aRef
.aEnd
.Col(), bSizeChanged
))
3438 // CopyData - fuer Query in anderen Bereich
3440 void ScTable::CopyData( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
3441 SCCOL nDestCol
, SCROW nDestRow
, SCTAB nDestTab
)
3443 //! wenn fuer mehrere Zeilen benutzt, nach Spalten optimieren!
3445 ScAddress
aSrc( nStartCol
, nStartRow
, nTab
);
3446 ScAddress
aDest( nDestCol
, nDestRow
, nDestTab
);
3447 ScRange
aRange( aSrc
, aDest
);
3448 bool bThisTab
= ( nDestTab
== nTab
);
3449 SCROW nDestY
= nDestRow
;
3450 for (SCROW nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
3452 aSrc
.SetRow( nRow
);
3453 aDest
.SetRow( nDestY
);
3454 SCCOL nDestX
= nDestCol
;
3455 for (SCCOL nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
3457 aSrc
.SetCol( nCol
);
3458 aDest
.SetCol( nDestX
);
3459 ScBaseCell
* pCell
= GetCell( nCol
, nRow
);
3462 pCell
= pCell
->Clone( *pDocument
);
3463 if (pCell
->GetCellType() == CELLTYPE_FORMULA
)
3465 ((ScFormulaCell
*)pCell
)->UpdateReference( URM_COPY
, aRange
,
3466 ((SCsCOL
) nDestCol
) - ((SCsCOL
) nStartCol
),
3467 ((SCsROW
) nDestRow
) - ((SCsROW
) nStartRow
),
3468 ((SCsTAB
) nDestTab
) - ((SCsTAB
) nTab
) );
3469 ((ScFormulaCell
*)pCell
)->aPos
= aDest
;
3474 PutCell( nDestX
, nDestY
, pCell
);
3475 SetPattern( nDestX
, nDestY
, *GetPattern( nCol
, nRow
), true );
3479 pDocument
->PutCell( aDest
, pCell
);
3480 pDocument
->SetPattern( aDest
, *GetPattern( nCol
, nRow
), true );
3490 bool ScTable::RefVisible(ScFormulaCell
* pCell
)
3494 if (pCell
->HasOneReference(aRef
))
3496 if (aRef
.aStart
.Col()==aRef
.aEnd
.Col() && aRef
.aStart
.Tab()==aRef
.aEnd
.Tab())
3499 if (!RowFiltered(aRef
.aStart
.Row(), NULL
, &nEndRow
))
3500 // row not filtered.
3501 nEndRow
= ::std::numeric_limits
<SCROW
>::max();
3503 if (!ValidRow(nEndRow
) || nEndRow
< aRef
.aEnd
.Row())
3504 return true; // at least partly visible
3505 return false; // completely invisible
3509 return true; // irgendwie anders
3513 void ScTable::GetUpperCellString(SCCOL nCol
, SCROW nRow
, OUString
& rStr
)
3515 GetInputString(nCol
, nRow
, rStr
);
3516 rStr
= ScGlobal::pCharClass
->uppercase(rStr
.trim());
3520 // Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
3522 void ScTable::SetDrawPageSize(bool bResetStreamValid
, bool bUpdateNoteCaptionPos
)
3524 ScDrawLayer
* pDrawLayer
= pDocument
->GetDrawLayer();
3527 double fValX
= GetColOffset( MAXCOL
+ 1 ) * HMM_PER_TWIPS
;
3528 double fValY
= GetRowOffset( MAXROW
+ 1 ) * HMM_PER_TWIPS
;
3529 const long nMax
= ::std::numeric_limits
<long>::max();
3530 // #i113884# Avoid int32 overflow with possible negative results than can cause bad effects.
3531 // If the draw page size is smaller than all rows, only the bottom of the sheet is affected.
3532 long x
= ( fValX
> (double)nMax
) ? nMax
: (long) fValX
;
3533 long y
= ( fValY
> (double)nMax
) ? nMax
: (long) fValY
;
3535 if ( IsLayoutRTL() ) // IsNegativePage
3538 pDrawLayer
->SetPageSize( static_cast<sal_uInt16
>(nTab
), Size( x
, y
), bUpdateNoteCaptionPos
);
3541 // #i102616# actions that modify the draw page size count as sheet modification
3542 // (exception: InitDrawLayer)
3543 if (bResetStreamValid
&& IsStreamValid())
3544 SetStreamValid(false);
3547 void ScTable::SetRangeName(ScRangeName
* pNew
)
3552 //fdo#39792: mark stream as invalid, otherwise new ScRangeName will not be written to file
3553 if (IsStreamValid())
3554 SetStreamValid(false);
3557 ScRangeName
* ScTable::GetRangeName() const
3560 mpRangeName
= new ScRangeName
;
3565 sal_uLong
ScTable::GetRowOffset( SCROW nRow
, bool bHiddenAsZero
) const
3568 if ( mpHiddenRows
&& mpRowHeights
)
3573 return GetRowHeight(0, NULL
, NULL
, bHiddenAsZero
);
3575 n
= GetTotalRowHeight(0, nRow
-1, bHiddenAsZero
);
3576 #if OSL_DEBUG_LEVEL > 0
3577 if (n
== ::std::numeric_limits
<unsigned long>::max())
3578 OSL_FAIL("ScTable::GetRowOffset: row heights overflow");
3583 OSL_FAIL("GetRowOffset: Data missing");
3588 SCROW
ScTable::GetRowForHeight(sal_uLong nHeight
) const
3590 sal_uInt32 nSum
= 0;
3592 ScFlatBoolRowSegments::RangeData aData
;
3593 for (SCROW nRow
= 0; nRow
<= MAXROW
; ++nRow
)
3595 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
3600 nRow
= aData
.mnRow2
;
3604 sal_uInt32 nNew
= mpRowHeights
->getValue(nRow
);
3608 return nRow
< MAXROW
? nRow
+ 1 : MAXROW
;
3615 sal_uLong
ScTable::GetColOffset( SCCOL nCol
, bool bHiddenAsZero
) const
3621 for( i
= 0; i
< nCol
; i
++ )
3622 if (!( bHiddenAsZero
&& ColHidden(i
) ))
3627 OSL_FAIL("GetColumnOffset: Data missing");
3632 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */