Stop leaking all ScPostIt instances.
[LibreOffice.git] / sc / source / ui / unoobj / dispuno.cxx
blob6ee045a55c9c1a392168db0ab17748913b04335c
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 <comphelper/uno3.hxx>
22 #include <svx/dataaccessdescriptor.hxx>
23 #include <svl/smplhint.hxx>
24 #include <vcl/svapp.hxx>
26 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
27 #include <com/sun/star/view/XSelectionSupplier.hpp>
28 #include <com/sun/star/sdb/CommandType.hpp>
30 #include "dispuno.hxx"
31 #include "tabvwsh.hxx"
32 #include "dbdocfun.hxx"
33 #include "dbdata.hxx"
35 using namespace com::sun::star;
37 //------------------------------------------------------------------------
39 static const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns"; //data into text
40 static const char* cURLDocDataSource = ".uno:DataSourceBrowser/DocumentDataSource";
42 //------------------------------------------------------------------------
44 static uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( SfxViewShell* pViewShell )
46 if ( pViewShell )
48 SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
49 if (pViewFrame)
51 return uno::Reference<view::XSelectionSupplier>( pViewFrame->GetFrame().GetController(), uno::UNO_QUERY );
54 return uno::Reference<view::XSelectionSupplier>();
57 //------------------------------------------------------------------------
60 ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell* pViewSh) :
61 pViewShell( pViewSh )
63 if ( pViewShell )
65 m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY));
66 if (m_xIntercepted.is())
68 comphelper::increment( m_refCount );
70 m_xIntercepted->registerDispatchProviderInterceptor(
71 static_cast<frame::XDispatchProviderInterceptor*>(this));
72 // this should make us the top-level dispatch-provider for the component, via a call to our
73 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
74 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
75 if (xInterceptedComponent.is())
76 xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
78 comphelper::decrement( m_refCount );
81 StartListening(*pViewShell);
85 ScDispatchProviderInterceptor::~ScDispatchProviderInterceptor()
87 if (pViewShell)
88 EndListening(*pViewShell);
91 void ScDispatchProviderInterceptor::Notify( SfxBroadcaster&, const SfxHint& rHint )
93 if ( rHint.ISA( SfxSimpleHint ) &&
94 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
95 pViewShell = NULL;
98 // XDispatchProvider
100 uno::Reference<frame::XDispatch> SAL_CALL ScDispatchProviderInterceptor::queryDispatch(
101 const util::URL& aURL, const OUString& aTargetFrameName,
102 sal_Int32 nSearchFlags )
103 throw(uno::RuntimeException)
105 SolarMutexGuard aGuard;
107 uno::Reference<frame::XDispatch> xResult;
108 // create some dispatch ...
109 if ( pViewShell && (
110 aURL.Complete.equalsAscii(cURLInsertColumns) ||
111 aURL.Complete.equalsAscii(cURLDocDataSource) ) )
113 if (!m_xMyDispatch.is())
114 m_xMyDispatch = new ScDispatch( pViewShell );
115 xResult = m_xMyDispatch;
118 // ask our slave provider
119 if (!xResult.is() && m_xSlaveDispatcher.is())
120 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
122 return xResult;
125 uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
126 ScDispatchProviderInterceptor::queryDispatches(
127 const uno::Sequence<frame::DispatchDescriptor>& aDescripts )
128 throw(uno::RuntimeException)
130 SolarMutexGuard aGuard;
132 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
133 uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray();
134 const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
135 for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts)
137 *pReturn = queryDispatch(pDescripts->FeatureURL,
138 pDescripts->FrameName, pDescripts->SearchFlags);
140 return aReturn;
143 // XDispatchProviderInterceptor
145 uno::Reference<frame::XDispatchProvider> SAL_CALL
146 ScDispatchProviderInterceptor::getSlaveDispatchProvider()
147 throw(uno::RuntimeException)
149 SolarMutexGuard aGuard;
150 return m_xSlaveDispatcher;
153 void SAL_CALL ScDispatchProviderInterceptor::setSlaveDispatchProvider(
154 const uno::Reference<frame::XDispatchProvider>& xNewDispatchProvider )
155 throw(uno::RuntimeException)
157 SolarMutexGuard aGuard;
158 m_xSlaveDispatcher.set(xNewDispatchProvider);
161 uno::Reference<frame::XDispatchProvider> SAL_CALL
162 ScDispatchProviderInterceptor::getMasterDispatchProvider()
163 throw(uno::RuntimeException)
165 SolarMutexGuard aGuard;
166 return m_xMasterDispatcher;
169 void SAL_CALL ScDispatchProviderInterceptor::setMasterDispatchProvider(
170 const uno::Reference<frame::XDispatchProvider>& xNewSupplier )
171 throw(uno::RuntimeException)
173 SolarMutexGuard aGuard;
174 m_xMasterDispatcher.set(xNewSupplier);
177 // XEventListener
179 void SAL_CALL ScDispatchProviderInterceptor::disposing( const lang::EventObject& /* Source */ )
180 throw(::com::sun::star::uno::RuntimeException)
182 SolarMutexGuard aGuard;
184 if (m_xIntercepted.is())
186 m_xIntercepted->releaseDispatchProviderInterceptor(
187 static_cast<frame::XDispatchProviderInterceptor*>(this));
188 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
189 if (xInterceptedComponent.is())
190 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
192 m_xMyDispatch = NULL;
194 m_xIntercepted = NULL;
197 //------------------------------------------------------------------------
199 ScDispatch::ScDispatch(ScTabViewShell* pViewSh) :
200 pViewShell( pViewSh ),
201 bListeningToView( false )
203 if (pViewShell)
204 StartListening(*pViewShell);
207 ScDispatch::~ScDispatch()
209 if (pViewShell)
210 EndListening(*pViewShell);
212 if (bListeningToView && pViewShell)
214 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
215 if ( xSupplier.is() )
216 xSupplier->removeSelectionChangeListener(this);
220 void ScDispatch::Notify( SfxBroadcaster&, const SfxHint& rHint )
222 if ( rHint.ISA( SfxSimpleHint ) &&
223 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
224 pViewShell = NULL;
227 // XDispatch
229 void SAL_CALL ScDispatch::dispatch( const util::URL& aURL,
230 const uno::Sequence<beans::PropertyValue>& aArgs )
231 throw(uno::RuntimeException)
233 SolarMutexGuard aGuard;
235 sal_Bool bDone = false;
236 if ( pViewShell && aURL.Complete.equalsAscii(cURLInsertColumns) )
238 ScViewData* pViewData = pViewShell->GetViewData();
239 ScAddress aPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
241 ScDBDocFunc aFunc( *pViewData->GetDocShell() );
242 bDone = aFunc.DoImportUno( aPos, aArgs );
244 // cURLDocDataSource is never dispatched
246 if (!bDone)
247 throw uno::RuntimeException();
250 static void lcl_FillDataSource( frame::FeatureStateEvent& rEvent, const ScImportParam& rParam )
252 rEvent.IsEnabled = rParam.bImport;
254 ::svx::ODataAccessDescriptor aDescriptor;
255 if ( rParam.bImport )
257 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
258 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
259 sdb::CommandType::TABLE );
261 aDescriptor.setDataSource(rParam.aDBName);
262 aDescriptor[svx::daCommand] <<= rParam.aStatement;
263 aDescriptor[svx::daCommandType] <<= nType;
265 else
267 // descriptor has to be complete anyway
269 OUString aEmpty;
270 aDescriptor[svx::daDataSource] <<= aEmpty;
271 aDescriptor[svx::daCommand] <<= aEmpty;
272 aDescriptor[svx::daCommandType] <<= (sal_Int32)sdb::CommandType::TABLE;
274 rEvent.State <<= aDescriptor.createPropertyValueSequence();
277 void SAL_CALL ScDispatch::addStatusListener(
278 const uno::Reference<frame::XStatusListener>& xListener,
279 const util::URL& aURL )
280 throw(uno::RuntimeException)
282 SolarMutexGuard aGuard;
284 if (!pViewShell)
285 throw uno::RuntimeException();
287 // initial state
288 frame::FeatureStateEvent aEvent;
289 aEvent.IsEnabled = sal_True;
290 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
291 aEvent.FeatureURL = aURL;
293 if ( aURL.Complete.equalsAscii(cURLDocDataSource) )
295 uno::Reference<frame::XStatusListener>* pObj =
296 new uno::Reference<frame::XStatusListener>( xListener );
297 aDataSourceListeners.push_back( pObj );
299 if (!bListeningToView)
301 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
302 if ( xSupplier.is() )
303 xSupplier->addSelectionChangeListener(this);
304 bListeningToView = sal_True;
307 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
308 if ( pDBData )
309 pDBData->GetImportParam( aLastImport );
310 lcl_FillDataSource( aEvent, aLastImport ); // modifies State, IsEnabled
312 //! else add to listener for "enabled" changes?
314 xListener->statusChanged( aEvent );
317 void SAL_CALL ScDispatch::removeStatusListener(
318 const uno::Reference<frame::XStatusListener>& xListener,
319 const util::URL& aURL )
320 throw(uno::RuntimeException)
322 SolarMutexGuard aGuard;
324 if ( aURL.Complete.equalsAscii(cURLDocDataSource) )
326 sal_uInt16 nCount = aDataSourceListeners.size();
327 for ( sal_uInt16 n=nCount; n--; )
329 uno::Reference<frame::XStatusListener>& rObj = aDataSourceListeners[n];
330 if ( rObj == xListener )
332 aDataSourceListeners.erase( aDataSourceListeners.begin() + n );
333 break;
337 if ( aDataSourceListeners.empty() && pViewShell )
339 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
340 if ( xSupplier.is() )
341 xSupplier->removeSelectionChangeListener(this);
342 bListeningToView = false;
347 // XSelectionChangeListener
349 void SAL_CALL ScDispatch::selectionChanged( const ::com::sun::star::lang::EventObject& /* aEvent */ )
350 throw (::com::sun::star::uno::RuntimeException)
352 // currently only called for URL cURLDocDataSource
354 if ( pViewShell )
356 ScImportParam aNewImport;
357 ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
358 if ( pDBData )
359 pDBData->GetImportParam( aNewImport );
361 // notify listeners only if data source has changed
362 if ( aNewImport.bImport != aLastImport.bImport ||
363 aNewImport.aDBName != aLastImport.aDBName ||
364 aNewImport.aStatement != aLastImport.aStatement ||
365 aNewImport.bSql != aLastImport.bSql ||
366 aNewImport.nType != aLastImport.nType )
368 frame::FeatureStateEvent aEvent;
369 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
370 aEvent.FeatureURL.Complete = OUString::createFromAscii( cURLDocDataSource );
372 lcl_FillDataSource( aEvent, aNewImport ); // modifies State, IsEnabled
374 for ( sal_uInt16 n=0; n<aDataSourceListeners.size(); n++ )
375 aDataSourceListeners[n]->statusChanged( aEvent );
377 aLastImport = aNewImport;
382 // XEventListener
384 void SAL_CALL ScDispatch::disposing( const ::com::sun::star::lang::EventObject& rSource )
385 throw (::com::sun::star::uno::RuntimeException)
387 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
388 xSupplier->removeSelectionChangeListener(this);
389 bListeningToView = false;
391 lang::EventObject aEvent;
392 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
393 for ( sal_uInt16 n=0; n<aDataSourceListeners.size(); n++ )
394 aDataSourceListeners[n]->disposing( aEvent );
396 pViewShell = NULL;
399 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */