diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-09-26 20:22:21 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-09-27 13:11:56 +0200 |
commit | 4a736dff5ae2865318cab5d504b5b68feeb949be (patch) | |
tree | 491c583c8dea73639642698f0cd565437b46f286 /sw | |
parent | 1c3eb14d8620e1b8f933c6faf24fdfcfa322cf2f (diff) |
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/79657
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/doc/doclay.cxx | 59 |
1 files changed, 31 insertions, 28 deletions
diff --git a/sw/source/core/doc/doclay.cxx b/sw/source/core/doc/doclay.cxx index 1899a9f8a918..5f6e9c669533 100644 --- a/sw/source/core/doc/doclay.cxx +++ b/sw/source/core/doc/doclay.cxx @@ -1287,21 +1287,21 @@ 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); + 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 |