Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / core / dataaccess / documentevents.cxx
blob40c0d18ff07b3ab57f0de0a1062301c44a08b99f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "documentevents.hxx"
22 #include <com/sun/star/beans/PropertyValue.hpp>
24 #include <osl/diagnose.h>
25 #include <comphelper/namedvaluecollection.hxx>
27 #include <algorithm>
28 #include <functional>
29 #include <o3tl/compat_functional.hxx>
31 namespace dbaccess
34 using ::com::sun::star::uno::Reference;
35 using ::com::sun::star::uno::XInterface;
36 using ::com::sun::star::uno::UNO_QUERY;
37 using ::com::sun::star::uno::UNO_QUERY_THROW;
38 using ::com::sun::star::uno::UNO_SET_THROW;
39 using ::com::sun::star::uno::Exception;
40 using ::com::sun::star::uno::RuntimeException;
41 using ::com::sun::star::uno::Any;
42 using ::com::sun::star::uno::makeAny;
43 using ::com::sun::star::beans::PropertyValue;
44 using ::com::sun::star::container::NoSuchElementException;
45 using ::com::sun::star::lang::WrappedTargetException;
46 using ::com::sun::star::lang::IllegalArgumentException;
47 using ::com::sun::star::uno::Sequence;
48 using ::com::sun::star::uno::Type;
50 // DocumentEvents_Data
51 struct DocumentEvents_Data : public ::boost::noncopyable
53 ::cppu::OWeakObject& rParent;
54 ::osl::Mutex& rMutex;
55 DocumentEventsData& rEventsData;
57 DocumentEvents_Data( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData )
58 :rParent( _rParent )
59 ,rMutex( _rMutex )
60 ,rEventsData( _rEventsData )
65 // helper
66 struct DocumentEventData
68 const sal_Char* pAsciiEventName;
69 bool bNeedsSyncNotify;
72 namespace
74 static const DocumentEventData* lcl_getDocumentEventData()
76 static const DocumentEventData s_aData[] = {
77 { "OnCreate", true },
78 { "OnLoadFinished", true },
79 { "OnNew", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
80 { "OnLoad", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
81 { "OnSaveAs", true },
82 { "OnSaveAsDone", false },
83 { "OnSaveAsFailed", false },
84 { "OnSave", true },
85 { "OnSaveDone", false },
86 { "OnSaveFailed", false },
87 { "OnSaveTo", true },
88 { "OnSaveToDone", false },
89 { "OnSaveToFailed", false },
90 { "OnPrepareUnload", true },
91 { "OnUnload", true },
92 { "OnFocus", false },
93 { "OnUnfocus", false },
94 { "OnModifyChanged", false },
95 { "OnViewCreated", false },
96 { "OnPrepareViewClosing", true },
97 { "OnViewClosed", false },
98 { "OnTitleChanged", false },
99 { "OnSubComponentOpened", false },
100 { "OnSubComponentClosed", false },
101 { NULL, false }
103 return s_aData;
107 // DocumentEvents
108 DocumentEvents::DocumentEvents( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData )
109 :m_pData( new DocumentEvents_Data( _rParent, _rMutex, _rEventsData ) )
111 const DocumentEventData* pEventData = lcl_getDocumentEventData();
112 while ( pEventData->pAsciiEventName )
114 OUString sEventName = OUString::createFromAscii( pEventData->pAsciiEventName );
115 DocumentEventsData::iterator existingPos = m_pData->rEventsData.find( sEventName );
116 if ( existingPos == m_pData->rEventsData.end() )
117 m_pData->rEventsData[ sEventName ] = Sequence< PropertyValue >();
118 ++pEventData;
122 DocumentEvents::~DocumentEvents()
126 void SAL_CALL DocumentEvents::acquire() throw()
128 m_pData->rParent.acquire();
131 void SAL_CALL DocumentEvents::release() throw()
133 m_pData->rParent.release();
136 bool DocumentEvents::needsSynchronousNotification( const OUString& _rEventName )
138 const DocumentEventData* pEventData = lcl_getDocumentEventData();
139 while ( pEventData->pAsciiEventName )
141 if ( _rEventName.equalsAscii( pEventData->pAsciiEventName ) )
142 return pEventData->bNeedsSyncNotify;
143 ++pEventData;
146 // this is an unknown event ... assume async notification
147 return false;
150 void SAL_CALL DocumentEvents::replaceByName( const OUString& _Name, const Any& _Element ) throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
152 ::osl::MutexGuard aGuard( m_pData->rMutex );
154 DocumentEventsData::iterator elementPos = m_pData->rEventsData.find( _Name );
155 if ( elementPos == m_pData->rEventsData.end() )
156 throw NoSuchElementException( _Name, *this );
158 Sequence< PropertyValue > aEventDescriptor;
159 if ( _Element.hasValue() && !( _Element >>= aEventDescriptor ) )
160 throw IllegalArgumentException( _Element.getValueTypeName(), *this, 2 );
162 // Weird enough, the event assignment UI has (well: had) the idea of using an empty "EventType"/"Script"
163 // to indicate the event descriptor should be reset, instead of just passing an empty event descriptor.
164 ::comphelper::NamedValueCollection aCheck( aEventDescriptor );
165 if ( aCheck.has( "EventType" ) )
167 OUString sEventType = aCheck.getOrDefault( "EventType", OUString() );
168 OSL_ENSURE( !sEventType.isEmpty(), "DocumentEvents::replaceByName: doing a reset via an empty EventType is weird!" );
169 if ( sEventType.isEmpty() )
170 aEventDescriptor.realloc( 0 );
172 if ( aCheck.has( "Script" ) )
174 OUString sScript = aCheck.getOrDefault( "Script", OUString() );
175 OSL_ENSURE( !sScript.isEmpty(), "DocumentEvents::replaceByName: doing a reset via an empty Script is weird!" );
176 if ( sScript.isEmpty() )
177 aEventDescriptor.realloc( 0 );
180 elementPos->second = aEventDescriptor;
183 Any SAL_CALL DocumentEvents::getByName( const OUString& _Name ) throw (NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
185 ::osl::MutexGuard aGuard( m_pData->rMutex );
187 DocumentEventsData::const_iterator elementPos = m_pData->rEventsData.find( _Name );
188 if ( elementPos == m_pData->rEventsData.end() )
189 throw NoSuchElementException( _Name, *this );
191 Any aReturn;
192 const Sequence< PropertyValue >& rEventDesc( elementPos->second );
193 if ( rEventDesc.getLength() > 0 )
194 aReturn <<= rEventDesc;
195 return aReturn;
198 Sequence< OUString > SAL_CALL DocumentEvents::getElementNames( ) throw (RuntimeException, std::exception)
200 ::osl::MutexGuard aGuard( m_pData->rMutex );
202 Sequence< OUString > aNames( m_pData->rEventsData.size() );
203 ::std::transform(
204 m_pData->rEventsData.begin(),
205 m_pData->rEventsData.end(),
206 aNames.getArray(),
207 ::o3tl::select1st< DocumentEventsData::value_type >()
209 return aNames;
212 sal_Bool SAL_CALL DocumentEvents::hasByName( const OUString& _Name ) throw (RuntimeException, std::exception)
214 ::osl::MutexGuard aGuard( m_pData->rMutex );
216 return m_pData->rEventsData.find( _Name ) != m_pData->rEventsData.end();
219 Type SAL_CALL DocumentEvents::getElementType( ) throw (RuntimeException, std::exception)
221 return ::cppu::UnoType< Sequence< PropertyValue > >::get();
224 sal_Bool SAL_CALL DocumentEvents::hasElements( ) throw (RuntimeException, std::exception)
226 ::osl::MutexGuard aGuard( m_pData->rMutex );
227 return !m_pData->rEventsData.empty();
230 } // namespace dbaccess
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */