formula/source/core/api/FormulaCompiler.cxx                |    4 -
 formula/source/core/api/token.cxx                          |    2 
 offapi/UnoApi_offapi.mk                                    |    1 
 offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl |   12 +++
 offapi/com/sun/star/sheet/TableRefToken.idl                |   44 ++++++++++++
 sc/source/core/tool/token.cxx                              |   33 ++++++++-
 sc/source/ui/unoobj/tokenuno.cxx                           |   46 +++++++++++--
 7 files changed, 132 insertions(+), 10 deletions(-)

New commits:
commit 4c3f65ea3b1f2e7f6d92c732f72936fecc017b29
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Mon Jul 29 11:41:41 2024 +0200
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Mon Jul 29 16:29:19 2024 +0200

    Resolves: tdf#159343 Implement TableRef API token conversion
    
    Change-Id: I1b0d9e002d267e62dc7cbbbfc9f5c5c728374345
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/171165
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins

diff --git a/formula/source/core/api/FormulaCompiler.cxx 
b/formula/source/core/api/FormulaCompiler.cxx
index 93886a061b25..c58c9023c3a7 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -529,10 +529,10 @@ uno::Sequence< sheet::FormulaOpCodeMapEntry > 
FormulaCompiler::OpCodeMap::create
             { FormulaMapGroupSpecialOffset::SPACES            , ocSpaces }     
    ,
             { FormulaMapGroupSpecialOffset::MAT_REF           , ocMatRef }     
    ,
             { FormulaMapGroupSpecialOffset::DB_AREA           , ocDBArea }     
    ,
-            /* TODO: { FormulaMapGroupSpecialOffset::TABLE_REF         , 
ocTableRef }       , */
             { FormulaMapGroupSpecialOffset::MACRO             , ocMacro }      
    ,
             { FormulaMapGroupSpecialOffset::COL_ROW_NAME      , ocColRowName } 
    ,
-            { FormulaMapGroupSpecialOffset::WHITESPACE        , ocWhitespace }
+            { FormulaMapGroupSpecialOffset::WHITESPACE        , ocWhitespace } 
    ,
+            { FormulaMapGroupSpecialOffset::TABLE_REF         , ocTableRef }
         };
         const size_t nCount = SAL_N_ELEMENTS(aMap);
         // Preallocate vector elements.
diff --git a/formula/source/core/api/token.cxx 
b/formula/source/core/api/token.cxx
index c8124672d4bf..1167b3ebcd0d 100644
--- a/formula/source/core/api/token.cxx
+++ b/formula/source/core/api/token.cxx
@@ -418,8 +418,6 @@ bool FormulaTokenArray::AddFormulaToken(
                 sal_Int32 nValue = rToken.Data.get<sal_Int32>();
                 if ( eOpCode == ocDBArea )
                     Add( new formula::FormulaIndexToken( eOpCode, 
static_cast<sal_uInt16>(nValue) ) );
-                else if ( eOpCode == ocTableRef )
-                    bError = true;  /* TODO: implementation */
                 else if ( eOpCode == ocSpaces )
                     Add( new formula::FormulaByteToken( ocSpaces, 
static_cast<sal_uInt8>(nValue) ) );
                 else
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index cf86c82a2ab9..b3c1c4e52ddf 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -3476,6 +3476,7 @@ $(eval $(call 
gb_UnoApi_add_idlfiles,offapi,com/sun/star/sheet,\
        TableFilterField3 \
        TableOperationMode \
        TablePageBreakData \
+       TableRefToken \
        TableValidationVisibility \
        ValidationAlertStyle \
        ValidationType \
diff --git a/offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl 
b/offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
index 9b525a13d7a7..122a64e7c497 100644
--- a/offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
+++ b/offapi/com/sun/star/sheet/FormulaMapGroupSpecialOffset.idl
@@ -189,6 +189,18 @@ constants FormulaMapGroupSpecialOffset
     const long WHITESPACE = 13;
 
 
+    /** Formula tokens containing the op-code obtained from this offset
+        describe the reference to an item of a database range used in
+        formulas.
+
+        <p>The FormulaToken::Data member shall contain a struct of type
+        `TableRefToken`.</p>
+
+        @since LibreOffice 25.2
+     */
+    const long TABLE_REF = 14;
+
+
 };
 
 
diff --git a/offapi/com/sun/star/sheet/TableRefToken.idl 
b/offapi/com/sun/star/sheet/TableRefToken.idl
new file mode 100644
index 000000000000..ff238d3c4a0a
--- /dev/null
+++ b/offapi/com/sun/star/sheet/TableRefToken.idl
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * 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 {
+
+
+/** contains the information regarding table structured reference tokens
+
+    @see DatabaseRange
+    @see com::sun::star::sheet::FormulaMapGroupSpecialOffset::TABLE_REF
+
+    @since LibreOffice 25.2
+ */
+struct TableRefToken
+{
+    /** The index of the database range. This index can be obtained from
+        the database range using its DatabaseRange::TokenIndex property.
+     */
+    long                Index;
+
+
+    /** The item specifier, type of the table reference within the
+        database range.
+     */
+    short               Item;
+
+
+    /** The corresponding cell range reference.
+     */
+    ComplexReference    Reference;
+
+};
+
+
+}; }; }; };
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 9881f33e2f6a..d78b04df8bd8 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -51,6 +51,7 @@
 #include <com/sun/star/sheet/FormulaToken.hpp>
 #include <com/sun/star/sheet/ReferenceFlags.hpp>
 #include <com/sun/star/sheet/NameToken.hpp>
+#include <com/sun/star/sheet/TableRefToken.hpp>
 #include <utility>
 #include <o3tl/safeint.hxx>
 #include <o3tl/sorted_vector.hxx>
@@ -1195,8 +1196,36 @@ bool ScTokenArray::AddFormulaToken(
                         }
                         else if (eOpCode == ocDBArea)
                             AddDBRange(aTokenData.Index);
-                        else if (eOpCode == ocTableRef)
-                            bError = true;  /* TODO: implementation */
+                        else
+                            bError = true;
+                    }
+                    else if ( aType.equals( 
cppu::UnoType<sheet::TableRefToken>::get() ) )
+                    {
+                        if (eOpCode == ocTableRef)
+                        {
+                            sheet::TableRefToken aTokenData;
+                            rToken.Data >>= aTokenData;
+                            ScTableRefToken* pToken = new ScTableRefToken( 
aTokenData.Index,
+                                    
static_cast<ScTableRefToken::Item>(aTokenData.Item));
+                            if (Add(pToken))    // else pToken is deleted
+                            {
+                                if (aTokenData.Reference.Reference1 == 
aTokenData.Reference.Reference2)
+                                {
+                                    ScSingleRefData aRefData;
+                                    lcl_SingleRefToCalc( aRefData, 
aTokenData.Reference.Reference1 );
+                                    pToken->SetAreaRefRPN( new 
ScSingleRefToken( *mxSheetLimits, aRefData));
+                                }
+                                else
+                                {
+                                    ScComplexRefData aRefData;
+                                    lcl_SingleRefToCalc( aRefData.Ref1, 
aTokenData.Reference.Reference1 );
+                                    lcl_SingleRefToCalc( aRefData.Ref2, 
aTokenData.Reference.Reference2 );
+                                    pToken->SetAreaRefRPN( new 
ScDoubleRefToken( *mxSheetLimits, aRefData));
+                                }
+                            }
+                            else
+                                bError = true;
+                        }
                         else
                             bError = true;
                     }
diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx
index c5f34540f87f..1f867189687a 100644
--- a/sc/source/ui/unoobj/tokenuno.cxx
+++ b/sc/source/ui/unoobj/tokenuno.cxx
@@ -28,6 +28,7 @@
 #include <com/sun/star/sheet/ReferenceFlags.hpp>
 #include <com/sun/star/sheet/AddressConvention.hpp>
 #include <com/sun/star/sheet/NameToken.hpp>
+#include <com/sun/star/sheet/TableRefToken.hpp>
 #include <com/sun/star/table/CellAddress.hpp>
 
 #include <svl/itemprop.hxx>
@@ -143,6 +144,14 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL 
ScFormulaParserObj::parseFormula(
         SetCompilerFlags( aCompiler );
 
         std::unique_ptr<ScTokenArray> pCode = aCompiler.CompileString( 
aFormula );
+        if (pCode->HasOpCode(ocTableRef))
+        {
+            FormulaError nErr = pCode->GetCodeError();
+            aCompiler.EnableJumpCommandReorder(true);
+            aCompiler.CompileTokenArray();  // needed for corresponding inner 
reference
+            pCode->DelRPN();                // can be discarded
+            pCode->SetCodeError(nErr);      // reset to parsing error, if any
+        }
         ScTokenConversion::ConvertToTokenSequence( rDoc, aRet, *pCode );
     }
 
@@ -442,10 +451,39 @@ void ScTokenConversion::ConvertToTokenSequence( const 
ScDocument& rDoc,
                     break;
                 case svIndex:
                     {
-                        sheet::NameToken aNameToken;
-                        aNameToken.Index = static_cast<sal_Int32>( 
rToken.GetIndex() );
-                        aNameToken.Sheet = rToken.GetSheet();
-                        rAPI.Data <<= aNameToken;
+                        const ScTableRefToken* pTR;
+                        if (rToken.GetOpCode() == ocTableRef && (pTR = 
dynamic_cast<const ScTableRefToken*>(&rToken)))
+                        {
+                            sheet::TableRefToken aTableRefToken;
+                            aTableRefToken.Index = static_cast<sal_Int32>( 
pTR->GetIndex());
+                            aTableRefToken.Item = static_cast<sal_Int16>( 
pTR->GetItem());
+                            const FormulaToken* pRef = pTR->GetAreaRefRPN();
+                            assert(pRef && "something forgot to create RPN for 
ocTableRef inner reference");
+                            if (pRef)
+                            {
+                                switch (pRef->GetType())
+                                {
+                                    case svSingleRef:
+                                        lcl_SingleRefToApi( 
aTableRefToken.Reference.Reference1, *pRef->GetSingleRef());
+                                        aTableRefToken.Reference.Reference2 = 
aTableRefToken.Reference.Reference1;
+                                    break;
+                                    case svDoubleRef:
+                                        lcl_SingleRefToApi( 
aTableRefToken.Reference.Reference1, *pRef->GetSingleRef());
+                                        lcl_SingleRefToApi( 
aTableRefToken.Reference.Reference2, *pRef->GetSingleRef2());
+                                    break;
+                                    default:
+                                        ;   // nothing
+                                }
+                            }
+                            rAPI.Data <<= aTableRefToken;
+                        }
+                        else
+                        {
+                            sheet::NameToken aNameToken;
+                            aNameToken.Index = static_cast<sal_Int32>( 
rToken.GetIndex() );
+                            aNameToken.Sheet = rToken.GetSheet();
+                            rAPI.Data <<= aNameToken;
+                        }
                     }
                     break;
                 case svMatrix:

Reply via email to