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