LibreOffice Module sw (master) 1
unodispatch.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_features.h>
21#include <config_fuzzers.h>
22
23#include <com/sun/star/frame/XFrame.hpp>
24#include <com/sun/star/view/XSelectionSupplier.hpp>
25
26#include <sfx2/viewfrm.hxx>
27#include <sfx2/dispatch.hxx>
30#include <osl/diagnose.h>
31#include <unodispatch.hxx>
32#include <view.hxx>
33#include <cmdid.h>
34#include <wrtsh.hxx>
35#include <dbmgr.hxx>
36
37using namespace ::com::sun::star;
38
39const char cURLFormLetter[] = ".uno:DataSourceBrowser/FormLetter";
40const char cURLInsertContent[] = ".uno:DataSourceBrowser/InsertContent";//data into fields
41const char cURLInsertColumns[] = ".uno:DataSourceBrowser/InsertColumns";//data into text
42const char cURLDocumentDataSource[] = ".uno:DataSourceBrowser/DocumentDataSource";//current data source of the document
43const char cInternalDBChangeNotification[] = ".uno::Writer/DataSourceChanged";
44
46 m_pView(&rVw)
47{
48 uno::Reference< frame::XFrame> xUnoFrame = m_pView->GetViewFrame()->GetFrame().GetFrameInterface();
49 m_xIntercepted.set(xUnoFrame, uno::UNO_QUERY);
50 if(m_xIntercepted.is())
51 {
52 osl_atomic_increment(&m_refCount);
53 m_xIntercepted->registerDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
54 // this should make us the top-level dispatch-provider for the component, via a call to our
55 // setDispatchProvider we should have got a fallback for requests we (i.e. our master) cannot fulfill
56 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
57 if (xInterceptedComponent.is())
58 xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
59 osl_atomic_decrement(&m_refCount);
60 }
61}
62
64{
65}
66
67uno::Reference< frame::XDispatch > SwXDispatchProviderInterceptor::queryDispatch(
68 const util::URL& aURL, const OUString& aTargetFrameName, sal_Int32 nSearchFlags )
69{
71 uno::Reference< frame::XDispatch> xResult;
72 // create some dispatch ...
73 if(m_pView && aURL.Complete.startsWith(".uno:DataSourceBrowser/"))
74 {
75 if(aURL.Complete == cURLFormLetter ||
76 aURL.Complete == cURLInsertContent ||
77 aURL.Complete == cURLInsertColumns ||
78 aURL.Complete == cURLDocumentDataSource)
79 {
80 if(!m_xDispatch.is())
82 xResult = m_xDispatch;
83 }
84 }
85
86 // ask our slave provider
87 if (!xResult.is() && m_xSlaveDispatcher.is())
88 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
89
90 return xResult;
91}
92
94{
95 uno::Sequence<OUString> aRet =
96 {
97 OUString(".uno:DataSourceBrowser/*")
98 };
99
100 return aRet;
101}
102
103uno::Sequence< uno::Reference< frame::XDispatch > > SwXDispatchProviderInterceptor::queryDispatches(
104 const uno::Sequence< frame::DispatchDescriptor >& aDescripts )
105{
107 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
108 std::transform(aDescripts.begin(), aDescripts.end(), aReturn.getArray(),
109 [this](const frame::DispatchDescriptor& rDescr) -> uno::Reference<frame::XDispatch> {
110 return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); });
111 return aReturn;
112}
113
114uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getSlaveDispatchProvider( )
115{
117 return m_xSlaveDispatcher;
118}
119
121 const uno::Reference< frame::XDispatchProvider >& xNewDispatchProvider )
122{
124 m_xSlaveDispatcher = xNewDispatchProvider;
125}
126
127uno::Reference< frame::XDispatchProvider > SwXDispatchProviderInterceptor::getMasterDispatchProvider( )
128{
130 return m_xMasterDispatcher;
131}
132
134 const uno::Reference< frame::XDispatchProvider >& xNewSupplier )
135{
137 m_xMasterDispatcher = xNewSupplier;
138}
139
140void SwXDispatchProviderInterceptor::disposing( const lang::EventObject& )
141{
143 if (m_xIntercepted.is())
144 {
145 m_xIntercepted->releaseDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
146 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
147 if (xInterceptedComponent.is())
148 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
149 m_xDispatch = nullptr;
150 }
151 m_xIntercepted = nullptr;
152}
153
154const uno::Sequence< sal_Int8 > & SwXDispatchProviderInterceptor::getUnoTunnelId()
155{
156 static const comphelper::UnoIdInit theSwXDispatchProviderInterceptorUnoTunnelId;
157 return theSwXDispatchProviderInterceptorUnoTunnelId.getSeq();
158}
159
161 const uno::Sequence< sal_Int8 >& aIdentifier )
162{
163 return comphelper::getSomethingImpl(aIdentifier, this);
164}
165
167{
169 if (m_xIntercepted.is())
170 {
171 m_xIntercepted->releaseDispatchProviderInterceptor(static_cast<frame::XDispatchProviderInterceptor*>(this));
172 uno::Reference< lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
173 if (xInterceptedComponent.is())
174 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
175 m_xDispatch = nullptr;
176 }
177 m_xIntercepted = nullptr;
178 m_pView = nullptr;
179}
180
182 m_pView(&rVw),
183 m_bOldEnable(false),
184 m_bListenerAdded(false)
185{
186}
187
189{
191 {
192 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
193 uno::Reference<view::XSelectionChangeListener> xThis = this;
194 xSupplier->removeSelectionChangeListener(xThis);
195 }
196}
197
198void SwXDispatch::dispatch(const util::URL& aURL,
199 const uno::Sequence< beans::PropertyValue >& aArgs)
200{
201 if(!m_pView)
202 throw uno::RuntimeException();
203#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS
204 (void) aArgs;
205 if (false)
206 {
207 }
208#else
210 SwDBManager* pDBManager = rSh.GetDBManager();
211 if(aURL.Complete == cURLInsertContent)
212 {
213 svx::ODataAccessDescriptor aDescriptor(aArgs);
214 SwMergeDescriptor aMergeDesc( DBMGR_MERGE, rSh, aDescriptor );
215 pDBManager->Merge(aMergeDesc);
216 }
217 else if(aURL.Complete == cURLInsertColumns)
218 {
219 SwDBManager::InsertText(rSh, aArgs);
220 }
221 else if(aURL.Complete == cURLFormLetter)
222 {
226 SfxCallMode::ASYNCHRON,
227 { &aDBProperties });
228 }
229#endif
230 else if(aURL.Complete == cURLDocumentDataSource)
231 {
232 OSL_FAIL("SwXDispatch::dispatch: this URL is not to be dispatched!");
233 }
234 else if(aURL.Complete == cInternalDBChangeNotification)
235 {
236 frame::FeatureStateEvent aEvent;
237 aEvent.Source = *static_cast<cppu::OWeakObject*>(this);
238
240 svx::ODataAccessDescriptor aDescriptor;
241 aDescriptor.setDataSource(rData.sDataSource);
242 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= rData.sCommand;
243 aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= rData.nCommandType;
244
245 aEvent.State <<= aDescriptor.createPropertyValueSequence();
246 aEvent.IsEnabled = !rData.sDataSource.isEmpty();
247
248 // calls to statusChanged may call addStatusListener or removeStatusListener
249 // so copy m_aStatusListenerVector on stack
250 auto copyStatusListenerVector = m_aStatusListenerVector;
251 for (auto & status : copyStatusListenerVector)
252 {
253 if(status.aURL.Complete == cURLDocumentDataSource)
254 {
255 aEvent.FeatureURL = status.aURL;
256 status.xListener->statusChanged( aEvent );
257 }
258 }
259 }
260 else
261 throw uno::RuntimeException();
262
263}
264
266 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& aURL )
267{
268 if(!m_pView)
269 throw uno::RuntimeException();
271 bool bEnable = ShellMode::Text == eMode ||
275
276 m_bOldEnable = bEnable;
277 frame::FeatureStateEvent aEvent;
278 aEvent.IsEnabled = bEnable;
279 aEvent.Source = *static_cast<cppu::OWeakObject*>(this);
280 aEvent.FeatureURL = aURL;
281
282 // one of the URLs requires a special state...
283 if (aURL.Complete == cURLDocumentDataSource)
284 {
286
287 svx::ODataAccessDescriptor aDescriptor;
288 aDescriptor.setDataSource(rData.sDataSource);
289 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= rData.sCommand;
290 aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= rData.nCommandType;
291
292 aEvent.State <<= aDescriptor.createPropertyValueSequence();
293 aEvent.IsEnabled = !rData.sDataSource.isEmpty();
294 }
295
296 xControl->statusChanged( aEvent );
297
298 StatusStruct_Impl aStatus;
299 aStatus.xListener = xControl;
300 aStatus.aURL = aURL;
301 m_aStatusListenerVector.emplace_back(aStatus);
302
304 {
305 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
306 uno::Reference<view::XSelectionChangeListener> xThis = this;
307 xSupplier->addSelectionChangeListener(xThis);
308 m_bListenerAdded = true;
309 }
310}
311
313 const uno::Reference< frame::XStatusListener >& xControl, const util::URL& )
314{
316 std::remove_if(m_aStatusListenerVector.begin(), m_aStatusListenerVector.end(),
317 [&](const StatusStruct_Impl& status) { return status.xListener.get() == xControl.get(); }),
319 if(m_aStatusListenerVector.empty() && m_pView)
320 {
321 uno::Reference<view::XSelectionSupplier> xSupplier = m_pView->GetUNOObject();
322 uno::Reference<view::XSelectionChangeListener> xThis = this;
323 xSupplier->removeSelectionChangeListener(xThis);
324 m_bListenerAdded = false;
325 }
326}
327
328void SwXDispatch::selectionChanged( const lang::EventObject& )
329{
331 bool bEnable = ShellMode::Text == eMode ||
335 if(bEnable == m_bOldEnable)
336 return;
337
338 m_bOldEnable = bEnable;
339 frame::FeatureStateEvent aEvent;
340 aEvent.IsEnabled = bEnable;
341 aEvent.Source = *static_cast<cppu::OWeakObject*>(this);
342
343 // calls to statusChanged may call addStatusListener or removeStatusListener
344 // so copy m_aStatusListenerVector on stack
345 auto copyStatusListenerVector = m_aStatusListenerVector;
346 for (auto & status : copyStatusListenerVector)
347 {
348 aEvent.FeatureURL = status.aURL;
349 if (status.aURL.Complete != cURLDocumentDataSource)
350 // the document's data source does not depend on the selection, so it's state does not change here
351 status.xListener->statusChanged( aEvent );
352 }
353}
354
355void SwXDispatch::disposing( const lang::EventObject& rSource )
356{
357 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
358 uno::Reference<view::XSelectionChangeListener> xThis = this;
359 xSupplier->removeSelectionChangeListener(xThis);
360 m_bListenerAdded = false;
361
362 lang::EventObject aObject;
363 aObject.Source = static_cast<cppu::OWeakObject*>(this);
364 // calls to statusChanged may call addStatusListener or removeStatusListener
365 // so copy m_aStatusListenerVector on stack
366 auto copyStatusListenerVector = m_aStatusListenerVector;
367 for (auto & status : copyStatusListenerVector)
368 {
369 status.xListener->disposing(aObject);
370 }
371 m_pView = nullptr;
372}
373
375{
377}
378
380{
381}
382
384{
385}
386
387/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
const SfxPoolItem * ExecuteList(sal_uInt16 nSlot, SfxCallMode nCall, std::initializer_list< SfxPoolItem const * > args, std::initializer_list< SfxPoolItem const * > internalargs=std::initializer_list< SfxPoolItem const * >())
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
SfxDispatcher * GetDispatcher()
SfxFrame & GetFrame() const
SfxViewFrame * GetViewFrame() const
bool Merge(const SwMergeDescriptor &rMergeDesc)
Merging of data records into fields.
Definition: dbmgr.cxx:417
static void InsertText(SwWrtShell &rSh, const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
Definition: dbmgr.cxx:3017
SwDBManager * GetDBManager() const
For evaluation of DB fields (new DB-manager).
Definition: edfld.cxx:328
SwDBData const & GetDBData() const
Database information.
Definition: edfld.cxx:291
Definition: view.hxx:145
SwWrtShell & GetWrtShell() const
Definition: view.hxx:413
css::view::XSelectionSupplier * GetUNOObject()
Definition: view0.cxx:110
ShellMode GetShellMode() const
Definition: view0.cxx:105
Used by the UI to modify the document model.
Definition: wrtsh.hxx:97
virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches(const css::uno::Sequence< css::frame::DispatchDescriptor > &aDescripts) override
virtual ~SwXDispatchProviderInterceptor() override
Definition: unodispatch.cxx:63
css::uno::Reference< css::frame::XDispatchProviderInterception > m_xIntercepted
Definition: unodispatch.hxx:55
SwXDispatchProviderInterceptor(SwView &rView)
Definition: unodispatch.cxx:45
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &aIdentifier) override
virtual void SAL_CALL setMasterDispatchProvider(const css::uno::Reference< css::frame::XDispatchProvider > &xNewSupplier) override
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
css::uno::Reference< css::frame::XDispatch > m_xDispatch
Definition: unodispatch.hxx:61
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
virtual void SAL_CALL setSlaveDispatchProvider(const css::uno::Reference< css::frame::XDispatchProvider > &xNewDispatchProvider) override
css::uno::Reference< css::frame::XDispatchProvider > m_xMasterDispatcher
Definition: unodispatch.hxx:59
css::uno::Reference< css::frame::XDispatchProvider > m_xSlaveDispatcher
Definition: unodispatch.hxx:58
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getMasterDispatchProvider() override
virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(const css::util::URL &aURL, const OUString &aTargetFrameName, sal_Int32 nSearchFlags) override
Definition: unodispatch.cxx:67
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getSlaveDispatchProvider() override
virtual css::uno::Sequence< OUString > SAL_CALL getInterceptedURLs() override
Definition: unodispatch.cxx:93
bool m_bListenerAdded
static const char * GetDBChangeURL()
virtual void SAL_CALL selectionChanged(const css::lang::EventObject &aEvent) override
virtual ~SwXDispatch() override
virtual void SAL_CALL dispatch(const css::util::URL &aURL, const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
SwView * m_pView
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
std::vector< StatusStruct_Impl > m_aStatusListenerVector
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
SwXDispatch(SwView &rView)
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
const css::uno::Sequence< sal_Int8 > & getSeq() const
css::uno::Sequence< css::beans::PropertyValue > const & createPropertyValueSequence()
void setDataSource(const OUString &_sDataSourceNameOrLocation)
#define FN_PARAM_DATABASE_PROPERTIES
Definition: cmdid.h:829
#define FN_MAILMERGE_WIZARD
Definition: cmdid.h:238
@ DBMGR_MERGE
Data records in fields.
Definition: dbmgr.hxx:88
URL aURL
ULONG m_refCount
Mutex aLock
Mode eMode
const ContentProperties & rData
sal_Int64 getSomethingImpl(const css::uno::Sequence< sal_Int8 > &rId, T *pThis, FallbackToGetSomethingOf< Base >={})
css::util::URL aURL
Definition: unodispatch.hxx:96
css::uno::Reference< css::frame::XStatusListener > xListener
Definition: unodispatch.hxx:95
const char cURLInsertContent[]
Definition: unodispatch.cxx:40
const char cURLFormLetter[]
Definition: unodispatch.cxx:39
const char cURLInsertColumns[]
Definition: unodispatch.cxx:41
const char cInternalDBChangeNotification[]
Definition: unodispatch.cxx:43
const char cURLDocumentDataSource[]
Definition: unodispatch.cxx:42
ShellMode
Definition: view.hxx:86