update ooo310-m15
[ooovba.git] / sc / source / core / data / table5.cxx
blobbc647e73d99c18fe6e296bf365c223751fa7c621
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: table5.cxx,v $
10 * $Revision: 1.14 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include "scitems.hxx"
37 #include "collect.hxx"
38 #include "attrib.hxx"
39 #include "patattr.hxx"
40 #include "docpool.hxx"
41 #include "cell.hxx"
42 #include "table.hxx"
43 #include "column.hxx"
44 #include "document.hxx"
45 #include "drwlayer.hxx"
46 #include "olinetab.hxx"
47 #include "userlist.hxx"
48 #include "stlsheet.hxx"
49 #include "global.hxx"
50 #include "rechead.hxx"
51 #include "stlpool.hxx"
52 #include "stlsheet.hxx"
53 #include "brdcst.hxx"
54 #include "tabprotection.hxx"
55 #include "globstr.hrc"
56 #include "segmenttree.hxx"
57 #include <com/sun/star/sheet/TablePageBreakData.hpp>
59 #include <algorithm>
60 #include <limits>
62 using ::com::sun::star::uno::Sequence;
63 using ::com::sun::star::sheet::TablePageBreakData;
64 using ::std::set;
66 // STATIC DATA -----------------------------------------------------------
68 #define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
71 void ScTable::UpdatePageBreaks( const ScRange* pUserArea )
73 if ( pDocument->IsImportingXML() )
74 return;
75 if ( !pUserArea && !bPageSizeValid )
76 return;
78 if (mbPageBreaksValid)
79 return;
81 SfxStyleSheetBase* pStyle = pDocument->GetStyleSheetPool()->
82 Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
83 if ( !pStyle )
85 DBG_ERROR("UpdatePageBreaks: Style nicht gefunden");
86 return;
88 SfxItemSet* pStyleSet = &pStyle->GetItemSet();
89 const SfxPoolItem* pItem;
91 SCCOL nX;
92 SCCOL nStartCol = 0;
93 SCROW nStartRow = 0;
94 SCCOL nEndCol = MAXCOL;
95 SCROW nEndRow = MAXROW;
96 if (pUserArea)
98 nStartCol = pUserArea->aStart.Col();
99 nStartRow = pUserArea->aStart.Row();
100 nEndCol = pUserArea->aEnd.Col();
101 nEndRow = pUserArea->aEnd.Row();
103 else
105 USHORT nAreaCount = GetPrintRangeCount();
106 if ( nAreaCount > 1 )
108 // bei mehreren Bereichen nichts anzeigen:
110 for (nX=0; nX<MAXCOL; nX++)
111 RemoveColBreak(nX, true, false);
113 RemoveRowPageBreaks(0, MAXROW-1);
115 return;
117 else if ( nAreaCount == 1 )
119 const ScRange* pArea = GetPrintRange( 0 );
120 if (pArea)
122 nStartCol = pArea->aStart.Col();
123 nStartRow = pArea->aStart.Row();
124 nEndCol = pArea->aEnd.Col();
125 nEndRow = pArea->aEnd.Row();
127 } // sonst alles
130 // bSkipBreaks holen:
132 BOOL bSkipBreaks = FALSE;
134 if ( pStyleSet->GetItemState( ATTR_PAGE_SCALETOPAGES, FALSE, &pItem ) == SFX_ITEM_SET )
136 DBG_ASSERT( pItem->ISA(SfxUInt16Item), "falsches Item" );
137 bSkipBreaks = ( ((const SfxUInt16Item*)pItem)->GetValue() > 0 );
140 if (!bSkipBreaks && pStyleSet->GetItemState(ATTR_PAGE_SCALETO, false, &pItem) == SFX_ITEM_SET)
142 const ScPageScaleToItem& rScaleToItem = static_cast<const ScPageScaleToItem&>(
143 pStyleSet->Get(ATTR_PAGE_SCALETO));
144 if (rScaleToItem.GetWidth() > 0 || rScaleToItem.GetHeight() > 0)
145 // when fitting to a fixed width x height, ignore manual breaks.
146 bSkipBreaks = true;
149 //--------------------------------------------------------------------------
151 long nPageSizeX = aPageSizeTwips.Width();
152 long nPageSizeY = aPageSizeTwips.Height();
154 // Anfang: Breaks loeschen
156 for (nX=0; nX<nStartCol; nX++)
157 RemoveColBreak(nX, true, false);
158 RemoveRowPageBreaks(0, nStartRow-1);
160 if (nStartCol > 0)
161 SetColBreak(nStartCol, true, false); // AREABREAK
162 if (nStartRow > 0)
163 SetRowBreak(nStartRow, true, false); // AREABREAK
165 // Mittelteil: Breaks verteilen
167 BOOL bRepeatCol = ( nRepeatStartX != SCCOL_REPEAT_NONE );
168 BOOL bColFound = FALSE;
169 long nSizeX = 0;
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 && !bSkipBreaks) )
177 SetColBreak(nX, true, false);
178 nSizeX = 0;
179 bStartOfPage = TRUE;
181 else if (nX != nStartCol)
182 RemoveColBreak(nX, true, false);
183 else
184 bStartOfPage = TRUE;
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);
193 bColFound = TRUE;
196 nSizeX += nThisX;
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;
205 long nSizeY = 0;
206 for (SCROW nY = nStartRow; nY <= nEndRow; ++nY)
208 BOOL bStartOfPage = FALSE;
209 long nThisY = RowHidden(nY) ? 0 : pRowHeight->GetValue(nY);
210 bool bManualBreak = HasRowManualBreak(nY);
211 if ( (nSizeY+nThisY > nPageSizeY) || (bManualBreak && !bSkipBreaks) )
213 SetRowBreak(nY, true, false);
214 nSizeY = 0;
215 bStartOfPage = TRUE;
217 else if (nY != nStartRow)
218 ; // page break already removed
219 else
220 bStartOfPage = TRUE;
222 if ( bStartOfPage && bRepeatRow && nY>nRepeatStartY && !bRowFound )
224 // subtract size of repeat rows from page size
225 unsigned long nHeights = GetTotalRowHeight(nRepeatStartY, nRepeatEndY);
226 #ifdef DBG_UTIL
227 if (nHeights == ::std::numeric_limits<unsigned long>::max())
228 DBG_ERRORFILE("ScTable::UpdatePageBreaks: row heights overflow");
229 #endif
230 nPageSizeY -= nHeights;
231 if (nY <= nRepeatEndY)
232 RemoveRowPageBreaks(nY, nRepeatEndY);
233 bRowFound = TRUE;
236 nSizeY += nThisY;
239 // Ende: Breaks loeschen
241 if (nEndCol < MAXCOL)
243 SetColBreak(nEndCol+1, true, false); // AREABREAK
244 for (nX=nEndCol+2; nX<=MAXCOL; nX++)
245 RemoveColBreak(nX, true, false);
247 if (nEndRow < MAXROW)
249 SetRowBreak(nEndRow+1, true, false); // AREABREAK
250 if (nEndRow+2 <= MAXROW)
251 RemoveRowPageBreaks(nEndRow+2, MAXROW);
253 mbPageBreaksValid = true;
256 void ScTable::RemoveManualBreaks()
258 maRowManualBreaks.clear();
259 maColManualBreaks.clear();
260 InvalidatePageBreaks();
263 BOOL ScTable::HasManualBreaks() const
265 return !maRowManualBreaks.empty() || !maColManualBreaks.empty();
268 void ScTable::GetAllRowBreaks(set<SCROW>& rBreaks, bool bPage, bool bManual) const
270 if (bPage)
271 rBreaks = maRowPageBreaks;
273 if (bManual)
275 using namespace std;
276 copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
280 void ScTable::GetAllColBreaks(set<SCCOL>& rBreaks, bool bPage, bool bManual) const
282 if (bPage)
283 rBreaks = maColPageBreaks;
285 if (bManual)
287 using namespace std;
288 copy(maColManualBreaks.begin(), maColManualBreaks.end(), inserter(rBreaks, rBreaks.begin()));
292 bool ScTable::HasRowPageBreak(SCROW nRow) const
294 if (!ValidRow(nRow))
295 return false;
297 return maRowPageBreaks.count(nRow) > 0;
300 bool ScTable::HasColPageBreak(SCCOL nCol) const
302 if (!ValidCol(nCol))
303 return false;
305 return maColPageBreaks.count(nCol) > 0;
308 bool ScTable::HasRowManualBreak(SCROW nRow) const
310 if (!ValidRow(nRow))
311 return false;
313 return maRowManualBreaks.count(nRow) > 0;
316 bool ScTable::HasColManualBreak(SCCOL nCol) const
318 if (!ValidCol(nCol))
319 return false;
321 return (maColManualBreaks.count(nCol) > 0);
324 void ScTable::RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow)
326 using namespace std;
328 if (!ValidRow(nStartRow) || !ValidRow(nEndRow))
329 return;
331 set<SCROW>::iterator low = maRowPageBreaks.lower_bound(nStartRow);
332 set<SCROW>::iterator high = maRowPageBreaks.upper_bound(nEndRow);
333 maRowPageBreaks.erase(low, high);
336 void ScTable::RemoveRowBreak(SCROW nRow, bool bPage, bool bManual)
338 if (!ValidRow(nRow))
339 return;
341 if (bPage)
342 maRowPageBreaks.erase(nRow);
344 if (bManual)
346 maRowManualBreaks.erase(nRow);
347 InvalidatePageBreaks();
351 void ScTable::RemoveColBreak(SCCOL nCol, bool bPage, bool bManual)
353 if (!ValidCol(nCol))
354 return;
356 if (bPage)
357 maColPageBreaks.erase(nCol);
359 if (bManual)
361 maColManualBreaks.erase(nCol);
362 InvalidatePageBreaks();
366 void ScTable::SetRowBreak(SCROW nRow, bool bPage, bool bManual)
368 if (!ValidRow(nRow))
369 return;
371 if (bPage)
372 maRowPageBreaks.insert(nRow);
374 if (bManual)
376 maRowManualBreaks.insert(nRow);
377 InvalidatePageBreaks();
381 void ScTable::SetColBreak(SCCOL nCol, bool bPage, bool bManual)
383 if (!ValidCol(nCol))
384 return;
386 if (bPage)
387 maColPageBreaks.insert(nCol);
389 if (bManual)
391 maColManualBreaks.insert(nCol);
392 InvalidatePageBreaks();
396 Sequence<TablePageBreakData> ScTable::GetRowBreakData() const
398 using ::std::copy;
399 using ::std::inserter;
401 set<SCROW> aRowBreaks = maRowPageBreaks;
402 copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(aRowBreaks, aRowBreaks.begin()));
404 set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end();
405 Sequence<TablePageBreakData> aSeq(aRowBreaks.size());
407 for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i)
409 SCROW nRow = *itr;
410 TablePageBreakData aData;
411 aData.Position = nRow;
412 aData.ManualBreak = HasRowManualBreak(nRow);
413 aSeq[i] = aData;
416 return aSeq;
419 bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
421 if (!ValidRow(nRow))
422 return true;
424 ScFlatBoolRowSegments::RangeData aData;
425 if (!mpHiddenRows->getRangeData(nRow, aData))
426 // search failed.
427 return true;
429 if (pFirstRow)
430 *pFirstRow = aData.mnRow1;
431 if (pLastRow)
432 *pLastRow = aData.mnRow2;
434 return aData.mbValue;
438 bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow)
440 rLastRow = nRow;
441 if (!ValidRow(nRow))
442 return true;
444 ScFlatBoolRowSegments::RangeData aData;
445 if (!mpHiddenRows->getRangeData(nRow, aData))
446 // search failed.
447 return true;
449 rLastRow = aData.mnRow2;
450 return aData.mbValue;
453 bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow)
455 SCROW nRow = nStartRow;
456 while (nRow <= nEndRow)
458 SCROW nLastRow = -1;
459 bool bHidden = RowHidden(nRow, nLastRow);
460 if (bHidden)
461 return true;
463 nRow = nLastRow + 1;
465 return false;
468 bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol)
470 rLastCol = nCol;
471 if (!ValidCol(nCol))
472 return true;
474 ScFlatBoolColSegments::RangeData aData;
475 if (!mpHiddenCols->getRangeData(nCol, aData))
476 return true;
478 rLastCol = aData.mnCol2;
479 return aData.mbValue;
482 bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
484 if (!ValidCol(nCol))
485 return true;
487 ScFlatBoolColSegments::RangeData aData;
488 if (!mpHiddenCols->getRangeData(nCol, aData))
489 return true;
491 if (pFirstCol)
492 *pFirstCol = aData.mnCol1;
493 if (pLastCol)
494 *pLastCol = aData.mnCol2;
496 return aData.mbValue;
499 void ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden)
501 if (bHidden)
502 mpHiddenRows->setTrue(nStartRow, nEndRow);
503 else
504 mpHiddenRows->setFalse(nStartRow, nEndRow);
506 #if 0
507 // Remove this once the refactoring is complete.
508 if (bHidden)
509 pRowFlags->OrValue(nStartRow, nEndRow, CR_HIDDEN);
510 else
511 pRowFlags->AndValue(nStartRow, nEndRow, ~CR_HIDDEN);
512 #endif
515 void ScTable::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden)
517 if (bHidden)
518 mpHiddenCols->setTrue(nStartCol, nEndCol);
519 else
520 mpHiddenCols->setFalse(nStartCol, nEndCol);
521 #if 0
522 for (SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol)
524 if (bHidden)
525 pColFlags[nCol] |= CR_HIDDEN;
526 else
527 pColFlags[nCol] &= ~CR_HIDDEN;
529 #endif
532 void ScTable::CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol)
534 SCCOL nCol = nStartCol;
535 while (nCol <= nEndCol)
537 SCCOL nLastCol;
538 bool bHidden = rTable.ColHidden(nCol, NULL, &nLastCol);
539 if (nLastCol > nEndCol)
540 nLastCol = nEndCol;
542 SetColHidden(nCol, nLastCol, bHidden);
543 nCol = nLastCol + 1;
547 void ScTable::CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow)
549 SCROW nRow = nStartRow;
550 while (nRow <= nEndRow)
552 SCROW nLastRow = -1;
553 bool bHidden = rTable.RowHidden(nRow, nLastRow);
554 if (nLastRow > nEndRow)
555 nLastRow = nEndRow;
556 SetRowHidden(nRow, nLastRow, bHidden);
557 nRow = nLastRow + 1;
561 SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow)
563 SCROW nRow = nStartRow;
564 ScFlatBoolRowSegments::RangeData aData;
565 while (nRow <= nEndRow)
567 if (!ValidRow(nRow))
568 break;
570 if (!mpHiddenRows->getRangeData(nRow, aData))
571 // failed to get range data.
572 break;
574 if (!aData.mbValue)
575 // visible row found
576 return nRow;
578 nRow = aData.mnRow2 + 1;
581 return ::std::numeric_limits<SCROW>::max();
584 SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow)
586 SCROW nRow = nEndRow;
587 ScFlatBoolRowSegments::RangeData aData;
588 while (nRow >= nStartRow)
590 if (!ValidRow(nRow))
591 break;
593 if (!mpHiddenRows->getRangeData(nRow, aData))
594 // failed to get range data.
595 break;
597 if (!aData.mbValue)
598 // visible row found
599 return nRow;
601 nRow = aData.mnRow1 - 1;
604 return ::std::numeric_limits<SCROW>::max();
607 SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow)
609 SCROW nCount = 0;
610 SCROW nRow = nStartRow;
611 ScFlatBoolRowSegments::RangeData aData;
612 while (nRow <= nEndRow)
614 if (!mpHiddenRows->getRangeData(nRow, aData))
615 break;
617 if (aData.mnRow2 > nEndRow)
618 aData.mnRow2 = nEndRow;
620 if (!aData.mbValue)
621 nCount += aData.mnRow2 - nRow + 1;
623 nRow = aData.mnRow2 + 1;
625 return nCount;
628 sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow)
630 sal_uInt32 nHeight = 0;
631 SCROW nRow = nStartRow;
632 ScFlatBoolRowSegments::RangeData aData;
633 while (nRow <= nEndRow)
635 if (!mpHiddenRows->getRangeData(nRow, aData))
636 break;
638 if (aData.mnRow2 > nEndRow)
639 aData.mnRow2 = nEndRow;
641 if (!aData.mbValue)
642 // visible row range.
643 nHeight += pRowHeight->SumValues(nRow, aData.mnRow2);
645 nRow = aData.mnRow2 + 1;
648 return nHeight;
651 SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol)
653 if (bCol)
655 SCCOL nCol = static_cast<SCCOL>(nPos);
656 if (ColHidden(nCol))
658 for (SCCOL i = nCol+1; i <= MAXCOL; ++i)
660 if (!ColHidden(nCol))
661 return nCol - 1;
665 else
667 SCROW nRow = static_cast<SCROW>(nPos);
668 SCROW nLastRow;
669 if (RowHidden(nRow, NULL, &nLastRow))
670 return static_cast<SCCOLROW>(nLastRow);
672 return ::std::numeric_limits<SCCOLROW>::max();
675 bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow)
677 #if 1
678 if (!ValidRow(nRow))
679 return false;
681 ScFlatBoolRowSegments::RangeData aData;
682 if (!mpFilteredRows->getRangeData(nRow, aData))
683 // search failed.
684 return false;
686 if (pFirstRow)
687 *pFirstRow = aData.mnRow1;
688 if (pLastRow)
689 *pLastRow = aData.mnRow2;
691 return aData.mbValue;
692 #else
693 if (pFirstRow)
694 *pFirstRow = nRow;
695 if (pLastRow)
696 *pLastRow = nRow;
697 return (pRowFlags->GetValue(nRow) & CR_FILTERED) == CR_FILTERED;
698 #endif
701 bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol)
703 #if 1
704 if (!ValidCol(nCol))
705 return false;
707 ScFlatBoolColSegments::RangeData aData;
708 if (!mpFilteredCols->getRangeData(nCol, aData))
709 // search failed.
710 return false;
712 if (pFirstCol)
713 *pFirstCol = aData.mnCol1;
714 if (pLastCol)
715 *pLastCol = aData.mnCol2;
717 return aData.mbValue;
718 #else
719 if (pFirstCol)
720 *pFirstCol = nCol;
721 if (pLastCol)
722 *pLastCol = nCol;
723 return (pColFlags[nCol] & CR_FILTERED) == CR_FILTERED;
724 #endif
727 bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow)
729 SCROW nRow = nStartRow;
730 while (nRow <= nEndRow)
732 SCROW nLastRow = nRow;
733 bool bFiltered = RowFiltered(nRow, NULL, &nLastRow);
734 if (bFiltered)
735 return true;
737 nRow = nLastRow + 1;
739 return false;
742 void ScTable::CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol)
744 SCCOL nCol = nStartCol;
745 while (nCol <= nEndCol)
747 SCCOL nLastCol;
748 bool bFiltered = rTable.ColFiltered(nCol, NULL, &nLastCol);
749 if (nLastCol > nEndCol)
750 nLastCol = nEndCol;
752 SetColFiltered(nCol, nLastCol, bFiltered);
753 nCol = nLastCol + 1;
757 void ScTable::CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow)
759 SCROW nRow = nStartRow;
760 while (nRow <= nEndRow)
762 SCROW nLastRow = -1;
763 bool bFiltered = rTable.RowFiltered(nRow, NULL, &nLastRow);
764 if (nLastRow > nEndRow)
765 nLastRow = nEndRow;
766 SetRowFiltered(nRow, nLastRow, bFiltered);
767 nRow = nLastRow + 1;
771 void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered)
773 if (bFiltered)
774 mpFilteredRows->setTrue(nStartRow, nEndRow);
775 else
776 mpFilteredRows->setFalse(nStartRow, nEndRow);
778 #if 0
779 // Remove this once the refactoring is complete.
780 if (bFiltered)
781 pRowFlags->OrValue(nStartRow, nEndRow, CR_FILTERED);
782 else
783 pRowFlags->AndValue(nStartRow, nEndRow, ~CR_FILTERED);
784 #endif
787 void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered)
789 if (bFiltered)
790 mpFilteredCols->setTrue(nStartCol, nEndCol);
791 else
792 mpFilteredCols->setFalse(nStartCol, nEndCol);
794 #if 0
795 // Remove this once the refactoring is complete.
796 for (SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol)
798 if (bFiltered)
799 pColFlags[nCol] |= CR_FILTERED;
800 else
801 pColFlags[nCol] &= ~CR_FILTERED;
803 #endif
806 SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
808 SCROW nRow = nStartRow;
809 ScFlatBoolRowSegments::RangeData aData;
810 while (nRow <= nEndRow)
812 if (!ValidRow(nRow))
813 break;
815 if (!mpFilteredRows->getRangeData(nRow, aData))
816 // failed to get range data.
817 break;
819 if (!aData.mbValue)
820 // non-filtered row found
821 return nRow;
823 nRow = aData.mnRow2 + 1;
826 return ::std::numeric_limits<SCROW>::max();
829 SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow)
831 SCROW nRow = nEndRow;
832 ScFlatBoolRowSegments::RangeData aData;
833 while (nRow >= nStartRow)
835 if (!ValidRow(nRow))
836 break;
838 if (!mpFilteredRows->getRangeData(nRow, aData))
839 // failed to get range data.
840 break;
842 if (!aData.mbValue)
843 // non-filtered row found
844 return nRow;
846 nRow = aData.mnRow1 - 1;
849 return ::std::numeric_limits<SCROW>::max();
852 SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow)
854 SCROW nCount = 0;
855 SCROW nRow = nStartRow;
856 ScFlatBoolRowSegments::RangeData aData;
857 while (nRow <= nEndRow)
859 if (!mpFilteredRows->getRangeData(nRow, aData))
860 break;
862 if (aData.mnRow2 > nEndRow)
863 aData.mnRow2 = nEndRow;
865 if (!aData.mbValue)
866 nCount += aData.mnRow2 - nRow + 1;
868 nRow = aData.mnRow2 + 1;
870 return nCount;
873 namespace {
875 void lcl_syncFlags(ScFlatBoolColSegments& rColSegments, ScFlatBoolRowSegments& rRowSegments,
876 BYTE* pColFlags, ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, const BYTE nFlagMask)
878 using ::sal::static_int_cast;
880 pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~nFlagMask));
881 for (SCCOL i = 0; i <= MAXCOL; ++i)
882 pColFlags[i] &= static_int_cast<BYTE>(~nFlagMask);
885 // row hidden flags.
887 SCROW nRow = 0;
888 ScFlatBoolRowSegments::RangeData aData;
889 while (nRow <= MAXROW)
891 if (!rRowSegments.getRangeData(nRow, aData))
892 break;
894 if (aData.mbValue)
895 pRowFlags->OrValue(nRow, aData.mnRow2, static_int_cast<BYTE>(nFlagMask));
897 nRow = aData.mnRow2 + 1;
902 // column hidden flags.
904 SCCOL nCol = 0;
905 ScFlatBoolColSegments::RangeData aData;
906 while (nCol <= MAXCOL)
908 if (!rColSegments.getRangeData(nCol, aData))
909 break;
911 if (aData.mbValue)
913 for (SCCOL i = nCol; i <= aData.mnCol2; ++i)
914 pColFlags[i] |= nFlagMask;
917 nCol = aData.mnCol2 + 1;
924 void ScTable::SyncColRowFlags()
926 using ::sal::static_int_cast;
928 // Manual breaks.
929 pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_MANUALBREAK));
930 for (SCCOL i = 0; i <= MAXCOL; ++i)
931 pColFlags[i] &= static_int_cast<BYTE>(~CR_MANUALBREAK);
933 if (!maRowManualBreaks.empty())
935 for (set<SCROW>::const_iterator itr = maRowManualBreaks.begin(), itrEnd = maRowManualBreaks.end();
936 itr != itrEnd; ++itr)
937 pRowFlags->OrValue(*itr, static_int_cast<BYTE>(CR_MANUALBREAK));
940 if (!maColManualBreaks.empty())
942 for (set<SCCOL>::const_iterator itr = maColManualBreaks.begin(), itrEnd = maColManualBreaks.end();
943 itr != itrEnd; ++itr)
944 pColFlags[*itr] |= CR_MANUALBREAK;
947 // Hidden flags.
948 lcl_syncFlags(*mpHiddenCols, *mpHiddenRows, pColFlags, pRowFlags, CR_HIDDEN);
949 lcl_syncFlags(*mpFilteredCols, *mpFilteredRows, pColFlags, pRowFlags, CR_FILTERED);
952 void ScTable::SetPageSize( const Size& rSize )
954 if ( rSize.Width() != 0 && rSize.Height() != 0 )
956 if (aPageSizeTwips != rSize)
957 InvalidatePageBreaks();
959 bPageSizeValid = TRUE;
960 aPageSizeTwips = rSize;
962 else
963 bPageSizeValid = FALSE;
966 BOOL ScTable::IsProtected() const
968 return pTabProtection.get() && pTabProtection->isProtected();
971 void ScTable::SetProtection(const ScTableProtection* pProtect)
973 if (pProtect)
974 pTabProtection.reset(new ScTableProtection(*pProtect));
975 else
976 pTabProtection.reset(NULL);
979 ScTableProtection* ScTable::GetProtection()
981 return pTabProtection.get();
984 Size ScTable::GetPageSize() const
986 if ( bPageSizeValid )
987 return aPageSizeTwips;
988 else
989 return Size(); // leer
992 void ScTable::SetRepeatArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow )
994 nRepeatStartX = nStartCol;
995 nRepeatEndX = nEndCol;
996 nRepeatStartY = nStartRow;
997 nRepeatEndY = nEndRow;
1000 void ScTable::StartListening( const ScAddress& rAddress, SvtListener* pListener )
1002 aCol[rAddress.Col()].StartListening( *pListener, rAddress.Row() );
1005 void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener )
1007 aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() );
1010 void ScTable::SetPageStyle( const String& rName )
1012 if ( aPageStyle != rName )
1014 String aStrNew = rName;
1015 SfxStyleSheetBasePool* pStylePool = pDocument->GetStyleSheetPool();
1016 SfxStyleSheetBase* pNewStyle = pStylePool->Find( aStrNew, SFX_STYLE_FAMILY_PAGE );
1018 if ( !pNewStyle )
1020 aStrNew = ScGlobal::GetRscString(STR_STYLENAME_STANDARD);
1021 pNewStyle = pStylePool->Find( aStrNew, SFX_STYLE_FAMILY_PAGE );
1024 if ( aPageStyle != aStrNew )
1026 SfxStyleSheetBase* pOldStyle = pStylePool->Find( aPageStyle, SFX_STYLE_FAMILY_PAGE );
1028 if ( pOldStyle && pNewStyle )
1030 SfxItemSet& rOldSet = pOldStyle->GetItemSet();
1031 SfxItemSet& rNewSet = pNewStyle->GetItemSet();
1032 const USHORT nOldScale = GET_SCALEVALUE(rOldSet,ATTR_PAGE_SCALE);
1033 const USHORT nOldScaleToPages = GET_SCALEVALUE(rOldSet,ATTR_PAGE_SCALETOPAGES);
1034 const USHORT nNewScale = GET_SCALEVALUE(rNewSet,ATTR_PAGE_SCALE);
1035 const USHORT nNewScaleToPages = GET_SCALEVALUE(rNewSet,ATTR_PAGE_SCALETOPAGES);
1037 if ( (nOldScale != nNewScale) || (nOldScaleToPages != nNewScaleToPages) )
1038 InvalidateTextWidth(NULL, NULL, FALSE, FALSE);
1041 if ( pNewStyle ) // auch ohne den alten (fuer UpdateStdNames)
1042 aPageStyle = aStrNew;
1047 void ScTable::PageStyleModified( const String& rNewName )
1049 aPageStyle = rNewName;
1050 InvalidateTextWidth(NULL, NULL, FALSE, FALSE); // don't know what was in the style before
1053 void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
1054 BOOL bNumFormatChanged, BOOL bBroadcast )
1056 if ( pAdrFrom && !pAdrTo )
1058 ScBaseCell* pCell = aCol[pAdrFrom->Col()].GetCell( pAdrFrom->Row() );
1059 if ( pCell )
1061 pCell->SetTextWidth( TEXTWIDTH_DIRTY );
1062 if ( bNumFormatChanged )
1063 pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
1064 if ( bBroadcast )
1065 { // nur bei CalcAsShown
1066 switch ( pCell->GetCellType() )
1068 case CELLTYPE_VALUE :
1069 pDocument->Broadcast( SC_HINT_DATACHANGED,
1070 ScAddress( pAdrFrom->Col(), pAdrFrom->Row(), nTab ),
1071 pCell );
1072 break;
1073 case CELLTYPE_FORMULA :
1074 ((ScFormulaCell*)pCell)->SetDirty();
1075 break;
1076 default:
1078 // added to avoid warnings
1084 else
1086 const SCCOL nColStart = pAdrFrom ? pAdrFrom->Col() : 0;
1087 const SCROW nRowStart = pAdrFrom ? pAdrFrom->Row() : 0;
1088 const SCCOL nColEnd = pAdrTo ? pAdrTo->Col() : MAXCOL;
1089 const SCROW nRowEnd = pAdrTo ? pAdrTo->Row() : MAXROW;
1091 for ( SCCOL nCol=nColStart; nCol<=nColEnd; nCol++ )
1093 ScColumnIterator aIter( &aCol[nCol], nRowStart, nRowEnd );
1094 ScBaseCell* pCell = NULL;
1095 SCROW nRow = nRowStart;
1097 while ( aIter.Next( nRow, pCell ) )
1099 pCell->SetTextWidth( TEXTWIDTH_DIRTY );
1100 if ( bNumFormatChanged )
1101 pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
1102 if ( bBroadcast )
1103 { // nur bei CalcAsShown
1104 switch ( pCell->GetCellType() )
1106 case CELLTYPE_VALUE :
1107 pDocument->Broadcast( SC_HINT_DATACHANGED,
1108 ScAddress( nCol, nRow, nTab ), pCell );
1109 break;
1110 case CELLTYPE_FORMULA :
1111 ((ScFormulaCell*)pCell)->SetDirty();
1112 break;
1113 default:
1115 // added to avoid warnings