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_sw.hxx" 26 27 #include <vcl/svapp.hxx> 28 #include <sfx2/viewfrm.hxx> 29 #include <sfx2/dispatch.hxx> 30 #include <svx/dataaccessdescriptor.hxx> 31 32 #include <unodispatch.hxx> 33 #include <unobaseclass.hxx> 34 #include <view.hxx> 35 #include <cmdid.h> 36 #include "wrtsh.hxx" 37 #include "dbmgr.hxx" 38 39 40 using namespace ::com::sun::star; 41 using namespace rtl; 42 using namespace vos; 43 44 const char* cURLStart = ".uno:DataSourceBrowser/"; 45 const char* cURLFormLetter = ".uno:DataSourceBrowser/FormLetter"; 46 const char* cURLInsertContent = ".uno:DataSourceBrowser/InsertContent";//data into fields 47 const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns";//data into text 48 const char* cURLDocumentDataSource = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document 49 const sal_Char* cInternalDBChangeNotification = ".uno::Writer/DataSourceChanged"; 50 /*-- 07.11.00 13:25:51--------------------------------------------------- 51 52 -----------------------------------------------------------------------*/ 53 SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView& rVw) : 54 m_pView(&rVw) 55 { 56 uno::Reference< frame::XFrame> xUnoFrame = m_pView->GetViewFrame()->GetFrame().GetFrameInterface(); 57 m_xIntercepted = uno::Reference< frame::XDispatchProviderInterception>(xUnoFrame, uno::UNO_QUERY); 58 if(m_xIntercepted.is()) 59 { 60 m_refCount++; 61 m_xIntercepted->registerDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this); 62 // this should make us the top-level dispatch-provider for the component, via a call to our 63 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill 64 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY); 65 if (xInterceptedComponent.is()) 66 xInterceptedComponent->addEventListener((lang::XEventListener*)this); 67 m_refCount--; 68 } 69 } 70 /*-- 07.11.00 13:25:51--------------------------------------------------- 71 72 -----------------------------------------------------------------------*/ 73 SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor() 74 { 75 } 76 /*-- 07.11.00 13:25:51--------------------------------------------------- 77 78 -----------------------------------------------------------------------*/ 79 uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch( 80 const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags ) 81 throw(uno::RuntimeException) 82 { 83 DispatchMutexLock_Impl aLock(*this); 84 uno::Reference< frame::XDispatch> xResult; 85 // create some dispatch ... 86 if(m_pView && !aURL.Complete.compareToAscii(cURLStart, 23)) 87 { 88 if(!aURL.Complete.compareToAscii(cURLFormLetter) || 89 !aURL.Complete.compareToAscii(cURLInsertContent) || 90 !aURL.Complete.compareToAscii(cURLInsertColumns)|| 91 !aURL.Complete.compareToAscii(cURLDocumentDataSource)) 92 { 93 if(!m_xDispatch.is()) 94 m_xDispatch = new SwXDispatch(*m_pView); 95 xResult = m_xDispatch; 96 } 97 } 98 99 // ask our slave provider 100 if (!xResult.is() && m_xSlaveDispatcher.is()) 101 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags); 102 103 return xResult; 104 } 105 /*-- 07.11.00 13:25:52--------------------------------------------------- 106 107 -----------------------------------------------------------------------*/ 108 uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches( 109 const uno::Sequence< frame::DispatchDescriptor >& aDescripts ) throw(uno::RuntimeException) 110 { 111 DispatchMutexLock_Impl aLock(*this); 112 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength()); 113 uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray(); 114 const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray(); 115 for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts) 116 { 117 *pReturn = queryDispatch(pDescripts->FeatureURL, 118 pDescripts->FrameName, pDescripts->SearchFlags); 119 } 120 return aReturn; 121 } 122 /*-- 07.11.00 13:25:52--------------------------------------------------- 123 124 -----------------------------------------------------------------------*/ 125 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider( ) 126 throw(uno::RuntimeException) 127 { 128 DispatchMutexLock_Impl aLock(*this); 129 return m_xSlaveDispatcher; 130 } 131 /*-- 07.11.00 13:25:52--------------------------------------------------- 132 133 -----------------------------------------------------------------------*/ 134 void SwXDispatchProviderInterceptor::setSlaveDispatchProvider( 135 const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider ) throw(uno::RuntimeException) 136 { 137 DispatchMutexLock_Impl aLock(*this); 138 m_xSlaveDispatcher = xNewDispatchProvider; 139 } 140 /*-- 07.11.00 13:25:52--------------------------------------------------- 141 142 -----------------------------------------------------------------------*/ 143 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider( ) 144 throw(uno::RuntimeException) 145 { 146 DispatchMutexLock_Impl aLock(*this); 147 return m_xMasterDispatcher; 148 } 149 /*-- 07.11.00 13:25:52--------------------------------------------------- 150 151 -----------------------------------------------------------------------*/ 152 void SwXDispatchProviderInterceptor::setMasterDispatchProvider( 153 const uno::Reference< frame::XDispatchProvider >& xNewSupplier ) throw(uno::RuntimeException) 154 { 155 DispatchMutexLock_Impl aLock(*this); 156 m_xMasterDispatcher = xNewSupplier; 157 } 158 /*-- 07.11.00 13:25:53--------------------------------------------------- 159 160 -----------------------------------------------------------------------*/ 161 void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& ) 162 throw(uno::RuntimeException) 163 { 164 DispatchMutexLock_Impl aLock(*this); 165 if (m_xIntercepted.is()) 166 { 167 m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this); 168 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY); 169 if (xInterceptedComponent.is()) 170 xInterceptedComponent->removeEventListener((lang::XEventListener*)this); 171 m_xDispatch = 0; 172 } 173 m_xIntercepted = NULL; 174 } 175 /* -----------------------------01.10.2001 14:31------------------------------ 176 177 ---------------------------------------------------------------------------*/ 178 const uno::Sequence< sal_Int8 > & SwXDispatchProviderInterceptor::getUnoTunnelId() 179 { 180 static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId(); 181 return aSeq; 182 } 183 /* -----------------------------01.10.2001 14:31------------------------------ 184 185 ---------------------------------------------------------------------------*/ 186 sal_Int64 SwXDispatchProviderInterceptor::getSomething( 187 const uno::Sequence< sal_Int8 >& aIdentifier ) 188 throw(uno::RuntimeException) 189 { 190 if( aIdentifier.getLength() == 16 191 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), 192 aIdentifier.getConstArray(), 16 ) ) 193 { 194 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this )); 195 } 196 return 0; 197 } 198 /* -----------------------------01.10.2001 14:32------------------------------ 199 200 ---------------------------------------------------------------------------*/ 201 void SwXDispatchProviderInterceptor::Invalidate() 202 { 203 DispatchMutexLock_Impl aLock(*this); 204 if (m_xIntercepted.is()) 205 { 206 m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this); 207 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY); 208 if (xInterceptedComponent.is()) 209 xInterceptedComponent->removeEventListener((lang::XEventListener*)this); 210 m_xDispatch = 0; 211 } 212 m_xIntercepted = NULL; 213 m_pView = 0; 214 } 215 /* -----------------------------07.11.00 14:26-------------------------------- 216 217 ---------------------------------------------------------------------------*/ 218 SwXDispatch::SwXDispatch(SwView& rVw) : 219 m_pView(&rVw), 220 m_bOldEnable(sal_False), 221 m_bListenerAdded(sal_False) 222 { 223 } 224 /*-- 07.11.00 14:26:13--------------------------------------------------- 225 226 -----------------------------------------------------------------------*/ 227 SwXDispatch::~SwXDispatch() 228 { 229 if(m_bListenerAdded && m_pView) 230 { 231 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject(); 232 uno::Reference<view::XSelectionChangeListener> xThis = this; 233 xSupplier->removeSelectionChangeListener(xThis); 234 } 235 } 236 /*-- 07.11.00 14:26:13--------------------------------------------------- 237 238 -----------------------------------------------------------------------*/ 239 void SwXDispatch::dispatch( 240 const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs ) throw(uno::RuntimeException) 241 { 242 if(!m_pView) 243 throw uno::RuntimeException(); 244 SwWrtShell& rSh = m_pView->GetWrtShell(); 245 SwNewDBMgr* pNewDBMgr = rSh.GetNewDBMgr(); 246 if(!aURL.Complete.compareToAscii(cURLInsertContent)) 247 { 248 ::svx::ODataAccessDescriptor aDescriptor(aArgs); 249 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor ); 250 pNewDBMgr->MergeNew(aMergeDesc); 251 } 252 else if(!aURL.Complete.compareToAscii(cURLInsertColumns)) 253 { 254 pNewDBMgr->InsertText(rSh, aArgs); 255 } 256 else if(!aURL.Complete.compareToAscii(cURLFormLetter)) 257 { 258 SfxUsrAnyItem aDBProperties(FN_PARAM_DATABASE_PROPERTIES, uno::makeAny(aArgs)); 259 m_pView->GetViewFrame()->GetDispatcher()->Execute( 260 FN_MAILMERGE_WIZARD, 261 SFX_CALLMODE_ASYNCHRON, 262 &aDBProperties, 0L); 263 // pNewDBMgr->ExecuteFormLetter(rSh, aArgs); 264 } 265 else if(!aURL.Complete.compareToAscii(cURLDocumentDataSource)) 266 { 267 OSL_ENSURE(sal_False, "SwXDispatch::dispatch: this URL is not to be dispatched!"); 268 } 269 else if(!aURL.Complete.compareToAscii(cInternalDBChangeNotification)) 270 { 271 frame::FeatureStateEvent aEvent; 272 aEvent.IsEnabled = sal_True; 273 aEvent.Source = *(cppu::OWeakObject*)this; 274 275 const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc(); 276 ::svx::ODataAccessDescriptor aDescriptor; 277 aDescriptor.setDataSource(rData.sDataSource); 278 aDescriptor[::svx::daCommand] <<= rData.sCommand; 279 aDescriptor[::svx::daCommandType] <<= rData.nCommandType; 280 281 aEvent.State <<= aDescriptor.createPropertyValueSequence(); 282 aEvent.IsEnabled = rData.sDataSource.getLength() > 0; 283 284 StatusListenerList::iterator aListIter = m_aListenerList.begin(); 285 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter) 286 { 287 StatusStruct_Impl aStatus = *aListIter; 288 if(!aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource)) 289 { 290 aEvent.FeatureURL = aStatus.aURL; 291 aStatus.xListener->statusChanged( aEvent ); 292 } 293 } 294 } 295 else 296 throw uno::RuntimeException(); 297 298 } 299 /*-- 07.11.00 14:26:13--------------------------------------------------- 300 301 -----------------------------------------------------------------------*/ 302 void SwXDispatch::addStatusListener( 303 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL ) throw(uno::RuntimeException) 304 { 305 if(!m_pView) 306 throw uno::RuntimeException(); 307 ShellModes eMode = m_pView->GetShellMode(); 308 sal_Bool bEnable = SHELL_MODE_TEXT == eMode || 309 SHELL_MODE_LIST_TEXT == eMode || 310 SHELL_MODE_TABLE_TEXT == eMode || 311 SHELL_MODE_TABLE_LIST_TEXT == eMode; 312 313 m_bOldEnable = bEnable; 314 frame::FeatureStateEvent aEvent; 315 aEvent.IsEnabled = bEnable; 316 aEvent.Source = *(cppu::OWeakObject*)this; 317 aEvent.FeatureURL = aURL; 318 319 // one of the URLs requires a special state .... 320 if (!aURL.Complete.compareToAscii(cURLDocumentDataSource)) 321 { 322 const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc(); 323 324 ::svx::ODataAccessDescriptor aDescriptor; 325 aDescriptor.setDataSource(rData.sDataSource); 326 aDescriptor[::svx::daCommand] <<= rData.sCommand; 327 aDescriptor[::svx::daCommandType] <<= rData.nCommandType; 328 329 aEvent.State <<= aDescriptor.createPropertyValueSequence(); 330 aEvent.IsEnabled = rData.sDataSource.getLength() > 0; 331 } 332 333 334 xControl->statusChanged( aEvent ); 335 336 StatusListenerList::iterator aListIter = m_aListenerList.begin(); 337 StatusStruct_Impl aStatus; 338 aStatus.xListener = xControl; 339 aStatus.aURL = aURL; 340 m_aListenerList.insert(aListIter, aStatus); 341 342 if(!m_bListenerAdded) 343 { 344 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject(); 345 uno::Reference<view::XSelectionChangeListener> xThis = this; 346 xSupplier->addSelectionChangeListener(xThis); 347 m_bListenerAdded = sal_True; 348 } 349 } 350 /*-- 07.11.00 14:26:15--------------------------------------------------- 351 352 -----------------------------------------------------------------------*/ 353 void SwXDispatch::removeStatusListener( 354 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& ) throw(uno::RuntimeException) 355 { 356 StatusListenerList::iterator aListIter = m_aListenerList.begin(); 357 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter) 358 { 359 StatusStruct_Impl aStatus = *aListIter; 360 if(aStatus.xListener.get() == xControl.get()) 361 { 362 m_aListenerList.erase(aListIter); 363 break; 364 } 365 } 366 if(m_aListenerList.empty() && m_pView) 367 { 368 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject(); 369 uno::Reference<view::XSelectionChangeListener> xThis = this; 370 xSupplier->removeSelectionChangeListener(xThis); 371 m_bListenerAdded = sal_False; 372 } 373 } 374 /* -----------------------------07.03.01 10:27-------------------------------- 375 376 ---------------------------------------------------------------------------*/ 377 void SwXDispatch::selectionChanged( const lang::EventObject& ) throw(uno::RuntimeException) 378 { 379 ShellModes eMode = m_pView->GetShellMode(); 380 sal_Bool bEnable = SHELL_MODE_TEXT == eMode || 381 SHELL_MODE_LIST_TEXT == eMode || 382 SHELL_MODE_TABLE_TEXT == eMode || 383 SHELL_MODE_TABLE_LIST_TEXT == eMode; 384 if(bEnable != m_bOldEnable) 385 { 386 m_bOldEnable = bEnable; 387 frame::FeatureStateEvent aEvent; 388 aEvent.IsEnabled = bEnable; 389 aEvent.Source = *(cppu::OWeakObject*)this; 390 391 StatusListenerList::iterator aListIter = m_aListenerList.begin(); 392 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter) 393 { 394 StatusStruct_Impl aStatus = *aListIter; 395 aEvent.FeatureURL = aStatus.aURL; 396 if (0 != aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource)) 397 // the document's data source does not depend on the selection, so it's state does not change here 398 aStatus.xListener->statusChanged( aEvent ); 399 } 400 } 401 } 402 /* -----------------------------07.03.01 10:46-------------------------------- 403 404 ---------------------------------------------------------------------------*/ 405 void SwXDispatch::disposing( const lang::EventObject& rSource ) throw(uno::RuntimeException) 406 { 407 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY); 408 uno::Reference<view::XSelectionChangeListener> xThis = this; 409 xSupplier->removeSelectionChangeListener(xThis); 410 m_bListenerAdded = sal_False; 411 412 lang::EventObject aObject; 413 aObject.Source = (cppu::OWeakObject*)this; 414 StatusListenerList::iterator aListIter = m_aListenerList.begin(); 415 for(; aListIter != m_aListenerList.end(); ++aListIter) 416 { 417 StatusStruct_Impl aStatus = *aListIter; 418 aStatus.xListener->disposing(aObject); 419 } 420 m_pView = 0; 421 } 422 /* -----------------------------12.07.01 13:30-------------------------------- 423 424 ---------------------------------------------------------------------------*/ 425 const sal_Char* SwXDispatch::GetDBChangeURL() 426 { 427 return cInternalDBChangeNotification; 428 } 429 /* -----------------------------09.09.2002 08:48------------------------------ 430 431 ---------------------------------------------------------------------------*/ 432 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl( 433 SwXDispatchProviderInterceptor& ) : 434 // aGuard(rInterceptor.m_aMutex) #102295# solar mutex has to be used currently 435 aGuard(Application::GetSolarMutex()) 436 { 437 } 438 /* -----------------------------09.09.2002 08:48------------------------------ 439 440 ---------------------------------------------------------------------------*/ 441 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl() 442 { 443 } 444 445