Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/basic/source/classes/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 18 kB image not shown  

Quelle  eventatt.cxx   Sprache: C

 
/* -*- 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */



#include <comphelper/processfactory.hxx>
#include <comphelper/string.hxx>

#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <com/sun/star/awt/DialogProvider.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <com/sun/star/script/XLibraryContainer.hpp>
#include <com/sun/star/script/provider/theMasterScriptProviderFactory.hpp>
#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
#include <com/sun/star/script/provider/XScriptProvider.hpp>
#include <com/sun/star/io/XInputStreamProvider.hpp>

#include <basic/basicmanagerrepository.hxx>
#include <basic/basmgr.hxx>

#include <sal/log.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <vcl/svapp.hxx>
#include <sbunoobj.hxx>
#include <basic/sberrors.hxx>
#include <basic/sbstar.hxx>
#include <basic/sbmeth.hxx>
#include <basic/sbuno.hxx>
#include <runtime.hxx>
#include <sbintern.hxx>
#include <eventatt.hxx>

#include <cppuhelper/implbase.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::script;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::cppu;

namespace {

void SFURL_firing_impl( const ScriptEvent& aScriptEvent, Any* pRet, const Reference< frame::XModel >& xModel )
{
        SAL_INFO("basic""Processing script url " << aScriptEvent.ScriptCode);
        try
        {
            Reference< provider::XScriptProvider > xScriptProvider;
            if ( xModel.is() )
            {
                Reference< provider::XScriptProviderSupplier > xSupplier( xModel, UNO_QUERY );
                OSL_ENSURE( xSupplier.is(), "SFURL_firing_impl: failed to get script provider supplier" );
                if ( xSupplier.is() )
                    xScriptProvider.set( xSupplier->getScriptProvider() );
            }
            else
            {
                const Reference< XComponentContext >& xContext(
                    comphelper::getProcessComponentContext() );
                Reference< provider::XScriptProviderFactory > xFactory =
                    provider::theMasterScriptProviderFactory::get( xContext );

                Any aCtx;
                aCtx <<= u"user"_ustr;
                xScriptProvider = xFactory->createScriptProvider( aCtx );
            }

            if ( !xScriptProvider.is() )
            {
                SAL_INFO("basic""Failed to create msp");
                return;
            }
            Sequence< Any > inArgs( 0 );
            Sequence< Any > outArgs( 0 );
            Sequence< sal_Int16 > outIndex;

            // get Arguments for script
            inArgs = aScriptEvent.Arguments;

            Reference< provider::XScript > xScript = xScriptProvider->getScript( aScriptEvent.ScriptCode );

            if ( !xScript.is() )
            {
                SAL_INFO("basic""Failed to Failed to obtain XScript");
                return;
            }

            Any result = xScript->invoke( inArgs, outIndex, outArgs );
            if ( pRet )
            {
                *pRet = std::move(result);
            }
        }
        catch ( const RuntimeException& )
        {
            TOOLS_INFO_EXCEPTION("basic""" );
        }
        catch ( const Exception& )
        {
            TOOLS_INFO_EXCEPTION("basic""" );
        }

}


class BasicScriptListener_Impl : public WeakImplHelper< XScriptListener >
{
    StarBASICRef maBasicRef;
        Reference< frame::XModel > m_xModel;

    void firing_impl(const ScriptEvent& aScriptEvent, Any* pRet);

public:
    BasicScriptListener_Impl( StarBASIC* pBasic, const Reference< frame::XModel >& xModel )
        : maBasicRef( pBasic ), m_xModel( xModel ) {}

    // Methods of XAllListener
    virtual void SAL_CALL firing(const ScriptEvent& aScriptEvent) override;
    virtual Any SAL_CALL approveFiring(const ScriptEvent& aScriptEvent) override;

    // Methods of XEventListener
    virtual void SAL_CALL disposing(const EventObject& Source) override;
};

// Methods XAllListener
void BasicScriptListener_Impl::firing( const ScriptEvent& aScriptEvent )
{
    SolarMutexGuard g;

    firing_impl( aScriptEvent, nullptr );
}

Any BasicScriptListener_Impl::approveFiring( const ScriptEvent& aScriptEvent )
{
    SolarMutexGuard g;

    Any aRetAny;
    firing_impl( aScriptEvent, &aRetAny );
    return aRetAny;
}

// Methods XEventListener
void BasicScriptListener_Impl::disposing(const EventObject& )
{
    // TODO: ???
    //SolarMutexGuard aGuard;
    //xSbxObj.Clear();
}


void BasicScriptListener_Impl::firing_impl( const ScriptEvent& aScriptEvent, Any* pRet )
{
    if( aScriptEvent.ScriptType == "StarBasic" )
    {
        // Full qualified name?
        OUString aMacro( aScriptEvent.ScriptCode );
        OUString aLibName;
        OUString aLocation;
        if( comphelper::string::getTokenCount(aMacro, '.') == 3 )
        {
            sal_Int32 nLast = 0;
            std::u16string_view aFullLibName = o3tl::getToken(aMacro, 0, '.', nLast );

            size_t nIndex = aFullLibName.find( ':' );
            if (nIndex != std::u16string_view::npos)
            {
                aLocation = aFullLibName.substr( 0, nIndex );
                aLibName = aFullLibName.substr( nIndex + 1 );
            }

            aMacro = aMacro.copy( nLast );
        }

        SbxObject* p = maBasicRef.get();
        SbxObject* pParent = p->GetParent();
        SbxObject* pParentParent = pParent ? pParent->GetParent() : nullptr;

        StarBASICRef xAppStandardBasic;
        StarBASICRef xDocStandardBasic;
        if( pParentParent )
        {
            // Own basic must be document library
            xAppStandardBasic = static_cast<StarBASIC*>(pParentParent);
            xDocStandardBasic = static_cast<StarBASIC*>(pParent);
        }
        else if( pParent )
        {
            OUString aName = p->GetName();
            if( aName == "Standard" )
            {
                // Own basic is doc standard lib
                xDocStandardBasic = static_cast<StarBASIC*>(p);
            }
            xAppStandardBasic = static_cast<StarBASIC*>(pParent);
        }
        else
        {
            xAppStandardBasic = static_cast<StarBASIC*>(p);
        }

        bool bSearchLib = true;
        StarBASICRef xLibSearchBasic;
        if( aLocation == "application" )
        {
            xLibSearchBasic = std::move(xAppStandardBasic);
        }
        else if( aLocation == "document" )
        {
            xLibSearchBasic = std::move(xDocStandardBasic);
        }
        else
        {
            bSearchLib = false;
        }
        SbxVariable* pMethVar = nullptr;
        // Be still tolerant and make default search if no search basic exists
        if( bSearchLib && xLibSearchBasic.is() )
        {
            sal_Int32 nCount = xLibSearchBasic->GetObjects()->Count();
            for( sal_Int32 nObj = -1; nObj < nCount ; nObj++ )
            {
                StarBASIC* pBasic;
                if( nObj == -1 )
                {
                    pBasic = xLibSearchBasic.get();
                }
                else
                {
                    SbxVariable* pVar = xLibSearchBasic->GetObjects()->Get(nObj);
                    pBasic = dynamic_cast<StarBASIC*>( pVar );
                }
                if( pBasic )
                {
                    OUString aName = pBasic->GetName();
                    if( aName == aLibName )
                    {
                        // Search only in the lib, not automatically in application basic
                        SbxFlagBits nFlags = pBasic->GetFlags();
                        pBasic->ResetFlag( SbxFlagBits::GlobalSearch );
                        pMethVar = pBasic->Find( aMacro, SbxClassType::DontCare );
                        pBasic->SetFlags( nFlags );
                        break;
                    }
                }
            }
        }

        // Default: Be tolerant and search everywhere
        if( (!pMethVar || dynamic_cast<const SbMethod*>( pMethVar) == nullptr) && maBasicRef.is() )
        {
            pMethVar = maBasicRef->FindQualified( aMacro, SbxClassType::DontCare );
        }
        SbMethod* pMeth = dynamic_cast<SbMethod*>( pMethVar );
        if( !pMeth )
        {
            return;
        }
        // Setup parameters
        SbxArrayRef xArray;
        sal_Int32 nCnt = aScriptEvent.Arguments.getLength();
        if( nCnt )
        {
            xArray = new SbxArray;
            const Any *pArgs = aScriptEvent.Arguments.getConstArray();
            for( sal_Int32 i = 0; i < nCnt; i++ )
            {
                SbxVariableRef xVar = new SbxVariable( SbxVARIANT );
                unoToSbxValue( xVar.get(), pArgs[i] );
                xArray->Put(xVar.get(), sal::static_int_cast<sal_uInt32>(i + 1));
            }
        }

        // Call method
        SbxVariableRef xValue = pRet ? new SbxVariable : nullptr;
        if( xArray.is() )
        {
            pMeth->SetParameters( xArray.get() );
        }
        pMeth->Call( xValue.get() );
        if( pRet )
        {
            *pRet = sbxToUnoValue( xValue.get() );
        }
        pMeth->SetParameters( nullptr );
    }
    else // scripting framework script
    {
        //callBasic via scripting framework
        SFURL_firing_impl( aScriptEvent, pRet, m_xModel );
    }
}

css::uno::Reference< css::container::XNameContainer > implFindDialogLibForDialog( const Any& rDlgAny, SbxObject* pBasic )
{
    css::uno::Reference< css::container::XNameContainer > aRetDlgLib;

    SbxVariable* pDlgLibContVar = pBasic->Find(u"DialogLibraries"_ustr, SbxClassType::Object);
    ifauto pDlgLibContUnoObj = dynamic_cast<SbUnoObject*>( pDlgLibContVar) )
    {
        Any aDlgLibContAny = pDlgLibContUnoObj->getUnoAny();

        Reference< XLibraryContainer > xDlgLibContNameAccess( aDlgLibContAny, UNO_QUERY );
        OSL_ENSURE( xDlgLibContNameAccess.is(), "implFindDialogLibForDialog: no lib container for the given dialog!" );
        if( xDlgLibContNameAccess.is() )
        {
            Sequence< OUString > aLibNames = xDlgLibContNameAccess->getElementNames();
            const OUString* pLibNames = aLibNames.getConstArray();
            sal_Int32 nLibNameCount = aLibNames.getLength();

            for( sal_Int32 iLib = 0 ; iLib < nLibNameCount ; iLib++ )
            {
                if ( !xDlgLibContNameAccess->isLibraryLoaded( pLibNames[ iLib ] ) )
                    // if the library isn't loaded, then the dialog cannot originate from this lib
                    continue;

                Any aDlgLibAny = xDlgLibContNameAccess->getByName( pLibNames[ iLib ] );

                Reference< XNameContainer > xDlgLibNameCont( aDlgLibAny, UNO_QUERY );
                OSL_ENSURE( xDlgLibNameCont.is(), "implFindDialogLibForDialog: invalid dialog lib!" );
                if( xDlgLibNameCont.is() )
                {
                    Sequence< OUString > aDlgNames = xDlgLibNameCont->getElementNames();
                    const OUString* pDlgNames = aDlgNames.getConstArray();
                    sal_Int32 nDlgNameCount = aDlgNames.getLength();

                    for( sal_Int32 iDlg = 0 ; iDlg < nDlgNameCount ; iDlg++ )
                    {
                        Any aDlgAny = xDlgLibNameCont->getByName( pDlgNames[ iDlg ] );
                        if( aDlgAny == rDlgAny )
                        {
                            aRetDlgLib = xDlgLibNameCont;
                            break;
                        }
                    }
                }
            }
        }
    }

    return aRetDlgLib;
}

css::uno::Reference< css::container::XNameContainer > implFindDialogLibForDialogBasicconst Any& aAnyISP, SbxObject* pBasic, StarBASIC*& pFoundBasic )
{
    css::uno::Reference< css::container::XNameContainer > aDlgLib;
    // Find dialog library for dialog, direct access is not possible here
    StarBASIC* pStartedBasic = static_cast<StarBASIC*>(pBasic);
    SbxObject* pParentBasic = pStartedBasic ? pStartedBasic->GetParent() : nullptr;
    SbxObject* pParentParentBasic = pParentBasic ? pParentBasic->GetParent() : nullptr;

    SbxObject* pSearchBasic1 = nullptr;
    SbxObject* pSearchBasic2 = nullptr;
    if( pParentParentBasic )
    {
        pSearchBasic1 = pParentBasic;
        pSearchBasic2 = pParentParentBasic;
    }
    else
    {
        pSearchBasic1 = pStartedBasic;
        pSearchBasic2 = pParentBasic;
    }
    if( pSearchBasic1 )
    {
        aDlgLib = implFindDialogLibForDialog( aAnyISP, pSearchBasic1 );

        if ( aDlgLib.is() )
            pFoundBasic = static_cast<StarBASIC*>(pSearchBasic1);

        else if( pSearchBasic2 )
        {
            aDlgLib = implFindDialogLibForDialog( aAnyISP, pSearchBasic2 );
            if ( aDlgLib.is() )
                pFoundBasic = static_cast<StarBASIC*>(pSearchBasic2);
        }
    }
    return aDlgLib;
}

}

void RTL_Impl_CreateUnoDialog( SbxArray& rPar )
{
    const Reference< XComponentContext >& xContext( comphelper::getProcessComponentContext() );

    // We need at least 1 parameter
    if (rPar.Count() < 2)
    {
        StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT );
        return;
    }

    // Get dialog
    SbxBaseRef pObj = rPar.Get(1)->GetObject();
    SbUnoObject* pUnoObj = dynamic_cast<SbUnoObject*>(pObj.get());
    if( !pUnoObj )
    {
        StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT );
        return;
    }
    Any aAnyISP = pUnoObj->getUnoAny();
    TypeClass eType = aAnyISP.getValueTypeClass();

    if( eType != TypeClass_INTERFACE )
    {
        StarBASIC::Error( ERRCODE_BASIC_BAD_ARGUMENT );
        return;
    }

    // Create new uno dialog
    Reference< XNameContainer > xDialogModel( xContext->getServiceManager()->createInstanceWithContext(
                      u"com.sun.star.awt.UnoControlDialogModel"_ustr, xContext), UNO_QUERY );
    if( !xDialogModel.is() )
    {
        return;
    }
    Reference< XInputStreamProvider > xISP;
    aAnyISP >>= xISP;
    if( !xISP.is() )
    {
        return;
    }

    // Import the DialogModel
    Reference< XInputStream > xInput( xISP->createInputStream() );

    // i83963 Force decoration
    uno::Reference< beans::XPropertySet > xDlgModPropSet( xDialogModel, uno::UNO_QUERY );
    if( xDlgModPropSet.is() )
    {
        try
        {
            bool bDecoration = true;
            OUString aDecorationPropName(u"Decoration"_ustr);
            Any aDecorationAny = xDlgModPropSet->getPropertyValue( aDecorationPropName );
            aDecorationAny >>= bDecoration;
            if( !bDecoration )
            {
                xDlgModPropSet->setPropertyValue( aDecorationPropName, Any( true ) );
                xDlgModPropSet->setPropertyValue( u"Title"_ustr, Any( OUString() ) );
            }
        }
        catch(const UnknownPropertyException& )
        {}
    }

    css::uno::Reference< css::container::XNameContainer > aDlgLib;
    bool bDocDialog = false;
    StarBASIC* pFoundBasic = nullptr;
    SAL_INFO("basic""About to try get a hold of ThisComponent");
    Reference< frame::XModel > xModel = StarBASIC::GetModelFromBasic( GetSbData()->pInst->GetBasic() ) ;
    aDlgLib = implFindDialogLibForDialogBasic( aAnyISP, GetSbData()->pInst->GetBasic(), pFoundBasic );
    // If we found the dialog then it belongs to the Search basic
    if ( !pFoundBasic )
    {
        Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( xContext );
        Reference< container::XEnumeration > xModels;
        Reference< container::XEnumerationAccess > xComponents = xDesktop->getComponents();
        if ( xComponents.is() )
        {
            xModels = xComponents->createEnumeration();
        }
        if ( xModels.is() )
        {
            while ( xModels->hasMoreElements() )
            {
                Reference< frame::XModel > xNextModel( xModels->nextElement(), UNO_QUERY );
                if ( xNextModel.is() )
                {
                    BasicManager* pMgr = basic::BasicManagerRepository::getDocumentBasicManager( xNextModel );
                    if ( pMgr )
                    {
                        aDlgLib = implFindDialogLibForDialogBasic( aAnyISP, pMgr->GetLib(0), pFoundBasic );
                    }
                    if ( aDlgLib.is() )
                    {
                        bDocDialog = true;
                        xModel = std::move(xNextModel);
                        break;
                    }
                }
            }
        }
    }
    if ( pFoundBasic )
    {
        bDocDialog = pFoundBasic->IsDocBasic();
    }
    Reference< XScriptListener > xScriptListener = new BasicScriptListener_Impl( GetSbData()->pInst->GetBasic(), xModel );

    // Create a "living" Dialog
    Reference< XControl > xCntrl;
    try
    {
       Reference< XDialogProvider >  xDlgProv;
       if( bDocDialog )
           xDlgProv = css::awt::DialogProvider::createWithModelAndScripting( xContext, xModel, xInput, aDlgLib, xScriptListener );
       else
           xDlgProv = css::awt::DialogProvider::createWithModelAndScripting( xContext, uno::Reference< frame::XModel >(), xInput, aDlgLib, xScriptListener );

       xCntrl.set( xDlgProv->createDialog(OUString() ), UNO_QUERY_THROW );
       // Add dialog model to dispose vector
       Reference< XComponent > xDlgComponent( xCntrl->getModel(), UNO_QUERY );
       GetSbData()->pInst->getComponentVector().push_back( xDlgComponent );
       // need ThisComponent from calling script
    }
    // preserve existing bad behaviour, it's possible... but probably
    // illegal to open 2 dialogs ( they ARE modal ) when this happens, sometimes
    // create dialog fails.  So, in this case let's not throw, just leave basic
    // detect the unset object.
    catch(const uno::Exception& )
    {
    }

    // Return dialog
    Any aRetVal;
    aRetVal <<= xCntrl;
    SbxVariableRef refVar = rPar.Get(0);
    unoToSbxValue( refVar.get(), aRetVal );
}


/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

96%


¤ Dauer der Verarbeitung: 0.8 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.