[Libreoffice-commits] core.git: sw/source

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Fri Sep 27 11:13:52 UTC 2019


 sw/source/core/doc/doclay.cxx |   59 ++++++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 28 deletions(-)

New commits:
commit 4a736dff5ae2865318cab5d504b5b68feeb949be
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Thu Sep 26 20:22:21 2019 +0100
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Fri Sep 27 13:11:56 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/79657
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

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


More information about the Libreoffice-commits mailing list