LibreOffice Module sc (master) 1
dispuno.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 <sfx2/viewfrm.hxx>
22#include <svl/hint.hxx>
23#include <vcl/svapp.hxx>
24
25#include <com/sun/star/frame/XDispatchProviderInterception.hpp>
26#include <com/sun/star/view/XSelectionSupplier.hpp>
27#include <com/sun/star/sdb/CommandType.hpp>
28
29#include <dispuno.hxx>
30#include <tabvwsh.hxx>
31#include <dbdocfun.hxx>
32#include <dbdata.hxx>
33
34using namespace com::sun::star;
35
36const char cURLInsertColumns[] = ".uno:DataSourceBrowser/InsertColumns"; //data into text
37constexpr OUStringLiteral cURLDocDataSource = u".uno:DataSourceBrowser/DocumentDataSource";
38
39static uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( const SfxViewShell* pViewShell )
40{
41 if ( pViewShell )
42 {
43 SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
44 return uno::Reference<view::XSelectionSupplier>( rViewFrame.GetFrame().GetController(), uno::UNO_QUERY );
45 }
46 return uno::Reference<view::XSelectionSupplier>();
47}
48
50 pViewShell( pViewSh )
51{
52 if ( !pViewShell )
53 return;
54
55 m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame().GetFrame().GetFrameInterface(), uno::UNO_QUERY));
56 if (m_xIntercepted.is())
57 {
58 osl_atomic_increment( &m_refCount );
59
60 m_xIntercepted->registerDispatchProviderInterceptor(
61 static_cast<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 a fallback for requests we (i.e. our master) cannot fulfill
64 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
65 if (xInterceptedComponent.is())
66 xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
67
68 osl_atomic_decrement( &m_refCount );
69 }
70
72}
73
75{
76 if (pViewShell)
78}
79
81{
82 if ( rHint.GetId() == SfxHintId::Dying )
83 pViewShell = nullptr;
84}
85
86// XDispatchProvider
87
88uno::Reference<frame::XDispatch> SAL_CALL ScDispatchProviderInterceptor::queryDispatch(
89 const util::URL& aURL, const OUString& aTargetFrameName,
90 sal_Int32 nSearchFlags )
91{
92 SolarMutexGuard aGuard;
93
94 uno::Reference<frame::XDispatch> xResult;
95 // create some dispatch ...
96 if ( pViewShell && (
97 aURL.Complete == cURLInsertColumns ||
98 aURL.Complete == cURLDocDataSource ) )
99 {
100 if (!m_xMyDispatch.is())
102 xResult = m_xMyDispatch;
103 }
104
105 // ask our slave provider
106 if (!xResult.is() && m_xSlaveDispatcher.is())
107 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
108
109 return xResult;
110}
111
112uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
114 const uno::Sequence<frame::DispatchDescriptor>& aDescripts )
115{
116 SolarMutexGuard aGuard;
117
118 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
119 std::transform(aDescripts.begin(), aDescripts.end(), aReturn.getArray(),
120 [this](const frame::DispatchDescriptor& rDescr) -> uno::Reference<frame::XDispatch> {
121 return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); });
122 return aReturn;
123}
124
125// XDispatchProviderInterceptor
126
127uno::Reference<frame::XDispatchProvider> SAL_CALL
129{
130 SolarMutexGuard aGuard;
131 return m_xSlaveDispatcher;
132}
133
135 const uno::Reference<frame::XDispatchProvider>& xNewDispatchProvider )
136{
137 SolarMutexGuard aGuard;
138 m_xSlaveDispatcher.set(xNewDispatchProvider);
139}
140
141uno::Reference<frame::XDispatchProvider> SAL_CALL
143{
144 SolarMutexGuard aGuard;
145 return m_xMasterDispatcher;
146}
147
149 const uno::Reference<frame::XDispatchProvider>& xNewSupplier )
150{
151 SolarMutexGuard aGuard;
152 m_xMasterDispatcher.set(xNewSupplier);
153}
154
155// XEventListener
156
157void SAL_CALL ScDispatchProviderInterceptor::disposing( const lang::EventObject& /* Source */ )
158{
159 SolarMutexGuard aGuard;
160
161 if (m_xIntercepted.is())
162 {
163 m_xIntercepted->releaseDispatchProviderInterceptor(
164 static_cast<frame::XDispatchProviderInterceptor*>(this));
165 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
166 if (xInterceptedComponent.is())
167 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
168
169 m_xMyDispatch = nullptr;
170 }
171 m_xIntercepted = nullptr;
172}
173
175 pViewShell( pViewSh ),
176 bListeningToView( false )
177{
178 if (pViewShell)
180}
181
183{
184 if (pViewShell)
186
188 {
189 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
190 if ( xSupplier.is() )
191 xSupplier->removeSelectionChangeListener(this);
192 }
193}
194
196{
197 if ( rHint.GetId() == SfxHintId::Dying )
198 pViewShell = nullptr;
199}
200
201// XDispatch
202
203void SAL_CALL ScDispatch::dispatch( const util::URL& aURL,
204 const uno::Sequence<beans::PropertyValue>& aArgs )
205{
206 SolarMutexGuard aGuard;
207
208 bool bDone = false;
209 if ( pViewShell && aURL.Complete == cURLInsertColumns )
210 {
211 ScViewData& rViewData = pViewShell->GetViewData();
212 ScAddress aPos( rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() );
213
214 ScDBDocFunc aFunc( *rViewData.GetDocShell() );
215 aFunc.DoImportUno( aPos, aArgs );
216 bDone = true;
217 }
218 // cURLDocDataSource is never dispatched
219
220 if (!bDone)
221 throw uno::RuntimeException();
222}
223
224static void lcl_FillDataSource( frame::FeatureStateEvent& rEvent, const ScImportParam& rParam )
225{
226 rEvent.IsEnabled = rParam.bImport;
227
228 svx::ODataAccessDescriptor aDescriptor;
229 if ( rParam.bImport )
230 {
231 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
232 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
234
235 aDescriptor.setDataSource(rParam.aDBName);
238 }
239 else
240 {
241 // descriptor has to be complete anyway
242
243 aDescriptor[svx::DataAccessDescriptorProperty::DataSource] <<= OUString();
244 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= OUString();
246 }
247 rEvent.State <<= aDescriptor.createPropertyValueSequence();
248}
249
251 const uno::Reference<frame::XStatusListener>& xListener,
252 const util::URL& aURL)
253{
254 SolarMutexGuard aGuard;
255
256 if (!pViewShell)
257 throw uno::RuntimeException();
258
259 // initial state
260 frame::FeatureStateEvent aEvent;
261 aEvent.IsEnabled = true;
262 aEvent.Source = getXWeak();
263 aEvent.FeatureURL = aURL;
264
265 if ( aURL.Complete == cURLDocDataSource )
266 {
267 aDataSourceListeners.emplace_back( xListener );
268
269 if (!bListeningToView)
270 {
271 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
272 if ( xSupplier.is() )
273 xSupplier->addSelectionChangeListener(this);
274 bListeningToView = true;
275 }
276
277 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
278 if ( pDBData )
279 pDBData->GetImportParam( aLastImport );
280 lcl_FillDataSource( aEvent, aLastImport ); // modifies State, IsEnabled
281 }
283
284 xListener->statusChanged( aEvent );
285}
286
288 const uno::Reference<frame::XStatusListener>& xListener,
289 const util::URL& aURL )
290{
291 SolarMutexGuard aGuard;
292
293 if ( aURL.Complete != cURLDocDataSource )
294 return;
295
296 sal_uInt16 nCount = aDataSourceListeners.size();
297 for ( sal_uInt16 n=nCount; n--; )
298 {
299 uno::Reference<frame::XStatusListener>& rObj = aDataSourceListeners[n];
300 if ( rObj == xListener )
301 {
303 break;
304 }
305 }
306
307 if ( aDataSourceListeners.empty() && pViewShell )
308 {
309 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
310 if ( xSupplier.is() )
311 xSupplier->removeSelectionChangeListener(this);
312 bListeningToView = false;
313 }
314}
315
316// XSelectionChangeListener
317
318void SAL_CALL ScDispatch::selectionChanged( const css::lang::EventObject& /* aEvent */ )
319{
320 // currently only called for URL cURLDocDataSource
321
322 if ( !pViewShell )
323 return;
324
325 ScImportParam aNewImport;
326 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
327 if ( pDBData )
328 pDBData->GetImportParam( aNewImport );
329
330 // notify listeners only if data source has changed
331 if ( !(aNewImport.bImport != aLastImport.bImport ||
332 aNewImport.aDBName != aLastImport.aDBName ||
333 aNewImport.aStatement != aLastImport.aStatement ||
334 aNewImport.bSql != aLastImport.bSql ||
335 aNewImport.nType != aLastImport.nType) )
336 return;
337
338 frame::FeatureStateEvent aEvent;
339 aEvent.Source = getXWeak();
340 aEvent.FeatureURL.Complete = cURLDocDataSource;
341
342 lcl_FillDataSource( aEvent, aNewImport ); // modifies State, IsEnabled
343
344 for (uno::Reference<frame::XStatusListener> & xDataSourceListener : aDataSourceListeners)
345 xDataSourceListener->statusChanged( aEvent );
346
347 aLastImport = aNewImport;
348}
349
350// XEventListener
351
352void SAL_CALL ScDispatch::disposing( const css::lang::EventObject& rSource )
353{
354 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
355 xSupplier->removeSelectionChangeListener(this);
356 bListeningToView = false;
357
358 lang::EventObject aEvent;
359 aEvent.Source = getXWeak();
360 for (uno::Reference<frame::XStatusListener> & xDataSourceListener : aDataSourceListeners)
361 xDataSourceListener->disposing( aEvent );
362
363 pViewShell = nullptr;
364}
365
366/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
void GetImportParam(ScImportParam &rImportParam) const
Definition: dbdata.cxx:478
void DoImportUno(const ScAddress &rPos, const css::uno::Sequence< css::beans::PropertyValue > &aArgs)
Definition: dbdocimp.cxx:108
ScDBData * GetDBData(bool bMarkArea=true, ScGetDBMode eMode=SC_DB_MAKE, ScGetDBSelection eSel=ScGetDBSelection::Keep)
Definition: dbfunc.cxx:81
virtual void SAL_CALL setMasterDispatchProvider(const css::uno::Reference< css::frame::XDispatchProvider > &xNewSupplier) override
Definition: dispuno.cxx:148
ScTabViewShell * pViewShell
Definition: dispuno.hxx:36
virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches(const css::uno::Sequence< css::frame::DispatchDescriptor > &aDescripts) override
Definition: dispuno.cxx:113
css::uno::Reference< css::frame::XDispatchProvider > m_xMasterDispatcher
Definition: dispuno.hxx:43
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
XEventListener.
Definition: dispuno.cxx:157
virtual ~ScDispatchProviderInterceptor() override
Definition: dispuno.cxx:74
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getSlaveDispatchProvider() override
XDispatchProviderInterceptor.
Definition: dispuno.cxx:128
virtual void SAL_CALL setSlaveDispatchProvider(const css::uno::Reference< css::frame::XDispatchProvider > &xNewDispatchProvider) override
Definition: dispuno.cxx:134
css::uno::Reference< css::frame::XDispatch > m_xMyDispatch
own dispatch
Definition: dispuno.hxx:46
ScDispatchProviderInterceptor(ScTabViewShell *pViewSh)
Definition: dispuno.cxx:49
virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(const css::util::URL &aURL, const OUString &aTargetFrameName, sal_Int32 nSearchFlags) override
XDispatchProvider.
Definition: dispuno.cxx:88
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getMasterDispatchProvider() override
Definition: dispuno.cxx:142
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: dispuno.cxx:80
css::uno::Reference< css::frame::XDispatchProvider > m_xSlaveDispatcher
chaining
Definition: dispuno.hxx:42
css::uno::Reference< css::frame::XDispatchProviderInterception > m_xIntercepted
the component which's dispatches we're intercepting
Definition: dispuno.hxx:39
ScDispatch(ScTabViewShell *pViewSh)
Definition: dispuno.cxx:174
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
Definition: dispuno.cxx:250
bool bListeningToView
Definition: dispuno.hxx:86
ScTabViewShell * pViewShell
Definition: dispuno.hxx:82
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
Definition: dispuno.cxx:287
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
XEventListener.
Definition: dispuno.cxx:352
virtual void SAL_CALL selectionChanged(const css::lang::EventObject &aEvent) override
XSelectionChangeListener.
Definition: dispuno.cxx:318
ScImportParam aLastImport
Definition: dispuno.hxx:85
virtual void SAL_CALL dispatch(const css::util::URL &aURL, const css::uno::Sequence< css::beans::PropertyValue > &aArgs) override
XDispatch.
Definition: dispuno.cxx:203
std::vector< css::uno::Reference< css::frame::XStatusListener > > aDataSourceListeners
Definition: dispuno.hxx:84
virtual ~ScDispatch() override
Definition: dispuno.cxx:182
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: dispuno.cxx:195
ScViewData & GetViewData()
Definition: tabview.hxx:344
SCTAB GetTabNo() const
Definition: viewdata.hxx:395
ScDocShell * GetDocShell() const
Definition: viewdata.hxx:354
SCROW GetCurY() const
Definition: viewdata.hxx:402
SCCOL GetCurX() const
Definition: viewdata.hxx:401
const css::uno::Reference< css::frame::XFrame > & GetFrameInterface() const
css::uno::Reference< css::frame::XController > GetController() const
SfxHintId GetId() const
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
void EndListening(SfxBroadcaster &rBroadcaster, bool bRemoveAllDuplicates=false)
SfxFrame & GetFrame() const
SfxViewFrame & GetViewFrame() const
css::uno::Sequence< css::beans::PropertyValue > const & createPropertyValueSequence()
void setDataSource(const OUString &_sDataSourceNameOrLocation)
int nCount
URL aURL
static void lcl_FillDataSource(frame::FeatureStateEvent &rEvent, const ScImportParam &rParam)
Definition: dispuno.cxx:224
const char cURLInsertColumns[]
Definition: dispuno.cxx:36
static uno::Reference< view::XSelectionSupplier > lcl_GetSelectionSupplier(const SfxViewShell *pViewShell)
Definition: dispuno.cxx:39
constexpr OUStringLiteral cURLDocDataSource
Definition: dispuno.cxx:37
ULONG m_refCount
float u
@ ScDbQuery
Definition: global.hxx:421
@ SC_DB_OLD
don't create
Definition: global.hxx:386
sal_Int64 n
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
OUString aStatement
Definition: global.hxx:447
sal_uInt8 nType
Definition: global.hxx:450
OUString aDBName
Definition: global.hxx:446
bool bImport
Definition: global.hxx:445
@ QUERY
Definition: xmldpimp.hxx:44
@ TABLE
Definition: xmldpimp.hxx:43