Update ooo320-m1
[ooovba.git] / sw / source / ui / uno / unodispatch.cxx
blob44b82239b104220e21a7d66f6f946511cf5c2969
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: unodispatch.cxx,v $
10 * $Revision: 1.23 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <vcl/svapp.hxx>
36 #include <sfx2/viewfrm.hxx>
37 #include <sfx2/dispatch.hxx>
38 #include <unodispatch.hxx>
39 #include <unoobj.hxx>
40 #include <view.hxx>
41 #include <cmdid.h>
42 #include "wrtsh.hxx"
43 #include "dbmgr.hxx"
44 #include <svx/dataaccessdescriptor.hxx>
46 using namespace ::com::sun::star;
47 using namespace rtl;
48 using namespace vos;
50 const char* cURLStart = ".uno:DataSourceBrowser/";
51 const char* cURLFormLetter = ".uno:DataSourceBrowser/FormLetter";
52 const char* cURLInsertContent = ".uno:DataSourceBrowser/InsertContent";//data into fields
53 const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns";//data into text
54 const char* cURLDocumentDataSource = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document
55 const sal_Char* cInternalDBChangeNotification = ".uno::Writer/DataSourceChanged";
56 /*-- 07.11.00 13:25:51---------------------------------------------------
58 -----------------------------------------------------------------------*/
59 SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView& rVw) :
60 m_pView(&rVw)
62 SfxFrame* pFrame = m_pView->GetViewFrame()->GetFrame();
63 uno::Reference< frame::XFrame> xUnoFrame = pFrame->GetFrameInterface();
64 m_xIntercepted = uno::Reference< frame::XDispatchProviderInterception>(xUnoFrame, uno::UNO_QUERY);
65 if(m_xIntercepted.is())
67 m_refCount++;
68 m_xIntercepted->registerDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
69 // this should make us the top-level dispatch-provider for the component, via a call to our
70 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
71 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
72 if (xInterceptedComponent.is())
73 xInterceptedComponent->addEventListener((lang::XEventListener*)this);
74 m_refCount--;
77 /*-- 07.11.00 13:25:51---------------------------------------------------
79 -----------------------------------------------------------------------*/
80 SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor()
83 /*-- 07.11.00 13:25:51---------------------------------------------------
85 -----------------------------------------------------------------------*/
86 uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch(
87 const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags )
88 throw(uno::RuntimeException)
90 DispatchMutexLock_Impl aLock(*this);
91 uno::Reference< frame::XDispatch> xResult;
92 // create some dispatch ...
93 if(m_pView && !aURL.Complete.compareToAscii(cURLStart, 23))
95 if(!aURL.Complete.compareToAscii(cURLFormLetter) ||
96 !aURL.Complete.compareToAscii(cURLInsertContent) ||
97 !aURL.Complete.compareToAscii(cURLInsertColumns)||
98 !aURL.Complete.compareToAscii(cURLDocumentDataSource))
100 if(!m_xDispatch.is())
101 m_xDispatch = new SwXDispatch(*m_pView);
102 xResult = m_xDispatch;
106 // ask our slave provider
107 if (!xResult.is() && m_xSlaveDispatcher.is())
108 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
110 return xResult;
112 /*-- 07.11.00 13:25:52---------------------------------------------------
114 -----------------------------------------------------------------------*/
115 uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches(
116 const uno::Sequence< frame::DispatchDescriptor >& aDescripts ) throw(uno::RuntimeException)
118 DispatchMutexLock_Impl aLock(*this);
119 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
120 uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray();
121 const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
122 for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts)
124 *pReturn = queryDispatch(pDescripts->FeatureURL,
125 pDescripts->FrameName, pDescripts->SearchFlags);
127 return aReturn;
129 /*-- 07.11.00 13:25:52---------------------------------------------------
131 -----------------------------------------------------------------------*/
132 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider( )
133 throw(uno::RuntimeException)
135 DispatchMutexLock_Impl aLock(*this);
136 return m_xSlaveDispatcher;
138 /*-- 07.11.00 13:25:52---------------------------------------------------
140 -----------------------------------------------------------------------*/
141 void SwXDispatchProviderInterceptor::setSlaveDispatchProvider(
142 const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider ) throw(uno::RuntimeException)
144 DispatchMutexLock_Impl aLock(*this);
145 m_xSlaveDispatcher = xNewDispatchProvider;
147 /*-- 07.11.00 13:25:52---------------------------------------------------
149 -----------------------------------------------------------------------*/
150 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider( )
151 throw(uno::RuntimeException)
153 DispatchMutexLock_Impl aLock(*this);
154 return m_xMasterDispatcher;
156 /*-- 07.11.00 13:25:52---------------------------------------------------
158 -----------------------------------------------------------------------*/
159 void SwXDispatchProviderInterceptor::setMasterDispatchProvider(
160 const uno::Reference< frame::XDispatchProvider >& xNewSupplier ) throw(uno::RuntimeException)
162 DispatchMutexLock_Impl aLock(*this);
163 m_xMasterDispatcher = xNewSupplier;
165 /*-- 07.11.00 13:25:53---------------------------------------------------
167 -----------------------------------------------------------------------*/
168 void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& )
169 throw(uno::RuntimeException)
171 DispatchMutexLock_Impl aLock(*this);
172 if (m_xIntercepted.is())
174 m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
175 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
176 if (xInterceptedComponent.is())
177 xInterceptedComponent->removeEventListener((lang::XEventListener*)this);
178 m_xDispatch = 0;
180 m_xIntercepted = NULL;
182 /* -----------------------------01.10.2001 14:31------------------------------
184 ---------------------------------------------------------------------------*/
185 const uno::Sequence< sal_Int8 > & SwXDispatchProviderInterceptor::getUnoTunnelId()
187 static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
188 return aSeq;
190 /* -----------------------------01.10.2001 14:31------------------------------
192 ---------------------------------------------------------------------------*/
193 sal_Int64 SwXDispatchProviderInterceptor::getSomething(
194 const uno::Sequence< sal_Int8 >& aIdentifier )
195 throw(uno::RuntimeException)
197 if( aIdentifier.getLength() == 16
198 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
199 aIdentifier.getConstArray(), 16 ) )
201 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
203 return 0;
205 /* -----------------------------01.10.2001 14:32------------------------------
207 ---------------------------------------------------------------------------*/
208 void SwXDispatchProviderInterceptor::Invalidate()
210 DispatchMutexLock_Impl aLock(*this);
211 if (m_xIntercepted.is())
213 m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
214 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
215 if (xInterceptedComponent.is())
216 xInterceptedComponent->removeEventListener((lang::XEventListener*)this);
217 m_xDispatch = 0;
219 m_xIntercepted = NULL;
220 m_pView = 0;
222 /* -----------------------------07.11.00 14:26--------------------------------
224 ---------------------------------------------------------------------------*/
225 SwXDispatch::SwXDispatch(SwView& rVw) :
226 m_pView(&rVw),
227 m_bOldEnable(sal_False),
228 m_bListenerAdded(sal_False)
231 /*-- 07.11.00 14:26:13---------------------------------------------------
233 -----------------------------------------------------------------------*/
234 SwXDispatch::~SwXDispatch()
236 if(m_bListenerAdded && m_pView)
238 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
239 uno::Reference<view::XSelectionChangeListener> xThis = this;
240 xSupplier->removeSelectionChangeListener(xThis);
243 /*-- 07.11.00 14:26:13---------------------------------------------------
245 -----------------------------------------------------------------------*/
246 void SwXDispatch::dispatch(
247 const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs ) throw(uno::RuntimeException)
249 if(!m_pView)
250 throw uno::RuntimeException();
251 SwWrtShell& rSh = m_pView->GetWrtShell();
252 SwNewDBMgr* pNewDBMgr = rSh.GetNewDBMgr();
253 if(!aURL.Complete.compareToAscii(cURLInsertContent))
255 ::svx::ODataAccessDescriptor aDescriptor(aArgs);
256 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor );
257 pNewDBMgr->MergeNew(aMergeDesc);
259 else if(!aURL.Complete.compareToAscii(cURLInsertColumns))
261 pNewDBMgr->InsertText(rSh, aArgs);
263 else if(!aURL.Complete.compareToAscii(cURLFormLetter))
265 SfxUsrAnyItem aDBProperties(FN_PARAM_DATABASE_PROPERTIES, uno::makeAny(aArgs));
266 m_pView->GetViewFrame()->GetDispatcher()->Execute(
267 FN_MAILMERGE_WIZARD,
268 SFX_CALLMODE_ASYNCHRON,
269 &aDBProperties, 0L);
270 // pNewDBMgr->ExecuteFormLetter(rSh, aArgs);
272 else if(!aURL.Complete.compareToAscii(cURLDocumentDataSource))
274 OSL_ENSURE(sal_False, "SwXDispatch::dispatch: this URL is not to be dispatched!");
276 else if(!aURL.Complete.compareToAscii(cInternalDBChangeNotification))
278 frame::FeatureStateEvent aEvent;
279 aEvent.IsEnabled = sal_True;
280 aEvent.Source = *(cppu::OWeakObject*)this;
282 const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc();
283 ::svx::ODataAccessDescriptor aDescriptor;
284 aDescriptor.setDataSource(rData.sDataSource);
285 aDescriptor[::svx::daCommand] <<= rData.sCommand;
286 aDescriptor[::svx::daCommandType] <<= rData.nCommandType;
288 aEvent.State <<= aDescriptor.createPropertyValueSequence();
289 aEvent.IsEnabled = rData.sDataSource.getLength() > 0;
291 StatusListenerList::iterator aListIter = m_aListenerList.begin();
292 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
294 StatusStruct_Impl aStatus = *aListIter;
295 if(!aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource))
297 aEvent.FeatureURL = aStatus.aURL;
298 aStatus.xListener->statusChanged( aEvent );
302 else
303 throw uno::RuntimeException();
306 /*-- 07.11.00 14:26:13---------------------------------------------------
308 -----------------------------------------------------------------------*/
309 void SwXDispatch::addStatusListener(
310 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL ) throw(uno::RuntimeException)
312 if(!m_pView)
313 throw uno::RuntimeException();
314 ShellModes eMode = m_pView->GetShellMode();
315 sal_Bool bEnable = SHELL_MODE_TEXT == eMode ||
316 SHELL_MODE_LIST_TEXT == eMode ||
317 SHELL_MODE_TABLE_TEXT == eMode ||
318 SHELL_MODE_TABLE_LIST_TEXT == eMode;
320 m_bOldEnable = bEnable;
321 frame::FeatureStateEvent aEvent;
322 aEvent.IsEnabled = bEnable;
323 aEvent.Source = *(cppu::OWeakObject*)this;
324 aEvent.FeatureURL = aURL;
326 // one of the URLs requires a special state ....
327 if (!aURL.Complete.compareToAscii(cURLDocumentDataSource))
329 const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc();
331 ::svx::ODataAccessDescriptor aDescriptor;
332 aDescriptor.setDataSource(rData.sDataSource);
333 aDescriptor[::svx::daCommand] <<= rData.sCommand;
334 aDescriptor[::svx::daCommandType] <<= rData.nCommandType;
336 aEvent.State <<= aDescriptor.createPropertyValueSequence();
337 aEvent.IsEnabled = rData.sDataSource.getLength() > 0;
341 xControl->statusChanged( aEvent );
343 StatusListenerList::iterator aListIter = m_aListenerList.begin();
344 StatusStruct_Impl aStatus;
345 aStatus.xListener = xControl;
346 aStatus.aURL = aURL;
347 m_aListenerList.insert(aListIter, aStatus);
349 if(!m_bListenerAdded)
351 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
352 uno::Reference<view::XSelectionChangeListener> xThis = this;
353 xSupplier->addSelectionChangeListener(xThis);
354 m_bListenerAdded = sal_True;
357 /*-- 07.11.00 14:26:15---------------------------------------------------
359 -----------------------------------------------------------------------*/
360 void SwXDispatch::removeStatusListener(
361 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& ) throw(uno::RuntimeException)
363 StatusListenerList::iterator aListIter = m_aListenerList.begin();
364 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
366 StatusStruct_Impl aStatus = *aListIter;
367 if(aStatus.xListener.get() == xControl.get())
369 m_aListenerList.erase(aListIter);
370 break;
373 if(m_aListenerList.empty() && m_pView)
375 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
376 uno::Reference<view::XSelectionChangeListener> xThis = this;
377 xSupplier->removeSelectionChangeListener(xThis);
378 m_bListenerAdded = sal_False;
381 /* -----------------------------07.03.01 10:27--------------------------------
383 ---------------------------------------------------------------------------*/
384 void SwXDispatch::selectionChanged( const lang::EventObject& ) throw(uno::RuntimeException)
386 ShellModes eMode = m_pView->GetShellMode();
387 sal_Bool bEnable = SHELL_MODE_TEXT == eMode ||
388 SHELL_MODE_LIST_TEXT == eMode ||
389 SHELL_MODE_TABLE_TEXT == eMode ||
390 SHELL_MODE_TABLE_LIST_TEXT == eMode;
391 if(bEnable != m_bOldEnable)
393 m_bOldEnable = bEnable;
394 frame::FeatureStateEvent aEvent;
395 aEvent.IsEnabled = bEnable;
396 aEvent.Source = *(cppu::OWeakObject*)this;
398 StatusListenerList::iterator aListIter = m_aListenerList.begin();
399 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
401 StatusStruct_Impl aStatus = *aListIter;
402 aEvent.FeatureURL = aStatus.aURL;
403 if (0 != aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource))
404 // the document's data source does not depend on the selection, so it's state does not change here
405 aStatus.xListener->statusChanged( aEvent );
409 /* -----------------------------07.03.01 10:46--------------------------------
411 ---------------------------------------------------------------------------*/
412 void SwXDispatch::disposing( const lang::EventObject& rSource ) throw(uno::RuntimeException)
414 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
415 uno::Reference<view::XSelectionChangeListener> xThis = this;
416 xSupplier->removeSelectionChangeListener(xThis);
417 m_bListenerAdded = sal_False;
419 lang::EventObject aObject;
420 aObject.Source = (cppu::OWeakObject*)this;
421 StatusListenerList::iterator aListIter = m_aListenerList.begin();
422 for(; aListIter != m_aListenerList.end(); ++aListIter)
424 StatusStruct_Impl aStatus = *aListIter;
425 aStatus.xListener->disposing(aObject);
427 m_pView = 0;
429 /* -----------------------------12.07.01 13:30--------------------------------
431 ---------------------------------------------------------------------------*/
432 const sal_Char* SwXDispatch::GetDBChangeURL()
434 return cInternalDBChangeNotification;
436 /* -----------------------------09.09.2002 08:48------------------------------
438 ---------------------------------------------------------------------------*/
439 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl(
440 SwXDispatchProviderInterceptor& ) :
441 // aGuard(rInterceptor.m_aMutex) #102295# solar mutex has to be used currently
442 aGuard(Application::GetSolarMutex())
445 /* -----------------------------09.09.2002 08:48------------------------------
447 ---------------------------------------------------------------------------*/
448 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl()