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