diff options
120 files changed, 2043 insertions, 1629 deletions
diff --git a/chart2/source/view/main/ChartItemPool.cxx b/chart2/source/view/main/ChartItemPool.cxx index ed62e57c1a53..8f787cd4bd70 100644 --- a/chart2/source/view/main/ChartItemPool.cxx +++ b/chart2/source/view/main/ChartItemPool.cxx @@ -190,8 +190,10 @@ ChartItemPool::ChartItemPool(): const sal_uInt16 nMax = SCHATTR_END - SCHATTR_START + 1; for( sal_uInt16 i = 0; i < nMax; i++ ) { + // _nSID, _bNeedsPoolRegistration, _bShareable pItemInfos[i]._nSID = 0; - pItemInfos[i]._bPoolable = true; + pItemInfos[i]._bNeedsPoolRegistration = false; + pItemInfos[i]._bShareable = true; } // slot ids differing from which ids diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx index 9b082680fcee..4b50b74b8b68 100644 --- a/cui/source/tabpages/tabarea.cxx +++ b/cui/source/tabpages/tabarea.cxx @@ -83,7 +83,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aColorListItem ); else - mpDrawModel->GetItemPool().Put(aColorListItem,SID_COLOR_TABLE); + mpDrawModel->GetItemPool().DirectPutItemInPool(aColorListItem,SID_COLOR_TABLE); mpColorList = mpDrawModel->GetColorList(); } if( mpNewGradientList != mpDrawModel->GetGradientList() ) @@ -93,7 +93,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().Put(aItem,SID_GRADIENT_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_GRADIENT_LIST); mpGradientList = mpDrawModel->GetGradientList(); } if( mpNewHatchingList != mpDrawModel->GetHatchList() ) @@ -103,7 +103,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().Put(aItem,SID_HATCH_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_HATCH_LIST); mpHatchingList = mpDrawModel->GetHatchList(); } if( mpNewBitmapList != mpDrawModel->GetBitmapList() ) @@ -113,7 +113,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().Put(aItem,SID_BITMAP_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_BITMAP_LIST); mpBitmapList = mpDrawModel->GetBitmapList(); } if( mpNewPatternList != mpDrawModel->GetPatternList() ) @@ -123,7 +123,7 @@ void SvxAreaTabDialog::SavePalettes() if( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().Put(aItem,SID_PATTERN_LIST); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_PATTERN_LIST); mpPatternList = mpDrawModel->GetPatternList(); } @@ -148,7 +148,7 @@ void SvxAreaTabDialog::SavePalettes() if ( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().Put(aItem); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); } if( mnBitmapListState & ChangeType::MODIFIED ) @@ -162,7 +162,7 @@ void SvxAreaTabDialog::SavePalettes() pShell->PutItem( aItem ); else { - mpDrawModel->GetItemPool().Put(aItem); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); } } @@ -176,7 +176,7 @@ void SvxAreaTabDialog::SavePalettes() if( pShell ) pShell->PutItem( aItem ); else - mpDrawModel->GetItemPool().Put(aItem); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); } if( mnGradientListState & ChangeType::MODIFIED ) @@ -190,7 +190,7 @@ void SvxAreaTabDialog::SavePalettes() pShell->PutItem( aItem ); else { - mpDrawModel->GetItemPool().Put(aItem); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); } } @@ -202,7 +202,7 @@ void SvxAreaTabDialog::SavePalettes() pShell->PutItem( aItem ); else { - mpDrawModel->GetItemPool().Put(aItem); + mpDrawModel->GetItemPool().DirectPutItemInPool(aItem); } } } diff --git a/dbaccess/source/ui/dlg/dbadmin.cxx b/dbaccess/source/ui/dlg/dbadmin.cxx index 95bc34e11443..372e72e258a7 100644 --- a/dbaccess/source/ui/dlg/dbadmin.cxx +++ b/dbaccess/source/ui/dlg/dbadmin.cxx @@ -340,67 +340,68 @@ void ODbAdminDialog::createItemSet(std::unique_ptr<SfxItemSet>& _rpSet, rtl::Ref // create the pool static SfxItemInfo const aItemInfos[DSID_LAST_ITEM_ID - DSID_FIRST_ITEM_ID + 1] = { - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, - {0,false}, + // _nSID, _bNeedsPoolRegistration, _bShareable + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, + {0,false,false}, }; OSL_ENSURE(std::size(aItemInfos) == sal_uInt16(DSID_LAST_ITEM_ID),"Invalid Ids!"); diff --git a/dbaccess/source/ui/misc/UITools.cxx b/dbaccess/source/ui/misc/UITools.cxx index ae856a34b35f..a07d588be2a9 100644 --- a/dbaccess/source/ui/misc/UITools.cxx +++ b/dbaccess/source/ui/misc/UITools.cxx @@ -763,11 +763,12 @@ bool callColumnFormatDialog(weld::Widget* _pParent, // UNO->ItemSet static SfxItemInfo aItemInfos[] = { - { 0, false }, - { SID_ATTR_NUMBERFORMAT_VALUE, true }, - { SID_ATTR_ALIGN_HOR_JUSTIFY, true }, - { SID_ATTR_NUMBERFORMAT_INFO, true }, - { SID_ATTR_NUMBERFORMAT_ONE_AREA, true } + // _nSID, _bNeedsPoolRegistration, _bShareable + { 0, false, true }, // SBA_DEF_RANGEFORMAT + { SID_ATTR_NUMBERFORMAT_VALUE, false, true }, // SBA_DEF_FMTVALUE + { SID_ATTR_ALIGN_HOR_JUSTIFY, false, true }, // SBA_ATTR_ALIGN_HOR_JUSTIFY + { SID_ATTR_NUMBERFORMAT_INFO, false, true }, // SID_ATTR_NUMBERFORMAT_INFO + { SID_ATTR_NUMBERFORMAT_ONE_AREA, false, true } // SID_ATTR_NUMBERFORMAT_ONE_AREA }; static const auto aAttrMap = svl::Items< SBA_DEF_RANGEFORMAT, SBA_ATTR_ALIGN_HOR_JUSTIFY, diff --git a/editeng/source/editeng/editdoc.cxx b/editeng/source/editeng/editdoc.cxx index 9b0d3948bc13..9841d7854c32 100644 --- a/editeng/source/editeng/editdoc.cxx +++ b/editeng/source/editeng/editdoc.cxx @@ -157,70 +157,72 @@ bool IsScriptItemValid( sal_uInt16 nItemId, short nScriptType ) return bValid; } -const SfxItemInfo aItemInfos[EDITITEMCOUNT] = { - { SID_ATTR_FRAMEDIRECTION, true }, // EE_PARA_WRITINGDIR - { 0, true }, // EE_PARA_XMLATTRIBS - { SID_ATTR_PARA_HANGPUNCTUATION, true }, // EE_PARA_HANGINGPUNCTUATION - { SID_ATTR_PARA_FORBIDDEN_RULES, true }, // EE_PARA_FORBIDDENRULES - { SID_ATTR_PARA_SCRIPTSPACE, true }, // EE_PARA_ASIANCJKSPACING - { SID_ATTR_NUMBERING_RULE, true }, // EE_PARA_NUMBULL - { 0, true }, // EE_PARA_HYPHENATE - { 0, true }, // EE_PARA_HYPHENATE_NO_CAPS - { 0, true }, // EE_PARA_HYPHENATE_NO_LAST_WORD - { 0, true }, // EE_PARA_BULLETSTATE - { 0, true }, // EE_PARA_OUTLLRSPACE - { SID_ATTR_PARA_OUTLLEVEL, true }, // EE_PARA_OUTLLEVEL - { SID_ATTR_PARA_BULLET, true }, // EE_PARA_BULLET - { SID_ATTR_LRSPACE, true }, // EE_PARA_LRSPACE - { SID_ATTR_ULSPACE, true }, // EE_PARA_ULSPACE - { SID_ATTR_PARA_LINESPACE, true }, // EE_PARA_SBL - { SID_ATTR_PARA_ADJUST, true }, // EE_PARA_JUST - { SID_ATTR_TABSTOP, true }, // EE_PARA_TABS - { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, true }, // EE_PARA_JUST_METHOD - { SID_ATTR_ALIGN_VER_JUSTIFY, true }, // EE_PARA_VER_JUST - { SID_ATTR_CHAR_COLOR, true }, // EE_CHAR_COLOR - { SID_ATTR_CHAR_FONT, true }, // EE_CHAR_FONTINFO - { SID_ATTR_CHAR_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT - { SID_ATTR_CHAR_SCALEWIDTH, true }, // EE_CHAR_FONTWIDTH - { SID_ATTR_CHAR_WEIGHT, true }, // EE_CHAR_WEIGHT - { SID_ATTR_CHAR_UNDERLINE, true }, // EE_CHAR_UNDERLINE - { SID_ATTR_CHAR_STRIKEOUT, true }, // EE_CHAR_STRIKEOUT - { SID_ATTR_CHAR_POSTURE, true }, // EE_CHAR_ITALIC - { SID_ATTR_CHAR_CONTOUR, true }, // EE_CHAR_OUTLINE - { SID_ATTR_CHAR_SHADOWED, true }, // EE_CHAR_SHADOW - { SID_ATTR_CHAR_ESCAPEMENT, true }, // EE_CHAR_ESCAPEMENT - { SID_ATTR_CHAR_AUTOKERN, true }, // EE_CHAR_PAIRKERNING - { SID_ATTR_CHAR_KERNING, true }, // EE_CHAR_KERNING - { SID_ATTR_CHAR_WORDLINEMODE, true }, // EE_CHAR_WLM - { SID_ATTR_CHAR_LANGUAGE, true }, // EE_CHAR_LANGUAGE - { SID_ATTR_CHAR_CJK_LANGUAGE, true }, // EE_CHAR_LANGUAGE_CJK - { SID_ATTR_CHAR_CTL_LANGUAGE, true }, // EE_CHAR_LANGUAGE_CTL - { SID_ATTR_CHAR_CJK_FONT, true }, // EE_CHAR_FONTINFO_CJK - { SID_ATTR_CHAR_CTL_FONT, true }, // EE_CHAR_FONTINFO_CTL - { SID_ATTR_CHAR_CJK_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT_CJK - { SID_ATTR_CHAR_CTL_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT_CTL - { SID_ATTR_CHAR_CJK_WEIGHT, true }, // EE_CHAR_WEIGHT_CJK - { SID_ATTR_CHAR_CTL_WEIGHT, true }, // EE_CHAR_WEIGHT_CTL - { SID_ATTR_CHAR_CJK_POSTURE, true }, // EE_CHAR_ITALIC_CJK - { SID_ATTR_CHAR_CTL_POSTURE, true }, // EE_CHAR_ITALIC_CTL - { SID_ATTR_CHAR_EMPHASISMARK, true }, // EE_CHAR_EMPHASISMARK - { SID_ATTR_CHAR_RELIEF, true }, // EE_CHAR_RELIEF - { 0, true }, // EE_CHAR_RUBI_DUMMY - { 0, true }, // EE_CHAR_XMLATTRIBS - { SID_ATTR_CHAR_OVERLINE, true }, // EE_CHAR_OVERLINE - { SID_ATTR_CHAR_CASEMAP, true }, // EE_CHAR_CASEMAP - { SID_ATTR_CHAR_GRABBAG, true }, // EE_CHAR_GRABBAG - { SID_ATTR_CHAR_BACK_COLOR, true }, // EE_CHAR_BKGCOLOR - { 0, true }, // EE_FEATURE_TAB - { 0, true }, // EE_FEATURE_LINEBR - { SID_ATTR_CHAR_CHARSETCOLOR, true }, // EE_FEATURE_NOTCONV - { SID_FIELD, false }, // EE_FEATURE_FIELD +const SfxItemInfo aItemInfos[EDITITEMCOUNT] = +{ + // _nSID, _bNeedsPoolRegistration, _bShareable + { SID_ATTR_FRAMEDIRECTION, false, true }, // EE_PARA_WRITINGDIR + { 0, true, true }, // EE_PARA_XMLATTRIBS + { SID_ATTR_PARA_HANGPUNCTUATION, false, true }, // EE_PARA_HANGINGPUNCTUATION + { SID_ATTR_PARA_FORBIDDEN_RULES, false, true }, // EE_PARA_FORBIDDENRULES + { SID_ATTR_PARA_SCRIPTSPACE, false, true }, // EE_PARA_ASIANCJKSPACING + { SID_ATTR_NUMBERING_RULE, false, true }, // EE_PARA_NUMBULL + { 0, false, true }, // EE_PARA_HYPHENATE + { 0, false, true }, // EE_PARA_HYPHENATE_NO_CAPS + { 0, false, true }, // EE_PARA_HYPHENATE_NO_LAST_WORD + { 0, false, true }, // EE_PARA_BULLETSTATE + { 0, false, true }, // EE_PARA_OUTLLRSPACE + { SID_ATTR_PARA_OUTLLEVEL, false, true }, // EE_PARA_OUTLLEVEL + { SID_ATTR_PARA_BULLET, false, true }, // EE_PARA_BULLET + { SID_ATTR_LRSPACE, false, true }, // EE_PARA_LRSPACE + { SID_ATTR_ULSPACE, false, true }, // EE_PARA_ULSPACE + { SID_ATTR_PARA_LINESPACE, false, true }, // EE_PARA_SBL + { SID_ATTR_PARA_ADJUST, false, true }, // EE_PARA_JUST + { SID_ATTR_TABSTOP, false, true }, // EE_PARA_TABS + { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, false, true }, // EE_PARA_JUST_METHOD + { SID_ATTR_ALIGN_VER_JUSTIFY, false, true }, // EE_PARA_VER_JUST + { SID_ATTR_CHAR_COLOR, true, true }, // EE_CHAR_COLOR + { SID_ATTR_CHAR_FONT, true, true }, // EE_CHAR_FONTINFO + { SID_ATTR_CHAR_FONTHEIGHT, false, true }, // EE_CHAR_FONTHEIGHT + { SID_ATTR_CHAR_SCALEWIDTH, false, true }, // EE_CHAR_FONTWIDTH + { SID_ATTR_CHAR_WEIGHT, false, true }, // EE_CHAR_WEIGHT + { SID_ATTR_CHAR_UNDERLINE, false, true }, // EE_CHAR_UNDERLINE + { SID_ATTR_CHAR_STRIKEOUT, false, true }, // EE_CHAR_STRIKEOUT + { SID_ATTR_CHAR_POSTURE, false, true }, // EE_CHAR_ITALIC + { SID_ATTR_CHAR_CONTOUR, false, true }, // EE_CHAR_OUTLINE + { SID_ATTR_CHAR_SHADOWED, false, true }, // EE_CHAR_SHADOW + { SID_ATTR_CHAR_ESCAPEMENT, false, true }, // EE_CHAR_ESCAPEMENT + { SID_ATTR_CHAR_AUTOKERN, false, true }, // EE_CHAR_PAIRKERNING + { SID_ATTR_CHAR_KERNING, false, true }, // EE_CHAR_KERNING + { SID_ATTR_CHAR_WORDLINEMODE, false, true }, // EE_CHAR_WLM + { SID_ATTR_CHAR_LANGUAGE, false, true }, // EE_CHAR_LANGUAGE + { SID_ATTR_CHAR_CJK_LANGUAGE, false, true }, // EE_CHAR_LANGUAGE_CJK + { SID_ATTR_CHAR_CTL_LANGUAGE, false, true }, // EE_CHAR_LANGUAGE_CTL + { SID_ATTR_CHAR_CJK_FONT, true, true }, // EE_CHAR_FONTINFO_CJK + { SID_ATTR_CHAR_CTL_FONT, true, true }, // EE_CHAR_FONTINFO_CTL + { SID_ATTR_CHAR_CJK_FONTHEIGHT, false, true }, // EE_CHAR_FONTHEIGHT_CJK + { SID_ATTR_CHAR_CTL_FONTHEIGHT, false, true }, // EE_CHAR_FONTHEIGHT_CTL + { SID_ATTR_CHAR_CJK_WEIGHT, false, true }, // EE_CHAR_WEIGHT_CJK + { SID_ATTR_CHAR_CTL_WEIGHT, false, true }, // EE_CHAR_WEIGHT_CTL + { SID_ATTR_CHAR_CJK_POSTURE, false, true }, // EE_CHAR_ITALIC_CJK + { SID_ATTR_CHAR_CTL_POSTURE, false, true }, // EE_CHAR_ITALIC_CTL + { SID_ATTR_CHAR_EMPHASISMARK, false, true }, // EE_CHAR_EMPHASISMARK + { SID_ATTR_CHAR_RELIEF, false, true }, // EE_CHAR_RELIEF + { 0, false, true }, // EE_CHAR_RUBI_DUMMY + { 0, true, true }, // EE_CHAR_XMLATTRIBS + { SID_ATTR_CHAR_OVERLINE, false, true }, // EE_CHAR_OVERLINE + { SID_ATTR_CHAR_CASEMAP, false, true }, // EE_CHAR_CASEMAP + { SID_ATTR_CHAR_GRABBAG, false, true }, // EE_CHAR_GRABBAG + { SID_ATTR_CHAR_BACK_COLOR, false, true }, // EE_CHAR_BKGCOLOR + { 0, false, true }, // EE_FEATURE_TAB + { 0, false, true }, // EE_FEATURE_LINEBR + { SID_ATTR_CHAR_CHARSETCOLOR, false, true }, // EE_FEATURE_NOTCONV + { SID_FIELD, true, true }, // EE_FEATURE_FIELD }; EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, sal_Int32 nS, sal_Int32 nE ) { // Create a new attribute in the pool - const SfxPoolItem& rNew = rPool.Put( rAttr ); + const SfxPoolItem& rNew = rPool.DirectPutItemInPool( rAttr ); EditCharAttrib* pNew = nullptr; switch( rNew.Which() ) @@ -813,7 +815,7 @@ ContentAttribsInfo::ContentAttribsInfo( SfxItemSet aParaAttribs ) : void ContentAttribsInfo::RemoveAllCharAttribsFromPool(SfxItemPool& rPool) const { for (const std::unique_ptr<EditCharAttrib>& rAttrib : aPrevCharAttribs) - rPool.Remove(*rAttrib->GetItem()); + rPool.DirectRemoveItemFromPool(*rAttrib->GetItem()); } void ContentAttribsInfo::AppendCharAttrib(EditCharAttrib* pNew) @@ -1328,7 +1330,7 @@ void ContentNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew, SfxItemPool& { OSL_FAIL( "Empty Attribute after ExpandAttribs?" ); bResort = true; - rItemPool.Remove( *pAttrib->GetItem() ); + rItemPool.DirectRemoveItemFromPool( *pAttrib->GetItem() ); rAttribs.erase(rAttribs.begin()+nAttr); } else @@ -1424,7 +1426,7 @@ void ContentNode::CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDeleted, SfxItem if ( bDelAttr ) { bResort = true; - rItemPool.Remove( *pAttrib->GetItem() ); + rItemPool.DirectRemoveItemFromPool( *pAttrib->GetItem() ); rAttribs.erase(rAttribs.begin()+nAttr); } else @@ -1969,7 +1971,7 @@ void EditDoc::RemoveItemsFromPool(const ContentNode& rNode) for (sal_Int32 nAttr = 0; nAttr < rNode.GetCharAttribs().Count(); ++nAttr) { const EditCharAttrib& rAttr = *rNode.GetCharAttribs().GetAttribs()[nAttr]; - GetItemPool().Remove(*rAttr.GetItem()); + GetItemPool().DirectRemoveItemFromPool(*rAttr.GetItem()); } } @@ -2403,7 +2405,7 @@ void EditDoc::InsertAttribInSelection( ContentNode* pNode, sal_Int32 nStart, sal { // Will become a large Attribute. pEndingAttrib->GetEnd() = pStartingAttrib->GetEnd(); - GetItemPool().Remove( *(pStartingAttrib->GetItem()) ); + GetItemPool().DirectRemoveItemFromPool( *(pStartingAttrib->GetItem()) ); pNode->GetCharAttribs().Remove(pStartingAttrib); } else if ( pStartingAttrib && ( *(pStartingAttrib->GetItem()) == rPoolItem ) ) @@ -2525,7 +2527,7 @@ bool EditDoc::RemoveAttribs( ContentNode* pNode, sal_Int32 nStart, sal_Int32 nEn { DBG_ASSERT( ( pAttr != rpStarting ) && ( pAttr != rpEnding ), "Delete and retain the same attribute?" ); DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a feature?!" ); - GetItemPool().Remove( *pAttr->GetItem() ); + GetItemPool().DirectRemoveItemFromPool( *pAttr->GetItem() ); rAttribs.erase(rAttribs.begin()+nAttr); } else @@ -2822,7 +2824,7 @@ void CharAttribList::OptimizeRanges( SfxItemPool& rItemPool ) if (*rNext.GetItem() == *rAttr.GetItem()) { rAttr.GetEnd() = rNext.GetEnd(); - rItemPool.Remove(*rNext.GetItem()); + rItemPool.DirectRemoveItemFromPool(*rNext.GetItem()); aAttribs.erase(aAttribs.begin()+nNext); } break; // only 1 attr with same which can start here. @@ -2998,7 +3000,7 @@ public: void operator() (const std::unique_ptr<EditCharAttrib>& r) { if (r->IsEmpty()) - mrItemPool.Remove(*r->GetItem()); + mrItemPool.DirectRemoveItemFromPool(*r->GetItem()); } }; diff --git a/editeng/source/editeng/editobj.cxx b/editeng/source/editeng/editobj.cxx index d0ec8632f134..ba3aac6990e2 100644 --- a/editeng/source/editeng/editobj.cxx +++ b/editeng/source/editeng/editobj.cxx @@ -47,7 +47,7 @@ using namespace com::sun::star; static XEditAttribute MakeXEditAttribute( SfxItemPool& rPool, const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd ) { // Create the new attribute in the pool - const SfxPoolItem& rNew = rPool.Put( rItem ); + const SfxPoolItem& rNew = rPool.DirectPutItemInPool( rItem ); return XEditAttribute( rNew, nStart, nEnd ); } @@ -122,7 +122,7 @@ ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse ContentInfo::~ContentInfo() { for (auto const& charAttrib : maCharAttribs) - aParaAttribs.GetPool()->Remove(*charAttrib.GetItem()); + aParaAttribs.GetPool()->DirectRemoveItemFromPool(*charAttrib.GetItem()); maCharAttribs.clear(); } @@ -381,7 +381,7 @@ XEditAttribute EditTextObjectImpl::CreateAttrib( const SfxPoolItem& rItem, sal_I void EditTextObjectImpl::DestroyAttrib( const XEditAttribute& rAttr ) { - mpPool->Remove( *rAttr.GetItem() ); + mpPool->DirectRemoveItemFromPool( *rAttr.GetItem() ); } @@ -540,7 +540,7 @@ bool EditTextObjectImpl::RemoveCharAttribs( sal_uInt16 _nWhich ) XEditAttribute& rAttr = rC.maCharAttribs[--nAttr]; if ( !_nWhich || (rAttr.GetItem()->Which() == _nWhich) ) { - mpPool->Remove(*rAttr.GetItem()); + mpPool->DirectRemoveItemFromPool(*rAttr.GetItem()); rC.maCharAttribs.erase(rC.maCharAttribs.begin()+nAttr); bChanged = true; } diff --git a/editeng/source/editeng/editobj2.hxx b/editeng/source/editeng/editobj2.hxx index 86c81e23f94e..8a714741ebb4 100644 --- a/editeng/source/editeng/editobj2.hxx +++ b/editeng/source/editeng/editobj2.hxx @@ -74,9 +74,7 @@ inline bool XEditAttribute::operator==( const XEditAttribute& rCompare ) const { return (nStart == rCompare.nStart) && (nEnd == rCompare.nEnd) && - ((pItem == rCompare.pItem) || - ((pItem->Which() == rCompare.pItem->Which()) && - (*pItem == *rCompare.pItem))); + SfxPoolItem::areSame(pItem, rCompare.pItem); } struct XParaPortion diff --git a/editeng/source/editeng/fieldupdater.cxx b/editeng/source/editeng/fieldupdater.cxx index 41d9be7aeee7..008793a04ffd 100644 --- a/editeng/source/editeng/fieldupdater.cxx +++ b/editeng/source/editeng/fieldupdater.cxx @@ -47,7 +47,7 @@ public: // Create a new table field with the new ID, and set it to the // attribute object. SvxFieldItem aNewItem(SvxTableField(nTab), EE_FEATURE_FIELD); - rAttr.SetItem(pPool->Put(aNewItem)); + rAttr.SetItem(pPool->DirectPutItemInPool(aNewItem)); } } } diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx index cac394c119c4..e242566bd36f 100644 --- a/editeng/source/items/textitem.cxx +++ b/editeng/source/items/textitem.cxx @@ -159,24 +159,6 @@ bool SvxFontListItem::GetPresentation // class SvxFontItem ----------------------------------------------------- -namespace -{ -sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB) -{ - if (nA < nB) - { - return -1; - } - - if (nA > nB) - { - return 1; - } - - return 0; -} -} - SvxFontItem::SvxFontItem( const sal_uInt16 nId ) : SfxPoolItem( nId ) { @@ -314,36 +296,6 @@ bool SvxFontItem::operator==( const SfxPoolItem& rAttr ) const return bRet; } -bool SvxFontItem::operator<(const SfxPoolItem& rCmp) const -{ - const auto& rOther = static_cast<const SvxFontItem&>(rCmp); - sal_Int32 nRet = GetFamilyName().compareTo(rOther.GetFamilyName()); - if (nRet != 0) - { - return nRet < 0; - } - - nRet = GetStyleName().compareTo(rOther.GetStyleName()); - if (nRet != 0) - { - return nRet < 0; - } - - nRet = CompareTo(GetFamily(), rOther.GetFamily()); - if (nRet != 0) - { - return nRet < 0; - } - - nRet = CompareTo(GetPitch(), rOther.GetPitch()); - if (nRet != 0) - { - return nRet < 0; - } - - return GetCharSet() < rOther.GetCharSet(); -} - SvxFontItem* SvxFontItem::Clone( SfxItemPool * ) const { return new SvxFontItem( *this ); diff --git a/extensions/source/propctrlr/fontdialog.cxx b/extensions/source/propctrlr/fontdialog.cxx index 1a101876ffda..59757421a06e 100644 --- a/extensions/source/propctrlr/fontdialog.cxx +++ b/extensions/source/propctrlr/fontdialog.cxx @@ -532,26 +532,27 @@ namespace pcr // create the pool static SfxItemInfo const aItemInfos[FontItemIds::CFID_LAST_ITEM_ID - FontItemIds::CFID_FIRST_ITEM_ID + 1] = { - { SID_ATTR_CHAR_FONT, false }, - { SID_ATTR_CHAR_FONTHEIGHT, false }, - { SID_ATTR_CHAR_WEIGHT, false }, - { SID_ATTR_CHAR_POSTURE, false }, - { SID_ATTR_CHAR_LANGUAGE, false }, - { SID_ATTR_CHAR_UNDERLINE, false }, - { SID_ATTR_CHAR_STRIKEOUT, false }, - { SID_ATTR_CHAR_WORDLINEMODE, false }, - { SID_ATTR_CHAR_COLOR, false }, - { SID_ATTR_CHAR_RELIEF, false }, - { SID_ATTR_CHAR_EMPHASISMARK, false }, - { 0, false }, - { 0, false }, - { 0, false }, - { 0, false }, - { 0, false }, - { 0, false }, - { 0, false }, - { 0, false }, - { SID_ATTR_CHAR_FONTLIST, false } + // _nSID, _bNeedsPoolRegistration, _bShareable + { SID_ATTR_CHAR_FONT, false, false }, + { SID_ATTR_CHAR_FONTHEIGHT, false, false }, + { SID_ATTR_CHAR_WEIGHT, false, false }, + { SID_ATTR_CHAR_POSTURE, false, false }, + { SID_ATTR_CHAR_LANGUAGE, false, false }, + { SID_ATTR_CHAR_UNDERLINE, false, false }, + { SID_ATTR_CHAR_STRIKEOUT, false, false }, + { SID_ATTR_CHAR_WORDLINEMODE, false, false }, + { SID_ATTR_CHAR_COLOR, false, false }, + { SID_ATTR_CHAR_RELIEF, false, false }, + { SID_ATTR_CHAR_EMPHASISMARK, false, false }, + { 0, false, false }, + { 0, false, false }, + { 0, false, false }, + { 0, false, false }, + { 0, false, false }, + { 0, false, false }, + { 0, false, false }, + { 0, false, false }, + { SID_ATTR_CHAR_FONTLIST, false, false } }; _rpPool = new SfxItemPool("PCRControlFontItemPool", FontItemIds::CFID_FIRST_ITEM_ID, FontItemIds::CFID_LAST_ITEM_ID, diff --git a/include/editeng/fontitem.hxx b/include/editeng/fontitem.hxx index deabf3101f44..7cab5f462e4e 100644 --- a/include/editeng/fontitem.hxx +++ b/include/editeng/fontitem.hxx @@ -46,7 +46,6 @@ public: // "pure virtual Methods" from SfxPoolItem virtual bool operator==(const SfxPoolItem& rItem) const override; - bool operator<(const SfxPoolItem& rCmp) const override; virtual SvxFontItem* Clone(SfxItemPool *pPool = nullptr) const override; virtual bool QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId = 0) const override; virtual bool PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) override; diff --git a/include/editeng/wghtitem.hxx b/include/editeng/wghtitem.hxx index 6f5f4b31ccc3..121cfcf318a6 100644 --- a/include/editeng/wghtitem.hxx +++ b/include/editeng/wghtitem.hxx @@ -59,14 +59,6 @@ public: FontWeight GetWeight() const { return GetValue(); } void dumpAsXml(xmlTextWriterPtr pWriter) const override; - - virtual bool IsSortable() const override { return true; } - - virtual bool operator<(const SfxPoolItem& rCmp) const override - { - auto const & other = static_cast<const SvxWeightItem&>(rCmp); - return GetValue() < other.GetValue(); - } }; #endif // INCLUDED_EDITENG_WGHTITEM_HXX diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox index 8e6d5d81f1ae..0b3907e08610 100644 --- a/include/sal/log-areas.dox +++ b/include/sal/log-areas.dox @@ -499,6 +499,7 @@ certain functionality. @li @c vcl.helper @li @c vcl.icontest @li @c vcl.ios.clipboard +@li @c vcl.items @li @c vcl.kf5 - KF5 @li @c vcl.layout - Widget layout @li @c vcl.lazydelete diff --git a/include/svl/custritm.hxx b/include/svl/custritm.hxx index 90215aff45d3..3159c41dfc96 100644 --- a/include/svl/custritm.hxx +++ b/include/svl/custritm.hxx @@ -39,8 +39,6 @@ public: {} virtual bool operator ==(const SfxPoolItem & rItem) const override; - virtual bool operator <(const SfxPoolItem & rItem) const override; - virtual bool IsSortable() const override { return true; } virtual bool GetPresentation(SfxItemPresentation, MapUnit, MapUnit, diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx index e85451ecb738..8dfac4766ffb 100644 --- a/include/svl/itempool.hxx +++ b/include/svl/itempool.hxx @@ -26,6 +26,7 @@ #include <svl/whichranges.hxx> #include <memory> #include <vector> +#include <unordered_set> #include <o3tl/sorted_vector.hxx> #include <salhelper/simplereferenceobject.hxx> @@ -34,11 +35,30 @@ struct SfxItemPool_Impl; struct SfxItemInfo { + // Defines a mapping between WhichID <-> SlotID sal_uInt16 _nSID; - bool _bPoolable; + + // Defines if this Item needs to be registered at the pool + // to make it accessible for the GetItemSurrogates call. It + // will not be included when this flag is not set, but also + // needs no registration. There are SAL_INFO calls in the + // GetItemSurrogates impl that will mention that + bool _bNeedsPoolRegistration : 1; + + // Defines if the Item can be shared/RefCounted else it will be cloned. + // Default is true - as it should be for all Items. It is needed by some + // SW items, so protected to let them set it in constructor. If this could + // be fixed at that Items we may remove this again. + bool _bShareable : 1; }; class SfxItemPool; +typedef std::unordered_set<const SfxPoolItem*> registeredSfxPoolItems; + +#ifdef DBG_UTIL +SVL_DLLPUBLIC size_t getAllDirectlyPooledSfxPoolItemCount(); +SVL_DLLPUBLIC size_t getRemainingDirectlyPooledSfxPoolItemCount(); +#endif /** Base class for providers of defaults of SfxPoolItems. * @@ -53,14 +73,26 @@ class SVL_DLLPUBLIC SfxItemPool : public salhelper::SimpleReferenceObject friend class SfxItemSet; friend class SfxAllItemSet; + // allow ItemSetTooling to access + friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool, bool); + friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*); + + // unit testing + friend class PoolItemTest; + const SfxItemInfo* pItemInfos; std::unique_ptr<SfxItemPool_Impl> pImpl; + registeredSfxPoolItems** ppRegisteredSfxPoolItems; + private: sal_uInt16 GetIndex_Impl(sal_uInt16 nWhich) const; sal_uInt16 GetSize_Impl() const; - SVL_DLLPRIVATE bool IsItemPoolable_Impl( sal_uInt16 nWhich ) const; + SVL_DLLPRIVATE bool NeedsPoolRegistration_Impl(sal_uInt16 nPos) const + { return pItemInfos[nPos]._bNeedsPoolRegistration; } + SVL_DLLPRIVATE bool Shareable_Impl(sal_uInt16 nPos) const + { return pItemInfos[nPos]._bShareable; } public: // for default SfxItemSet::CTOR, set default WhichRanges @@ -135,18 +167,16 @@ public: virtual rtl::Reference<SfxItemPool> Clone() const; const OUString& GetName() const; - template<class T> const T& Put( std::unique_ptr<T> xItem, sal_uInt16 nWhich = 0 ) - { return static_cast<const T&>(PutImpl( *xItem.release(), nWhich, /*bPassingOwnership*/true)); } - template<class T> const T& Put( const T& rItem, sal_uInt16 nWhich = 0 ) - { return static_cast<const T&>(PutImpl( rItem, nWhich, /*bPassingOwnership*/false)); } - void Remove( const SfxPoolItem& ); + template<class T> const T& DirectPutItemInPool( std::unique_ptr<T> xItem, sal_uInt16 nWhich = 0 ) + { return static_cast<const T&>(DirectPutItemInPoolImpl( *xItem.release(), nWhich, /*bPassingOwnership*/true)); } + template<class T> const T& DirectPutItemInPool( const T& rItem, sal_uInt16 nWhich = 0 ) + { return static_cast<const T&>(DirectPutItemInPoolImpl( rItem, nWhich, /*bPassingOwnership*/false)); } + void DirectRemoveItemFromPool( const SfxPoolItem& ); const SfxPoolItem& GetDefaultItem( sal_uInt16 nWhich ) const; template<class T> const T& GetDefaultItem( TypedWhichId<T> nWhich ) const { return static_cast<const T&>(GetDefaultItem(sal_uInt16(nWhich))); } - bool CheckItemInPool(const SfxPoolItem *) const; - struct Item2Range { o3tl::sorted_vector<SfxPoolItem*>::const_iterator m_begin; @@ -158,8 +188,7 @@ public: template<class T> const T* GetItem2Default( TypedWhichId<T> nWhich ) const { return static_cast<const T*>(GetItem2Default(sal_uInt16(nWhich))); } - sal_uInt32 GetItemCount2(sal_uInt16 nWhich) const; - Item2Range GetItemSurrogates(sal_uInt16 nWhich) const; + const registeredSfxPoolItems& GetItemSurrogates(sal_uInt16 nWhich) const; /* This is only valid for SfxPoolItem that override IsSortable and operator<. Returns a range of items defined by using operator<. @@ -179,9 +208,14 @@ public: void Delete(); - bool IsItemPoolable( sal_uInt16 nWhich ) const; - bool IsItemPoolable( const SfxPoolItem &rItem ) const - { return IsItemPoolable( rItem.Which() ); } + bool NeedsPoolRegistration(sal_uInt16 nWhich) const; + bool NeedsPoolRegistration(const SfxPoolItem &rItem) const + { return NeedsPoolRegistration(rItem.Which()); } + + bool Shareable(sal_uInt16 nWhich) const; + bool Shareable(const SfxPoolItem &rItem) const + { return Shareable(rItem.Which()); } + void SetItemInfos( const SfxItemInfo *pInfos ); sal_uInt16 GetWhich( sal_uInt16 nSlot, bool bDeep = true ) const; template<class T> @@ -196,10 +230,34 @@ public: static bool IsSlot(sal_uInt16 nId) { return nId && nId > SFX_WHICH_MAX; } + // this method tries to register an Item at this Pool. If this + // is done depends on the SfxItemInfo-flag _bNeedsPoolRegistration + // which needs to be set for Items that are acessed using + // GetItemSurrogates, else the Item will not be returned/accessed + void tryRegisterSfxPoolItem(const SfxPoolItem& rItem, bool bPoolDirect); + + // this method will register the Item at this Pool, no matter what. + // It is needed for all calls that directly register Items at the + // Pool, so the DirectPutItemInPool-methods + void doRegisterSfxPoolItem(const SfxPoolItem& rItem); + + // this method will unregister an Item from this Pool + void unregisterSfxPoolItem(const SfxPoolItem& rItem); + + // check if this Item is registered at this Pool, needed to detect + // if an Item is to be set at another Pool and needs to be cloned + bool isSfxPoolItemRegisteredAtThisPool(const SfxPoolItem& rItem) const; + + // try to find an equal existing Item to given one in pool + const SfxPoolItem* tryToGetEqualItem(const SfxPoolItem& rItem, sal_uInt16 nWhich) const; + void dumpAsXml(xmlTextWriterPtr pWriter) const; protected: - virtual const SfxPoolItem& PutImpl( const SfxPoolItem&, sal_uInt16 nWhich = 0, bool bPassingOwnership = false ); + const SfxPoolItem& DirectPutItemInPoolImpl( const SfxPoolItem&, sal_uInt16 nWhich = 0, bool bPassingOwnership = false ); + virtual void newItem_Callback(const SfxPoolItem& rItem) const; + virtual bool newItem_UseDirect(const SfxPoolItem& rItem) const; + private: const SfxItemPool& operator=(const SfxItemPool &) = delete; diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx index 01d9d5058b14..06e82b87e054 100644 --- a/include/svl/itemset.hxx +++ b/include/svl/itemset.hxx @@ -36,11 +36,19 @@ SVL_DLLPUBLIC size_t getAllocatedSfxItemSetCount(); SVL_DLLPUBLIC size_t getUsedSfxItemSetCount(); #endif +// ItemSet/ItemPool helpers +SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource, sal_uInt16 nWhich, bool bPassingOwnership, bool bPoolDirect); +void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource); + class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet { friend class SfxItemIter; friend class SfxWhichIter; + // allow ItemSetTooling to access + friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool, bool); + friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*); + SfxItemPool* m_pPool; ///< pool that stores the items const SfxItemSet* m_pParent; ///< derivation sal_uInt16 m_nCount; ///< number of items @@ -88,7 +96,7 @@ private: const SfxItemSet& operator=(const SfxItemSet &) = delete; protected: - virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership ); + virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bPassingOwnership ); /** special constructor for SfxAllItemSet */ enum class SfxAllItemSetFlag { Flag }; @@ -207,9 +215,9 @@ public: // add, delete items, work on items public: const SfxPoolItem* Put( const SfxPoolItem& rItem, sal_uInt16 nWhich ) - { return PutImpl(rItem, nWhich, /*bItemIsSetMember*/false, /*bPassingOwnership*/false); } + { return PutImpl(rItem, nWhich, /*bPassingOwnership*/false); } const SfxPoolItem* Put( std::unique_ptr<SfxPoolItem> xItem, sal_uInt16 nWhich ) - { return PutImpl(*xItem.release(), nWhich, /*bItemIsSetMember*/false, /*bPassingOwnership*/true); } + { return PutImpl(*xItem.release(), nWhich, /*bPassingOwnership*/true); } const SfxPoolItem* Put( const SfxPoolItem& rItem ) { return Put(rItem, rItem.Which()); } const SfxPoolItem* Put( std::unique_ptr<SfxPoolItem> xItem ) @@ -261,7 +269,7 @@ private: sal_uInt16 ClearAllItemsImpl(); // Merge two given Item(entries) - void MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, bool bItemIsSetMember, bool bIgnoreDefaults); + void MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, bool bIgnoreDefaults); // split version(s) of InvalidateItem for input types WhichID and Offset void InvalidateItem_ForWhichID(sal_uInt16 nWhich); @@ -270,9 +278,6 @@ private: // split version(s) of GetItemStateImpl for input types WhichID and Offset SfxItemState GetItemState_ForWhichID( SfxItemState eState, sal_uInt16 nWhich, bool bSrchInParent, const SfxPoolItem **ppItem) const; SfxItemState GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPoolItem **ppItem) const; - - SfxPoolItem const* implCreateItemEntry(SfxPoolItem const* pSource, sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership); - void implCleanupItemEntry(SfxPoolItem const* pSource); }; inline void SfxItemSet::SetParent( const SfxItemSet* pNew ) @@ -292,7 +297,7 @@ public: virtual std::unique_ptr<SfxItemSet> Clone( bool bItems = true, SfxItemPool *pToPool = nullptr ) const override; private: - virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bItemIsSetMember,bool bPassingOwnership ) override; + virtual const SfxPoolItem* PutImpl( const SfxPoolItem&, sal_uInt16 nWhich, bool bPassingOwnership ) override; }; diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx index 4714e2f44be6..b434302a2f85 100644 --- a/include/svl/poolitem.hxx +++ b/include/svl/poolitem.hxx @@ -100,6 +100,7 @@ enum class SfxItemState { #ifdef DBG_UTIL SVL_DLLPUBLIC size_t getAllocatedSfxPoolItemCount(); SVL_DLLPUBLIC size_t getUsedSfxPoolItemCount(); +SVL_DLLPUBLIC void listAllocatedSfxPoolItems(); #endif class SfxItemPool; @@ -108,31 +109,40 @@ typedef struct _xmlTextWriter* xmlTextWriterPtr; class SVL_DLLPUBLIC SfxPoolItem { -friend class SfxItemPool; -friend class SfxItemDisruptor_Impl; -friend class SfxItemPoolCache; -friend class SfxItemSet; + friend class SfxItemPool; + friend class SfxItemDisruptor_Impl; + friend class SfxItemPoolCache; + friend class SfxItemSet; + + // allow ItemSetTooling to access + friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem const*, sal_uInt16, bool, bool); + friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*); mutable sal_uInt32 m_nRefCount; sal_uInt16 m_nWhich; +#ifdef DBG_UTIL + // for debugging add a serial number, will be set in the constructor + // and count up from zero. If you have a deterministic error case and + // see the Item involved in the debugger you can use that number in + // the next run to see where that Item gets constructed and how it is + // involved/ processed + sal_uInt32 m_nSerialNumber; +#endif + // bitfield for flags (instead of SfxItemKind) - bool m_bIsVoidItem : 1; - bool m_bDeleteOnIdle : 1; - bool m_bStaticDefault : 1; - bool m_bPoolDefault : 1; + bool m_bIsVoidItem : 1; // bit 0 + bool m_bDeleteOnIdle : 1; // bit 1 + bool m_bStaticDefault : 1; // bit 2 + bool m_bPoolDefault : 1; // bit 3 + bool m_bRegisteredAtPool : 1; // bit 4 + bool m_bNewItemCallback : 1; // bit 5 + bool m_bIsSetItem : 1; // bit 6 protected: - // Defines if the Item can be shared/RefCounted else it will be cloned. - // Default is true - as it should be for all Items. It is needed by some - // SW items, so protected to let them set it in constructor. If this could - // be fixed at that Items we may remove this again. - bool m_bShareable : 1; - -private: #ifdef DBG_UTIL // this flag will make debugging item stuff much simpler - bool m_bDeleted : 1; + bool m_bDeleted : 1; // bit 7 #endif private: @@ -143,10 +153,13 @@ private: } protected: - void setVoidItem() { m_bIsVoidItem = true; } + void setIsVoidItem() { m_bIsVoidItem = true; } void setDeleteOnIdle() { m_bDeleteOnIdle = true; } void setStaticDefault() { m_bStaticDefault = true; } void setPoolDefault() { m_bPoolDefault = true; } + void setRegisteredAtPool(bool bNew) { m_bRegisteredAtPool = bNew; } + void setNewItemCallback() { m_bNewItemCallback = true; } + void setIsSetItem() { m_bIsSetItem = true; } public: inline void AddRef(sal_uInt32 n = 1) const @@ -156,11 +169,23 @@ public: m_nRefCount += n; } +#ifdef DBG_UTIL + sal_uInt32 getSerialNumber() const { return m_nSerialNumber; } +#endif + bool isVoidItem() const { return m_bIsVoidItem; } bool isDeleteOnIdle() const { return m_bDeleteOnIdle; } bool isStaticDefault() const { return m_bStaticDefault; } bool isPoolDefault() const { return m_bPoolDefault; } - bool isShareable() const { return m_bShareable; } + bool isRegisteredAtPool() const { return m_bRegisteredAtPool; } + bool isNewItemCallback() const { return m_bNewItemCallback; } + bool isSetItem() const { return m_bIsSetItem; } + + // version that allows nullptrs + static bool areSame(const SfxPoolItem* pItem1, const SfxPoolItem* pItem2); + + // if you have the items (not nullptrs) use this version + static bool areSame(const SfxPoolItem& rItem1, const SfxPoolItem& rItem2); private: inline sal_uInt32 ReleaseRef(sal_uInt32 n = 1) const @@ -223,24 +248,6 @@ public: bool operator!=( const SfxPoolItem& rItem ) const { return !(*this == rItem); } - // Sorting is only used for faster searching in a pool which contains large quantities - // of a single kind of pool item. - virtual bool operator<( const SfxPoolItem& ) const { assert(false); return false; } - virtual bool IsSortable() const { return false; } - - // Some item types cannot be IsSortable() (such as because they are modified while stored - // in a pool, which would change the ordering position, see e.g. 585e0ac43b9bd8a2f714903034). - // To improve performance in such cases it is possible to reimplement Lookup() to do a linear - // lookup optimized for the specific class (avoiding virtual functions may allow the compiler - // to generate better code and class-specific optimizations such as hashing or caching may - // be used.) - // If reimplemented, the Lookup() function should search [begin,end) for an item matching - // this object and return an iterator pointing to the item or the end iterator. - virtual bool HasLookup() const { return false; } - typedef std::vector<SfxPoolItem*>::const_iterator lookup_iterator; - virtual lookup_iterator Lookup(lookup_iterator /*begin*/, lookup_iterator end ) const - { assert( false ); return end; } - /** @return true if it has a valid string representation */ virtual bool GetPresentation( SfxItemPresentation ePresentation, MapUnit eCoreMetric, @@ -299,6 +306,8 @@ inline bool IsInvalidItem(const SfxPoolItem *pItem) return pItem == INVALID_POOL_ITEM; } +SVL_DLLPUBLIC bool areSfxPoolItemPtrsEqual(const SfxPoolItem* pItem1, const SfxPoolItem* pItem2); + class SVL_DLLPUBLIC SfxPoolItemHint final : public SfxHint { SfxPoolItem* pObj; diff --git a/include/svx/pageitem.hxx b/include/svx/pageitem.hxx index 32702fe8089f..de93730731d2 100644 --- a/include/svx/pageitem.hxx +++ b/include/svx/pageitem.hxx @@ -98,7 +98,7 @@ class SVX_DLLPUBLIC SvxSetItem final : public SfxSetItem { public: SvxSetItem( const TypedWhichId<SvxSetItem> nId, const SfxItemSet& rSet ); - SvxSetItem( const SvxSetItem& rItem ); + SvxSetItem( const SvxSetItem& rItem, SfxItemPool* pPool = nullptr ); SvxSetItem( const TypedWhichId<SvxSetItem> nId, SfxItemSet&& pSet ); virtual SvxSetItem* Clone( SfxItemPool *pPool = nullptr ) const override; diff --git a/include/svx/sdasitm.hxx b/include/svx/sdasitm.hxx index e53e9c3604a2..cb7230afe703 100644 --- a/include/svx/sdasitm.hxx +++ b/include/svx/sdasitm.hxx @@ -70,8 +70,6 @@ private: SdrCustomShapeGeometryItem & operator =(SdrCustomShapeGeometryItem &&) = delete; // due to SfxPoolItem virtual bool operator==( const SfxPoolItem& ) const override; - virtual bool operator<( const SfxPoolItem& ) const override; - virtual bool IsSortable() const override { return true; } virtual bool GetPresentation(SfxItemPresentation ePresentation, MapUnit eCoreMetric, MapUnit ePresentationMetric, diff --git a/include/svx/xbtmpit.hxx b/include/svx/xbtmpit.hxx index 0882081fb7ca..6d7d75f3de7c 100644 --- a/include/svx/xbtmpit.hxx +++ b/include/svx/xbtmpit.hxx @@ -41,8 +41,6 @@ public: XFillBitmapItem( const XFillBitmapItem& rItem ); virtual bool operator==( const SfxPoolItem& rItem ) const override; - // no idea why, but this item does not play nice with the sorting optimisation, get failures in sd_import_tests - virtual bool IsSortable() const override { return false; } virtual XFillBitmapItem* Clone( SfxItemPool* pPool = nullptr ) const override; virtual bool QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId = 0 ) const override; diff --git a/reportdesign/source/ui/misc/UITools.cxx b/reportdesign/source/ui/misc/UITools.cxx index 8d32c4ec1a2b..9ac14c4bc10e 100644 --- a/reportdesign/source/ui/misc/UITools.cxx +++ b/reportdesign/source/ui/misc/UITools.cxx @@ -559,67 +559,68 @@ bool openCharDialog( const uno::Reference<report::XReportControlFormat >& _rxRep // UNO->ItemSet static SfxItemInfo aItemInfos[] = { - { 0, true }, // XATTR_FILLSTYLE - { 0, true }, // XATTR_FILLCOLOR - { 0, true }, // XATTR_FILLGRADIENT - { 0, true }, // XATTR_FILLHATCH - { 0, true }, // XATTR_FILLBITMAP - { 0, true }, // XATTR_FILLTRANSPARENCE - { 0, true }, // XATTR_GRADIENTSTEPCOUNT - { 0, true }, // XATTR_FILLBMP_TILE - { 0, true }, // XATTR_FILLBMP_POS - { 0, true }, // XATTR_FILLBMP_SIZEX - { 0, true }, // XATTR_FILLBMP_SIZEY - { 0, true }, // XATTR_FILLFLOATTRANSPARENCE - { 0, true }, // XATTR_SECONDARYFILLCOLOR - { 0, true }, // XATTR_FILLBMP_SIZELOG - { 0, true }, // XATTR_FILLBMP_TILEOFFSETX - { 0, true }, // XATTR_FILLBMP_TILEOFFSETY - { 0, true }, // XATTR_FILLBMP_STRETCH - { 0, true }, // XATTR_FILLBMP_POSOFFSETX - { 0, true }, // XATTR_FILLBMP_POSOFFSETY - { 0, true }, // XATTR_FILLBACKGROUND - - { SID_ATTR_CHAR_FONT, true }, - { SID_ATTR_CHAR_FONTHEIGHT, true }, - { SID_ATTR_CHAR_LANGUAGE, true }, - { SID_ATTR_CHAR_POSTURE, true }, - { SID_ATTR_CHAR_WEIGHT, true }, - { SID_ATTR_CHAR_SHADOWED, true }, - { SID_ATTR_CHAR_WORDLINEMODE, true }, - { SID_ATTR_CHAR_CONTOUR, true }, - { SID_ATTR_CHAR_STRIKEOUT, true }, - { SID_ATTR_CHAR_UNDERLINE, true }, - { SID_ATTR_CHAR_COLOR, true }, - { SID_ATTR_CHAR_KERNING, true }, - { SID_ATTR_CHAR_CASEMAP, true }, - { SID_ATTR_CHAR_ESCAPEMENT, true }, - { SID_ATTR_CHAR_FONTLIST, true }, - { SID_ATTR_CHAR_AUTOKERN, true }, - { SID_COLOR_TABLE, true }, - { SID_ATTR_FLASH, true }, - { SID_ATTR_CHAR_EMPHASISMARK, true }, - { SID_ATTR_CHAR_TWO_LINES, true }, - { SID_ATTR_CHAR_ROTATED, true }, - { SID_ATTR_CHAR_SCALEWIDTH, true }, - { SID_ATTR_CHAR_RELIEF, true }, - { SID_ATTR_CHAR_HIDDEN, true }, - { SID_ATTR_BRUSH, true }, - { SID_ATTR_ALIGN_HOR_JUSTIFY, true }, - { SID_ATTR_ALIGN_VER_JUSTIFY, true }, + // _nSID, _bNeedsPoolRegistration, _bShareable + { 0, false, true }, // XATTR_FILLSTYLE + { 0, true, true }, // XATTR_FILLCOLOR + { 0, false, true }, // XATTR_FILLGRADIENT + { 0, false, true }, // XATTR_FILLHATCH + { 0, false, true }, // XATTR_FILLBITMAP + { 0, false, true }, // XATTR_FILLTRANSPARENCE + { 0, false, true }, // XATTR_GRADIENTSTEPCOUNT + { 0, false, true }, // XATTR_FILLBMP_TILE + { 0, false, true }, // XATTR_FILLBMP_POS + { 0, false, true }, // XATTR_FILLBMP_SIZEX + { 0, false, true }, // XATTR_FILLBMP_SIZEY + { 0, false, true }, // XATTR_FILLFLOATTRANSPARENCE + { 0, false, true }, // XATTR_SECONDARYFILLCOLOR + { 0, false, true }, // XATTR_FILLBMP_SIZELOG + { 0, false, true }, // XATTR_FILLBMP_TILEOFFSETX + { 0, false, true }, // XATTR_FILLBMP_TILEOFFSETY + { 0, false, true }, // XATTR_FILLBMP_STRETCH + { 0, false, true }, // XATTR_FILLBMP_POSOFFSETX + { 0, false, true }, // XATTR_FILLBMP_POSOFFSETY + { 0, false, true }, // XATTR_FILLBACKGROUND + + { SID_ATTR_CHAR_FONT, false, true }, + { SID_ATTR_CHAR_FONTHEIGHT, false, true }, + { SID_ATTR_CHAR_LANGUAGE, false, true }, + { SID_ATTR_CHAR_POSTURE, false, true }, + { SID_ATTR_CHAR_WEIGHT, false, true }, + { SID_ATTR_CHAR_SHADOWED, false, true }, + { SID_ATTR_CHAR_WORDLINEMODE, false, true }, + { SID_ATTR_CHAR_CONTOUR, false, true }, + { SID_ATTR_CHAR_STRIKEOUT, false, true }, + { SID_ATTR_CHAR_UNDERLINE, false, true }, + { SID_ATTR_CHAR_COLOR, false, true }, + { SID_ATTR_CHAR_KERNING, false, true }, + { SID_ATTR_CHAR_CASEMAP, false, true }, + { SID_ATTR_CHAR_ESCAPEMENT, false, true }, + { SID_ATTR_CHAR_FONTLIST, false, true }, + { SID_ATTR_CHAR_AUTOKERN, false, true }, + { SID_COLOR_TABLE, false, true }, + { SID_ATTR_FLASH, false, true }, + { SID_ATTR_CHAR_EMPHASISMARK, false, true }, + { SID_ATTR_CHAR_TWO_LINES, false, true }, + { SID_ATTR_CHAR_ROTATED, false, true }, + { SID_ATTR_CHAR_SCALEWIDTH, false, true }, + { SID_ATTR_CHAR_RELIEF, false, true }, + { SID_ATTR_CHAR_HIDDEN, false, true }, + { SID_ATTR_BRUSH, false, true }, + { SID_ATTR_ALIGN_HOR_JUSTIFY, false, true }, + { SID_ATTR_ALIGN_VER_JUSTIFY, false, true }, // Asian - { SID_ATTR_CHAR_CJK_FONT, true }, - { SID_ATTR_CHAR_CJK_FONTHEIGHT, true }, - { SID_ATTR_CHAR_CJK_LANGUAGE, true }, - { SID_ATTR_CHAR_CJK_POSTURE, true }, - { SID_ATTR_CHAR_CJK_WEIGHT, true }, + { SID_ATTR_CHAR_CJK_FONT, false, true }, + { SID_ATTR_CHAR_CJK_FONTHEIGHT, false, true }, + { SID_ATTR_CHAR_CJK_LANGUAGE, false, true }, + { SID_ATTR_CHAR_CJK_POSTURE, false, true }, + { SID_ATTR_CHAR_CJK_WEIGHT, false, true }, // Complex - { SID_ATTR_CHAR_CTL_FONT, true }, - { SID_ATTR_CHAR_CTL_FONTHEIGHT, true }, - { SID_ATTR_CHAR_CTL_LANGUAGE, true }, - { SID_ATTR_CHAR_CTL_POSTURE, true }, - { SID_ATTR_CHAR_CTL_WEIGHT, true } + { SID_ATTR_CHAR_CTL_FONT, false, true }, + { SID_ATTR_CHAR_CTL_FONTHEIGHT, false, true }, + { SID_ATTR_CHAR_CTL_LANGUAGE, false, true }, + { SID_ATTR_CHAR_CTL_POSTURE, false, true }, + { SID_ATTR_CHAR_CTL_WEIGHT, false, true } }; FontList aFontList(Application::GetDefaultDevice()); XColorListRef pColorList( XColorList::CreateStdColorList() ); diff --git a/reportdesign/source/ui/report/ReportController.cxx b/reportdesign/source/ui/report/ReportController.cxx index 69929a2d1656..351d28fc9e71 100644 --- a/reportdesign/source/ui/report/ReportController.cxx +++ b/reportdesign/source/ui/report/ReportController.cxx @@ -2331,35 +2331,36 @@ void OReportController::openPageDialog(const uno::Reference<report::XSection>& _ // UNO->ItemSet static SfxItemInfo aItemInfos[] = { - { SID_ATTR_LRSPACE, true }, - { SID_ATTR_ULSPACE, true }, - { SID_ATTR_PAGE, true }, - { SID_ATTR_PAGE_SIZE, true }, - { SID_ENUM_PAGE_MODE, true }, - { SID_PAPER_START, true }, - { SID_PAPER_END, true }, - { SID_ATTR_BRUSH, true }, - { 0, true }, // XATTR_FILLSTYLE - { 0, true }, // XATTR_FILLCOLOR - { 0, true }, // XATTR_FILLGRADIENT - { 0, true }, // XATTR_FILLHATCH - { 0, true }, // XATTR_FILLBITMAP - { 0, true }, // XATTR_FILLTRANSPARENCE - { 0, true }, // XATTR_GRADIENTSTEPCOUNT - { 0, true }, // XATTR_FILLBMP_TILE - { 0, true }, // XATTR_FILLBMP_POS - { 0, true }, // XATTR_FILLBMP_SIZEX - { 0, true }, // XATTR_FILLBMP_SIZEY - { 0, true }, // XATTR_FILLFLOATTRANSPARENCE - { 0, true }, // XATTR_SECONDARYFILLCOLOR - { 0, true }, // XATTR_FILLBMP_SIZELOG - { 0, true }, // XATTR_FILLBMP_TILEOFFSETX - { 0, true }, // XATTR_FILLBMP_TILEOFFSETY - { 0, true }, // XATTR_FILLBMP_STRETCH - { 0, true }, // XATTR_FILLBMP_POSOFFSETX - { 0, true }, // XATTR_FILLBMP_POSOFFSETY - { 0, true }, // XATTR_FILLBACKGROUND - { SID_ATTR_METRIC, true } + // _nSID, _bNeedsPoolRegistration, _bShareable + { SID_ATTR_LRSPACE, false, true }, + { SID_ATTR_ULSPACE, false, true }, + { SID_ATTR_PAGE, false, true }, + { SID_ATTR_PAGE_SIZE, false, true }, + { SID_ENUM_PAGE_MODE, false, true }, + { SID_PAPER_START, false, true }, + { SID_PAPER_END, false, true }, + { SID_ATTR_BRUSH, false, true }, + { 0, false, true }, // XATTR_FILLSTYLE + { 0, true, true }, // XATTR_FILLCOLOR + { 0, false, true }, // XATTR_FILLGRADIENT + { 0, false, true }, // XATTR_FILLHATCH + { 0, false, true }, // XATTR_FILLBITMAP + { 0, false, true }, // XATTR_FILLTRANSPARENCE + { 0, false, true }, // XATTR_GRADIENTSTEPCOUNT + { 0, false, true }, // XATTR_FILLBMP_TILE + { 0, false, true }, // XATTR_FILLBMP_POS + { 0, false, true }, // XATTR_FILLBMP_SIZEX + { 0, false, true }, // XATTR_FILLBMP_SIZEY + { 0, false, true }, // XATTR_FILLFLOATTRANSPARENCE + { 0, false, true }, // XATTR_SECONDARYFILLCOLOR + { 0, false, true }, // XATTR_FILLBMP_SIZELOG + { 0, false, true }, // XATTR_FILLBMP_TILEOFFSETX + { 0, false, true }, // XATTR_FILLBMP_TILEOFFSETY + { 0, false, true }, // XATTR_FILLBMP_STRETCH + { 0, false, true }, // XATTR_FILLBMP_POSOFFSETX + { 0, false, true }, // XATTR_FILLBMP_POSOFFSETY + { 0, false, true }, // XATTR_FILLBACKGROUND + { SID_ATTR_METRIC, false, true } }; MeasurementSystem eSystem = SvtSysLocale().GetLocaleData().getMeasurementSystemEnum(); @@ -4189,7 +4190,8 @@ void OReportController::openZoomDialog() static SfxItemInfo aItemInfos[] = { - { SID_ATTR_ZOOM, true } + // _nSID, _bNeedsPoolRegistration, _bShareable + { SID_ATTR_ZOOM, false, true } }; std::vector<SfxPoolItem*> pDefaults { diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index 521f3b7bb1d6..0d2457c0db25 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -84,7 +84,7 @@ struct ScAttrEntry const ScPatternAttr* pPattern; bool operator==( const ScAttrEntry& other ) const { - return nEndRow == other.nEndRow && pPattern == other.pPattern; + return nEndRow == other.nEndRow && SfxPoolItem::areSame(pPattern, other.pPattern); } }; diff --git a/sc/inc/attrib.hxx b/sc/inc/attrib.hxx index dc394dfb1c08..ec004f37d8b6 100644 --- a/sc/inc/attrib.hxx +++ b/sc/inc/attrib.hxx @@ -280,8 +280,6 @@ public: virtual ~ScCondFormatItem() override; virtual bool operator==(const SfxPoolItem& rCmp ) const override; - virtual bool operator<(const SfxPoolItem& rCmp) const override; - virtual bool IsSortable() const override { return true; } virtual ScCondFormatItem* Clone( SfxItemPool* = nullptr ) const override; const ScCondFormatIndexes& GetCondFormatData() const { return maIndex;} diff --git a/sc/inc/docpool.hxx b/sc/inc/docpool.hxx index 9280fb3602b0..c73d034f2fb2 100644 --- a/sc/inc/docpool.hxx +++ b/sc/inc/docpool.hxx @@ -47,7 +47,8 @@ public: OUString& rText, const IntlWrapper& rIntl ) const override; private: - virtual const SfxPoolItem& PutImpl( const SfxPoolItem&, sal_uInt16 nWhich = 0, bool bPassingOwnership = false ) override; + virtual void newItem_Callback(const SfxPoolItem& rItem) const override; + virtual bool newItem_UseDirect(const SfxPoolItem& rItem) const override; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx index eacb69fd640b..b5deb19826d9 100644 --- a/sc/inc/patattr.hxx +++ b/sc/inc/patattr.hxx @@ -56,7 +56,7 @@ class SC_DLLPUBLIC ScPatternAttr final : public SfxSetItem mutable std::optional<sal_uInt32> mxHashCode; mutable std::optional<bool> mxVisible; ScStyleSheet* pStyle; - sal_uInt64 mnKey; + sal_uInt64 mnPAKey; public: ScPatternAttr(SfxItemSet&& pItemSet, const OUString& rStyleName); ScPatternAttr(SfxItemSet&& pItemSet); @@ -66,9 +66,6 @@ public: virtual ScPatternAttr* Clone( SfxItemPool *pPool = nullptr ) const override; virtual bool operator==(const SfxPoolItem& rCmp) const override; - // Class cannot be IsSortable() because it's mutable, implement at least Lookup(). - virtual bool HasLookup() const override { return true; } - virtual lookup_iterator Lookup(lookup_iterator begin, lookup_iterator end ) const override; const SfxPoolItem& GetItem( sal_uInt16 nWhichP ) const { return GetItemSet().Get(nWhichP); } @@ -181,8 +178,8 @@ public: Degree100 GetRotateVal( const SfxItemSet* pCondSet ) const; ScRotateDir GetRotateDir( const SfxItemSet* pCondSet ) const; - void SetKey(sal_uInt64 nKey); - sal_uInt64 GetKey() const; + void SetPAKey(sal_uInt64 nKey); + sal_uInt64 GetPAKey() const; static std::optional<bool> FastEqualPatternSets( const SfxItemSet& rSet1, const SfxItemSet& rSet2 ); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index c7bfc3eb8198..a3e2d2ddd567 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -1211,7 +1211,7 @@ CPPUNIT_TEST_FIXTURE(Test, testHorizontalAttrIterator) size_t nCheckPos = 0; for (const ScPatternAttr* pAttr = aIter.GetNext(nCol1, nCol2, nRow); pAttr; pAttr = aIter.GetNext(nCol1, nCol2, nRow)) { - if( pAttr == m_pDoc->GetDefPattern()) + if (SfxPoolItem::areSame( pAttr, m_pDoc->GetDefPattern())) continue; CPPUNIT_ASSERT_MESSAGE("Iteration longer than expected.", nCheckPos < nCheckLen); CPPUNIT_ASSERT_EQUAL(aChecks[nCheckPos][0], static_cast<int>(nCol1)); @@ -1302,7 +1302,7 @@ CPPUNIT_TEST_FIXTURE(Test, testIteratorsDefPattern) CPPUNIT_ASSERT_EQUAL(SCCOL(102 + 1), m_pDoc->GetAllocatedColumnsCount(0)); const ScPatternAttr* pattern = m_pDoc->GetPattern(100, 0, 0); const ScPatternAttr* defPattern = m_pDoc->GetDefPattern(); - CPPUNIT_ASSERT(pattern != defPattern); + CPPUNIT_ASSERT(!SfxPoolItem::areSame(pattern, defPattern)); CPPUNIT_ASSERT_EQUAL(pattern, m_pDoc->GetPattern(102, 0, 0)); CPPUNIT_ASSERT_EQUAL(defPattern, m_pDoc->GetPattern(101, 0, 0)); CPPUNIT_ASSERT_EQUAL(defPattern, m_pDoc->GetPattern(103, 0, 0)); diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index b6d062b93d66..3e56226f3704 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -63,7 +63,7 @@ ScAttrArray::ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument& rDoc, ScAttr { mvData[nIdx].nEndRow = pDefaultColAttrArray->mvData[nIdx].nEndRow; ScPatternAttr aNewPattern( *(pDefaultColAttrArray->mvData[nIdx].pPattern) ); - mvData[nIdx].pPattern = &rDocument.GetPool()->Put( aNewPattern ); + mvData[nIdx].pPattern = &rDocument.GetPool()->DirectPutItemInPool( aNewPattern ); bool bNumFormatChanged = false; if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged, mvData[nIdx].pPattern->GetItemSet(), rDocument.GetDefPattern()->GetItemSet() ) ) @@ -83,7 +83,7 @@ ScAttrArray::~ScAttrArray() ScDocumentPool* pDocPool = rDocument.GetPool(); for (auto const & rEntry : mvData) - pDocPool->Remove(*rEntry.pPattern); + pDocPool->DirectRemoveItemFromPool(*rEntry.pPattern); } #if DEBUG_SC_TESTATTRARRAY @@ -140,14 +140,14 @@ void ScAttrArray::Reset( const ScPatternAttr* pPattern ) rDocument.InvalidateTextWidth( &aAdrStart, &aAdrEnd, bNumFormatChanged ); } } - pDocPool->Remove(*pOldPattern); + pDocPool->DirectRemoveItemFromPool(*pOldPattern); } mvData.resize(0); rDocument.SetStreamValid(nTab, false); mvData.resize(1); - const ScPatternAttr* pNewPattern = &pDocPool->Put(*pPattern); + const ScPatternAttr* pNewPattern = &pDocPool->DirectPutItemInPool(*pPattern); mvData[0].nEndRow = rDocument.MaxRow(); mvData[0].pPattern = pNewPattern; } @@ -159,10 +159,10 @@ bool ScAttrArray::Concat(SCSIZE nPos) { if (nPos > 0) { - if (mvData[nPos - 1].pPattern == mvData[nPos].pPattern) + if (SfxPoolItem::areSame(mvData[nPos - 1].pPattern, mvData[nPos].pPattern)) { mvData[nPos - 1].nEndRow = mvData[nPos].nEndRow; - rDocument.GetPool()->Remove(*mvData[nPos].pPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); mvData.erase(mvData.begin() + nPos); nPos--; bRet = true; @@ -170,10 +170,10 @@ bool ScAttrArray::Concat(SCSIZE nPos) } if (nPos + 1 < mvData.size()) { - if (mvData[nPos + 1].pPattern == mvData[nPos].pPattern) + if (SfxPoolItem::areSame(mvData[nPos + 1].pPattern, mvData[nPos].pPattern)) { mvData[nPos].nEndRow = mvData[nPos + 1].nEndRow; - rDocument.GetPool()->Remove(*mvData[nPos].pPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); mvData.erase(mvData.begin() + nPos + 1); bRet = true; } @@ -459,9 +459,9 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd if (bPutToPool) { if (bPassingOwnership) - pPattern = &rDocument.GetPool()->Put(std::unique_ptr<ScPatternAttr>(const_cast<ScPatternAttr*>(pPattern))); + pPattern = &rDocument.GetPool()->DirectPutItemInPool(std::unique_ptr<ScPatternAttr>(const_cast<ScPatternAttr*>(pPattern))); else - pPattern = &rDocument.GetPool()->Put(*pPattern); + pPattern = &rDocument.GetPool()->DirectPutItemInPool(*pPattern); } if ((nStartRow == 0) && (nEndRow == rDocument.MaxRow())) Reset(pPattern); @@ -520,7 +520,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd if ( nStartRow > 0 ) { nInsert = rDocument.MaxRow() + 1; - if ( mvData[ni].pPattern != pPattern ) + if ( !SfxPoolItem::areSame(mvData[ni].pPattern, pPattern ) ) { if ( ni == 0 || (mvData[ni-1].nEndRow < nStartRow - 1) ) { // may be a split or a simple insert or just a shrink, @@ -533,7 +533,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd else if (mvData[ni - 1].nEndRow == nStartRow - 1) nInsert = ni; } - if ( ni > 0 && mvData[ni-1].pPattern == pPattern ) + if ( ni > 0 && SfxPoolItem::areSame(mvData[ni-1].pPattern, pPattern) ) { // combine mvData[ni-1].nEndRow = nEndRow; nInsert = rDocument.MaxRow() + 1; @@ -548,11 +548,11 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd nj++; if ( !bSplit ) { - if ( nj < mvData.size() && mvData[nj].pPattern == pPattern ) + if ( nj < mvData.size() && SfxPoolItem::areSame(mvData[nj].pPattern, pPattern ) ) { // combine if ( ni > 0 ) { - if ( mvData[ni-1].pPattern == pPattern ) + if ( SfxPoolItem::areSame(mvData[ni-1].pPattern, pPattern ) ) { // adjacent entries mvData[ni-1].nEndRow = mvData[nj].nEndRow; nj++; @@ -569,13 +569,13 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd ScDocumentPool* pDocPool = rDocument.GetPool(); if ( bSplit ) { // duplicate split entry in pool - pDocPool->Put( *mvData[ni-1].pPattern ); + pDocPool->DirectPutItemInPool( *mvData[ni-1].pPattern ); } if ( ni < nj ) { // remove middle entries for ( SCSIZE nk=ni; nk<nj; nk++) { // remove entries from pool - pDocPool->Remove( *mvData[nk].pPattern ); + pDocPool->DirectRemoveItemFromPool( *mvData[nk].pPattern ); } if ( !bCombined ) { // replace one entry @@ -681,8 +681,8 @@ void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, const ScStyleS } } - rDocument.GetPool()->Remove(*mvData[nPos].pPattern); - mvData[nPos].pPattern = &rDocument.GetPool()->Put(*pNewPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); + mvData[nPos].pPattern = &rDocument.GetPool()->DirectPutItemInPool(*pNewPattern); if (Concat(nPos)) Search(nStart, nPos); else @@ -818,9 +818,9 @@ void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow, else { // remove from pool ? - rDocument.GetPool()->Remove(*mvData[nPos].pPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); mvData[nPos].pPattern = - &rDocument.GetPool()->Put(std::move(pNewPattern)); + &rDocument.GetPool()->DirectPutItemInPool(std::move(pNewPattern)); if (Concat(nPos)) Search(nStart, nPos); @@ -862,7 +862,7 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCac { const ScPatternAttr* pOldPattern = mvData[nPos].pPattern; const ScPatternAttr* pNewPattern = static_cast<const ScPatternAttr*>( &pCache->ApplyTo( *pOldPattern ) ); - if (pNewPattern != pOldPattern) + if (!SfxPoolItem::areSame(pNewPattern, pOldPattern)) { SCROW nY1 = nStart; SCROW nY2 = mvData[nPos].nEndRow; @@ -897,7 +897,7 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCac } } - rDocument.GetPool()->Remove(*mvData[nPos].pPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); mvData[nPos].pPattern = pNewPattern; if (Concat(nPos)) Search(nStart, nPos); @@ -924,7 +924,7 @@ void ScAttrArray::SetAttrEntries(std::vector<ScAttrEntry> && vNewData) { ScDocumentPool* pDocPool = rDocument.GetPool(); for (auto const & rEntry : mvData) - pDocPool->Remove(*rEntry.pPattern); + pDocPool->DirectRemoveItemFromPool(*rEntry.pPattern); mvData = std::move(vNewData); @@ -961,7 +961,7 @@ static void lcl_MergeDeep( SfxItemSet& rMergeSet, const SfxItemSet& rSource ) SfxItemState eNewState = rSource.GetItemState( nId, true, &pNewItem ); if ( eNewState == SfxItemState::SET ) { - if ( pNewItem != pOldItem ) // Both pulled + if ( !SfxPoolItem::areSame(pNewItem, pOldItem) ) // Both pulled rMergeSet.InvalidateItem( nId ); } else // Default @@ -996,7 +996,7 @@ void ScAttrArray::MergePatternArea( SCROW nStartRow, SCROW nEndRow, pPattern = mvData[nPos].pPattern; else pPattern = rDocument.GetDefPattern(); - if ( pPattern != rState.pOld1 && pPattern != rState.pOld2 ) + if ( !SfxPoolItem::areSame(pPattern, rState.pOld1) && !SfxPoolItem::areSame(pPattern, rState.pOld2) ) { const SfxItemSet& rThisSet = pPattern->GetItemSet(); if (rState.pItemSet) @@ -1012,7 +1012,7 @@ void ScAttrArray::MergePatternArea( SCROW nStartRow, SCROW nEndRow, // first pattern - copied from parent rState.pItemSet.emplace( *rThisSet.GetPool(), rThisSet.GetRanges() ); rState.pItemSet->Set( rThisSet, bDeep ); - rState.mnPatternId = pPattern->GetKey(); + rState.mnPatternId = pPattern->GetPAKey(); } rState.pOld2 = rState.pOld1; @@ -1585,7 +1585,7 @@ void ScAttrArray::SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow, while ( nThisRow <= nEndRow ) { pOldPattern = mvData[nIndex].pPattern; - if (pOldPattern != pWantedPattern) // FIXME: else-branch? + if (!SfxPoolItem::areSame(pOldPattern, pWantedPattern)) // FIXME: else-branch? { if (nThisRow < nStartRow) nThisRow = nStartRow; nRow = mvData[nIndex].nEndRow; @@ -1610,7 +1610,7 @@ void ScAttrArray::SetPatternAreaSafe( SCROW nStartRow, SCROW nEndRow, bFirstUse = false; else // it's in the pool - rDocument.GetPool()->Put( *pWantedPattern ); + rDocument.GetPool()->DirectPutItemInPool( *pWantedPattern ); } SetPatternArea( nThisRow, nAttrRow, pWantedPattern ); } @@ -1843,13 +1843,13 @@ void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBo if (bReset) { ScPatternAttr aNewPattern(*mvData[nPos].pPattern); - rDocument.GetPool()->Remove(*mvData[nPos].pPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern); aNewPattern.SetStyleSheet( static_cast<ScStyleSheet*>( rDocument.GetStyleSheetPool()-> Find( ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para, SfxStyleSearchBits::Auto | SfxStyleSearchBits::ScStandard ) ) ); - mvData[nPos].pPattern = &rDocument.GetPool()->Put(aNewPattern); + mvData[nPos].pPattern = &rDocument.GetPool()->DirectPutItemInPool(aNewPattern); if (Concat(nPos)) { @@ -1904,7 +1904,7 @@ bool ScAttrArray::IsEmpty() const if (mvData.size() == 1) { - return mvData[0].pPattern == rDocument.GetDefPattern(); + return SfxPoolItem::areSame(mvData[0].pPattern, rDocument.GetDefPattern()); } else return false; @@ -2043,7 +2043,7 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther, { const ScPatternAttr* pDefPattern1 = rDocument.GetDefPattern(); const ScPatternAttr* pDefPattern2 = rOther.rDocument.GetDefPattern(); - return ( pDefPattern1 == pDefPattern2 || pDefPattern1->IsVisibleEqual( *pDefPattern2 ) ); + return ( SfxPoolItem::areSame(pDefPattern1, pDefPattern2) || pDefPattern1->IsVisibleEqual( *pDefPattern2 ) ); } { @@ -2073,7 +2073,7 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther, while ( nPos < pNonDefault->Count() && bEqual ) { const ScPatternAttr* pNonDefPattern = pNonDefault->mvData[nPos].pPattern; - bEqual = ( pNonDefPattern == pDefPattern || + bEqual = ( SfxPoolItem::areSame(pNonDefPattern, pDefPattern) || pNonDefPattern->IsVisibleEqual( *pDefPattern ) ); if ( pNonDefault->mvData[nPos].nEndRow >= nEndRow ) break; @@ -2098,7 +2098,7 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& rOther, SCROW nOtherRow = rOther.mvData[nOtherPos].nEndRow; const ScPatternAttr* pThisPattern = mvData[nThisPos].pPattern; const ScPatternAttr* pOtherPattern = rOther.mvData[nOtherPos].pPattern; - bEqual = ( pThisPattern == pOtherPattern || + bEqual = ( SfxPoolItem::areSame(pThisPattern, pOtherPattern) || pThisPattern->IsVisibleEqual(*pOtherPattern) ); if ( nThisRow >= nOtherRow ) @@ -2123,7 +2123,7 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW { const ScPatternAttr* pDefPattern1 = rDocument.GetDefPattern(); const ScPatternAttr* pDefPattern2 = rOther.rDocument.GetDefPattern(); - return ( pDefPattern1 == pDefPattern2 ); + return SfxPoolItem::areSame(pDefPattern1, pDefPattern2); } { @@ -2153,7 +2153,7 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW while ( nPos < pNonDefault->Count() && bEqual ) { const ScPatternAttr* pNonDefPattern = pNonDefault->mvData[nPos].pPattern; - bEqual = ( pNonDefPattern == pDefPattern ); + bEqual = SfxPoolItem::areSame( pNonDefPattern, pDefPattern ); if ( pNonDefault->mvData[nPos].nEndRow >= nEndRow ) break; ++nPos; @@ -2177,7 +2177,7 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, SCROW nStartRow, SCROW SCROW nOtherRow = rOther.mvData[nOtherPos].nEndRow; const ScPatternAttr* pThisPattern = mvData[nThisPos].pPattern; const ScPatternAttr* pOtherPattern = rOther.mvData[nOtherPos].pPattern; - bEqual = ( pThisPattern == pOtherPattern ); + bEqual = SfxPoolItem::areSame( pThisPattern, pOtherPattern ); if ( nThisRow >= nOtherRow ) { @@ -2323,7 +2323,7 @@ void ScAttrArray::DeleteRow( SCROW nStartRow, SCSIZE nSize ) { DeleteRange( nStartIndex, nEndIndex ); if (nStartIndex > 0) - if ( mvData[nStartIndex-1].pPattern == mvData[nStartIndex].pPattern ) + if ( SfxPoolItem::areSame( mvData[nStartIndex-1].pPattern, mvData[nStartIndex].pPattern ) ) DeleteRange( nStartIndex-1, nStartIndex-1 ); } } @@ -2341,7 +2341,7 @@ void ScAttrArray::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex ) SetDefaultIfNotInit(); ScDocumentPool* pDocPool = rDocument.GetPool(); for (SCSIZE i = nStartIndex; i <= nEndIndex; i++) - pDocPool->Remove(*mvData[i].pPattern); + pDocPool->DirectRemoveItemFromPool(*mvData[i].pPattern); mvData.erase(mvData.begin() + nStartIndex, mvData.begin() + nEndIndex + 1); } @@ -2468,14 +2468,14 @@ void ScAttrArray::CopyArea( aTmpPattern.GetItemSet().ClearItem( ATTR_MERGE_FLAG ); if (bSamePool) - pNewPattern = &pDestDocPool->Put(aTmpPattern); + pNewPattern = &pDestDocPool->DirectPutItemInPool(aTmpPattern); else pNewPattern = aTmpPattern.PutInPool( &rAttrArray.rDocument, &rDocument ); } else { if (bSamePool) - pNewPattern = &pDestDocPool->Put(*pOldPattern); + pNewPattern = &pDestDocPool->DirectPutItemInPool(*pOldPattern); else pNewPattern = pOldPattern->PutInPool( &rAttrArray.rDocument, &rDocument ); } @@ -2516,7 +2516,7 @@ void ScAttrArray::CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, tools::Long nDy, { const ScPatternAttr* pNewPattern; if (bSamePool) - pNewPattern = &pDestDocPool->Put(*rDocument.GetDefPattern()); + pNewPattern = &pDestDocPool->DirectPutItemInPool(*rDocument.GetDefPattern()); else pNewPattern = rDocument.GetDefPattern()->PutInPool( &rAttrArray.rDocument, &rDocument ); @@ -2533,7 +2533,7 @@ void ScAttrArray::CopyAreaSafe( SCROW nStartRow, SCROW nEndRow, tools::Long nDy, const ScPatternAttr* pNewPattern; if (bSamePool) - pNewPattern = &pDestDocPool->Put(*pOldPattern); + pNewPattern = &pDestDocPool->DirectPutItemInPool(*pOldPattern); else pNewPattern = pOldPattern->PutInPool( &rAttrArray.rDocument, &rDocument ); diff --git a/sc/source/core/data/attrib.cxx b/sc/source/core/data/attrib.cxx index efe494c316a5..1a587d2b6572 100644 --- a/sc/source/core/data/attrib.cxx +++ b/sc/source/core/data/attrib.cxx @@ -733,21 +733,6 @@ bool ScCondFormatItem::operator==( const SfxPoolItem& rCmp ) const && memcmp(&maIndex.front(), &other.maIndex.front(), maIndex.size() * sizeof(sal_uInt32)) == 0; } -bool ScCondFormatItem::operator<( const SfxPoolItem& rCmp ) const -{ - auto const & other = static_cast<const ScCondFormatItem&>(rCmp); - if ( maIndex.size() < other.maIndex.size() ) - return true; - if ( maIndex.size() > other.maIndex.size() ) - return false; - if (maIndex.empty() && other.maIndex.empty()) - return false; - // memcmp is faster than operator< on std::vector - // Note that on little-endian this results in a confusing ordering (256 < 1), - // which technically doesn't matter as the ordering may be arbitrary. - return memcmp(&maIndex.front(), &other.maIndex.front(), maIndex.size() * sizeof(sal_uInt32)) < 0; -} - ScCondFormatItem* ScCondFormatItem::Clone(SfxItemPool*) const { return new ScCondFormatItem(maIndex); diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 7ffd5ae9c735..c448f79ae996 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -476,7 +476,7 @@ void ScColumn::ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr ) const ScPatternAttr* pNewPattern = static_cast<const ScPatternAttr*>( &aCache.ApplyTo( *pPattern ) ); - if (pNewPattern != pPattern) + if (!SfxPoolItem::areSame(pNewPattern, pPattern)) pAttrArray->SetPattern( nRow, pNewPattern ); } @@ -628,12 +628,12 @@ void ScColumn::ApplyAttr( SCROW nRow, const SfxPoolItem& rAttr ) const ScPatternAttr* pOldPattern = pAttrArray->GetPattern( nRow ); ScPatternAttr aTemp(*pOldPattern); aTemp.GetItemSet().Put(rAttr); - const ScPatternAttr* pNewPattern = &pDocPool->Put( aTemp ); + const ScPatternAttr* pNewPattern = &pDocPool->DirectPutItemInPool( aTemp ); - if ( pNewPattern != pOldPattern ) + if (!SfxPoolItem::areSame( pNewPattern, pOldPattern )) pAttrArray->SetPattern( nRow, pNewPattern ); else - pDocPool->Remove( *pNewPattern ); // free up resources + pDocPool->DirectRemoveItemFromPool( *pNewPattern ); // free up resources } ScRefCellValue ScColumn::GetCellValue( SCROW nRow ) const diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx index e7ca588a0b34..28d928cacea1 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -203,7 +203,7 @@ tools::Long ScColumn::GetNeededSize( } if (bNumeric) { - if (!bMayInvalidatePattern || pPattern == pOldPattern) + if (!bMayInvalidatePattern || SfxPoolItem::areSame(pPattern, pOldPattern)) bBreak = false; else { @@ -772,7 +772,7 @@ sal_uInt16 ScColumn::GetOptimalColWidth( // Or again in case there was a leading sep=";" row or two header // rows.. const ScPatternAttr* pNextPattern = GetPattern( ++nRow ); - if (pNextPattern != pPattern) + if (!SfxPoolItem::areSame(pNextPattern, pPattern)) nFormat = pNextPattern->GetNumberFormat( pFormatter ); } OUString aLongStr; @@ -830,7 +830,7 @@ sal_uInt16 ScColumn::GetOptimalColWidth( const ScPatternAttr* pPattern = GetPattern(nRow); aOptions.pPattern = pPattern; - aOptions.bGetFont = (pPattern != pOldPattern || nScript != SvtScriptType::NONE); + aOptions.bGetFont = (!SfxPoolItem::areSame(pPattern, pOldPattern) || nScript != SvtScriptType::NONE); pOldPattern = pPattern; sal_uInt16 nThis = static_cast<sal_uInt16>(GetNeededSize( nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, true, aOptions, &pOldPattern)); @@ -1079,7 +1079,7 @@ void ScColumn::GetOptimalHeight( if (nHeight > rHeights.GetValue(nRow)) rHeights.SetValue(nRow, nRow, nHeight); // Pattern changed due to calculation? => sync. - if (pPattern != pOldPattern) + if (!SfxPoolItem::areSame(pPattern, pOldPattern)) { pPattern = aIter.Resync( nRow, nStart, nEnd); nNextEnd = 0; diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx index 8e22b13a8e1e..324e54be2a92 100644 --- a/sc/source/core/data/column4.cxx +++ b/sc/source/core/data/column4.cxx @@ -1248,10 +1248,10 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern ) { const ScPatternAttr* pPat1 = GetPattern(nRow); const ScPatternAttr* pPat2 = rOther.GetPattern(nRow); - if (pPat1 != pPat2) + if (!SfxPoolItem::areSame(pPat1, pPat2)) { if (pPat1->GetRefCount() == 1) - pPat1 = &rOther.GetDoc().GetPool()->Put(*pPat1); + pPat1 = &rOther.GetDoc().GetPool()->DirectPutItemInPool(*pPat1); SetPattern(nRow, *pPat2); rOther.SetPattern(nRow, *pPat1); } diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index 5c0f0984b308..35c0d2caa8fd 100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -1424,7 +1424,7 @@ void ScHorizontalAttrIterator::InitForNextRow(bool bInitialization) nMinNextEnd = pNextEnd[nPos]; // store positions of ScHorizontalAttrIterator elements (minimizing expensive ScPatternAttr comparisons) - if (i > nStartCol && ppPatterns[nThisHead] != ppPatterns[nPos]) + if (i > nStartCol && !SfxPoolItem::areSame(ppPatterns[nThisHead], ppPatterns[nPos])) { pHorizEnd[nThisHead] = i - 1; nThisHead = nPos; // start position of the next horizontal group diff --git a/sc/source/core/data/docpool.cxx b/sc/source/core/data/docpool.cxx index 47c485e4f139..05dd88958288 100644 --- a/sc/source/core/data/docpool.cxx +++ b/sc/source/core/data/docpool.cxx @@ -88,96 +88,97 @@ SvxFontItem* getDefaultFontItem(LanguageType eLang, DefaultFontType nFontType, s SfxItemInfo const aItemInfos[] = { - { SID_ATTR_CHAR_FONT, true }, // ATTR_FONT - { SID_ATTR_CHAR_FONTHEIGHT, true }, // ATTR_FONT_HEIGHT - { SID_ATTR_CHAR_WEIGHT, true }, // ATTR_FONT_WEIGHT - { SID_ATTR_CHAR_POSTURE, true }, // ATTR_FONT_POSTURE - { SID_ATTR_CHAR_UNDERLINE, true }, // ATTR_FONT_UNDERLINE - { SID_ATTR_CHAR_OVERLINE, true }, // ATTR_FONT_OVERLINE - { SID_ATTR_CHAR_STRIKEOUT, true }, // ATTR_FONT_CROSSEDOUT - { SID_ATTR_CHAR_CONTOUR, true }, // ATTR_FONT_CONTOUR - { SID_ATTR_CHAR_SHADOWED, true }, // ATTR_FONT_SHADOWED - { SID_ATTR_CHAR_COLOR, true }, // ATTR_FONT_COLOR - { SID_ATTR_CHAR_LANGUAGE, true }, // ATTR_FONT_LANGUAGE - { SID_ATTR_CHAR_CJK_FONT, true }, // ATTR_CJK_FONT from 614 - { SID_ATTR_CHAR_CJK_FONTHEIGHT, true }, // ATTR_CJK_FONT_HEIGHT from 614 - { SID_ATTR_CHAR_CJK_WEIGHT, true }, // ATTR_CJK_FONT_WEIGHT from 614 - { SID_ATTR_CHAR_CJK_POSTURE, true }, // ATTR_CJK_FONT_POSTURE from 614 - { SID_ATTR_CHAR_CJK_LANGUAGE, true }, // ATTR_CJK_FONT_LANGUAGE from 614 - { SID_ATTR_CHAR_CTL_FONT, true }, // ATTR_CTL_FONT from 614 - { SID_ATTR_CHAR_CTL_FONTHEIGHT, true }, // ATTR_CTL_FONT_HEIGHT from 614 - { SID_ATTR_CHAR_CTL_WEIGHT, true }, // ATTR_CTL_FONT_WEIGHT from 614 - { SID_ATTR_CHAR_CTL_POSTURE, true }, // ATTR_CTL_FONT_POSTURE from 614 - { SID_ATTR_CHAR_CTL_LANGUAGE, true }, // ATTR_CTL_FONT_LANGUAGE from 614 - { SID_ATTR_CHAR_EMPHASISMARK, true }, // ATTR_FONT_EMPHASISMARK from 614 - { 0, true }, // ATTR_USERDEF from 614 / 641c - { SID_ATTR_CHAR_WORDLINEMODE, true }, // ATTR_FONT_WORDLINE from 632b - { SID_ATTR_CHAR_RELIEF, true }, // ATTR_FONT_RELIEF from 632b - { SID_ATTR_ALIGN_HYPHENATION, true }, // ATTR_HYPHENATE from 632b - { 0, true }, // ATTR_SCRIPTSPACE from 614d - { 0, true }, // ATTR_HANGPUNCTUATION from 614d - { SID_ATTR_PARA_FORBIDDEN_RULES,true }, // ATTR_FORBIDDEN_RULES from 614d - { SID_ATTR_ALIGN_HOR_JUSTIFY, true }, // ATTR_HOR_JUSTIFY - { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, true }, // ATTR_HOR_JUSTIFY_METHOD - { SID_ATTR_ALIGN_INDENT, true }, // ATTR_INDENT from 350 - { SID_ATTR_ALIGN_VER_JUSTIFY, true }, // ATTR_VER_JUSTIFY - { SID_ATTR_ALIGN_VER_JUSTIFY_METHOD, true }, // ATTR_VER_JUSTIFY_METHOD - { SID_ATTR_ALIGN_STACKED, true }, // ATTR_STACKED from 680/dr14 (replaces ATTR_ORIENTATION) - { SID_ATTR_ALIGN_DEGREES, true }, // ATTR_ROTATE_VALUE from 367 - { SID_ATTR_ALIGN_LOCKPOS, true }, // ATTR_ROTATE_MODE from 367 - { SID_ATTR_ALIGN_ASIANVERTICAL, true }, // ATTR_VERTICAL_ASIAN from 642 - { SID_ATTR_FRAMEDIRECTION, true }, // ATTR_WRITINGDIR from 643 - { SID_ATTR_ALIGN_LINEBREAK, true }, // ATTR_LINEBREAK - { SID_ATTR_ALIGN_SHRINKTOFIT, true }, // ATTR_SHRINKTOFIT from 680/dr14 - { SID_ATTR_BORDER_DIAG_TLBR, true }, // ATTR_BORDER_TLBR from 680/dr14 - { SID_ATTR_BORDER_DIAG_BLTR, true }, // ATTR_BORDER_BLTR from 680/dr14 - { SID_ATTR_ALIGN_MARGIN, true }, // ATTR_MARGIN - { 0, true }, // ATTR_MERGE - { 0, true }, // ATTR_MERGE_FLAG - { SID_ATTR_NUMBERFORMAT_VALUE, true }, // ATTR_VALUE_FORMAT - { 0, true }, // ATTR_LANGUAGE_FORMAT from 329, is combined with SID_ATTR_NUMBERFORMAT_VALUE in the dialog - { SID_ATTR_BRUSH, true }, // ATTR_BACKGROUND - { SID_SCATTR_PROTECTION, true }, // ATTR_PROTECTION - { SID_ATTR_BORDER_OUTER, true }, // ATTR_BORDER - { SID_ATTR_BORDER_INNER, true }, // ATTR_BORDER_INNER - { SID_ATTR_BORDER_SHADOW, true }, // ATTR_SHADOW - { 0, true }, // ATTR_VALIDDATA - { 0, true }, // ATTR_CONDITIONAL - { 0, true }, // ATTR_HYPERLINK - { 0, true }, // ATTR_PATTERN - { SID_ATTR_LRSPACE, true }, // ATTR_LRSPACE - { SID_ATTR_ULSPACE, true }, // ATTR_ULSPACE - { SID_ATTR_PAGE, true }, // ATTR_PAGE - { SID_ATTR_PAGE_PAPERBIN, true }, // ATTR_PAGE_PAPERBIN - { SID_ATTR_PAGE_SIZE, true }, // ATTR_PAGE_SIZE - { SID_ATTR_PAGE_EXT1, true }, // ATTR_PAGE_HORCENTER - { SID_ATTR_PAGE_EXT2, true }, // ATTR_PAGE_VERCENTER - { SID_ATTR_PAGE_ON, true }, // ATTR_PAGE_ON - { SID_ATTR_PAGE_DYNAMIC, true }, // ATTR_PAGE_DYNAMIC - { SID_ATTR_PAGE_SHARED, true }, // ATTR_PAGE_SHARED - { SID_ATTR_PAGE_SHARED_FIRST, true }, // ATTR_PAGE_SHARED_FIRST - { 0, true }, // ATTR_PAGE_NOTES aka. SID_SCATTR_PAGE_NOTES - { 0, true }, // ATTR_PAGE_GRID aka. SID_SCATTR_PAGE_GRID - { 0, true }, // ATTR_PAGE_HEADERS aka. SID_SCATTR_PAGE_HEADERS - { 0, true }, // ATTR_PAGE_CHARTS aka. SID_SCATTR_PAGE_CHARTS - { 0, true }, // ATTR_PAGE_OBJECTS aka. SID_SCATTR_PAGE_OBJECTS - { 0, true }, // ATTR_PAGE_DRAWINGS aka. SID_SCATTR_PAGE_DRAWINGS - { 0, true }, // ATTR_PAGE_TOPDOWN aka. SID_SCATTR_PAGE_TOPDOWN - { 0, true }, // ATTR_PAGE_SCALE aka SID_SCATTR_PAGE_SCALE - { 0, true }, // ATTR_PAGE_SCALETOPAGES aka SID_SCATTR_PAGE_SCALETOPAGES - { 0, true }, // ATTR_PAGE_FIRSTPAGENO aka SID_SCATTR_PAGE_FIRSTPAGENO - { 0, true }, // ATTR_PAGE_HEADERLEFT aka SID_SCATTR_PAGE_HEADERLEFT - { 0, true }, // ATTR_PAGE_FOOTERLEFT aka SID_SCATTR_PAGE_FOOTERLEFT - { 0, true }, // ATTR_PAGE_HEADERRIGHT aka SID_SCATTR_PAGE_HEADERRIGHT - { 0, true }, // ATTR_PAGE_FOOTERRIGHT aka. SID_SCATTR_PAGE_FOOTERRIGHT - { 0, true }, // ATTR_PAGE_HEADERFIRST aka. SID_SCATTR_PAGE_HEADERFIRST - { 0, true }, // ATTR_PAGE_FOOTERFIRST aka. SID_SCATTR_PAGE_FOOTERFIRST` - { SID_ATTR_PAGE_HEADERSET, true }, // ATTR_PAGE_HEADERSET - { SID_ATTR_PAGE_FOOTERSET, true }, // ATTR_PAGE_FOOTERSET - { 0, true }, // ATTR_PAGE_FORMULAS aka. SID_SCATTR_PAGE_FORMULAS - { 0, true }, // ATTR_PAGE_NULLVALS aka. SID_SCATTR_PAGE_NULLVALS - { 0, true }, // ATTR_PAGE_SCALETO aka. SID_SCATTR_PAGE_SCALETO - { 0, true } // ATTR_HIDDEN + // _nSID, _bNeedsPoolRegistration, _bShareable + { SID_ATTR_CHAR_FONT, true, true }, // ATTR_FONT + { SID_ATTR_CHAR_FONTHEIGHT, false, true }, // ATTR_FONT_HEIGHT + { SID_ATTR_CHAR_WEIGHT, false, true }, // ATTR_FONT_WEIGHT + { SID_ATTR_CHAR_POSTURE, false, true }, // ATTR_FONT_POSTURE + { SID_ATTR_CHAR_UNDERLINE, false, true }, // ATTR_FONT_UNDERLINE + { SID_ATTR_CHAR_OVERLINE, false, true }, // ATTR_FONT_OVERLINE + { SID_ATTR_CHAR_STRIKEOUT, false, true }, // ATTR_FONT_CROSSEDOUT + { SID_ATTR_CHAR_CONTOUR, false, true }, // ATTR_FONT_CONTOUR + { SID_ATTR_CHAR_SHADOWED, false, true }, // ATTR_FONT_SHADOWED + { SID_ATTR_CHAR_COLOR, true, true }, // ATTR_FONT_COLOR + { SID_ATTR_CHAR_LANGUAGE, false, true }, // ATTR_FONT_LANGUAGE + { SID_ATTR_CHAR_CJK_FONT, true, true }, // ATTR_CJK_FONT from 614 + { SID_ATTR_CHAR_CJK_FONTHEIGHT, false, true }, // ATTR_CJK_FONT_HEIGHT from 614 + { SID_ATTR_CHAR_CJK_WEIGHT, false, true }, // ATTR_CJK_FONT_WEIGHT from 614 + { SID_ATTR_CHAR_CJK_POSTURE, false, true }, // ATTR_CJK_FONT_POSTURE from 614 + { SID_ATTR_CHAR_CJK_LANGUAGE, false, true }, // ATTR_CJK_FONT_LANGUAGE from 614 + { SID_ATTR_CHAR_CTL_FONT, true, true }, // ATTR_CTL_FONT from 614 + { SID_ATTR_CHAR_CTL_FONTHEIGHT, false, true }, // ATTR_CTL_FONT_HEIGHT from 614 + { SID_ATTR_CHAR_CTL_WEIGHT, false, true }, // ATTR_CTL_FONT_WEIGHT from 614 + { SID_ATTR_CHAR_CTL_POSTURE, false, true }, // ATTR_CTL_FONT_POSTURE from 614 + { SID_ATTR_CHAR_CTL_LANGUAGE, false, true }, // ATTR_CTL_FONT_LANGUAGE from 614 + { SID_ATTR_CHAR_EMPHASISMARK, false, true }, // ATTR_FONT_EMPHASISMARK from 614 + { 0, true, true }, // ATTR_USERDEF from 614 / 641c + { SID_ATTR_CHAR_WORDLINEMODE, false, true }, // ATTR_FONT_WORDLINE from 632b + { SID_ATTR_CHAR_RELIEF, false, true }, // ATTR_FONT_RELIEF from 632b + { SID_ATTR_ALIGN_HYPHENATION, false, true }, // ATTR_HYPHENATE from 632b + { 0, false, true }, // ATTR_SCRIPTSPACE from 614d + { 0, false, true }, // ATTR_HANGPUNCTUATION from 614d + { SID_ATTR_PARA_FORBIDDEN_RULES, false, true }, // ATTR_FORBIDDEN_RULES from 614d + { SID_ATTR_ALIGN_HOR_JUSTIFY, false, true }, // ATTR_HOR_JUSTIFY + { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, false, true }, // ATTR_HOR_JUSTIFY_METHOD + { SID_ATTR_ALIGN_INDENT, false, true }, // ATTR_INDENT from 350 + { SID_ATTR_ALIGN_VER_JUSTIFY, false, true }, // ATTR_VER_JUSTIFY + { SID_ATTR_ALIGN_VER_JUSTIFY_METHOD, false, true }, // ATTR_VER_JUSTIFY_METHOD + { SID_ATTR_ALIGN_STACKED, false, true }, // ATTR_STACKED from 680/dr14 (replaces ATTR_ORIENTATION) + { SID_ATTR_ALIGN_DEGREES, true, true }, // ATTR_ROTATE_VALUE from 367 + { SID_ATTR_ALIGN_LOCKPOS, false, true }, // ATTR_ROTATE_MODE from 367 + { SID_ATTR_ALIGN_ASIANVERTICAL, false, true }, // ATTR_VERTICAL_ASIAN from 642 + { SID_ATTR_FRAMEDIRECTION, false, true }, // ATTR_WRITINGDIR from 643 + { SID_ATTR_ALIGN_LINEBREAK, false, true }, // ATTR_LINEBREAK + { SID_ATTR_ALIGN_SHRINKTOFIT, false, true }, // ATTR_SHRINKTOFIT from 680/dr14 + { SID_ATTR_BORDER_DIAG_TLBR, false, true }, // ATTR_BORDER_TLBR from 680/dr14 + { SID_ATTR_BORDER_DIAG_BLTR, false, true }, // ATTR_BORDER_BLTR from 680/dr14 + { SID_ATTR_ALIGN_MARGIN, false, true }, // ATTR_MARGIN + { 0, false, true }, // ATTR_MERGE + { 0, false, true }, // ATTR_MERGE_FLAG + { SID_ATTR_NUMBERFORMAT_VALUE, false, true }, // ATTR_VALUE_FORMAT + { 0, false, true }, // ATTR_LANGUAGE_FORMAT from 329, is combined with SID_ATTR_NUMBERFORMAT_VALUE in the dialog + { SID_ATTR_BRUSH, true, true }, // ATTR_BACKGROUND + { SID_SCATTR_PROTECTION, false, true }, // ATTR_PROTECTION + { SID_ATTR_BORDER_OUTER, false, true }, // ATTR_BORDER + { SID_ATTR_BORDER_INNER, false, true }, // ATTR_BORDER_INNER + { SID_ATTR_BORDER_SHADOW, false, true }, // ATTR_SHADOW + { 0, false, true }, // ATTR_VALIDDATA + { 0, false, true }, // ATTR_CONDITIONAL + { 0, false, true }, // ATTR_HYPERLINK + { 0, true, true }, // ATTR_PATTERN + { SID_ATTR_LRSPACE, false, true }, // ATTR_LRSPACE + { SID_ATTR_ULSPACE, false, true }, // ATTR_ULSPACE + { SID_ATTR_PAGE, false, true }, // ATTR_PAGE + { SID_ATTR_PAGE_PAPERBIN, false, true }, // ATTR_PAGE_PAPERBIN + { SID_ATTR_PAGE_SIZE, false, true }, // ATTR_PAGE_SIZE + { SID_ATTR_PAGE_EXT1, false, true }, // ATTR_PAGE_HORCENTER + { SID_ATTR_PAGE_EXT2, false, true }, // ATTR_PAGE_VERCENTER + { SID_ATTR_PAGE_ON, false, true }, // ATTR_PAGE_ON + { SID_ATTR_PAGE_DYNAMIC, false, true }, // ATTR_PAGE_DYNAMIC + { SID_ATTR_PAGE_SHARED, false, true }, // ATTR_PAGE_SHARED + { SID_ATTR_PAGE_SHARED_FIRST, false, true }, // ATTR_PAGE_SHARED_FIRST + { 0, false, true }, // ATTR_PAGE_NOTES aka. SID_SCATTR_PAGE_NOTES + { 0, false, true }, // ATTR_PAGE_GRID aka. SID_SCATTR_PAGE_GRID + { 0, false, true }, // ATTR_PAGE_HEADERS aka. SID_SCATTR_PAGE_HEADERS + { 0, false, true }, // ATTR_PAGE_CHARTS aka. SID_SCATTR_PAGE_CHARTS + { 0, false, true }, // ATTR_PAGE_OBJECTS aka. SID_SCATTR_PAGE_OBJECTS + { 0, false, true }, // ATTR_PAGE_DRAWINGS aka. SID_SCATTR_PAGE_DRAWINGS + { 0, false, true }, // ATTR_PAGE_TOPDOWN aka. SID_SCATTR_PAGE_TOPDOWN + { 0, false, true }, // ATTR_PAGE_SCALE aka SID_SCATTR_PAGE_SCALE + { 0, false, true }, // ATTR_PAGE_SCALETOPAGES aka SID_SCATTR_PAGE_SCALETOPAGES + { 0, false, true }, // ATTR_PAGE_FIRSTPAGENO aka SID_SCATTR_PAGE_FIRSTPAGENO + { 0, true, true }, // ATTR_PAGE_HEADERLEFT aka SID_SCATTR_PAGE_HEADERLEFT + { 0, true, true }, // ATTR_PAGE_FOOTERLEFT aka SID_SCATTR_PAGE_FOOTERLEFT + { 0, true, true }, // ATTR_PAGE_HEADERRIGHT aka SID_SCATTR_PAGE_HEADERRIGHT + { 0, true, true }, // ATTR_PAGE_FOOTERRIGHT aka. SID_SCATTR_PAGE_FOOTERRIGHT + { 0, true, true }, // ATTR_PAGE_HEADERFIRST aka. SID_SCATTR_PAGE_HEADERFIRST + { 0, true, true }, // ATTR_PAGE_FOOTERFIRST aka. SID_SCATTR_PAGE_FOOTERFIRST` + { SID_ATTR_PAGE_HEADERSET, false, true }, // ATTR_PAGE_HEADERSET + { SID_ATTR_PAGE_FOOTERSET, false, true }, // ATTR_PAGE_FOOTERSET + { 0, false, true }, // ATTR_PAGE_FORMULAS aka. SID_SCATTR_PAGE_FORMULAS + { 0, false, true }, // ATTR_PAGE_NULLVALS aka. SID_SCATTR_PAGE_NULLVALS + { 0, false, true }, // ATTR_PAGE_SCALETO aka. SID_SCATTR_PAGE_SCALETO + { 0, false, true } // ATTR_HIDDEN }; static_assert( SAL_N_ELEMENTS(aItemInfos) == ATTR_ENDINDEX - ATTR_STARTINDEX + 1, "these must match"); @@ -336,24 +337,20 @@ ScDocumentPool::~ScDocumentPool() } } -const SfxPoolItem& ScDocumentPool::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership ) +void ScDocumentPool::newItem_Callback(const SfxPoolItem& rItem) const { - if ( rItem.Which() != ATTR_PATTERN ) // Only Pattern is special - return SfxItemPool::PutImpl( rItem, nWhich, bPassingOwnership ); - - // Don't copy the default pattern of this Pool - if (&rItem == mvPoolDefaults[ ATTR_PATTERN - ATTR_STARTINDEX ]) - return rItem; - - // Else Put must always happen, because it could be another Pool - const SfxPoolItem& rNew = SfxItemPool::PutImpl( rItem, nWhich, bPassingOwnership ); - sal_uInt32 nRef = rNew.GetRefCount(); - if (nRef == 1) + if (ATTR_PATTERN == rItem.Which() && 1 == rItem.GetRefCount()) { - ++mnCurrentMaxKey; - const_cast<ScPatternAttr&>(static_cast<const ScPatternAttr&>(rNew)).SetKey(mnCurrentMaxKey); + const_cast<ScDocumentPool*>(this)->mnCurrentMaxKey++; + const_cast<ScPatternAttr&>(static_cast<const ScPatternAttr&>(rItem)).SetPAKey(mnCurrentMaxKey); } - return rNew; +} + +bool ScDocumentPool::newItem_UseDirect(const SfxPoolItem& rItem) const +{ + // I have evaluated that this is currently needed for ATTR_PATTERN/ScPatternAttr to work, + // so this needs to stay at ptr-compare + return (ATTR_PATTERN == rItem.Which() && areSfxPoolItemPtrsEqual(&rItem, mvPoolDefaults[ATTR_PATTERN - ATTR_STARTINDEX])); } void ScDocumentPool::StyleDeleted( const ScStyleSheet* pStyle ) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 8996577b588e..6225e92781b9 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -5060,7 +5060,7 @@ std::unique_ptr<ScPatternAttr> ScDocument::CreateSelectionPattern( const ScMarkD { std::unique_ptr<ScPatternAttr> pPattern(new ScPatternAttr( std::move(*aState.pItemSet) )); if (aState.mbValidPatternId) - pPattern->SetKey(aState.mnPatternId); + pPattern->SetPAKey(aState.mnPatternId); return pPattern; } diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index 9a8675fcd190..4a573e1c21da 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -186,7 +186,7 @@ public: bool isRotateItemUsed(const ScDocumentPool *pPool) { - return pPool->GetItemCount2( ATTR_ROTATE_VALUE ) > 0; + return pPool->GetItemSurrogates(ATTR_ROTATE_VALUE).size() > 0; } void initRowInfo(const ScDocument* pDoc, RowInfo* pRowInfo, const SCSIZE nMaxRow, @@ -488,11 +488,11 @@ void ScDocument::FillInfo( const SvxLineItem* pBLTRLine = &pPattern->GetItem( ATTR_BORDER_BLTR ); const SvxShadowItem* pShadowAttr = &pPattern->GetItem(ATTR_SHADOW); - if (pShadowAttr != pDefShadow) + if (!SfxPoolItem::areSame(pShadowAttr, pDefShadow)) bAnyShadow = true; const ScMergeAttr* pMergeAttr = &pPattern->GetItem(ATTR_MERGE); - bool bMerged = ( pMergeAttr != pDefMerge && *pMergeAttr != *pDefMerge ); + bool bMerged = !SfxPoolItem::areSame( pMergeAttr, pDefMerge ); ScMF nOverlap = pPattern->GetItemSet(). Get(ATTR_MERGE_FLAG).GetValue(); bool bHOverlapped(nOverlap & ScMF::Hor); @@ -530,7 +530,7 @@ void ScDocument::FillInfo( if ( GetPreviewCellStyle( nCol, nCurRow, nTab ) != nullptr ) bAnyPreview = true; RowInfo* pThisRowInfo = &pRowInfo[nArrRow]; - if (pBackground != pDefBackground) // Column background == Default ? + if (!SfxPoolItem::areSame(pBackground, pDefBackground)) // Column background == Default ? pThisRowInfo->bEmptyBack = false; if (bContainsCondFormat) pThisRowInfo->bEmptyBack = false; @@ -687,7 +687,7 @@ void ScDocument::FillInfo( if( bAnyCondition && pInfo->mxColorScale) { pRowInfo[nArrRow].bEmptyBack = false; - pInfo->pBackground = &pPool->Put(SvxBrushItem(*pInfo->mxColorScale, ATTR_BACKGROUND)); + pInfo->pBackground = &pPool->DirectPutItemInPool(SvxBrushItem(*pInfo->mxColorScale, ATTR_BACKGROUND)); } } } @@ -735,7 +735,7 @@ void ScDocument::FillInfo( !(pShadowItem = pStartCond->GetItemIfSet(ATTR_SHADOW)) ) pShadowItem = &pStartPattern->GetItem(ATTR_SHADOW); pInfo->pShadowAttr = pShadowItem; - if (pInfo->pShadowAttr != pDefShadow) + if (!SfxPoolItem::areSame(pInfo->pShadowAttr, pDefShadow)) bAnyShadow = true; const ScCondFormatIndexes& rCondFormatIndex diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index 027bc5768a35..57c9759f17a4 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -139,7 +139,7 @@ bool ScGlobal::HasAttrChanged( const SfxItemSet& rNewAttrs, // Both Items set // PoolItems, meaning comparing pointers is valid if ( SfxItemState::SET == eOldState ) - bInvalidate = (pNewItem != pOldItem); + bInvalidate = !SfxPoolItem::areSame(pNewItem, pOldItem); } else { diff --git a/sc/source/core/data/patattr.cxx b/sc/source/core/data/patattr.cxx index 7638652e6857..d7d460abdbb5 100644 --- a/sc/source/core/data/patattr.cxx +++ b/sc/source/core/data/patattr.cxx @@ -72,30 +72,34 @@ ScPatternAttr::ScPatternAttr( SfxItemSet&& pItemSet, const OUString& rStyleName : SfxSetItem ( ATTR_PATTERN, std::move(pItemSet) ), pName ( rStyleName ), pStyle ( nullptr ), - mnKey(0) + mnPAKey(0) { + setNewItemCallback(); } ScPatternAttr::ScPatternAttr( SfxItemSet&& pItemSet ) : SfxSetItem ( ATTR_PATTERN, std::move(pItemSet) ), pStyle ( nullptr ), - mnKey(0) + mnPAKey(0) { + setNewItemCallback(); } ScPatternAttr::ScPatternAttr( SfxItemPool* pItemPool ) : SfxSetItem ( ATTR_PATTERN, SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END>( *pItemPool ) ), pStyle ( nullptr ), - mnKey(0) + mnPAKey(0) { + setNewItemCallback(); } ScPatternAttr::ScPatternAttr( const ScPatternAttr& rPatternAttr ) : SfxSetItem ( rPatternAttr ), pName ( rPatternAttr.pName ), pStyle ( rPatternAttr.pStyle ), - mnKey(rPatternAttr.mnKey) + mnPAKey(rPatternAttr.mnPAKey) { + setNewItemCallback(); } ScPatternAttr* ScPatternAttr::Clone( SfxItemPool *pPool ) const @@ -166,25 +170,6 @@ bool ScPatternAttr::operator==( const SfxPoolItem& rCmp ) const StrCmp( GetStyleName(), rOther.GetStyleName() ); } -SfxPoolItem::lookup_iterator ScPatternAttr::Lookup(lookup_iterator begin, lookup_iterator end ) const -{ - if( !mxHashCode ) - CalcHashCode(); - for( auto it = begin; it != end; ++it) - { - const ScPatternAttr* other = static_cast<const ScPatternAttr*>(*it); - if( !other->mxHashCode ) - other->CalcHashCode(); - if (*mxHashCode == *other->mxHashCode - && EqualPatternSets( GetItemSet(), other->GetItemSet()) - && StrCmp( GetStyleName(), other->GetStyleName())) - { - return it; - } - } - return end; -} - SvxCellOrientation ScPatternAttr::GetCellOrientation( const SfxItemSet& rItemSet, const SfxItemSet* pCondSet ) { SvxCellOrientation eOrient = SvxCellOrientation::Standard; @@ -1027,7 +1012,7 @@ void ScPatternAttr::DeleteUnchanged( const ScPatternAttr* pOldAttrs ) if ( eOldState == SfxItemState::SET ) { // item is set in OldAttrs (or its parent) -> compare pointers - if ( pThisItem == pOldItem ) + if (SfxPoolItem::areSame( pThisItem, pOldItem )) { rThisSet.ClearItem( nSubWhich ); mxHashCode.reset(); @@ -1194,7 +1179,7 @@ ScPatternAttr* ScPatternAttr::PutInPool( ScDocument* pDestDoc, ScDocument* pSrcD } } - ScPatternAttr* pPatternAttr = const_cast<ScPatternAttr*>( &pDestDoc->GetPool()->Put(aDestPattern) ); + ScPatternAttr* pPatternAttr = const_cast<ScPatternAttr*>( &pDestDoc->GetPool()->DirectPutItemInPool(aDestPattern) ); return pPatternAttr; } @@ -1289,7 +1274,7 @@ bool ScPatternAttr::IsVisibleEqual( const ScPatternAttr& rOther ) const if (state1 != state2 && (state1 < SfxItemState::DEFAULT || state2 < SfxItemState::DEFAULT)) return false; - if (pItem1 != pItem2) + if (!SfxPoolItem::areSame(pItem1, pItem2)) return false; } nWhich1 = aIter1.NextWhich(); @@ -1494,14 +1479,14 @@ ScRotateDir ScPatternAttr::GetRotateDir( const SfxItemSet* pCondSet ) const return nRet; } -void ScPatternAttr::SetKey(sal_uInt64 nKey) +void ScPatternAttr::SetPAKey(sal_uInt64 nKey) { - mnKey = nKey; + mnPAKey = nKey; } -sal_uInt64 ScPatternAttr::GetKey() const +sal_uInt64 ScPatternAttr::GetPAKey() const { - return mnKey; + return mnPAKey; } void ScPatternAttr::CalcHashCode() const diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 978bd00ecbac..d6c1eead2c48 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -2905,7 +2905,7 @@ namespace std::vector<ScAttrEntry> aData(rOrigData); for (size_t nIdx = 0; nIdx < aData.size(); ++nIdx) { - aData[nIdx].pPattern = &rDocument.GetPool()->Put(*aData[nIdx].pPattern); + aData[nIdx].pPattern = &rDocument.GetPool()->DirectPutItemInPool(*aData[nIdx].pPattern); } return aData; } diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index f0a55b478c0c..71cf80bcef38 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -1192,13 +1192,13 @@ void ScTable::SortReorderByRow( ScSortInfoArray* pArray, SCCOL nCol1, SCCOL nCol for (const auto& rSpan : aSpans) { assert(rSpan.mpPattern); // should never be NULL. - rDocument.GetPool()->Put(*rSpan.mpPattern); + rDocument.GetPool()->DirectPutItemInPool(*rSpan.mpPattern); } for (const auto& rSpan : aSpans) { aCol[nThisCol].SetPatternArea(rSpan.mnRow1, rSpan.mnRow2, *rSpan.mpPattern); - rDocument.GetPool()->Remove(*rSpan.mpPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*rSpan.mpPattern); } } @@ -1393,13 +1393,13 @@ void ScTable::SortReorderByRowRefUpdate( for (const auto& rSpan : aSpans) { assert(rSpan.mpPattern); // should never be NULL. - rDocument.GetPool()->Put(*rSpan.mpPattern); + rDocument.GetPool()->DirectPutItemInPool(*rSpan.mpPattern); } for (const auto& rSpan : aSpans) { aCol[nThisCol].SetPatternArea(rSpan.mnRow1, rSpan.mnRow2, *rSpan.mpPattern); - rDocument.GetPool()->Remove(*rSpan.mpPattern); + rDocument.GetPool()->DirectRemoveItemFromPool(*rSpan.mpPattern); } } diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index 9c6852990efe..d8a4cf584132 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -1005,7 +1005,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, if ( bVertical && nISrcStart == nISrcEnd && !bHasFiltered ) { // set all attributes at once (en bloc) - if (pNewPattern || pSrcPattern != rDocument.GetDefPattern()) + if (pNewPattern || !SfxPoolItem::areSame(pSrcPattern, rDocument.GetDefPattern())) { // Default is already present (DeleteArea) SCROW nY1 = static_cast<SCROW>(std::min( nIStart, nIEnd )); @@ -1036,7 +1036,7 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, DeleteArea(static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), static_cast<SCCOL>(nCol), static_cast<SCROW>(nRow), InsertDeleteFlags::AUTOFILL); - if ( pSrcPattern != aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) ) + if ( !SfxPoolItem::areSame(pSrcPattern, aCol[nCol].GetPattern( static_cast<SCROW>(nRow) ) ) ) { // Transfer template too //TODO: Merge ApplyPattern to AttrArray ?? diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx index a68d6408edd9..2230987ce8b0 100644 --- a/sc/source/filter/excel/xestyle.cxx +++ b/sc/source/filter/excel/xestyle.cxx @@ -2815,7 +2815,7 @@ sal_uInt32 XclExpXFBuffer::InsertCellXF( const ScPatternAttr* pPattern, sal_Int1 pPattern = pDefPattern; // special handling for default cell formatting - if( (pPattern == pDefPattern) && !bForceLineBreak && + if( SfxPoolItem::areSame(pPattern, pDefPattern) && !bForceLineBreak && (nForceScNumFmt == NUMBERFORMAT_ENTRY_NOT_FOUND) && (nForceXclFont == EXC_FONT_NOTFOUND) ) { diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx index e1dc476e1d9e..21b86a4ed4fa 100644 --- a/sc/source/filter/excel/xistyle.cxx +++ b/sc/source/filter/excel/xistyle.cxx @@ -1405,7 +1405,7 @@ void XclImpXF::ApplyPatternToAttrVector( ScAttrEntry aEntry; aEntry.nEndRow = nRow2; - aEntry.pPattern = &rDoc.GetPool()->Put(rPat); + aEntry.pPattern = &rDoc.GetPool()->DirectPutItemInPool(rPat); rAttrs.push_back(aEntry); } diff --git a/sc/source/filter/lotus/lotattr.cxx b/sc/source/filter/lotus/lotattr.cxx index f87984056fe6..458e3c677b62 100644 --- a/sc/source/filter/lotus/lotattr.cxx +++ b/sc/source/filter/lotus/lotattr.cxx @@ -189,7 +189,7 @@ void LotAttrCol::SetAttr( const ScDocument* pDoc, const SCROW nRow, const ScPatt if(iterLast != aEntries.rend()) { - if( ( (*iterLast)->nLastRow == nRow - 1 ) && ( &rAttr == (*iterLast)->pPattAttr ) ) + if( ( (*iterLast)->nLastRow == nRow - 1 ) && SfxPoolItem::areSame( &rAttr, (*iterLast)->pPattAttr ) ) (*iterLast)->nLastRow = nRow; else { diff --git a/sc/source/filter/oox/sheetdatabuffer.cxx b/sc/source/filter/oox/sheetdatabuffer.cxx index d1410eb04970..b25dba6eb079 100644 --- a/sc/source/filter/oox/sheetdatabuffer.cxx +++ b/sc/source/filter/oox/sheetdatabuffer.cxx @@ -523,7 +523,7 @@ void SheetDataBuffer::finalizeImport() ScAttrEntry aEntry; aEntry.nEndRow = rDoc.MaxRow(); aEntry.pPattern = pDefPattern; - rDoc.GetPool()->Put(*aEntry.pPattern); + rDoc.GetPool()->DirectPutItemInPool(*aEntry.pPattern); aAttrs.maAttrs.push_back(aEntry); if (!sc::NumFmtUtil::isLatinScript(*aEntry.pPattern, rDoc)) diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx index e38b5cd13002..7481b1dec851 100644 --- a/sc/source/filter/oox/stylesbuffer.cxx +++ b/sc/source/filter/oox/stylesbuffer.cxx @@ -2168,7 +2168,7 @@ void Xf::applyPatternToAttrList( AttrList& rAttrs, SCROW nRow1, SCROW nRow2, sal // Fill this gap with the default pattern. ScAttrEntry aEntry; aEntry.nEndRow = nRow1 - 1; - aEntry.pPattern = &rDoc.GetPool()->Put(*rAttrs.mpDefPattern); + aEntry.pPattern = &rDoc.GetPool()->DirectPutItemInPool(*rAttrs.mpDefPattern); rAttrs.maAttrs.push_back(aEntry); // Check if the default pattern is 'General'. @@ -2178,7 +2178,7 @@ void Xf::applyPatternToAttrList( AttrList& rAttrs, SCROW nRow1, SCROW nRow2, sal ScAttrEntry aEntry; aEntry.nEndRow = nRow2; - aEntry.pPattern = &rDoc.GetPool()->Put(rPat); + aEntry.pPattern = &rDoc.GetPool()->DirectPutItemInPool(rPat); // Put the allocated pattern to cache if (!pCachedPattern) rCache.add(nXfId, nNumFmtId, const_cast<ScPatternAttr*>(aEntry.pPattern)); diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index de2ce3679cca..769f4249a4bf 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -2519,7 +2519,7 @@ bool ScInputHandler::StartTable( sal_Unicode cTyped, bool bFromCommand, bool bIn const ScPatternAttr* pPattern = rDoc.GetPattern( aCursorPos.Col(), aCursorPos.Row(), aCursorPos.Tab() ); - if (pPattern != pLastPattern) + if (!SfxPoolItem::areSame(pPattern, pLastPattern)) { // Percent format? const SfxItemSet& rAttrSet = pPattern->GetItemSet(); diff --git a/sc/source/ui/app/msgpool.cxx b/sc/source/ui/app/msgpool.cxx index 58daba682830..227dbce4560b 100644 --- a/sc/source/ui/app/msgpool.cxx +++ b/sc/source/ui/app/msgpool.cxx @@ -25,16 +25,17 @@ SfxItemInfo const aMsgItemInfos[] = { - { 0, true }, // SCITEM_STRING - { 0, true }, // SCITEM_SEARCHDATA - stop using this! - { SID_SORT, true }, // SCITEM_SORTDATA - { SID_QUERY, true }, // SCITEM_QUERYDATA - { SID_SUBTOTALS, true }, // SCITEM_SUBTDATA - { SID_CONSOLIDATE, true }, // SCITEM_CONSOLIDATEDATA - { SID_PIVOT_TABLE, true }, // SCITEM_PIVOTDATA - { SID_SOLVE, true }, // SCITEM_SOLVEDATA - { SID_SCUSERLISTS, true }, // SCITEM_USERLIST - { 0, false } // SCITEM_CONDFORMATDLGDATA + // _nSID, _bNeedsPoolRegistration, _bShareable + { 0, false, true }, // SCITEM_STRING + { 0, false, true }, // SCITEM_SEARCHDATA - stop using this! + { SID_SORT, false, true }, // SCITEM_SORTDATA + { SID_QUERY, false, true }, // SCITEM_QUERYDATA + { SID_SUBTOTALS, false, true }, // SCITEM_SUBTDATA + { SID_CONSOLIDATE, false, true }, // SCITEM_CONSOLIDATEDATA + { SID_PIVOT_TABLE, false, true }, // SCITEM_PIVOTDATA + { SID_SOLVE, false, true }, // SCITEM_SOLVEDATA + { SID_SCUSERLISTS, false, true }, // SCITEM_USERLIST + { 0, true, false } // SCITEM_CONDFORMATDLGDATA }; ScMessagePool::ScMessagePool() diff --git a/sc/source/ui/condformat/condformatdlg.cxx b/sc/source/ui/condformat/condformatdlg.cxx index 6fd71f90f6e9..2a1b72459665 100644 --- a/sc/source/ui/condformat/condformatdlg.cxx +++ b/sc/source/ui/condformat/condformatdlg.cxx @@ -634,7 +634,7 @@ void ScCondFormatDlg::OkPressed() pFormat->SetKey(nKey); pList->InsertNew(std::move(pFormat)); } - mpViewData->GetViewShell()->GetPool().Put(*mpDlgItem); + mpViewData->GetViewShell()->GetPool().DirectPutItemInPool(*mpDlgItem); SetDispatcherLock( false ); // Queue message to open Conditional Format Manager Dialog @@ -650,7 +650,7 @@ void ScCondFormatDlg::CancelPressed() { if ( mpDlgItem->IsManaged() ) { - mpViewData->GetViewShell()->GetPool().Put(*mpDlgItem); + mpViewData->GetViewShell()->GetPool().DirectPutItemInPool(*mpDlgItem); SetDispatcherLock( false ); // Queue message to open Conditional Format Manager Dialog GetBindings().GetDispatcher()->Execute( SID_OPENDLG_CONDFRMT_MANAGER, diff --git a/sc/source/ui/inc/editsh.hxx b/sc/source/ui/inc/editsh.hxx index 01457c3b7f2a..3777d1988887 100644 --- a/sc/source/ui/inc/editsh.hxx +++ b/sc/source/ui/inc/editsh.hxx @@ -29,7 +29,7 @@ class SfxModule; class EditView; class ScViewData; class ScInputHandler; -class SvxURLField; +class SvxFieldData; class TransferableDataHelper; class TransferableClipboardListener; @@ -48,8 +48,14 @@ private: // currently happens to be when the menu was dismissed. std::optional<bool> moAtContextMenu_DisableEditHyperlink; - const SvxURLField* GetURLField(); - const SvxURLField* GetFirstURLFieldFromCell(); + // These methods did return 'const SvxURLField*' before, but + // at least for GetFirstURLFieldFromCell this is not safe: The + // SvxFieldItem accessed there and held in the local temporary + // SfxItemSet may be deleted with it, so return value can be + // corrupted/deleted. To avoid that, return a Clone + std::unique_ptr<const SvxFieldData> GetURLField(); + std::unique_ptr<const SvxFieldData> GetFirstURLFieldFromCell(); + ScInputHandler* GetMyInputHdl(); DECL_LINK( ClipboardChanged, TransferableDataHelper*, void ); diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx index f614e0ff0b4a..b7b615d6608f 100644 --- a/sc/source/ui/undo/undoblk3.cxx +++ b/sc/source/ui/undo/undoblk3.cxx @@ -355,20 +355,20 @@ ScUndoSelectionAttr::ScUndoSelectionAttr( ScDocShell* pNewDocShell, bMulti ( bNewMulti ) { ScDocumentPool* pPool = pDocShell->GetDocument().GetPool(); - pApplyPattern = const_cast<ScPatternAttr*>(&pPool->Put( *pNewApply )); - pLineOuter = pNewOuter ? const_cast<SvxBoxItem*>( &pPool->Put( *pNewOuter ) ) : nullptr; - pLineInner = pNewInner ? const_cast<SvxBoxInfoItem*>( &pPool->Put( *pNewInner ) ) : nullptr; + pApplyPattern = const_cast<ScPatternAttr*>(&pPool->DirectPutItemInPool( *pNewApply )); + pLineOuter = pNewOuter ? const_cast<SvxBoxItem*>( &pPool->DirectPutItemInPool( *pNewOuter ) ) : nullptr; + pLineInner = pNewInner ? const_cast<SvxBoxInfoItem*>( &pPool->DirectPutItemInPool( *pNewInner ) ) : nullptr; aRangeCover = pRangeCover ? *pRangeCover : aRange; } ScUndoSelectionAttr::~ScUndoSelectionAttr() { ScDocumentPool* pPool = pDocShell->GetDocument().GetPool(); - pPool->Remove(*pApplyPattern); + pPool->DirectRemoveItemFromPool(*pApplyPattern); if (pLineOuter) - pPool->Remove(*pLineOuter); + pPool->DirectRemoveItemFromPool(*pLineOuter); if (pLineInner) - pPool->Remove(*pLineInner); + pPool->DirectRemoveItemFromPool(*pLineInner); pUndoDoc.reset(); } diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx index 4cb9d03fed6d..84e4a95bcb1e 100644 --- a/sc/source/ui/undo/undocell.cxx +++ b/sc/source/ui/undo/undocell.cxx @@ -84,17 +84,17 @@ ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell* pNewDocShell, pNewEditData( static_cast<EditTextObject*>(nullptr) ) { ScDocumentPool* pPool = pDocShell->GetDocument().GetPool(); - pNewPattern = const_cast<ScPatternAttr*>( &pPool->Put( *pNewPat ) ); - pOldPattern = const_cast<ScPatternAttr*>( &pPool->Put( *pOldPat ) ); - pApplyPattern = const_cast<ScPatternAttr*>( &pPool->Put( *pApplyPat ) ); + pNewPattern = const_cast<ScPatternAttr*>( &pPool->DirectPutItemInPool( *pNewPat ) ); + pOldPattern = const_cast<ScPatternAttr*>( &pPool->DirectPutItemInPool( *pOldPat ) ); + pApplyPattern = const_cast<ScPatternAttr*>( &pPool->DirectPutItemInPool( *pApplyPat ) ); } ScUndoCursorAttr::~ScUndoCursorAttr() { ScDocumentPool* pPool = pDocShell->GetDocument().GetPool(); - pPool->Remove(*pNewPattern); - pPool->Remove(*pOldPattern); - pPool->Remove(*pApplyPattern); + pPool->DirectRemoveItemFromPool(*pNewPattern); + pPool->DirectRemoveItemFromPool(*pOldPattern); + pPool->DirectRemoveItemFromPool(*pApplyPattern); } OUString ScUndoCursorAttr::GetComment() const diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index 59d77e3517fa..3325b0bbcf6c 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -2448,7 +2448,7 @@ void ScCellRangesBase::GetOnePropertyValue( const SfxItemPropertyMapEntry* pEntr case SC_WID_UNO_FORMATID: { const ScPatternAttr* pPattern = GetCurrentAttrsFlat(); - rAny <<= pPattern->GetKey(); + rAny <<= pPattern->GetPAKey(); } break; } diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index 1b307963dc01..558d5a816615 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -2410,7 +2410,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) // Conditional Format Dialog. ScCondFormatDlgItem aDlgItem(nullptr, nIndex, false); aDlgItem.SetDialogType(eType); - pTabViewShell->GetPool().Put(aDlgItem); + pTabViewShell->GetPool().DirectPutItemInPool(aDlgItem); sal_uInt16 nId = ScCondFormatDlgWrapper::GetChildWindowId(); SfxViewFrame& rViewFrm = pTabViewShell->GetViewFrame(); @@ -2878,7 +2878,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) { // Put the xml string parameter to initialize the // Conditional Format Dialog. ( add new ) - pTabViewShell->GetPool().Put(ScCondFormatDlgItem( + pTabViewShell->GetPool().DirectPutItemInPool(ScCondFormatDlgItem( std::shared_ptr<ScConditionalFormatList>(pCondFormatList.release()), -1, true)); // Queue message to open Conditional Format Dialog GetViewData().GetDispatcher().Execute( SID_OPENDLG_CONDFRMT, SfxCallMode::ASYNCHRON ); @@ -2889,7 +2889,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) sal_Int32 nIndex = pFormat ? pFormat->GetKey() : -1; // Put the xml string parameter to initialize the // Conditional Format Dialog. ( edit selected conditional format ) - pTabViewShell->GetPool().Put(ScCondFormatDlgItem( + pTabViewShell->GetPool().DirectPutItemInPool(ScCondFormatDlgItem( std::shared_ptr<ScConditionalFormatList>(pCondFormatList.release()), nIndex, true)); // Queue message to open Conditional Format Dialog @@ -2899,7 +2899,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) pCondFormatList.reset(); if (pDlgItem) - pTabViewShell->GetPool().Remove(*pDlgItem); + pTabViewShell->GetPool().DirectRemoveItemFromPool(*pDlgItem); pDlg->disposeOnce(); }); diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx index 493ab18f78cc..2c4328d78145 100644 --- a/sc/source/ui/view/editsh.cxx +++ b/sc/source/ui/view/editsh.cxx @@ -577,7 +577,8 @@ void ScEditShell::Execute( SfxRequest& rReq ) bool bDone = false; if ( (eMode == HLINK_DEFAULT || eMode == HLINK_FIELD) && !bCellLinksOnly ) { - const SvxURLField* pURLField = GetURLField(); + std::unique_ptr<const SvxFieldData> aSvxFieldDataPtr(GetURLField()); + const SvxURLField* pURLField(static_cast<const SvxURLField*>(aSvxFieldDataPtr.get())); if ( pURLField ) { // select old field @@ -637,7 +638,8 @@ void ScEditShell::Execute( SfxRequest& rReq ) break; case SID_OPEN_HYPERLINK: { - const SvxURLField* pURLField = GetURLField(); + std::unique_ptr<const SvxFieldData> aSvxFieldDataPtr(GetURLField()); + const SvxURLField* pURLField(static_cast<const SvxURLField*>(aSvxFieldDataPtr.get())); if ( pURLField ) ScGlobal::OpenURL( pURLField->GetURL(), pURLField->GetTargetFrame(), true ); return; @@ -792,7 +794,8 @@ void ScEditShell::GetState( SfxItemSet& rSet ) bool bCellLinksOnly = SC_MOD()->GetAppOptions().GetLinksInsertedLikeMSExcel() && rViewData.GetSfxDocShell()->GetMedium()->GetFilter()->IsMSOFormat(); - const SvxURLField* pURLField = GetURLField(); + std::unique_ptr<const SvxFieldData> aSvxFieldDataPtr(GetURLField()); + const SvxURLField* pURLField(static_cast<const SvxURLField*>(aSvxFieldDataPtr.get())); if (!bCellLinksOnly) { if (pURLField) @@ -814,7 +817,8 @@ void ScEditShell::GetState( SfxItemSet& rSet ) { if (!pURLField) { - pURLField = GetFirstURLFieldFromCell(); + aSvxFieldDataPtr = GetFirstURLFieldFromCell(); + pURLField = static_cast<const SvxURLField*>(aSvxFieldDataPtr.get()); } if (pURLField) { @@ -893,21 +897,21 @@ void ScEditShell::GetState( SfxItemSet& rSet ) } } -const SvxURLField* ScEditShell::GetURLField() +std::unique_ptr<const SvxFieldData> ScEditShell::GetURLField() { ScInputHandler* pHdl = GetMyInputHdl(); EditView* pActiveView = pHdl ? pHdl->GetActiveView() : pEditView; if (!pActiveView) - return nullptr; + return std::unique_ptr<const SvxFieldData>(); const SvxFieldData* pField = pActiveView->GetFieldAtCursor(); if (auto pURLField = dynamic_cast<const SvxURLField*>(pField)) - return pURLField; + return pURLField->Clone(); - return nullptr; + return std::unique_ptr<const SvxFieldData>(); } -const SvxURLField* ScEditShell::GetFirstURLFieldFromCell() +std::unique_ptr<const SvxFieldData> ScEditShell::GetFirstURLFieldFromCell() { EditEngine* pEE = GetEditView()->GetEditEngine(); sal_Int32 nParaCount = pEE->GetParagraphCount(); @@ -929,14 +933,15 @@ const SvxURLField* ScEditShell::GetFirstURLFieldFromCell() const SvxFieldData* pField = pItem->GetField(); if (const SvxURLField* pUrlField = dynamic_cast<const SvxURLField*>(pField)) { - return pUrlField; + return pUrlField->Clone(); } } } aSel.nStartPos = aSel.nEndPos; } } - return nullptr; + + return std::unique_ptr<const SvxFieldData>(); } IMPL_LINK( ScEditShell, ClipboardChanged, TransferableDataHelper*, pDataHelper, void ) diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index 8461aaaac446..47fdab381c9f 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -766,14 +766,14 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const RowInfo& rOther, const ScPatternAttr* pPat1 = rFirst.cellInfo(nX).pPatternAttr; const ScPatternAttr* pPat2 = rOther.cellInfo(nX).pPatternAttr; if ( !pPat1 || !pPat2 || - &pPat1->GetItem(ATTR_PROTECTION) != &pPat2->GetItem(ATTR_PROTECTION) ) + !SfxPoolItem::areSame(&pPat1->GetItem(ATTR_PROTECTION), &pPat2->GetItem(ATTR_PROTECTION) ) ) return false; } } else { for ( nX=nX1; nX<=nX2; nX++ ) - if ( rFirst.cellInfo(nX).pBackground != rOther.cellInfo(nX).pBackground ) + if ( !SfxPoolItem::areSame(rFirst.cellInfo(nX).pBackground, rOther.cellInfo(nX).pBackground ) ) return false; } @@ -970,7 +970,7 @@ void drawCells(vcl::RenderContext& rRenderContext, std::optional<Color> const & rRect.SetLeft( nPosX - nSignedOneX ); } - if ( pOldBackground && (pColor ||pBackground != pOldBackground || pOldDataBarInfo || pDataBarInfo || pIconSetInfo || pOldIconSetInfo) ) + if ( pOldBackground && (pColor || !SfxPoolItem::areSame(pBackground, pOldBackground) || pOldDataBarInfo || pDataBarInfo || pIconSetInfo || pOldIconSetInfo) ) { rRect.SetRight( nPosX-nSignedOneX ); if (pOldBackground) // ==0 if hidden diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 1b67ab4f4b24..2d6cda3d652a 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -1025,71 +1025,71 @@ static bool StringDiffer( const ScPatternAttr*& rpOldPattern, const ScPatternAtt { OSL_ENSURE( pNewPattern, "pNewPattern" ); - if ( pNewPattern == rpOldPattern ) + if ( SfxPoolItem::areSame( pNewPattern, rpOldPattern ) ) return false; else if ( !rpOldPattern ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT ) != &rpOldPattern->GetItem( ATTR_FONT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT ), &rpOldPattern->GetItem( ATTR_FONT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CJK_FONT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CJK_FONT ), &rpOldPattern->GetItem( ATTR_CJK_FONT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CTL_FONT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CTL_FONT ), &rpOldPattern->GetItem( ATTR_CTL_FONT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_HEIGHT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_HEIGHT ), &rpOldPattern->GetItem( ATTR_FONT_HEIGHT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CJK_FONT_HEIGHT ), &rpOldPattern->GetItem( ATTR_CJK_FONT_HEIGHT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CTL_FONT_HEIGHT ), &rpOldPattern->GetItem( ATTR_CTL_FONT_HEIGHT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_FONT_WEIGHT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_WEIGHT ), &rpOldPattern->GetItem( ATTR_FONT_WEIGHT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CJK_FONT_WEIGHT ), &rpOldPattern->GetItem( ATTR_CJK_FONT_WEIGHT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CTL_FONT_WEIGHT ), &rpOldPattern->GetItem( ATTR_CTL_FONT_WEIGHT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_FONT_POSTURE ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_POSTURE ), &rpOldPattern->GetItem( ATTR_FONT_POSTURE ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CJK_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CJK_FONT_POSTURE ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CJK_FONT_POSTURE ), &rpOldPattern->GetItem( ATTR_CJK_FONT_POSTURE ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_CTL_FONT_POSTURE ) != &rpOldPattern->GetItem( ATTR_CTL_FONT_POSTURE ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_CTL_FONT_POSTURE ), &rpOldPattern->GetItem( ATTR_CTL_FONT_POSTURE ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_UNDERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_UNDERLINE ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_UNDERLINE ), &rpOldPattern->GetItem( ATTR_FONT_UNDERLINE ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_OVERLINE ) != &rpOldPattern->GetItem( ATTR_FONT_OVERLINE ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_OVERLINE ), &rpOldPattern->GetItem( ATTR_FONT_OVERLINE ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_WORDLINE ) != &rpOldPattern->GetItem( ATTR_FONT_WORDLINE ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_WORDLINE ), &rpOldPattern->GetItem( ATTR_FONT_WORDLINE ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_CROSSEDOUT ) != &rpOldPattern->GetItem( ATTR_FONT_CROSSEDOUT ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_CROSSEDOUT ), &rpOldPattern->GetItem( ATTR_FONT_CROSSEDOUT ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_CONTOUR ) != &rpOldPattern->GetItem( ATTR_FONT_CONTOUR ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_CONTOUR ), &rpOldPattern->GetItem( ATTR_FONT_CONTOUR ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_SHADOWED ) != &rpOldPattern->GetItem( ATTR_FONT_SHADOWED ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_SHADOWED ), &rpOldPattern->GetItem( ATTR_FONT_SHADOWED ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_COLOR ) != &rpOldPattern->GetItem( ATTR_FONT_COLOR ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_COLOR ), &rpOldPattern->GetItem( ATTR_FONT_COLOR ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_HOR_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_HOR_JUSTIFY ), &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ) != &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ), &rpOldPattern->GetItem( ATTR_HOR_JUSTIFY_METHOD ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_VER_JUSTIFY ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_VER_JUSTIFY ), &rpOldPattern->GetItem( ATTR_VER_JUSTIFY ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ) != &rpOldPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ), &rpOldPattern->GetItem( ATTR_VER_JUSTIFY_METHOD ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_STACKED ) != &rpOldPattern->GetItem( ATTR_STACKED ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_STACKED ), &rpOldPattern->GetItem( ATTR_STACKED ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_LINEBREAK ) != &rpOldPattern->GetItem( ATTR_LINEBREAK ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_LINEBREAK ), &rpOldPattern->GetItem( ATTR_LINEBREAK ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_MARGIN ) != &rpOldPattern->GetItem( ATTR_MARGIN ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_MARGIN ), &rpOldPattern->GetItem( ATTR_MARGIN ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_ROTATE_VALUE ) != &rpOldPattern->GetItem( ATTR_ROTATE_VALUE ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_ROTATE_VALUE ), &rpOldPattern->GetItem( ATTR_ROTATE_VALUE ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FORBIDDEN_RULES ) != &rpOldPattern->GetItem( ATTR_FORBIDDEN_RULES ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FORBIDDEN_RULES ), &rpOldPattern->GetItem( ATTR_FORBIDDEN_RULES ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_EMPHASISMARK ) != &rpOldPattern->GetItem( ATTR_FONT_EMPHASISMARK ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_EMPHASISMARK ), &rpOldPattern->GetItem( ATTR_FONT_EMPHASISMARK ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_FONT_RELIEF ) != &rpOldPattern->GetItem( ATTR_FONT_RELIEF ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_FONT_RELIEF ), &rpOldPattern->GetItem( ATTR_FONT_RELIEF ) ) ) return true; - else if ( &pNewPattern->GetItem( ATTR_BACKGROUND ) != &rpOldPattern->GetItem( ATTR_BACKGROUND ) ) + else if ( !SfxPoolItem::areSame( &pNewPattern->GetItem( ATTR_BACKGROUND ), &rpOldPattern->GetItem( ATTR_BACKGROUND ) ) ) return true; // needed with automatic text color else { @@ -1714,7 +1714,7 @@ void ScOutputData::LayoutStrings(bool bPixelToLogic) if (nScript == SvtScriptType::NONE) nScript = ScGlobal::GetDefaultScriptType(); - if ( pPattern != pOldPattern || pCondSet != pOldCondSet || + if ( !SfxPoolItem::areSame(pPattern, pOldPattern) || pCondSet != pOldCondSet || nScript != nOldScript || mbSyntaxMode ) { if ( StringDiffer(pOldPattern,pPattern) || @@ -2488,7 +2488,7 @@ void ScOutputData::DrawEditParam::setPatternToEngine(bool bUseStyleColor) // syntax highlighting mode is ignored here // StringDiffer doesn't look at hyphenate, language items - if (mpPattern == mpOldPattern && mpCondSet == mpOldCondSet && mpPreviewFontSet == mpOldPreviewFontSet ) + if (SfxPoolItem::areSame(mpPattern, mpOldPattern) && mpCondSet == mpOldCondSet && mpPreviewFontSet == mpOldPreviewFontSet ) return; Color nConfBackColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor; @@ -4701,7 +4701,7 @@ void ScOutputData::DrawRotated(bool bPixelToLogic) // syntax mode is ignored here... // StringDiffer doesn't look at hyphenate, language items - if ( pPattern != pOldPattern || pCondSet != pOldCondSet ) + if ( !SfxPoolItem::areSame(pPattern, pOldPattern) || pCondSet != pOldCondSet ) { auto pSet = std::make_unique<SfxItemSet>( mxOutputEditEngine->GetEmptyItemSet() ); pPattern->FillEditItemSet( pSet.get(), pCondSet ); diff --git a/sc/source/ui/view/spelleng.cxx b/sc/source/ui/view/spelleng.cxx index f325d7dd556c..ae50d82930ee 100644 --- a/sc/source/ui/view/spelleng.cxx +++ b/sc/source/ui/view/spelleng.cxx @@ -209,7 +209,7 @@ bool ScConversionEngineBase::FindNextConversionCell() { // GetPattern may implicitly allocates the column if not exists, pPattern = mrDoc.GetPattern( nNewCol, nNewRow, mnStartTab ); - if( pPattern && (pPattern != pLastPattern) ) + if( pPattern && !SfxPoolItem::areSame(pPattern, pLastPattern) ) { pPattern->FillEditItemSet( &aEditDefaults ); SetDefaults( aEditDefaults ); diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx index 47a15f64a7c9..d253e8102396 100644 --- a/sc/source/ui/view/tabvwshc.cxx +++ b/sc/source/ui/view/tabvwshc.cxx @@ -440,7 +440,7 @@ std::shared_ptr<SfxModelessDialogController> ScTabViewShell::CreateRefDialogCont xResult = std::make_shared<ScCondFormatDlg>(pB, pCW, pParent, &rViewData, pDlgItem); // Remove the pool item stored by Conditional Format Manager Dialog. - GetPool().Remove(*pDlgItem); + GetPool().DirectRemoveItemFromPool(*pDlgItem); } break; diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index af0dc57357f9..cffb0dcab5c9 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -1050,8 +1050,8 @@ void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet, SfxItemSet& rNewSet = aNewAttrs.GetItemSet(); SfxItemPool* pNewPool = rNewSet.GetPool(); - pNewPool->Put(rNewOuter); // don't delete yet - pNewPool->Put(rNewInner); + pNewPool->DirectPutItemInPool(rNewOuter); // don't delete yet + pNewPool->DirectPutItemInPool(rNewInner); rNewSet.ClearItem( ATTR_BORDER ); rNewSet.ClearItem( ATTR_BORDER_INNER ); @@ -1065,7 +1065,7 @@ void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet, bool bFrame = (pDialogSet->GetItemState( ATTR_BORDER ) != SfxItemState::DEFAULT) || (pDialogSet->GetItemState( ATTR_BORDER_INNER ) != SfxItemState::DEFAULT); - if (&rNewOuter == &rOldOuter && &rNewInner == &rOldInner) + if (SfxPoolItem::areSame(&rNewOuter, &rOldOuter) && SfxPoolItem::areSame(&rNewInner, &rOldInner)) bFrame = false; // this should be intercepted by the pool: ?!??!?? @@ -1095,8 +1095,8 @@ void ScViewFunc::ApplyAttributes( const SfxItemSet* pDialogSet, bDefNewInner ? &rOldInner : &rNewInner ); } - pNewPool->Remove(rNewOuter); // release - pNewPool->Remove(rNewInner); + pNewPool->DirectRemoveItemFromPool(rNewOuter); // release + pNewPool->DirectRemoveItemFromPool(rNewInner); // adjust height only if needed if (bAdjustBlockHeight) diff --git a/sd/source/ui/func/fupage.cxx b/sd/source/ui/func/fupage.cxx index 4660c1d02d12..9401a56b30ec 100644 --- a/sd/source/ui/func/fupage.cxx +++ b/sd/source/ui/func/fupage.cxx @@ -373,7 +373,7 @@ const SfxItemSet* FuPage::ExecuteDialog(weld::Window* pParent, const SfxRequest& if( pTempSet->GetItemState( i ) == SfxItemState::DEFAULT ) pTempSet->Put( aMergedAttr.Get( i ) ); else - if( aMergedAttr.GetItem( i ) != pTempSet->GetItem( i ) ) + if( !SfxPoolItem::areSame(aMergedAttr.GetItem( i ), pTempSet->GetItem( i ) ) ) bChanges = true; } } diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index 77aeb444979c..802aab269e46 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -1383,12 +1383,13 @@ uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( const OUString& Property for(sal_uInt16 nWhichId : aWhichIds) { - sal_uInt32 nItems = rPool.GetItemCount2( nWhichId ); + const registeredSfxPoolItems& rSurrogates(rPool.GetItemSurrogates(nWhichId)); + const sal_uInt32 nItems(rSurrogates.size()); aSeq.realloc( aSeq.getLength() + nItems*5 + 5 ); auto pSeq = aSeq.getArray(); - for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId)) + for (const SfxPoolItem* pItem : rSurrogates) { const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem); diff --git a/sfx2/source/control/shell.cxx b/sfx2/source/control/shell.cxx index 5cba99c231d5..f4b2960da34b 100644 --- a/sfx2/source/control/shell.cxx +++ b/sfx2/source/control/shell.cxx @@ -158,7 +158,7 @@ void SfxShell::PutItem which is stored in the SfxShell in a list. */ ) { - DBG_ASSERT( dynamic_cast< const SfxSetItem* >( &rItem) == nullptr, "SetItems aren't allowed here" ); + DBG_ASSERT( !rItem.isSetItem(), "SetItems aren't allowed here" ); DBG_ASSERT( SfxItemPool::IsSlot( rItem.Which() ), "items with Which-Ids aren't allowed here" ); diff --git a/sfx2/source/control/statcach.cxx b/sfx2/source/control/statcach.cxx index cf059affbed1..2346333fd06a 100644 --- a/sfx2/source/control/statcach.cxx +++ b/sfx2/source/control/statcach.cxx @@ -404,14 +404,7 @@ void SfxStateCache::SetState_Impl bool bNotify = bItemDirty; if ( !bItemDirty ) { - bool bBothAvailable = pLastItem && pState && - !IsInvalidItem(pState) && !IsInvalidItem(pLastItem); - DBG_ASSERT( !bBothAvailable || pState != pLastItem, "setting state with own item" ); - if ( bBothAvailable ) - bNotify = typeid(*pState) != typeid(*pLastItem) || - *pState != *pLastItem; - else - bNotify = ( pState != pLastItem ) || ( eState != eLastState ); + bNotify = !SfxPoolItem::areSame(pLastItem, pState) || (eState != eLastState); } if ( bNotify ) diff --git a/sfx2/source/dialog/dinfdlg.cxx b/sfx2/source/dialog/dinfdlg.cxx index c11419dc02d9..044757c6cdd2 100644 --- a/sfx2/source/dialog/dinfdlg.cxx +++ b/sfx2/source/dialog/dinfdlg.cxx @@ -731,7 +731,8 @@ bool SfxDocumentDescPage::FillItemSet(SfxItemSet *rSet) pInfo->setDescription( m_xCommentEd->get_text() ); } rSet->Put( *pInfo ); - if ( pInfo != m_pInfoItem ) + // ptr compare OK, pInfo was created above as temporary data holder + if ( !areSfxPoolItemPtrsEqual(pInfo, m_pInfoItem) ) { delete pInfo; } diff --git a/sfx2/source/explorer/nochaos.cxx b/sfx2/source/explorer/nochaos.cxx index 1ec9f106af93..999db2dd3de4 100644 --- a/sfx2/source/explorer/nochaos.cxx +++ b/sfx2/source/explorer/nochaos.cxx @@ -165,7 +165,7 @@ inline void CntStaticPoolDefaults_Impl::Insert( mvDefaults[ nPos ] = pItem; m_pItemInfos[ nPos ]._nSID = 0; - m_pItemInfos[ nPos ]._bPoolable = true; + m_pItemInfos[ nPos ]._bNeedsPoolRegistration = false; } diff --git a/svl/qa/unit/items/stylepool.cxx b/svl/qa/unit/items/stylepool.cxx index 94ff91aea73c..d852dd29a24c 100644 --- a/svl/qa/unit/items/stylepool.cxx +++ b/svl/qa/unit/items/stylepool.cxx @@ -26,7 +26,9 @@ CPPUNIT_TEST_FIXTURE(StylePoolTest, testIterationOrder) // Set up a style pool with multiple parents. SfxStringItem aDefault1(1); std::vector<SfxPoolItem*> aDefaults{ &aDefault1 }; - SfxItemInfo const aItems[] = { { 2, false } }; + SfxItemInfo const aItems[] = { // _nSID, _bNeedsPoolRegistration, _bShareable + { 2, false, false } + }; rtl::Reference<SfxItemPool> pPool = new SfxItemPool("test", 1, 1, aItems); pPool->SetDefaults(&aDefaults); diff --git a/svl/qa/unit/items/test_itempool.cxx b/svl/qa/unit/items/test_itempool.cxx index 339da002bfc1..c8e313bb61e5 100644 --- a/svl/qa/unit/items/test_itempool.cxx +++ b/svl/qa/unit/items/test_itempool.cxx @@ -35,63 +35,71 @@ class PoolItemTest : public CppUnit::TestFixture void PoolItemTest::testPool() { SfxItemInfo const aItems[] = - { { 4, true }, - { 3, false /* not poolable */ }, - { 2, false }, - { 1, false /* not poolable */} - }; + { + // _nSID, _bNeedsPoolRegistration, _bShareable + { 4, false, true }, + { 3, true, false /* test NeedsPoolRegistration */ }, + { 2, false, false }, + { 1, true, false /* test NeedsPoolRegistration */} + }; rtl::Reference<SfxItemPool> pPool = new SfxItemPool("testpool", 1, 4, aItems); - SfxItemPool_Impl *pImpl = SfxItemPool_Impl::GetImpl(pPool.get()); - CPPUNIT_ASSERT(pImpl != nullptr); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), pImpl->maPoolItemArrays.size()); // Poolable SfxVoidItem aItemOne( 1 ); SfxVoidItem aNotherOne( 1 ); { - CPPUNIT_ASSERT(pImpl->maPoolItemArrays[0].empty()); - const SfxPoolItem &rVal = pPool->Put(aItemOne); + CPPUNIT_ASSERT(nullptr == pPool->ppRegisteredSfxPoolItems); + const SfxPoolItem &rVal = pPool->DirectPutItemInPool(aItemOne); CPPUNIT_ASSERT(bool(rVal == aItemOne)); - CPPUNIT_ASSERT(!pImpl->maPoolItemArrays[0].empty()); - const SfxPoolItem &rVal2 = pPool->Put(aNotherOne); + CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems); + CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems[0]); + CPPUNIT_ASSERT(!pPool->ppRegisteredSfxPoolItems[0]->empty()); + const SfxPoolItem &rVal2 = pPool->DirectPutItemInPool(aNotherOne); CPPUNIT_ASSERT(bool(rVal2 == rVal)); - CPPUNIT_ASSERT_EQUAL(&rVal, &rVal2); + + // ITEM: With leaving the paradigm that internally an already + // existing Item with true = operator==() (which is very + // expensive) the ptr's are no longer required to be equal, + // but the content-compare *is* + CPPUNIT_ASSERT(SfxPoolItem::areSame(rVal, rVal2)); // Clones on Put ... - CPPUNIT_ASSERT(&rVal2 != &aItemOne); - CPPUNIT_ASSERT(&rVal2 != &aNotherOne); - CPPUNIT_ASSERT(&rVal != &aItemOne); - CPPUNIT_ASSERT(&rVal != &aNotherOne); + // ptr compare OK, we want to check just the ptrs here + CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &aItemOne)); + CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &aNotherOne)); + CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal, &aItemOne)); + CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal, &aNotherOne)); } // non-poolable SfxVoidItem aItemTwo( 2 ); SfxVoidItem aNotherTwo( 2 ); { - CPPUNIT_ASSERT(pImpl->maPoolItemArrays[1].empty()); - const SfxPoolItem &rVal = pPool->Put(aItemTwo); + CPPUNIT_ASSERT(nullptr == pPool->ppRegisteredSfxPoolItems[1]); + const SfxPoolItem &rVal = pPool->DirectPutItemInPool(aItemTwo); CPPUNIT_ASSERT(bool(rVal == aItemTwo)); - CPPUNIT_ASSERT(!pImpl->maPoolItemArrays[1].empty()); - - const SfxPoolItem &rVal2 = pPool->Put(aNotherTwo); + CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems[1]); + CPPUNIT_ASSERT(!pPool->ppRegisteredSfxPoolItems[1]->empty()); + const SfxPoolItem &rVal2 = pPool->DirectPutItemInPool(aNotherTwo); CPPUNIT_ASSERT(bool(rVal2 == rVal)); - CPPUNIT_ASSERT(&rVal2 != &rVal); + // ptr compare OK, we want to check just the ptrs here + CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &rVal)); } // Test removal. SfxVoidItem aRemoveFour(4); SfxVoidItem aNotherFour(4); - const SfxPoolItem &rKeyFour = pPool->Put(aRemoveFour); - pPool->Put(aNotherFour); - CPPUNIT_ASSERT(pImpl->maPoolItemArrays[3].size() > 0); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pImpl->maPoolItemArrays[3].size()); - pPool->Remove(rKeyFour); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pImpl->maPoolItemArrays[3].size()); - pPool->Put(aNotherFour); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pImpl->maPoolItemArrays[3].size()); + const SfxPoolItem &rKeyFour = pPool->DirectPutItemInPool(aRemoveFour); + pPool->DirectPutItemInPool(aNotherFour); + CPPUNIT_ASSERT(pPool->ppRegisteredSfxPoolItems[3]->size() > 0); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pPool->ppRegisteredSfxPoolItems[3]->size()); + pPool->DirectRemoveItemFromPool(rKeyFour); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pPool->ppRegisteredSfxPoolItems[3]->size()); + pPool->DirectPutItemInPool(aNotherFour); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pPool->ppRegisteredSfxPoolItems[3]->size()); } diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx index cc406f31e0a0..118deaf50e2e 100644 --- a/svl/source/inc/poolio.hxx +++ b/svl/source/inc/poolio.hxx @@ -31,128 +31,9 @@ class SfxPoolItem; class SfxItemPoolUser; -const sal_uInt32 SFX_ITEMS_DEFAULT = 0xfffffffe; - -static bool CompareSortablePoolItems(SfxPoolItem const* lhs, SfxPoolItem const* rhs) -{ - return (*lhs) < (*rhs); -} -/** - * This array contains a set of SfxPoolItems, if those items are - * poolable then each item has a unique set of properties, and we - * often search linearly to ensure uniqueness. If they are - * non-poolable we maintain an (often large) list of pointers. - */ -struct SfxPoolItemArray_Impl -{ -private: - o3tl::sorted_vector<SfxPoolItem*> maPoolItemSet; - // In some cases, e.g. subclasses of NameOrIndex, the parent class (NameOrIndex) is sortable, - // but the subclasses do not define an operator<, which means that we don't get an ordering - // strong enough to enforce uniqueness purely with operator<, which means we need to do - // a partial scan with operator== - std::vector<SfxPoolItem*> maSortablePoolItems; -public: - o3tl::sorted_vector<SfxPoolItem*>::const_iterator begin() const { return maPoolItemSet.begin(); } - o3tl::sorted_vector<SfxPoolItem*>::const_iterator end() const { return maPoolItemSet.end(); } - /// clear array of PoolItem variants after all PoolItems are deleted - /// or all ref counts are decreased - void clear(); - size_t size() const {return maPoolItemSet.size();} - bool empty() const {return maPoolItemSet.empty();} - o3tl::sorted_vector<SfxPoolItem*>::const_iterator find(SfxPoolItem* pItem) const { return maPoolItemSet.find(pItem); } - void insert(SfxPoolItem* pItem) - { - bool bInserted = maPoolItemSet.insert(pItem).second; - assert( bInserted && "duplicate item?" ); - (void)bInserted; - - if (pItem->IsSortable()) - { - // bail early if someone modified one of these things underneath me - assert( std::is_sorted_until(maSortablePoolItems.begin(), maSortablePoolItems.end(), CompareSortablePoolItems) == maSortablePoolItems.end()); - - auto it = std::lower_bound(maSortablePoolItems.begin(), maSortablePoolItems.end(), pItem, CompareSortablePoolItems); - maSortablePoolItems.insert(maSortablePoolItems.begin() + (it - maSortablePoolItems.begin()), pItem); - } - } - const SfxPoolItem* findByLessThan(const SfxPoolItem* pNeedle) const - { - // bail early if someone modified one of these things underneath me - assert( std::is_sorted_until(maSortablePoolItems.begin(), maSortablePoolItems.end(), CompareSortablePoolItems) == maSortablePoolItems.end()); - assert( maPoolItemSet.empty() || maPoolItemSet.front()->IsSortable() ); - - auto it = std::lower_bound(maSortablePoolItems.begin(), maSortablePoolItems.end(), pNeedle, CompareSortablePoolItems); - for (;;) - { - if (it == maSortablePoolItems.end()) - return nullptr; - if (*pNeedle < **it) - return nullptr; - if (*pNeedle == **it) - return *it; - ++it; - } - } - std::vector<const SfxPoolItem*> findSurrogateRange(const SfxPoolItem* pNeedle) const - { - std::vector<const SfxPoolItem*> rv; - if (!maSortablePoolItems.empty()) - { - // bail early if someone modified one of these things underneath me - assert( std::is_sorted_until(maSortablePoolItems.begin(), maSortablePoolItems.end(), CompareSortablePoolItems) == maSortablePoolItems.end()); - - auto range = std::equal_range(maSortablePoolItems.begin(), maSortablePoolItems.end(), pNeedle, CompareSortablePoolItems); - rv.reserve(std::distance(range.first, range.second)); - for (auto it = range.first; it != range.second; ++it) - rv.push_back(*it); - } - else - { - for (const SfxPoolItem* p : maPoolItemSet) - if (*pNeedle == *p) - rv.push_back(p); - } - return rv; - } - void erase(o3tl::sorted_vector<SfxPoolItem*>::const_iterator it) - { - auto pNeedle = *it; - if ((*it)->IsSortable()) - { - // bail early if someone modified one of these things underneath me - assert( std::is_sorted_until(maSortablePoolItems.begin(), maSortablePoolItems.end(), CompareSortablePoolItems) == maSortablePoolItems.end()); - - auto sortIt = std::lower_bound(maSortablePoolItems.begin(), maSortablePoolItems.end(), pNeedle, CompareSortablePoolItems); - for (;;) - { - if (sortIt == maSortablePoolItems.end()) - { - assert(false && "did not find item?"); - break; - } - if (*pNeedle < **sortIt) - { - assert(false && "did not find item?"); - break; - } - // need to compare by pointer here, since we might have duplicates - if (*sortIt == pNeedle) - { - maSortablePoolItems.erase(sortIt); - break; - } - ++sortIt; - } - } - maPoolItemSet.erase(it); - } -}; - struct SfxItemPool_Impl { SfxBroadcaster aBC; - std::vector<SfxPoolItemArray_Impl> maPoolItemArrays; OUString aName; std::vector<SfxPoolItem*> maPoolDefaults; std::vector<SfxPoolItem*>* mpStaticDefaults; @@ -164,8 +45,7 @@ struct SfxItemPool_Impl MapUnit eDefMetric; SfxItemPool_Impl( SfxItemPool* pMaster, OUString _aName, sal_uInt16 nStart, sal_uInt16 nEnd ) - : maPoolItemArrays(nEnd - nStart + 1) - , aName(std::move(_aName)) + : aName(std::move(_aName)) , maPoolDefaults(nEnd - nStart + 1) , mpStaticDefaults(nullptr) , mpMaster(pMaster) @@ -183,31 +63,11 @@ struct SfxItemPool_Impl void DeleteItems() { - maPoolItemArrays.clear(); maPoolDefaults.clear(); mpPoolRanges.reset(); } - - // unit testing - friend class PoolItemTest; - static SfxItemPool_Impl *GetImpl(SfxItemPool const *pPool) { return pPool->pImpl.get(); } }; - -#define SFX_ITEMPOOL_VER_MAJOR sal_uInt8(2) -#define SFX_ITEMPOOL_VER_MINOR sal_uInt8(0) - -#define SFX_ITEMPOOL_TAG_STARTPOOL_4 sal_uInt16(0x1111) -#define SFX_ITEMPOOL_TAG_STARTPOOL_5 sal_uInt16(0xBBBB) -#define SFX_ITEMPOOL_TAG_TRICK4OLD sal_uInt16(0xFFFF) - -#define SFX_ITEMPOOL_REC sal_uInt8(0x01) -#define SFX_ITEMPOOL_REC_HEADER sal_uInt8(0x10) -#define SFX_ITEMPOOL_REC_VERSIONMAP sal_uInt16(0x0020) -#define SFX_ITEMPOOL_REC_WHICHIDS sal_uInt16(0x0030) -#define SFX_ITEMPOOL_REC_ITEMS sal_uInt16(0x0040) -#define SFX_ITEMPOOL_REC_DEFAULTS sal_uInt16(0x0050) - #endif // INCLUDED_SVL_SOURCE_INC_POOLIO_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svl/source/items/custritm.cxx b/svl/source/items/custritm.cxx index 21c835ece189..0d68b6d4559f 100644 --- a/svl/source/items/custritm.cxx +++ b/svl/source/items/custritm.cxx @@ -33,14 +33,6 @@ bool CntUnencodedStringItem::operator ==(const SfxPoolItem & rItem) const m_aValue; } -bool CntUnencodedStringItem::operator<(const SfxPoolItem & rItem) const -{ - assert(dynamic_cast<const CntUnencodedStringItem*>( &rItem )); - return m_aValue - < static_cast< const CntUnencodedStringItem * >(&rItem)-> - m_aValue; -} - // virtual bool CntUnencodedStringItem::GetPresentation(SfxItemPresentation, MapUnit, MapUnit, OUString & rText, diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx index 525adf309fb8..0d3275471eac 100644 --- a/svl/source/items/itempool.cxx +++ b/svl/source/items/itempool.cxx @@ -34,6 +34,170 @@ #include <cassert> #include <vector> +#ifdef DBG_UTIL +static size_t nAllDirectlyPooledSfxPoolItemCount(0); +static size_t nRemainingDirectlyPooledSfxPoolItemCount(0); +size_t getAllDirectlyPooledSfxPoolItemCount() { return nAllDirectlyPooledSfxPoolItemCount; } +size_t getRemainingDirectlyPooledSfxPoolItemCount() { return nRemainingDirectlyPooledSfxPoolItemCount; } +#endif +// NOTE: Only needed for one Item in SC, see note in itemset.cxx +static bool g_bItemClassicMode(getenv("ITEM_CLASSIC_MODE")); + +// WhichIDs that need to set _bNeedsPoolRegistration in SfxItemInfo +// to true to allow a register of all items of that type/with that WhichID +// to be accessible using SfxItemPool::GetItemSurrogates. Created by +// grepping for 'GetItemSurrogates' usages & interpreting. Some +// are double, more may be necessary. There is a SAL_INFO("svl.items", ...) +// in SfxItemPool::GetItemSurrogates that will give hints on missing flags. +// +// due to SwTable::UpdateFields +// due to SwCursorShell::GotoNxtPrvTableFormula +// due to DocumentFieldsManager::UpdateTableFields +// due to SwTable::GatherFormulas +// RES_BOXATR_FORMULA ok +// due to SwContentTree::EditEntry +// due to SwDoc::FindINetAttr +// due to SwUndoResetAttr::RedoImpl +// due to SwContentTree::EditEntry +// due to SwContentTree::BringEntryToAttention +// RES_TXTATR_REFMARK ok +// due to ImpEditEngine::WriteRTF +// due to ScDocument::UpdateFontCharSet() +// due to ScXMLFontAutoStylePool_Impl +// due to SdXImpressDocument::getPropertyValue +// due to Writer::AddFontItems_ +// EE_CHAR_FONTINFO ok +// due to ImpEditEngine::WriteRTF +// due to ScXMLFontAutoStylePool_Impl +// due to SdXImpressDocument::getPropertyValue +// due to Writer::AddFontItems_ +// EE_CHAR_FONTINFO_CJK ok +// due to ImpEditEngine::WriteRTF +// due to ScXMLFontAutoStylePool_Impl +// due to SdXImpressDocument::getPropertyValue +// due to Writer::AddFontItems_ +// EE_CHAR_FONTINFO_CTL ok +// due to ImpEditEngine::WriteRTF +// EE_CHAR_COLOR ok +// due to ScDocumentPool::StyleDeleted +// ATTR_PATTERN ok +// due to ScDocument::UpdateFontCharSet() +// due to ScXMLFontAutoStylePool_Impl +// ATTR_FONT ok +// due to OptimizeHasAttrib +// ATTR_ROTATE_VALUE ok +// due to ScDocument::GetDocColors() +// ATTR_BACKGROUND ok +// ATTR_FONT_COLOR ok +// due to ScXMLExport::CollectUserDefinedNamespaces +// ATTR_USERDEF ok +// due to ScXMLExport::CollectUserDefinedNamespaces +// due to SwXMLExport::exportDoc +// EE_PARA_XMLATTRIBS ok +// due to ScXMLExport::CollectUserDefinedNamespaces +// due to SwXMLExport::exportDoc +// EE_CHAR_XMLATTRIBS ok +// due to ScXMLExport::CollectUserDefinedNamespaces +// due to SwXMLExport::exportDoc +// SDRATTR_XMLATTRIBUTES ok +// due to ScXMLFontAutoStylePool_Impl +// ATTR_CJK_FONT ok +// ATTR_CTL_FONT ok +// ATTR_PAGE_HEADERLEFT ok +// ATTR_PAGE_FOOTERLEFT ok +// ATTR_PAGE_HEADERRIGHT ok +// ATTR_PAGE_FOOTERRIGHT ok +// ATTR_PAGE_HEADERFIRST ok +// ATTR_PAGE_FOOTERFIRST ok +// due to ScCellShell::ExecuteEdit +// due to ScTabViewShell::CreateRefDialogController +// SCITEM_CONDFORMATDLGDATA ok +// due to SdDrawDocument::UpdatePageRelativeURLs +// EE_FEATURE_FIELD ok +// due to SvxUnoMarkerTable::replaceByName +// due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute +// due to XLineStartItem::checkForUniqueItem +// XATTR_LINESTART ok +// due to SvxUnoMarkerTable::replaceByName +// due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute +// due to XLineStartItem::checkForUniqueItem +// XATTR_LINEEND ok +// due to SvxUnoNameItemTable +// due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute +// due to NameOrIndex::CheckNamedItem all derived from NameOrIndex +// XATTR_FILLBITMAP ok +// due to SvxUnoNameItemTable +// due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute +// XATTR_LINEDASH ok +// due to SvxUnoNameItemTable +// due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute +// due to NameOrIndex::CheckNamedItem all derived from NameOrIndex +// XATTR_FILLGRADIENT ok +// due to SvxUnoNameItemTable +// due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute +// XATTR_FILLHATCH ok +// due to SvxUnoNameItemTable +// due to SvxShape::setPropertyValueImpl/SvxShape::SetFillAttribute +// XATTR_FILLFLOATTRANSPARENCE ok +// due to NamespaceIteratorImpl +// -> needs to be evaluated +// due to SwCursorShell::GotoNxtPrvTOXMark +// due to SwDoc::GetTOIKeys +// RES_TXTATR_TOXMARK ok +// due to SwDoc::GetRefMark +// due to SwDoc::CallEvent +// due to SwURLStateChanged::Notify +// due to SwHTMLWriter::CollectLinkTargets +// due to MSWordExportBase::CollectOutlineBookmarks +// RES_TXTATR_INETFMT ok +// due to SwDoc::GetAllUsedDB +// due to lcl_FindInputField +// due to SwViewShell::IsAnyFieldInDoc +// RES_TXTATR_FIELD ok +// due to SwDoc::GetAllUsedDB +// due to lcl_FindInputField +// due to SwViewShell::IsAnyFieldInDoc +// RES_TXTATR_INPUTFIELD ok +// due to SwDoc::SetDefault +// RES_PARATR_TABSTOP ok +// due to SwDoc::GetDocColors() +// due to RtfExport::OutColorTable +// RES_CHRATR_COLOR ok +// due to SwDoc::GetDocColors() +// RES_CHRATR_HIGHLIGHT ok +// due to SwDoc::GetDocColors() +// RES_BACKGROUND ok +// due to SwNode::FindPageDesc +// due to SwPageNumberFieldType::ChangeExpansion +// due to SwFrame::GetVirtPageNum +// RES_PAGEDESC ok +// due to SwAutoStylesEnumImpl:: +// RES_TXTATR_CJK_RUBY ok +// due to SwHTMLWriter::CollectLinkTargets +// due to MSWordExportBase::CollectOutlineBookmarks +// RES_URL +// due to RtfExport::OutColorTable +// RES_CHRATR_UNDERLINE ok +// RES_CHRATR_OVERLINE ok +// RES_CHRATR_BACKGROUND ok +// RES_SHADOW ok +// RES_BOX ok +// RES_CHRATR_BOX ok +// XATTR_FILLCOLOR ok +// due to wwFontHelper::InitFontTable +// due to SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl +// RES_CHRATR_FONT ok +// due to wwFontHelper::InitFontTable +// due to SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl +// RES_CHRATR_CJK_FONT ok +// due to wwFontHelper::InitFontTable +// due to SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl +// RES_CHRATR_CTL_FONT +// due to SwXMLExport::exportDoc +// RES_UNKNOWNATR_CONTAINER ok +// RES_TXTATR_UNKNOWN_CONTAINER ok + + #if OSL_DEBUG_LEVEL > 0 #include <map> @@ -85,15 +249,6 @@ do { \ #define CHECK_SLOTS() do {} while (false) #endif -/// clear array of PoolItem variants -/// after all PoolItems are deleted -/// or all ref counts are decreased -void SfxPoolItemArray_Impl::clear() -{ - maPoolItemSet.clear(); - maSortablePoolItems.clear(); -} - sal_uInt16 SfxItemPool::GetFirstWhich() const { return pImpl->mnStart; @@ -124,35 +279,6 @@ sal_uInt16 SfxItemPool::GetSize_Impl() const return pImpl->mnEnd - pImpl->mnStart + 1; } - -bool SfxItemPool::CheckItemInPool(const SfxPoolItem *pItem) const -{ - DBG_ASSERT( pItem, "no 0-Pointer Surrogate" ); - DBG_ASSERT( !IsInvalidItem(pItem), "no Invalid-Item Surrogate" ); - DBG_ASSERT( !IsPoolDefaultItem(pItem), "no Pool-Default-Item Surrogate" ); - - if ( !IsInRange(pItem->Which()) ) - { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->CheckItemInPool( pItem ); - SAL_WARN( "svl.items", "unknown Which-Id - don't ask me for surrogates, with ID/pos " << pItem->Which()); - } - - // Pointer on static or pool-default attribute? - if( IsStaticDefaultItem(pItem) || IsPoolDefaultItem(pItem) ) - return true; - - SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(pItem->Which())]; - - for ( auto p : rItemArr ) - { - if ( p == pItem ) - return true; - } - SAL_WARN( "svl.items", "Item not in the pool, with ID/pos " << pItem->Which()); - return false; -} - const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const { const SfxPoolItem* pRet; @@ -169,21 +295,30 @@ const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const } -bool SfxItemPool::IsItemPoolable_Impl( sal_uInt16 nPos ) const +bool SfxItemPool::NeedsPoolRegistration(sal_uInt16 nWhich) const { - return pItemInfos[nPos]._bPoolable; -} + if (!IsInRange(nWhich)) + { + // get to correct pool + if (pImpl->mpSecondary) + return pImpl->mpSecondary->NeedsPoolRegistration(nWhich); + return false; + } + return NeedsPoolRegistration_Impl(nWhich - pImpl->mnStart); +} -bool SfxItemPool::IsItemPoolable( sal_uInt16 nWhich ) const +bool SfxItemPool::Shareable(sal_uInt16 nWhich) const { - for ( const SfxItemPool *pPool = this; pPool; pPool = pPool->pImpl->mpSecondary.get() ) + if (!IsInRange(nWhich)) { - if ( pPool->IsInRange(nWhich) ) - return pPool->IsItemPoolable_Impl( pPool->GetIndex_Impl(nWhich)); + // get to correct pool + if (pImpl->mpSecondary) + return pImpl->mpSecondary->Shareable(nWhich); + return false; } - DBG_ASSERT( !IsWhich(nWhich), "unknown which-id" ); - return false; + + return Shareable_Impl(nWhich - pImpl->mnStart); } @@ -227,7 +362,8 @@ SfxItemPool::SfxItemPool but no transfer of ownership */ ) : pItemInfos(pInfo), - pImpl( new SfxItemPool_Impl( this, rName, nStartWhich, nEndWhich ) ) + pImpl( new SfxItemPool_Impl( this, rName, nStartWhich, nEndWhich ) ), + ppRegisteredSfxPoolItems(nullptr) { pImpl->eDefMetric = MapUnit::MapTwip; @@ -270,7 +406,8 @@ SfxItemPool::SfxItemPool ) : salhelper::SimpleReferenceObject(), pItemInfos(rPool.pItemInfos), - pImpl( new SfxItemPool_Impl( this, rPool.pImpl->aName, rPool.pImpl->mnStart, rPool.pImpl->mnEnd ) ) + pImpl( new SfxItemPool_Impl( this, rPool.pImpl->aName, rPool.pImpl->mnStart, rPool.pImpl->mnEnd ) ), + ppRegisteredSfxPoolItems(nullptr) { pImpl->eDefMetric = rPool.pImpl->eDefMetric; @@ -319,7 +456,8 @@ void SfxItemPool::SetDefaults( std::vector<SfxPoolItem*>* pDefaults ) assert( ((*pImpl->mpStaticDefaults)[n]->Which() == n + pImpl->mnStart) && "items ids in pool-ranges and in static-defaults do not match" ); (*pImpl->mpStaticDefaults)[n]->setStaticDefault(); - DBG_ASSERT( pImpl->maPoolItemArrays[n].empty(), "defaults with setitems with items?!" ); + DBG_ASSERT(nullptr == ppRegisteredSfxPoolItems || nullptr == ppRegisteredSfxPoolItems[n] + || ppRegisteredSfxPoolItems[n]->empty(), "defaults with setitems with items?!" ); } } } @@ -400,7 +538,9 @@ void SfxItemPool::ReleaseDefaults SfxItemPool::~SfxItemPool() { - if ( !pImpl->maPoolItemArrays.empty() && !pImpl->maPoolDefaults.empty() ) + // Need to be deleted? + // Caution: ppRegisteredSfxPoolItems is on-demand created and can be nullptr + if ( nullptr != ppRegisteredSfxPoolItems || !pImpl->maPoolDefaults.empty() ) Delete(); if (pImpl->mpMaster != nullptr && pImpl->mpMaster != this) @@ -421,26 +561,33 @@ void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool ) if ( pImpl->mpSecondary ) { #ifdef DBG_UTIL - if (pImpl->mpStaticDefaults != nullptr && !pImpl->maPoolItemArrays.empty() - && !pImpl->mpSecondary->pImpl->maPoolItemArrays.empty()) + if (nullptr != pImpl->mpStaticDefaults + && nullptr != ppRegisteredSfxPoolItems + && nullptr != pImpl->mpSecondary->ppRegisteredSfxPoolItems) // Delete() did not yet run? { - // Does the Master have SetItems? - bool bHasSetItems = false; - for ( sal_uInt16 i = 0; !bHasSetItems && i < pImpl->mnEnd - pImpl->mnStart; ++i ) - bHasSetItems = dynamic_cast<const SfxSetItem *>((*pImpl->mpStaticDefaults)[i]) != nullptr; - - // Detached Pools must be empty - bool bOK = bHasSetItems; - for (auto const& rSecArray : pImpl->mpSecondary->pImpl->maPoolItemArrays) + // Does the Master have SetItems? + bool bHasSetItems(false); + + for (sal_uInt16 i(0); !bHasSetItems && i < pImpl->mnEnd - pImpl->mnStart; ++i) + { + const SfxPoolItem* pStaticDefaultItem((*pImpl->mpStaticDefaults)[i]); + bHasSetItems = pStaticDefaultItem->isSetItem(); + } + + if (bHasSetItems) { - if (!bOK) - break; - if (rSecArray.size()>0) + // Detached Pools must be empty + registeredSfxPoolItems** ppSet(pImpl->mpSecondary->ppRegisteredSfxPoolItems); + + for (sal_uInt16 a(0); a < pImpl->mpSecondary->GetSize_Impl(); a++, ppSet++) { - SAL_WARN("svl.items", "old secondary pool: " << pImpl->mpSecondary->pImpl->aName - << " of pool: " << pImpl->aName << " must be empty."); - break; + if (nullptr != *ppSet && (*ppSet)->size() != 0) + { + SAL_WARN("svl.items", "old secondary pool: " << pImpl->mpSecondary->pImpl->aName + << " of pool: " << pImpl->aName << " must be empty."); + break; + } } } } @@ -515,24 +662,26 @@ rtl::Reference<SfxItemPool> SfxItemPool::Clone() const void SfxItemPool::Delete() { // Already deleted? - if (pImpl->maPoolItemArrays.empty() || pImpl->maPoolDefaults.empty()) + // Caution: ppRegisteredSfxPoolItems is on-demand created and can be nullptr + if (nullptr == ppRegisteredSfxPoolItems && pImpl->maPoolDefaults.empty()) return; // Inform e.g. running Requests pImpl->aBC.Broadcast( SfxHint( SfxHintId::Dying ) ); // Iterate through twice: first for the SetItems. - if (pImpl->mpStaticDefaults != nullptr) { + if (nullptr != pImpl->mpStaticDefaults && nullptr != ppRegisteredSfxPoolItems) + { for (size_t n = 0; n < GetSize_Impl(); ++n) { // *mpStaticDefaultItem could've already been deleted in a class derived // from SfxItemPool // This causes chaos in Itempool! - const SfxPoolItem* pStaticDefaultItem = (*pImpl->mpStaticDefaults)[n]; - if (dynamic_cast<const SfxSetItem*>(pStaticDefaultItem)) + const SfxPoolItem* pStaticDefaultItem((*pImpl->mpStaticDefaults)[n]); + if (pStaticDefaultItem->isSetItem() && nullptr != ppRegisteredSfxPoolItems[n]) { // SfxSetItem found, remove PoolItems (and defaults) with same ID - auto& rArray = pImpl->maPoolItemArrays[n]; + auto& rArray(*(ppRegisteredSfxPoolItems[n])); for (auto& rItemPtr : rArray) { ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor @@ -553,18 +702,32 @@ void SfxItemPool::Delete() } } - // now remove remaining PoolItems (and defaults) who didn't have SetItems - for (auto& rArray : pImpl->maPoolItemArrays) + if (nullptr != ppRegisteredSfxPoolItems) { - for (auto& rItemPtr : rArray) + registeredSfxPoolItems** ppSet(ppRegisteredSfxPoolItems); + + for (sal_uInt16 a(0); a < GetSize_Impl(); a++, ppSet++) { - ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor - delete rItemPtr; + if (nullptr != *ppSet) + { + for (auto& rCandidate : **ppSet) + { + if (nullptr != rCandidate && !IsDefaultItem(rCandidate)) + { + ReleaseRef(*rCandidate, rCandidate->GetRefCount()); // for RefCount check in dtor + delete rCandidate; + } + } + + delete *ppSet; + *ppSet = nullptr; + } } - rArray.clear(); - // let pImpl->DeleteItems() delete item arrays in maPoolItems + + delete[] ppRegisteredSfxPoolItems; + ppRegisteredSfxPoolItems = nullptr; } - pImpl->maPoolItemArrays.clear(); + // default items for (auto rItemPtr : pImpl->maPoolDefaults) { @@ -631,189 +794,40 @@ void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId ) } } - -const SfxPoolItem& SfxItemPool::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership ) +const SfxPoolItem& SfxItemPool::DirectPutItemInPoolImpl(const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership) { - if ( 0 == nWhich ) - nWhich = rItem.Which(); - - // Find correct Secondary Pool - bool bSID = IsSlot(nWhich); - if ( !bSID && !IsInRange(nWhich) ) - { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->PutImpl( rItem, nWhich, bPassingOwnership ); - OSL_FAIL( "unknown WhichId - cannot put item" ); - } - - // SID ? - if (bSID) - { - assert((rItem.Which() != nWhich || - !IsDefaultItem(&rItem) || rItem.isDeleteOnIdle()) - && "a non Pool Item is Default?!"); - SfxPoolItem *pPoolItem = rItem.Clone(pImpl->mpMaster); - pPoolItem->SetWhich(nWhich); - AddRef( *pPoolItem ); - if (bPassingOwnership) - delete &rItem; - return *pPoolItem; - } - - assert(!pImpl->mpStaticDefaults || - typeid(rItem) == typeid(GetDefaultItem(nWhich))); - - const sal_uInt16 nIndex = GetIndex_Impl(nWhich); - SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[nIndex]; - - // Is this a 'poolable' item - ie. should we re-use and return - // the same underlying item for equivalent (==) SfxPoolItems? - if ( IsItemPoolable_Impl( nIndex ) ) - { - // if is already in a pool, then it is worth checking if it is in this one. - if ( IsPooledItem(&rItem) ) - { - // 1. search for an identical pointer in the pool - auto it = rItemArr.find(const_cast<SfxPoolItem *>(&rItem)); - if (it != rItemArr.end()) - { - AddRef(rItem); - assert(!bPassingOwnership && "can't be passing ownership and have the item already in the pool"); - return rItem; - } - } - - const SfxPoolItem* pFoundItem = nullptr; - // 2. search for an item with matching attributes. - if (rItem.IsSortable()) - { - pFoundItem = rItemArr.findByLessThan(&rItem); - if (pFoundItem) - assert(*pFoundItem == rItem); - } - else if(rItem.HasLookup()) - { - auto it = rItem.Lookup(rItemArr.begin(), rItemArr.end()); - if( it != rItemArr.end()) - pFoundItem = *it; - } - else - { - for (auto it = rItemArr.begin(); it != rItemArr.end(); ++it) - { - if (**it == rItem) - { - pFoundItem = *it; - break; - } - } - } - if (pFoundItem) - { - assert((!bPassingOwnership || (&rItem != pFoundItem)) && "can't be passing ownership and have the item already in the pool"); - AddRef(*pFoundItem); - if (bPassingOwnership) - delete &rItem; - return *pFoundItem; - } - } - - // 3. not found, so clone to insert into the pointer array. - SfxPoolItem* pNewItem; - if (bPassingOwnership) - { -#ifndef NDEBUG - if (auto pSetItem = dynamic_cast<const SfxSetItem*>(&rItem)) - assert(pSetItem->GetItemSet().GetPool() == pImpl->mpMaster && "can't pass ownership of SfxSetItem, unless they have been cloned to the master pool"); -#endif - pNewItem = const_cast<SfxPoolItem*>(&rItem); - } - else - pNewItem = rItem.Clone(pImpl->mpMaster); - pNewItem->SetWhich(nWhich); - assert(typeid(rItem) == typeid(*pNewItem) && "SfxItemPool::Put(): unequal types, no Clone() override?"); -#ifndef NDEBUG - if (dynamic_cast<const SfxSetItem*>(&rItem) == nullptr) - { - assert((!IsItemPoolable(nWhich) || rItem == *pNewItem) - && "SfxItemPool::Put(): unequal items: no operator== override?"); - assert((!IsItemPoolable(*pNewItem) || *pNewItem == rItem) - && "SfxItemPool::Put(): unequal items: no operator== override?"); - } +#ifdef DBG_UTIL + nAllDirectlyPooledSfxPoolItemCount++; + nRemainingDirectlyPooledSfxPoolItemCount++; #endif - AddRef( *pNewItem ); - // 4. finally insert into the pointer array - rItemArr.insert( pNewItem ); - return *pNewItem; + // make sure to use 'master'-pool, that's the one used by SfxItemSets + return *implCreateItemEntry(*GetMasterPool(), &rItem, nWhich, bPassingOwnership, true); } -void SfxItemPool::Remove( const SfxPoolItem& rItem ) +void SfxItemPool::DirectRemoveItemFromPool(const SfxPoolItem& rItem) { - assert(!IsPoolDefaultItem(&rItem) && "cannot remove Pool Default"); - - // Find correct Secondary Pool - const sal_uInt16 nWhich = rItem.Which(); - bool bSID = IsSlot(nWhich); - if ( !bSID && !IsInRange(nWhich) ) - { - if ( pImpl->mpSecondary ) - { - pImpl->mpSecondary->Remove( rItem ); - return; - } - OSL_FAIL( "unknown WhichId - cannot remove item" ); - } - - // SID ? - if ( bSID ) - { - assert(!IsDefaultItem(&rItem) && "a non Pool Item is Default?!"); - if ( 0 == ReleaseRef(rItem) ) - { - delete &rItem; - } - return; - } - - const sal_uInt16 nIndex = GetIndex_Impl(nWhich); - // Static Defaults are just there - if ( IsStaticDefaultItem(&rItem) && - &rItem == (*pImpl->mpStaticDefaults)[nIndex]) - return; - - // moved below StaticDefaultItem detection - StaticDefaultItems - // do not need a RefCnt of SFX_ITEMS_SPECIAL (0xffffffff) anymore - assert(rItem.GetRefCount() && "RefCount == 0, Remove impossible"); - - // Find Item in own Pool - SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[nIndex]; - - auto it = rItemArr.find(const_cast<SfxPoolItem *>(&rItem)); - if (it != rItemArr.end()) - { - if ( rItem.GetRefCount() ) //! - ReleaseRef( rItem ); - else - { - assert(false && "removing Item without ref"); - } - - // FIXME: Hack, for as long as we have problems with the Outliner - // See other MI-REF - if ( 0 == rItem.GetRefCount() && nWhich < 4000 ) - { - rItemArr.erase(it); - delete &rItem; - } +#ifdef DBG_UTIL + nRemainingDirectlyPooledSfxPoolItemCount--; +#endif - return; - } + // make sure to use 'master'-pool, that's the one used by SfxItemSets + implCleanupItemEntry(*GetMasterPool(), &rItem); + return; +} - // not found - assert(false && "removing Item not in Pool"); +void SfxItemPool::newItem_Callback(const SfxPoolItem& rItem) const +{ + if (!IsInRange(rItem.Which()) && pImpl->mpSecondary) + pImpl->mpSecondary->newItem_Callback(rItem); } +bool SfxItemPool::newItem_UseDirect(const SfxPoolItem& rItem) const +{ + if (!IsInRange(rItem.Which()) && pImpl->mpSecondary) + return pImpl->mpSecondary->newItem_UseDirect(rItem); + return false; +} const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const { @@ -893,51 +907,93 @@ const SfxPoolItem *SfxItemPool::GetItem2Default(sal_uInt16 nWhich) const return (*pImpl->mpStaticDefaults)[ GetIndex_Impl(nWhich) ]; } -SfxItemPool::Item2Range SfxItemPool::GetItemSurrogates(sal_uInt16 nWhich) const +#ifdef DBG_UTIL +static void warnForMissingPoolRegistration(const SfxItemPool& rPool, sal_uInt16 nWhich) { - static const o3tl::sorted_vector<SfxPoolItem*> EMPTY; + if (!rPool.NeedsPoolRegistration(nWhich)) + SAL_INFO("svl.items", "ITEM: ItemSurrogate requested for WhichID " << nWhich << + " class " << typeid(rPool.GetDefaultItem(nWhich)).name() << + ": needs _bNeedsPoolRegistration==true in SfxItemInfo for that slot"); +} +#endif - if ( !IsInRange(nWhich) ) +const registeredSfxPoolItems& SfxItemPool::GetItemSurrogates(sal_uInt16 nWhich) const +{ + static const registeredSfxPoolItems EMPTY; + + if (!IsInRange(nWhich)) { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->GetItemSurrogates( nWhich ); - assert(false && "unknown WhichId - cannot resolve surrogate"); - return { EMPTY.end(), EMPTY.end() }; + if (pImpl->mpSecondary) + return pImpl->mpSecondary->GetItemSurrogates(nWhich); + return EMPTY; } - SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(nWhich)]; - return { rItemArr.begin(), rItemArr.end() }; + if (nullptr == ppRegisteredSfxPoolItems) + { +#ifdef DBG_UTIL + warnForMissingPoolRegistration(*this, nWhich); +#endif + return EMPTY; + } + + registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nWhich - pImpl->mnStart]); + + if (nullptr == pSet) + { +#ifdef DBG_UTIL + warnForMissingPoolRegistration(*this, nWhich); +#endif + return EMPTY; + } + + return *pSet; } -/* This is only valid for SfxPoolItem that override IsSortable and operator< */ std::vector<const SfxPoolItem*> SfxItemPool::FindItemSurrogate(sal_uInt16 nWhich, SfxPoolItem const & rSample) const { + static const std::vector<const SfxPoolItem*> EMPTY; + + if (nullptr == ppRegisteredSfxPoolItems) + return EMPTY; + if ( !IsInRange(nWhich) ) { if ( pImpl->mpSecondary ) return pImpl->mpSecondary->FindItemSurrogate( nWhich, rSample ); assert(false && "unknown WhichId - cannot resolve surrogate"); - return std::vector<const SfxPoolItem*>(); + return EMPTY; } - SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(nWhich)]; - return rItemArr.findSurrogateRange(&rSample); -} + // get index (must exist due to checks above) + const sal_uInt16 nIndex(rSample.Which() - pImpl->mnStart); -sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const -{ - if ( !IsInRange(nWhich) ) + if (nullptr == ppRegisteredSfxPoolItems) { - if ( pImpl->mpSecondary ) - return pImpl->mpSecondary->GetItemCount2( nWhich ); - assert(false && "unknown WhichId - cannot resolve surrogate"); - return 0; +#ifdef DBG_UTIL + warnForMissingPoolRegistration(*this, nWhich); +#endif + return EMPTY; } - SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(nWhich)]; - return rItemArr.size(); -} + // get registeredSfxPoolItems container + registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); + if (nullptr == pSet) + { +#ifdef DBG_UTIL + warnForMissingPoolRegistration(*this, nWhich); +#endif + return EMPTY; + } + + std::vector<const SfxPoolItem*> rv; + + for (const SfxPoolItem* p : *pSet) + if (rSample == *p) + rv.push_back(p); + + return rv; +} sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, bool bDeep ) const { @@ -1002,12 +1058,219 @@ sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich ) const return pItemInfos[nWhich - pImpl->mnStart]._nSID; } +void SfxItemPool::tryRegisterSfxPoolItem(const SfxPoolItem& rItem, bool bPoolDirect) +{ + assert(rItem.Which() != 0); + + if (IsSlot(rItem.Which())) + // do not register SlotItems + return; + + if (rItem.isRegisteredAtPool()) + // already registered, done (should not happen) + return; + + if (!IsInRange(rItem.Which())) + { + // get to the right pool + if (pImpl->mpSecondary) + { + pImpl->mpSecondary->tryRegisterSfxPoolItem(rItem, bPoolDirect); + return; + } + + return; + } + + // get index (must exist due to checks above) + const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart); + bool bRegisterItem(bPoolDirect); + + if (!bRegisterItem) + { + if (g_bItemClassicMode) + { + // classic mode: register in general *all* items + // ...but only shareable ones: for non-shareable registering for re-use + // makes no sense + bRegisterItem = Shareable_Impl(nIndex); + } + else + { + // experimental mode: only register items that are defined to be registered + bRegisterItem = NeedsPoolRegistration_Impl(nIndex); + } + } + + if (bRegisterItem) + doRegisterSfxPoolItem(rItem); +} + +void SfxItemPool::doRegisterSfxPoolItem(const SfxPoolItem& rItem) +{ + assert(rItem.Which() != 0); + + if (IsSlot(rItem.Which())) + // do not register SlotItems + return; + + if (rItem.isRegisteredAtPool()) + // already registered, done + return; + + if (nullptr == ppRegisteredSfxPoolItems) + // on-demand allocate array of registeredSfxPoolItems and init to nullptr + ppRegisteredSfxPoolItems = new registeredSfxPoolItems*[GetSize_Impl()]{}; + + // get correct registeredSfxPoolItems + const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart); + registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); + + if (nullptr == pSet) + // on-demand allocate + ppRegisteredSfxPoolItems[nIndex] = pSet = new registeredSfxPoolItems; + + // insert to registeredSfxPoolItems and set flag at Item + pSet->insert(&rItem); + const_cast<SfxPoolItem&>(rItem).setRegisteredAtPool(true); +} + +void SfxItemPool::unregisterSfxPoolItem(const SfxPoolItem& rItem) +{ + if (!rItem.isRegisteredAtPool()) + // Item is not registered, done + return; + + if (!IsInRange(rItem.Which())) + { + // get to the right pool + if (pImpl->mpSecondary) + { + pImpl->mpSecondary->unregisterSfxPoolItem(rItem); + return; + } + + assert(false && "unknown WhichId - cannot execute unregisterSfxPoolItem"); + return; + } + + // we need a valid WhichID and the array of containers has to exist + assert(rItem.Which() != 0); + assert(nullptr != ppRegisteredSfxPoolItems); + + // get index (must exist due to checks above) + const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart); + + // a valid registeredSfxPoolItems container has to exist + registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); + assert(nullptr != pSet); + + // remove registered Item and reset flag at Item + pSet->erase(&rItem); + const_cast<SfxPoolItem&>(rItem).setRegisteredAtPool(false); +} + +bool SfxItemPool::isSfxPoolItemRegisteredAtThisPool(const SfxPoolItem& rItem) const +{ + if (!rItem.isRegisteredAtPool()) + // Item is not registered at all, so also not at this Pool + return false; + + if (IsSlot(rItem.Which())) + // do not check being registered for SlotItems + return false; + + if (!IsInRange(rItem.Which())) + { + // get to the right pool + if (pImpl->mpSecondary) + return pImpl->mpSecondary->isSfxPoolItemRegisteredAtThisPool(rItem); + return false; + } + + // we need a valid WhichID + assert(rItem.Which() != 0); + + if (nullptr == ppRegisteredSfxPoolItems) + // when no array of containers exists the Item is not registered + return false; + + // get index (must exist due to checks above) + const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart); + + // get registeredSfxPoolItems container + registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); + + if (nullptr == pSet) + // when no registeredSfxPoolItems container exists the Item is not registered + return false; + + // test if Item is registered + return pSet->find(&rItem) != pSet->end(); +} + +const SfxPoolItem* SfxItemPool::tryToGetEqualItem(const SfxPoolItem& rItem, sal_uInt16 nWhich) const +{ + if (IsSlot(nWhich)) + // SlotItems are not registered @pool and not in any range + return nullptr; + + if (!IsInRange(nWhich)) + { + // get to the right pool + if (pImpl->mpSecondary) + return pImpl->mpSecondary->tryToGetEqualItem(rItem, nWhich); + return nullptr; + } + + if (nullptr == ppRegisteredSfxPoolItems) + // no Items at all + return nullptr; + + // get index (must exist due to checks above) + const sal_uInt16 nIndex(nWhich - pImpl->mnStart); + + if (!Shareable_Impl(nIndex)) + // not shareable + return nullptr; + + // get registeredSfxPoolItems container + registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]); + + if (nullptr == pSet) + // no registeredSfxPoolItems for this WhichID + return nullptr; + + for (const auto& rCandidate : *pSet) + if (*rCandidate == rItem) + return rCandidate; + + return nullptr; +} + void SfxItemPool::dumpAsXml(xmlTextWriterPtr pWriter) const { (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxItemPool")); - for (auto const & rArray : pImpl->maPoolItemArrays) - for (auto const & rItem : rArray) - rItem->dumpAsXml(pWriter); + + if (nullptr != ppRegisteredSfxPoolItems) + { + registeredSfxPoolItems** ppSet(ppRegisteredSfxPoolItems); + + for (sal_uInt16 a(0); a < GetSize_Impl(); a++, ppSet++) + { + if (nullptr != *ppSet) + { + for (auto& rCandidate : **ppSet) + { + if (nullptr != rCandidate) + { + rCandidate->dumpAsXml(pWriter); + } + } + } + } + } + (void)xmlTextWriterEndElement(pWriter); } diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx index 62f4df050577..c3faecabb6f1 100644 --- a/svl/source/items/itemset.cxx +++ b/svl/source/items/itemset.cxx @@ -42,6 +42,11 @@ static size_t nUsedSfxItemSetCount(0); size_t getAllocatedSfxItemSetCount() { return nAllocatedSfxItemSetCount; } size_t getUsedSfxItemSetCount() { return nUsedSfxItemSetCount; } #endif +// NOTE: Only needed for one Item in SC (see notes below for +// ScPatternAttr/ATTR_PATTERN). Still keep it so that when errors +// come up to this change be able to quickly check using the +// fallback flag 'ITEM_CLASSIC_MODE' +static bool g_bItemClassicMode(getenv("ITEM_CLASSIC_MODE")); /** * Ctor for a SfxItemSet with exactly the Which Ranges, which are known to @@ -123,65 +128,235 @@ SfxItemSet::SfxItemSet(SfxItemPool& pool, WhichRangesContainer wids) assert(svl::detail::validRanges2(m_pWhichRanges)); } -SfxPoolItem const* SfxItemSet::implCreateItemEntry(SfxPoolItem const* pSource, sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership) +SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource, sal_uInt16 nWhich, bool bPassingOwnership, bool bPoolDirect) { if (nullptr == pSource) // SfxItemState::UNKNOWN aka current default (nullptr) - // just use nullptr + // just use/return nullptr return pSource; if (IsInvalidItem(pSource)) // SfxItemState::DONTCARE aka invalid item - // just use pSource which is INVALID_POOL_ITEM + // just use pSource which equals INVALID_POOL_ITEM + return pSource; + + if (pSource->isNewItemCallback() && rPool.GetMasterPool()->newItem_UseDirect(*pSource)) + // exceptional handling for *some* items, see SC + // (do not copy item: use directly, it is a pool default) return pSource; // CAUTION: static default items are not *that* static as it seems // (or: should be). If they are freed with the Pool (see - // ::ReleaseDefaults) they will be deleted. If the target pool is - // different from the source pool static default items from the - // source pool can be used that then might be deleted (sigh). - // A solution would be to change all pools to really work on - // static instances of default items. Another one would be to know - // here that the targetPool != sourcePool, so maybe extend - // bItemIsSetMember -> bSamePool. - // A good test for this is CppunitTest_chart2_uichart/testTdf98690. - // Until solving/cleaning up we unfortunately *have* to continue - // to clone static default items... - + // ::ReleaseDefaults) they will be deleted. Same is true for + // dynamic defaults. Thus currently no default can be shared + // at all since these may be deleted with the pool owning them. + // That these are not shared but cloned is ensured by those + // having a default RefCount of zero, so these are used merely as + // templates. // if (IsStaticDefaultItem(pSource)) - // // these Items are owned by the pool and not ref-counted. - // // they will exist while the pool exists, and thus the - // // ItemSet (this). // return pSource; if (0 == pSource->Which()) // These *should* be SfxVoidItem(0) the only Items with 0 == WhichID, - // these need to be cloned + // these need to be cloned (currently...) return pSource->Clone(); - if (pSource->isShareable() && bItemIsSetMember && IsPooledItem(pSource))//!IsPoolDefaultItem(pSource) && GetPool()->IsItemPoolable(*pSource)) + // get correct target WhichID + if (0 == nWhich) + nWhich = pSource->Which(); + + if (SfxItemPool::IsSlot(nWhich)) + { + // SlotItems were always cloned in original (even when bPassingOwnership), + // so do that here, too (but without bPassingOwnership). + // They do not need to be registerd at pool (actually impossible, pools + // do not have entries for SlotItems) so handle here early + if (!bPassingOwnership) + pSource = pSource->Clone(rPool.GetMasterPool()); + + if (pSource->Which() != nWhich) + const_cast<SfxPoolItem*>(pSource)->SetWhich(nWhich); + + pSource->AddRef(); + return pSource; + } + + // get the pool with which ItemSets have to work, plus get the + // pool at which the WhichID is defined, so calls to it do not + // have to do this repeatedly + SfxItemPool* pMasterPool(rPool.GetMasterPool()); + assert(nullptr != pMasterPool); + SfxItemPool* pTargetPool(pMasterPool); + while (!pTargetPool->IsInRange(nWhich)) + pTargetPool = pTargetPool->GetSecondaryPool(); + + // if this goes wrong, an Item with invalid ID for this pool is + // processed. This is not allowed (and should not happen, e.g. + // ItemSets already have WhichRanges that are checked against + // their Pool) + if (nullptr == pTargetPool) + { + assert(false); + return pSource; + } + + // CAUTION: Shareable_Impl and NeedsPoolRegistration_Impl + // use index, not WhichID (one more reason to change the Pools) + const sal_uInt16 nIndex(pTargetPool->GetIndex_Impl(nWhich)); + + // the Item itself is shareable when it already is used somewhere + // which is equlivalent to be referenced already. IsPooledItem also + // checked for SFX_ITEMS_MAXREF, that is not needed here. Use a + // fake 'while' loop and 'break' to make this better readable + + // only try to share items that are already shared somehow, else + // these items are probably not (heap) item-ptr's (but on the + // stack or else) + while(pSource->GetRefCount() > 0) { - // shortcut: if we know that the Item is already a member - // of another SfxItemSet we can just copy the pointer and increase RefCount + if (pSource->Which() != nWhich) + // If the target WhichID differs from the WhichID of a shared Item + // the item needs to be cloned. This happens, e.g. in + // ScPatternAttr::GetFromEditItemSet existing items with WhichIDs + // from EditEngine get set at a SetItem's ItemSet with different + // target ranges (e.g. look for ATTR_FONT_UNDERLINE) + break; + + if (!pTargetPool->Shareable_Impl(nIndex)) + // not shareable, done + break; + + // SfxSetItems cannot be shared if they are in/use another pool + if (pSource->isSetItem() && static_cast<const SfxSetItem*>(pSource)->GetItemSet().GetPool() != pMasterPool) + break; + + // If the Item is registered it is pool-dependent, so do not share when + // it is registered but not at this pool + if (pSource->isRegisteredAtPool() && !pTargetPool->isSfxPoolItemRegisteredAtThisPool(*pSource)) + break; + + // If we get here we can share the Item pSource->AddRef(); return pSource; } - // assign via Pool - return &GetPool()->PutImpl(*pSource, 0 == nWhich ? pSource->Which() : nWhich, bPassingOwnership); + // classic mode: try finding already existing item + // NOTE: bPoolDirect currently required due to DirectPutItemInPool and the + // self-handled Item ScPatternAttr/ATTR_PATTERN in SC, else e.g. + // testIteratorsDefPattern will fail in line 1306 + // NOTE: the UnitTest testIteratorsDefPattern claims that that Item "can be + // edited by the user" which explains why it breaks so many rules for Items, + // it behaves like an alien. That Item in the SC Pool claims to be a + // 'StaticDefault' and gets changed (..?) + // NOTE: despite 1st thinking that this can be limited to ScPatternAttr/ + // ATTR_PATTERN it also has to be applied to the range + // [ATTR_PATTERN_START, ATTR_PATTERN_END] *used* by ATTR_PATTERN, plus + // it, so it's [100 .. 155] and [156] in SC. For now, just use bPoolDirect. + // This needs to be cleaned-up somehow anyways + + // only do this if classic mode or required (calls from Pool::Direct*) + while(g_bItemClassicMode || bPoolDirect) + { + if (!pTargetPool->Shareable_Impl(nIndex)) + // not shareable, so no need to search for identical item + break; + + // try to get equal Item. This is the expensive part... + const SfxPoolItem* pExisting(pTargetPool->tryToGetEqualItem(*pSource, nWhich)); + + if (nullptr == pExisting) + // none found, done + break; + + if (0 == pExisting->GetRefCount()) + // do not share not-yet shared Items (should not happen) + break; + + if (bPassingOwnership) + // need to cleanup if we are offered to own pSource + delete pSource; + + // If we get here we can share the found Item + pExisting->AddRef(); + return pExisting; + } + + // check if the handed over and to be directly used item is a + // SfxSetItem, that would make it pool-dependent. It then must have + // the same target-pool, ensure that by the cost of cloning it + // (should not happen) + if (bPassingOwnership + && pSource->isSetItem() + && static_cast<const SfxSetItem*>(pSource)->GetItemSet().GetPool() != pMasterPool) + { + const SfxPoolItem* pOld(pSource); + pSource = pSource->Clone(pMasterPool); + delete pOld; + } + + // when we reach this line we know that we have to add/create a new item. If + // bPassingOwnership is given just use the item, else clone it + if (!bPassingOwnership) + pSource = pSource->Clone(pMasterPool); + + // ensure WhichID @Item + if (pSource->Which() != nWhich) + const_cast<SfxPoolItem*>(pSource)->SetWhich(nWhich); + + // increase RefCnt 0->1 + pSource->AddRef(); + + // Unfortunately e,g, SC does 'special' things for some new Items, + // so we need to give the opportunity for this. To limit this to + // the needed cases, use m_bNewItemCallback flag at item + if (pSource->isNewItemCallback()) + pMasterPool->newItem_Callback(*pSource); + + // try to register @Pool (only needed if not yet registered) + if (!pSource->isRegisteredAtPool()) + { + if (!bPoolDirect) // re-use bPoolDirect + { + if (g_bItemClassicMode) + { + // in classic mode register only/all shareable items + bPoolDirect = pTargetPool->Shareable_Impl(nIndex); + } + else + { + // in new mode register only/all items marked as need to be registered + bPoolDirect = pTargetPool->NeedsPoolRegistration_Impl(nIndex); + } + } + + if (bPoolDirect) + pTargetPool->doRegisterSfxPoolItem(*pSource); + } + + return pSource; } -void SfxItemSet::implCleanupItemEntry(SfxPoolItem const* pSource) +void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource) { - if (nullptr == pSource // no entry, done - || IsInvalidItem(pSource) // nothing to do for invalid item entries - || IsStaticDefaultItem(pSource)) // static default items are owned by the pool, nothing to do - { + if (nullptr == pSource) + // no entry, done + return; + + if (IsInvalidItem(pSource)) + // nothing to do for invalid item entries + return; + + if (pSource->isNewItemCallback() && rPool.GetMasterPool()->newItem_UseDirect(*pSource)) + // exceptional handling for *some* items, see SC + // do not delete Item, it is a pool default return; - } if (0 == pSource->Which()) { + // de-register when registered @pool + if (pSource->isRegisteredAtPool()) + rPool.unregisterSfxPoolItem(*pSource); + // These *should* be SfxVoidItem(0) the only Items with 0 == WhichID // and need to be deleted delete pSource; @@ -195,8 +370,20 @@ void SfxItemSet::implCleanupItemEntry(SfxPoolItem const* pSource) return; } - // Delete from Pool - GetPool()->Remove(*pSource); + if (IsDefaultItem(pSource)) + // default items (static and dynamic) are owned by the pool, do not delete + return; + + // decrease RefCnt before deleting (destructor asserts for it and that's + // good to find other errors) + pSource->ReleaseRef(); + + // de-register before deletion when registered @pool + if (pSource->isRegisteredAtPool()) + rPool.unregisterSfxPoolItem(*pSource); + + // delete Item + delete pSource; } SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) @@ -218,16 +405,23 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet ) return; } + if (0 == rASet.Count()) + { + // no Items set in source ItemSet, allocate new array + // *plus* init to nullptr + m_ppItems = new const SfxPoolItem* [TotalCount()]{}; + return; + } + // allocate new array (no need to initialize, will be done below) m_ppItems = new const SfxPoolItem* [TotalCount()]; // Copy attributes SfxPoolItem const** ppDst(m_ppItems); - const bool bSamePool(GetPool() == rASet.GetPool()); for (const auto& rSource : rASet) { - *ppDst = implCreateItemEntry(rSource, 0, bSamePool, false); + *ppDst = implCreateItemEntry(*GetPool(), rSource, 0, false, false); ppDst++; } @@ -339,7 +533,7 @@ sal_uInt16 SfxItemSet::ClearSingleItem_ForOffset( sal_uInt16 nOffset ) } // cleanup item & reset ptr - implCleanupItemEntry(*aEntry); + implCleanupItemEntry(*GetPool(), *aEntry); *aEntry = nullptr; return 1; @@ -359,7 +553,7 @@ sal_uInt16 SfxItemSet::ClearAllItemsImpl() m_aCallback(rCandidate, nullptr); } - implCleanupItemEntry(rCandidate); + implCleanupItemEntry(*GetPool(), rCandidate); } // remember count before resetting it, that is the retval @@ -460,7 +654,7 @@ bool SfxItemSet::HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem) const return bRet; } -const SfxPoolItem* SfxItemSet::PutImpl(const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership) +const SfxPoolItem* SfxItemSet::PutImpl(const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership) { bool bActionNeeded(0 != nWhich); sal_uInt16 nOffset(INVALID_WHICHPAIR_OFFSET); @@ -492,18 +686,8 @@ const SfxPoolItem* SfxItemSet::PutImpl(const SfxPoolItem& rItem, sal_uInt16 nWhi } else { - if (*aEntry == &rItem) - { - // Same Item already present (ptr compare)? - bActionNeeded = false; - } - else if (typeid(**aEntry) == typeid(rItem) && **aEntry == rItem) - { - // Same value already present (content compare)? - // NOTE: we can now use typeid since we do not have (-1) - // anymore for Invalid state -> safe - bActionNeeded = false; - } + // compare items, evtl. containing content compare + bActionNeeded = !SfxPoolItem::areSame(**aEntry, rItem); } } @@ -518,7 +702,7 @@ const SfxPoolItem* SfxItemSet::PutImpl(const SfxPoolItem& rItem, sal_uInt16 nWhi } // prepare new entry - SfxPoolItem const* pNew(implCreateItemEntry(&rItem, nWhich, bItemIsSetMember, bPassingOwnership)); + SfxPoolItem const* pNew(implCreateItemEntry(*GetPool(), &rItem, nWhich, bPassingOwnership, false)); // Notification-Callback if(m_aCallback) @@ -527,7 +711,7 @@ const SfxPoolItem* SfxItemSet::PutImpl(const SfxPoolItem& rItem, sal_uInt16 nWhi } // cleanup old entry & set entry at m_ppItems array - implCleanupItemEntry(*aEntry); + implCleanupItemEntry(*GetPool(), *aEntry); *aEntry = pNew; return pNew; @@ -541,7 +725,6 @@ bool SfxItemSet::Put(const SfxItemSet& rSource, bool bInvalidAsDefault) const_iterator aSource(rSource.begin()); sal_uInt16 nNumberToGo(rSource.Count()); - const bool bSamePool(GetPool() == rSource.GetPool()); bool bRetval(false); // iterate based on WhichIDs to have it available for evtl. PutImpl calls @@ -566,7 +749,7 @@ bool SfxItemSet::Put(const SfxItemSet& rSource, bool bInvalidAsDefault) } else { - bRetval |= nullptr != PutImpl(**aSource, nWhich, bSamePool, false); + bRetval |= nullptr != PutImpl(**aSource, nWhich, false); } } @@ -605,7 +788,6 @@ void SfxItemSet::PutExtended { // don't "optimize" with "if( rSource.Count()" because of dontcare + defaults const_iterator aSource(rSource.begin()); - const bool bSamePool(GetPool() == rSource.GetPool()); for (const WhichPair& rPair : rSource.GetRanges()) { @@ -619,7 +801,7 @@ void SfxItemSet::PutExtended switch (eDontCareAs) { case SfxItemState::SET: - PutImpl(rSource.GetPool()->GetDefaultItem(nWhich), nWhich, false, false); + PutImpl(rSource.GetPool()->GetDefaultItem(nWhich), nWhich, false); break; case SfxItemState::DEFAULT: @@ -637,7 +819,7 @@ void SfxItemSet::PutExtended else { // Item is set: - PutImpl(**aSource, nWhich, bSamePool, false); + PutImpl(**aSource, nWhich, false); } } else @@ -646,7 +828,7 @@ void SfxItemSet::PutExtended switch (eDefaultAs) { case SfxItemState::SET: - PutImpl(rSource.GetPool()->GetDefaultItem(nWhich), nWhich, false, false); + PutImpl(rSource.GetPool()->GetDefaultItem(nWhich), nWhich, false); break; case SfxItemState::DEFAULT: @@ -1111,7 +1293,7 @@ void SfxItemSet::Differentiate(const SfxItemSet& rSet) * dontcare unknown != sal_True - - - * unknown unknown != sal_True - - - */ -void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, bool bItemIsSetMember, bool bIgnoreDefaults) +void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, bool bIgnoreDefaults) { assert(ppFnd1 != nullptr && "Merging to 0-Item"); @@ -1129,7 +1311,7 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p else if ( pFnd2 && bIgnoreDefaults ) // Decision table: default, set, doesn't matter, sal_True - *ppFnd1 = implCreateItemEntry(pFnd2, 0, bItemIsSetMember, false); + *ppFnd1 = implCreateItemEntry(*GetPool(), pFnd2, 0, false, false); // *ppFnd1 = &GetPool()->Put( *pFnd2 ); if ( *ppFnd1 ) @@ -1146,7 +1328,7 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p **ppFnd1 != GetPool()->GetDefaultItem((*ppFnd1)->Which()) ) { // Decision table: set, default, !=, sal_False - implCleanupItemEntry(*ppFnd1); + implCleanupItemEntry(*GetPool(), *ppFnd1); // GetPool()->Remove( **ppFnd1 ); *ppFnd1 = INVALID_POOL_ITEM; } @@ -1159,7 +1341,7 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p { // Decision table: set, dontcare, doesn't matter, sal_False // or: set, dontcare, !=, sal_True - implCleanupItemEntry(*ppFnd1); + implCleanupItemEntry(*GetPool(), *ppFnd1); // GetPool()->Remove( **ppFnd1 ); *ppFnd1 = INVALID_POOL_ITEM; } @@ -1170,7 +1352,7 @@ void SfxItemSet::MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *p if ( **ppFnd1 != *pFnd2 ) { // Decision table: set, set, !=, doesn't matter - implCleanupItemEntry(*ppFnd1); + implCleanupItemEntry(*GetPool(), *ppFnd1); // GetPool()->Remove( **ppFnd1 ); *ppFnd1 = INVALID_POOL_ITEM; } @@ -1193,16 +1375,13 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet ) // evtl. could not find that WhichID in local WhichRanges // Better to loop over local WhichRanges (these get changed) and look // for Item with same WhichID in rSet, this is done now. - - const bool bSamePool(GetPool() == rSet.GetPool()); - if (GetRanges() == rSet.GetRanges()) { // loop over both & merge, WhichIDs are identical for (const_iterator dst(begin()), src(rSet.begin()); dst != end(); dst++, src++) { - MergeItem_Impl(dst, *src, bSamePool/*bItemIsSetMember*/, false/*bIgnoreDefaults*/); + MergeItem_Impl(dst, *src, false/*bIgnoreDefaults*/); } } else @@ -1220,7 +1399,7 @@ void SfxItemSet::MergeValues( const SfxItemSet& rSet ) if (INVALID_WHICHPAIR_OFFSET != nOffset) { // if entry with same WhichID exists in rSet, merge with local entry - MergeItem_Impl(dst, *(rSet.begin() + nOffset), bSamePool/*bItemIsSetMember*/, false/*bIgnoreDefaults*/); + MergeItem_Impl(dst, *(rSet.begin() + nOffset), false/*bIgnoreDefaults*/); } } } @@ -1237,7 +1416,7 @@ void SfxItemSet::MergeValue(const SfxPoolItem& rAttr, bool bIgnoreDefaults) if (INVALID_WHICHPAIR_OFFSET != nOffset) { - MergeItem_Impl(begin() + nOffset, &rAttr, false/*bItemIsSetMember*/, bIgnoreDefaults); + MergeItem_Impl(begin() + nOffset, &rAttr, bIgnoreDefaults); } } @@ -1271,7 +1450,7 @@ void SfxItemSet::InvalidateItem_ForOffset(sal_uInt16 nOffset) return; // cleanup entry - implCleanupItemEntry(*aFoundOne); + implCleanupItemEntry(*GetPool(), *aFoundOne); } // set new entry @@ -1329,14 +1508,11 @@ bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool bComparePool) const nWh; nWh = aIter.NextWhich() ) { - // If the pointer of the poolable Items are unequal, the Items must match + // If the pointer of the shareable Items are unequal, the Items must match const SfxPoolItem *pItem1 = nullptr, *pItem2 = nullptr; if ( GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWh, false, &pItem1 ) != rCmp.GetItemState_ForWhichID(SfxItemState::UNKNOWN, nWh, false, &pItem2 ) || - ( pItem1 != pItem2 && - ( !pItem1 || IsInvalidItem(pItem1) || - (GetPool()->IsItemPoolable(*pItem1) && - *pItem1 != *pItem2 ) ) ) ) + !SfxPoolItem::areSame(pItem1, pItem2)) return false; } @@ -1353,13 +1529,9 @@ bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool bComparePool) const const SfxPoolItem **ppItem2 = rCmp.m_ppItems; for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos ) { - // If the pointers of the poolable Items are not the same, the Items + // If the pointers of the shareable Items are not the same, the Items // must match - if ( *ppItem1 != *ppItem2 && - ( ( !*ppItem1 || !*ppItem2 ) || - ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) || - (!bDifferentPools && GetPool()->IsItemPoolable(**ppItem1)) || - **ppItem1 != **ppItem2 ) ) + if (!SfxPoolItem::areSame(*ppItem1, *ppItem2)) return false; ++ppItem1; @@ -1467,10 +1639,10 @@ SfxAllItemSet::SfxAllItemSet(const SfxAllItemSet &rCopy) /** * Putting with automatic extension of the WhichId with the ID of the Item. */ -const SfxPoolItem* SfxAllItemSet::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership ) +const SfxPoolItem* SfxAllItemSet::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership ) { MergeRange(nWhich, nWhich); - return SfxItemSet::PutImpl(rItem, nWhich, bItemIsSetMember, bPassingOwnership); + return SfxItemSet::PutImpl(rItem, nWhich, bPassingOwnership); } /** diff --git a/svl/source/items/poolcach.cxx b/svl/source/items/poolcach.cxx index 882510c5b425..957f9a37edb1 100644 --- a/svl/source/items/poolcach.cxx +++ b/svl/source/items/poolcach.cxx @@ -28,7 +28,7 @@ SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool, const SfxPoolItem *pPutItem ): pPool(pItemPool), pSetToPut( nullptr ), - pItemToPut( &pItemPool->Put(*pPutItem) ) + pItemToPut( &pItemPool->DirectPutItemInPool(*pPutItem) ) { DBG_ASSERT(pItemPool, "No Pool provided"); } @@ -47,12 +47,12 @@ SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool, SfxItemPoolCache::~SfxItemPoolCache() { for (const SfxItemModifyImpl & rImpl : m_aCache) { - pPool->Remove( *rImpl.pPoolItem ); - pPool->Remove( *rImpl.pOrigItem ); + pPool->DirectRemoveItemFromPool( *rImpl.pPoolItem ); + pPool->DirectRemoveItemFromPool( *rImpl.pOrigItem ); } if ( pItemToPut ) - pPool->Remove( *pItemToPut ); + pPool->DirectRemoveItemFromPool( *pItemToPut ); } @@ -65,13 +65,14 @@ const SfxSetItem& SfxItemPoolCache::ApplyTo( const SfxSetItem &rOrigItem ) // Find whether this Transformations ever occurred for (const SfxItemModifyImpl & rMapEntry : m_aCache) { - if ( rMapEntry.pOrigItem == &rOrigItem ) + // use Item PtrCompare OK + if ( areSfxPoolItemPtrsEqual(rMapEntry.pOrigItem, &rOrigItem) ) { - // Did anything change at all? - if ( rMapEntry.pPoolItem != &rOrigItem ) + // Did anything change at all? use Item PtrCompare OK + if ( !areSfxPoolItemPtrsEqual(rMapEntry.pPoolItem, &rOrigItem) ) { rMapEntry.pPoolItem->AddRef(2); // One for the cache - pPool->Put( rOrigItem ); //FIXME: AddRef? + pPool->DirectPutItemInPool( rOrigItem ); //FIXME: AddRef? } return *rMapEntry.pPoolItem; } @@ -82,16 +83,16 @@ const SfxSetItem& SfxItemPoolCache::ApplyTo( const SfxSetItem &rOrigItem ) if ( pItemToPut ) { pNewItem->GetItemSet().Put( *pItemToPut ); - DBG_ASSERT( &pNewItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut, + DBG_ASSERT( areSfxPoolItemPtrsEqual(&pNewItem->GetItemSet().Get( pItemToPut->Which() ), pItemToPut), "wrong item in temporary set" ); } else pNewItem->GetItemSet().Put( *pSetToPut ); - const SfxSetItem* pNewPoolItem = &pPool->Put( std::move(pNewItem) ); + const SfxSetItem* pNewPoolItem = &pPool->DirectPutItemInPool( std::move(pNewItem) ); // Adapt refcount; one each for the cache - pNewPoolItem->AddRef( pNewPoolItem != &rOrigItem ? 2 : 1 ); - pPool->Put( rOrigItem ); //FIXME: AddRef? + pNewPoolItem->AddRef( !areSfxPoolItemPtrsEqual(pNewPoolItem, &rOrigItem) ? 2 : 1 ); + pPool->DirectPutItemInPool( rOrigItem ); //FIXME: AddRef? // Add the transformation to the cache SfxItemModifyImpl aModify; @@ -100,7 +101,7 @@ const SfxSetItem& SfxItemPoolCache::ApplyTo( const SfxSetItem &rOrigItem ) m_aCache.push_back( aModify ); DBG_ASSERT( !pItemToPut || - &pNewPoolItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut, + areSfxPoolItemPtrsEqual(&pNewPoolItem->GetItemSet().Get( pItemToPut->Which() ), pItemToPut), "wrong item in resulting set" ); return *pNewPoolItem; diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx index 928ac3de3430..94ce9ceb2965 100644 --- a/svl/source/items/poolitem.cxx +++ b/svl/source/items/poolitem.cxx @@ -26,6 +26,10 @@ #include <typeinfo> #include <boost/property_tree/ptree.hpp> +#ifdef DBG_UTIL +#include <unordered_set> +#endif + ////////////////////////////////////////////////////////////////////////////// // list of classes derived from SfxPoolItem // will not be kept up-to-date, but give a good overview for right now @@ -466,16 +470,32 @@ static size_t nAllocatedSfxPoolItemCount(0); static size_t nUsedSfxPoolItemCount(0); size_t getAllocatedSfxPoolItemCount() { return nAllocatedSfxPoolItemCount; } size_t getUsedSfxPoolItemCount() { return nUsedSfxPoolItemCount; } +static std::unordered_set<const SfxPoolItem*> incarnatedSfxPoolItems; +void listAllocatedSfxPoolItems() +{ + SAL_INFO("svl.items", "ITEM: List of still allocated SfxPoolItems:"); + for (const auto& rCandidate : incarnatedSfxPoolItems) + { + SAL_INFO("svl.items", " ITEM: WhichID: " << rCandidate->Which() << " SerialNumber: " + << rCandidate->getSerialNumber() + << " Class: " << typeid(*rCandidate).name()); + } +} #endif SfxPoolItem::SfxPoolItem(sal_uInt16 const nWhich) : m_nRefCount(0) , m_nWhich(nWhich) +#ifdef DBG_UTIL + , m_nSerialNumber(nUsedSfxPoolItemCount) +#endif , m_bIsVoidItem(false) , m_bDeleteOnIdle(false) , m_bStaticDefault(false) , m_bPoolDefault(false) - , m_bShareable(true) + , m_bRegisteredAtPool(false) + , m_bNewItemCallback(false) + , m_bIsSetItem(false) #ifdef DBG_UTIL , m_bDeleted(false) #endif @@ -483,6 +503,7 @@ SfxPoolItem::SfxPoolItem(sal_uInt16 const nWhich) #ifdef DBG_UTIL nAllocatedSfxPoolItemCount++; nUsedSfxPoolItemCount++; + incarnatedSfxPoolItems.insert(this); #endif assert(nWhich <= SHRT_MAX); } @@ -491,6 +512,7 @@ SfxPoolItem::~SfxPoolItem() { #ifdef DBG_UTIL nAllocatedSfxPoolItemCount--; + incarnatedSfxPoolItems.erase(this); m_bDeleted = true; #endif assert((m_nRefCount == 0 || m_nRefCount > SFX_ITEMS_MAXREF) && "destroying item in use"); @@ -598,6 +620,70 @@ bool SfxPoolItem::PutValue(const css::uno::Any&, sal_uInt8) return false; } +bool areSfxPoolItemPtrsEqual(const SfxPoolItem* pItem1, const SfxPoolItem* pItem2) +{ +#ifdef DBG_UTIL + if (nullptr != pItem1 && nullptr != pItem2 && pItem1->Which() == pItem2->Which() + && static_cast<const void*>(pItem1) != static_cast<const void*>(pItem2) + && typeid(*pItem1) == typeid(*pItem2) && *pItem1 == *pItem2) + { + SAL_INFO("svl.items", "ITEM: PtrCompare != ContentCompare (!)"); + } +#endif + + // cast to void* to not trigger [loplugin:itemcompare] + return (static_cast<const void*>(pItem1) == static_cast<const void*>(pItem2)); +} + +bool SfxPoolItem::areSame(const SfxPoolItem* pItem1, const SfxPoolItem* pItem2) +{ + if (pItem1 == pItem2) + // pointer compare, this handles already + // nullptr, INVALID_POOL_ITEM, SfxVoidItem + // and if any Item is indeed handed over twice + return true; + + if (nullptr == pItem1 || nullptr == pItem2) + // one ptr is nullptr, not both, that would + // have triggered above + return false; + + if (pItem1->Which() != pItem2->Which()) + // WhichIDs differ (fast) + return false; + + if (typeid(*pItem1) != typeid(*pItem2)) + // types differ (fast) + // NOTE: we can now use typeid since we do not have (-1) + // anymore for Invalid state -> safe + return false; + + // return content compare using operator== at last + return *pItem1 == *pItem2; +} + +bool SfxPoolItem::areSame(const SfxPoolItem& rItem1, const SfxPoolItem& rItem2) +{ + if (&rItem1 == &rItem2) + // still use pointer compare, this handles already + // nullptr, INVALID_POOL_ITEM, SfxVoidItem + // and if any Item is indeed handed over twice + return true; + + if (rItem1.Which() != rItem2.Which()) + // WhichIDs differ (fast) + return false; + + if (typeid(rItem1) != typeid(rItem2)) + // types differ (fast) + // NOTE: we can now use typeid since we do not have (-1) + // anymore for Invalid state -> safe + return false; + + // return content compare using operator== at last + return rItem1 == rItem2; +} + namespace { class InvalidItem final : public SfxPoolItem diff --git a/svl/source/items/sitem.cxx b/svl/source/items/sitem.cxx index a34b9ebff532..037097f7bc3a 100644 --- a/svl/source/items/sitem.cxx +++ b/svl/source/items/sitem.cxx @@ -29,6 +29,7 @@ SfxSetItem::SfxSetItem( sal_uInt16 which, const SfxItemSet &rSet) : maSet(rSet) { assert(!dynamic_cast<const SfxAllItemSet*>(&rSet) && "cannot handle SfxAllItemSet here"); + setIsSetItem(); } @@ -37,6 +38,7 @@ SfxSetItem::SfxSetItem( sal_uInt16 which, SfxItemSet &&pS) : maSet(pS) { assert(!dynamic_cast<SfxAllItemSet*>(&pS) && "cannot handle SfxAllItemSet here"); + setIsSetItem(); } @@ -45,6 +47,7 @@ SfxSetItem::SfxSetItem( const SfxSetItem& rCopy, SfxItemPool *pPool ) : maSet(rCopy.maSet.CloneAsValue(true, pPool)) { assert(!dynamic_cast<const SfxAllItemSet*>(&rCopy.maSet) && "cannot handle SfxAllItemSet here"); + setIsSetItem(); } diff --git a/svl/source/items/stylepool.cxx b/svl/source/items/stylepool.cxx index dc992a6ede72..9de8d87d13b2 100644 --- a/svl/source/items/stylepool.cxx +++ b/svl/source/items/stylepool.cxx @@ -373,7 +373,7 @@ public: std::shared_ptr<SfxItemSet> StylePoolImpl::insertItemSet( const SfxItemSet& rSet, const OUString* pParentName ) { - bool bNonPoolable = false; + bool bNonShareable(false); Node* pCurNode = &maRoot[ rSet.GetParent() ]; if (pParentName) maParentNames[ rSet.GetParent() ] = *pParentName; @@ -389,8 +389,8 @@ std::shared_ptr<SfxItemSet> StylePoolImpl::insertItemSet( const SfxItemSet& rSet } while( pItem ) { - if( !rSet.GetPool()->IsItemPoolable(pItem->Which() ) ) - bNonPoolable = true; + if (!rSet.GetPool()->Shareable(pItem->Which())) + bNonShareable = true; if (!xFoundIgnorableItems || (xFoundIgnorableItems->Put(*pItem) == nullptr)) { pCurNode = pCurNode->findChildNode( *pItem, false ); @@ -403,8 +403,8 @@ std::shared_ptr<SfxItemSet> StylePoolImpl::insertItemSet( const SfxItemSet& rSet pItem = aIgnorableItemsIter.GetCurItem(); while( pItem ) { - if( !rSet.GetPool()->IsItemPoolable(pItem->Which() ) ) - bNonPoolable = true; + if (!rSet.GetPool()->Shareable(pItem->Which())) + bNonShareable = true; pCurNode = pCurNode->findChildNode( *pItem, true ); pItem = aIgnorableItemsIter.NextItem(); } @@ -415,13 +415,13 @@ std::shared_ptr<SfxItemSet> StylePoolImpl::insertItemSet( const SfxItemSet& rSet if( !pCurNode->hasItemSet( false ) ) { pCurNode->setItemSet( rSet ); - bNonPoolable = false; // to avoid a double insertion + bNonShareable = false; // to avoid a double insertion #ifdef DEBUG ++mnCount; #endif } // If rSet contains at least one non poolable item, a new itemset has to be inserted - if( bNonPoolable ) + if( bNonShareable ) pCurNode->setItemSet( rSet ); #ifdef DEBUG { diff --git a/svl/source/items/voiditem.cxx b/svl/source/items/voiditem.cxx index 6977c28553d3..32057e1e2c75 100644 --- a/svl/source/items/voiditem.cxx +++ b/svl/source/items/voiditem.cxx @@ -25,19 +25,19 @@ SfxPoolItem* SfxVoidItem::CreateDefault() { return new SfxVoidItem(0); } SfxVoidItem::SfxVoidItem(sal_uInt16 which) : SfxPoolItem(which) { - setVoidItem(); + setIsVoidItem(); } SfxVoidItem::SfxVoidItem(const SfxVoidItem& rCopy) : SfxPoolItem(rCopy.Which()) { - setVoidItem(); + setIsVoidItem(); } SfxVoidItem::SfxVoidItem(SfxVoidItem&& rOrig) : SfxPoolItem(rOrig) { - setVoidItem(); + setIsVoidItem(); } bool SfxVoidItem::operator==(const SfxPoolItem& rCmp) const diff --git a/svx/qa/unit/customshapes.cxx b/svx/qa/unit/customshapes.cxx index be3808dfd3fc..523cf7342b7b 100644 --- a/svx/qa/unit/customshapes.cxx +++ b/svx/qa/unit/customshapes.cxx @@ -150,7 +150,7 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf147409_GeomItemHash) pSdrView->MarkObj(pSdrCustomShape, pSdrView->GetSdrPageView()); // Apply FontworkSameLetterHeights toggle - // Without patch a debug build fails assert in SfxItemPool::PutImpl and so crashes. + // Without patch a debug build fails assert in SfxItemPool::DirectPutItemInPoolImpl and so crashes. dispatchCommand(mxComponent, ".uno:FontworkSameLetterHeights", {}); } @@ -167,7 +167,7 @@ CPPUNIT_TEST_FIXTURE(CustomshapesTest, testTdf146866_GeomItemHash) pSdrView->MarkObj(pSdrCustomShape, pSdrView->GetSdrPageView()); // Apply extrusion toggle - // Without patch a debug build fails assert in SfxItemPool::PutImpl and so crashes. + // Without patch a debug build fails assert in SfxItemPool::DirectPutItemInPoolImpl and so crashes. dispatchCommand(mxComponent, ".uno:ExtrusionToggle", {}); } diff --git a/svx/source/dialog/framelinkarray.cxx b/svx/source/dialog/framelinkarray.cxx index 24c69fb7e5ee..c5efc9f2b422 100644 --- a/svx/source/dialog/framelinkarray.cxx +++ b/svx/source/dialog/framelinkarray.cxx @@ -269,11 +269,11 @@ static void lclSetMergedRange( SfxItemPool& rPool, CellVec& rCells, sal_Int32 nW Cell aTempCell(*pCell); aTempCell.mbOverlapX = nCol > nFirstCol; aTempCell.mbOverlapY = nRow > nFirstRow; - rCells[ nRow * nWidth + nCol ] = &rPool.Put(aTempCell); + rCells[ nRow * nWidth + nCol ] = &rPool.DirectPutItemInPool(aTempCell); } } Cell aTempCell(*rCells[ nFirstRow * nWidth + nFirstCol ]); - rCells[ nFirstRow * nWidth + nFirstCol ] = &rPool.Put(aTempCell); + rCells[ nFirstRow * nWidth + nFirstCol ] = &rPool.DirectPutItemInPool(aTempCell); } @@ -336,8 +336,10 @@ struct ArrayImpl bool HasCellRotation() const; }; -const SfxItemInfo maItemInfos[] { - {0, true} +const SfxItemInfo maItemInfos[] +{ + // _nSID, _bNeedsPoolRegistration, _bShareable + {0, false, true } }; ArrayImpl::ArrayImpl( sal_Int32 nWidth, sal_Int32 nHeight ) : mxPool(new SfxItemPool("Mine", 10, 10, maItemInfos)), @@ -351,7 +353,7 @@ ArrayImpl::ArrayImpl( sal_Int32 nWidth, sal_Int32 nHeight ) : mbYCoordsDirty( false ), mbMayHaveCellRotation( false ) { - const Cell* pDefaultCell = &mxPool->Put(Cell()); + const Cell* pDefaultCell = &mxPool->DirectPutItemInPool(Cell()); // default-construct all vectors maCells.resize( mnWidth * mnHeight, pDefaultCell ); maWidths.resize( mnWidth, 0 ); @@ -368,7 +370,7 @@ const Cell& ArrayImpl::GetCell( sal_Int32 nCol, sal_Int32 nRow ) const void ArrayImpl::PutCell( sal_Int32 nCol, sal_Int32 nRow, const Cell & rCell ) { if (IsValidPos( nCol, nRow )) - maCells[ GetIndex( nCol, nRow ) ] = &mxPool->Put(rCell); + maCells[ GetIndex( nCol, nRow ) ] = &mxPool->DirectPutItemInPool(rCell); } sal_Int32 ArrayImpl::GetMergedFirstCol( sal_Int32 nCol, sal_Int32 nRow ) const @@ -1061,7 +1063,7 @@ void Array::MirrorSelfX() { Cell aTempCell(CELL(mxImpl->GetMirrorCol( nCol ), nRow)); aTempCell.MirrorSelfX(); - aNewCells.push_back( &mxImpl->mxPool->Put(aTempCell) ); + aNewCells.push_back( &mxImpl->mxPool->DirectPutItemInPool(aTempCell) ); } } mxImpl->maCells.swap( aNewCells ); diff --git a/svx/source/items/customshapeitem.cxx b/svx/source/items/customshapeitem.cxx index 1aaa0e7ff02b..7fc4a0601d30 100644 --- a/svx/source/items/customshapeitem.cxx +++ b/svx/source/items/customshapeitem.cxx @@ -239,23 +239,6 @@ bool SdrCustomShapeGeometryItem::operator==( const SfxPoolItem& rCmp ) const return m_aPropSeq == other.m_aPropSeq; } -bool SdrCustomShapeGeometryItem::operator<( const SfxPoolItem& rCmp ) const -{ - assert(dynamic_cast<const SdrCustomShapeGeometryItem*>( &rCmp )); - const SdrCustomShapeGeometryItem& other = static_cast<const SdrCustomShapeGeometryItem&>(rCmp); - // Again, try to optimize by checking hashes first (this is operator< for sorting purposes, - // so the ordering can be somewhat arbitrary). - UpdateHash(); - other.UpdateHash(); - if( m_aHashState != other.m_aHashState ) - return m_aHashState < other.m_aHashState; - if( m_aHashState == HashState::Valid ) - return m_aHash < other.m_aHash; - - return comphelper::anyLess( css::uno::Any( m_aPropSeq ), - css::uno::Any( other.m_aPropSeq )); -} - void SdrCustomShapeGeometryItem::UpdateHash() const { if( m_aHashState != HashState::Unknown ) diff --git a/svx/source/items/pageitem.cxx b/svx/source/items/pageitem.cxx index 93239ea3d5b1..65e016f741a6 100644 --- a/svx/source/items/pageitem.cxx +++ b/svx/source/items/pageitem.cxx @@ -256,9 +256,9 @@ SvxSetItem::SvxSetItem( const TypedWhichId<SvxSetItem> nId, const SfxItemSet& rS { } -SvxSetItem::SvxSetItem( const SvxSetItem& rItem ) : +SvxSetItem::SvxSetItem( const SvxSetItem& rItem, SfxItemPool* pPool ) : - SfxSetItem( rItem ) + SfxSetItem( rItem, pPool ) { } @@ -268,9 +268,9 @@ SvxSetItem::SvxSetItem( const TypedWhichId<SvxSetItem> nId, SfxItemSet&& _pSet ) { } -SvxSetItem* SvxSetItem::Clone( SfxItemPool * ) const +SvxSetItem* SvxSetItem::Clone( SfxItemPool * pPool ) const { - return new SvxSetItem(*this); + return new SvxSetItem(*this, pPool); } bool SvxSetItem::GetPresentation diff --git a/svx/source/sidebar/nbdtmg.cxx b/svx/source/sidebar/nbdtmg.cxx index ebdfa34256fd..b572d49f8adf 100644 --- a/svx/source/sidebar/nbdtmg.cxx +++ b/svx/source/sidebar/nbdtmg.cxx @@ -666,7 +666,7 @@ sal_uInt16 OutlineTypeMgr::GetNBOIndexForNumRule(SvxNumRule& aNum,sal_uInt16 /*m const SvxBrushItem* pBrsh1 = aFmt.GetBrush(); const SvxBrushItem* pBrsh2 = _pSet->pBrushItem; bool bIsMatch = false; - if (pBrsh1==pBrsh2) bIsMatch = true; + if (SfxPoolItem::areSame(pBrsh1,pBrsh2)) bIsMatch = true; if (pBrsh1 && pBrsh2) { const Graphic* pGrf1 = pBrsh1->GetGraphic(); const Graphic* pGrf2 = pBrsh2->GetGraphic(); diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx index 0a4ce01cab2c..6ba680e5d520 100644 --- a/svx/source/svdraw/svdattr.cxx +++ b/svx/source/svdraw/svdattr.cxx @@ -126,9 +126,13 @@ SdrItemPool::SdrItemPool( // init the non-persistent items for(sal_uInt16 i(SDRATTR_NOTPERSIST_FIRST); i <= SDRATTR_NOTPERSIST_LAST; i++) { - mpLocalItemInfos[i - SDRATTR_START]._bPoolable = false; + mpLocalItemInfos[i - SDRATTR_START]._bNeedsPoolRegistration = false; } + // these slots need _bNeedsPoolRegistration == true, see + // text @svl/source/items/itempool.cxx + mpLocalItemInfos[SDRATTR_XMLATTRIBUTES -SDRATTR_START]._bNeedsPoolRegistration = true; + // init own PoolDefaults std::vector<SfxPoolItem*>& rPoolDefaults = *mpLocalPoolDefaults; rPoolDefaults[SDRATTR_SHADOW -SDRATTR_START]=new SdrOnOffItem(SDRATTR_SHADOW, false); diff --git a/svx/source/unodraw/UnoNamespaceMap.cxx b/svx/source/unodraw/UnoNamespaceMap.cxx index 0eced8574da5..b013c5a8ab6b 100644 --- a/svx/source/unodraw/UnoNamespaceMap.cxx +++ b/svx/source/unodraw/UnoNamespaceMap.cxx @@ -127,8 +127,9 @@ NamespaceIteratorImpl::NamespaceIteratorImpl( sal_uInt16* pWhichIds, SfxItemPool mnItem = -1; if (mpWhichId && (0 != *mpWhichId) && mpPool) { - mvItems.reserve(mpPool->GetItemCount2( *mpWhichId )); - for (const SfxPoolItem* pItem : mpPool->GetItemSurrogates( *mpWhichId )) + const registeredSfxPoolItems& rSurrogates(mpPool->GetItemSurrogates(*mpWhichId)); + mvItems.reserve(rSurrogates.size()); + for (const SfxPoolItem* pItem : rSurrogates) mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem)); } } @@ -162,8 +163,9 @@ bool NamespaceIteratorImpl::next( OUString& rPrefix, OUString& rURL ) mvItems.clear(); if (mpPool) { - mvItems.reserve(mpPool->GetItemCount2( *mpWhichId )); - for (const SfxPoolItem* pItem2 : mpPool->GetItemSurrogates( *mpWhichId )) + const registeredSfxPoolItems& rSurrogates(mpPool->GetItemSurrogates(*mpWhichId)); + mvItems.reserve(rSurrogates.size()); + for (const SfxPoolItem* pItem2 : rSurrogates) mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem2)); } return next( rPrefix, rURL ); diff --git a/svx/source/xoutdev/xpool.cxx b/svx/source/xoutdev/xpool.cxx index e0a280791b30..017401983ced 100644 --- a/svx/source/xoutdev/xpool.cxx +++ b/svx/source/xoutdev/xpool.cxx @@ -159,10 +159,24 @@ XOutdevItemPool::XOutdevItemPool(SfxItemPool* _pMaster) // create ItemInfos for(sal_uInt16 i(GetFirstWhich()); i <= GetLastWhich(); i++) { + // _nSID, _bNeedsPoolRegistration, _bShareable mpLocalItemInfos[i - XATTR_START]._nSID = 0; - mpLocalItemInfos[i - XATTR_START]._bPoolable = true; + mpLocalItemInfos[i - XATTR_START]._bNeedsPoolRegistration = false; + mpLocalItemInfos[i - XATTR_START]._bShareable = true; } + // these slots need _bNeedsPoolRegistration == true, see + // text @svl/source/items/itempool.cxx + mpLocalItemInfos[XATTR_FILLBITMAP -XATTR_START]._bNeedsPoolRegistration = true; + mpLocalItemInfos[XATTR_FILLGRADIENT -XATTR_START]._bNeedsPoolRegistration = true; + mpLocalItemInfos[XATTR_FILLHATCH -XATTR_START]._bNeedsPoolRegistration = true; + mpLocalItemInfos[XATTR_FILLFLOATTRANSPARENCE - XATTR_START]._bNeedsPoolRegistration = true; + mpLocalItemInfos[XATTR_LINEEND -XATTR_START]._bNeedsPoolRegistration = true; + mpLocalItemInfos[XATTR_LINESTART -XATTR_START]._bNeedsPoolRegistration = true; + mpLocalItemInfos[XATTR_LINEDASH -XATTR_START]._bNeedsPoolRegistration = true; + mpLocalItemInfos[XATTR_FILLCOLOR -XATTR_START]._bNeedsPoolRegistration = true; + + // set the SlotIDs, this is a mapping used by GetWhich()/GetSlotId() mpLocalItemInfos[XATTR_LINESTYLE -XATTR_START]._nSID = SID_ATTR_LINE_STYLE; mpLocalItemInfos[XATTR_LINEDASH -XATTR_START]._nSID = SID_ATTR_LINE_DASH; mpLocalItemInfos[XATTR_LINEWIDTH -XATTR_START]._nSID = SID_ATTR_LINE_WIDTH; diff --git a/sw/source/core/attr/cellatr.cxx b/sw/source/core/attr/cellatr.cxx index 09b070e42c3a..9023cca2f793 100644 --- a/sw/source/core/attr/cellatr.cxx +++ b/sw/source/core/attr/cellatr.cxx @@ -58,9 +58,6 @@ SwTableBoxFormula::SwTableBoxFormula( const OUString& rFormula ) SwTableFormula( rFormula ), m_pDefinedIn( nullptr ) { - // ITEM: mark this Item to be non-shareable/non-RefCountable. For more - // info see comment @SwAttrSet::SetModifyAtAttr - m_bShareable = false; } bool SwTableBoxFormula::operator==( const SfxPoolItem& rAttr ) const diff --git a/sw/source/core/attr/hints.cxx b/sw/source/core/attr/hints.cxx index 7102ce7d7f5d..641d7380312f 100644 --- a/sw/source/core/attr/hints.cxx +++ b/sw/source/core/attr/hints.cxx @@ -140,10 +140,13 @@ SwMsgPoolItem::SwMsgPoolItem( sal_uInt16 nWhch ) { } -bool SwMsgPoolItem::operator==( const SfxPoolItem& ) const +bool SwMsgPoolItem::operator==( const SfxPoolItem& rItem ) const { - assert( false && "SwMsgPoolItem knows no ==" ); - return false; + assert( SfxPoolItem::operator==(rItem)); (void)rItem; + // SwMsgPoolItem now knows operator== due to evtl. deeper + // ItemCompares using SfxPoolItem::areSame. No members, + // so always equal + return true; } SwMsgPoolItem* SwMsgPoolItem::Clone( SfxItemPool* ) const diff --git a/sw/source/core/attr/swatrset.cxx b/sw/source/core/attr/swatrset.cxx index b08026a1bd34..fc4612757dcc 100644 --- a/sw/source/core/attr/swatrset.cxx +++ b/sw/source/core/attr/swatrset.cxx @@ -141,12 +141,12 @@ void SwAttrSet::changeCallback(const SfxPoolItem* pOld, const SfxPoolItem* pNew) const SfxItemSet* pParent(GetParent()); m_pOldSet->PutImpl(nullptr != pParent ? pParent->Get(nWhich) - : GetPool()->GetDefaultItem(nWhich), nWhich, false, false); + : GetPool()->GetDefaultItem(nWhich), nWhich, false); } else if (!IsInvalidItem(pOld)) { // set/remember old value - m_pOldSet->PutImpl(*pOld, nWhich, true, false); + m_pOldSet->PutImpl(*pOld, nWhich, false); } } @@ -159,12 +159,12 @@ void SwAttrSet::changeCallback(const SfxPoolItem* pOld, const SfxPoolItem* pNew) const SfxItemSet* pParent(GetParent()); m_pNewSet->PutImpl(nullptr != pParent ? pParent->Get(nWhich) - : GetPool()->GetDefaultItem(nWhich), nWhich, false, false); + : GetPool()->GetDefaultItem(nWhich), nWhich, false); } else if (!IsInvalidItem(pNew)) { // set/remember new value - m_pNewSet->PutImpl(*pNew, nWhich, true, false); + m_pNewSet->PutImpl(*pNew, nWhich, false); } } } @@ -337,33 +337,6 @@ bool SwAttrSet::SetModifyAtAttr( const sw::BroadcastingModify* pModify ) { bool bSet = false; - // ITEM: At this place the paradigm of Item/Set/Pool gets broken: - // The three Items in Writer - // - SwFormatPageDesc - // - SwFormatDrop - // - SwTableBoxFormula - // contain a unique ptr to SwFormat (or: sw::BroadcastingModify - // if you wish), so the Item *cannot* be shared or re-used. - // But that is the intended nature of Items: - // - they are read-only (note the bad const_cast's below) - // - they are ref-counted to be re-usable in as many Sets as - // possible - // Thus if we need to change that ptr @ Item we *need* to make - // sure that Item is *unique*. This is now done by using the - // 'm_bShareable' at the Item (see where that gets set). - // This was done in the past using the 'poolable' flag, but that - // flag was/is for a completely different purpose - uniqueness is - // a side-effect. It already led to massively cloning that Item. - // That something is not 'clean' here can also be seen by using - // const_cast to *change* values at Items *in* the Set - these - // are returned by const reference for a purpose. - // If info/data at an Item has to be changed, the official/clean - // way is to create a new one (e.g. Clone), set the values (if - // not given to the constructor) and then set that Item at the Set. - // NOTE: I do not know if and how it would be possible, but holding - // a SwFormat*/sw::BroadcastingModify* at those Items should - // be fixed/removed ASAP - const SwFormatPageDesc* pPageDescItem = GetItemIfSet( RES_PAGEDESC, false ); if( pPageDescItem && pPageDescItem->GetDefinedIn() != pModify ) diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index 3e286b31e80a..f0080719c28d 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -264,180 +264,181 @@ SwDfltAttrTab aAttrTab( POOLATTR_END - POOLATTR_BEGIN, nullptr ); SfxItemInfo aSlotTab[] = { - { SID_ATTR_CHAR_CASEMAP, true }, // RES_CHRATR_CASEMAP - { SID_ATTR_CHAR_CHARSETCOLOR, true }, // RES_CHRATR_CHARSETCOLOR - { SID_ATTR_CHAR_COLOR, true }, // RES_CHRATR_COLOR - { SID_ATTR_CHAR_CONTOUR, true }, // RES_CHRATR_CONTOUR - { SID_ATTR_CHAR_STRIKEOUT, true }, // RES_CHRATR_CROSSEDOUT - { SID_ATTR_CHAR_ESCAPEMENT, true }, // RES_CHRATR_ESCAPEMENT - { SID_ATTR_CHAR_FONT, true }, // RES_CHRATR_FONT - { SID_ATTR_CHAR_FONTHEIGHT, true }, // RES_CHRATR_FONTSIZE - { SID_ATTR_CHAR_KERNING, true }, // RES_CHRATR_KERNING - { SID_ATTR_CHAR_LANGUAGE, true }, // RES_CHRATR_LANGUAGE - { SID_ATTR_CHAR_POSTURE, true }, // RES_CHRATR_POSTURE - { 0, true }, // RES_CHRATR_UNUSED1 - { SID_ATTR_CHAR_SHADOWED, true }, // RES_CHRATR_SHADOWED - { SID_ATTR_CHAR_UNDERLINE, true }, // RES_CHRATR_UNDERLINE - { SID_ATTR_CHAR_WEIGHT, true }, // RES_CHRATR_WEIGHT - { SID_ATTR_CHAR_WORDLINEMODE, true }, // RES_CHRATR_WORDLINEMODE - { SID_ATTR_CHAR_AUTOKERN, true }, // RES_CHRATR_AUTOKERN - { SID_ATTR_FLASH, true }, // RES_CHRATR_BLINK - { 0, true }, // RES_CHRATR_UNUSED2 - { 0, true }, // RES_CHRATR_NOHYPHEN - { SID_ATTR_BRUSH_CHAR, true }, // RES_CHRATR_BACKGROUND - { SID_ATTR_CHAR_CJK_FONT, true }, // RES_CHRATR_CJK_FONT - { SID_ATTR_CHAR_CJK_FONTHEIGHT, true },// RES_CHRATR_CJK_FONTSIZE - { SID_ATTR_CHAR_CJK_LANGUAGE, true }, // RES_CHRATR_CJK_LANGUAGE - { SID_ATTR_CHAR_CJK_POSTURE, true }, // RES_CHRATR_CJK_POSTURE - { SID_ATTR_CHAR_CJK_WEIGHT, true }, // RES_CHRATR_CJK_WEIGHT - { SID_ATTR_CHAR_CTL_FONT, true }, // RES_CHRATR_CTL_FONT - { SID_ATTR_CHAR_CTL_FONTHEIGHT, true },// RES_CHRATR_CTL_FONTSIZE - { SID_ATTR_CHAR_CTL_LANGUAGE, true }, // RES_CHRATR_CTL_LANGUAGE - { SID_ATTR_CHAR_CTL_POSTURE, true }, // RES_CHRATR_CTL_POSTURE - { SID_ATTR_CHAR_CTL_WEIGHT, true }, // RES_CHRATR_CTL_WEIGHT - { SID_ATTR_CHAR_ROTATED, true }, // RES_CHRATR_ROTATE - { SID_ATTR_CHAR_EMPHASISMARK, true }, // RES_CHRATR_EMPHASIS_MARK - { SID_ATTR_CHAR_TWO_LINES, true }, // RES_CHRATR_TWO_LINES - { SID_ATTR_CHAR_SCALEWIDTH, true }, // RES_CHRATR_SCALEW - { SID_ATTR_CHAR_RELIEF, true }, // RES_CHRATR_RELIEF - { SID_ATTR_CHAR_HIDDEN, true }, // RES_CHRATR_HIDDEN - { SID_ATTR_CHAR_OVERLINE, true }, // RES_CHRATR_OVERLINE - { 0, true }, // RES_CHRATR_RSID - { SID_ATTR_CHAR_BOX, true }, // RES_CHRATR_BOX - { SID_ATTR_CHAR_SHADOW, true }, // RES_CHRATR_SHADOW - { 0, true }, // RES_CHRATR_HIGHLIGHT - { SID_ATTR_CHAR_GRABBAG, true }, // RES_CHRATR_GRABBAG - { 0, true }, // RES_CHRATR_BIDIRTL - { 0, true }, // RES_CHRATR_IDCTHINT - - { 0, false }, // RES_TXTATR_REFMARK - { 0, false }, // RES_TXTATR_TOXMARK - { 0, false }, // RES_TXTATR_META - { 0, false }, // RES_TXTATR_METAFIELD - { 0, true }, // RES_TXTATR_AUTOFMT - { FN_TXTATR_INET, false }, // RES_TXTATR_INETFMT - { 0, false }, // RES_TXTATR_CHARFMT - { SID_ATTR_CHAR_CJK_RUBY, false }, // RES_TXTATR_CJK_RUBY - { 0, true }, // RES_TXTATR_UNKNOWN_CONTAINER - { 0, false }, // RES_TXTATR_INPUTFIELD - { 0, false }, // RES_TXTATR_CONTENTCONTROL - - { 0, false }, // RES_TXTATR_FIELD - { 0, false }, // RES_TXTATR_FLYCNT - { 0, false }, // RES_TXTATR_FTN - { 0, false }, // RES_TXTATR_ANNOTATION - { 0, false }, // RES_TXTATR_LINEBREAK - { 0, true }, // RES_TXTATR_DUMMY1 - - { SID_ATTR_PARA_LINESPACE, true }, // RES_PARATR_LINESPACING - { SID_ATTR_PARA_ADJUST, true }, // RES_PARATR_ADJUST - { SID_ATTR_PARA_SPLIT, true }, // RES_PARATR_SPLIT - { SID_ATTR_PARA_ORPHANS, true }, // RES_PARATR_ORPHANS - { SID_ATTR_PARA_WIDOWS, true }, // RES_PARATR_WIDOWS - { SID_ATTR_TABSTOP, true }, // RES_PARATR_TABSTOP - { SID_ATTR_PARA_HYPHENZONE, true }, // RES_PARATR_HYPHENZONE - { FN_FORMAT_DROPCAPS, false }, // RES_PARATR_DROP - { SID_ATTR_PARA_REGISTER, true }, // RES_PARATR_REGISTER - { SID_ATTR_PARA_NUMRULE, true }, // RES_PARATR_NUMRULE - { SID_ATTR_PARA_SCRIPTSPACE, true }, // RES_PARATR_SCRIPTSPACE - { SID_ATTR_PARA_HANGPUNCTUATION, true },// RES_PARATR_HANGINGPUNCTUATION - - { SID_ATTR_PARA_FORBIDDEN_RULES, true },// RES_PARATR_FORBIDDEN_RULES - { SID_PARA_VERTALIGN, true }, // RES_PARATR_VERTALIGN - { SID_ATTR_PARA_SNAPTOGRID, true }, // RES_PARATR_SNAPTOGRID - { SID_ATTR_BORDER_CONNECT, true }, // RES_PARATR_CONNECT_BORDER - - { SID_ATTR_PARA_OUTLINE_LEVEL, true }, // RES_PARATR_OUTLINELEVEL //#outline level - { 0, true }, // RES_PARATR_RSID - { SID_ATTR_PARA_GRABBAG, true }, // RES_PARATR_GRABBAG - { 0, true }, // RES_PARATR_LIST_ID - { 0, true }, // RES_PARATR_LIST_LEVEL - { 0, true }, // RES_PARATR_LIST_ISRESTART - { 0, true }, // RES_PARATR_LIST_RESTARTVALUE - { 0, true }, // RES_PARATR_LIST_ISCOUNTED - { 0, true }, // RES_PARATR_LIST_AUTOFMT - - { 0, true }, // RES_FILL_ORDER - { 0, true }, // RES_FRM_SIZE - { SID_ATTR_PAGE_PAPERBIN, true }, // RES_PAPER_BIN - { SID_ATTR_PARA_FIRSTLINESPACE, true }, // RES_MARGIN_FIRSTLINE - { SID_ATTR_PARA_LEFTSPACE, true }, // RES_MARGIN_TEXTLEFT - { SID_ATTR_PARA_RIGHTSPACE, true }, // RES_MARGIN_RIGHT - { 0, true }, // RES_MARGIN_LEFT - { 0, true }, // RES_MARGIN_GUTTER - { 0, true }, // RES_MARGIN_GUTTER_RIGHT - { SID_ATTR_LRSPACE, true }, // RES_LR_SPACE - { SID_ATTR_ULSPACE, true }, // RES_UL_SPACE - { 0, false }, // RES_PAGEDESC - { SID_ATTR_PARA_PAGEBREAK, true }, // RES_BREAK - { 0, false }, // RES_CNTNT - { 0, true }, // RES_HEADER - { 0, true }, // RES_FOOTER - { 0, true }, // RES_PRINT - { FN_OPAQUE, true }, // RES_OPAQUE - { FN_SET_PROTECT, true }, // RES_PROTECT - { FN_SURROUND, true }, // RES_SURROUND - { FN_VERT_ORIENT, true }, // RES_VERT_ORIENT - { FN_HORI_ORIENT, true }, // RES_HORI_ORIENT - { 0, false }, // RES_ANCHOR - { SID_ATTR_BRUSH, true }, // RES_BACKGROUND - { SID_ATTR_BORDER_OUTER, true }, // RES_BOX - { SID_ATTR_BORDER_SHADOW, true }, // RES_SHADOW - { SID_ATTR_MACROITEM, true }, // RES_FRMMACRO - { FN_ATTR_COLUMNS, true }, // RES_COL - { SID_ATTR_PARA_KEEP, true }, // RES_KEEP - { 0, true }, // RES_URL - { 0, true }, // RES_EDIT_IN_READONLY - - { 0, true }, // RES_LAYOUT_SPLIT - { 0, false }, // RES_CHAIN - { 0, true }, // RES_TEXTGRID - { FN_FORMAT_LINENUMBER, true }, // RES_LINENUMBER - { 0, true }, // RES_FTN_AT_TXTEND - { 0, true }, // RES_END_AT_TXTEND - { 0, true }, // RES_COLUMNBALANCE - - { SID_ATTR_FRAMEDIRECTION, true }, // RES_FRAMEDIR - - { SID_ATTR_HDFT_DYNAMIC_SPACING, true },// RES_HEADER_FOOTER_EAT_SPACING - { FN_TABLE_ROW_SPLIT, true }, // RES_ROW_SPLIT - { 0, true } , // RES_FLY_SPLIT + // _nSID, _bNeedsPoolRegistration, _bShareable + { SID_ATTR_CHAR_CASEMAP, false, true }, // RES_CHRATR_CASEMAP + { SID_ATTR_CHAR_CHARSETCOLOR, false, true }, // RES_CHRATR_CHARSETCOLOR + { SID_ATTR_CHAR_COLOR, true, true }, // RES_CHRATR_COLOR + { SID_ATTR_CHAR_CONTOUR, false, true }, // RES_CHRATR_CONTOUR + { SID_ATTR_CHAR_STRIKEOUT, false, true }, // RES_CHRATR_CROSSEDOUT + { SID_ATTR_CHAR_ESCAPEMENT, false, true }, // RES_CHRATR_ESCAPEMENT + { SID_ATTR_CHAR_FONT, true, true }, // RES_CHRATR_FONT + { SID_ATTR_CHAR_FONTHEIGHT, false, true }, // RES_CHRATR_FONTSIZE + { SID_ATTR_CHAR_KERNING, false, true }, // RES_CHRATR_KERNING + { SID_ATTR_CHAR_LANGUAGE, false, true }, // RES_CHRATR_LANGUAGE + { SID_ATTR_CHAR_POSTURE, false, true }, // RES_CHRATR_POSTURE + { 0, false, true }, // RES_CHRATR_UNUSED1 + { SID_ATTR_CHAR_SHADOWED, false, true }, // RES_CHRATR_SHADOWED + { SID_ATTR_CHAR_UNDERLINE, true, true }, // RES_CHRATR_UNDERLINE + { SID_ATTR_CHAR_WEIGHT, false, true }, // RES_CHRATR_WEIGHT + { SID_ATTR_CHAR_WORDLINEMODE, false, true }, // RES_CHRATR_WORDLINEMODE + { SID_ATTR_CHAR_AUTOKERN, false, true }, // RES_CHRATR_AUTOKERN + { SID_ATTR_FLASH, false, true }, // RES_CHRATR_BLINK + { 0, false, true }, // RES_CHRATR_UNUSED2 + { 0, false, true }, // RES_CHRATR_NOHYPHEN + { SID_ATTR_BRUSH_CHAR, true, true }, // RES_CHRATR_BACKGROUND + { SID_ATTR_CHAR_CJK_FONT, true, true }, // RES_CHRATR_CJK_FONT + { SID_ATTR_CHAR_CJK_FONTHEIGHT, false, true }, // RES_CHRATR_CJK_FONTSIZE + { SID_ATTR_CHAR_CJK_LANGUAGE, false, true }, // RES_CHRATR_CJK_LANGUAGE + { SID_ATTR_CHAR_CJK_POSTURE, false, true }, // RES_CHRATR_CJK_POSTURE + { SID_ATTR_CHAR_CJK_WEIGHT, false, true }, // RES_CHRATR_CJK_WEIGHT + { SID_ATTR_CHAR_CTL_FONT, true, true }, // RES_CHRATR_CTL_FONT + { SID_ATTR_CHAR_CTL_FONTHEIGHT, false, true }, // RES_CHRATR_CTL_FONTSIZE + { SID_ATTR_CHAR_CTL_LANGUAGE, false, true }, // RES_CHRATR_CTL_LANGUAGE + { SID_ATTR_CHAR_CTL_POSTURE, false, true }, // RES_CHRATR_CTL_POSTURE + { SID_ATTR_CHAR_CTL_WEIGHT, false, true }, // RES_CHRATR_CTL_WEIGHT + { SID_ATTR_CHAR_ROTATED, false, true }, // RES_CHRATR_ROTATE + { SID_ATTR_CHAR_EMPHASISMARK, false, true }, // RES_CHRATR_EMPHASIS_MARK + { SID_ATTR_CHAR_TWO_LINES, false, true }, // RES_CHRATR_TWO_LINES + { SID_ATTR_CHAR_SCALEWIDTH, false, true }, // RES_CHRATR_SCALEW + { SID_ATTR_CHAR_RELIEF, false, true }, // RES_CHRATR_RELIEF + { SID_ATTR_CHAR_HIDDEN, false, true }, // RES_CHRATR_HIDDEN + { SID_ATTR_CHAR_OVERLINE, true, true }, // RES_CHRATR_OVERLINE + { 0, false, true }, // RES_CHRATR_RSID + { SID_ATTR_CHAR_BOX, true, true }, // RES_CHRATR_BOX + { SID_ATTR_CHAR_SHADOW, false, true }, // RES_CHRATR_SHADOW + { 0, true, true }, // RES_CHRATR_HIGHLIGHT + { SID_ATTR_CHAR_GRABBAG, false, true }, // RES_CHRATR_GRABBAG + { 0, false, true }, // RES_CHRATR_BIDIRTL + { 0, false, true }, // RES_CHRATR_IDCTHINT + + { 0, true, false }, // RES_TXTATR_REFMARK + { 0, true, false }, // RES_TXTATR_TOXMARK + { 0, false, false }, // RES_TXTATR_META + { 0, false, false }, // RES_TXTATR_METAFIELD + { 0, false, true }, // RES_TXTATR_AUTOFMT + { FN_TXTATR_INET, true, false }, // RES_TXTATR_INETFMT + { 0, false, false }, // RES_TXTATR_CHARFMT + { SID_ATTR_CHAR_CJK_RUBY, true, false }, // RES_TXTATR_CJK_RUBY + { 0, true, true }, // RES_TXTATR_UNKNOWN_CONTAINER + { 0, true, false }, // RES_TXTATR_INPUTFIELD + { 0, false, false }, // RES_TXTATR_CONTENTCONTROL + + { 0, true, false }, // RES_TXTATR_FIELD + { 0, false, false }, // RES_TXTATR_FLYCNT + { 0, false, false }, // RES_TXTATR_FTN + { 0, false, false }, // RES_TXTATR_ANNOTATION + { 0, false, false }, // RES_TXTATR_LINEBREAK + { 0, false, true }, // RES_TXTATR_DUMMY1 + + { SID_ATTR_PARA_LINESPACE, false, true }, // RES_PARATR_LINESPACING + { SID_ATTR_PARA_ADJUST, false, true }, // RES_PARATR_ADJUST + { SID_ATTR_PARA_SPLIT, false, true }, // RES_PARATR_SPLIT + { SID_ATTR_PARA_ORPHANS, false, true }, // RES_PARATR_ORPHANS + { SID_ATTR_PARA_WIDOWS, false, true }, // RES_PARATR_WIDOWS + { SID_ATTR_TABSTOP, true, true }, // RES_PARATR_TABSTOP + { SID_ATTR_PARA_HYPHENZONE, false, true }, // RES_PARATR_HYPHENZONE + { FN_FORMAT_DROPCAPS, false, false }, // RES_PARATR_DROP + { SID_ATTR_PARA_REGISTER, false, true }, // RES_PARATR_REGISTER + { SID_ATTR_PARA_NUMRULE, false, true }, // RES_PARATR_NUMRULE + { SID_ATTR_PARA_SCRIPTSPACE, false, true }, // RES_PARATR_SCRIPTSPACE + { SID_ATTR_PARA_HANGPUNCTUATION, false, true }, // RES_PARATR_HANGINGPUNCTUATION + + { SID_ATTR_PARA_FORBIDDEN_RULES, false, true }, // RES_PARATR_FORBIDDEN_RULES + { SID_PARA_VERTALIGN, false, true }, // RES_PARATR_VERTALIGN + { SID_ATTR_PARA_SNAPTOGRID, false, true }, // RES_PARATR_SNAPTOGRID + { SID_ATTR_BORDER_CONNECT, false, true }, // RES_PARATR_CONNECT_BORDER + + { SID_ATTR_PARA_OUTLINE_LEVEL, false, true }, // RES_PARATR_OUTLINELEVEL //#outline level + { 0, false, true }, // RES_PARATR_RSID + { SID_ATTR_PARA_GRABBAG, false, true }, // RES_PARATR_GRABBAG + { 0, false, true }, // RES_PARATR_LIST_ID + { 0, false, true }, // RES_PARATR_LIST_LEVEL + { 0, false, true }, // RES_PARATR_LIST_ISRESTART + { 0, false, true }, // RES_PARATR_LIST_RESTARTVALUE + { 0, false, true }, // RES_PARATR_LIST_ISCOUNTED + { 0, false, true }, // RES_PARATR_LIST_AUTOFMT + + { 0, false, true }, // RES_FILL_ORDER + { 0, false, true }, // RES_FRM_SIZE + { SID_ATTR_PAGE_PAPERBIN, false, true }, // RES_PAPER_BIN + { SID_ATTR_PARA_FIRSTLINESPACE, false, true }, // RES_MARGIN_FIRSTLINE + { SID_ATTR_PARA_LEFTSPACE, false, true }, // RES_MARGIN_TEXTLEFT + { SID_ATTR_PARA_RIGHTSPACE, false, true }, // RES_MARGIN_RIGHT + { 0, false, true }, // RES_MARGIN_LEFT + { 0, false, true }, // RES_MARGIN_GUTTER + { 0, false, true }, // RES_MARGIN_GUTTER_RIGHT + { SID_ATTR_LRSPACE, false, true }, // RES_LR_SPACE + { SID_ATTR_ULSPACE, false, true }, // RES_UL_SPACE + { 0, true, false }, // RES_PAGEDESC + { SID_ATTR_PARA_PAGEBREAK, false, true }, // RES_BREAK + { 0, false, false }, // RES_CNTNT + { 0, false, true }, // RES_HEADER + { 0, false, true }, // RES_FOOTER + { 0, false, true }, // RES_PRINT + { FN_OPAQUE, false, true }, // RES_OPAQUE + { FN_SET_PROTECT, false, true }, // RES_PROTECT + { FN_SURROUND, false, true }, // RES_SURROUND + { FN_VERT_ORIENT, false, true }, // RES_VERT_ORIENT + { FN_HORI_ORIENT, false, true }, // RES_HORI_ORIENT + { 0, false, false }, // RES_ANCHOR + { SID_ATTR_BRUSH, true, true }, // RES_BACKGROUND + { SID_ATTR_BORDER_OUTER, true, true }, // RES_BOX + { SID_ATTR_BORDER_SHADOW, true, true }, // RES_SHADOW + { SID_ATTR_MACROITEM, false, true }, // RES_FRMMACRO + { FN_ATTR_COLUMNS, false, true }, // RES_COL + { SID_ATTR_PARA_KEEP, false, true }, // RES_KEEP + { 0, true, true }, // RES_URL + { 0, false, true }, // RES_EDIT_IN_READONLY + + { 0, false, true }, // RES_LAYOUT_SPLIT + { 0, false, false }, // RES_CHAIN + { 0, false, true }, // RES_TEXTGRID + { FN_FORMAT_LINENUMBER, false, true }, // RES_LINENUMBER + { 0, false, true }, // RES_FTN_AT_TXTEND + { 0, false, true }, // RES_END_AT_TXTEND + { 0, false, true }, // RES_COLUMNBALANCE + + { SID_ATTR_FRAMEDIRECTION, false, true }, // RES_FRAMEDIR + + { SID_ATTR_HDFT_DYNAMIC_SPACING, false, true }, // RES_HEADER_FOOTER_EAT_SPACING + { FN_TABLE_ROW_SPLIT, false, true }, // RES_ROW_SPLIT + { 0, false, true }, // RES_FLY_SPLIT // #i18732# - use slot-id define in svx - { SID_SW_FOLLOW_TEXT_FLOW, true }, // RES_FOLLOW_TEXT_FLOW + { SID_SW_FOLLOW_TEXT_FLOW, false, true }, // RES_FOLLOW_TEXT_FLOW // #i29550# - { SID_SW_COLLAPSING_BORDERS, true }, // RES_COLLAPSING_BORDERS + { SID_SW_COLLAPSING_BORDERS, false, true }, // RES_COLLAPSING_BORDERS // #i28701# - { SID_SW_WRAP_INFLUENCE_ON_OBJPOS, true },// RES_WRAP_INFLUENCE_ON_OBJPOS - { 0, false }, // RES_AUTO_STYLE - { 0, true }, // RES_FRMATR_STYLE_NAME - { 0, true }, // RES_FRMATR_CONDITIONAL_STYLE_NAME - { 0, true }, // RES_FRMATR_GRABBAG - { 0, true }, // RES_TEXT_VERT_ADJUST - { 0, true }, // RES_BACKGROUND_FULL_SIZE - { 0, true }, // RES_RTL_GUTTER - { 0, true }, // RES_DECORATIVE - - { 0, true }, // RES_GRFATR_MIRRORGRF - { SID_ATTR_GRAF_CROP, true }, // RES_GRFATR_CROPGRF - { 0, true }, // RES_GRFATR_ROTATION, - { 0, true }, // RES_GRFATR_LUMINANCE, - { 0, true }, // RES_GRFATR_CONTRAST, - { 0, true }, // RES_GRFATR_CHANNELR, - { 0, true }, // RES_GRFATR_CHANNELG, - { 0, true }, // RES_GRFATR_CHANNELB, - { 0, true }, // RES_GRFATR_GAMMA, - { 0, true }, // RES_GRFATR_INVERT, - { 0, true }, // RES_GRFATR_TRANSPARENCY, - { 0, true }, // RES_GRFATR_DUMMY3, - { 0, true }, // RES_GRFATR_DUMMY4, - { 0, true }, // RES_GRFATR_DUMMY5, - { 0, true }, // RES_GRFATR_DUMMY6, - - { 0, true }, // RES_BOXATR_FORMAT - { 0, false }, // RES_BOXATR_FORMULA, - { 0, true }, // RES_BOXATR_VALUE - - { 0, true } // RES_UNKNOWNATR_CONTAINER + { SID_SW_WRAP_INFLUENCE_ON_OBJPOS, false, true }, // RES_WRAP_INFLUENCE_ON_OBJPOS + { 0, false, false }, // RES_AUTO_STYLE + { 0, false, true }, // RES_FRMATR_STYLE_NAME + { 0, false, true }, // RES_FRMATR_CONDITIONAL_STYLE_NAME + { 0, false, true }, // RES_FRMATR_GRABBAG + { 0, false, true }, // RES_TEXT_VERT_ADJUST + { 0, false, true }, // RES_BACKGROUND_FULL_SIZE + { 0, false, true }, // RES_RTL_GUTTER + { 0, false, true }, // RES_DECORATIVE + + { 0, false, true }, // RES_GRFATR_MIRRORGRF + { SID_ATTR_GRAF_CROP, false, true }, // RES_GRFATR_CROPGRF + { 0, false, true }, // RES_GRFATR_ROTATION, + { 0, false, true }, // RES_GRFATR_LUMINANCE, + { 0, false, true }, // RES_GRFATR_CONTRAST, + { 0, false, true }, // RES_GRFATR_CHANNELR, + { 0, false, true }, // RES_GRFATR_CHANNELG, + { 0, false, true }, // RES_GRFATR_CHANNELB, + { 0, false, true }, // RES_GRFATR_GAMMA, + { 0, false, true }, // RES_GRFATR_INVERT, + { 0, false, true }, // RES_GRFATR_TRANSPARENCY, + { 0, false, true }, // RES_GRFATR_DUMMY3, + { 0, false, true }, // RES_GRFATR_DUMMY4, + { 0, false, true }, // RES_GRFATR_DUMMY5, + { 0, false, true }, // RES_GRFATR_DUMMY6, + + { 0, false, true }, // RES_BOXATR_FORMAT + { 0, true, false }, // RES_BOXATR_FORMULA, + { 0, false, true }, // RES_BOXATR_VALUE + + { 0, true, true } // RES_UNKNOWNATR_CONTAINER }; std::vector<SvGlobalName> *pGlobalOLEExcludeList = nullptr; diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index 05ea83bfad70..acee83905967 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -416,12 +416,13 @@ bool SwCursorShell::GotoNxtPrvTableFormula( bool bNext, bool bOnlyErrors ) &rPos, &tmp) ); } - sal_uInt32 nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA ); + const registeredSfxPoolItems& rSurrogates(GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)); + const sal_uInt32 nMaxItems(rSurrogates.size()); if( nMaxItems > 0 ) { sal_uInt8 nMaxDo = 2; do { - for (const SfxPoolItem* pItem : GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)) + for (const SfxPoolItem* pItem : rSurrogates) { const SwTableBox* pTBox; auto pFormulaItem = dynamic_cast<const SwTableBoxFormula*>(pItem); @@ -521,7 +522,8 @@ bool SwCursorShell::GotoNxtPrvTOXMark( bool bNext ) const SwTextNode* pTextNd; const SwTextTOXMark* pTextTOX; - sal_uInt32 nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK ); + const registeredSfxPoolItems& rSurrogates(GetDoc()->GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK)); + const sal_uInt32 nMaxItems(rSurrogates.size()); if( nMaxItems == 0 ) { SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound ); @@ -529,7 +531,7 @@ bool SwCursorShell::GotoNxtPrvTOXMark( bool bNext ) } do { - for (const SfxPoolItem* pItem : GetDoc()->GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK)) + for (const SfxPoolItem* pItem : rSurrogates) { auto pToxMarkItem = dynamic_cast<const SwTOXMark*>(pItem); if( !pToxMarkItem ) diff --git a/sw/source/core/doc/docbasic.cxx b/sw/source/core/doc/docbasic.cxx index c28a15f12bf5..697559b0b469 100644 --- a/sw/source/core/doc/docbasic.cxx +++ b/sw/source/core/doc/docbasic.cxx @@ -143,7 +143,7 @@ sal_uInt16 SwDoc::CallEvent( SvMacroItemId nEvent, const SwCallMouseEvent& rCall for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT)) { auto pFormatItem = dynamic_cast<const SwFormatINetFormat*>(pItem); - if( pFormatItem && rCallEvent.PTR.pINetAttr == pFormatItem ) + if( pFormatItem && SfxPoolItem::areSame(rCallEvent.PTR.pINetAttr, pFormatItem) ) { bCheckPtr = false; // misuse as a flag break; diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx index 82051e0be6a8..f03687d810e4 100644 --- a/sw/source/core/doc/doctxm.cxx +++ b/sw/source/core/doc/doctxm.cxx @@ -247,7 +247,8 @@ const SwTOXMark& SwDoc::GotoTOXMark( const SwTOXMark& rCurTOXMark, for(SwTOXMark* pTOXMark : aMarks) { - if ( pTOXMark == &rCurTOXMark ) + // Item PtrCompare needed here + if (areSfxPoolItemPtrsEqual( pTOXMark, &rCurTOXMark )) continue; pMark = pTOXMark->GetTextTOXMark(); diff --git a/sw/source/core/doc/fmtcol.cxx b/sw/source/core/doc/fmtcol.cxx index 5561b882ee3f..4d87241a03ba 100644 --- a/sw/source/core/doc/fmtcol.cxx +++ b/sw/source/core/doc/fmtcol.cxx @@ -237,7 +237,7 @@ void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rH const SvxFirstLineIndentItem *pOldFirstLineIndent(GetItemIfSet(RES_MARGIN_FIRSTLINE, false)); if (pNewFirstLineIndent && pOldFirstLineIndent) { - if (pOldFirstLineIndent != pNewFirstLineIndent) // Avoid recursion (SetAttr!) + if (!SfxPoolItem::areSame(pOldFirstLineIndent, pNewFirstLineIndent)) // Avoid recursion (SetAttr!) { bool bChg = false; SvxFirstLineIndentItem aNew(*pOldFirstLineIndent); @@ -263,7 +263,7 @@ void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rH const SvxTextLeftMarginItem *pOldTextLeftMargin(GetItemIfSet(RES_MARGIN_TEXTLEFT, false)); if (pNewTextLeftMargin && pOldTextLeftMargin) { - if (pOldTextLeftMargin != pNewTextLeftMargin) // Avoid recursion (SetAttr!) + if (!SfxPoolItem::areSame(pOldTextLeftMargin, pNewTextLeftMargin)) // Avoid recursion (SetAttr!) { bool bChg = false; SvxTextLeftMarginItem aNew(*pOldTextLeftMargin); @@ -289,7 +289,7 @@ void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rH const SvxRightMarginItem *pOldRightMargin(GetItemIfSet(RES_MARGIN_RIGHT, false)); if (pNewRightMargin && pOldRightMargin) { - if (pOldRightMargin != pNewRightMargin) // Avoid recursion (SetAttr!) + if (!SfxPoolItem::areSame(pOldRightMargin, pNewRightMargin)) // Avoid recursion (SetAttr!) { bool bChg = false; SvxRightMarginItem aNew(*pOldRightMargin); @@ -313,7 +313,7 @@ void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rH } if( pNewULSpace && (pOldULSpace = GetItemIfSet(RES_UL_SPACE, false)) && - pOldULSpace != pNewULSpace ) // Avoid recursion (SetAttr!) + !SfxPoolItem::areSame(pOldULSpace, pNewULSpace) ) // Avoid recursion (SetAttr!) { SvxULSpaceItem aNew( *pOldULSpace ); bool bChg = false; @@ -348,7 +348,7 @@ void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rH if( pFSize && (SfxItemState::SET == GetItemState( pFSize->Which(), false, reinterpret_cast<const SfxPoolItem**>(&pOldFSize) )) && // Avoid recursion (SetAttr!) - pFSize != pOldFSize ) + !SfxPoolItem::areSame(pFSize, pOldFSize) ) { if( 100 == pOldFSize->GetProp() && MapUnit::MapRelative == pOldFSize->GetPropUnit() ) diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx index 6cfab7801f43..b2419bd132ec 100644 --- a/sw/source/core/docnode/node.cxx +++ b/sw/source/core/docnode/node.cxx @@ -1174,13 +1174,13 @@ void SwContentNode::SwClientNotify( const SwModify&, const SfxHint& rHint) // Thus we are asserting here, but falling back to an proper // hint instead. so that we at least will not spread such poison further. #ifdef DBG_UTIL - if(pLegacyHint->m_pNew != pLegacyHint->m_pOld) + if (!SfxPoolItem::areSame(pLegacyHint->m_pNew, pLegacyHint->m_pOld)) { auto pBT = sal::backtrace_get(20); SAL_WARN("sw.core", "UpdateAttr not matching! " << sal::backtrace_to_string(pBT.get())); } #endif - assert(pLegacyHint->m_pNew == pLegacyHint->m_pOld); + assert(SfxPoolItem::areSame(pLegacyHint->m_pNew, pLegacyHint->m_pOld)); assert(dynamic_cast<const SwUpdateAttr*>(pLegacyHint->m_pNew)); const SwUpdateAttr aFallbackHint(0,0,0); const SwUpdateAttr& rUpdateAttr = pLegacyHint->m_pNew ? *static_cast<const SwUpdateAttr*>(pLegacyHint->m_pNew) : aFallbackHint; diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx index b3dd57ca6c7f..ee4a451d16dc 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -634,9 +634,6 @@ SwFormatPageDesc::SwFormatPageDesc( const SwFormatPageDesc &rCpy ) m_oNumOffset( rCpy.m_oNumOffset ), m_pDefinedIn( nullptr ) { - // ITEM: mark this Item to be non-shareable/non-RefCountable. For more - // info see comment @SwAttrSet::SetModifyAtAttr - m_bShareable = false; } SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc ) @@ -644,14 +641,11 @@ SwFormatPageDesc::SwFormatPageDesc( const SwPageDesc *pDesc ) SwClient( const_cast<SwPageDesc*>(pDesc) ), m_pDefinedIn( nullptr ) { - // ITEM: mark this Item to be non-shareable/non-RefCountable. For more - // info see comment @SwAttrSet::SetModifyAtAttr - m_bShareable = false; } SwFormatPageDesc &SwFormatPageDesc::operator=(const SwFormatPageDesc &rCpy) { - if(this == &rCpy) + if (SfxPoolItem::areSame(this, &rCpy)) return *this; if (rCpy.GetPageDesc()) @@ -865,7 +859,7 @@ SwFormatCol::~SwFormatCol() {} SwFormatCol& SwFormatCol::operator=( const SwFormatCol& rCpy ) { - if (this != &rCpy) + if (!SfxPoolItem::areSame(this, &rCpy)) { m_eLineStyle = rCpy.m_eLineStyle; m_nLineWidth = rCpy.m_nLineWidth; @@ -1650,7 +1644,7 @@ sal_Int32 SwFormatAnchor::GetAnchorContentOffset() const SwFormatAnchor& SwFormatAnchor::operator=(const SwFormatAnchor& rAnchor) { - if (this != &rAnchor) + if (!SfxPoolItem::areSame(this, &rAnchor)) { m_eAnchorId = rAnchor.m_eAnchorId; m_nPageNumber = rAnchor.m_nPageNumber; diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx index 7afcb6b89800..fdbcb5a57092 100644 --- a/sw/source/core/layout/sectfrm.cxx +++ b/sw/source/core/layout/sectfrm.cxx @@ -147,7 +147,7 @@ void SwSectionFrame::Init() { const SwFormatCol *pOld = Lower() ? &rCol : new SwFormatCol; ChgColumns( *pOld, rCol, IsAnyNoteAtEnd() ); - if( pOld != &rCol ) + if (!SfxPoolItem::areSame( pOld, &rCol )) delete pOld; } } diff --git a/sw/source/core/para/paratr.cxx b/sw/source/core/para/paratr.cxx index 7d57bcd3c7a4..f724ac21c0fe 100644 --- a/sw/source/core/para/paratr.cxx +++ b/sw/source/core/para/paratr.cxx @@ -44,9 +44,6 @@ SwFormatDrop::SwFormatDrop() m_nChars( 0 ), m_bWholeWord( false ) { - // ITEM: mark this Item to be non-shareable/non-RefCountable. For more - // info see comment @SwAttrSet::SetModifyAtAttr - m_bShareable = false; } SwFormatDrop::SwFormatDrop( const SwFormatDrop &rCpy ) @@ -58,9 +55,6 @@ SwFormatDrop::SwFormatDrop( const SwFormatDrop &rCpy ) m_nChars( rCpy.GetChars() ), m_bWholeWord( rCpy.GetWholeWord() ) { - // ITEM: mark this Item to be non-shareable/non-RefCountable. For more - // info see comment @SwAttrSet::SetModifyAtAttr - m_bShareable = false; } SwFormatDrop::~SwFormatDrop() diff --git a/sw/source/core/table/swnewtable.cxx b/sw/source/core/table/swnewtable.cxx index 4e1386f4e21a..3cc2e3670711 100644 --- a/sw/source/core/table/swnewtable.cxx +++ b/sw/source/core/table/swnewtable.cxx @@ -2383,7 +2383,7 @@ bool SwTable::CanConvertSubtables() const { return false; // no formulas in fields yet } - if (pDoc->GetAttrPool().GetItemCount2(RES_BOXATR_FORMULA) != 0) + if (pDoc->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA).size() != 0) { return false; // no table box formulas yet } diff --git a/sw/source/core/table/swtable.cxx b/sw/source/core/table/swtable.cxx index d50c493079a2..a5540a491b0e 100644 --- a/sw/source/core/table/swtable.cxx +++ b/sw/source/core/table/swtable.cxx @@ -1630,16 +1630,16 @@ bool SwTable::IsDeleted() const void SwTable::GatherFormulas(std::vector<SwTableBoxFormula*>& rvFormulas) { - for(SfxPoolItem* pItem: GetFrameFormat()->GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)) + for(const SfxPoolItem* pItem: GetFrameFormat()->GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA)) { - auto pBoxFormula = dynamic_cast<SwTableBoxFormula*>(pItem); + auto pBoxFormula = dynamic_cast<const SwTableBoxFormula*>(pItem); assert(pBoxFormula); // use StaticWhichCast instead? if(!pBoxFormula->GetDefinedIn()) continue; const SwNode* pNd = pBoxFormula->GetNodeOfFormula(); if(!pNd || &pNd->GetNodes() != &pNd->GetDoc().GetNodes()) // is this ever valid or should we assert here? continue; - rvFormulas.push_back(pBoxFormula); + rvFormulas.push_back(const_cast<SwTableBoxFormula*>(pBoxFormula)); } } diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx index 358d6d5068f3..24203ecb531c 100644 --- a/sw/source/core/text/itratr.cxx +++ b/sw/source/core/text/itratr.cxx @@ -659,9 +659,9 @@ static bool CanSkipOverRedline( } for (size_t i = 0; i < SAL_N_ELEMENTS(activeCharAttrsStart); ++i) { - // all of these are poolable -// assert(!activeCharAttrsStart[i] || activeCharAttrsStart[i]->GetItemPool()->IsItemPoolable(*activeCharAttrsStart[i])); - if (activeCharAttrsStart[i] != activeCharAttrsEnd[i]) + // all of these should be shareable (but we have no SfxItemPool to check it here) + // assert(!activeCharAttrsStart[i] || activeCharAttrsStart[i]->GetItemPool()->Shareable(*activeCharAttrsStart[i])); + if (!SfxPoolItem::areSame(activeCharAttrsStart[i], activeCharAttrsEnd[i])) { if (!isTheAnswerYes) return false; } diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx index 67cd13af4d6d..4e7268698efc 100644 --- a/sw/source/core/text/pormulti.cxx +++ b/sw/source/core/text/pormulti.cxx @@ -1080,7 +1080,7 @@ std::optional<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &rP return aRet; } if (pActiveTwoLinesHint || - (pNodeTwoLinesItem && pNodeTwoLinesItem == pActiveTwoLinesItem && + (pNodeTwoLinesItem && SfxPoolItem::areSame(pNodeTwoLinesItem, pActiveTwoLinesItem) && rPos < TextFrameIndex(GetText().getLength()))) { // The winner is a 2-line-attribute, // the end of the multiportion depends on the following attributes... @@ -1228,7 +1228,7 @@ std::optional<SwMultiCreator> SwTextSizeInfo::GetMultiCreator(TextFrameIndex &rP return aRet; } if (pActiveRotateHint || - (pNodeRotateItem && pNodeRotateItem == pActiveRotateItem && + (pNodeRotateItem && SfxPoolItem::areSame(pNodeRotateItem, pActiveRotateItem) && rPos < TextFrameIndex(GetText().getLength()))) { // The winner is a rotate-attribute, // the end of the multiportion depends on the following attributes... diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx index a86dfcaf175f..470ce8b528fd 100644 --- a/sw/source/core/text/txtfrm.cxx +++ b/sw/source/core/text/txtfrm.cxx @@ -2459,7 +2459,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint) nPos = MapModelToView(&rNode, nNPos); if (IsIdxInside(nPos, TextFrameIndex(1))) { - if( pNew == pOld ) + if (SfxPoolItem::areSame( pNew, pOld )) { // only repaint // opt: invalidate window? @@ -2518,7 +2518,7 @@ void SwTextFrame::SwClientNotify(SwModify const& rModify, SfxHint const& rHint) { const SfxPoolItem* pOldItem = pOld ? &(static_cast<const SwAttrSetChg*>(pOld)->GetChgSet()->Get(RES_TXTATR_FIELD)) : nullptr; - if( pItem == pOldItem ) + if (SfxPoolItem::areSame( pItem, pOldItem )) { InvalidatePage(); SetCompletePaint(); diff --git a/sw/source/core/txtnode/attrcontentcontrol.cxx b/sw/source/core/txtnode/attrcontentcontrol.cxx index 34db9fde8aaa..1782f23fb526 100644 --- a/sw/source/core/txtnode/attrcontentcontrol.cxx +++ b/sw/source/core/txtnode/attrcontentcontrol.cxx @@ -67,7 +67,9 @@ SwFormatContentControl::SwFormatContentControl( SwFormatContentControl::~SwFormatContentControl() { - if (m_pContentControl && (m_pContentControl->GetFormatContentControl() == this)) + if (m_pContentControl + // SwFormatContentControl is not shareable, so ptr compare is OK + && areSfxPoolItemPtrsEqual(m_pContentControl->GetFormatContentControl(), this)) { NotifyChangeTextNode(nullptr); m_pContentControl->SetFormatContentControl(nullptr); @@ -116,7 +118,8 @@ void SwFormatContentControl::SetTextAttr(SwTextContentControl* pTextAttr) { m_pContentControl->SetFormatContentControl(this); } - else if (m_pContentControl->GetFormatContentControl() == this) + // SwFormatContentControl is not shareable, so ptr compare is OK + else if (areSfxPoolItemPtrsEqual(m_pContentControl->GetFormatContentControl(), this)) { // The text attribute is gone, so de-register from text node. NotifyChangeTextNode(nullptr); @@ -132,7 +135,9 @@ void SwFormatContentControl::NotifyChangeTextNode(SwTextNode* pTextNode) { SAL_WARN("sw.core", "SwFormatContentControl::NotifyChangeTextNode: no content control?"); } - if (m_pContentControl && (m_pContentControl->GetFormatContentControl() == this)) + if (m_pContentControl + // SwFormatContentControl is not shareable, so ptr compare is OK + && areSfxPoolItemPtrsEqual(m_pContentControl->GetFormatContentControl(), this)) { // Not calling Modify, that would call SwXContentControl::SwClientNotify. m_pContentControl->NotifyChangeTextNode(pTextNode); diff --git a/sw/source/core/txtnode/fmtatr2.cxx b/sw/source/core/txtnode/fmtatr2.cxx index 7792d0183d54..3a57680fa51b 100644 --- a/sw/source/core/txtnode/fmtatr2.cxx +++ b/sw/source/core/txtnode/fmtatr2.cxx @@ -428,7 +428,8 @@ SwFormatRuby::~SwFormatRuby() SwFormatRuby& SwFormatRuby::operator=( const SwFormatRuby& rAttr ) { - if(this == &rAttr) + // SwFormatRuby is not shareable, so ptr compare is OK + if (areSfxPoolItemPtrsEqual(this, &rAttr)) return *this; m_sRubyText = rAttr.m_sRubyText; @@ -568,7 +569,8 @@ SwFormatMeta::SwFormatMeta( std::shared_ptr< ::sw::Meta > i_pMeta, SwFormatMeta::~SwFormatMeta() { - if (m_pMeta && (m_pMeta->GetFormatMeta() == this)) + // SwFormatMeta is not shareable, so ptr compare is OK + if (m_pMeta && areSfxPoolItemPtrsEqual(m_pMeta->GetFormatMeta(), this)) { NotifyChangeTextNode(nullptr); m_pMeta->SetFormatMeta(nullptr); @@ -603,7 +605,8 @@ void SwFormatMeta::SetTextAttr(SwTextMeta * const i_pTextAttr) { m_pMeta->SetFormatMeta(this); } - else if (m_pMeta->GetFormatMeta() == this) + // SwFormatMeta is not shareable, so ptr compare is OK + else if (areSfxPoolItemPtrsEqual(m_pMeta->GetFormatMeta(), this)) { // text attribute gone => de-register from text node! NotifyChangeTextNode(nullptr); m_pMeta->SetFormatMeta(nullptr); @@ -616,7 +619,8 @@ void SwFormatMeta::NotifyChangeTextNode(SwTextNode *const pTextNode) // N.B.: do not reset m_pTextAttr here: see call in nodes.cxx, // where the hint is not deleted! OSL_ENSURE(m_pMeta, "SwFormatMeta::NotifyChangeTextNode: no Meta?"); - if (m_pMeta && (m_pMeta->GetFormatMeta() == this)) + // SwFormatMeta is not shareable, so ptr compare is OK + if (m_pMeta && areSfxPoolItemPtrsEqual(m_pMeta->GetFormatMeta(), this)) { // do not call Modify, that would call SwXMeta::SwClientNotify m_pMeta->NotifyChangeTextNode(pTextNode); } diff --git a/sw/source/core/txtnode/thints.cxx b/sw/source/core/txtnode/thints.cxx index 71c1ed75d059..0556facafe19 100644 --- a/sw/source/core/txtnode/thints.cxx +++ b/sw/source/core/txtnode/thints.cxx @@ -899,7 +899,7 @@ void SwpHints::BuildPortions( SwTextNode& rNode, SwTextAttr& rNewHint, { const SfxPoolItem* pTmpItem = nullptr; if ( SfxItemState::SET == rWholeParaAttrSet.GetItemState( pItem->Which(), false, &pTmpItem ) && - pTmpItem == pItem ) + SfxPoolItem::areSame(pTmpItem, pItem) ) { // Do not clear item if the attribute is set in a character format: if ( !pCurrentCharFormat || nullptr == CharFormat::GetItem( *pCurrentCharFormat, pItem->Which() ) ) @@ -936,8 +936,9 @@ void SwpHints::BuildPortions( SwTextNode& rNode, SwTextAttr& rNewHint, do { const SfxPoolItem* pTmpItem = nullptr; + // here direct SfxPoolItem ptr comp was wrong, found using SfxPoolItem::areSame if ( SfxItemState::SET == rWholeParaAttrSet.GetItemState( pItem->Which(), false, &pTmpItem ) && - pTmpItem == pItem ) + SfxPoolItem::areSame(pTmpItem, pItem) ) { // Do not clear item if the attribute is set in a character format: if ( !pCurrentCharFormat || nullptr == CharFormat::GetItem( *pCurrentCharFormat, pItem->Which() ) ) @@ -1023,7 +1024,7 @@ SwTextAttr* MakeRedlineTextAttr( SwDoc & rDoc, SfxPoolItem const & rAttr ) // Put new attribute into pool // FIXME: this const_cast is evil! SfxPoolItem& rNew = - const_cast<SfxPoolItem&>( rDoc.GetAttrPool().Put( rAttr ) ); + const_cast<SfxPoolItem&>( rDoc.GetAttrPool().DirectPutItemInPool( rAttr ) ); return new SwTextAttrEnd( rNew, 0, 0 ); } @@ -1061,7 +1062,7 @@ SwTextAttr* MakeTextAttr( // Put new attribute into pool // FIXME: this const_cast is evil! SfxPoolItem& rNew = - const_cast<SfxPoolItem&>( rDoc.GetAttrPool().Put( rAttr ) ); + const_cast<SfxPoolItem&>( rDoc.GetAttrPool().DirectPutItemInPool( rAttr ) ); SwTextAttr* pNew = nullptr; switch( rNew.Which() ) @@ -2981,18 +2982,22 @@ static MergeResult lcl_Compare_Attributes( pItem1 = iter1.NextItem(); if (pItem2 && pItem2->Which() == RES_CHRATR_RSID) pItem2 = iter2.NextItem(); - if (!pItem1 && !pItem2) + + if (nullptr == pItem1 && nullptr == pItem2) { eMerge = DIFFER_ONLY_RSID; break; } - if (!pItem1 || !pItem2) + + if (nullptr == pItem1 || nullptr == pItem2) { + // one ptr is nullptr, not both, that would + // have triggered above return DIFFER; } - if (pItem1 != pItem2) // all are poolable + + if (!SfxPoolItem::areSame(*pItem1, *pItem2)) { - assert(IsInvalidItem(pItem1) || IsInvalidItem(pItem2) || pItem1->Which() != pItem2->Which() || *pItem1 != *pItem2); return DIFFER; } pItem1 = iter1.NextItem(); diff --git a/sw/source/core/txtnode/txatbase.cxx b/sw/source/core/txtnode/txatbase.cxx index df347860db11..1d57f0e0dda5 100644 --- a/sw/source/core/txtnode/txatbase.cxx +++ b/sw/source/core/txtnode/txatbase.cxx @@ -60,7 +60,7 @@ void SwTextAttr::Destroy( SwTextAttr * pToDestroy, SfxItemPool& rPool ) if (!pToDestroy) return; SfxPoolItem * const pAttr = pToDestroy->m_pAttr; delete pToDestroy; - rPool.Remove( *pAttr ); + rPool.DirectRemoveItemFromPool( *pAttr ); } bool SwTextAttr::operator==( const SwTextAttr& rAttr ) const diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx index d17c08e4795b..9a18fde99ffe 100644 --- a/sw/source/core/undo/rolbck.cxx +++ b/sw/source/core/undo/rolbck.cxx @@ -502,7 +502,7 @@ void SwHistorySetFootnote::SetInDoc( SwDoc* pDoc, bool ) // set the footnote in the TextNode SwFormatFootnote aTemp( m_bEndNote ); SwFormatFootnote& rNew = const_cast<SwFormatFootnote&>( - pDoc->GetAttrPool().Put(aTemp) ); + pDoc->GetAttrPool().DirectPutItemInPool(aTemp) ); if ( !m_FootnoteNumber.isEmpty() ) { rNew.SetNumStr( m_FootnoteNumber ); @@ -1382,7 +1382,7 @@ void SwRegHistory::SwClientNotify(const SwModify&, const SfxHint& rHint) if (rHint.GetId() != SfxHintId::SwLegacyModify) return; auto pLegacyHint = static_cast<const sw::LegacyModifyHint*>(&rHint); - if ( !(m_pHistory && pLegacyHint->m_pNew && pLegacyHint->m_pOld != pLegacyHint->m_pNew) ) + if ( !(m_pHistory && pLegacyHint->m_pNew && !areSfxPoolItemPtrsEqual(pLegacyHint->m_pOld, pLegacyHint->m_pNew) ) ) return; if ( pLegacyHint->m_pNew->Which() < POOLATTR_END ) diff --git a/sw/source/core/undo/unattr.cxx b/sw/source/core/undo/unattr.cxx index 66ccb4073bc3..7e694e21b7d2 100644 --- a/sw/source/core/undo/unattr.cxx +++ b/sw/source/core/undo/unattr.cxx @@ -683,7 +683,7 @@ void SwUndoResetAttr::RedoImpl(::sw::UndoRedoContext & rContext) break; case RES_TXTATR_REFMARK: { - SfxItemPool::Item2Range aRange = rDoc.GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK); + const registeredSfxPoolItems& aRange(rDoc.GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)); SwHistoryHint* pHistoryHint = GetHistory()[0]; if (pHistoryHint && HSTRY_SETREFMARKHNT == pHistoryHint->Which()) { diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx index 781c5555a6f6..f0430b965bc2 100644 --- a/sw/source/core/undo/undobj1.cxx +++ b/sw/source/core/undo/undobj1.cxx @@ -648,7 +648,7 @@ void SwUndoSetFlyFormat::RedoImpl(::sw::UndoRedoContext & rContext) void SwUndoSetFlyFormat::PutAttr( sal_uInt16 nWhich, const SfxPoolItem* pItem ) { - if( pItem && pItem != GetDfltAttr( nWhich ) ) + if( pItem && !SfxPoolItem::areSame(pItem, GetDfltAttr( nWhich ) ) ) { // Special treatment for this anchor if( RES_ANCHOR == nWhich ) diff --git a/sw/source/core/unocore/unorefmk.cxx b/sw/source/core/unocore/unorefmk.cxx index b86fbc675730..43b0690ecb08 100644 --- a/sw/source/core/unocore/unorefmk.cxx +++ b/sw/source/core/unocore/unorefmk.cxx @@ -284,7 +284,7 @@ SwXReferenceMark::getAnchor() { SwFormatRefMark const*const pNewMark = m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName); - if (pNewMark && (pNewMark == m_pImpl->m_pMarkFormat)) + if (pNewMark && SfxPoolItem::areSame(pNewMark, m_pImpl->m_pMarkFormat)) { SwTextRefMark const*const pTextMark = m_pImpl->m_pMarkFormat->GetTextRefMark(); @@ -315,7 +315,7 @@ void SAL_CALL SwXReferenceMark::dispose() { SwFormatRefMark const*const pNewMark = m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName); - if (pNewMark && (pNewMark == m_pImpl->m_pMarkFormat)) + if (pNewMark && SfxPoolItem::areSame(pNewMark, m_pImpl->m_pMarkFormat)) { SwTextRefMark const*const pTextMark = m_pImpl->m_pMarkFormat->GetTextRefMark(); @@ -385,7 +385,7 @@ void SAL_CALL SwXReferenceMark::setName(const OUString& rName) SwFormatRefMark const*const pCurMark = m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName); if ((rName != m_pImpl->m_sMarkName) - && pCurMark && (pCurMark == m_pImpl->m_pMarkFormat)) + && pCurMark && SfxPoolItem::areSame(pCurMark, m_pImpl->m_pMarkFormat)) { const UnoActionContext aCont(m_pImpl->m_pDoc); SwTextRefMark const*const pTextMark = diff --git a/sw/source/filter/basflt/fltshell.cxx b/sw/source/filter/basflt/fltshell.cxx index d33cd0a81652..731a7c42d770 100644 --- a/sw/source/filter/basflt/fltshell.cxx +++ b/sw/source/filter/basflt/fltshell.cxx @@ -915,7 +915,7 @@ void SwFltAnchorListener::Notify(const SfxHint& rHint) bool SwFltRedline::operator==(const SfxPoolItem& rItem) const { return SfxPoolItem::operator==(rItem) && - this == &rItem; + SfxPoolItem::areSame(this, &rItem); } SwFltRedline* SwFltRedline::Clone( SfxItemPool* ) const diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx index 5ed18a2cad7c..448a64a2f2a5 100644 --- a/sw/source/filter/writer/writer.cxx +++ b/sw/source/filter/writer/writer.cxx @@ -63,7 +63,7 @@ void Writer_Impl::RemoveFontList( SwDoc& rDoc ) { for( const auto& rpFontItem : aFontRemoveLst ) { - rDoc.GetAttrPool().Remove( *rpFontItem ); + rDoc.GetAttrPool().DirectRemoveItemFromPool( *rpFontItem ); } } @@ -379,13 +379,13 @@ void Writer::AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont ) { SvxFontItem aFont( rFont ); aFont.SetWhich( RES_CHRATR_FONT ); - pItem = &rPool.Put( aFont ); + pItem = &rPool.DirectPutItemInPool( aFont ); } else - pItem = &rPool.Put( rFont ); + pItem = &rPool.DirectPutItemInPool( rFont ); if( 1 < pItem->GetRefCount() ) - rPool.Remove( *pItem ); + rPool.DirectRemoveItemFromPool( *pItem ); else { m_pImpl->aFontRemoveLst.push_back( pItem ); diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx index 06f96f23d24f..fdadb13d34a7 100644 --- a/sw/source/filter/ww8/wrtww8.cxx +++ b/sw/source/filter/ww8/wrtww8.cxx @@ -3330,7 +3330,7 @@ void MSWordExportBase::AddLinkTarget(std::u16string_view rURL) { pMark = &m_rDoc.GotoTOXMark(*pMark, TOX_SAME_NXT, true); } - if (pMark != &tmp->first) + if (!SfxPoolItem::areSame(pMark, &tmp->first)) { m_TOXMarkBookmarksByURL.emplace(aURL, name); m_TOXMarkBookmarksByTOXMark.emplace(pMark, nameDecoded); diff --git a/sw/source/filter/xml/xmlfonte.cxx b/sw/source/filter/xml/xmlfonte.cxx index b8c0f7730d57..c6a9c89cb6ca 100644 --- a/sw/source/filter/xml/xmlfonte.cxx +++ b/sw/source/filter/xml/xmlfonte.cxx @@ -39,6 +39,24 @@ public: } +namespace +{ +sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB) +{ + if (nA < nB) + { + return -1; + } + + if (nA > nB) + { + return 1; + } + + return 0; +} +} + SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& _rExport, bool bFontEmbedding) : XMLFontAutoStylePool(_rExport, bFontEmbedding) { @@ -60,7 +78,34 @@ SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& _rExport, } std::sort(aFonts.begin(), aFonts.end(), - [](const SvxFontItem* pA, const SvxFontItem* pB) -> bool { return *pA < *pB; }); + [](const SvxFontItem* pA, const SvxFontItem* pB) -> bool + { + sal_Int32 nRet = pA->GetFamilyName().compareTo(pB->GetFamilyName()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = pA->GetStyleName().compareTo(pB->GetStyleName()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = CompareTo(pA->GetFamily(), pB->GetFamily()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = CompareTo(pA->GetPitch(), pB->GetPitch()); + if (nRet != 0) + { + return nRet < 0; + } + + return pA->GetCharSet() < pB->GetCharSet(); + }); for (const auto& pFont : aFonts) { Add(pFont->GetFamilyName(), pFont->GetStyleName(), pFont->GetFamily(), pFont->GetPitch(), diff --git a/sw/source/ui/index/swuiidxmrk.cxx b/sw/source/ui/index/swuiidxmrk.cxx index 52904b73d68e..39443f7e7b04 100644 --- a/sw/source/ui/index/swuiidxmrk.cxx +++ b/sw/source/ui/index/swuiidxmrk.cxx @@ -287,19 +287,19 @@ void SwIndexMarkPane::InitControls() bool bShow = false; pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) { m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT ); bShow = true; } - m_xPrevBT->set_sensitive(pMoveMark != pMark); + m_xPrevBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark)); pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) { m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV ); bShow = true; } - m_xNextBT->set_sensitive(pMoveMark != pMark); + m_xNextBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark)); if( bShow ) { m_xPrevBT->show(); @@ -308,19 +308,19 @@ void SwIndexMarkPane::InitControls() } pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) { m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT ); bShow = true; } - m_xPrevSameBT->set_sensitive(pMoveMark != pMark); + m_xPrevSameBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark)); pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) { m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV ); bShow = true; } - m_xNextSameBT->set_sensitive(pMoveMark != pMark); + m_xNextSameBT->set_sensitive(!SfxPoolItem::areSame(pMoveMark, pMark)); if( bShow ) { m_xNextSameBT->show(); @@ -894,25 +894,25 @@ void SwIndexMarkPane::UpdateDialog() if( m_xPrevBT->get_visible() ) { const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_PRV ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) m_pSh->GotoTOXMark( *pMoveMark, TOX_NXT ); - m_xPrevBT->set_sensitive( pMoveMark != pMark ); + m_xPrevBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) ); pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_NXT ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) m_pSh->GotoTOXMark( *pMoveMark, TOX_PRV ); - m_xNextBT->set_sensitive( pMoveMark != pMark ); + m_xNextBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) ); } if (m_xPrevSameBT->get_visible()) { const SwTOXMark* pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_PRV ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_NXT ); - m_xPrevSameBT->set_sensitive( pMoveMark != pMark ); + m_xPrevSameBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) ); pMoveMark = &m_pSh->GotoTOXMark( *pMark, TOX_SAME_NXT ); - if( pMoveMark != pMark ) + if (!SfxPoolItem::areSame( pMoveMark, pMark )) m_pSh->GotoTOXMark( *pMoveMark, TOX_SAME_PRV ); - m_xNextSameBT->set_sensitive( pMoveMark != pMark ); + m_xNextSameBT->set_sensitive( !SfxPoolItem::areSame(pMoveMark, pMark) ); } const bool bEnable = !m_pSh->HasReadonlySel(); @@ -1013,7 +1013,7 @@ void SwIndexMarkPane::ReInitDlg(SwWrtShell& rWrtShell, SwTOXMark const * pCurTOX if(pCurTOXMark) { for(sal_uInt16 i = 0; i < m_pTOXMgr->GetTOXMarkCount(); i++) - if(m_pTOXMgr->GetTOXMark(i) == pCurTOXMark) + if (SfxPoolItem::areSame(m_pTOXMgr->GetTOXMark(i), pCurTOXMark)) { m_pTOXMgr->SetCurTOXMark(i); break; diff --git a/sw/source/uibase/index/toxmgr.cxx b/sw/source/uibase/index/toxmgr.cxx index 5fc78fc18053..8b8ff6dbd8ec 100644 --- a/sw/source/uibase/index/toxmgr.cxx +++ b/sw/source/uibase/index/toxmgr.cxx @@ -47,7 +47,7 @@ void SwTOXMgr::DeleteTOXMark() if( m_pCurTOXMark ) { pNext = const_cast<SwTOXMark*>(&m_pSh->GotoTOXMark( *m_pCurTOXMark, TOX_NXT )); - if( pNext == m_pCurTOXMark ) + if (SfxPoolItem::areSame( pNext, m_pCurTOXMark )) pNext = nullptr; m_pSh->DeleteTOXMark( m_pCurTOXMark ); diff --git a/sw/source/uibase/shells/frmsh.cxx b/sw/source/uibase/shells/frmsh.cxx index 65c41becb0c3..0976b6cb42c0 100644 --- a/sw/source/uibase/shells/frmsh.cxx +++ b/sw/source/uibase/shells/frmsh.cxx @@ -1093,7 +1093,7 @@ void SwFrameShell::ExecFrameStyle(SfxRequest const & rReq) rSh.GetFlyFrameAttr( aFrameSet ); const SvxBoxItem& rBoxItem = aFrameSet.Get(RES_BOX); - if (pPoolBoxItem == &rBoxItem) + if (SfxPoolItem::areSame(pPoolBoxItem, &rBoxItem)) bDefault = true; std::unique_ptr<SvxBoxItem> aBoxItem(rBoxItem.Clone()); diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx index a6aae01383a8..6cb3aeedeece 100644 --- a/sw/source/uibase/uiview/view2.cxx +++ b/sw/source/uibase/uiview/view2.cxx @@ -2538,7 +2538,8 @@ static auto JumpToTOXMark(SwWrtShell & rSh, std::u16string_view aName) -> bool } SwTOXMark const* pMark(&tmp->first); // hack: check first if one exists - if (&tmp->first != &rSh.GetDoc()->GotoTOXMark(tmp->first, TOX_SAME_NXT, rSh.IsReadOnlyAvailable())) + // need simple ptr control, else UnitTest CppunitTest_sw_uiwriter3 fails + if (!areSfxPoolItemPtrsEqual(&tmp->first, &rSh.GetDoc()->GotoTOXMark(tmp->first, TOX_SAME_NXT, rSh.IsReadOnlyAvailable()))) { for (sal_Int32 i = 0; i < tmp->second; ++i) { diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 3a4322ad1532..4c126fb6193d 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -5262,7 +5262,7 @@ void SwContentTree::EditEntry(const weld::TreeIter& rEntry, EditEntryMode nMode) if(nMode == EditEntryMode::DELETE) { const OUString& rName = pCnt->GetName(); - for (SfxPoolItem* pItem : + for (const SfxPoolItem* pItem : m_pActiveShell->GetDoc()->GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK)) { assert(dynamic_cast<const SwFormatRefMark*>(pItem)); diff --git a/vcl/source/app/svapp.cxx b/vcl/source/app/svapp.cxx index 269077ddb0ff..44dfa0ad2a7b 100644 --- a/vcl/source/app/svapp.cxx +++ b/vcl/source/app/svapp.cxx @@ -78,6 +78,7 @@ #ifdef DBG_UTIL #include <svl/poolitem.hxx> #include <svl/itemset.hxx> +#include <svl/itempool.hxx> #endif #include <cassert> @@ -192,12 +193,20 @@ Application::~Application() // on amounts of SfxPoolItems used during office usage and to be able to // detect if an error in future changes may lead to memory losses - these // would show in dramatically higher numbers then immediately - SAL_WARN("vcl", "ITEM: " << getAllocatedSfxPoolItemCount() << " SfxPoolItems still allocated at shutdown"); - SAL_WARN("vcl", "ITEM: " << getUsedSfxPoolItemCount() << " SfxPoolItems were incarnated during office usage"); + SAL_INFO("vcl.items", "ITEM: " << getAllocatedSfxPoolItemCount() << " SfxPoolItems still allocated at shutdown"); + SAL_INFO("vcl.items", "ITEM: " << getUsedSfxPoolItemCount() << " SfxPoolItems were incarnated during runtime"); // Same mechanism for SfxItemSet(s) - SAL_WARN("vcl", "ITEM: " << getAllocatedSfxItemSetCount() << " SfxItemSets still allocated at shutdown"); - SAL_WARN("vcl", "ITEM: " << getUsedSfxItemSetCount() << " SfxItemSets were incarnated during office usage"); + SAL_INFO("vcl.items", "ITEM: " << getAllocatedSfxItemSetCount() << " SfxItemSets still allocated at shutdown"); + SAL_INFO("vcl.items", "ITEM: " << getUsedSfxItemSetCount() << " SfxItemSets were incarnated during runtime"); + + // Same mechanism for SfxPoolItem(s)directly put to a Pool + SAL_INFO("vcl.items", "ITEM: " << getRemainingDirectlyPooledSfxPoolItemCount() << " SfxPoolItems still directly put in Pool at shutdown (deleted @Pool destruction)"); + SAL_INFO("vcl.items", "ITEM: " << getAllDirectlyPooledSfxPoolItemCount() << " SfxPoolItems directly put in Pool"); + + // Additional call to list still incarnated SfxPoolItems (under 'svl.items') + listAllocatedSfxPoolItems(); + #endif } |