sw/source/core/doc/doclay.cxx | 61 ++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 29 deletions(-)
New commits: commit e9170061513c38f8958ddc1a461540823ec34423 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Thu Sep 26 20:22:21 2019 +0100 Commit: Michael Stahl <michael.st...@cib.de> CommitDate: Fri Sep 27 11:26:44 2019 +0200 Resolves: tdf#122487 avoid duplicates when auto-naming drawing objects we were looking inside groups already, but our set was limited to the length of toplevel objects, so it wasn't sufficient. just collect all used nums and return the first unused number Change-Id: I239118e9cff7b7ed2a40d68f284c3c4d1d9eb6c4 Reviewed-on: https://gerrit.libreoffice.org/79658 Tested-by: Jenkins Reviewed-by: Michael Stahl <michael.st...@cib.de> diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx index 851be6949741..5be7e052f832 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1287,22 +1287,22 @@ SwFlyFrameFormat* SwDoc::InsertDrawLabel( return pNewFormat; } -static void lcl_SetNumUsedBit(std::vector<sal_uInt8>& rSetFlags, size_t nFormatSize, sal_Int32 nNmLen, const OUString& rName, const OUString& rCmpName) +static void lcl_collectUsedNums(std::vector<unsigned int>& rSetFlags, sal_Int32 nNmLen, const OUString& rName, const OUString& rCmpName) { if (rName.startsWith(rCmpName)) { // Only get and set the Flag - const sal_Int32 nNum = rName.copy(nNmLen).toInt32()-1; - if (nNum >= 0 && static_cast<SwFrameFormats::size_type>(nNum) < nFormatSize) - rSetFlags[ nNum / 8 ] |= (0x01 << ( nNum & 0x07 )); + const sal_Int32 nNum = rName.copy(nNmLen).toInt32() - 1; + if (nNum >= 0) + rSetFlags.push_back(nNum); } } -static void lcl_SetNumUsedBit(std::vector<sal_uInt8>& rSetFlags, size_t nFormatSize, sal_Int32 nNmLen, const SdrObject& rObj, const OUString& rCmpName) +static void lcl_collectUsedNums(std::vector<unsigned int>& rSetFlags, sal_Int32 nNmLen, const SdrObject& rObj, const OUString& rCmpName) { OUString sName = rObj.GetName(); - lcl_SetNumUsedBit(rSetFlags, nFormatSize, nNmLen, sName, rCmpName); - // tdf#122487 take groups into account, interate and recurse through their + lcl_collectUsedNums(rSetFlags, nNmLen, sName, rCmpName); + // tdf#122487 take groups into account, iterate and recurse through their // contents for name collision check if (rObj.IsGroupObject()) { @@ -1314,11 +1314,29 @@ static void lcl_SetNumUsedBit(std::vector<sal_uInt8>& rSetFlags, size_t nFormatS SdrObject* pObj = pSub->GetObj(i); if (!pObj) continue; - lcl_SetNumUsedBit(rSetFlags, nFormatSize, nNmLen, *pObj, rCmpName); + lcl_collectUsedNums(rSetFlags, nNmLen, *pObj, rCmpName); } } } +namespace +{ + int first_available_number(std::vector<unsigned int>& numbers) + { + std::sort(numbers.begin(), numbers.end()); + auto last = std::unique(numbers.begin(), numbers.end()); + numbers.erase(last, numbers.end()); + + for (size_t i = 0; i < numbers.size(); ++i) + { + if (numbers[i] != i) + return i; + } + + return numbers.size(); + } +} + static OUString lcl_GetUniqueFlyName(const SwDoc* pDoc, const char* pDefStrId, sal_uInt16 eType) { assert(eType >= RES_FMT_BEGIN && eType < RES_FMT_END); @@ -1335,7 +1353,8 @@ static OUString lcl_GetUniqueFlyName(const SwDoc* pDoc, const char* pDefStrId, s const SwFrameFormats& rFormats = *pDoc->GetSpzFrameFormats(); - std::vector<sal_uInt8> aSetFlags(rFormats.size()/8 + 2); + std::vector<unsigned int> aUsedNums; + aUsedNums.reserve(rFormats.size()); for( SwFrameFormats::size_type n = 0; n < rFormats.size(); ++n ) { @@ -1346,34 +1365,18 @@ static OUString lcl_GetUniqueFlyName(const SwDoc* pDoc, const char* pDefStrId, s { const SdrObject *pObj = pFlyFormat->FindSdrObject(); if (pObj) - lcl_SetNumUsedBit(aSetFlags, rFormats.size(), nNmLen, *pObj, aName); + lcl_collectUsedNums(aUsedNums, nNmLen, *pObj, aName); } else { OUString sName = pFlyFormat->GetName(); - lcl_SetNumUsedBit(aSetFlags, rFormats.size(), nNmLen, sName, aName); + lcl_collectUsedNums(aUsedNums, nNmLen, sName, aName); } } // All numbers are flagged accordingly, so determine the right one - SwFrameFormats::size_type nNum = rFormats.size(); - for( std::vector<sal_uInt8>::size_type n=0; n<aSetFlags.size(); ++n ) - { - sal_uInt8 nTmp = aSetFlags[ n ]; - if( 0xff != nTmp ) - { - // so determine the number - nNum = n * 8; - while( nTmp & 1 ) - { - ++nNum; - nTmp >>= 1; - } - break; - } - } - - return aName + OUString::number( ++nNum ); + SwFrameFormats::size_type nNum = first_available_number(aUsedNums) + 1; + return aName + OUString::number(nNum); } OUString SwDoc::GetUniqueGrfName() const _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits