diff options
author | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2017-04-07 15:05:06 +0200 |
---|---|---|
committer | Markus Mohrhard <markus.mohrhard@googlemail.com> | 2017-04-08 01:22:08 +0000 |
commit | 7e03a22b690ff2fa9e2a1cf3a7b0f86ab48b10a4 (patch) | |
tree | 1ad2c8430d1856730641a635b8d59859a5b9ea10 /sc | |
parent | 2f7b05988e6853ddac68b614e9d83e05af08bc0f (diff) |
ScAttrArray::HasAttrib needs to process the default pattern if none set
Change-Id: I00f82387ce67ce7d6e8708c7def994767cd79b6f
Reviewed-on: https://gerrit.libreoffice.org/36269
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Markus Mohrhard <markus.mohrhard@googlemail.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/attarray.hxx | 1 | ||||
-rw-r--r-- | sc/source/core/data/attarray.cxx | 269 |
2 files changed, 140 insertions, 130 deletions
diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index a78d77497541..e43ff9268866 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -101,6 +101,7 @@ friend class ScHorizontalAttrIterator; void RemoveCellCharAttribs( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern, ScEditDataArray* pDataArray ); void SetDefaultIfNotInit( SCSIZE nNeeded = 1 ); + bool HasAttrib_Impl(const ScPatternAttr* pPattern, HasAttrFlags nMask, SCROW nRow1, SCROW nRow2, SCSIZE i) const; ScAttrArray(const ScAttrArray&) = delete; ScAttrArray& operator=(const ScAttrArray&) = delete; diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index a55f8dcfd260..bb81939ad342 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -1286,12 +1286,147 @@ void ScAttrArray::ApplyBlockFrame( const SvxBoxItem* pLineOuter, const SvxBoxInf } } -// Test if field contains specific attribute +bool ScAttrArray::HasAttrib_Impl(const ScPatternAttr* pPattern, HasAttrFlags nMask, SCROW nRow1, SCROW nRow2, SCSIZE i) const +{ + bool bFound = false; + if ( nMask & HasAttrFlags::Merged ) + { + const ScMergeAttr* pMerge = + static_cast<const ScMergeAttr*>( &pPattern->GetItem( ATTR_MERGE ) ); + if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 ) + bFound = true; + } + if ( nMask & ( HasAttrFlags::Overlapped | HasAttrFlags::NotOverlapped | HasAttrFlags::AutoFilter ) ) + { + const ScMergeFlagAttr* pMergeFlag = + static_cast<const ScMergeFlagAttr*>( &pPattern->GetItem( ATTR_MERGE_FLAG ) ); + if ( (nMask & HasAttrFlags::Overlapped) && pMergeFlag->IsOverlapped() ) + bFound = true; + if ( (nMask & HasAttrFlags::NotOverlapped) && !pMergeFlag->IsOverlapped() ) + bFound = true; + if ( (nMask & HasAttrFlags::AutoFilter) && pMergeFlag->HasAutoFilter() ) + bFound = true; + } + if ( nMask & HasAttrFlags::Lines ) + { + const SvxBoxItem* pBox = + static_cast<const SvxBoxItem*>( &pPattern->GetItem( ATTR_BORDER ) ); + if ( pBox->GetLeft() || pBox->GetRight() || pBox->GetTop() || pBox->GetBottom() ) + bFound = true; + } + if ( nMask & HasAttrFlags::Shadow ) + { + const SvxShadowItem* pShadow = + static_cast<const SvxShadowItem*>( &pPattern->GetItem( ATTR_SHADOW ) ); + if ( pShadow->GetLocation() != SvxShadowLocation::NONE ) + bFound = true; + } + if ( nMask & HasAttrFlags::Conditional ) + { + bool bContainsCondFormat = + !static_cast<const ScCondFormatItem&>(pPattern->GetItem( ATTR_CONDITIONAL )).GetCondFormatData().empty(); + if ( bContainsCondFormat ) + bFound = true; + } + if ( nMask & HasAttrFlags::Protected ) + { + const ScProtectionAttr* pProtect = + static_cast<const ScProtectionAttr*>( &pPattern->GetItem( ATTR_PROTECTION ) ); + bool bFoundTemp = false; + if ( pProtect->GetProtection() || pProtect->GetHideCell() ) + bFoundTemp = true; + + bool bContainsCondFormat = pData && + !static_cast<const ScCondFormatItem&>(pPattern->GetItem( ATTR_CONDITIONAL )).GetCondFormatData().empty(); + if ( bContainsCondFormat && nCol != -1 ) // pDocument->GetCondResult() is valid only for real columns. + { + SCROW nRowStartCond = std::max<SCROW>( nRow1, i ? pData[i-1].nRow + 1: 0 ); + SCROW nRowEndCond = std::min<SCROW>( nRow2, pData[i].nRow ); + bool bFoundCond = false; + for(SCROW nRowCond = nRowStartCond; nRowCond <= nRowEndCond && !bFoundCond; ++nRowCond) + { + const SfxItemSet* pSet = pDocument->GetCondResult( nCol, nRowCond, nTab ); + + const SfxPoolItem* pItem; + if( pSet && pSet->GetItemState( ATTR_PROTECTION, true, &pItem ) == SfxItemState::SET ) + { + const ScProtectionAttr* pCondProtect = static_cast<const ScProtectionAttr*>(pItem); + if( pCondProtect->GetProtection() || pCondProtect->GetHideCell() ) + bFoundCond = true; + else + break; + } + else + { + // well it is not true that we found one + // but existing one + cell where conditional + // formatting does not remove it + // => we should use the existing protection setting + bFoundCond = bFoundTemp; + } + } + bFoundTemp = bFoundCond; + } + + if(bFoundTemp) + bFound = true; + } + if ( nMask & HasAttrFlags::Rotate ) + { + const SfxInt32Item* pRotate = + static_cast<const SfxInt32Item*>( &pPattern->GetItem( ATTR_ROTATE_VALUE ) ); + // 90 or 270 degrees is former SvxOrientationItem - only look for other values + // (see ScPatternAttr::GetCellOrientation) + sal_Int32 nAngle = pRotate->GetValue(); + if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 ) + bFound = true; + } + if ( nMask & HasAttrFlags::NeedHeight ) + { + if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD) + bFound = true; + else if (static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_LINEBREAK )).GetValue()) + bFound = true; + else if ((SvxCellHorJustify)static_cast<const SvxHorJustifyItem&>(pPattern-> + GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SvxCellHorJustify::Block) + bFound = true; + + else if (!static_cast<const ScCondFormatItem&>(pPattern->GetItem(ATTR_CONDITIONAL)).GetCondFormatData().empty()) + bFound = true; + else if (static_cast<const SfxInt32Item&>(pPattern->GetItem( ATTR_ROTATE_VALUE )).GetValue()) + bFound = true; + } + if ( nMask & ( HasAttrFlags::ShadowRight | HasAttrFlags::ShadowDown ) ) + { + const SvxShadowItem* pShadow = + static_cast<const SvxShadowItem*>( &pPattern->GetItem( ATTR_SHADOW )); + SvxShadowLocation eLoc = pShadow->GetLocation(); + if ( nMask & HasAttrFlags::ShadowRight ) + if ( eLoc == SvxShadowLocation::TopRight || eLoc == SvxShadowLocation::BottomRight ) + bFound = true; + if ( nMask & HasAttrFlags::ShadowDown ) + if ( eLoc == SvxShadowLocation::BottomLeft || eLoc == SvxShadowLocation::BottomRight ) + bFound = true; + } + if ( nMask & HasAttrFlags::RightOrCenter ) + { + // called only if the sheet is LTR, so physical=logical alignment can be assumed + SvxCellHorJustify eHorJust = (SvxCellHorJustify) + static_cast<const SvxHorJustifyItem&>( pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue(); + if ( eHorJust == SvxCellHorJustify::Right || eHorJust == SvxCellHorJustify::Center ) + bFound = true; + } + + return bFound; +} +// Test if field contains specific attribute bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, HasAttrFlags nMask ) const { - if ( !pData ) - return false; + if (!pData) + { + return HasAttrib_Impl(pDocument->GetDefPattern(), nMask, 0, MAXROW, 0); + } SCSIZE nStartIndex; SCSIZE nEndIndex; @@ -1305,133 +1440,7 @@ bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, HasAttrFlags nMask ) cons for (SCSIZE i=nStartIndex; i<=nEndIndex && !bFound; i++) { const ScPatternAttr* pPattern = pData[i].pPattern; - if ( nMask & HasAttrFlags::Merged ) - { - const ScMergeAttr* pMerge = - static_cast<const ScMergeAttr*>( &pPattern->GetItem( ATTR_MERGE ) ); - if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 ) - bFound = true; - } - if ( nMask & ( HasAttrFlags::Overlapped | HasAttrFlags::NotOverlapped | HasAttrFlags::AutoFilter ) ) - { - const ScMergeFlagAttr* pMergeFlag = - static_cast<const ScMergeFlagAttr*>( &pPattern->GetItem( ATTR_MERGE_FLAG ) ); - if ( (nMask & HasAttrFlags::Overlapped) && pMergeFlag->IsOverlapped() ) - bFound = true; - if ( (nMask & HasAttrFlags::NotOverlapped) && !pMergeFlag->IsOverlapped() ) - bFound = true; - if ( (nMask & HasAttrFlags::AutoFilter) && pMergeFlag->HasAutoFilter() ) - bFound = true; - } - if ( nMask & HasAttrFlags::Lines ) - { - const SvxBoxItem* pBox = - static_cast<const SvxBoxItem*>( &pPattern->GetItem( ATTR_BORDER ) ); - if ( pBox->GetLeft() || pBox->GetRight() || pBox->GetTop() || pBox->GetBottom() ) - bFound = true; - } - if ( nMask & HasAttrFlags::Shadow ) - { - const SvxShadowItem* pShadow = - static_cast<const SvxShadowItem*>( &pPattern->GetItem( ATTR_SHADOW ) ); - if ( pShadow->GetLocation() != SvxShadowLocation::NONE ) - bFound = true; - } - if ( nMask & HasAttrFlags::Conditional ) - { - bool bContainsCondFormat = - !static_cast<const ScCondFormatItem&>(pPattern->GetItem( ATTR_CONDITIONAL )).GetCondFormatData().empty(); - if ( bContainsCondFormat ) - bFound = true; - } - if ( nMask & HasAttrFlags::Protected ) - { - const ScProtectionAttr* pProtect = - static_cast<const ScProtectionAttr*>( &pPattern->GetItem( ATTR_PROTECTION ) ); - bool bFoundTemp = false; - if ( pProtect->GetProtection() || pProtect->GetHideCell() ) - bFoundTemp = true; - - bool bContainsCondFormat = - !static_cast<const ScCondFormatItem&>(pPattern->GetItem( ATTR_CONDITIONAL )).GetCondFormatData().empty(); - if ( bContainsCondFormat && nCol != -1 ) // pDocument->GetCondResult() is valid only for real columns. - { - SCROW nRowStartCond = std::max<SCROW>( nRow1, i ? pData[i-1].nRow + 1: 0 ); - SCROW nRowEndCond = std::min<SCROW>( nRow2, pData[i].nRow ); - bool bFoundCond = false; - for(SCROW nRowCond = nRowStartCond; nRowCond <= nRowEndCond && !bFoundCond; ++nRowCond) - { - const SfxItemSet* pSet = pDocument->GetCondResult( nCol, nRowCond, nTab ); - - const SfxPoolItem* pItem; - if( pSet && pSet->GetItemState( ATTR_PROTECTION, true, &pItem ) == SfxItemState::SET ) - { - const ScProtectionAttr* pCondProtect = static_cast<const ScProtectionAttr*>(pItem); - if( pCondProtect->GetProtection() || pCondProtect->GetHideCell() ) - bFoundCond = true; - else - break; - } - else - { - // well it is not true that we found one - // but existing one + cell where conditional - // formatting does not remove it - // => we should use the existing protection setting - bFoundCond = bFoundTemp; - } - } - bFoundTemp = bFoundCond; - } - - if(bFoundTemp) - bFound = true; - } - if ( nMask & HasAttrFlags::Rotate ) - { - const SfxInt32Item* pRotate = - static_cast<const SfxInt32Item*>( &pPattern->GetItem( ATTR_ROTATE_VALUE ) ); - // 90 or 270 degrees is former SvxOrientationItem - only look for other values - // (see ScPatternAttr::GetCellOrientation) - sal_Int32 nAngle = pRotate->GetValue(); - if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 ) - bFound = true; - } - if ( nMask & HasAttrFlags::NeedHeight ) - { - if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD) - bFound = true; - else if (static_cast<const SfxBoolItem&>(pPattern->GetItem( ATTR_LINEBREAK )).GetValue()) - bFound = true; - else if ((SvxCellHorJustify)static_cast<const SvxHorJustifyItem&>(pPattern-> - GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SvxCellHorJustify::Block) - bFound = true; - - else if (!static_cast<const ScCondFormatItem&>(pPattern->GetItem(ATTR_CONDITIONAL)).GetCondFormatData().empty()) - bFound = true; - else if (static_cast<const SfxInt32Item&>(pPattern->GetItem( ATTR_ROTATE_VALUE )).GetValue()) - bFound = true; - } - if ( nMask & ( HasAttrFlags::ShadowRight | HasAttrFlags::ShadowDown ) ) - { - const SvxShadowItem* pShadow = - static_cast<const SvxShadowItem*>( &pPattern->GetItem( ATTR_SHADOW )); - SvxShadowLocation eLoc = pShadow->GetLocation(); - if ( nMask & HasAttrFlags::ShadowRight ) - if ( eLoc == SvxShadowLocation::TopRight || eLoc == SvxShadowLocation::BottomRight ) - bFound = true; - if ( nMask & HasAttrFlags::ShadowDown ) - if ( eLoc == SvxShadowLocation::BottomLeft || eLoc == SvxShadowLocation::BottomRight ) - bFound = true; - } - if ( nMask & HasAttrFlags::RightOrCenter ) - { - // called only if the sheet is LTR, so physical=logical alignment can be assumed - SvxCellHorJustify eHorJust = (SvxCellHorJustify) - static_cast<const SvxHorJustifyItem&>( pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue(); - if ( eHorJust == SvxCellHorJustify::Right || eHorJust == SvxCellHorJustify::Center ) - bFound = true; - } + bFound = HasAttrib_Impl(pPattern, nMask, nRow1, nRow2, i); } return bFound; |