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: "