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* pViewFrame = pViewShell->GetViewFrame();
44 if (pViewFrame)
45 {
46 return uno::Reference<view::XSelectionSupplier>( pViewFrame->GetFrame().GetController(), uno::UNO_QUERY );
47 }
48 }
49 return uno::Reference<view::XSelectionSupplier>();
50}
51
53 pViewShell( pViewSh )
54{
55 if ( !pViewShell )
56 return;
57
58 m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY));
59 if (m_xIntercepted.is())
60 {
61 osl_atomic_increment( &m_refCount );
62
63 m_xIntercepted->registerDispatchProviderInterceptor(
64 static_cast<frame::XDispatchProviderInterceptor*>(this));
65 // this should make us the top-level dispatch-provider for the component, via a call to our
66 // setDispatchProvider we should have got a fallback for requests we (i.e. our master) cannot fulfill
67 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
68 if (xInterceptedComponent.is())
69 xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
70
71 osl_atomic_decrement( &m_refCount );
72 }
73
75}
76
78{
79 if (pViewShell)
81}
82
84{
85 if ( rHint.GetId() == SfxHintId::Dying )
86 pViewShell = nullptr;
87}
88
89// XDispatchProvider
90
91uno::Reference<frame::XDispatch> SAL_CALL ScDispatchProviderInterceptor::queryDispatch(
92 const util::URL& aURL, const OUString& aTargetFrameName,
93 sal_Int32 nSearchFlags )
94{
95 SolarMutexGuard aGuard;
96
97 uno::Reference<frame::XDispatch> xResult;
98 // create some dispatch ...
99 if ( pViewShell && (
100 aURL.Complete == cURLInsertColumns ||
101 aURL.Complete == cURLDocDataSource ) )
102 {
103 if (!m_xMyDispatch.is())
105 xResult = m_xMyDispatch;
106 }
107
108 // ask our slave provider
109 if (!xResult.is() && m_xSlaveDispatcher.is())
110 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
111
112 return xResult;
113}
114
115uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
117 const uno::Sequence<frame::DispatchDescriptor>& aDescripts )
118{
119 SolarMutexGuard aGuard;
120
121 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
122 std::transform(aDescripts.begin(), aDescripts.end(), aReturn.getArray(),
123 [this](const frame::DispatchDescriptor& rDescr) -> uno::Reference<frame::XDispatch> {
124 return queryDispatch(rDescr.FeatureURL, rDescr.FrameName, rDescr.SearchFlags); });
125 return aReturn;
126}
127
128// XDispatchProviderInterceptor
129
130uno::Reference<frame::XDispatchProvider> SAL_CALL
132{
133 SolarMutexGuard aGuard;
134 return m_xSlaveDispatcher;
135}
136
138 const uno::Reference<frame::XDispatchProvider>& xNewDispatchProvider )
139{
140 SolarMutexGuard aGuard;
141 m_xSlaveDispatcher.set(xNewDispatchProvider);
142}
143
144uno::Reference<frame::XDispatchProvider> SAL_CALL
146{
147 SolarMutexGuard aGuard;
148 return m_xMasterDispatcher;
149}
150
152 const uno::Reference<frame::XDispatchProvider>& xNewSupplier )
153{
154 SolarMutexGuard aGuard;
155 m_xMasterDispatcher.set(xNewSupplier);
156}
157
158// XEventListener
159
160void SAL_CALL ScDispatchProviderInterceptor::disposing( const lang::EventObject& /* Source */ )
161{
162 SolarMutexGuard aGuard;
163
164 if (m_xIntercepted.is())
165 {
166 m_xIntercepted->releaseDispatchProviderInterceptor(
167 static_cast<frame::XDispatchProviderInterceptor*>(this));
168 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
169 if (xInterceptedComponent.is())
170 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
171
172 m_xMyDispatch = nullptr;
173 }
174 m_xIntercepted = nullptr;
175}
176
178 pViewShell( pViewSh ),
179 bListeningToView( false )
180{
181 if (pViewShell)
183}
184
186{
187 if (pViewShell)
189
191 {
192 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
193 if ( xSupplier.is() )
194 xSupplier->removeSelectionChangeListener(this);
195 }
196}
197
199{
200 if ( rHint.GetId() == SfxHintId::Dying )
201 pViewShell = nullptr;
202}
203
204// XDispatch
205
206void SAL_CALL ScDispatch::dispatch( const util::URL& aURL,
207 const uno::Sequence<beans::PropertyValue>& aArgs )
208{
209 SolarMutexGuard aGuard;
210
211 bool bDone = false;
212 if ( pViewShell && aURL.Complete == cURLInsertColumns )
213 {
214 ScViewData& rViewData = pViewShell->GetViewData();
215 ScAddress aPos( rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() );
216
217 ScDBDocFunc aFunc( *rViewData.GetDocShell() );
218 aFunc.DoImportUno( aPos, aArgs );
219 bDone = true;
220 }
221 // cURLDocDataSource is never dispatched
222
223 if (!bDone)
224 throw uno::RuntimeException();
225}
226
227static void lcl_FillDataSource( frame::FeatureStateEvent& rEvent, const ScImportParam& rParam )
228{
229 rEvent.IsEnabled = rParam.bImport;
230
231 svx::ODataAccessDescriptor aDescriptor;
232 if ( rParam.bImport )
233 {
234 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
235 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
237
238 aDescriptor.setDataSource(rParam.aDBName);
241 }
242 else
243 {
244 // descriptor has to be complete anyway
245
246 aDescriptor[svx::DataAccessDescriptorProperty::DataSource] <<= OUString();
247 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= OUString();
249 }
250 rEvent.State <<= aDescriptor.createPropertyValueSequence();
251}
252
254 const uno::Reference<frame::XStatusListener>& xListener,
255 const util::URL& aURL)
256{
257 SolarMutexGuard aGuard;
258
259 if (!pViewShell)
260 throw uno::RuntimeException();
261
262 // initial state
263 frame::FeatureStateEvent aEvent;
264 aEvent.IsEnabled = true;
265 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
266 aEvent.FeatureURL = aURL;
267
268 if ( aURL.Complete == cURLDocDataSource )
269 {
270 aDataSourceListeners.emplace_back( xListener );
271
272 if (!bListeningToView)
273 {
274 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
275 if ( xSupplier.is() )
276 xSupplier->addSelectionChangeListener(this);
277 bListeningToView = true;
278 }
279
280 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
281 if ( pDBData )
282 pDBData->GetImportParam( aLastImport );
283 lcl_FillDataSource( aEvent, aLastImport ); // modifies State, IsEnabled
284 }
286
287 xListener->statusChanged( aEvent );
288}
289
291 const uno::Reference<frame::XStatusListener>& xListener,
292 const util::URL& aURL )
293{
294 SolarMutexGuard aGuard;
295
296 if ( aURL.Complete != cURLDocDataSource )
297 return;
298
299 sal_uInt16 nCount = aDataSourceListeners.size();
300 for ( sal_uInt16 n=nCount; n--; )
301 {
302 uno::Reference<frame::XStatusListener>& rObj = aDataSourceListeners[n];
303 if ( rObj == xListener )
304 {
306 break;
307 }
308 }
309
310 if ( aDataSourceListeners.empty() && pViewShell )
311 {
312 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
313 if ( xSupplier.is() )
314 xSupplier->removeSelectionChangeListener(this);
315 bListeningToView = false;
316 }
317}
318
319// XSelectionChangeListener
320
321void SAL_CALL ScDispatch::selectionChanged( const css::lang::EventObject& /* aEvent */ )
322{
323 // currently only called for URL cURLDocDataSource
324
325 if ( !pViewShell )
326 return;
327
328 ScImportParam aNewImport;
329 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
330 if ( pDBData )
331 pDBData->GetImportParam( aNewImport );
332
333 // notify listeners only if data source has changed
334 if ( !(aNewImport.bImport != aLastImport.bImport ||
335 aNewImport.aDBName != aLastImport.aDBName ||
336 aNewImport.aStatement != aLastImport.aStatement ||
337 aNewImport.bSql != aLastImport.bSql ||
338 aNewImport.nType != aLastImport.nType) )
339 return;
340
341 frame::FeatureStateEvent aEvent;
342 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
343 aEvent.FeatureURL.Complete = cURLDocDataSource;
344
345 lcl_FillDataSource( aEvent, aNewImport ); // modifies State, IsEnabled
346
347 for (uno::Reference<frame::XStatusListener> & xDataSourceListener : aDataSourceListeners)
348 xDataSourceListener->statusChanged( aEvent );
349
350 aLastImport = aNewImport;
351}
352
353// XEventListener
354
355void SAL_CALL ScDispatch::disposing( const css::lang::EventObject& rSource )
356{
357 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
358 xSupplier->removeSelectionChangeListener(this);
359 bListeningToView = false;
360
361 lang::EventObject aEvent;
362 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
363 for (uno::Reference<frame::XStatusListener> & xDataSourceListener : aDataSourceListeners)
364 xDataSourceListener->disposing( aEvent );
365
366 pViewShell = nullptr;
367}
368
369/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
void GetImportParam(ScImportParam &rImportParam) const
Definition: dbdata.cxx:480
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:151
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:116
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:160
virtual ~ScDispatchProviderInterceptor() override
Definition: dispuno.cxx:77
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getSlaveDispatchProvider() override
XDispatchProviderInterceptor.
Definition: dispuno.cxx:131
virtual void SAL_CALL setSlaveDispatchProvider(const css::uno::Reference< css::frame::XDispatchProvider > &xNewDispatchProvider) override
Definition: dispuno.cxx:137
css::uno::Reference< css::frame::XDispatch > m_xMyDispatch
own dispatch
Definition: dispuno.hxx:46
ScDispatchProviderInterceptor(ScTabViewShell *pViewSh)
Definition: dispuno.cxx:52
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:91
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getMasterDispatchProvider() override
Definition: dispuno.cxx:145
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: dispuno.cxx:83
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:177
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
Definition: dispuno.cxx:253
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:290
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
XEventListener.
Definition: dispuno.cxx:355
virtual void SAL_CALL selectionChanged(const css::lang::EventObject &aEvent) override
XSelectionChangeListener.
Definition: dispuno.cxx:321
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:206
std::vector< css::uno::Reference< css::frame::XStatusListener > > aDataSourceListeners
Definition: dispuno.hxx:84
virtual ~ScDispatch() override
Definition: dispuno.cxx:185
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: dispuno.cxx:198
ScViewData & GetViewData()
Definition: tabview.hxx:335
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:227
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:420
@ SC_DB_OLD
don't create
Definition: global.hxx:385
sal_Int64 n
QPRO_FUNC_TYPE nType
Definition: qproform.cxx:398
OUString aStatement
Definition: global.hxx:446
sal_uInt8 nType
Definition: global.hxx:449
OUString aDBName
Definition: global.hxx:445
bool bImport
Definition: global.hxx:444
@ QUERY
Definition: xmldpimp.hxx:44
@ TABLE
Definition: xmldpimp.hxx:43