1 /************************************************************************* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * Copyright 2000, 2010 Oracle and/or its affiliates. 5 * 6 * OpenOffice.org - a multi-platform office productivity suite 7 * 8 * This file is part of OpenOffice.org. 9 * 10 * OpenOffice.org is free software: you can redistribute it and/or modify 11 * it under the terms of the GNU Lesser General Public License version 3 12 * only, as published by the Free Software Foundation. 13 * 14 * OpenOffice.org is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License version 3 for more details 18 * (a copy is included in the LICENSE file that accompanied this code). 19 * 20 * You should have received a copy of the GNU Lesser General Public License 21 * version 3 along with OpenOffice.org. If not, see 22 * <http://www.openoffice.org/license.html> 23 * for a copy of the LGPLv3 License. 24 * 25 ************************************************************************/ 26 27 // MARKER(update_precomp.py): autogen include statement, do not remove 28 #include "precompiled_dbaccess.hxx" 29 30 #include "documentevents.hxx" 31 32 /** === begin UNO includes === **/ 33 #include <com/sun/star/beans/PropertyValue.hpp> 34 /** === end UNO includes === **/ 35 36 #include <comphelper/namedvaluecollection.hxx> 37 38 #include <algorithm> 39 #include <functional> 40 41 //........................................................................ 42 namespace dbaccess 43 { 44 //........................................................................ 45 46 /** === begin UNO using === **/ 47 using ::com::sun::star::uno::Reference; 48 using ::com::sun::star::uno::XInterface; 49 using ::com::sun::star::uno::UNO_QUERY; 50 using ::com::sun::star::uno::UNO_QUERY_THROW; 51 using ::com::sun::star::uno::UNO_SET_THROW; 52 using ::com::sun::star::uno::Exception; 53 using ::com::sun::star::uno::RuntimeException; 54 using ::com::sun::star::uno::Any; 55 using ::com::sun::star::uno::makeAny; 56 using ::com::sun::star::beans::PropertyValue; 57 using ::com::sun::star::container::NoSuchElementException; 58 using ::com::sun::star::lang::WrappedTargetException; 59 using ::com::sun::star::lang::IllegalArgumentException; 60 using ::com::sun::star::uno::Sequence; 61 using ::com::sun::star::uno::Type; 62 /** === end UNO using === **/ 63 64 //==================================================================== 65 //= DocumentEvents_Data 66 //==================================================================== 67 struct DocumentEvents_Data : public ::boost::noncopyable 68 { 69 ::cppu::OWeakObject& rParent; 70 ::osl::Mutex& rMutex; 71 DocumentEventsData& rEventsData; 72 73 DocumentEvents_Data( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData ) 74 :rParent( _rParent ) 75 ,rMutex( _rMutex ) 76 ,rEventsData( _rEventsData ) 77 { 78 } 79 }; 80 81 //==================================================================== 82 //= helper 83 //==================================================================== 84 struct DocumentEventData 85 { 86 const sal_Char* pAsciiEventName; 87 bool bNeedsSyncNotify; 88 }; 89 90 //-------------------------------------------------------------------- 91 namespace 92 { 93 static const DocumentEventData* lcl_getDocumentEventData() 94 { 95 static const DocumentEventData s_aData[] = { 96 { "OnCreate", true }, 97 { "OnLoadFinished", true }, 98 { "OnNew", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484 99 { "OnLoad", false }, // compatibility, see http://www.openoffice.org/issues/show_bug.cgi?id=46484 100 { "OnSaveAs", true }, 101 { "OnSaveAsDone", false }, 102 { "OnSaveAsFailed", false }, 103 { "OnSave", true }, 104 { "OnSaveDone", false }, 105 { "OnSaveFailed", false }, 106 { "OnSaveTo", true }, 107 { "OnSaveToDone", false }, 108 { "OnSaveToFailed", false }, 109 { "OnPrepareUnload", true }, 110 { "OnUnload", true }, 111 { "OnFocus", false }, 112 { "OnUnfocus", false }, 113 { "OnModifyChanged", false }, 114 { "OnViewCreated", false }, 115 { "OnPrepareViewClosing", true }, 116 { "OnViewClosed", false }, 117 { "OnTitleChanged", false }, 118 { "OnSubComponentOpened", false }, 119 { "OnSubComponentClosed", false }, 120 { NULL, false } 121 }; 122 return s_aData; 123 } 124 } 125 126 //==================================================================== 127 //= DocumentEvents 128 //==================================================================== 129 //-------------------------------------------------------------------- 130 DocumentEvents::DocumentEvents( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rMutex, DocumentEventsData& _rEventsData ) 131 :m_pData( new DocumentEvents_Data( _rParent, _rMutex, _rEventsData ) ) 132 { 133 const DocumentEventData* pEventData = lcl_getDocumentEventData(); 134 while ( pEventData->pAsciiEventName ) 135 { 136 ::rtl::OUString sEventName = ::rtl::OUString::createFromAscii( pEventData->pAsciiEventName ); 137 DocumentEventsData::iterator existingPos = m_pData->rEventsData.find( sEventName ); 138 if ( existingPos == m_pData->rEventsData.end() ) 139 m_pData->rEventsData[ sEventName ] = Sequence< PropertyValue >(); 140 ++pEventData; 141 } 142 } 143 144 //-------------------------------------------------------------------- 145 DocumentEvents::~DocumentEvents() 146 { 147 } 148 149 //-------------------------------------------------------------------- 150 void SAL_CALL DocumentEvents::acquire() throw() 151 { 152 m_pData->rParent.acquire(); 153 } 154 155 //-------------------------------------------------------------------- 156 void SAL_CALL DocumentEvents::release() throw() 157 { 158 m_pData->rParent.release(); 159 } 160 161 //-------------------------------------------------------------------- 162 bool DocumentEvents::needsSynchronousNotification( const ::rtl::OUString& _rEventName ) 163 { 164 const DocumentEventData* pEventData = lcl_getDocumentEventData(); 165 while ( pEventData->pAsciiEventName ) 166 { 167 if ( _rEventName.compareToAscii( pEventData->pAsciiEventName ) == 0 ) 168 return pEventData->bNeedsSyncNotify; 169 ++pEventData; 170 } 171 172 // this is an unknown event ... assume async notification 173 return false; 174 } 175 176 //-------------------------------------------------------------------- 177 void SAL_CALL DocumentEvents::replaceByName( const ::rtl::OUString& _Name, const Any& _Element ) throw (IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException) 178 { 179 ::osl::MutexGuard aGuard( m_pData->rMutex ); 180 181 DocumentEventsData::iterator elementPos = m_pData->rEventsData.find( _Name ); 182 if ( elementPos == m_pData->rEventsData.end() ) 183 throw NoSuchElementException( _Name, *this ); 184 185 Sequence< PropertyValue > aEventDescriptor; 186 if ( _Element.hasValue() && !( _Element >>= aEventDescriptor ) ) 187 throw IllegalArgumentException( _Element.getValueTypeName(), *this, 2 ); 188 189 // Weird enough, the event assignment UI has (well: had) the idea of using an empty "EventType"/"Script" 190 // to indicate the event descriptor should be reset, instead of just passing an empty event descriptor. 191 ::comphelper::NamedValueCollection aCheck( aEventDescriptor ); 192 if ( aCheck.has( "EventType" ) ) 193 { 194 ::rtl::OUString sEventType = aCheck.getOrDefault( "EventType", ::rtl::OUString() ); 195 OSL_ENSURE( sEventType.getLength(), "DocumentEvents::replaceByName: doing a reset via an empty EventType is weird!" ); 196 if ( !sEventType.getLength() ) 197 aEventDescriptor.realloc( 0 ); 198 } 199 if ( aCheck.has( "Script" ) ) 200 { 201 ::rtl::OUString sScript = aCheck.getOrDefault( "Script", ::rtl::OUString() ); 202 OSL_ENSURE( sScript.getLength(), "DocumentEvents::replaceByName: doing a reset via an empty Script is weird!" ); 203 if ( !sScript.getLength() ) 204 aEventDescriptor.realloc( 0 ); 205 } 206 207 elementPos->second = aEventDescriptor; 208 } 209 210 //-------------------------------------------------------------------- 211 Any SAL_CALL DocumentEvents::getByName( const ::rtl::OUString& _Name ) throw (NoSuchElementException, WrappedTargetException, RuntimeException) 212 { 213 ::osl::MutexGuard aGuard( m_pData->rMutex ); 214 215 DocumentEventsData::const_iterator elementPos = m_pData->rEventsData.find( _Name ); 216 if ( elementPos == m_pData->rEventsData.end() ) 217 throw NoSuchElementException( _Name, *this ); 218 219 Any aReturn; 220 const Sequence< PropertyValue >& rEventDesc( elementPos->second ); 221 if ( rEventDesc.getLength() > 0 ) 222 aReturn <<= rEventDesc; 223 return aReturn; 224 } 225 226 //-------------------------------------------------------------------- 227 Sequence< ::rtl::OUString > SAL_CALL DocumentEvents::getElementNames( ) throw (RuntimeException) 228 { 229 ::osl::MutexGuard aGuard( m_pData->rMutex ); 230 231 Sequence< ::rtl::OUString > aNames( m_pData->rEventsData.size() ); 232 ::std::transform( 233 m_pData->rEventsData.begin(), 234 m_pData->rEventsData.end(), 235 aNames.getArray(), 236 ::std::select1st< DocumentEventsData::value_type >() 237 ); 238 return aNames; 239 } 240 241 //-------------------------------------------------------------------- 242 ::sal_Bool SAL_CALL DocumentEvents::hasByName( const ::rtl::OUString& _Name ) throw (RuntimeException) 243 { 244 ::osl::MutexGuard aGuard( m_pData->rMutex ); 245 246 return m_pData->rEventsData.find( _Name ) != m_pData->rEventsData.end(); 247 } 248 249 //-------------------------------------------------------------------- 250 Type SAL_CALL DocumentEvents::getElementType( ) throw (RuntimeException) 251 { 252 return ::cppu::UnoType< Sequence< PropertyValue > >::get(); 253 } 254 255 //-------------------------------------------------------------------- 256 ::sal_Bool SAL_CALL DocumentEvents::hasElements( ) throw (RuntimeException) 257 { 258 ::osl::MutexGuard aGuard( m_pData->rMutex ); 259 return !m_pData->rEventsData.empty(); 260 } 261 262 263 //........................................................................ 264 } // namespace dbaccess 265 //........................................................................ 266