1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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>
29 #include <o3tl/compat_functional.hxx>
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
;
55 DocumentEventsData
& rEventsData
;
57 DocumentEvents_Data( ::cppu::OWeakObject
& _rParent
, ::osl::Mutex
& _rMutex
, DocumentEventsData
& _rEventsData
)
60 ,rEventsData( _rEventsData
)
66 struct DocumentEventData
68 const sal_Char
* pAsciiEventName
;
69 bool bNeedsSyncNotify
;
74 static const DocumentEventData
* lcl_getDocumentEventData()
76 static const DocumentEventData s_aData
[] = {
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
82 { "OnSaveAsDone", false },
83 { "OnSaveAsFailed", false },
85 { "OnSaveDone", false },
86 { "OnSaveFailed", false },
88 { "OnSaveToDone", false },
89 { "OnSaveToFailed", false },
90 { "OnPrepareUnload", true },
93 { "OnUnfocus", false },
94 { "OnModifyChanged", false },
95 { "OnViewCreated", false },
96 { "OnPrepareViewClosing", true },
97 { "OnViewClosed", false },
98 { "OnTitleChanged", false },
99 { "OnSubComponentOpened", false },
100 { "OnSubComponentClosed", false },
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
>();
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
;
146 // this is an unknown event ... assume async notification
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 );
192 const Sequence
< PropertyValue
>& rEventDesc( elementPos
->second
);
193 if ( rEventDesc
.getLength() > 0 )
194 aReturn
<<= rEventDesc
;
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() );
204 m_pData
->rEventsData
.begin(),
205 m_pData
->rEventsData
.end(),
207 ::o3tl::select1st
< DocumentEventsData::value_type
>()
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: */