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 .
20 #include "scitems.hxx"
22 #include "patattr.hxx"
23 #include "docpool.hxx"
24 #include "formulacell.hxx"
27 #include "document.hxx"
28 #include "drwlayer.hxx"
29 #include "olinetab.hxx"
30 #include "userlist.hxx"
31 #include "stlsheet.hxx"
33 #include "rechead.hxx"
34 #include "stlpool.hxx"
36 #include "tabprotection.hxx"
37 #include "globstr.hrc"
38 #include "segmenttree.hxx"
39 #include "columniterator.hxx"
40 #include "globalnames.hxx"
42 #include <com/sun/star/sheet/TablePageBreakData.hpp>
47 using ::com::sun::star::uno::Sequence
;
48 using ::com::sun::star::sheet::TablePageBreakData
;
51 // STATIC DATA -----------------------------------------------------------
53 #define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
56 void ScTable::UpdatePageBreaks( const ScRange
* pUserArea
)
58 if ( pDocument
->IsImportingXML() )
61 // pUserArea != NULL -> print area is specified. We need to force-update
69 if (mbPageBreaksValid
)
73 SfxStyleSheetBase
* pStyle
= pDocument
->GetStyleSheetPool()->
74 Find( aPageStyle
, SFX_STYLE_FAMILY_PAGE
);
77 OSL_FAIL("UpdatePageBreaks: Style not found");
80 SfxItemSet
* pStyleSet
= &pStyle
->GetItemSet();
81 const SfxPoolItem
* pItem
;
86 SCCOL nEndCol
= MAXCOL
;
87 SCROW nEndRow
= MAXROW
;
90 nStartCol
= pUserArea
->aStart
.Col();
91 nStartRow
= pUserArea
->aStart
.Row();
92 nEndCol
= pUserArea
->aEnd
.Col();
93 nEndRow
= pUserArea
->aEnd
.Row();
97 sal_uInt16 nAreaCount
= GetPrintRangeCount();
100 // bei mehreren Bereichen nichts anzeigen:
102 for (nX
=0; nX
<MAXCOL
; nX
++)
103 RemoveColBreak(nX
, true, false);
105 RemoveRowPageBreaks(0, MAXROW
-1);
109 else if ( nAreaCount
== 1 )
111 const ScRange
* pArea
= GetPrintRange( 0 );
114 nStartCol
= pArea
->aStart
.Col();
115 nStartRow
= pArea
->aStart
.Row();
116 nEndCol
= pArea
->aEnd
.Col();
117 nEndRow
= pArea
->aEnd
.Row();
122 // get bSkipColBreaks/bSkipRowBreaks flags:
124 bool bSkipColBreaks
= false;
125 bool bSkipRowBreaks
= false;
127 if ( pStyleSet
->GetItemState( ATTR_PAGE_SCALETOPAGES
, false, &pItem
) == SFX_ITEM_SET
)
129 OSL_ENSURE( pItem
->ISA(SfxUInt16Item
), "invalid Item" );
130 bSkipColBreaks
= bSkipRowBreaks
= ( ((const SfxUInt16Item
*)pItem
)->GetValue() > 0 );
133 if ( !bSkipColBreaks
&& pStyleSet
->GetItemState(ATTR_PAGE_SCALETO
, false, &pItem
) == SFX_ITEM_SET
)
135 // #i54993# when fitting to width or height, ignore only manual breaks in that direction
136 const ScPageScaleToItem
* pScaleToItem
= static_cast<const ScPageScaleToItem
*>(pItem
);
137 if ( pScaleToItem
->GetWidth() > 0 )
138 bSkipColBreaks
= true;
139 if ( pScaleToItem
->GetHeight() > 0 )
140 bSkipRowBreaks
= true;
143 //--------------------------------------------------------------------------
145 long nPageSizeX
= aPageSizeTwips
.Width();
146 long nPageSizeY
= aPageSizeTwips
.Height();
148 // Anfang: Breaks loeschen
150 for (nX
=0; nX
<nStartCol
; nX
++)
151 RemoveColBreak(nX
, true, false);
152 RemoveRowPageBreaks(0, nStartRow
-1);
155 SetColBreak(nStartCol
, true, false); // AREABREAK
157 SetRowBreak(nStartRow
, true, false); // AREABREAK
159 // Mittelteil: Breaks verteilen
161 bool bRepeatCol
= ( nRepeatStartX
!= SCCOL_REPEAT_NONE
);
162 bool bColFound
= false;
164 for (nX
=nStartCol
; nX
<=nEndCol
; nX
++)
166 bool bStartOfPage
= false;
167 long nThisX
= ColHidden(nX
) ? 0 : pColWidth
[nX
];
168 bool bManualBreak
= HasColManualBreak(nX
);
169 if ( (nSizeX
+nThisX
> nPageSizeX
) || (bManualBreak
&& !bSkipColBreaks
) )
171 SetColBreak(nX
, true, false);
175 else if (nX
!= nStartCol
)
176 RemoveColBreak(nX
, true, false);
180 if ( bStartOfPage
&& bRepeatCol
&& nX
>nRepeatStartX
&& !bColFound
)
182 // subtract size of repeat columns from page size
183 for (SCCOL i
=nRepeatStartX
; i
<=nRepeatEndX
; i
++)
184 nPageSizeX
-= ColHidden(i
) ? 0 : pColWidth
[i
];
185 while (nX
<=nRepeatEndX
)
186 RemoveColBreak(++nX
, true, false);
193 // Remove all page breaks in range.
194 RemoveRowPageBreaks(nStartRow
+1, nEndRow
);
196 // And set new page breaks.
197 bool bRepeatRow
= ( nRepeatStartY
!= SCROW_REPEAT_NONE
);
198 bool bRowFound
= false;
200 ScFlatBoolRowSegments::ForwardIterator
aIterHidden(*mpHiddenRows
);
201 ScFlatUInt16RowSegments::ForwardIterator
aIterHeights(*mpRowHeights
);
202 SCROW nNextManualBreak
= GetNextManualBreak(nStartRow
); // -1 => no more manual breaks
203 for (SCROW nY
= nStartRow
; nY
<= nEndRow
; ++nY
)
205 bool bStartOfPage
= false;
206 bool bThisRowHidden
= false;
207 aIterHidden
.getValue(nY
, bThisRowHidden
);
212 aIterHeights
.getValue(nY
, nTmp
);
213 nThisY
= static_cast<long>(nTmp
);
216 bool bManualBreak
= false;
217 if (nNextManualBreak
>= 0)
219 bManualBreak
= (nY
== nNextManualBreak
);
220 if (nY
>= nNextManualBreak
)
221 // Query the next menual break position.
222 nNextManualBreak
= GetNextManualBreak(nY
+1);
225 if ( (nSizeY
+nThisY
> nPageSizeY
) || (bManualBreak
&& !bSkipRowBreaks
) )
227 SetRowBreak(nY
, true, false);
231 else if (nY
!= nStartRow
)
232 ; // page break already removed
236 if ( bStartOfPage
&& bRepeatRow
&& nY
>nRepeatStartY
&& !bRowFound
)
238 // subtract size of repeat rows from page size
239 unsigned long nHeights
= GetTotalRowHeight(nRepeatStartY
, nRepeatEndY
);
240 #if OSL_DEBUG_LEVEL > 0
241 if (nHeights
== ::std::numeric_limits
<unsigned long>::max())
242 OSL_FAIL("ScTable::UpdatePageBreaks: row heights overflow");
244 nPageSizeY
-= nHeights
;
245 if (nY
<= nRepeatEndY
)
246 RemoveRowPageBreaks(nY
, nRepeatEndY
);
252 // Hidden row range. Skip them unless there is a manual break.
253 SCROW nLastCommon
= aIterHidden
.getLastPos();
254 if (nNextManualBreak
>= 0)
255 nLastCommon
= ::std::min(nLastCommon
, nNextManualBreak
-1);
260 // Visible row range.
262 SCROW nLastHidden
= aIterHidden
.getLastPos();
263 SCROW nLastHeight
= aIterHeights
.getLastPos();
264 SCROW nLastCommon
= ::std::min(nLastHidden
, nLastHeight
);
265 if (nNextManualBreak
>= 0)
266 nLastCommon
= ::std::min(nLastCommon
, nNextManualBreak
-1);
268 if (nLastCommon
> nY
)
270 long nMaxMultiple
= static_cast<long>(nLastCommon
- nY
);
271 long nMultiple
= (nPageSizeY
- nSizeY
) / nThisY
;
272 if (nMultiple
> nMaxMultiple
)
273 nMultiple
= nMaxMultiple
;
276 nSizeY
+= nThisY
* (nMultiple
- 1);
285 // Ende: Breaks loeschen
287 if (nEndCol
< MAXCOL
)
289 SetColBreak(nEndCol
+1, true, false); // AREABREAK
290 for (nX
=nEndCol
+2; nX
<=MAXCOL
; nX
++)
291 RemoveColBreak(nX
, true, false);
293 if (nEndRow
< MAXROW
)
295 SetRowBreak(nEndRow
+1, true, false); // AREABREAK
296 if (nEndRow
+2 <= MAXROW
)
297 RemoveRowPageBreaks(nEndRow
+2, MAXROW
);
299 mbPageBreaksValid
= !pUserArea
; // #i116881# the valid flag can only apply to the "no user area" case
302 void ScTable::RemoveManualBreaks()
304 maRowManualBreaks
.clear();
305 maColManualBreaks
.clear();
306 InvalidatePageBreaks();
309 SetStreamValid(false);
312 bool ScTable::HasManualBreaks() const
314 return !maRowManualBreaks
.empty() || !maColManualBreaks
.empty();
317 void ScTable::SetRowManualBreaks( const ::std::set
<SCROW
>& rBreaks
)
319 maRowManualBreaks
= rBreaks
;
320 InvalidatePageBreaks();
322 SetStreamValid(false);
325 void ScTable::SetColManualBreaks( const ::std::set
<SCCOL
>& rBreaks
)
327 maColManualBreaks
= rBreaks
;
328 InvalidatePageBreaks();
330 SetStreamValid(false);
333 void ScTable::GetAllRowBreaks(set
<SCROW
>& rBreaks
, bool bPage
, bool bManual
) const
336 rBreaks
= maRowPageBreaks
;
341 copy(maRowManualBreaks
.begin(), maRowManualBreaks
.end(), inserter(rBreaks
, rBreaks
.begin()));
345 void ScTable::GetAllColBreaks(set
<SCCOL
>& rBreaks
, bool bPage
, bool bManual
) const
348 rBreaks
= maColPageBreaks
;
353 copy(maColManualBreaks
.begin(), maColManualBreaks
.end(), inserter(rBreaks
, rBreaks
.begin()));
357 bool ScTable::HasRowPageBreak(SCROW nRow
) const
362 return maRowPageBreaks
.find(nRow
) != maRowPageBreaks
.end();
365 bool ScTable::HasColPageBreak(SCCOL nCol
) const
370 return maColPageBreaks
.find(nCol
) != maColPageBreaks
.end();
373 bool ScTable::HasRowManualBreak(SCROW nRow
) const
378 return maRowManualBreaks
.find(nRow
) != maRowManualBreaks
.end();
381 bool ScTable::HasColManualBreak(SCCOL nCol
) const
386 return maColManualBreaks
.find(nCol
) != maColManualBreaks
.end();
389 SCROW
ScTable::GetNextManualBreak(SCROW nRow
) const
391 set
<SCROW
>::const_iterator itr
= maRowManualBreaks
.lower_bound(nRow
);
392 return itr
== maRowManualBreaks
.end() ? -1 : *itr
;
395 void ScTable::RemoveRowPageBreaks(SCROW nStartRow
, SCROW nEndRow
)
399 if (!ValidRow(nStartRow
) || !ValidRow(nEndRow
))
402 set
<SCROW
>::iterator low
= maRowPageBreaks
.lower_bound(nStartRow
);
403 set
<SCROW
>::iterator high
= maRowPageBreaks
.upper_bound(nEndRow
);
404 maRowPageBreaks
.erase(low
, high
);
407 void ScTable::RemoveRowBreak(SCROW nRow
, bool bPage
, bool bManual
)
413 maRowPageBreaks
.erase(nRow
);
417 maRowManualBreaks
.erase(nRow
);
418 InvalidatePageBreaks();
422 void ScTable::RemoveColBreak(SCCOL nCol
, bool bPage
, bool bManual
)
428 maColPageBreaks
.erase(nCol
);
432 maColManualBreaks
.erase(nCol
);
433 InvalidatePageBreaks();
437 void ScTable::SetRowBreak(SCROW nRow
, bool bPage
, bool bManual
)
443 maRowPageBreaks
.insert(nRow
);
447 maRowManualBreaks
.insert(nRow
);
448 InvalidatePageBreaks();
452 void ScTable::SetColBreak(SCCOL nCol
, bool bPage
, bool bManual
)
458 maColPageBreaks
.insert(nCol
);
462 maColManualBreaks
.insert(nCol
);
463 InvalidatePageBreaks();
467 Sequence
<TablePageBreakData
> ScTable::GetRowBreakData() const
470 using ::std::inserter
;
472 set
<SCROW
> aRowBreaks
= maRowPageBreaks
;
473 copy(maRowManualBreaks
.begin(), maRowManualBreaks
.end(), inserter(aRowBreaks
, aRowBreaks
.begin()));
475 set
<SCROW
>::const_iterator itr
= aRowBreaks
.begin(), itrEnd
= aRowBreaks
.end();
476 Sequence
<TablePageBreakData
> aSeq(aRowBreaks
.size());
478 for (sal_Int32 i
= 0; itr
!= itrEnd
; ++itr
, ++i
)
481 TablePageBreakData aData
;
482 aData
.Position
= nRow
;
483 aData
.ManualBreak
= HasRowManualBreak(nRow
);
490 bool ScTable::RowHidden(SCROW nRow
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
501 ScFlatBoolRowSegments::RangeData aData
;
502 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
513 *pFirstRow
= aData
.mnRow1
;
515 *pLastRow
= aData
.mnRow2
;
517 return aData
.mbValue
;
520 bool ScTable::RowHiddenLeaf(SCROW nRow
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
531 ScFlatBoolRowSegments::RangeData aData
;
532 if (!mpHiddenRows
->getRangeDataLeaf(nRow
, aData
))
543 *pFirstRow
= aData
.mnRow1
;
545 *pLastRow
= aData
.mnRow2
;
547 return aData
.mbValue
;
550 bool ScTable::HasHiddenRows(SCROW nStartRow
, SCROW nEndRow
) const
552 SCROW nRow
= nStartRow
;
553 while (nRow
<= nEndRow
)
556 bool bHidden
= RowHidden(nRow
, NULL
, &nLastRow
);
565 bool ScTable::ColHidden(SCCOL nCol
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
570 ScFlatBoolColSegments::RangeData aData
;
571 if (!mpHiddenCols
->getRangeData(nCol
, aData
))
575 *pFirstCol
= aData
.mnCol1
;
577 *pLastCol
= aData
.mnCol2
;
579 return aData
.mbValue
;
582 bool ScTable::SetRowHidden(SCROW nStartRow
, SCROW nEndRow
, bool bHidden
)
584 bool bChanged
= false;
586 bChanged
= mpHiddenRows
->setTrue(nStartRow
, nEndRow
);
588 bChanged
= mpHiddenRows
->setFalse(nStartRow
, nEndRow
);
593 SetStreamValid(false);
599 bool ScTable::SetColHidden(SCCOL nStartCol
, SCCOL nEndCol
, bool bHidden
)
601 bool bChanged
= false;
603 bChanged
= mpHiddenCols
->setTrue(nStartCol
, nEndCol
);
605 bChanged
= mpHiddenCols
->setFalse(nStartCol
, nEndCol
);
610 SetStreamValid(false);
616 void ScTable::CopyColHidden(ScTable
& rTable
, SCCOL nStartCol
, SCCOL nEndCol
)
618 SCCOL nCol
= nStartCol
;
619 while (nCol
<= nEndCol
)
622 bool bHidden
= rTable
.ColHidden(nCol
, NULL
, &nLastCol
);
623 if (nLastCol
> nEndCol
)
626 SetColHidden(nCol
, nLastCol
, bHidden
);
631 void ScTable::CopyRowHidden(ScTable
& rTable
, SCROW nStartRow
, SCROW nEndRow
)
633 SCROW nRow
= nStartRow
;
634 while (nRow
<= nEndRow
)
637 bool bHidden
= rTable
.RowHidden(nRow
, NULL
, &nLastRow
);
638 if (nLastRow
> nEndRow
)
640 SetRowHidden(nRow
, nLastRow
, bHidden
);
645 void ScTable::CopyRowHeight(ScTable
& rSrcTable
, SCROW nStartRow
, SCROW nEndRow
, SCROW nSrcOffset
)
647 SCROW nRow
= nStartRow
;
648 ScFlatUInt16RowSegments::RangeData aSrcData
;
649 while (nRow
<= nEndRow
)
651 if (!rSrcTable
.mpRowHeights
->getRangeData(nRow
+ nSrcOffset
, aSrcData
))
652 // Something is wrong !
655 SCROW nLastRow
= aSrcData
.mnRow2
- nSrcOffset
;
656 if (nLastRow
> nEndRow
)
659 mpRowHeights
->setValue(nRow
, nLastRow
, aSrcData
.mnValue
);
664 SCROW
ScTable::FirstVisibleRow(SCROW nStartRow
, SCROW nEndRow
) const
666 SCROW nRow
= nStartRow
;
667 ScFlatBoolRowSegments::RangeData aData
;
668 while (nRow
<= nEndRow
)
673 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
674 // failed to get range data.
681 nRow
= aData
.mnRow2
+ 1;
684 return ::std::numeric_limits
<SCROW
>::max();
687 SCROW
ScTable::LastVisibleRow(SCROW nStartRow
, SCROW nEndRow
) const
689 SCROW nRow
= nEndRow
;
690 ScFlatBoolRowSegments::RangeData aData
;
691 while (nRow
>= nStartRow
)
696 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
697 // failed to get range data.
704 nRow
= aData
.mnRow1
- 1;
707 return ::std::numeric_limits
<SCROW
>::max();
710 SCROW
ScTable::CountVisibleRows(SCROW nStartRow
, SCROW nEndRow
) const
713 SCROW nRow
= nStartRow
;
714 ScFlatBoolRowSegments::RangeData aData
;
715 while (nRow
<= nEndRow
)
717 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
720 if (aData
.mnRow2
> nEndRow
)
721 aData
.mnRow2
= nEndRow
;
724 nCount
+= aData
.mnRow2
- nRow
+ 1;
726 nRow
= aData
.mnRow2
+ 1;
731 sal_uInt32
ScTable::GetTotalRowHeight(SCROW nStartRow
, SCROW nEndRow
, bool bHiddenAsZero
) const
733 sal_uInt32 nHeight
= 0;
734 SCROW nRow
= nStartRow
;
735 ScFlatBoolRowSegments::RangeData aData
;
736 while (nRow
<= nEndRow
)
738 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
741 if (aData
.mnRow2
> nEndRow
)
742 aData
.mnRow2
= nEndRow
;
744 if ( !( bHiddenAsZero
&& aData
.mbValue
) )
745 // visible row range.
746 nHeight
+= mpRowHeights
->getSumValue(nRow
, aData
.mnRow2
);
748 nRow
= aData
.mnRow2
+ 1;
754 SCCOLROW
ScTable::LastHiddenColRow(SCCOLROW nPos
, bool bCol
) const
758 SCCOL nCol
= static_cast<SCCOL
>(nPos
);
761 for (SCCOL i
= nCol
+1; i
<= MAXCOL
; ++i
)
763 if (!ColHidden(nCol
))
770 SCROW nRow
= static_cast<SCROW
>(nPos
);
772 if (RowHidden(nRow
, NULL
, &nLastRow
))
773 return static_cast<SCCOLROW
>(nLastRow
);
775 return ::std::numeric_limits
<SCCOLROW
>::max();
778 bool ScTable::RowFiltered(SCROW nRow
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
783 ScFlatBoolRowSegments::RangeData aData
;
784 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
789 *pFirstRow
= aData
.mnRow1
;
791 *pLastRow
= aData
.mnRow2
;
793 return aData
.mbValue
;
796 bool ScTable::ColFiltered(SCCOL nCol
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
801 ScFlatBoolColSegments::RangeData aData
;
802 if (!mpFilteredCols
->getRangeData(nCol
, aData
))
807 *pFirstCol
= aData
.mnCol1
;
809 *pLastCol
= aData
.mnCol2
;
811 return aData
.mbValue
;
814 bool ScTable::HasFilteredRows(SCROW nStartRow
, SCROW nEndRow
) const
816 SCROW nRow
= nStartRow
;
817 while (nRow
<= nEndRow
)
819 SCROW nLastRow
= nRow
;
820 bool bFiltered
= RowFiltered(nRow
, NULL
, &nLastRow
);
829 void ScTable::CopyColFiltered(ScTable
& rTable
, SCCOL nStartCol
, SCCOL nEndCol
)
831 SCCOL nCol
= nStartCol
;
832 while (nCol
<= nEndCol
)
835 bool bFiltered
= rTable
.ColFiltered(nCol
, NULL
, &nLastCol
);
836 if (nLastCol
> nEndCol
)
839 SetColFiltered(nCol
, nLastCol
, bFiltered
);
844 void ScTable::CopyRowFiltered(ScTable
& rTable
, SCROW nStartRow
, SCROW nEndRow
)
846 SCROW nRow
= nStartRow
;
847 while (nRow
<= nEndRow
)
850 bool bFiltered
= rTable
.RowFiltered(nRow
, NULL
, &nLastRow
);
851 if (nLastRow
> nEndRow
)
853 SetRowFiltered(nRow
, nLastRow
, bFiltered
);
858 void ScTable::SetRowFiltered(SCROW nStartRow
, SCROW nEndRow
, bool bFiltered
)
861 mpFilteredRows
->setTrue(nStartRow
, nEndRow
);
863 mpFilteredRows
->setFalse(nStartRow
, nEndRow
);
866 void ScTable::SetColFiltered(SCCOL nStartCol
, SCCOL nEndCol
, bool bFiltered
)
869 mpFilteredCols
->setTrue(nStartCol
, nEndCol
);
871 mpFilteredCols
->setFalse(nStartCol
, nEndCol
);
874 SCROW
ScTable::FirstNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
) const
876 SCROW nRow
= nStartRow
;
877 ScFlatBoolRowSegments::RangeData aData
;
878 while (nRow
<= nEndRow
)
883 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
884 // failed to get range data.
888 // non-filtered row found
891 nRow
= aData
.mnRow2
+ 1;
894 return ::std::numeric_limits
<SCROW
>::max();
897 SCROW
ScTable::LastNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
) const
899 SCROW nRow
= nEndRow
;
900 ScFlatBoolRowSegments::RangeData aData
;
901 while (nRow
>= nStartRow
)
906 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
907 // failed to get range data.
911 // non-filtered row found
914 nRow
= aData
.mnRow1
- 1;
917 return ::std::numeric_limits
<SCROW
>::max();
920 SCROW
ScTable::CountNonFilteredRows(SCROW nStartRow
, SCROW nEndRow
) const
923 SCROW nRow
= nStartRow
;
924 ScFlatBoolRowSegments::RangeData aData
;
925 while (nRow
<= nEndRow
)
927 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
930 if (aData
.mnRow2
> nEndRow
)
931 aData
.mnRow2
= nEndRow
;
934 nCount
+= aData
.mnRow2
- nRow
+ 1;
936 nRow
= aData
.mnRow2
+ 1;
941 bool ScTable::IsManualRowHeight(SCROW nRow
) const
943 return (pRowFlags
->GetValue(nRow
) & CR_MANUALSIZE
) != 0;
948 void lcl_syncFlags(ScFlatBoolColSegments
& rColSegments
, ScFlatBoolRowSegments
& rRowSegments
,
949 sal_uInt8
* pColFlags
, ScBitMaskCompressedArray
< SCROW
, sal_uInt8
>* pRowFlags
, const sal_uInt8 nFlagMask
)
951 using ::sal::static_int_cast
;
953 sal_uInt8 nFlagMaskComplement
= static_int_cast
<sal_uInt8
>(~nFlagMask
);
955 pRowFlags
->AndValue(0, MAXROW
, nFlagMaskComplement
);
956 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
957 pColFlags
[i
] &= nFlagMaskComplement
;
963 ScFlatBoolRowSegments::RangeData aData
;
964 while (nRow
<= MAXROW
)
966 if (!rRowSegments
.getRangeData(nRow
, aData
))
970 pRowFlags
->OrValue(nRow
, aData
.mnRow2
, nFlagMask
);
972 nRow
= aData
.mnRow2
+ 1;
977 // column hidden flags.
980 ScFlatBoolColSegments::RangeData aData
;
981 while (nCol
<= MAXCOL
)
983 if (!rColSegments
.getRangeData(nCol
, aData
))
988 for (SCCOL i
= nCol
; i
<= aData
.mnCol2
; ++i
)
989 pColFlags
[i
] |= nFlagMask
;
992 nCol
= aData
.mnCol2
+ 1;
999 void ScTable::SyncColRowFlags()
1001 using ::sal::static_int_cast
;
1003 sal_uInt8 nManualBreakComplement
= static_int_cast
<sal_uInt8
>(~CR_MANUALBREAK
);
1006 pRowFlags
->AndValue(0, MAXROW
, nManualBreakComplement
);
1007 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1008 pColFlags
[i
] &= nManualBreakComplement
;
1010 if (!maRowManualBreaks
.empty())
1012 for (set
<SCROW
>::const_iterator itr
= maRowManualBreaks
.begin(), itrEnd
= maRowManualBreaks
.end();
1013 itr
!= itrEnd
; ++itr
)
1014 pRowFlags
->OrValue(*itr
, CR_MANUALBREAK
);
1017 if (!maColManualBreaks
.empty())
1019 for (set
<SCCOL
>::const_iterator itr
= maColManualBreaks
.begin(), itrEnd
= maColManualBreaks
.end();
1020 itr
!= itrEnd
; ++itr
)
1021 pColFlags
[*itr
] |= CR_MANUALBREAK
;
1025 lcl_syncFlags(*mpHiddenCols
, *mpHiddenRows
, pColFlags
, pRowFlags
, CR_HIDDEN
);
1026 lcl_syncFlags(*mpFilteredCols
, *mpFilteredRows
, pColFlags
, pRowFlags
, CR_FILTERED
);
1029 void ScTable::SetPageSize( const Size
& rSize
)
1031 if ( rSize
.Width() != 0 && rSize
.Height() != 0 )
1033 if (aPageSizeTwips
!= rSize
)
1034 InvalidatePageBreaks();
1036 bPageSizeValid
= true;
1037 aPageSizeTwips
= rSize
;
1040 bPageSizeValid
= false;
1043 bool ScTable::IsProtected() const
1045 return pTabProtection
.get() && pTabProtection
->isProtected();
1048 void ScTable::SetProtection(const ScTableProtection
* pProtect
)
1051 pTabProtection
.reset(new ScTableProtection(*pProtect
));
1053 pTabProtection
.reset(NULL
);
1055 if (IsStreamValid())
1056 SetStreamValid(false);
1059 ScTableProtection
* ScTable::GetProtection()
1061 return pTabProtection
.get();
1064 Size
ScTable::GetPageSize() const
1066 if ( bPageSizeValid
)
1067 return aPageSizeTwips
;
1069 return Size(); // leer
1072 void ScTable::SetRepeatArea( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCROW nEndRow
)
1074 // #i117952# page break calculation uses these values (set from ScPrintFunc), not pRepeatColRange/pRepeatRowRange
1075 if ( nStartCol
!= nRepeatStartX
|| nEndCol
!= nRepeatEndX
|| nStartRow
!= nRepeatStartY
|| nEndRow
!= nRepeatEndY
)
1076 InvalidatePageBreaks();
1078 nRepeatStartX
= nStartCol
;
1079 nRepeatEndX
= nEndCol
;
1080 nRepeatStartY
= nStartRow
;
1081 nRepeatEndY
= nEndRow
;
1084 void ScTable::StartListening( const ScAddress
& rAddress
, SvtListener
* pListener
)
1086 if (!ValidCol(rAddress
.Col()))
1089 aCol
[rAddress
.Col()].StartListening( *pListener
, rAddress
.Row() );
1092 void ScTable::EndListening( const ScAddress
& rAddress
, SvtListener
* pListener
)
1094 if (!ValidCol(rAddress
.Col()))
1097 aCol
[rAddress
.Col()].EndListening( *pListener
, rAddress
.Row() );
1100 void ScTable::StartListening( sc::StartListeningContext
& rCxt
, SCCOL nCol
, SCROW nRow
, SvtListener
& rListener
)
1102 if (!ValidCol(nCol
))
1105 aCol
[nCol
].StartListening(rCxt
, nRow
, rListener
);
1108 void ScTable::EndListening( sc::EndListeningContext
& rCxt
, SCCOL nCol
, SCROW nRow
, SvtListener
& rListener
)
1110 if (!ValidCol(nCol
))
1113 aCol
[nCol
].EndListening(rCxt
, nRow
, rListener
);
1116 void ScTable::SetPageStyle( const OUString
& rName
)
1118 if ( aPageStyle
!= rName
)
1120 OUString aStrNew
= rName
;
1121 SfxStyleSheetBasePool
* pStylePool
= pDocument
->GetStyleSheetPool();
1122 SfxStyleSheetBase
* pNewStyle
= pStylePool
->Find( aStrNew
, SFX_STYLE_FAMILY_PAGE
);
1126 aStrNew
= ScGlobal::GetRscString(STR_STYLENAME_STANDARD
);
1127 pNewStyle
= pStylePool
->Find( aStrNew
, SFX_STYLE_FAMILY_PAGE
);
1130 if ( aPageStyle
!= aStrNew
)
1132 SfxStyleSheetBase
* pOldStyle
= pStylePool
->Find( aPageStyle
, SFX_STYLE_FAMILY_PAGE
);
1134 if ( pOldStyle
&& pNewStyle
)
1136 SfxItemSet
& rOldSet
= pOldStyle
->GetItemSet();
1137 SfxItemSet
& rNewSet
= pNewStyle
->GetItemSet();
1138 const sal_uInt16 nOldScale
= GET_SCALEVALUE(rOldSet
,ATTR_PAGE_SCALE
);
1139 const sal_uInt16 nOldScaleToPages
= GET_SCALEVALUE(rOldSet
,ATTR_PAGE_SCALETOPAGES
);
1140 const sal_uInt16 nNewScale
= GET_SCALEVALUE(rNewSet
,ATTR_PAGE_SCALE
);
1141 const sal_uInt16 nNewScaleToPages
= GET_SCALEVALUE(rNewSet
,ATTR_PAGE_SCALETOPAGES
);
1143 if ( (nOldScale
!= nNewScale
) || (nOldScaleToPages
!= nNewScaleToPages
) )
1144 InvalidateTextWidth(NULL
, NULL
, false, false);
1147 if ( pNewStyle
) // auch ohne den alten (fuer UpdateStdNames)
1148 aPageStyle
= aStrNew
;
1150 if (IsStreamValid())
1151 SetStreamValid(false);
1156 void ScTable::PageStyleModified( const String
& rNewName
)
1158 aPageStyle
= rNewName
;
1159 InvalidateTextWidth(NULL
, NULL
, false, false); // don't know what was in the style before
1162 void ScTable::InvalidateTextWidth( const ScAddress
* pAdrFrom
, const ScAddress
* pAdrTo
,
1163 bool bNumFormatChanged
, bool bBroadcast
)
1165 if ( pAdrFrom
&& !pAdrTo
)
1167 // Special case: only process the "from" cell.
1168 SCCOL nCol
= pAdrFrom
->Col();
1169 SCROW nRow
= pAdrFrom
->Row();
1170 ScColumn
& rCol
= aCol
[nCol
];
1171 ScBaseCell
* pCell
= rCol
.GetCell(nRow
);
1175 rCol
.SetTextWidth(nRow
, TEXTWIDTH_DIRTY
);
1177 if ( bNumFormatChanged
)
1178 rCol
.SetScriptType(nRow
, SC_SCRIPTTYPE_UNKNOWN
);
1181 { // nur bei CalcAsShown
1182 switch ( pCell
->GetCellType() )
1184 case CELLTYPE_VALUE
:
1185 pDocument
->Broadcast(ScHint(SC_HINT_DATACHANGED
, ScAddress(nCol
, nRow
, nTab
)));
1187 case CELLTYPE_FORMULA
:
1188 ((ScFormulaCell
*)pCell
)->SetDirty();
1192 // added to avoid warnings
1200 const SCCOL nCol1
= pAdrFrom
? pAdrFrom
->Col() : 0;
1201 const SCROW nRow1
= pAdrFrom
? pAdrFrom
->Row() : 0;
1202 const SCCOL nCol2
= pAdrTo
? pAdrTo
->Col() : MAXCOL
;
1203 const SCROW nRow2
= pAdrTo
? pAdrTo
->Row() : MAXROW
;
1205 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
1207 ScColumnTextWidthIterator
aIter(aCol
[nCol
], nRow1
, nRow2
);
1209 for (; aIter
.hasCell(); aIter
.next())
1211 SCROW nRow
= aIter
.getPos();
1212 aIter
.setValue(TEXTWIDTH_DIRTY
);
1213 ScBaseCell
* pCell
= aCol
[nCol
].GetCell(nRow
);
1219 if ( bNumFormatChanged
)
1220 aCol
[nCol
].SetScriptType(nRow
, SC_SCRIPTTYPE_UNKNOWN
);
1223 { // nur bei CalcAsShown
1224 switch ( pCell
->GetCellType() )
1226 case CELLTYPE_VALUE
:
1227 pDocument
->Broadcast(
1228 ScHint(SC_HINT_DATACHANGED
, ScAddress(nCol
, nRow
, nTab
)));
1230 case CELLTYPE_FORMULA
:
1231 ((ScFormulaCell
*)pCell
)->SetDirty();
1235 // added to avoid warnings
1247 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */