Update ooo320-m1
[ooovba.git] / sc / source / ui / unoobj / dispuno.cxx
blobab294dd61eb9ce42030906722677aa8b4d57c7a0
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dispuno.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #include <sfx2/viewfrm.hxx>
37 #include <comphelper/uno3.hxx>
38 #include <svx/dataaccessdescriptor.hxx>
39 #include <svtools/smplhint.hxx>
41 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
42 #include <com/sun/star/view/XSelectionSupplier.hpp>
43 #include <com/sun/star/sdb/CommandType.hpp>
45 #include "dispuno.hxx"
46 #include "unoguard.hxx"
47 #include "tabvwsh.hxx"
48 #include "dbdocfun.hxx"
49 #include "dbcolect.hxx"
51 using namespace com::sun::star;
53 //------------------------------------------------------------------------
55 const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns"; //data into text
56 const char* cURLDocDataSource = ".uno:DataSourceBrowser/DocumentDataSource";
58 //------------------------------------------------------------------------
60 SV_IMPL_PTRARR( XStatusListenerArr_Impl, XStatusListenerPtr );
62 //------------------------------------------------------------------------
64 uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( SfxViewShell* pViewShell )
66 if ( pViewShell )
68 SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
69 if (pViewFrame)
71 SfxFrame* pFrame = pViewFrame->GetFrame();
72 if (pFrame)
73 return uno::Reference<view::XSelectionSupplier>( pFrame->GetController(), uno::UNO_QUERY );
76 return uno::Reference<view::XSelectionSupplier>();
79 //------------------------------------------------------------------------
82 ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell* pViewSh) :
83 pViewShell( pViewSh )
85 if ( pViewShell )
87 SfxFrame* pFrame = pViewShell->GetViewFrame()->GetFrame();
88 m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pFrame->GetFrameInterface(), uno::UNO_QUERY));
89 if (m_xIntercepted.is())
91 comphelper::increment( m_refCount );
93 m_xIntercepted->registerDispatchProviderInterceptor(
94 static_cast<frame::XDispatchProviderInterceptor*>(this));
95 // this should make us the top-level dispatch-provider for the component, via a call to our
96 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
97 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
98 if (xInterceptedComponent.is())
99 xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
101 comphelper::decrement( m_refCount );
104 StartListening(*pViewShell);
108 ScDispatchProviderInterceptor::~ScDispatchProviderInterceptor()
110 if (pViewShell)
111 EndListening(*pViewShell);
114 void ScDispatchProviderInterceptor::Notify( SfxBroadcaster&, const SfxHint& rHint )
116 if ( rHint.ISA( SfxSimpleHint ) &&
117 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
118 pViewShell = NULL;
121 // XDispatchProvider
123 uno::Reference<frame::XDispatch> SAL_CALL ScDispatchProviderInterceptor::queryDispatch(
124 const util::URL& aURL, const rtl::OUString& aTargetFrameName,
125 sal_Int32 nSearchFlags )
126 throw(uno::RuntimeException)
128 ScUnoGuard aGuard;
130 uno::Reference<frame::XDispatch> xResult;
131 // create some dispatch ...
132 if ( pViewShell && (
133 !aURL.Complete.compareToAscii(cURLInsertColumns) ||
134 !aURL.Complete.compareToAscii(cURLDocDataSource) ) )
136 if (!m_xMyDispatch.is())
137 m_xMyDispatch = new ScDispatch( pViewShell );
138 xResult = m_xMyDispatch;
141 // ask our slave provider
142 if (!xResult.is() && m_xSlaveDispatcher.is())
143 xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
145 return xResult;
148 uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
149 ScDispatchProviderInterceptor::queryDispatches(
150 const uno::Sequence<frame::DispatchDescriptor>& aDescripts )
151 throw(uno::RuntimeException)
153 ScUnoGuard aGuard;
155 uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
156 uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray();
157 const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
158 for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts)
160 *pReturn = queryDispatch(pDescripts->FeatureURL,
161 pDescripts->FrameName, pDescripts->SearchFlags);
163 return aReturn;
166 // XDispatchProviderInterceptor
168 uno::Reference<frame::XDispatchProvider> SAL_CALL
169 ScDispatchProviderInterceptor::getSlaveDispatchProvider()
170 throw(uno::RuntimeException)
172 ScUnoGuard aGuard;
173 return m_xSlaveDispatcher;
176 void SAL_CALL ScDispatchProviderInterceptor::setSlaveDispatchProvider(
177 const uno::Reference<frame::XDispatchProvider>& xNewDispatchProvider )
178 throw(uno::RuntimeException)
180 ScUnoGuard aGuard;
181 m_xSlaveDispatcher.set(xNewDispatchProvider);
184 uno::Reference<frame::XDispatchProvider> SAL_CALL
185 ScDispatchProviderInterceptor::getMasterDispatchProvider()
186 throw(uno::RuntimeException)
188 ScUnoGuard aGuard;
189 return m_xMasterDispatcher;
192 void SAL_CALL ScDispatchProviderInterceptor::setMasterDispatchProvider(
193 const uno::Reference<frame::XDispatchProvider>& xNewSupplier )
194 throw(uno::RuntimeException)
196 ScUnoGuard aGuard;
197 m_xMasterDispatcher.set(xNewSupplier);
200 // XEventListener
202 void SAL_CALL ScDispatchProviderInterceptor::disposing( const lang::EventObject& /* Source */ )
203 throw(::com::sun::star::uno::RuntimeException)
205 ScUnoGuard aGuard;
207 if (m_xIntercepted.is())
209 m_xIntercepted->releaseDispatchProviderInterceptor(
210 static_cast<frame::XDispatchProviderInterceptor*>(this));
211 uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
212 if (xInterceptedComponent.is())
213 xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
215 m_xMyDispatch = NULL;
217 m_xIntercepted = NULL;
220 //------------------------------------------------------------------------
222 ScDispatch::ScDispatch(ScTabViewShell* pViewSh) :
223 pViewShell( pViewSh ),
224 bListeningToView( FALSE )
226 if (pViewShell)
227 StartListening(*pViewShell);
230 ScDispatch::~ScDispatch()
232 if (pViewShell)
233 EndListening(*pViewShell);
235 if (bListeningToView && pViewShell)
237 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
238 if ( xSupplier.is() )
239 xSupplier->removeSelectionChangeListener(this);
243 void ScDispatch::Notify( SfxBroadcaster&, const SfxHint& rHint )
245 if ( rHint.ISA( SfxSimpleHint ) &&
246 ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
247 pViewShell = NULL;
250 // XDispatch
252 void SAL_CALL ScDispatch::dispatch( const util::URL& aURL,
253 const uno::Sequence<beans::PropertyValue>& aArgs )
254 throw(uno::RuntimeException)
256 ScUnoGuard aGuard;
258 BOOL bDone = FALSE;
259 if ( pViewShell && !aURL.Complete.compareToAscii(cURLInsertColumns) )
261 ScViewData* pViewData = pViewShell->GetViewData();
262 ScAddress aPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
264 ScDBDocFunc aFunc( *pViewData->GetDocShell() );
265 bDone = aFunc.DoImportUno( aPos, aArgs );
267 // cURLDocDataSource is never dispatched
269 if (!bDone)
270 throw uno::RuntimeException();
273 void lcl_FillDataSource( frame::FeatureStateEvent& rEvent, const ScImportParam& rParam )
275 rEvent.IsEnabled = rParam.bImport;
277 ::svx::ODataAccessDescriptor aDescriptor;
278 if ( rParam.bImport )
280 sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
281 ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
282 sdb::CommandType::TABLE );
284 aDescriptor.setDataSource(rtl::OUString( rParam.aDBName ));
285 aDescriptor[svx::daCommand] <<= rtl::OUString( rParam.aStatement );
286 aDescriptor[svx::daCommandType] <<= nType;
288 else
290 // descriptor has to be complete anyway
292 rtl::OUString aEmpty;
293 aDescriptor[svx::daDataSource] <<= aEmpty;
294 aDescriptor[svx::daCommand] <<= aEmpty;
295 aDescriptor[svx::daCommandType] <<= (sal_Int32)sdb::CommandType::TABLE;
297 rEvent.State <<= aDescriptor.createPropertyValueSequence();
300 void SAL_CALL ScDispatch::addStatusListener(
301 const uno::Reference<frame::XStatusListener>& xListener,
302 const util::URL& aURL )
303 throw(uno::RuntimeException)
305 ScUnoGuard aGuard;
307 if (!pViewShell)
308 throw uno::RuntimeException();
310 // initial state
311 frame::FeatureStateEvent aEvent;
312 aEvent.IsEnabled = sal_True;
313 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
314 aEvent.FeatureURL = aURL;
316 if ( !aURL.Complete.compareToAscii(cURLDocDataSource) )
318 uno::Reference<frame::XStatusListener>* pObj =
319 new uno::Reference<frame::XStatusListener>( xListener );
320 aDataSourceListeners.Insert( pObj, aDataSourceListeners.Count() );
322 if (!bListeningToView)
324 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
325 if ( xSupplier.is() )
326 xSupplier->addSelectionChangeListener(this);
327 bListeningToView = sal_True;
330 ScDBData* pDBData = pViewShell->GetDBData(FALSE,SC_DB_OLD);
331 if ( pDBData )
332 pDBData->GetImportParam( aLastImport );
333 lcl_FillDataSource( aEvent, aLastImport ); // modifies State, IsEnabled
335 //! else add to listener for "enabled" changes?
337 xListener->statusChanged( aEvent );
340 void SAL_CALL ScDispatch::removeStatusListener(
341 const uno::Reference<frame::XStatusListener>& xListener,
342 const util::URL& aURL )
343 throw(uno::RuntimeException)
345 ScUnoGuard aGuard;
347 if ( !aURL.Complete.compareToAscii(cURLDocDataSource) )
349 USHORT nCount = aDataSourceListeners.Count();
350 for ( USHORT n=nCount; n--; )
352 uno::Reference<frame::XStatusListener> *pObj = aDataSourceListeners[n];
353 if ( *pObj == xListener )
355 aDataSourceListeners.DeleteAndDestroy( n );
356 break;
360 if ( aDataSourceListeners.Count() == 0 && pViewShell )
362 uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
363 if ( xSupplier.is() )
364 xSupplier->removeSelectionChangeListener(this);
365 bListeningToView = sal_False;
370 // XSelectionChangeListener
372 void SAL_CALL ScDispatch::selectionChanged( const ::com::sun::star::lang::EventObject& /* aEvent */ )
373 throw (::com::sun::star::uno::RuntimeException)
375 // currently only called for URL cURLDocDataSource
377 if ( pViewShell )
379 ScImportParam aNewImport;
380 ScDBData* pDBData = pViewShell->GetDBData(FALSE,SC_DB_OLD);
381 if ( pDBData )
382 pDBData->GetImportParam( aNewImport );
384 // notify listeners only if data source has changed
385 if ( aNewImport.bImport != aLastImport.bImport ||
386 aNewImport.aDBName != aLastImport.aDBName ||
387 aNewImport.aStatement != aLastImport.aStatement ||
388 aNewImport.bSql != aLastImport.bSql ||
389 aNewImport.nType != aLastImport.nType )
391 frame::FeatureStateEvent aEvent;
392 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
393 aEvent.FeatureURL.Complete = rtl::OUString::createFromAscii( cURLDocDataSource );
395 lcl_FillDataSource( aEvent, aNewImport ); // modifies State, IsEnabled
397 for ( USHORT n=0; n<aDataSourceListeners.Count(); n++ )
398 (*aDataSourceListeners[n])->statusChanged( aEvent );
400 aLastImport = aNewImport;
405 // XEventListener
407 void SAL_CALL ScDispatch::disposing( const ::com::sun::star::lang::EventObject& rSource )
408 throw (::com::sun::star::uno::RuntimeException)
410 uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
411 xSupplier->removeSelectionChangeListener(this);
412 bListeningToView = sal_False;
414 lang::EventObject aEvent;
415 aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
416 for ( USHORT n=0; n<aDataSourceListeners.Count(); n++ )
417 (*aDataSourceListeners[n])->disposing( aEvent );
419 pViewShell = NULL;