editeng/source/items/numitem.cxx |   28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

New commits:
commit 047e3f62901ae89da30bf1367218104e57439f70
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri May 17 10:01:50 2024 -0400
Commit:     Justin Luth <jl...@mail.com>
CommitDate: Mon May 20 15:40:07 2024 +0200

    related tdf#156105 sw UI: recognize '%' in numbering prefix/suffix
    
    bug 156105's listWithPercents.odt is an example of a
    properly defined ListFormat which contains a percent symbol
    in the prefix and suffix, which looked fine in the document itself,
    but was cut off short in the UI.
    
    sw/qa/extras/ooxmlexport/data/tdf116883.docx is also an example,
    which can be seen if you reduce the first entry to level 1
    instead of level 2.
    Level 1 is improperly defined as "1%>". This is invalid formatting,
    so the entire thing should be considered a suffix.
    MS Word also considers it to be a suffix.
    
    This code segment still isn't completely comprehensive
    because it won't properly parse "%1xyz%1%." and "%1xyz%10%."
    but I'm losing patience.
    
    There is still a potential problem with the
    nInclUpperLevels calculation in case
    a '%' is used as an in-between separator,
    but that seems extremely theoretical and irrelevant to me.
    IIUC, the main impact is that it shows some extra dots
    in the bullets and numbering UI preview.
    
    Change-Id: Ic1b8fbda62917ad4c7b88bf4fff136d72242f977
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167782
    Reviewed-by: Justin Luth <jl...@mail.com>
    Reviewed-by: Vasily Melenchuk <vasily.melenc...@cib.de>
    Tested-by: Jenkins

diff --git a/editeng/source/items/numitem.cxx b/editeng/source/items/numitem.cxx
index b81172f9e5a2..0d677dfc6696 100644
--- a/editeng/source/items/numitem.cxx
+++ b/editeng/source/items/numitem.cxx
@@ -626,17 +626,39 @@ void 
SvxNumberFormat::SetListFormat(std::optional<OUString> oSet)
     // For backward compatibility and UI we should create something looking 
like
     // a prefix, suffix and included levels also. This is not possible in 
general case
     // since level format string is much more flexible. But for most cases is 
okay
+
+    // If properly formatted, sListFormat should look something like "%1%…%10%"
+    // with an optional prefix or suffix (which could theoretically include a 
percent symbol)
+    const sal_Int32 nLen = sListFormat->getLength();
     sal_Int32 nFirstReplacement = sListFormat->indexOf('%');
-    sal_Int32 nLastReplacement = sListFormat->lastIndexOf('%') + 1;
+    while (nFirstReplacement > -1 && nFirstReplacement < nLen - 1
+           && ((*sListFormat)[nFirstReplacement + 1] < '1'
+               || (*sListFormat)[nFirstReplacement + 1] > '9'))
+    {
+        nFirstReplacement = sListFormat->indexOf('%', nFirstReplacement + 1);
+    }
+
+    sal_Int32 nLastReplacement = nFirstReplacement == -1 ? -1 : 
sListFormat->lastIndexOf('%');
+    while (nLastReplacement > 0
+           && ((*sListFormat)[nLastReplacement - 1] < '0'
+               || (*sListFormat)[nLastReplacement - 1] > '9'))
+    {
+        nLastReplacement = sListFormat->lastIndexOf('%', nLastReplacement);
+    }
+    if (nLastReplacement < nFirstReplacement)
+        nLastReplacement = nFirstReplacement;
+    else
+        ++nLastReplacement;
+
     if (nFirstReplacement > 0)
         // Everything before first '%' will be prefix
         sPrefix = sListFormat->copy(0, nFirstReplacement);
-    if (nLastReplacement >= 0 && nLastReplacement < sListFormat->getLength())
+    if (nLastReplacement >= 0 && nLastReplacement < nLen)
         // Everything beyond last '%' is a suffix
         sSuffix = sListFormat->copy(nLastReplacement);
 
     sal_uInt8 nPercents = 0;
-    for (sal_Int32 i = 0; i < sListFormat->getLength(); i++)
+    for (sal_Int32 i = nFirstReplacement > 0 ? nFirstReplacement : 0; i < 
nLastReplacement; i++)
     {
         if ((*sListFormat)[i] == '%')
             nPercents++;

Reply via email to