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 <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"
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
)
48 SfxViewFrame
* pViewFrame
= pViewShell
->GetViewFrame();
51 return uno::Reference
<view::XSelectionSupplier
>( pViewFrame
->GetFrame().GetController(), uno::UNO_QUERY
);
54 return uno::Reference
<view::XSelectionSupplier
>();
57 //------------------------------------------------------------------------
60 ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell
* pViewSh
) :
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()
88 EndListening(*pViewShell
);
91 void ScDispatchProviderInterceptor::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
93 if ( rHint
.ISA( SfxSimpleHint
) &&
94 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DYING
)
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 ...
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
);
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
);
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
);
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 )
204 StartListening(*pViewShell
);
207 ScDispatch::~ScDispatch()
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
)
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
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
;
267 // descriptor has to be complete anyway
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
;
285 throw uno::RuntimeException();
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
);
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
);
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
356 ScImportParam aNewImport
;
357 ScDBData
* pDBData
= pViewShell
->GetDBData(false,SC_DB_OLD
);
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
;
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
);
399 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */