diff options
author | Andreas Heinisch <andreas.heinisch@yahoo.de> | 2021-10-04 21:32:20 +0200 |
---|---|---|
committer | Andreas Heinisch <andreas.heinisch@yahoo.de> | 2021-10-12 21:11:10 +0200 |
commit | 5c502a100476c6b57a1a9f4305195c7e2d5d5608 (patch) | |
tree | 80cad644cdafa7245ce55d90e3681975adf845a9 /basic | |
parent | 6e21f5a6b71790b3a36f67c3915b07a5f5717bcf (diff) |
tdf#130307 - Support for each loop for objects exposing XIndexAccess
Change-Id: Ib94c642e6d2a52ac7c60a8f7ae3c79d611b41614
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123072
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
Diffstat (limited to 'basic')
-rw-r--r-- | basic/source/inc/runtime.hxx | 3 | ||||
-rw-r--r-- | basic/source/runtime/runtime.cxx | 33 |
2 files changed, 35 insertions, 1 deletions
diff --git a/basic/source/inc/runtime.hxx b/basic/source/inc/runtime.hxx index 73e56838e2aa..d09db071a1a9 100644 --- a/basic/source/inc/runtime.hxx +++ b/basic/source/inc/runtime.hxx @@ -34,6 +34,7 @@ #include <memory> #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/container/XEnumeration.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> #include <unotools/localedatawrapper.hxx> #include <o3tl/deleter.hxx> #include <o3tl/typed_flags_set.hxx> @@ -55,6 +56,7 @@ enum class ForType { EachArray, EachCollection, EachXEnumeration, + EachXIndexAccess, Error, }; @@ -74,6 +76,7 @@ struct SbiForStack { // for/next stack: std::unique_ptr<sal_Int32[]> pArrayUpperBounds; css::uno::Reference< css::container::XEnumeration > xEnumeration; + css::uno::Reference<css::container::XIndexAccess> xIndexAccess; SbiForStack() : pNext(nullptr) diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 9a2a79e349b5..5c27b84223f7 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -1196,14 +1196,22 @@ void SbiRuntime::PushForEach() } else if (SbUnoObject* pUnoObj = dynamic_cast<SbUnoObject*>(pObj)) { - // XEnumerationAccess? + // XEnumerationAccess or XIndexAccess? Any aAny = pUnoObj->getUnoAny(); + Reference<XIndexAccess> xIndexAccess; Reference< XEnumerationAccess > xEnumerationAccess; if( aAny >>= xEnumerationAccess ) { p->xEnumeration = xEnumerationAccess->createEnumeration(); p->eForType = ForType::EachXEnumeration; } + // tdf#130307 - support for each loop for objects exposing XIndexAccess + else if (aAny >>= xIndexAccess) + { + p->eForType = ForType::EachXIndexAccess; + p->xIndexAccess = xIndexAccess; + p->nCurCollectionIndex = 0; + } else if ( isVBAEnabled() && pUnoObj->isNativeCOMObject() ) { uno::Reference< script::XInvocation > xInvocation; @@ -3204,6 +3212,29 @@ void SbiRuntime::StepTESTFOR( sal_uInt32 nOp1 ) } break; } + // tdf#130307 - support for each loop for objects exposing XIndexAccess + case ForType::EachXIndexAccess: + { + SbiForStack* p = pForStk; + if (!p->xIndexAccess) + { + SbxBase::SetError(ERRCODE_BASIC_CONVERSION); + pForStk->eForType = ForType::Error; // terminate loop at the next iteration + } + else if (pForStk->nCurCollectionIndex < p->xIndexAccess->getCount()) + { + Any aElem = p->xIndexAccess->getByIndex(pForStk->nCurCollectionIndex); + pForStk->nCurCollectionIndex++; + SbxVariableRef xVar = new SbxVariable(SbxVARIANT); + unoToSbxValue(xVar.get(), aElem); + (*pForStk->refVar) = *xVar; + } + else + { + bEndLoop = true; + } + break; + } case ForType::Error: { // We are in Resume Next mode after failed loop initialization |