From ed5640d8b587fbcfed7dd7967f3de04b37a76f26 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:06:44 +0200 Subject: Adding upstream version 4:7.4.7. Signed-off-by: Daniel Baumann --- dbaccess/source/core/dataaccess/documentevents.cxx | 216 +++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 dbaccess/source/core/dataaccess/documentevents.cxx (limited to 'dbaccess/source/core/dataaccess/documentevents.cxx') diff --git a/dbaccess/source/core/dataaccess/documentevents.cxx b/dbaccess/source/core/dataaccess/documentevents.cxx new file mode 100644 index 000000000..571ad2c6f --- /dev/null +++ b/dbaccess/source/core/dataaccess/documentevents.cxx @@ -0,0 +1,216 @@ +/* -*- 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 + +#include + +#include +#include +#include +#include + +namespace dbaccess +{ + + using ::com::sun::star::uno::Any; + using ::com::sun::star::beans::PropertyValue; + using ::com::sun::star::container::NoSuchElementException; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + + // DocumentEvents_Data + struct DocumentEvents_Data + { + ::cppu::OWeakObject& rParent; + ::osl::Mutex& rMutex; + DocumentEventsData& rEventsData; + + DocumentEvents_Data( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData ) + :rParent( _rParent ) + ,rMutex( _rMutex ) + ,rEventsData( _rEventsData ) + { + } + DocumentEvents_Data(const DocumentEvents_Data&) = delete; + const DocumentEvents_Data& operator=(const DocumentEvents_Data&) = delete; + }; + + namespace { + + // helper + struct DocumentEventData + { + const char* pAsciiEventName; + bool bNeedsSyncNotify; + }; + + const DocumentEventData* lcl_getDocumentEventData() + { + static const DocumentEventData s_aData[] = { + { "OnCreate", true }, + { "OnLoadFinished", true }, + { "OnNew", false }, // compatibility, see https://bz.apache.org/ooo/show_bug.cgi?id=46484 + { "OnLoad", false }, // compatibility, see https://bz.apache.org/ooo/show_bug.cgi?id=46484 + { "OnSaveAs", true }, + { "OnSaveAsDone", false }, + { "OnSaveAsFailed", false }, + { "OnSave", true }, + { "OnSaveDone", false }, + { "OnSaveFailed", false }, + { "OnSaveTo", true }, + { "OnSaveToDone", false }, + { "OnSaveToFailed", false }, + { "OnPrepareUnload", true }, + { "OnUnload", true }, + { "OnFocus", false }, + { "OnUnfocus", false }, + { "OnModifyChanged", false }, + { "OnViewCreated", false }, + { "OnPrepareViewClosing", true }, + { "OnViewClosed", false }, + { "OnTitleChanged", false }, + { "OnSubComponentOpened", false }, + { "OnSubComponentClosed", false }, + { nullptr, false } + }; + return s_aData; + } + } + + // DocumentEvents + DocumentEvents::DocumentEvents( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData ) + :m_pData( new DocumentEvents_Data( _rParent, _rMutex, _rEventsData ) ) + { + const DocumentEventData* pEventData = lcl_getDocumentEventData(); + while ( pEventData->pAsciiEventName ) + { + OUString sEventName = OUString::createFromAscii( pEventData->pAsciiEventName ); + DocumentEventsData::const_iterator existingPos = m_pData->rEventsData.find( sEventName ); + if ( existingPos == m_pData->rEventsData.end() ) + m_pData->rEventsData[ sEventName ] = Sequence< PropertyValue >(); + ++pEventData; + } + } + + DocumentEvents::~DocumentEvents() + { + } + + void SAL_CALL DocumentEvents::acquire() noexcept + { + m_pData->rParent.acquire(); + } + + void SAL_CALL DocumentEvents::release() noexcept + { + m_pData->rParent.release(); + } + + bool DocumentEvents::needsSynchronousNotification( std::u16string_view _rEventName ) + { + const DocumentEventData* pEventData = lcl_getDocumentEventData(); + while ( pEventData->pAsciiEventName ) + { + if ( o3tl::equalsAscii( _rEventName, pEventData->pAsciiEventName ) ) + return pEventData->bNeedsSyncNotify; + ++pEventData; + } + + // this is an unknown event ... assume async notification + return false; + } + + void SAL_CALL DocumentEvents::replaceByName( const OUString& Name, const Any& Element ) + { + ::osl::MutexGuard aGuard( m_pData->rMutex ); + + DocumentEventsData::iterator elementPos = m_pData->rEventsData.find( Name ); + if ( elementPos == m_pData->rEventsData.end() ) + throw NoSuchElementException( Name, *this ); + + Sequence< PropertyValue > aEventDescriptor; + if ( Element.hasValue() && !( Element >>= aEventDescriptor ) ) + throw IllegalArgumentException( Element.getValueTypeName(), *this, 2 ); + + // Weird enough, the event assignment UI has (well: had) the idea of using an empty "EventType"/"Script" + // to indicate the event descriptor should be reset, instead of just passing an empty event descriptor. + ::comphelper::NamedValueCollection aCheck( aEventDescriptor ); + if ( aCheck.has( "EventType" ) ) + { + OUString sEventType = aCheck.getOrDefault( "EventType", OUString() ); + OSL_ENSURE( !sEventType.isEmpty(), "DocumentEvents::replaceByName: doing a reset via an empty EventType is weird!" ); + if ( sEventType.isEmpty() ) + aEventDescriptor.realloc( 0 ); + } + if ( aCheck.has( "Script" ) ) + { + OUString sScript = aCheck.getOrDefault( "Script", OUString() ); + OSL_ENSURE( !sScript.isEmpty(), "DocumentEvents::replaceByName: doing a reset via an empty Script is weird!" ); + if ( sScript.isEmpty() ) + aEventDescriptor.realloc( 0 ); + } + + elementPos->second = aEventDescriptor; + } + + Any SAL_CALL DocumentEvents::getByName( const OUString& Name ) + { + ::osl::MutexGuard aGuard( m_pData->rMutex ); + + DocumentEventsData::const_iterator elementPos = m_pData->rEventsData.find( Name ); + if ( elementPos == m_pData->rEventsData.end() ) + throw NoSuchElementException( Name, *this ); + + Any aReturn; + const Sequence< PropertyValue >& rEventDesc( elementPos->second ); + if ( rEventDesc.hasElements() ) + aReturn <<= rEventDesc; + return aReturn; + } + + Sequence< OUString > SAL_CALL DocumentEvents::getElementNames( ) + { + ::osl::MutexGuard aGuard( m_pData->rMutex ); + + return comphelper::mapKeysToSequence( m_pData->rEventsData ); + } + + sal_Bool SAL_CALL DocumentEvents::hasByName( const OUString& Name ) + { + ::osl::MutexGuard aGuard( m_pData->rMutex ); + + return m_pData->rEventsData.find( Name ) != m_pData->rEventsData.end(); + } + + Type SAL_CALL DocumentEvents::getElementType( ) + { + return ::cppu::UnoType< Sequence< PropertyValue > >::get(); + } + + sal_Bool SAL_CALL DocumentEvents::hasElements( ) + { + ::osl::MutexGuard aGuard( m_pData->rMutex ); + return !m_pData->rEventsData.empty(); + } + +} // namespace dbaccess + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3