1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/smplhint.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"
34 using namespace com::sun::star
;
36 static const char* cURLInsertColumns
= ".uno:DataSourceBrowser/InsertColumns"; //data into text
37 static const char* cURLDocDataSource
= ".uno:DataSourceBrowser/DocumentDataSource";
39 static uno::Reference
<view::XSelectionSupplier
> lcl_GetSelectionSupplier( SfxViewShell
* pViewShell
)
43 SfxViewFrame
* pViewFrame
= pViewShell
->GetViewFrame();
46 return uno::Reference
<view::XSelectionSupplier
>( pViewFrame
->GetFrame().GetController(), uno::UNO_QUERY
);
49 return uno::Reference
<view::XSelectionSupplier
>();
52 ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell
* pViewSh
) :
57 m_xIntercepted
.set(uno::Reference
<frame::XDispatchProviderInterception
>(pViewShell
->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY
));
58 if (m_xIntercepted
.is())
60 osl_atomic_increment( &m_refCount
);
62 m_xIntercepted
->registerDispatchProviderInterceptor(
63 static_cast<frame::XDispatchProviderInterceptor
*>(this));
64 // this should make us the top-level dispatch-provider for the component, via a call to our
65 // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fulfill
66 uno::Reference
<lang::XComponent
> xInterceptedComponent(m_xIntercepted
, uno::UNO_QUERY
);
67 if (xInterceptedComponent
.is())
68 xInterceptedComponent
->addEventListener(static_cast<lang::XEventListener
*>(this));
70 osl_atomic_decrement( &m_refCount
);
73 StartListening(*pViewShell
);
77 ScDispatchProviderInterceptor::~ScDispatchProviderInterceptor()
80 EndListening(*pViewShell
);
83 void ScDispatchProviderInterceptor::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
85 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
86 if ( pSimpleHint
&& pSimpleHint
->GetId() == SFX_HINT_DYING
)
92 uno::Reference
<frame::XDispatch
> SAL_CALL
ScDispatchProviderInterceptor::queryDispatch(
93 const util::URL
& aURL
, const OUString
& aTargetFrameName
,
94 sal_Int32 nSearchFlags
)
95 throw(uno::RuntimeException
, std::exception
)
97 SolarMutexGuard aGuard
;
99 uno::Reference
<frame::XDispatch
> xResult
;
100 // create some dispatch ...
102 aURL
.Complete
.equalsAscii(cURLInsertColumns
) ||
103 aURL
.Complete
.equalsAscii(cURLDocDataSource
) ) )
105 if (!m_xMyDispatch
.is())
106 m_xMyDispatch
= new ScDispatch( pViewShell
);
107 xResult
= m_xMyDispatch
;
110 // ask our slave provider
111 if (!xResult
.is() && m_xSlaveDispatcher
.is())
112 xResult
= m_xSlaveDispatcher
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
117 uno::Sequence
< uno::Reference
<frame::XDispatch
> > SAL_CALL
118 ScDispatchProviderInterceptor::queryDispatches(
119 const uno::Sequence
<frame::DispatchDescriptor
>& aDescripts
)
120 throw(uno::RuntimeException
, std::exception
)
122 SolarMutexGuard aGuard
;
124 uno::Sequence
< uno::Reference
< frame::XDispatch
> > aReturn(aDescripts
.getLength());
125 uno::Reference
< frame::XDispatch
>* pReturn
= aReturn
.getArray();
126 const frame::DispatchDescriptor
* pDescripts
= aDescripts
.getConstArray();
127 for (sal_Int16 i
=0; i
<aDescripts
.getLength(); ++i
, ++pReturn
, ++pDescripts
)
129 *pReturn
= queryDispatch(pDescripts
->FeatureURL
,
130 pDescripts
->FrameName
, pDescripts
->SearchFlags
);
135 // XDispatchProviderInterceptor
137 uno::Reference
<frame::XDispatchProvider
> SAL_CALL
138 ScDispatchProviderInterceptor::getSlaveDispatchProvider()
139 throw(uno::RuntimeException
, std::exception
)
141 SolarMutexGuard aGuard
;
142 return m_xSlaveDispatcher
;
145 void SAL_CALL
ScDispatchProviderInterceptor::setSlaveDispatchProvider(
146 const uno::Reference
<frame::XDispatchProvider
>& xNewDispatchProvider
)
147 throw(uno::RuntimeException
, std::exception
)
149 SolarMutexGuard aGuard
;
150 m_xSlaveDispatcher
.set(xNewDispatchProvider
);
153 uno::Reference
<frame::XDispatchProvider
> SAL_CALL
154 ScDispatchProviderInterceptor::getMasterDispatchProvider()
155 throw(uno::RuntimeException
, std::exception
)
157 SolarMutexGuard aGuard
;
158 return m_xMasterDispatcher
;
161 void SAL_CALL
ScDispatchProviderInterceptor::setMasterDispatchProvider(
162 const uno::Reference
<frame::XDispatchProvider
>& xNewSupplier
)
163 throw(uno::RuntimeException
, std::exception
)
165 SolarMutexGuard aGuard
;
166 m_xMasterDispatcher
.set(xNewSupplier
);
171 void SAL_CALL
ScDispatchProviderInterceptor::disposing( const lang::EventObject
& /* Source */ )
172 throw(::com::sun::star::uno::RuntimeException
, std::exception
)
174 SolarMutexGuard aGuard
;
176 if (m_xIntercepted
.is())
178 m_xIntercepted
->releaseDispatchProviderInterceptor(
179 static_cast<frame::XDispatchProviderInterceptor
*>(this));
180 uno::Reference
<lang::XComponent
> xInterceptedComponent(m_xIntercepted
, uno::UNO_QUERY
);
181 if (xInterceptedComponent
.is())
182 xInterceptedComponent
->removeEventListener(static_cast<lang::XEventListener
*>(this));
184 m_xMyDispatch
= NULL
;
186 m_xIntercepted
= NULL
;
189 ScDispatch::ScDispatch(ScTabViewShell
* pViewSh
) :
190 pViewShell( pViewSh
),
191 bListeningToView( false )
194 StartListening(*pViewShell
);
197 ScDispatch::~ScDispatch()
200 EndListening(*pViewShell
);
202 if (bListeningToView
&& pViewShell
)
204 uno::Reference
<view::XSelectionSupplier
> xSupplier(lcl_GetSelectionSupplier( pViewShell
));
205 if ( xSupplier
.is() )
206 xSupplier
->removeSelectionChangeListener(this);
210 void ScDispatch::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
212 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
213 if ( pSimpleHint
&& pSimpleHint
->GetId() == SFX_HINT_DYING
)
219 void SAL_CALL
ScDispatch::dispatch( const util::URL
& aURL
,
220 const uno::Sequence
<beans::PropertyValue
>& aArgs
)
221 throw(uno::RuntimeException
, std::exception
)
223 SolarMutexGuard aGuard
;
226 if ( pViewShell
&& aURL
.Complete
.equalsAscii(cURLInsertColumns
) )
228 ScViewData
& rViewData
= pViewShell
->GetViewData();
229 ScAddress
aPos( rViewData
.GetCurX(), rViewData
.GetCurY(), rViewData
.GetTabNo() );
231 ScDBDocFunc
aFunc( *rViewData
.GetDocShell() );
232 bDone
= aFunc
.DoImportUno( aPos
, aArgs
);
234 // cURLDocDataSource is never dispatched
237 throw uno::RuntimeException();
240 static void lcl_FillDataSource( frame::FeatureStateEvent
& rEvent
, const ScImportParam
& rParam
)
242 rEvent
.IsEnabled
= rParam
.bImport
;
244 svx::ODataAccessDescriptor aDescriptor
;
245 if ( rParam
.bImport
)
247 sal_Int32 nType
= rParam
.bSql
? sdb::CommandType::COMMAND
:
248 ( (rParam
.nType
== ScDbQuery
) ? sdb::CommandType::QUERY
:
249 sdb::CommandType::TABLE
);
251 aDescriptor
.setDataSource(rParam
.aDBName
);
252 aDescriptor
[svx::daCommand
] <<= rParam
.aStatement
;
253 aDescriptor
[svx::daCommandType
] <<= nType
;
257 // descriptor has to be complete anyway
260 aDescriptor
[svx::daDataSource
] <<= aEmpty
;
261 aDescriptor
[svx::daCommand
] <<= aEmpty
;
262 aDescriptor
[svx::daCommandType
] <<= (sal_Int32
)sdb::CommandType::TABLE
;
264 rEvent
.State
<<= aDescriptor
.createPropertyValueSequence();
267 void SAL_CALL
ScDispatch::addStatusListener(
268 const uno::Reference
<frame::XStatusListener
>& xListener
,
269 const util::URL
& aURL
)
270 throw(uno::RuntimeException
, std::exception
)
272 SolarMutexGuard aGuard
;
275 throw uno::RuntimeException();
278 frame::FeatureStateEvent aEvent
;
279 aEvent
.IsEnabled
= sal_True
;
280 aEvent
.Source
.set(static_cast<cppu::OWeakObject
*>(this));
281 aEvent
.FeatureURL
= aURL
;
283 if ( aURL
.Complete
.equalsAscii(cURLDocDataSource
) )
285 uno::Reference
<frame::XStatusListener
>* pObj
=
286 new uno::Reference
<frame::XStatusListener
>( xListener
);
287 aDataSourceListeners
.push_back( pObj
);
289 if (!bListeningToView
)
291 uno::Reference
<view::XSelectionSupplier
> xSupplier(lcl_GetSelectionSupplier( pViewShell
));
292 if ( xSupplier
.is() )
293 xSupplier
->addSelectionChangeListener(this);
294 bListeningToView
= true;
297 ScDBData
* pDBData
= pViewShell
->GetDBData(false,SC_DB_OLD
);
299 pDBData
->GetImportParam( aLastImport
);
300 lcl_FillDataSource( aEvent
, aLastImport
); // modifies State, IsEnabled
302 //! else add to listener for "enabled" changes?
304 xListener
->statusChanged( aEvent
);
307 void SAL_CALL
ScDispatch::removeStatusListener(
308 const uno::Reference
<frame::XStatusListener
>& xListener
,
309 const util::URL
& aURL
)
310 throw(uno::RuntimeException
, std::exception
)
312 SolarMutexGuard aGuard
;
314 if ( aURL
.Complete
.equalsAscii(cURLDocDataSource
) )
316 sal_uInt16 nCount
= aDataSourceListeners
.size();
317 for ( sal_uInt16 n
=nCount
; n
--; )
319 uno::Reference
<frame::XStatusListener
>& rObj
= aDataSourceListeners
[n
];
320 if ( rObj
== xListener
)
322 aDataSourceListeners
.erase( aDataSourceListeners
.begin() + n
);
327 if ( aDataSourceListeners
.empty() && pViewShell
)
329 uno::Reference
<view::XSelectionSupplier
> xSupplier(lcl_GetSelectionSupplier( pViewShell
));
330 if ( xSupplier
.is() )
331 xSupplier
->removeSelectionChangeListener(this);
332 bListeningToView
= false;
337 // XSelectionChangeListener
339 void SAL_CALL
ScDispatch::selectionChanged( const ::com::sun::star::lang::EventObject
& /* aEvent */ )
340 throw (::com::sun::star::uno::RuntimeException
, std::exception
)
342 // currently only called for URL cURLDocDataSource
346 ScImportParam aNewImport
;
347 ScDBData
* pDBData
= pViewShell
->GetDBData(false,SC_DB_OLD
);
349 pDBData
->GetImportParam( aNewImport
);
351 // notify listeners only if data source has changed
352 if ( aNewImport
.bImport
!= aLastImport
.bImport
||
353 aNewImport
.aDBName
!= aLastImport
.aDBName
||
354 aNewImport
.aStatement
!= aLastImport
.aStatement
||
355 aNewImport
.bSql
!= aLastImport
.bSql
||
356 aNewImport
.nType
!= aLastImport
.nType
)
358 frame::FeatureStateEvent aEvent
;
359 aEvent
.Source
.set(static_cast<cppu::OWeakObject
*>(this));
360 aEvent
.FeatureURL
.Complete
= OUString::createFromAscii( cURLDocDataSource
);
362 lcl_FillDataSource( aEvent
, aNewImport
); // modifies State, IsEnabled
364 for ( sal_uInt16 n
=0; n
<aDataSourceListeners
.size(); n
++ )
365 aDataSourceListeners
[n
]->statusChanged( aEvent
);
367 aLastImport
= aNewImport
;
374 void SAL_CALL
ScDispatch::disposing( const ::com::sun::star::lang::EventObject
& rSource
)
375 throw (::com::sun::star::uno::RuntimeException
, std::exception
)
377 uno::Reference
<view::XSelectionSupplier
> xSupplier(rSource
.Source
, uno::UNO_QUERY
);
378 xSupplier
->removeSelectionChangeListener(this);
379 bListeningToView
= false;
381 lang::EventObject aEvent
;
382 aEvent
.Source
.set(static_cast<cppu::OWeakObject
*>(this));
383 for ( sal_uInt16 n
=0; n
<aDataSourceListeners
.size(); n
++ )
384 aDataSourceListeners
[n
]->disposing( aEvent
);
389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */