summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-09-26 20:22:21 +0100
committerCaolán McNamara <caolanm@redhat.com>2019-09-27 13:11:56 +0200
commit4a736dff5ae2865318cab5d504b5b68feeb949be (patch)
tree491c583c8dea73639642698f0cd565437b46f286 /sw
parent1c3eb14d8620e1b8f933c6faf24fdfcfa322cf2f (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.cxx59
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