1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_embeddedobj.hxx" 30 #include <com/sun/star/embed/EmbedStates.hpp> 31 #include <cppuhelper/weak.hxx> 32 33 #include "intercept.hxx" 34 #include "docholder.hxx" 35 #include "commonembobj.hxx" 36 37 using namespace ::com::sun::star; 38 39 40 #define IUL 6 41 42 43 uno::Sequence< ::rtl::OUString > Interceptor::m_aInterceptedURL(IUL); 44 45 struct equalOUString 46 { 47 bool operator()( 48 const rtl::OUString& rKey1, 49 const rtl::OUString& rKey2 ) const 50 { 51 return !!( rKey1 == rKey2 ); 52 } 53 }; 54 55 56 struct hashOUString 57 { 58 size_t operator()( const rtl::OUString& rName ) const 59 { 60 return rName.hashCode(); 61 } 62 }; 63 64 65 66 class StatusChangeListenerContainer 67 : public ::cppu::OMultiTypeInterfaceContainerHelperVar< 68 rtl::OUString,hashOUString,equalOUString> 69 { 70 public: 71 StatusChangeListenerContainer( ::osl::Mutex& aMutex ) 72 : cppu::OMultiTypeInterfaceContainerHelperVar< 73 rtl::OUString,hashOUString,equalOUString>(aMutex) 74 { 75 } 76 }; 77 78 79 void Interceptor::DisconnectDocHolder() 80 { 81 osl::MutexGuard aGuard( m_aMutex ); 82 m_pDocHolder = NULL; 83 } 84 85 void SAL_CALL 86 Interceptor::addEventListener( 87 const uno::Reference<lang::XEventListener >& Listener ) 88 throw( uno::RuntimeException ) 89 { 90 osl::MutexGuard aGuard( m_aMutex ); 91 92 if ( ! m_pDisposeEventListeners ) 93 m_pDisposeEventListeners = 94 new cppu::OInterfaceContainerHelper( m_aMutex ); 95 96 m_pDisposeEventListeners->addInterface( Listener ); 97 } 98 99 100 void SAL_CALL 101 Interceptor::removeEventListener( 102 const uno::Reference< lang::XEventListener >& Listener ) 103 throw( uno::RuntimeException ) 104 { 105 osl::MutexGuard aGuard( m_aMutex ); 106 107 if ( m_pDisposeEventListeners ) 108 m_pDisposeEventListeners->removeInterface( Listener ); 109 } 110 111 112 Interceptor::Interceptor( DocumentHolder* pDocHolder ) 113 : m_pDocHolder( pDocHolder ), 114 m_pDisposeEventListeners(0), 115 m_pStatCL(0) 116 { 117 m_aInterceptedURL[0] = rtl::OUString( 118 RTL_CONSTASCII_USTRINGPARAM(".uno:Save")); 119 m_aInterceptedURL[1] = rtl::OUString( 120 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAll")); 121 m_aInterceptedURL[2] = rtl::OUString( 122 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc")); 123 m_aInterceptedURL[3] = rtl::OUString( 124 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin")); 125 m_aInterceptedURL[4] = rtl::OUString( 126 RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame")); 127 m_aInterceptedURL[5] = rtl::OUString( 128 RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs")); 129 130 } 131 132 133 Interceptor::~Interceptor() 134 { 135 if( m_pDisposeEventListeners ) 136 delete m_pDisposeEventListeners; 137 138 if(m_pStatCL) 139 delete m_pStatCL; 140 } 141 142 143 144 //XDispatch 145 void SAL_CALL 146 Interceptor::dispatch( 147 const util::URL& URL, 148 const uno::Sequence< 149 beans::PropertyValue >& Arguments ) 150 throw (uno::RuntimeException) 151 { 152 osl::MutexGuard aGuard(m_aMutex); 153 if( m_pDocHolder ) 154 { 155 if(URL.Complete == m_aInterceptedURL[0]) 156 m_pDocHolder->GetEmbedObject()->SaveObject_Impl(); 157 else if(URL.Complete == m_aInterceptedURL[2] || 158 URL.Complete == m_aInterceptedURL[3] || 159 URL.Complete == m_aInterceptedURL[4]) 160 { 161 try { 162 m_pDocHolder->GetEmbedObject()->changeState( embed::EmbedStates::RUNNING ); 163 } 164 catch( uno::Exception& ) 165 { 166 } 167 } 168 else if ( URL.Complete == m_aInterceptedURL[5] ) 169 { 170 uno::Sequence< beans::PropertyValue > aNewArgs = Arguments; 171 sal_Int32 nInd = 0; 172 173 while( nInd < aNewArgs.getLength() ) 174 { 175 if ( aNewArgs[nInd].Name.equalsAscii( "SaveTo" ) ) 176 { 177 aNewArgs[nInd].Value <<= sal_True; 178 break; 179 } 180 nInd++; 181 } 182 183 if ( nInd == aNewArgs.getLength() ) 184 { 185 aNewArgs.realloc( nInd + 1 ); 186 aNewArgs[nInd].Name = ::rtl::OUString::createFromAscii( "SaveTo" ); 187 aNewArgs[nInd].Value <<= sal_True; 188 } 189 190 uno::Reference< frame::XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch( 191 URL, ::rtl::OUString::createFromAscii( "_self" ), 0 ); 192 if ( xDispatch.is() ) 193 xDispatch->dispatch( URL, aNewArgs ); 194 } 195 } 196 } 197 198 void SAL_CALL 199 Interceptor::addStatusListener( 200 const uno::Reference< 201 frame::XStatusListener >& Control, 202 const util::URL& URL ) 203 throw ( 204 uno::RuntimeException 205 ) 206 { 207 if(!Control.is()) 208 return; 209 210 if(URL.Complete == m_aInterceptedURL[0]) 211 { // Save 212 frame::FeatureStateEvent aStateEvent; 213 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[0]; 214 aStateEvent.FeatureDescriptor = rtl::OUString( 215 RTL_CONSTASCII_USTRINGPARAM("Update")); 216 aStateEvent.IsEnabled = sal_True; 217 aStateEvent.Requery = sal_False; 218 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($1) ")) + m_pDocHolder->GetTitle() ); 219 Control->statusChanged(aStateEvent); 220 221 { 222 osl::MutexGuard aGuard(m_aMutex); 223 if(!m_pStatCL) 224 m_pStatCL = 225 new StatusChangeListenerContainer(m_aMutex); 226 } 227 228 m_pStatCL->addInterface(URL.Complete,Control); 229 return; 230 } 231 232 sal_Int32 i = 2; 233 if(URL.Complete == m_aInterceptedURL[i] || 234 URL.Complete == m_aInterceptedURL[++i] || 235 URL.Complete == m_aInterceptedURL[++i] ) 236 { // Close and return 237 frame::FeatureStateEvent aStateEvent; 238 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i]; 239 aStateEvent.FeatureDescriptor = rtl::OUString( 240 RTL_CONSTASCII_USTRINGPARAM("Close and Return")); 241 aStateEvent.IsEnabled = sal_True; 242 aStateEvent.Requery = sal_False; 243 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($2) ")) + m_pDocHolder->GetTitle() ); 244 Control->statusChanged(aStateEvent); 245 246 247 { 248 osl::MutexGuard aGuard(m_aMutex); 249 if(!m_pStatCL) 250 m_pStatCL = 251 new StatusChangeListenerContainer(m_aMutex); 252 } 253 254 m_pStatCL->addInterface(URL.Complete,Control); 255 return; 256 } 257 258 if(URL.Complete == m_aInterceptedURL[5]) 259 { // SaveAs 260 frame::FeatureStateEvent aStateEvent; 261 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[5]; 262 aStateEvent.FeatureDescriptor = rtl::OUString( 263 RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo")); 264 aStateEvent.IsEnabled = sal_True; 265 aStateEvent.Requery = sal_False; 266 aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)"))); 267 Control->statusChanged(aStateEvent); 268 269 { 270 osl::MutexGuard aGuard(m_aMutex); 271 if(!m_pStatCL) 272 m_pStatCL = 273 new StatusChangeListenerContainer(m_aMutex); 274 } 275 276 m_pStatCL->addInterface(URL.Complete,Control); 277 return; 278 } 279 280 } 281 282 283 void SAL_CALL 284 Interceptor::removeStatusListener( 285 const uno::Reference< 286 frame::XStatusListener >& Control, 287 const util::URL& URL ) 288 throw ( 289 uno::RuntimeException 290 ) 291 { 292 if(!(Control.is() && m_pStatCL)) 293 return; 294 else { 295 m_pStatCL->removeInterface(URL.Complete,Control); 296 return; 297 } 298 } 299 300 301 //XInterceptorInfo 302 uno::Sequence< ::rtl::OUString > 303 SAL_CALL 304 Interceptor::getInterceptedURLs( ) 305 throw ( 306 uno::RuntimeException 307 ) 308 { 309 // now implemented as update 310 311 return m_aInterceptedURL; 312 } 313 314 315 // XDispatchProvider 316 317 uno::Reference< frame::XDispatch > SAL_CALL 318 Interceptor::queryDispatch( 319 const util::URL& URL, 320 const ::rtl::OUString& TargetFrameName, 321 sal_Int32 SearchFlags ) 322 throw ( 323 uno::RuntimeException 324 ) 325 { 326 osl::MutexGuard aGuard(m_aMutex); 327 if(URL.Complete == m_aInterceptedURL[0]) 328 return (frame::XDispatch*)this; 329 else if(URL.Complete == m_aInterceptedURL[1]) 330 return (frame::XDispatch*)0 ; 331 else if(URL.Complete == m_aInterceptedURL[2]) 332 return (frame::XDispatch*)this; 333 else if(URL.Complete == m_aInterceptedURL[3]) 334 return (frame::XDispatch*)this; 335 else if(URL.Complete == m_aInterceptedURL[4]) 336 return (frame::XDispatch*)this; 337 else if(URL.Complete == m_aInterceptedURL[5]) 338 return (frame::XDispatch*)this; 339 else { 340 if(m_xSlaveDispatchProvider.is()) 341 return m_xSlaveDispatchProvider->queryDispatch( 342 URL,TargetFrameName,SearchFlags); 343 else 344 return uno::Reference<frame::XDispatch>(0); 345 } 346 } 347 348 uno::Sequence< uno::Reference< frame::XDispatch > > SAL_CALL 349 Interceptor::queryDispatches( 350 const uno::Sequence<frame::DispatchDescriptor >& Requests ) 351 throw ( 352 uno::RuntimeException 353 ) 354 { 355 uno::Sequence< uno::Reference< frame::XDispatch > > aRet; 356 osl::MutexGuard aGuard(m_aMutex); 357 if(m_xSlaveDispatchProvider.is()) 358 aRet = m_xSlaveDispatchProvider->queryDispatches(Requests); 359 else 360 aRet.realloc(Requests.getLength()); 361 362 for(sal_Int32 i = 0; i < Requests.getLength(); ++i) 363 if(m_aInterceptedURL[0] == Requests[i].FeatureURL.Complete) 364 aRet[i] = (frame::XDispatch*) this; 365 else if(m_aInterceptedURL[1] == Requests[i].FeatureURL.Complete) 366 aRet[i] = (frame::XDispatch*) 0; 367 else if(m_aInterceptedURL[2] == Requests[i].FeatureURL.Complete) 368 aRet[i] = (frame::XDispatch*) this; 369 else if(m_aInterceptedURL[3] == Requests[i].FeatureURL.Complete) 370 aRet[i] = (frame::XDispatch*) this; 371 else if(m_aInterceptedURL[4] == Requests[i].FeatureURL.Complete) 372 aRet[i] = (frame::XDispatch*) this; 373 else if(m_aInterceptedURL[5] == Requests[i].FeatureURL.Complete) 374 aRet[i] = (frame::XDispatch*) this; 375 376 return aRet; 377 } 378 379 380 381 //XDispatchProviderInterceptor 382 383 uno::Reference< frame::XDispatchProvider > SAL_CALL 384 Interceptor::getSlaveDispatchProvider( ) 385 throw ( 386 uno::RuntimeException 387 ) 388 { 389 osl::MutexGuard aGuard(m_aMutex); 390 return m_xSlaveDispatchProvider; 391 } 392 393 void SAL_CALL 394 Interceptor::setSlaveDispatchProvider( 395 const uno::Reference< frame::XDispatchProvider >& NewDispatchProvider ) 396 throw ( 397 uno::RuntimeException 398 ) 399 { 400 osl::MutexGuard aGuard(m_aMutex); 401 m_xSlaveDispatchProvider = NewDispatchProvider; 402 } 403 404 405 uno::Reference< frame::XDispatchProvider > SAL_CALL 406 Interceptor::getMasterDispatchProvider( ) 407 throw ( 408 uno::RuntimeException 409 ) 410 { 411 osl::MutexGuard aGuard(m_aMutex); 412 return m_xMasterDispatchProvider; 413 } 414 415 416 void SAL_CALL 417 Interceptor::setMasterDispatchProvider( 418 const uno::Reference< frame::XDispatchProvider >& NewSupplier ) 419 throw ( 420 uno::RuntimeException 421 ) 422 { 423 osl::MutexGuard aGuard(m_aMutex); 424 m_xMasterDispatchProvider = NewSupplier; 425 } 426 427