tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / unoobj / dispuno.cxx
blob536d271d643fec71cc41710578bcefc88c5a101e
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 .
20 #include <sfx2/viewfrm.hxx>
21 #include <svx/dataaccessdescriptor.hxx>
22 #include <svl/hint.hxx>
23 #include <vcl/svapp.hxx>
25 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
26 #include <com/sun/star/view/XSelectionSupplier.hpp>
27 #include <com/sun/star/sdb/CommandType.hpp>
29 #include <dispuno.hxx>
30 #include <tabvwsh.hxx>
31 #include <dbdocfun.hxx>
32 #include <dbdata.hxx>
34 using namespace com::sun::star;
36 const char cURLInsertColumns[] = ".uno:DataSourceBrowser/InsertColumns"; //data into text
37 constexpr OUString cURLDocDataSource = u".uno:DataSourceBrowser/DocumentDataSource"_ustr;
39 static uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( const SfxViewShell* pViewShell )
41 if ( pViewShell )
43 SfxViewFrame& rViewFrame = pViewShell->GetViewFrame();
44 return uno::Reference<view::XSelectionSupplier>( rViewFrame.GetFrame().GetController(), uno::UNO_QUERY );
46 return uno::Reference<view::XSelectionSupplier>();
49 ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell* pViewSh) :
50 pViewShell( pViewSh )
52 if ( !pViewShell )
53 return;
55 m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame().GetFrame().GetFrameInterface(), uno::UNO_QUERY));
56 if (m_xIntercepted.is())
58 osl_atomic_increment( &m_refCount );
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));
68 osl_atomic_decrement( &m_refCount );
71 StartListening(*pViewShell);
74 ScDispatchProviderInterceptor::~ScDispatchProviderInterceptor()
76 if (pViewShell)
77 EndListening(*pViewShell);
80 void ScDispatchProviderInterceptor::Notify( SfxBroadcaster&, const SfxHint& rHint )
82 if ( rHint.GetId() == SfxHintId::Dying )
83 pViewShell = nullptr;
86 // XDispatchProvider
88 uno::Reference<frame::XDispatch> SAL_CALL ScDispatchProviderInterceptor::queryDispatch(
89 const util::URL& aURL, const OUString& aTargetFrameName,
90 sal_Int32 nSearchFlags )
92 SolarMutexGuard aGuard;
94 uno::Reference<frame::XDispatch> xResult;
95 // create some dispatch ...
96 if ( pViewShell && (
97 aURL.Complete == cURLInsertColumns ||
98 aURL.Complete == cURLDocDataSource ) )
100 if (!m_xMyDispatch.is())
101 m_xMyDispatch = new ScDispatch( pViewShell );
102 xResult = m_xMyDispatch;
105 // ask our slave provider
106 if (!xResult.is() && m_xSlaveDispatcher.is())
107 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
109 return xResult;
112 uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
113 ScDispatchProviderInterceptor::queryDispatches(
114 const uno::Sequence<frame::DispatchDescriptor>& aDescripts )
116 SolarMutexGuard aGuard;
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;
125 // XDispatchProviderInterceptor
127 uno::Reference<frame::XDispatchProvider> SAL_CALL
128 ScDispatchProviderInterceptor::getSlaveDispatchProvider()
130 SolarMutexGuard aGuard;
131 return m_xSlaveDispatcher;
134 void SAL_CALL ScDispatchProviderInterceptor::setSlaveDispatchProvider(
135 const uno::Reference<frame::XDispatchProvider>& xNewDispatchProvider )
137 SolarMutexGuard aGuard;
138 m_xSlaveDispatcher.set(xNewDispatchProvider);
141 uno::Reference<frame::XDispatchProvider> SAL_CALL
142 ScDispatchProviderInterceptor::getMasterDispatchProvider()
144 SolarMutexGuard aGuard;
145 return m_xMasterDispatcher;
148 void SAL_CALL ScDispatchProviderInterceptor::setMasterDispatchProvider(
149 const uno::Reference<frame::XDispatchProvider>& xNewSupplier )
151 SolarMutexGuard aGuard;
152 m_xMasterDispatcher.set(xNewSupplier);
155 // XEventListener
157 void SAL_CALL ScDispatchProviderInterceptor::disposing( const lang::EventObject& /* Source */ )
159 SolarMutexGuard aGuard;
161 if (m_xIntercepted.is())
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));
169 m_xMyDispatch = nullptr;
171 m_xIntercepted = nullptr;
174 ScDispatch::ScDispatch(ScTabViewShell* pViewSh) :
175 pViewShell( pViewSh ),
176 bListeningToView( false )
178 if (pViewShell)
179 StartListening(*pViewShell);
182 ScDispatch::~ScDispatch()
184 if (pViewShell)
185 EndListening(*pViewShell);
187 if (bListeningToView && pViewShell)
189 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
190 if ( xSupplier.is() )
191 xSupplier->removeSelectionChangeListener(this);
195 void ScDispatch::Notify( SfxBroadcaster&, const SfxHint& rHint )
197 if ( rHint.GetId() == SfxHintId::Dying )
198 pViewShell = nullptr;
201 // XDispatch
203 void SAL_CALL ScDispatch::dispatch( const util::URL& aURL,
204 const uno::Sequence<beans::PropertyValue>& aArgs )
206 SolarMutexGuard aGuard;
208 bool bDone = false;
209 if ( pViewShell && aURL.Complete == cURLInsertColumns )
211 ScViewData& rViewData = pViewShell->GetViewData();
212 ScAddress aPos( rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo() );
214 ScDBDocFunc aFunc( *rViewData.GetDocShell() );
215 aFunc.DoImportUno( aPos, aArgs );
216 bDone = true;
218 // cURLDocDataSource is never dispatched
220 if (!bDone)
221 throw uno::RuntimeException();
224 static void lcl_FillDataSource( frame::FeatureStateEvent& rEvent, const ScImportParam& rParam )
226 rEvent.IsEnabled = rParam.bImport;
228 svx::ODataAccessDescriptor aDescriptor;
229 if ( rParam.bImport )
231 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
232 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
233 sdb::CommandType::TABLE );
235 aDescriptor.setDataSource(rParam.aDBName);
236 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= rParam.aStatement;
237 aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= nType;
239 else
241 // descriptor has to be complete anyway
243 aDescriptor[svx::DataAccessDescriptorProperty::DataSource] <<= OUString();
244 aDescriptor[svx::DataAccessDescriptorProperty::Command] <<= OUString();
245 aDescriptor[svx::DataAccessDescriptorProperty::CommandType] <<= sal_Int32(sdb::CommandType::TABLE);
247 rEvent.State <<= aDescriptor.createPropertyValueSequence();
250 void SAL_CALL ScDispatch::addStatusListener(
251 const uno::Reference<frame::XStatusListener>& xListener,
252 const util::URL& aURL)
254 SolarMutexGuard aGuard;
256 if (!pViewShell)
257 throw uno::RuntimeException();
259 // initial state
260 frame::FeatureStateEvent aEvent;
261 aEvent.IsEnabled = true;
262 aEvent.Source = getXWeak();
263 aEvent.FeatureURL = aURL;
265 if ( aURL.Complete == cURLDocDataSource )
267 aDataSourceListeners.emplace_back( xListener );
269 if (!bListeningToView)
271 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
272 if ( xSupplier.is() )
273 xSupplier->addSelectionChangeListener(this);
274 bListeningToView = true;
277 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
278 if ( pDBData )
279 pDBData->GetImportParam( aLastImport );
280 lcl_FillDataSource( aEvent, aLastImport ); // modifies State, IsEnabled
282 //! else add to listener for "enabled" changes?
284 xListener->statusChanged( aEvent );
287 void SAL_CALL ScDispatch::removeStatusListener(
288 const uno::Reference<frame::XStatusListener>& xListener,
289 const util::URL& aURL )
291 SolarMutexGuard aGuard;
293 if ( aURL.Complete != cURLDocDataSource )
294 return;
296 sal_uInt16 nCount = aDataSourceListeners.size();
297 for ( sal_uInt16 n=nCount; n--; )
299 uno::Reference<frame::XStatusListener>& rObj = aDataSourceListeners[n];
300 if ( rObj == xListener )
302 aDataSourceListeners.erase( aDataSourceListeners.begin() + n );
303 break;
307 if ( aDataSourceListeners.empty() && pViewShell )
309 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
310 if ( xSupplier.is() )
311 xSupplier->removeSelectionChangeListener(this);
312 bListeningToView = false;
316 // XSelectionChangeListener
318 void SAL_CALL ScDispatch::selectionChanged( const css::lang::EventObject& /* aEvent */ )
320 // currently only called for URL cURLDocDataSource
322 if ( !pViewShell )
323 return;
325 ScImportParam aNewImport;
326 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
327 if ( pDBData )
328 pDBData->GetImportParam( aNewImport );
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;
338 frame::FeatureStateEvent aEvent;
339 aEvent.Source = getXWeak();
340 aEvent.FeatureURL.Complete = cURLDocDataSource;
342 lcl_FillDataSource( aEvent, aNewImport ); // modifies State, IsEnabled
344 for (uno::Reference<frame::XStatusListener> & xDataSourceListener : aDataSourceListeners)
345 xDataSourceListener->statusChanged( aEvent );
347 aLastImport = aNewImport;
350 // XEventListener
352 void SAL_CALL ScDispatch::disposing( const css::lang::EventObject& rSource )
354 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
355 xSupplier->removeSelectionChangeListener(this);
356 bListeningToView = false;
358 lang::EventObject aEvent;
359 aEvent.Source = getXWeak();
360 for (uno::Reference<frame::XStatusListener> & xDataSourceListener : aDataSourceListeners)
361 xDataSourceListener->disposing( aEvent );
363 pViewShell = nullptr;
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */