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>
26 #include <comphelper/sequence.hxx>
30 #include <o3tl/functional.hxx>
35 using ::com::sun::star::uno::RuntimeException
;
36 using ::com::sun::star::uno::Any
;
37 using ::com::sun::star::beans::PropertyValue
;
38 using ::com::sun::star::container::NoSuchElementException
;
39 using ::com::sun::star::lang::WrappedTargetException
;
40 using ::com::sun::star::lang::IllegalArgumentException
;
41 using ::com::sun::star::uno::Sequence
;
42 using ::com::sun::star::uno::Type
;
44 // DocumentEvents_Data
45 struct DocumentEvents_Data
47 ::cppu::OWeakObject
& rParent
;
49 DocumentEventsData
& rEventsData
;
51 DocumentEvents_Data( ::cppu::OWeakObject
& _rParent
, ::osl::Mutex
& _rMutex
, DocumentEventsData
& _rEventsData
)
54 ,rEventsData( _rEventsData
)
57 DocumentEvents_Data(const DocumentEvents_Data
&) = delete;
58 const DocumentEvents_Data
& operator=(const DocumentEvents_Data
&) = delete;
62 struct DocumentEventData
64 const sal_Char
* pAsciiEventName
;
65 bool bNeedsSyncNotify
;
70 const DocumentEventData
* lcl_getDocumentEventData()
72 static const DocumentEventData s_aData
[] = {
74 { "OnLoadFinished", true },
75 { "OnNew", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
76 { "OnLoad", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484
78 { "OnSaveAsDone", false },
79 { "OnSaveAsFailed", false },
81 { "OnSaveDone", false },
82 { "OnSaveFailed", false },
84 { "OnSaveToDone", false },
85 { "OnSaveToFailed", false },
86 { "OnPrepareUnload", true },
89 { "OnUnfocus", false },
90 { "OnModifyChanged", false },
91 { "OnViewCreated", false },
92 { "OnPrepareViewClosing", true },
93 { "OnViewClosed", false },
94 { "OnTitleChanged", false },
95 { "OnSubComponentOpened", false },
96 { "OnSubComponentClosed", false },
104 DocumentEvents::DocumentEvents( ::cppu::OWeakObject
& _rParent
, ::osl::Mutex
& _rMutex
, DocumentEventsData
& _rEventsData
)
105 :m_pData( new DocumentEvents_Data( _rParent
, _rMutex
, _rEventsData
) )
107 const DocumentEventData
* pEventData
= lcl_getDocumentEventData();
108 while ( pEventData
->pAsciiEventName
)
110 OUString sEventName
= OUString::createFromAscii( pEventData
->pAsciiEventName
);
111 DocumentEventsData::const_iterator existingPos
= m_pData
->rEventsData
.find( sEventName
);
112 if ( existingPos
== m_pData
->rEventsData
.end() )
113 m_pData
->rEventsData
[ sEventName
] = Sequence
< PropertyValue
>();
118 DocumentEvents::~DocumentEvents()
122 void SAL_CALL
DocumentEvents::acquire() throw()
124 m_pData
->rParent
.acquire();
127 void SAL_CALL
DocumentEvents::release() throw()
129 m_pData
->rParent
.release();
132 bool DocumentEvents::needsSynchronousNotification( const OUString
& _rEventName
)
134 const DocumentEventData
* pEventData
= lcl_getDocumentEventData();
135 while ( pEventData
->pAsciiEventName
)
137 if ( _rEventName
.equalsAscii( pEventData
->pAsciiEventName
) )
138 return pEventData
->bNeedsSyncNotify
;
142 // this is an unknown event ... assume async notification
146 void SAL_CALL
DocumentEvents::replaceByName( const OUString
& Name
, const Any
& Element
) throw (IllegalArgumentException
, NoSuchElementException
, WrappedTargetException
, RuntimeException
, std::exception
)
148 ::osl::MutexGuard
aGuard( m_pData
->rMutex
);
150 DocumentEventsData::iterator elementPos
= m_pData
->rEventsData
.find( Name
);
151 if ( elementPos
== m_pData
->rEventsData
.end() )
152 throw NoSuchElementException( Name
, *this );
154 Sequence
< PropertyValue
> aEventDescriptor
;
155 if ( Element
.hasValue() && !( Element
>>= aEventDescriptor
) )
156 throw IllegalArgumentException( Element
.getValueTypeName(), *this, 2 );
158 // Weird enough, the event assignment UI has (well: had) the idea of using an empty "EventType"/"Script"
159 // to indicate the event descriptor should be reset, instead of just passing an empty event descriptor.
160 ::comphelper::NamedValueCollection
aCheck( aEventDescriptor
);
161 if ( aCheck
.has( "EventType" ) )
163 OUString sEventType
= aCheck
.getOrDefault( "EventType", OUString() );
164 OSL_ENSURE( !sEventType
.isEmpty(), "DocumentEvents::replaceByName: doing a reset via an empty EventType is weird!" );
165 if ( sEventType
.isEmpty() )
166 aEventDescriptor
.realloc( 0 );
168 if ( aCheck
.has( "Script" ) )
170 OUString sScript
= aCheck
.getOrDefault( "Script", OUString() );
171 OSL_ENSURE( !sScript
.isEmpty(), "DocumentEvents::replaceByName: doing a reset via an empty Script is weird!" );
172 if ( sScript
.isEmpty() )
173 aEventDescriptor
.realloc( 0 );
176 elementPos
->second
= aEventDescriptor
;
179 Any SAL_CALL
DocumentEvents::getByName( const OUString
& Name
) throw (NoSuchElementException
, WrappedTargetException
, RuntimeException
, std::exception
)
181 ::osl::MutexGuard
aGuard( m_pData
->rMutex
);
183 DocumentEventsData::const_iterator elementPos
= m_pData
->rEventsData
.find( Name
);
184 if ( elementPos
== m_pData
->rEventsData
.end() )
185 throw NoSuchElementException( Name
, *this );
188 const Sequence
< PropertyValue
>& rEventDesc( elementPos
->second
);
189 if ( rEventDesc
.getLength() > 0 )
190 aReturn
<<= rEventDesc
;
194 Sequence
< OUString
> SAL_CALL
DocumentEvents::getElementNames( ) throw (RuntimeException
, std::exception
)
196 ::osl::MutexGuard
aGuard( m_pData
->rMutex
);
198 return comphelper::mapKeysToSequence( m_pData
->rEventsData
);
201 sal_Bool SAL_CALL
DocumentEvents::hasByName( const OUString
& Name
) throw (RuntimeException
, std::exception
)
203 ::osl::MutexGuard
aGuard( m_pData
->rMutex
);
205 return m_pData
->rEventsData
.find( Name
) != m_pData
->rEventsData
.end();
208 Type SAL_CALL
DocumentEvents::getElementType( ) throw (RuntimeException
, std::exception
)
210 return ::cppu::UnoType
< Sequence
< PropertyValue
> >::get();
213 sal_Bool SAL_CALL
DocumentEvents::hasElements( ) throw (RuntimeException
, std::exception
)
215 ::osl::MutexGuard
aGuard( m_pData
->rMutex
);
216 return !m_pData
->rEventsData
.empty();
219 } // namespace dbaccess
221 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */