/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" // INCLUDE --------------------------------------------------------------- #include "scitems.hxx" #include "collect.hxx" #include "attrib.hxx" #include "patattr.hxx" #include "docpool.hxx" #include "cell.hxx" #include "table.hxx" #include "column.hxx" #include "document.hxx" #include "drwlayer.hxx" #include "olinetab.hxx" #include "userlist.hxx" #include "stlsheet.hxx" #include "global.hxx" #include "rechead.hxx" #include "stlpool.hxx" #include "stlsheet.hxx" #include "brdcst.hxx" #include "tabprotection.hxx" #include "globstr.hrc" #include "segmenttree.hxx" #include #include #include using ::com::sun::star::uno::Sequence; using ::com::sun::star::sheet::TablePageBreakData; using ::std::set; // STATIC DATA ----------------------------------------------------------- #define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue() void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) { if ( pDocument->IsImportingXML() ) return; // pUserArea != NULL -> print area is specified. We need to force-update // the page breaks. if (!pUserArea) { if (!bPageSizeValid) return; if (mbPageBreaksValid) return; } SfxStyleSheetBase* pStyle = pDocument->GetStyleSheetPool()-> Find( aPageStyle, SFX_STYLE_FAMILY_PAGE ); if ( !pStyle ) { DBG_ERROR("UpdatePageBreaks: Style nicht gefunden"); return; } SfxItemSet* pStyleSet = &pStyle->GetItemSet(); const SfxPoolItem* pItem; SCCOL nX; SCCOL nStartCol = 0; SCROW nStartRow = 0; SCCOL nEndCol = MAXCOL; SCROW nEndRow = MAXROW; if (pUserArea) { nStartCol = pUserArea->aStart.Col(); nStartRow = pUserArea->aStart.Row(); nEndCol = pUserArea->aEnd.Col(); nEndRow = pUserArea->aEnd.Row(); } else { sal_uInt16 nAreaCount = GetPrintRangeCount(); if ( nAreaCount > 1 ) { // bei mehreren Bereichen nichts anzeigen: for (nX=0; nXaStart.Col(); nStartRow = pArea->aStart.Row(); nEndCol = pArea->aEnd.Col(); nEndRow = pArea->aEnd.Row(); } } // sonst alles } // get bSkipColBreaks/bSkipRowBreaks flags: bool bSkipColBreaks = false; bool bSkipRowBreaks = false; if ( pStyleSet->GetItemState( ATTR_PAGE_SCALETOPAGES, sal_False, &pItem ) == SFX_ITEM_SET ) { DBG_ASSERT( pItem->ISA(SfxUInt16Item), "falsches Item" ); bSkipColBreaks = bSkipRowBreaks = ( ((const SfxUInt16Item*)pItem)->GetValue() > 0 ); } if ( !bSkipColBreaks && pStyleSet->GetItemState(ATTR_PAGE_SCALETO, sal_False, &pItem) == SFX_ITEM_SET ) { // #i54993# when fitting to width or height, ignore only manual breaks in that direction const ScPageScaleToItem* pScaleToItem = static_cast(pItem); if ( pScaleToItem->GetWidth() > 0 ) bSkipColBreaks = true; if ( pScaleToItem->GetHeight() > 0 ) bSkipRowBreaks = true; } //-------------------------------------------------------------------------- long nPageSizeX = aPageSizeTwips.Width(); long nPageSizeY = aPageSizeTwips.Height(); // Anfang: Breaks loeschen for (nX=0; nX 0) SetColBreak(nStartCol, true, false); // AREABREAK if (nStartRow > 0) SetRowBreak(nStartRow, true, false); // AREABREAK // Mittelteil: Breaks verteilen sal_Bool bRepeatCol = ( nRepeatStartX != SCCOL_REPEAT_NONE ); sal_Bool bColFound = sal_False; long nSizeX = 0; for (nX=nStartCol; nX<=nEndCol; nX++) { sal_Bool bStartOfPage = sal_False; long nThisX = ColHidden(nX) ? 0 : pColWidth[nX]; bool bManualBreak = HasColManualBreak(nX); if ( (nSizeX+nThisX > nPageSizeX) || (bManualBreak && !bSkipColBreaks) ) { SetColBreak(nX, true, false); nSizeX = 0; bStartOfPage = sal_True; } else if (nX != nStartCol) RemoveColBreak(nX, true, false); else bStartOfPage = sal_True; if ( bStartOfPage && bRepeatCol && nX>nRepeatStartX && !bColFound ) { // subtract size of repeat columns from page size for (SCCOL i=nRepeatStartX; i<=nRepeatEndX; i++) nPageSizeX -= ColHidden(i) ? 0 : pColWidth[i]; while (nX<=nRepeatEndX) RemoveColBreak(++nX, true, false); bColFound = sal_True; } nSizeX += nThisX; } // Remove all page breaks in range. RemoveRowPageBreaks(nStartRow+1, nEndRow); // And set new page breaks. sal_Bool bRepeatRow = ( nRepeatStartY != SCROW_REPEAT_NONE ); sal_Bool bRowFound = sal_False; long nSizeY = 0; ScFlatBoolRowSegments::ForwardIterator aIterHidden(*mpHiddenRows); ScFlatUInt16RowSegments::ForwardIterator aIterHeights(*mpRowHeights); SCROW nNextManualBreak = GetNextManualBreak(nStartRow); // -1 => no more manual breaks for (SCROW nY = nStartRow; nY <= nEndRow; ++nY) { sal_Bool bStartOfPage = sal_False; bool bThisRowHidden = false; aIterHidden.getValue(nY, bThisRowHidden); long nThisY = 0; if (!bThisRowHidden) { sal_uInt16 nTmp; aIterHeights.getValue(nY, nTmp); nThisY = static_cast(nTmp); } bool bManualBreak = false; if (nNextManualBreak >= 0) { bManualBreak = (nY == nNextManualBreak); if (nY >= nNextManualBreak) // Query the next menual break position. nNextManualBreak = GetNextManualBreak(nY+1); } if ( (nSizeY+nThisY > nPageSizeY) || (bManualBreak && !bSkipRowBreaks) ) { SetRowBreak(nY, true, false); nSizeY = 0; bStartOfPage = sal_True; } else if (nY != nStartRow) ; // page break already removed else bStartOfPage = sal_True; if ( bStartOfPage && bRepeatRow && nY>nRepeatStartY && !bRowFound ) { // subtract size of repeat rows from page size unsigned long nHeights = GetTotalRowHeight(nRepeatStartY, nRepeatEndY); #ifdef DBG_UTIL if (nHeights == ::std::numeric_limits::max()) DBG_ERRORFILE("ScTable::UpdatePageBreaks: row heights overflow"); #endif nPageSizeY -= nHeights; if (nY <= nRepeatEndY) RemoveRowPageBreaks(nY, nRepeatEndY); bRowFound = sal_True; } if (bThisRowHidden) { // Hidden row range. Skip them unless there is a manual break. SCROW nLastCommon = aIterHidden.getLastPos(); if (nNextManualBreak >= 0) nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1); nY = nLastCommon; } else { // Visible row range. SCROW nLastHidden = aIterHidden.getLastPos(); SCROW nLastHeight = aIterHeights.getLastPos(); SCROW nLastCommon = ::std::min(nLastHidden, nLastHeight); if (nNextManualBreak >= 0) nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1); if (nLastCommon > nY) { long nMaxMultiple = static_cast(nLastCommon - nY); long nMultiple = (nPageSizeY - nSizeY) / nThisY; if (nMultiple > nMaxMultiple) nMultiple = nMaxMultiple; if (nMultiple > 1) { nSizeY += nThisY * (nMultiple - 1); nY += nMultiple - 1; } } } nSizeY += nThisY; } // Ende: Breaks loeschen if (nEndCol < MAXCOL) { SetColBreak(nEndCol+1, true, false); // AREABREAK for (nX=nEndCol+2; nX<=MAXCOL; nX++) RemoveColBreak(nX, true, false); } if (nEndRow < MAXROW) { SetRowBreak(nEndRow+1, true, false); // AREABREAK if (nEndRow+2 <= MAXROW) RemoveRowPageBreaks(nEndRow+2, MAXROW); } mbPageBreaksValid = !pUserArea; // #i116881# the valid flag can only apply to the "no user area" case } void ScTable::RemoveManualBreaks() { maRowManualBreaks.clear(); maColManualBreaks.clear(); InvalidatePageBreaks(); if (IsStreamValid()) SetStreamValid(sal_False); } sal_Bool ScTable::HasManualBreaks() const { return !maRowManualBreaks.empty() || !maColManualBreaks.empty(); } void ScTable::SetRowManualBreaks( const ::std::set& rBreaks ) { maRowManualBreaks = rBreaks; InvalidatePageBreaks(); if (IsStreamValid()) SetStreamValid(sal_False); } void ScTable::SetColManualBreaks( const ::std::set& rBreaks ) { maColManualBreaks = rBreaks; InvalidatePageBreaks(); if (IsStreamValid()) SetStreamValid(sal_False); } void ScTable::GetAllRowBreaks(set& rBreaks, bool bPage, bool bManual) const { if (bPage) rBreaks = maRowPageBreaks; if (bManual) { using namespace std; copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(rBreaks, rBreaks.begin())); } } void ScTable::GetAllColBreaks(set& rBreaks, bool bPage, bool bManual) const { if (bPage) rBreaks = maColPageBreaks; if (bManual) { using namespace std; copy(maColManualBreaks.begin(), maColManualBreaks.end(), inserter(rBreaks, rBreaks.begin())); } } bool ScTable::HasRowPageBreak(SCROW nRow) const { if (!ValidRow(nRow)) return false; return maRowPageBreaks.find(nRow) != maRowPageBreaks.end(); } bool ScTable::HasColPageBreak(SCCOL nCol) const { if (!ValidCol(nCol)) return false; return maColPageBreaks.find(nCol) != maColPageBreaks.end(); } bool ScTable::HasRowManualBreak(SCROW nRow) const { if (!ValidRow(nRow)) return false; return maRowManualBreaks.find(nRow) != maRowManualBreaks.end(); } bool ScTable::HasColManualBreak(SCCOL nCol) const { if (!ValidCol(nCol)) return false; return maColManualBreaks.find(nCol) != maColManualBreaks.end(); } SCROW ScTable::GetNextManualBreak(SCROW nRow) const { set::const_iterator itr = maRowManualBreaks.lower_bound(nRow); return itr == maRowManualBreaks.end() ? -1 : *itr; } void ScTable::RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow) { using namespace std; if (!ValidRow(nStartRow) || !ValidRow(nEndRow)) return; set::iterator low = maRowPageBreaks.lower_bound(nStartRow); set::iterator high = maRowPageBreaks.upper_bound(nEndRow); maRowPageBreaks.erase(low, high); } void ScTable::RemoveRowBreak(SCROW nRow, bool bPage, bool bManual) { if (!ValidRow(nRow)) return; if (bPage) maRowPageBreaks.erase(nRow); if (bManual) { maRowManualBreaks.erase(nRow); InvalidatePageBreaks(); } } void ScTable::RemoveColBreak(SCCOL nCol, bool bPage, bool bManual) { if (!ValidCol(nCol)) return; if (bPage) maColPageBreaks.erase(nCol); if (bManual) { maColManualBreaks.erase(nCol); InvalidatePageBreaks(); } } void ScTable::SetRowBreak(SCROW nRow, bool bPage, bool bManual) { if (!ValidRow(nRow)) return; if (bPage) maRowPageBreaks.insert(nRow); if (bManual) { maRowManualBreaks.insert(nRow); InvalidatePageBreaks(); } } void ScTable::SetColBreak(SCCOL nCol, bool bPage, bool bManual) { if (!ValidCol(nCol)) return; if (bPage) maColPageBreaks.insert(nCol); if (bManual) { maColManualBreaks.insert(nCol); InvalidatePageBreaks(); } } Sequence ScTable::GetRowBreakData() const { using ::std::copy; using ::std::inserter; set aRowBreaks = maRowPageBreaks; copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(aRowBreaks, aRowBreaks.begin())); set::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end(); Sequence aSeq(aRowBreaks.size()); for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i) { SCROW nRow = *itr; TablePageBreakData aData; aData.Position = nRow; aData.ManualBreak = HasRowManualBreak(nRow); aSeq[i] = aData; } return aSeq; } bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const { if (!ValidRow(nRow)) { if (pFirstRow) *pFirstRow = nRow; if (pLastRow) *pLastRow = nRow; return true; } ScFlatBoolRowSegments::RangeData aData; if (!mpHiddenRows->getRangeData(nRow, aData)) { // search failed. if (pFirstRow) *pFirstRow = nRow; if (pLastRow) *pLastRow = nRow; return true; } if (pFirstRow) *pFirstRow = aData.mnRow1; if (pLastRow) *pLastRow = aData.mnRow2; return aData.mbValue; } bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow) const { rLastRow = nRow; if (!ValidRow(nRow)) return true; ScFlatBoolRowSegments::RangeData aData; if (!mpHiddenRows->getRangeData(nRow, aData)) // search failed. return true; rLastRow = aData.mnRow2; return aData.mbValue; } bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow) const { SCROW nRow = nStartRow; while (nRow <= nEndRow) { SCROW nLastRow = -1; bool bHidden = RowHidden(nRow, nLastRow); if (bHidden) return true; nRow = nLastRow + 1; } return false; } bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol) const { rLastCol = nCol; if (!ValidCol(nCol)) return true; ScFlatBoolColSegments::RangeData aData; if (!mpHiddenCols->getRangeData(nCol, aData)) return true; rLastCol = aData.mnCol2; return aData.mbValue; } bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const { if (!ValidCol(nCol)) return true; ScFlatBoolColSegments::RangeData aData; if (!mpHiddenCols->getRangeData(nCol, aData)) return true; if (pFirstCol) *pFirstCol = aData.mnCol1; if (pLastCol) *pLastCol = aData.mnCol2; return aData.mbValue; } void ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden) { if (bHidden) mpHiddenRows->setTrue(nStartRow, nEndRow); else mpHiddenRows->setFalse(nStartRow, nEndRow); } void ScTable::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden) { if (bHidden) mpHiddenCols->setTrue(nStartCol, nEndCol); else mpHiddenCols->setFalse(nStartCol, nEndCol); } void ScTable::CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol) { SCCOL nCol = nStartCol; while (nCol <= nEndCol) { SCCOL nLastCol; bool bHidden = rTable.ColHidden(nCol, NULL, &nLastCol); if (nLastCol > nEndCol) nLastCol = nEndCol; SetColHidden(nCol, nLastCol, bHidden); nCol = nLastCol + 1; } } void ScTable::CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow) { SCROW nRow = nStartRow; while (nRow <= nEndRow) { SCROW nLastRow = -1; bool bHidden = rTable.RowHidden(nRow, nLastRow); if (nLastRow > nEndRow) nLastRow = nEndRow; SetRowHidden(nRow, nLastRow, bHidden); nRow = nLastRow + 1; } } void ScTable::CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset) { SCROW nRow = nStartRow; ScFlatUInt16RowSegments::RangeData aSrcData; while (nRow <= nEndRow) { if (!rSrcTable.mpRowHeights->getRangeData(nRow + nSrcOffset, aSrcData)) // Something is wrong ! return; SCROW nLastRow = aSrcData.mnRow2 - nSrcOffset; if (nLastRow > nEndRow) nLastRow = nEndRow; mpRowHeights->setValue(nRow, nLastRow, aSrcData.mnValue); nRow = nLastRow + 1; } } SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) const { SCROW nRow = nStartRow; ScFlatBoolRowSegments::RangeData aData; while (nRow <= nEndRow) { if (!ValidRow(nRow)) break; if (!mpHiddenRows->getRangeData(nRow, aData)) // failed to get range data. break; if (!aData.mbValue) // visible row found return nRow; nRow = aData.mnRow2 + 1; } return ::std::numeric_limits::max(); } SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow) const { SCROW nRow = nEndRow; ScFlatBoolRowSegments::RangeData aData; while (nRow >= nStartRow) { if (!ValidRow(nRow)) break; if (!mpHiddenRows->getRangeData(nRow, aData)) // failed to get range data. break; if (!aData.mbValue) // visible row found return nRow; nRow = aData.mnRow1 - 1; } return ::std::numeric_limits::max(); } SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow) const { SCROW nCount = 0; SCROW nRow = nStartRow; ScFlatBoolRowSegments::RangeData aData; while (nRow <= nEndRow) { if (!mpHiddenRows->getRangeData(nRow, aData)) break; if (aData.mnRow2 > nEndRow) aData.mnRow2 = nEndRow; if (!aData.mbValue) nCount += aData.mnRow2 - nRow + 1; nRow = aData.mnRow2 + 1; } return nCount; } sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) const { sal_uInt32 nHeight = 0; SCROW nRow = nStartRow; ScFlatBoolRowSegments::RangeData aData; while (nRow <= nEndRow) { if (!mpHiddenRows->getRangeData(nRow, aData)) break; if (aData.mnRow2 > nEndRow) aData.mnRow2 = nEndRow; if (!aData.mbValue) // visible row range. nHeight += mpRowHeights->getSumValue(nRow, aData.mnRow2); nRow = aData.mnRow2 + 1; } return nHeight; } SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol) const { if (bCol) { SCCOL nCol = static_cast(nPos); if (ColHidden(nCol)) { for (SCCOL i = nCol+1; i <= MAXCOL; ++i) { if (!ColHidden(nCol)) return nCol - 1; } } } else { SCROW nRow = static_cast(nPos); SCROW nLastRow; if (RowHidden(nRow, NULL, &nLastRow)) return static_cast(nLastRow); } return ::std::numeric_limits::max(); } bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) const { if (!ValidRow(nRow)) return false; ScFlatBoolRowSegments::RangeData aData; if (!mpFilteredRows->getRangeData(nRow, aData)) // search failed. return false; if (pFirstRow) *pFirstRow = aData.mnRow1; if (pLastRow) *pLastRow = aData.mnRow2; return aData.mbValue; } bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) const { if (!ValidCol(nCol)) return false; ScFlatBoolColSegments::RangeData aData; if (!mpFilteredCols->getRangeData(nCol, aData)) // search failed. return false; if (pFirstCol) *pFirstCol = aData.mnCol1; if (pLastCol) *pLastCol = aData.mnCol2; return aData.mbValue; } bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow) const { SCROW nRow = nStartRow; while (nRow <= nEndRow) { SCROW nLastRow = nRow; bool bFiltered = RowFiltered(nRow, NULL, &nLastRow); if (bFiltered) return true; nRow = nLastRow + 1; } return false; } void ScTable::CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol) { SCCOL nCol = nStartCol; while (nCol <= nEndCol) { SCCOL nLastCol; bool bFiltered = rTable.ColFiltered(nCol, NULL, &nLastCol); if (nLastCol > nEndCol) nLastCol = nEndCol; SetColFiltered(nCol, nLastCol, bFiltered); nCol = nLastCol + 1; } } void ScTable::CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow) { SCROW nRow = nStartRow; while (nRow <= nEndRow) { SCROW nLastRow = -1; bool bFiltered = rTable.RowFiltered(nRow, NULL, &nLastRow); if (nLastRow > nEndRow) nLastRow = nEndRow; SetRowFiltered(nRow, nLastRow, bFiltered); nRow = nLastRow + 1; } } void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered) { if (bFiltered) mpFilteredRows->setTrue(nStartRow, nEndRow); else mpFilteredRows->setFalse(nStartRow, nEndRow); } void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered) { if (bFiltered) mpFilteredCols->setTrue(nStartCol, nEndCol); else mpFilteredCols->setFalse(nStartCol, nEndCol); } SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const { SCROW nRow = nStartRow; ScFlatBoolRowSegments::RangeData aData; while (nRow <= nEndRow) { if (!ValidRow(nRow)) break; if (!mpFilteredRows->getRangeData(nRow, aData)) // failed to get range data. break; if (!aData.mbValue) // non-filtered row found return nRow; nRow = aData.mnRow2 + 1; } return ::std::numeric_limits::max(); } SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) const { SCROW nRow = nEndRow; ScFlatBoolRowSegments::RangeData aData; while (nRow >= nStartRow) { if (!ValidRow(nRow)) break; if (!mpFilteredRows->getRangeData(nRow, aData)) // failed to get range data. break; if (!aData.mbValue) // non-filtered row found return nRow; nRow = aData.mnRow1 - 1; } return ::std::numeric_limits::max(); } SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow) const { SCROW nCount = 0; SCROW nRow = nStartRow; ScFlatBoolRowSegments::RangeData aData; while (nRow <= nEndRow) { if (!mpFilteredRows->getRangeData(nRow, aData)) break; if (aData.mnRow2 > nEndRow) aData.mnRow2 = nEndRow; if (!aData.mbValue) nCount += aData.mnRow2 - nRow + 1; nRow = aData.mnRow2 + 1; } return nCount; } namespace { void lcl_syncFlags(ScFlatBoolColSegments& rColSegments, ScFlatBoolRowSegments& rRowSegments, sal_uInt8* pColFlags, ScBitMaskCompressedArray< SCROW, sal_uInt8>* pRowFlags, const sal_uInt8 nFlagMask) { using ::sal::static_int_cast; pRowFlags->AndValue(0, MAXROW, static_int_cast(~nFlagMask)); for (SCCOL i = 0; i <= MAXCOL; ++i) pColFlags[i] &= static_int_cast(~nFlagMask); { // row hidden flags. SCROW nRow = 0; ScFlatBoolRowSegments::RangeData aData; while (nRow <= MAXROW) { if (!rRowSegments.getRangeData(nRow, aData)) break; if (aData.mbValue) pRowFlags->OrValue(nRow, aData.mnRow2, static_int_cast(nFlagMask)); nRow = aData.mnRow2 + 1; } } { // column hidden flags. SCCOL nCol = 0; ScFlatBoolColSegments::RangeData aData; while (nCol <= MAXCOL) { if (!rColSegments.getRangeData(nCol, aData)) break; if (aData.mbValue) { for (SCCOL i = nCol; i <= aData.mnCol2; ++i) pColFlags[i] |= nFlagMask; } nCol = aData.mnCol2 + 1; } } } } void ScTable::SyncColRowFlags() { using ::sal::static_int_cast; // Manual breaks. pRowFlags->AndValue(0, MAXROW, static_int_cast(~CR_MANUALBREAK)); for (SCCOL i = 0; i <= MAXCOL; ++i) pColFlags[i] &= static_int_cast(~CR_MANUALBREAK); if (!maRowManualBreaks.empty()) { for (set::const_iterator itr = maRowManualBreaks.begin(), itrEnd = maRowManualBreaks.end(); itr != itrEnd; ++itr) pRowFlags->OrValue(*itr, static_int_cast(CR_MANUALBREAK)); } if (!maColManualBreaks.empty()) { for (set::const_iterator itr = maColManualBreaks.begin(), itrEnd = maColManualBreaks.end(); itr != itrEnd; ++itr) pColFlags[*itr] |= CR_MANUALBREAK; } // Hidden flags. lcl_syncFlags(*mpHiddenCols, *mpHiddenRows, pColFlags, pRowFlags, CR_HIDDEN); lcl_syncFlags(*mpFilteredCols, *mpFilteredRows, pColFlags, pRowFlags, CR_FILTERED); } void ScTable::SetPageSize( const Size& rSize ) { if ( rSize.Width() != 0 && rSize.Height() != 0 ) { if (aPageSizeTwips != rSize) InvalidatePageBreaks(); bPageSizeValid = sal_True; aPageSizeTwips = rSize; } else bPageSizeValid = sal_False; } sal_Bool ScTable::IsProtected() const { return pTabProtection.get() && pTabProtection->isProtected(); } void ScTable::SetProtection(const ScTableProtection* pProtect) { if (pProtect) pTabProtection.reset(new ScTableProtection(*pProtect)); else pTabProtection.reset(NULL); if (IsStreamValid()) SetStreamValid(sal_False); } ScTableProtection* ScTable::GetProtection() { return pTabProtection.get(); } Size ScTable::GetPageSize() const { if ( bPageSizeValid ) return aPageSizeTwips; else return Size(); // leer } void ScTable::SetRepeatArea( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow ) { // #i117952# page break calculation uses these values (set from ScPrintFunc), not pRepeatColRange/pRepeatRowRange if ( nStartCol != nRepeatStartX || nEndCol != nRepeatEndX || nStartRow != nRepeatStartY || nEndRow != nRepeatEndY ) InvalidatePageBreaks(); nRepeatStartX = nStartCol; nRepeatEndX = nEndCol; nRepeatStartY = nStartRow; nRepeatEndY = nEndRow; } void ScTable::StartListening( const ScAddress& rAddress, SvtListener* pListener ) { aCol[rAddress.Col()].StartListening( *pListener, rAddress.Row() ); } void ScTable::EndListening( const ScAddress& rAddress, SvtListener* pListener ) { aCol[rAddress.Col()].EndListening( *pListener, rAddress.Row() ); } void ScTable::SetPageStyle( const String& rName ) { if ( aPageStyle != rName ) { String aStrNew = rName; SfxStyleSheetBasePool* pStylePool = pDocument->GetStyleSheetPool(); SfxStyleSheetBase* pNewStyle = pStylePool->Find( aStrNew, SFX_STYLE_FAMILY_PAGE ); if ( !pNewStyle ) { aStrNew = ScGlobal::GetRscString(STR_STYLENAME_STANDARD); pNewStyle = pStylePool->Find( aStrNew, SFX_STYLE_FAMILY_PAGE ); } if ( aPageStyle != aStrNew ) { SfxStyleSheetBase* pOldStyle = pStylePool->Find( aPageStyle, SFX_STYLE_FAMILY_PAGE ); if ( pOldStyle && pNewStyle ) { SfxItemSet& rOldSet = pOldStyle->GetItemSet(); SfxItemSet& rNewSet = pNewStyle->GetItemSet(); const sal_uInt16 nOldScale = GET_SCALEVALUE(rOldSet,ATTR_PAGE_SCALE); const sal_uInt16 nOldScaleToPages = GET_SCALEVALUE(rOldSet,ATTR_PAGE_SCALETOPAGES); const sal_uInt16 nNewScale = GET_SCALEVALUE(rNewSet,ATTR_PAGE_SCALE); const sal_uInt16 nNewScaleToPages = GET_SCALEVALUE(rNewSet,ATTR_PAGE_SCALETOPAGES); if ( (nOldScale != nNewScale) || (nOldScaleToPages != nNewScaleToPages) ) InvalidateTextWidth(NULL, NULL, sal_False, sal_False); } if ( pNewStyle ) // auch ohne den alten (fuer UpdateStdNames) aPageStyle = aStrNew; if (IsStreamValid()) SetStreamValid(sal_False); } } } void ScTable::PageStyleModified( const String& rNewName ) { aPageStyle = rNewName; InvalidateTextWidth(NULL, NULL, sal_False, sal_False); // don't know what was in the style before } void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo, sal_Bool bNumFormatChanged, sal_Bool bBroadcast ) { if ( pAdrFrom && !pAdrTo ) { ScBaseCell* pCell = aCol[pAdrFrom->Col()].GetCell( pAdrFrom->Row() ); if ( pCell ) { pCell->SetTextWidth( TEXTWIDTH_DIRTY ); if ( bNumFormatChanged ) pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN ); if ( bBroadcast ) { // nur bei CalcAsShown switch ( pCell->GetCellType() ) { case CELLTYPE_VALUE : pDocument->Broadcast( SC_HINT_DATACHANGED, ScAddress( pAdrFrom->Col(), pAdrFrom->Row(), nTab ), pCell ); break; case CELLTYPE_FORMULA : ((ScFormulaCell*)pCell)->SetDirty(); break; default: { // added to avoid warnings } } } } } else { const SCCOL nColStart = pAdrFrom ? pAdrFrom->Col() : 0; const SCROW nRowStart = pAdrFrom ? pAdrFrom->Row() : 0; const SCCOL nColEnd = pAdrTo ? pAdrTo->Col() : MAXCOL; const SCROW nRowEnd = pAdrTo ? pAdrTo->Row() : MAXROW; for ( SCCOL nCol=nColStart; nCol<=nColEnd; nCol++ ) { ScColumnIterator aIter( &aCol[nCol], nRowStart, nRowEnd ); ScBaseCell* pCell = NULL; SCROW nRow = nRowStart; while ( aIter.Next( nRow, pCell ) ) { pCell->SetTextWidth( TEXTWIDTH_DIRTY ); if ( bNumFormatChanged ) pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN ); if ( bBroadcast ) { // nur bei CalcAsShown switch ( pCell->GetCellType() ) { case CELLTYPE_VALUE : pDocument->Broadcast( SC_HINT_DATACHANGED, ScAddress( nCol, nRow, nTab ), pCell ); break; case CELLTYPE_FORMULA : ((ScFormulaCell*)pCell)->SetDirty(); break; default: { // added to avoid warnings } } } } } } }