bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / uno / unodispatch.cxx
blob6af22e9a214e4f9f11b47e9646e9823a3dcea359
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <vcl/svapp.hxx>
22 #include <sfx2/viewfrm.hxx>
23 #include <sfx2/dispatch.hxx>
24 #include <svx/dataaccessdescriptor.hxx>
25 #include <comphelper/servicehelper.hxx>
26 #include <unodispatch.hxx>
27 #include <unobaseclass.hxx>
28 #include <view.hxx>
29 #include <cmdid.h>
30 #include "wrtsh.hxx"
31 #include "dbmgr.hxx"
34 using namespace ::com::sun::star;
37 static const char* cURLFormLetter = ".uno:DataSourceBrowser/FormLetter";
38 static const char* cURLInsertContent = ".uno:DataSourceBrowser/InsertContent";//data into fields
39 static const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns";//data into text
40 static const char* cURLDocumentDataSource = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document
41 static const sal_Char* cInternalDBChangeNotification = ".uno::Writer/DataSourceChanged";
43 SwXDispatchProviderInterceptor::SwXDispatchProviderInterceptor(SwView& rVw) :
44 m_pView(&rVw)
46 uno::Reference< frame::XFrame> xUnoFrame = m_pView->GetViewFrame()->GetFrame().GetFrameInterface();
47 m_xIntercepted = uno::Reference< frame::XDispatchProviderInterception>(xUnoFrame, uno::UNO_QUERY);
48 if(m_xIntercepted.is())
50 m_refCount++;
51 m_xIntercepted->registerDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
52 // this should make us the top-level dispatch-provider for the component, via a call to our
53 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
54 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
55 if (xInterceptedComponent.is())
56 xInterceptedComponent->addEventListener((lang::XEventListener*)this);
57 m_refCount--;
61 SwXDispatchProviderInterceptor::~SwXDispatchProviderInterceptor()
65 uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch(
66 const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags )
67 throw(uno::RuntimeException)
69 DispatchMutexLock_Impl aLock(*this);
70 uno::Reference< frame::XDispatch> xResult;
71 // create some dispatch ...
72 if(m_pView && aURL.Complete.startsWith(".uno:DataSourceBrowser/"))
74 if(!aURL.Complete.compareToAscii(cURLFormLetter) ||
75 !aURL.Complete.compareToAscii(cURLInsertContent) ||
76 !aURL.Complete.compareToAscii(cURLInsertColumns)||
77 !aURL.Complete.compareToAscii(cURLDocumentDataSource))
79 if(!m_xDispatch.is())
80 m_xDispatch = new SwXDispatch(*m_pView);
81 xResult = m_xDispatch;
85 // ask our slave provider
86 if (!xResult.is() && m_xSlaveDispatcher.is())
87 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
89 return xResult;
92 uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches(
93 const uno::Sequence< frame::DispatchDescriptor >& aDescripts ) throw(uno::RuntimeException)
95 DispatchMutexLock_Impl aLock(*this);
96 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
97 uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray();
98 const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
99 for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts)
101 *pReturn = queryDispatch(pDescripts->FeatureURL,
102 pDescripts->FrameName, pDescripts->SearchFlags);
104 return aReturn;
107 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider( )
108 throw(uno::RuntimeException)
110 DispatchMutexLock_Impl aLock(*this);
111 return m_xSlaveDispatcher;
114 void SwXDispatchProviderInterceptor::setSlaveDispatchProvider(
115 const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider ) throw(uno::RuntimeException)
117 DispatchMutexLock_Impl aLock(*this);
118 m_xSlaveDispatcher = xNewDispatchProvider;
121 uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider( )
122 throw(uno::RuntimeException)
124 DispatchMutexLock_Impl aLock(*this);
125 return m_xMasterDispatcher;
128 void SwXDispatchProviderInterceptor::setMasterDispatchProvider(
129 const uno::Reference< frame::XDispatchProvider >& xNewSupplier ) throw(uno::RuntimeException)
131 DispatchMutexLock_Impl aLock(*this);
132 m_xMasterDispatcher = xNewSupplier;
135 void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& )
136 throw(uno::RuntimeException)
138 DispatchMutexLock_Impl aLock(*this);
139 if (m_xIntercepted.is())
141 m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
142 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
143 if (xInterceptedComponent.is())
144 xInterceptedComponent->removeEventListener((lang::XEventListener*)this);
145 m_xDispatch = 0;
147 m_xIntercepted = NULL;
150 namespace
152 class theSwXDispatchProviderInterceptorUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXDispatchProviderInterceptorUnoTunnelId > {};
155 const uno::Sequence< sal_Int8 > & SwXDispatchProviderInterceptor::getUnoTunnelId()
157 return theSwXDispatchProviderInterceptorUnoTunnelId::get().getSeq();
160 sal_Int64 SwXDispatchProviderInterceptor::getSomething(
161 const uno::Sequence< sal_Int8 >& aIdentifier )
162 throw(uno::RuntimeException)
164 if( aIdentifier.getLength() == 16
165 && 0 == memcmp( getUnoTunnelId().getConstArray(),
166 aIdentifier.getConstArray(), 16 ) )
168 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
170 return 0;
173 void SwXDispatchProviderInterceptor::Invalidate()
175 DispatchMutexLock_Impl aLock(*this);
176 if (m_xIntercepted.is())
178 m_xIntercepted->releaseDispatchProviderInterceptor((frame::XDispatchProviderInterceptor*)this);
179 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
180 if (xInterceptedComponent.is())
181 xInterceptedComponent->removeEventListener((lang::XEventListener*)this);
182 m_xDispatch = 0;
184 m_xIntercepted = NULL;
185 m_pView = 0;
188 SwXDispatch::SwXDispatch(SwView& rVw) :
189 m_pView(&rVw),
190 m_bOldEnable(sal_False),
191 m_bListenerAdded(sal_False)
195 SwXDispatch::~SwXDispatch()
197 if(m_bListenerAdded && m_pView)
199 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
200 uno::Reference<view::XSelectionChangeListener> xThis = this;
201 xSupplier->removeSelectionChangeListener(xThis);
205 void SwXDispatch::dispatch(
206 const util::URL& aURL, const uno::Sequence< beans::PropertyValue >& aArgs ) throw(uno::RuntimeException)
208 if(!m_pView)
209 throw uno::RuntimeException();
210 SwWrtShell& rSh = m_pView->GetWrtShell();
211 SwNewDBMgr* pNewDBMgr = rSh.GetNewDBMgr();
212 if(!aURL.Complete.compareToAscii(cURLInsertContent))
214 ::svx::ODataAccessDescriptor aDescriptor(aArgs);
215 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor );
216 pNewDBMgr->MergeNew(aMergeDesc);
218 else if(!aURL.Complete.compareToAscii(cURLInsertColumns))
220 pNewDBMgr->InsertText(rSh, aArgs);
222 else if(!aURL.Complete.compareToAscii(cURLFormLetter))
224 SfxUsrAnyItem aDBProperties(FN_PARAM_DATABASE_PROPERTIES, uno::makeAny(aArgs));
225 m_pView->GetViewFrame()->GetDispatcher()->Execute(
226 FN_MAILMERGE_WIZARD,
227 SFX_CALLMODE_ASYNCHRON,
228 &aDBProperties, 0L);
230 else if(!aURL.Complete.compareToAscii(cURLDocumentDataSource))
232 OSL_FAIL("SwXDispatch::dispatch: this URL is not to be dispatched!");
234 else if(!aURL.Complete.compareToAscii(cInternalDBChangeNotification))
236 frame::FeatureStateEvent aEvent;
237 aEvent.IsEnabled = sal_True;
238 aEvent.Source = *(cppu::OWeakObject*)this;
240 const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc();
241 ::svx::ODataAccessDescriptor aDescriptor;
242 aDescriptor.setDataSource(rData.sDataSource);
243 aDescriptor[::svx::daCommand] <<= rData.sCommand;
244 aDescriptor[::svx::daCommandType] <<= rData.nCommandType;
246 aEvent.State <<= aDescriptor.createPropertyValueSequence();
247 aEvent.IsEnabled = !rData.sDataSource.isEmpty();
249 StatusListenerList::iterator aListIter = m_aListenerList.begin();
250 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
252 StatusStruct_Impl aStatus = *aListIter;
253 if(!aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource))
255 aEvent.FeatureURL = aStatus.aURL;
256 aStatus.xListener->statusChanged( aEvent );
260 else
261 throw uno::RuntimeException();
265 void SwXDispatch::addStatusListener(
266 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL ) throw(uno::RuntimeException)
268 if(!m_pView)
269 throw uno::RuntimeException();
270 ShellModes eMode = m_pView->GetShellMode();
271 sal_Bool bEnable = SHELL_MODE_TEXT == eMode ||
272 SHELL_MODE_LIST_TEXT == eMode ||
273 SHELL_MODE_TABLE_TEXT == eMode ||
274 SHELL_MODE_TABLE_LIST_TEXT == eMode;
276 m_bOldEnable = bEnable;
277 frame::FeatureStateEvent aEvent;
278 aEvent.IsEnabled = bEnable;
279 aEvent.Source = *(cppu::OWeakObject*)this;
280 aEvent.FeatureURL = aURL;
282 // one of the URLs requires a special state ....
283 if (!aURL.Complete.compareToAscii(cURLDocumentDataSource))
285 const SwDBData& rData = m_pView->GetWrtShell().GetDBDesc();
287 ::svx::ODataAccessDescriptor aDescriptor;
288 aDescriptor.setDataSource(rData.sDataSource);
289 aDescriptor[::svx::daCommand] <<= rData.sCommand;
290 aDescriptor[::svx::daCommandType] <<= rData.nCommandType;
292 aEvent.State <<= aDescriptor.createPropertyValueSequence();
293 aEvent.IsEnabled = !rData.sDataSource.isEmpty();
297 xControl->statusChanged( aEvent );
299 StatusListenerList::iterator aListIter = m_aListenerList.begin();
300 StatusStruct_Impl aStatus;
301 aStatus.xListener = xControl;
302 aStatus.aURL = aURL;
303 m_aListenerList.insert(aListIter, aStatus);
305 if(!m_bListenerAdded)
307 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
308 uno::Reference<view::XSelectionChangeListener> xThis = this;
309 xSupplier->addSelectionChangeListener(xThis);
310 m_bListenerAdded = sal_True;
314 void SwXDispatch::removeStatusListener(
315 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& ) throw(uno::RuntimeException)
317 StatusListenerList::iterator aListIter = m_aListenerList.begin();
318 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
320 StatusStruct_Impl aStatus = *aListIter;
321 if(aStatus.xListener.get() == xControl.get())
323 m_aListenerList.erase(aListIter);
324 break;
327 if(m_aListenerList.empty() && m_pView)
329 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
330 uno::Reference<view::XSelectionChangeListener> xThis = this;
331 xSupplier->removeSelectionChangeListener(xThis);
332 m_bListenerAdded = sal_False;
336 void SwXDispatch::selectionChanged( const lang::EventObject& ) throw(uno::RuntimeException)
338 ShellModes eMode = m_pView->GetShellMode();
339 sal_Bool bEnable = SHELL_MODE_TEXT == eMode ||
340 SHELL_MODE_LIST_TEXT == eMode ||
341 SHELL_MODE_TABLE_TEXT == eMode ||
342 SHELL_MODE_TABLE_LIST_TEXT == eMode;
343 if(bEnable != m_bOldEnable)
345 m_bOldEnable = bEnable;
346 frame::FeatureStateEvent aEvent;
347 aEvent.IsEnabled = bEnable;
348 aEvent.Source = *(cppu::OWeakObject*)this;
350 StatusListenerList::iterator aListIter = m_aListenerList.begin();
351 for(aListIter = m_aListenerList.begin(); aListIter != m_aListenerList.end(); ++aListIter)
353 StatusStruct_Impl aStatus = *aListIter;
354 aEvent.FeatureURL = aStatus.aURL;
355 if (0 != aStatus.aURL.Complete.compareToAscii(cURLDocumentDataSource))
356 // the document's data source does not depend on the selection, so it's state does not change here
357 aStatus.xListener->statusChanged( aEvent );
362 void SwXDispatch::disposing( const lang::EventObject& rSource ) throw(uno::RuntimeException)
364 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
365 uno::Reference<view::XSelectionChangeListener> xThis = this;
366 xSupplier->removeSelectionChangeListener(xThis);
367 m_bListenerAdded = sal_False;
369 lang::EventObject aObject;
370 aObject.Source = (cppu::OWeakObject*)this;
371 StatusListenerList::iterator aListIter = m_aListenerList.begin();
372 for(; aListIter != m_aListenerList.end(); ++aListIter)
374 StatusStruct_Impl aStatus = *aListIter;
375 aStatus.xListener->disposing(aObject);
377 m_pView = 0;
380 const sal_Char* SwXDispatch::GetDBChangeURL()
382 return cInternalDBChangeNotification;
385 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::DispatchMutexLock_Impl(
386 SwXDispatchProviderInterceptor& ) :
387 aGuard(Application::GetSolarMutex())
391 SwXDispatchProviderInterceptor::DispatchMutexLock_Impl::~DispatchMutexLock_Impl()
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */