offapi/UnoApi_offapi.mk                              |    1 
 offapi/com/sun/star/sheet/SheetSortDescriptor2.idl   |    8 +++
 offapi/com/sun/star/sheet/SortNumberBehavior.idl     |   41 +++++++++++++++++++
 sc/inc/datauno.hxx                                   |    3 -
 sc/inc/unonames.hxx                                  |    1 
 sc/qa/extras/macros-test.cxx                         |   22 ++++++++++
 sc/qa/extras/testdocuments/tdf161948_NaturalSort.ods |binary
 sc/source/ui/unoobj/datauno.cxx                      |   12 +++++
 test/source/sheet/sheetsortdescriptor2.cxx           |    7 +++
 9 files changed, 93 insertions(+), 2 deletions(-)

New commits:
commit 47eb7f4e4dd0ed72679246b462686e153a1c07d0
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Sun Aug 24 12:10:55 2025 +0200
Commit:     Regina Henschel <rb.hensc...@t-online.de>
CommitDate: Tue Aug 26 12:53:01 2025 +0200

    tdf161948 bring natural sort to API
    
    When sorting a database range the feature 'natural sort' can be used.
    If source has the strings K3 K10 K104 K23 K2, then the result will be
    K2 K3 K10 K23 K104. Alphanumerical sort results in K10 K104 K2 K23 K3.
    
    ODF has the attribute table:embedded-number-behavior for this
    (19.628 part3 ODF 1.4). Its values are 'alpha-numeric', 'double' and
    'integer'. LO has the attribute bool bNaturalSort in struct ScSortParam.
    The ODF method 'integer' is not implemented in LO.
    
    Currently natural sort is not read/written with ODF and is not available
    in the API. I plan three steps:
    1. Make natural sort available in the API (this patch)
    2. Read and write table:embedded-number-behavior attribute
    3. Implement 'integer' method.
    
    To be later able to have three values, not a boolean property is used for
    the API, but a group of constant values, although currently only two
    values are needed.
    
    Change-Id: I0418d5f23400fb0479034589fc90868a1e97ce44
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190133
    Reviewed-by: Regina Henschel <rb.hensc...@t-online.de>
    Tested-by: Jenkins

diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 0188d2ab7ba1..043045367745 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -3416,6 +3416,7 @@ $(eval $(call 
gb_UnoApi_add_idlfiles,offapi,com/sun/star/sheet,\
        SolverConstraintOperator \
        SolverStatus \
        SolverObjectiveType \
+       SortNumberBehavior \
        SpreadsheetViewObjectsMode \
        StatusBarFunction \
        SubTotalColumn \
diff --git a/offapi/com/sun/star/sheet/SheetSortDescriptor2.idl 
b/offapi/com/sun/star/sheet/SheetSortDescriptor2.idl
index 23bf5fdcde65..67d782d7e3bc 100644
--- a/offapi/com/sun/star/sheet/SheetSortDescriptor2.idl
+++ b/offapi/com/sun/star/sheet/SheetSortDescriptor2.idl
@@ -79,6 +79,14 @@ published service SheetSortDescriptor2
         should not be sorted.
      */
     [property] boolean ContainsHeader;
+
+
+    /** specifies how numbers inside text are handled in text comparisons
+        @see com::sun::star::sheet::SortNumberBehavior
+
+        @since LibreOffice 26.2
+    */
+    [optional, property] long NumberBehavior;
 };
 
 
diff --git a/offapi/com/sun/star/sheet/SortNumberBehavior.idl 
b/offapi/com/sun/star/sheet/SortNumberBehavior.idl
new file mode 100644
index 000000000000..61c5f0937964
--- /dev/null
+++ b/offapi/com/sun/star/sheet/SortNumberBehavior.idl
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; 
fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+module com {  module sun {  module star {  module sheet {
+
+/** Describes how numbers inside text are handled in text comparisons.
+
+    The constants correspond to the ODF attribute
+    table:embedded-number-behavior (19.628, part 3 ODF 1.4).
+    That has values 'alpha-numeric', 'double' and 'integer'.
+    Value 'integer' is not yet implemented.
+
+    @since LibreOffice 26.2
+ */
+published constants SortNumberBehavior
+{
+    /** Digits inside text are compared alphanumerically.
+
+        "K10" < "K2" < "K3", for example.
+      */
+    const long ALPHA_NUMERIC = 0;
+
+    /** Comparison of text uses natural sort.
+
+        "K2" < "K3" < "K10", for example. The number parts inside the text
+        may be decimal numbers. Which character is considered a decimal
+        separator, depends on the language of the text.
+        Read ODF standard for details.
+      */
+    const long DOUBLE = 1;
+};
+
+}; }; }; };
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
\ No newline at end of file
diff --git a/sc/inc/datauno.hxx b/sc/inc/datauno.hxx
index 6d152b1bc2ee..18357dab151f 100644
--- a/sc/inc/datauno.hxx
+++ b/sc/inc/datauno.hxx
@@ -88,10 +88,9 @@ public:
     static void FillProperties(
                     css::uno::Sequence<css::beans::PropertyValue>& rSeq,
                     const ScSortParam& rParam );
-    //! SortAscending needs to get out of the SheetSortDescriptor service 
description
     static tools::Long GetPropertyCount()
     {
-        return 9;       // TableSortDescriptor and SheetSortDescriptor
+        return 10;       // TableSortDescriptor2 (3) and SheetSortDescriptor2 
(7)
     }
 
 };
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index 1f8c01847666..433dcee0f4b2 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -329,6 +329,7 @@ inline constexpr OUString SC_UNONAME_CONRES           = 
u"ConnectionResource"_us
 inline constexpr OUString SC_UNONAME_TOKENINDEX       = u"TokenIndex"_ustr;
 inline constexpr OUString SC_UNONAME_ISSHAREDFMLA     = 
u"IsSharedFormula"_ustr;
 inline constexpr OUString SC_UNONAME_TOTALSROW        = u"TotalsRow"_ustr;
+inline constexpr OUString SC_UNONAME_NUMBERBEHAVIOR   = u"NumberBehavior"_ustr;
 
 //  text fields
 inline constexpr OUString SC_UNONAME_ANCTYPE          = u"AnchorType"_ustr;
diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx
index df8bb841f5ea..e45b6d6e90e8 100644
--- a/sc/qa/extras/macros-test.cxx
+++ b/sc/qa/extras/macros-test.cxx
@@ -995,6 +995,28 @@ CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf47479)
     CPPUNIT_ASSERT_EQUAL(SCTAB(1), xRowAddressable->getRangeAddress().Sheet);
 }
 
+CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf161948NaturalSortAPI)
+{
+    // Since LO 26.2 the feature natural sort is available in the API.
+    // Here we test, that is can be used in Basic macros.
+    createScDoc("tdf161948_NaturalSort.ods");
+    ScDocument* pDoc = getScDoc();
+    // The source has "K3", "K10", "K104", "K23", "K2" in Range A2:A6 and 
label in A1.
+    // The result goes to range C1:C6.
+
+    // Enable natural sorting and sort. Examine cell C2
+    executeMacro(u"vnd.sun.star.script:Standard.SortTest.EnableNaturalSort"
+                 "?language=Basic&location=document"_ustr);
+    OUString sCellContent = pDoc->GetString(2, 1, 0);
+    CPPUNIT_ASSERT_EQUAL(u"K2"_ustr, sCellContent);
+
+    // Enable default alphanumerically sorting and sort. Examine cell C2.
+    
executeMacro(u"vnd.sun.star.script:Standard.SortTest.EnableAlphaNumericSort"
+                 "?language=Basic&location=document"_ustr);
+    sCellContent = pDoc->GetString(2, 1, 0);
+    CPPUNIT_ASSERT_EQUAL(u"K10"_ustr, sCellContent);
+}
+
 ScMacrosTest::ScMacrosTest()
       : ScModelTestBase(u"/sc/qa/extras/testdocuments"_ustr)
 {
diff --git a/sc/qa/extras/testdocuments/tdf161948_NaturalSort.ods 
b/sc/qa/extras/testdocuments/tdf161948_NaturalSort.ods
new file mode 100644
index 000000000000..9d961d557109
Binary files /dev/null and 
b/sc/qa/extras/testdocuments/tdf161948_NaturalSort.ods differ
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 5a8e16395f3c..6da084dff2f1 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -38,6 +38,7 @@
 #include <com/sun/star/sheet/FilterFieldType.hpp>
 #include <com/sun/star/sheet/FilterOperator2.hpp>
 #include <com/sun/star/sheet/TableFilterField2.hpp>
+#include <com/sun/star/sheet/SortNumberBehavior.hpp>
 
 #include <dapiuno.hxx>
 #include <cellsuno.hxx>
@@ -317,11 +318,16 @@ void ScSortDescriptor::FillProperties( 
uno::Sequence<beans::PropertyValue>& rSeq
 
     pArray[8].Name = SC_UNONAME_UINDEX;
     pArray[8].Value <<= static_cast<sal_Int32>( rParam.nUserIndex );
+
+    pArray[9].Name = SC_UNONAME_NUMBERBEHAVIOR;
+    pArray[9].Value <<= rParam.bNaturalSort ? SortNumberBehavior::DOUBLE
+                            : SortNumberBehavior::ALPHA_NUMERIC;
 }
 
 void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const 
uno::Sequence<beans::PropertyValue>& rSeq )
 {
     sal_Int32 nSortSize = static_cast<sal_Int32>(rParam.GetSortKeyCount());
+    rParam.bNaturalSort = false; // default if optional 
SC_UNONAME_NUMBERBEHAVIOR does not exist
 
     for (const beans::PropertyValue& rProp : rSeq)
     {
@@ -437,6 +443,12 @@ void ScSortDescriptor::FillSortParam( ScSortParam& rParam, 
const uno::Sequence<b
             if ( rProp.Value >>= sStr )
                 rParam.aCollatorAlgorithm = sStr;
         }
+        else if (aPropName == SC_UNONAME_NUMBERBEHAVIOR)
+        {
+            sal_Int16 nVal = SortNumberBehavior::ALPHA_NUMERIC;
+            if (rProp.Value >>= nVal)
+                rParam.bNaturalSort = nVal == SortNumberBehavior::DOUBLE;
+        }
     }
 }
 
diff --git a/test/source/sheet/sheetsortdescriptor2.cxx 
b/test/source/sheet/sheetsortdescriptor2.cxx
index 3f84d9577f08..551f2d14f66a 100644
--- a/test/source/sheet/sheetsortdescriptor2.cxx
+++ b/test/source/sheet/sheetsortdescriptor2.cxx
@@ -14,6 +14,8 @@
 #include <com/sun/star/util/XSortable.hpp>
 #include <com/sun/star/table/CellAddress.hpp>
 #include <com/sun/star/table/TableSortField.hpp>
+#include <com/sun/star/sheet/SortNumberBehavior.hpp>
+
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/uno/Sequence.hxx>
 
@@ -91,6 +93,11 @@ void 
SheetSortDescriptor2::testSheetSortDescriptor2Properties()
             bool bValue = false;
             CPPUNIT_ASSERT(value.Value >>= bValue);
         }
+        else if (value.Name == "NumberBehavior")
+        {
+            sal_Int32 nValue = sheet::SortNumberBehavior::ALPHA_NUMERIC;
+            CPPUNIT_ASSERT(value.Value >>= nValue);
+        }
         else
         {
             OString sMsg = "Unsupported PropertyValue: "

Reply via email to