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 "printopt.hxx"
44 #include <com/sun/star/sheet/TablePageBreakData.hpp>
50 using ::com::sun::star::uno::Sequence
;
51 using ::com::sun::star::sheet::TablePageBreakData
;
54 // STATIC DATA -----------------------------------------------------------
56 #define GET_SCALEVALUE(set,id) static_cast<const SfxUInt16Item&>(set.Get( id )).GetValue()
58 void ScTable::UpdatePageBreaks( const ScRange
* pUserArea
)
60 if ( pDocument
->IsImportingXML() )
63 // pUserArea != NULL -> print area is specified. We need to force-update
71 // Always update breaks if force breaks option has changed
72 if (mbPageBreaksValid
&& mbForceBreaks
== SC_MOD()->GetPrintOptions().GetForceBreaks())
76 SfxStyleSheetBase
* pStyle
= pDocument
->GetStyleSheetPool()->
77 Find( aPageStyle
, SFX_STYLE_FAMILY_PAGE
);
80 OSL_FAIL("UpdatePageBreaks: Style not found");
83 SfxItemSet
* pStyleSet
= &pStyle
->GetItemSet();
84 const SfxPoolItem
* pItem
;
89 SCCOL nEndCol
= MAXCOL
;
90 SCROW nEndRow
= MAXROW
;
93 nStartCol
= pUserArea
->aStart
.Col();
94 nStartRow
= pUserArea
->aStart
.Row();
95 nEndCol
= pUserArea
->aEnd
.Col();
96 nEndRow
= pUserArea
->aEnd
.Row();
100 sal_uInt16 nAreaCount
= GetPrintRangeCount();
101 if ( nAreaCount
> 1 )
103 // Show nothing, when multiple ranges
105 for (nX
=0; nX
<MAXCOL
; nX
++)
106 RemoveColBreak(nX
, true, false);
108 RemoveRowPageBreaks(0, MAXROW
-1);
112 else if ( nAreaCount
== 1 )
114 const ScRange
* pArea
= GetPrintRange( 0 );
117 nStartCol
= pArea
->aStart
.Col();
118 nStartRow
= pArea
->aStart
.Row();
119 nEndCol
= pArea
->aEnd
.Col();
120 nEndRow
= pArea
->aEnd
.Row();
122 } // otherwise show everything
125 // get bSkipColBreaks/bSkipRowBreaks flags:
126 // fdo#40788 - print range scale settings can cause manual breaks to be
127 // ignored (see below). This behaviour may now be set by the user.
128 mbForceBreaks
= SC_MOD()->GetPrintOptions().GetForceBreaks();
129 bool bSkipColBreaks
= false;
130 bool bSkipRowBreaks
= false;
134 if ( pStyleSet
->GetItemState( ATTR_PAGE_SCALETOPAGES
, false, &pItem
) == SfxItemState::SET
)
136 OSL_ENSURE( pItem
->ISA(SfxUInt16Item
), "invalid Item" );
137 bSkipColBreaks
= bSkipRowBreaks
= static_cast<const SfxUInt16Item
*>(pItem
)->GetValue() > 0;
140 if ( !bSkipColBreaks
&& pStyleSet
->GetItemState(ATTR_PAGE_SCALETO
, false, &pItem
) == SfxItemState::SET
)
142 // #i54993# when fitting to width or height, ignore only manual breaks in that direction
143 const ScPageScaleToItem
* pScaleToItem
= static_cast<const ScPageScaleToItem
*>(pItem
);
144 if ( pScaleToItem
->GetWidth() > 0 )
145 bSkipColBreaks
= true;
146 if ( pScaleToItem
->GetHeight() > 0 )
147 bSkipRowBreaks
= true;
151 long nPageSizeX
= aPageSizeTwips
.Width();
152 long nPageSizeY
= aPageSizeTwips
.Height();
154 // Beginning: Remove breaks
156 for (nX
=0; nX
<nStartCol
; nX
++)
157 RemoveColBreak(nX
, true, false);
158 RemoveRowPageBreaks(0, nStartRow
-1);
161 SetColBreak(nStartCol
, true, false); // AREABREAK
163 SetRowBreak(nStartRow
, true, false); // AREABREAK
165 // Middle part: Distribute breaks
167 bool bRepeatCol
= ( nRepeatStartX
!= SCCOL_REPEAT_NONE
);
168 bool bColFound
= false;
170 for (nX
=nStartCol
; nX
<=nEndCol
; nX
++)
172 bool bStartOfPage
= false;
173 long nThisX
= ColHidden(nX
) ? 0 : pColWidth
[nX
];
174 bool bManualBreak
= HasColManualBreak(nX
);
175 if ( (nSizeX
+nThisX
> nPageSizeX
) || (bManualBreak
&& !bSkipColBreaks
) )
177 SetColBreak(nX
, true, false);
181 else if (nX
!= nStartCol
)
182 RemoveColBreak(nX
, true, false);
186 if ( bStartOfPage
&& bRepeatCol
&& nX
>nRepeatStartX
&& !bColFound
)
188 // subtract size of repeat columns from page size
189 for (SCCOL i
=nRepeatStartX
; i
<=nRepeatEndX
; i
++)
190 nPageSizeX
-= ColHidden(i
) ? 0 : pColWidth
[i
];
191 while (nX
<=nRepeatEndX
)
192 RemoveColBreak(++nX
, true, false);
199 // Remove all page breaks in range.
200 RemoveRowPageBreaks(nStartRow
+1, nEndRow
);
202 // And set new page breaks.
203 bool bRepeatRow
= ( nRepeatStartY
!= SCROW_REPEAT_NONE
);
204 bool bRowFound
= false;
206 ScFlatBoolRowSegments::ForwardIterator
aIterHidden(*mpHiddenRows
);
207 ScFlatUInt16RowSegments::ForwardIterator
aIterHeights(*mpRowHeights
);
208 SCROW nNextManualBreak
= GetNextManualBreak(nStartRow
); // -1 => no more manual breaks
209 for (SCROW nY
= nStartRow
; nY
<= nEndRow
; ++nY
)
211 bool bStartOfPage
= false;
212 bool bThisRowHidden
= false;
213 aIterHidden
.getValue(nY
, bThisRowHidden
);
218 aIterHeights
.getValue(nY
, nTmp
);
219 nThisY
= static_cast<long>(nTmp
);
222 bool bManualBreak
= false;
223 if (nNextManualBreak
>= 0)
225 bManualBreak
= (nY
== nNextManualBreak
);
226 if (nY
>= nNextManualBreak
)
227 // Query the next menual break position.
228 nNextManualBreak
= GetNextManualBreak(nY
+1);
231 if ( (nSizeY
+nThisY
> nPageSizeY
) || (bManualBreak
&& !bSkipRowBreaks
) )
233 SetRowBreak(nY
, true, false);
237 else if (nY
!= nStartRow
)
238 ; // page break already removed
242 if ( bStartOfPage
&& bRepeatRow
&& nY
>nRepeatStartY
&& !bRowFound
)
244 // subtract size of repeat rows from page size
245 unsigned long nHeights
= GetTotalRowHeight(nRepeatStartY
, nRepeatEndY
);
246 #if OSL_DEBUG_LEVEL > 0
247 if (nHeights
== ::std::numeric_limits
<unsigned long>::max())
248 OSL_FAIL("ScTable::UpdatePageBreaks: row heights overflow");
250 nPageSizeY
-= nHeights
;
251 if (nY
<= nRepeatEndY
)
252 RemoveRowPageBreaks(nY
, nRepeatEndY
);
258 // Hidden row range. Skip them unless there is a manual break.
259 SCROW nLastCommon
= aIterHidden
.getLastPos();
260 if (nNextManualBreak
>= 0)
261 nLastCommon
= ::std::min(nLastCommon
, nNextManualBreak
-1);
266 // Visible row range.
268 SCROW nLastHidden
= aIterHidden
.getLastPos();
269 SCROW nLastHeight
= aIterHeights
.getLastPos();
270 SCROW nLastCommon
= ::std::min(nLastHidden
, nLastHeight
);
271 if (nNextManualBreak
>= 0)
272 nLastCommon
= ::std::min(nLastCommon
, nNextManualBreak
-1);
274 if (nLastCommon
> nY
)
276 long nMaxMultiple
= static_cast<long>(nLastCommon
- nY
);
277 long nMultiple
= (nPageSizeY
- nSizeY
) / nThisY
;
278 if (nMultiple
> nMaxMultiple
)
279 nMultiple
= nMaxMultiple
;
282 nSizeY
+= nThisY
* (nMultiple
- 1);
293 if (nEndCol
< MAXCOL
)
295 SetColBreak(nEndCol
+1, true, false); // AREABREAK
296 for (nX
=nEndCol
+2; nX
<=MAXCOL
; nX
++)
297 RemoveColBreak(nX
, true, false);
299 if (nEndRow
< MAXROW
)
301 SetRowBreak(nEndRow
+1, true, false); // AREABREAK
302 if (nEndRow
+2 <= MAXROW
)
303 RemoveRowPageBreaks(nEndRow
+2, MAXROW
);
305 mbPageBreaksValid
= !pUserArea
; // #i116881# the valid flag can only apply to the "no user area" case
308 void ScTable::RemoveManualBreaks()
310 maRowManualBreaks
.clear();
311 maColManualBreaks
.clear();
312 InvalidatePageBreaks();
315 SetStreamValid(false);
318 bool ScTable::HasManualBreaks() const
320 return !maRowManualBreaks
.empty() || !maColManualBreaks
.empty();
323 void ScTable::SetRowManualBreaks( const ::std::set
<SCROW
>& rBreaks
)
325 maRowManualBreaks
= rBreaks
;
326 InvalidatePageBreaks();
328 SetStreamValid(false);
331 void ScTable::SetColManualBreaks( const ::std::set
<SCCOL
>& rBreaks
)
333 maColManualBreaks
= rBreaks
;
334 InvalidatePageBreaks();
336 SetStreamValid(false);
339 void ScTable::GetAllRowBreaks(set
<SCROW
>& rBreaks
, bool bPage
, bool bManual
) const
342 rBreaks
= maRowPageBreaks
;
347 copy(maRowManualBreaks
.begin(), maRowManualBreaks
.end(), inserter(rBreaks
, rBreaks
.begin()));
351 void ScTable::GetAllColBreaks(set
<SCCOL
>& rBreaks
, bool bPage
, bool bManual
) const
354 rBreaks
= maColPageBreaks
;
359 copy(maColManualBreaks
.begin(), maColManualBreaks
.end(), inserter(rBreaks
, rBreaks
.begin()));
363 bool ScTable::HasRowPageBreak(SCROW nRow
) const
368 return maRowPageBreaks
.find(nRow
) != maRowPageBreaks
.end();
371 bool ScTable::HasColPageBreak(SCCOL nCol
) const
376 return maColPageBreaks
.find(nCol
) != maColPageBreaks
.end();
379 bool ScTable::HasRowManualBreak(SCROW nRow
) const
384 return maRowManualBreaks
.find(nRow
) != maRowManualBreaks
.end();
387 bool ScTable::HasColManualBreak(SCCOL nCol
) const
392 return maColManualBreaks
.find(nCol
) != maColManualBreaks
.end();
395 SCROW
ScTable::GetNextManualBreak(SCROW nRow
) const
397 set
<SCROW
>::const_iterator itr
= maRowManualBreaks
.lower_bound(nRow
);
398 return itr
== maRowManualBreaks
.end() ? -1 : *itr
;
401 void ScTable::RemoveRowPageBreaks(SCROW nStartRow
, SCROW nEndRow
)
405 if (!ValidRow(nStartRow
) || !ValidRow(nEndRow
))
408 set
<SCROW
>::iterator low
= maRowPageBreaks
.lower_bound(nStartRow
);
409 set
<SCROW
>::iterator high
= maRowPageBreaks
.upper_bound(nEndRow
);
410 maRowPageBreaks
.erase(low
, high
);
413 void ScTable::RemoveRowBreak(SCROW nRow
, bool bPage
, bool bManual
)
419 maRowPageBreaks
.erase(nRow
);
423 maRowManualBreaks
.erase(nRow
);
424 InvalidatePageBreaks();
428 void ScTable::RemoveColBreak(SCCOL nCol
, bool bPage
, bool bManual
)
434 maColPageBreaks
.erase(nCol
);
438 maColManualBreaks
.erase(nCol
);
439 InvalidatePageBreaks();
443 void ScTable::SetRowBreak(SCROW nRow
, bool bPage
, bool bManual
)
449 maRowPageBreaks
.insert(nRow
);
453 maRowManualBreaks
.insert(nRow
);
454 InvalidatePageBreaks();
458 void ScTable::SetColBreak(SCCOL nCol
, bool bPage
, bool bManual
)
464 maColPageBreaks
.insert(nCol
);
468 maColManualBreaks
.insert(nCol
);
469 InvalidatePageBreaks();
473 Sequence
<TablePageBreakData
> ScTable::GetRowBreakData() const
476 using ::std::inserter
;
478 set
<SCROW
> aRowBreaks
= maRowPageBreaks
;
479 copy(maRowManualBreaks
.begin(), maRowManualBreaks
.end(), inserter(aRowBreaks
, aRowBreaks
.begin()));
481 set
<SCROW
>::const_iterator itr
= aRowBreaks
.begin(), itrEnd
= aRowBreaks
.end();
482 Sequence
<TablePageBreakData
> aSeq(aRowBreaks
.size());
484 for (sal_Int32 i
= 0; itr
!= itrEnd
; ++itr
, ++i
)
487 TablePageBreakData aData
;
488 aData
.Position
= nRow
;
489 aData
.ManualBreak
= HasRowManualBreak(nRow
);
496 bool ScTable::RowHidden(SCROW nRow
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
507 ScFlatBoolRowSegments::RangeData aData
;
508 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
519 *pFirstRow
= aData
.mnRow1
;
521 *pLastRow
= aData
.mnRow2
;
523 return aData
.mbValue
;
526 bool ScTable::RowHiddenLeaf(SCROW nRow
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
537 ScFlatBoolRowSegments::RangeData aData
;
538 if (!mpHiddenRows
->getRangeDataLeaf(nRow
, aData
))
549 *pFirstRow
= aData
.mnRow1
;
551 *pLastRow
= aData
.mnRow2
;
553 return aData
.mbValue
;
556 bool ScTable::HasHiddenRows(SCROW nStartRow
, SCROW nEndRow
) const
558 SCROW nRow
= nStartRow
;
559 while (nRow
<= nEndRow
)
562 bool bHidden
= RowHidden(nRow
, NULL
, &nLastRow
);
571 bool ScTable::ColHidden(SCCOL nCol
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
576 ScFlatBoolColSegments::RangeData aData
;
577 if (!mpHiddenCols
->getRangeData(nCol
, aData
))
581 *pFirstCol
= aData
.mnCol1
;
583 *pLastCol
= aData
.mnCol2
;
585 return aData
.mbValue
;
588 bool ScTable::SetRowHidden(SCROW nStartRow
, SCROW nEndRow
, bool bHidden
)
590 bool bChanged
= false;
592 bChanged
= mpHiddenRows
->setTrue(nStartRow
, nEndRow
);
594 bChanged
= mpHiddenRows
->setFalse(nStartRow
, nEndRow
);
599 SetStreamValid(false);
605 bool ScTable::SetColHidden(SCCOL nStartCol
, SCCOL nEndCol
, bool bHidden
)
607 bool bChanged
= false;
609 bChanged
= mpHiddenCols
->setTrue(nStartCol
, nEndCol
);
611 bChanged
= mpHiddenCols
->setFalse(nStartCol
, nEndCol
);
616 SetStreamValid(false);
622 void ScTable::CopyColHidden(ScTable
& rTable
, SCCOL nStartCol
, SCCOL nEndCol
)
624 SCCOL nCol
= nStartCol
;
625 while (nCol
<= nEndCol
)
628 bool bHidden
= rTable
.ColHidden(nCol
, NULL
, &nLastCol
);
629 if (nLastCol
> nEndCol
)
632 SetColHidden(nCol
, nLastCol
, bHidden
);
637 void ScTable::CopyRowHidden(ScTable
& rTable
, SCROW nStartRow
, SCROW nEndRow
)
639 SCROW nRow
= nStartRow
;
640 while (nRow
<= nEndRow
)
643 bool bHidden
= rTable
.RowHidden(nRow
, NULL
, &nLastRow
);
644 if (nLastRow
> nEndRow
)
646 SetRowHidden(nRow
, nLastRow
, bHidden
);
651 void ScTable::CopyRowHeight(ScTable
& rSrcTable
, SCROW nStartRow
, SCROW nEndRow
, SCROW nSrcOffset
)
653 SCROW nRow
= nStartRow
;
654 ScFlatUInt16RowSegments::RangeData aSrcData
;
655 while (nRow
<= nEndRow
)
657 if (!rSrcTable
.mpRowHeights
->getRangeData(nRow
+ nSrcOffset
, aSrcData
))
658 // Something is wrong !
661 SCROW nLastRow
= aSrcData
.mnRow2
- nSrcOffset
;
662 if (nLastRow
> nEndRow
)
665 mpRowHeights
->setValue(nRow
, nLastRow
, aSrcData
.mnValue
);
670 SCROW
ScTable::FirstVisibleRow(SCROW nStartRow
, SCROW nEndRow
) const
672 SCROW nRow
= nStartRow
;
673 ScFlatBoolRowSegments::RangeData aData
;
674 while (nRow
<= nEndRow
)
679 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
680 // failed to get range data.
687 nRow
= aData
.mnRow2
+ 1;
690 return ::std::numeric_limits
<SCROW
>::max();
693 SCROW
ScTable::LastVisibleRow(SCROW nStartRow
, SCROW nEndRow
) const
695 SCROW nRow
= nEndRow
;
696 ScFlatBoolRowSegments::RangeData aData
;
697 while (nRow
>= nStartRow
)
702 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
703 // failed to get range data.
710 nRow
= aData
.mnRow1
- 1;
713 return ::std::numeric_limits
<SCROW
>::max();
716 SCROW
ScTable::CountVisibleRows(SCROW nStartRow
, SCROW nEndRow
) const
719 SCROW nRow
= nStartRow
;
720 ScFlatBoolRowSegments::RangeData aData
;
721 while (nRow
<= nEndRow
)
723 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
726 if (aData
.mnRow2
> nEndRow
)
727 aData
.mnRow2
= nEndRow
;
730 nCount
+= aData
.mnRow2
- nRow
+ 1;
732 nRow
= aData
.mnRow2
+ 1;
737 sal_uInt32
ScTable::GetTotalRowHeight(SCROW nStartRow
, SCROW nEndRow
, bool bHiddenAsZero
) const
739 sal_uInt32 nHeight
= 0;
740 SCROW nRow
= nStartRow
;
741 ScFlatBoolRowSegments::RangeData aData
;
742 while (nRow
<= nEndRow
)
744 if (!mpHiddenRows
->getRangeData(nRow
, aData
))
747 if (aData
.mnRow2
> nEndRow
)
748 aData
.mnRow2
= nEndRow
;
750 if ( !( bHiddenAsZero
&& aData
.mbValue
) )
751 // visible row range.
752 nHeight
+= mpRowHeights
->getSumValue(nRow
, aData
.mnRow2
);
754 nRow
= aData
.mnRow2
+ 1;
760 SCCOLROW
ScTable::LastHiddenColRow(SCCOLROW nPos
, bool bCol
) const
764 SCCOL nCol
= static_cast<SCCOL
>(nPos
);
767 for (SCCOL i
= nCol
+1; i
<= MAXCOL
; ++i
)
769 if (!ColHidden(nCol
))
776 SCROW nRow
= static_cast<SCROW
>(nPos
);
778 if (RowHidden(nRow
, NULL
, &nLastRow
))
779 return static_cast<SCCOLROW
>(nLastRow
);
781 return ::std::numeric_limits
<SCCOLROW
>::max();
784 bool ScTable::RowFiltered(SCROW nRow
, SCROW
* pFirstRow
, SCROW
* pLastRow
) const
789 ScFlatBoolRowSegments::RangeData aData
;
790 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
795 *pFirstRow
= aData
.mnRow1
;
797 *pLastRow
= aData
.mnRow2
;
799 return aData
.mbValue
;
802 bool ScTable::ColFiltered(SCCOL nCol
, SCCOL
* pFirstCol
, SCCOL
* pLastCol
) const
807 ScFlatBoolColSegments::RangeData aData
;
808 if (!mpFilteredCols
->getRangeData(nCol
, aData
))
813 *pFirstCol
= aData
.mnCol1
;
815 *pLastCol
= aData
.mnCol2
;
817 return aData
.mbValue
;
820 bool ScTable::HasFilteredRows(SCROW nStartRow
, SCROW nEndRow
) const
822 SCROW nRow
= nStartRow
;
823 while (nRow
<= nEndRow
)
825 SCROW nLastRow
= nRow
;
826 bool bFiltered
= RowFiltered(nRow
, NULL
, &nLastRow
);
835 void ScTable::CopyColFiltered(ScTable
& rTable
, SCCOL nStartCol
, SCCOL nEndCol
)
837 SCCOL nCol
= nStartCol
;
838 while (nCol
<= nEndCol
)
841 bool bFiltered
= rTable
.ColFiltered(nCol
, NULL
, &nLastCol
);
842 if (nLastCol
> nEndCol
)
845 SetColFiltered(nCol
, nLastCol
, bFiltered
);
850 void ScTable::CopyRowFiltered(ScTable
& rTable
, SCROW nStartRow
, SCROW nEndRow
)
852 SCROW nRow
= nStartRow
;
853 while (nRow
<= nEndRow
)
856 bool bFiltered
= rTable
.RowFiltered(nRow
, NULL
, &nLastRow
);
857 if (nLastRow
> nEndRow
)
859 SetRowFiltered(nRow
, nLastRow
, bFiltered
);
864 void ScTable::SetRowFiltered(SCROW nStartRow
, SCROW nEndRow
, bool bFiltered
)
867 mpFilteredRows
->setTrue(nStartRow
, nEndRow
);
869 mpFilteredRows
->setFalse(nStartRow
, nEndRow
);
872 void ScTable::SetColFiltered(SCCOL nStartCol
, SCCOL nEndCol
, bool bFiltered
)
875 mpFilteredCols
->setTrue(nStartCol
, nEndCol
);
877 mpFilteredCols
->setFalse(nStartCol
, nEndCol
);
880 SCROW
ScTable::FirstNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
) const
882 SCROW nRow
= nStartRow
;
883 ScFlatBoolRowSegments::RangeData aData
;
884 while (nRow
<= nEndRow
)
889 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
890 // failed to get range data.
894 // non-filtered row found
897 nRow
= aData
.mnRow2
+ 1;
900 return ::std::numeric_limits
<SCROW
>::max();
903 SCROW
ScTable::LastNonFilteredRow(SCROW nStartRow
, SCROW nEndRow
) const
905 SCROW nRow
= nEndRow
;
906 ScFlatBoolRowSegments::RangeData aData
;
907 while (nRow
>= nStartRow
)
912 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
913 // failed to get range data.
917 // non-filtered row found
920 nRow
= aData
.mnRow1
- 1;
923 return ::std::numeric_limits
<SCROW
>::max();
926 SCROW
ScTable::CountNonFilteredRows(SCROW nStartRow
, SCROW nEndRow
) const
929 SCROW nRow
= nStartRow
;
930 ScFlatBoolRowSegments::RangeData aData
;
931 while (nRow
<= nEndRow
)
933 if (!mpFilteredRows
->getRangeData(nRow
, aData
))
936 if (aData
.mnRow2
> nEndRow
)
937 aData
.mnRow2
= nEndRow
;
940 nCount
+= aData
.mnRow2
- nRow
+ 1;
942 nRow
= aData
.mnRow2
+ 1;
947 bool ScTable::IsManualRowHeight(SCROW nRow
) const
949 return (pRowFlags
->GetValue(nRow
) & CR_MANUALSIZE
) != 0;
954 void lcl_syncFlags(ScFlatBoolColSegments
& rColSegments
, ScFlatBoolRowSegments
& rRowSegments
,
955 sal_uInt8
* pColFlags
, ScBitMaskCompressedArray
< SCROW
, sal_uInt8
>* pRowFlags
, const sal_uInt8 nFlagMask
)
957 using ::sal::static_int_cast
;
959 sal_uInt8 nFlagMaskComplement
= static_int_cast
<sal_uInt8
>(~nFlagMask
);
961 pRowFlags
->AndValue(0, MAXROW
, nFlagMaskComplement
);
962 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
963 pColFlags
[i
] &= nFlagMaskComplement
;
969 ScFlatBoolRowSegments::RangeData aData
;
970 while (nRow
<= MAXROW
)
972 if (!rRowSegments
.getRangeData(nRow
, aData
))
976 pRowFlags
->OrValue(nRow
, aData
.mnRow2
, nFlagMask
);
978 nRow
= aData
.mnRow2
+ 1;
983 // column hidden flags.
986 ScFlatBoolColSegments::RangeData aData
;
987 while (nCol
<= MAXCOL
)
989 if (!rColSegments
.getRangeData(nCol
, aData
))
994 for (SCCOL i
= nCol
; i
<= aData
.mnCol2
; ++i
)
995 pColFlags
[i
] |= nFlagMask
;
998 nCol
= aData
.mnCol2
+ 1;
1005 void ScTable::SyncColRowFlags()
1007 using ::sal::static_int_cast
;
1009 sal_uInt8 nManualBreakComplement
= static_int_cast
<sal_uInt8
>(~CR_MANUALBREAK
);
1012 pRowFlags
->AndValue(0, MAXROW
, nManualBreakComplement
);
1013 for (SCCOL i
= 0; i
<= MAXCOL
; ++i
)
1014 pColFlags
[i
] &= nManualBreakComplement
;
1016 if (!maRowManualBreaks
.empty())
1018 for (set
<SCROW
>::const_iterator itr
= maRowManualBreaks
.begin(), itrEnd
= maRowManualBreaks
.end();
1019 itr
!= itrEnd
; ++itr
)
1020 pRowFlags
->OrValue(*itr
, CR_MANUALBREAK
);
1023 if (!maColManualBreaks
.empty())
1025 for (set
<SCCOL
>::const_iterator itr
= maColManualBreaks
.begin(), itrEnd
= maColManualBreaks
.end();
1026 itr
!= itrEnd
; ++itr
)
1027 pColFlags
[*itr
] |= CR_MANUALBREAK
;
1031 lcl_syncFlags(*mpHiddenCols
, *mpHiddenRows
, pColFlags
, pRowFlags
, CR_HIDDEN
);
1032 lcl_syncFlags(*mpFilteredCols
, *mpFilteredRows
, pColFlags
, pRowFlags
, CR_FILTERED
);
1035 void ScTable::SetPageSize( const Size
& rSize
)
1037 if ( rSize
.Width() != 0 && rSize
.Height() != 0 )
1039 if (aPageSizeTwips
!= rSize
)
1040 InvalidatePageBreaks();
1042 bPageSizeValid
= true;
1043 aPageSizeTwips
= rSize
;
1046 bPageSizeValid
= false;
1049 bool ScTable::IsProtected() const
1051 return pTabProtection
.get() && pTabProtection
->isProtected();
1054 void ScTable::SetProtection(const ScTableProtection
* pProtect
)
1057 pTabProtection
.reset(new ScTableProtection(*pProtect
));
1059 pTabProtection
.reset();
1061 if (IsStreamValid())
1062 SetStreamValid(false);
1065 ScTableProtection
* ScTable::GetProtection()
1067 return pTabProtection
.get();
1070 Size
ScTable::GetPageSize() const
1072 if ( bPageSizeValid
)
1073 return aPageSizeTwips
;
1075 return Size(); // blank
1078 void ScTable::SetRepeatArea( SCCOL nStartCol
, SCCOL nEndCol
, SCROW nStartRow
, SCROW nEndRow
)
1080 // #i117952# page break calculation uses these values (set from ScPrintFunc), not pRepeatColRange/pRepeatRowRange
1081 if ( nStartCol
!= nRepeatStartX
|| nEndCol
!= nRepeatEndX
|| nStartRow
!= nRepeatStartY
|| nEndRow
!= nRepeatEndY
)
1082 InvalidatePageBreaks();
1084 nRepeatStartX
= nStartCol
;
1085 nRepeatEndX
= nEndCol
;
1086 nRepeatStartY
= nStartRow
;
1087 nRepeatEndY
= nEndRow
;
1090 void ScTable::StartListening( const ScAddress
& rAddress
, SvtListener
* pListener
)
1092 if (!ValidCol(rAddress
.Col()))
1095 aCol
[rAddress
.Col()].StartListening( *pListener
, rAddress
.Row() );
1098 void ScTable::EndListening( const ScAddress
& rAddress
, SvtListener
* pListener
)
1100 if (!ValidCol(rAddress
.Col()))
1103 aCol
[rAddress
.Col()].EndListening( *pListener
, rAddress
.Row() );
1106 void ScTable::StartListening( sc::StartListeningContext
& rCxt
, SCCOL nCol
, SCROW nRow
, SvtListener
& rListener
)
1108 if (!ValidCol(nCol
))
1111 aCol
[nCol
].StartListening(rCxt
, nRow
, rListener
);
1114 void ScTable::EndListening( sc::EndListeningContext
& rCxt
, SCCOL nCol
, SCROW nRow
, SvtListener
& rListener
)
1116 if (!ValidCol(nCol
))
1119 aCol
[nCol
].EndListening(rCxt
, nRow
, rListener
);
1122 void ScTable::SetPageStyle( const OUString
& rName
)
1124 if ( aPageStyle
!= rName
)
1126 OUString aStrNew
= rName
;
1127 SfxStyleSheetBasePool
* pStylePool
= pDocument
->GetStyleSheetPool();
1128 SfxStyleSheetBase
* pNewStyle
= pStylePool
->Find( aStrNew
, SFX_STYLE_FAMILY_PAGE
);
1132 aStrNew
= ScGlobal::GetRscString(STR_STYLENAME_STANDARD
);
1133 pNewStyle
= pStylePool
->Find( aStrNew
, SFX_STYLE_FAMILY_PAGE
);
1136 if ( aPageStyle
!= aStrNew
)
1138 SfxStyleSheetBase
* pOldStyle
= pStylePool
->Find( aPageStyle
, SFX_STYLE_FAMILY_PAGE
);
1140 if ( pOldStyle
&& pNewStyle
)
1142 SfxItemSet
& rOldSet
= pOldStyle
->GetItemSet();
1143 SfxItemSet
& rNewSet
= pNewStyle
->GetItemSet();
1144 const sal_uInt16 nOldScale
= GET_SCALEVALUE(rOldSet
,ATTR_PAGE_SCALE
);
1145 const sal_uInt16 nOldScaleToPages
= GET_SCALEVALUE(rOldSet
,ATTR_PAGE_SCALETOPAGES
);
1146 const sal_uInt16 nNewScale
= GET_SCALEVALUE(rNewSet
,ATTR_PAGE_SCALE
);
1147 const sal_uInt16 nNewScaleToPages
= GET_SCALEVALUE(rNewSet
,ATTR_PAGE_SCALETOPAGES
);
1149 if ( (nOldScale
!= nNewScale
) || (nOldScaleToPages
!= nNewScaleToPages
) )
1150 InvalidateTextWidth(NULL
, NULL
, false, false);
1153 if ( pNewStyle
) // also without the old one (for UpdateStdNames)
1154 aPageStyle
= aStrNew
;
1156 if (IsStreamValid())
1157 SetStreamValid(false);
1162 void ScTable::PageStyleModified( const OUString
& rNewName
)
1164 aPageStyle
= rNewName
;
1165 InvalidateTextWidth(NULL
, NULL
, false, false); // don't know what was in the style before
1168 void ScTable::InvalidateTextWidth( const ScAddress
* pAdrFrom
, const ScAddress
* pAdrTo
,
1169 bool bNumFormatChanged
, bool bBroadcast
)
1171 if ( pAdrFrom
&& !pAdrTo
)
1173 // Special case: only process the "from" cell.
1174 SCCOL nCol
= pAdrFrom
->Col();
1175 SCROW nRow
= pAdrFrom
->Row();
1176 ScColumn
& rCol
= aCol
[nCol
];
1177 ScRefCellValue aCell
= rCol
.GetCellValue(nRow
);
1178 if (aCell
.isEmpty())
1181 rCol
.SetTextWidth(nRow
, TEXTWIDTH_DIRTY
);
1183 if ( bNumFormatChanged
)
1184 rCol
.SetScriptType(nRow
, SvtScriptType::UNKNOWN
);
1187 { // Only with CalcAsShown
1188 switch (aCell
.meType
)
1190 case CELLTYPE_VALUE
:
1191 rCol
.Broadcast(nRow
);
1193 case CELLTYPE_FORMULA
:
1194 aCell
.mpFormula
->SetDirty();
1198 // added to avoid warnings
1206 const SCCOL nCol1
= pAdrFrom
? pAdrFrom
->Col() : 0;
1207 const SCROW nRow1
= pAdrFrom
? pAdrFrom
->Row() : 0;
1208 const SCCOL nCol2
= pAdrTo
? pAdrTo
->Col() : MAXCOL
;
1209 const SCROW nRow2
= pAdrTo
? pAdrTo
->Row() : MAXROW
;
1211 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
1213 ScColumnTextWidthIterator
aIter(aCol
[nCol
], nRow1
, nRow2
);
1215 for (; aIter
.hasCell(); aIter
.next())
1217 SCROW nRow
= aIter
.getPos();
1218 aIter
.setValue(TEXTWIDTH_DIRTY
);
1219 ScRefCellValue aCell
= aCol
[nCol
].GetCellValue(nRow
);
1220 if (aCell
.isEmpty())
1223 if ( bNumFormatChanged
)
1224 aCol
[nCol
].SetScriptType(nRow
, SvtScriptType::UNKNOWN
);
1227 { // Only with CalcAsShown
1228 switch (aCell
.meType
)
1230 case CELLTYPE_VALUE
:
1231 aCol
[nCol
].Broadcast(nRow
);
1233 case CELLTYPE_FORMULA
:
1234 aCell
.mpFormula
->SetDirty();
1238 // added to avoid warnings
1246 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */