Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <sfx2/viewfrm.hxx>
30 : : #include <comphelper/uno3.hxx>
31 : : #include <svx/dataaccessdescriptor.hxx>
32 : : #include <svl/smplhint.hxx>
33 : : #include <vcl/svapp.hxx>
34 : :
35 : : #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
36 : : #include <com/sun/star/view/XSelectionSupplier.hpp>
37 : : #include <com/sun/star/sdb/CommandType.hpp>
38 : :
39 : : #include "dispuno.hxx"
40 : : #include "tabvwsh.hxx"
41 : : #include "dbdocfun.hxx"
42 : : #include "dbdata.hxx"
43 : :
44 : : using namespace com::sun::star;
45 : :
46 : : //------------------------------------------------------------------------
47 : :
48 : : const char* cURLInsertColumns = ".uno:DataSourceBrowser/InsertColumns"; //data into text
49 : : const char* cURLDocDataSource = ".uno:DataSourceBrowser/DocumentDataSource";
50 : :
51 : : //------------------------------------------------------------------------
52 : :
53 : 0 : uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( SfxViewShell* pViewShell )
54 : : {
55 [ # # ]: 0 : if ( pViewShell )
56 : : {
57 : 0 : SfxViewFrame* pViewFrame = pViewShell->GetViewFrame();
58 [ # # ]: 0 : if (pViewFrame)
59 : : {
60 [ # # ]: 0 : return uno::Reference<view::XSelectionSupplier>( pViewFrame->GetFrame().GetController(), uno::UNO_QUERY );
61 : : }
62 : : }
63 : 0 : return uno::Reference<view::XSelectionSupplier>();
64 : : }
65 : :
66 : : //------------------------------------------------------------------------
67 : :
68 : :
69 : 229 : ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell* pViewSh) :
70 [ + - ]: 229 : pViewShell( pViewSh )
71 : : {
72 [ + - ]: 229 : if ( pViewShell )
73 : : {
74 [ + - ][ + - ]: 229 : m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY));
[ + - ][ + - ]
75 [ + - ]: 229 : if (m_xIntercepted.is())
76 : : {
77 [ + - ]: 229 : comphelper::increment( m_refCount );
78 : :
79 [ + - ]: 229 : m_xIntercepted->registerDispatchProviderInterceptor(
80 [ + - ][ + - ]: 229 : static_cast<frame::XDispatchProviderInterceptor*>(this));
81 : : // this should make us the top-level dispatch-provider for the component, via a call to our
82 : : // setDispatchProvider we should have got an fallback for requests we (i.e. our master) cannot fullfill
83 [ + - ]: 229 : uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
84 [ + - ]: 229 : if (xInterceptedComponent.is())
85 [ + - ][ + - ]: 229 : xInterceptedComponent->addEventListener(static_cast<lang::XEventListener*>(this));
[ + - ]
86 : :
87 [ + - ]: 229 : comphelper::decrement( m_refCount );
88 : : }
89 : :
90 [ + - ]: 229 : StartListening(*pViewShell);
91 : : }
92 : 229 : }
93 : :
94 [ + - ]: 225 : ScDispatchProviderInterceptor::~ScDispatchProviderInterceptor()
95 : : {
96 [ - + ]: 225 : if (pViewShell)
97 [ # # ]: 0 : EndListening(*pViewShell);
98 [ - + ]: 450 : }
99 : :
100 : 225 : void ScDispatchProviderInterceptor::Notify( SfxBroadcaster&, const SfxHint& rHint )
101 : : {
102 [ + - + - ]: 450 : if ( rHint.ISA( SfxSimpleHint ) &&
[ + - ]
103 : 225 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
104 : 225 : pViewShell = NULL;
105 : 225 : }
106 : :
107 : : // XDispatchProvider
108 : :
109 : 35951 : uno::Reference<frame::XDispatch> SAL_CALL ScDispatchProviderInterceptor::queryDispatch(
110 : : const util::URL& aURL, const rtl::OUString& aTargetFrameName,
111 : : sal_Int32 nSearchFlags )
112 : : throw(uno::RuntimeException)
113 : : {
114 [ + - ]: 35951 : SolarMutexGuard aGuard;
115 : :
116 : 35951 : uno::Reference<frame::XDispatch> xResult;
117 : : // create some dispatch ...
118 [ - + ][ + + : 103405 : if ( pViewShell && (
+ - - + ]
119 : 33727 : !aURL.Complete.compareToAscii(cURLInsertColumns) ||
120 : 33727 : !aURL.Complete.compareToAscii(cURLDocDataSource) ) )
121 : : {
122 [ # # ]: 0 : if (!m_xMyDispatch.is())
123 [ # # ][ # # ]: 0 : m_xMyDispatch = new ScDispatch( pViewShell );
[ # # ]
124 [ # # ]: 0 : xResult = m_xMyDispatch;
125 : : }
126 : :
127 : : // ask our slave provider
128 [ + - ][ + - ]: 35951 : if (!xResult.is() && m_xSlaveDispatcher.is())
[ + - ]
129 [ + - ][ + - ]: 35951 : xResult = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
[ + - ]
130 : :
131 [ + - ]: 35951 : return xResult;
132 : : }
133 : :
134 : : uno::Sequence< uno::Reference<frame::XDispatch> > SAL_CALL
135 : 0 : ScDispatchProviderInterceptor::queryDispatches(
136 : : const uno::Sequence<frame::DispatchDescriptor>& aDescripts )
137 : : throw(uno::RuntimeException)
138 : : {
139 [ # # ]: 0 : SolarMutexGuard aGuard;
140 : :
141 [ # # ]: 0 : uno::Sequence< uno::Reference< frame::XDispatch> > aReturn(aDescripts.getLength());
142 [ # # ]: 0 : uno::Reference< frame::XDispatch>* pReturn = aReturn.getArray();
143 : 0 : const frame::DispatchDescriptor* pDescripts = aDescripts.getConstArray();
144 [ # # ]: 0 : for (sal_Int16 i=0; i<aDescripts.getLength(); ++i, ++pReturn, ++pDescripts)
145 : : {
146 : : *pReturn = queryDispatch(pDescripts->FeatureURL,
147 [ # # ][ # # ]: 0 : pDescripts->FrameName, pDescripts->SearchFlags);
148 : : }
149 [ # # ]: 0 : return aReturn;
150 : : }
151 : :
152 : : // XDispatchProviderInterceptor
153 : :
154 : : uno::Reference<frame::XDispatchProvider> SAL_CALL
155 : 225 : ScDispatchProviderInterceptor::getSlaveDispatchProvider()
156 : : throw(uno::RuntimeException)
157 : : {
158 [ + - ]: 225 : SolarMutexGuard aGuard;
159 [ + - ]: 225 : return m_xSlaveDispatcher;
160 : : }
161 : :
162 : 454 : void SAL_CALL ScDispatchProviderInterceptor::setSlaveDispatchProvider(
163 : : const uno::Reference<frame::XDispatchProvider>& xNewDispatchProvider )
164 : : throw(uno::RuntimeException)
165 : : {
166 [ + - ]: 454 : SolarMutexGuard aGuard;
167 [ + - ][ + - ]: 454 : m_xSlaveDispatcher.set(xNewDispatchProvider);
168 : 454 : }
169 : :
170 : : uno::Reference<frame::XDispatchProvider> SAL_CALL
171 : 225 : ScDispatchProviderInterceptor::getMasterDispatchProvider()
172 : : throw(uno::RuntimeException)
173 : : {
174 [ + - ]: 225 : SolarMutexGuard aGuard;
175 [ + - ]: 225 : return m_xMasterDispatcher;
176 : : }
177 : :
178 : 454 : void SAL_CALL ScDispatchProviderInterceptor::setMasterDispatchProvider(
179 : : const uno::Reference<frame::XDispatchProvider>& xNewSupplier )
180 : : throw(uno::RuntimeException)
181 : : {
182 [ + - ]: 454 : SolarMutexGuard aGuard;
183 [ + - ][ + - ]: 454 : m_xMasterDispatcher.set(xNewSupplier);
184 : 454 : }
185 : :
186 : : // XEventListener
187 : :
188 : 225 : void SAL_CALL ScDispatchProviderInterceptor::disposing( const lang::EventObject& /* Source */ )
189 : : throw(::com::sun::star::uno::RuntimeException)
190 : : {
191 [ + - ]: 225 : SolarMutexGuard aGuard;
192 : :
193 [ + - ]: 225 : if (m_xIntercepted.is())
194 : : {
195 [ + - ]: 225 : m_xIntercepted->releaseDispatchProviderInterceptor(
196 [ + - ][ + - ]: 225 : static_cast<frame::XDispatchProviderInterceptor*>(this));
197 [ + - ]: 225 : uno::Reference<lang::XComponent> xInterceptedComponent(m_xIntercepted, uno::UNO_QUERY);
198 [ + - ]: 225 : if (xInterceptedComponent.is())
199 [ + - ][ + - ]: 225 : xInterceptedComponent->removeEventListener(static_cast<lang::XEventListener*>(this));
[ + - ]
200 : :
201 [ + - ]: 225 : m_xMyDispatch = NULL;
202 : : }
203 [ + - ][ + - ]: 225 : m_xIntercepted = NULL;
204 : 225 : }
205 : :
206 : : //------------------------------------------------------------------------
207 : :
208 : 0 : ScDispatch::ScDispatch(ScTabViewShell* pViewSh) :
209 : : pViewShell( pViewSh ),
210 [ # # ][ # # ]: 0 : bListeningToView( false )
[ # # ]
211 : : {
212 [ # # ]: 0 : if (pViewShell)
213 [ # # ]: 0 : StartListening(*pViewShell);
214 : 0 : }
215 : :
216 [ # # ][ # # ]: 0 : ScDispatch::~ScDispatch()
[ # # ]
217 : : {
218 [ # # ]: 0 : if (pViewShell)
219 [ # # ]: 0 : EndListening(*pViewShell);
220 : :
221 [ # # ][ # # ]: 0 : if (bListeningToView && pViewShell)
222 : : {
223 [ # # ]: 0 : uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
224 [ # # ]: 0 : if ( xSupplier.is() )
225 [ # # ][ # # ]: 0 : xSupplier->removeSelectionChangeListener(this);
[ # # ]
226 : : }
227 [ # # ]: 0 : }
228 : :
229 : 0 : void ScDispatch::Notify( SfxBroadcaster&, const SfxHint& rHint )
230 : : {
231 [ # # # # ]: 0 : if ( rHint.ISA( SfxSimpleHint ) &&
[ # # ]
232 : 0 : ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
233 : 0 : pViewShell = NULL;
234 : 0 : }
235 : :
236 : : // XDispatch
237 : :
238 : 0 : void SAL_CALL ScDispatch::dispatch( const util::URL& aURL,
239 : : const uno::Sequence<beans::PropertyValue>& aArgs )
240 : : throw(uno::RuntimeException)
241 : : {
242 [ # # ]: 0 : SolarMutexGuard aGuard;
243 : :
244 : 0 : sal_Bool bDone = false;
245 [ # # ][ # # ]: 0 : if ( pViewShell && !aURL.Complete.compareToAscii(cURLInsertColumns) )
[ # # ]
246 : : {
247 : 0 : ScViewData* pViewData = pViewShell->GetViewData();
248 : 0 : ScAddress aPos( pViewData->GetCurX(), pViewData->GetCurY(), pViewData->GetTabNo() );
249 : :
250 : 0 : ScDBDocFunc aFunc( *pViewData->GetDocShell() );
251 [ # # ]: 0 : bDone = aFunc.DoImportUno( aPos, aArgs );
252 : : }
253 : : // cURLDocDataSource is never dispatched
254 : :
255 [ # # ]: 0 : if (!bDone)
256 [ # # ][ # # ]: 0 : throw uno::RuntimeException();
257 : 0 : }
258 : :
259 : 0 : void lcl_FillDataSource( frame::FeatureStateEvent& rEvent, const ScImportParam& rParam )
260 : : {
261 : 0 : rEvent.IsEnabled = rParam.bImport;
262 : :
263 [ # # ]: 0 : ::svx::ODataAccessDescriptor aDescriptor;
264 [ # # ]: 0 : if ( rParam.bImport )
265 : : {
266 : : sal_Int32 nType = rParam.bSql ? sdb::CommandType::COMMAND :
267 : : ( (rParam.nType == ScDbQuery) ? sdb::CommandType::QUERY :
268 [ # # ][ # # ]: 0 : sdb::CommandType::TABLE );
269 : :
270 [ # # ]: 0 : aDescriptor.setDataSource(rParam.aDBName);
271 [ # # ][ # # ]: 0 : aDescriptor[svx::daCommand] <<= rParam.aStatement;
272 [ # # ][ # # ]: 0 : aDescriptor[svx::daCommandType] <<= nType;
273 : : }
274 : : else
275 : : {
276 : : // descriptor has to be complete anyway
277 : :
278 : 0 : rtl::OUString aEmpty;
279 [ # # ][ # # ]: 0 : aDescriptor[svx::daDataSource] <<= aEmpty;
280 [ # # ][ # # ]: 0 : aDescriptor[svx::daCommand] <<= aEmpty;
281 [ # # ][ # # ]: 0 : aDescriptor[svx::daCommandType] <<= (sal_Int32)sdb::CommandType::TABLE;
282 : : }
283 [ # # ][ # # ]: 0 : rEvent.State <<= aDescriptor.createPropertyValueSequence();
[ # # ][ # # ]
284 : 0 : }
285 : :
286 : 0 : void SAL_CALL ScDispatch::addStatusListener(
287 : : const uno::Reference<frame::XStatusListener>& xListener,
288 : : const util::URL& aURL )
289 : : throw(uno::RuntimeException)
290 : : {
291 [ # # ]: 0 : SolarMutexGuard aGuard;
292 : :
293 [ # # ]: 0 : if (!pViewShell)
294 [ # # ]: 0 : throw uno::RuntimeException();
295 : :
296 : : // initial state
297 [ # # ]: 0 : frame::FeatureStateEvent aEvent;
298 : 0 : aEvent.IsEnabled = sal_True;
299 [ # # ]: 0 : aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
300 : 0 : aEvent.FeatureURL = aURL;
301 : :
302 [ # # ]: 0 : if ( !aURL.Complete.compareToAscii(cURLDocDataSource) )
303 : : {
304 : : uno::Reference<frame::XStatusListener>* pObj =
305 : 0 : new uno::Reference<frame::XStatusListener>( xListener );
306 [ # # ]: 0 : aDataSourceListeners.push_back( pObj );
307 : :
308 [ # # ]: 0 : if (!bListeningToView)
309 : : {
310 [ # # ]: 0 : uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
311 [ # # ]: 0 : if ( xSupplier.is() )
312 [ # # ][ # # ]: 0 : xSupplier->addSelectionChangeListener(this);
[ # # ]
313 : 0 : bListeningToView = sal_True;
314 : : }
315 : :
316 [ # # ]: 0 : ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
317 [ # # ]: 0 : if ( pDBData )
318 [ # # ]: 0 : pDBData->GetImportParam( aLastImport );
319 [ # # ]: 0 : lcl_FillDataSource( aEvent, aLastImport ); // modifies State, IsEnabled
320 : : }
321 : : //! else add to listener for "enabled" changes?
322 : :
323 [ # # ][ # # ]: 0 : xListener->statusChanged( aEvent );
[ # # ][ # # ]
324 : 0 : }
325 : :
326 : 0 : void SAL_CALL ScDispatch::removeStatusListener(
327 : : const uno::Reference<frame::XStatusListener>& xListener,
328 : : const util::URL& aURL )
329 : : throw(uno::RuntimeException)
330 : : {
331 [ # # ]: 0 : SolarMutexGuard aGuard;
332 : :
333 [ # # ]: 0 : if ( !aURL.Complete.compareToAscii(cURLDocDataSource) )
334 : : {
335 : 0 : sal_uInt16 nCount = aDataSourceListeners.size();
336 [ # # ]: 0 : for ( sal_uInt16 n=nCount; n--; )
337 : : {
338 [ # # ]: 0 : uno::Reference<frame::XStatusListener>& rObj = aDataSourceListeners[n];
339 [ # # ][ # # ]: 0 : if ( rObj == xListener )
340 : : {
341 [ # # ][ # # ]: 0 : aDataSourceListeners.erase( aDataSourceListeners.begin() + n );
[ # # ]
342 : 0 : break;
343 : : }
344 : : }
345 : :
346 [ # # ][ # # ]: 0 : if ( aDataSourceListeners.empty() && pViewShell )
[ # # ]
347 : : {
348 [ # # ]: 0 : uno::Reference<view::XSelectionSupplier> xSupplier(lcl_GetSelectionSupplier( pViewShell ));
349 [ # # ]: 0 : if ( xSupplier.is() )
350 [ # # ][ # # ]: 0 : xSupplier->removeSelectionChangeListener(this);
[ # # ]
351 : 0 : bListeningToView = false;
352 : : }
353 [ # # ]: 0 : }
354 : 0 : }
355 : :
356 : : // XSelectionChangeListener
357 : :
358 : 0 : void SAL_CALL ScDispatch::selectionChanged( const ::com::sun::star::lang::EventObject& /* aEvent */ )
359 : : throw (::com::sun::star::uno::RuntimeException)
360 : : {
361 : : // currently only called for URL cURLDocDataSource
362 : :
363 [ # # ]: 0 : if ( pViewShell )
364 : : {
365 [ # # ]: 0 : ScImportParam aNewImport;
366 [ # # ]: 0 : ScDBData* pDBData = pViewShell->GetDBData(false,SC_DB_OLD);
367 [ # # ]: 0 : if ( pDBData )
368 [ # # ]: 0 : pDBData->GetImportParam( aNewImport );
369 : :
370 : : // notify listeners only if data source has changed
371 [ # # # # : 0 : if ( aNewImport.bImport != aLastImport.bImport ||
# # ][ # # ]
[ # # ][ # # ]
372 : 0 : aNewImport.aDBName != aLastImport.aDBName ||
373 : 0 : aNewImport.aStatement != aLastImport.aStatement ||
374 : : aNewImport.bSql != aLastImport.bSql ||
375 : : aNewImport.nType != aLastImport.nType )
376 : : {
377 [ # # ]: 0 : frame::FeatureStateEvent aEvent;
378 [ # # ]: 0 : aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
379 : 0 : aEvent.FeatureURL.Complete = rtl::OUString::createFromAscii( cURLDocDataSource );
380 : :
381 [ # # ]: 0 : lcl_FillDataSource( aEvent, aNewImport ); // modifies State, IsEnabled
382 : :
383 [ # # ]: 0 : for ( sal_uInt16 n=0; n<aDataSourceListeners.size(); n++ )
384 [ # # ][ # # ]: 0 : aDataSourceListeners[n]->statusChanged( aEvent );
[ # # ]
385 : :
386 [ # # ][ # # ]: 0 : aLastImport = aNewImport;
387 [ # # ]: 0 : }
388 : : }
389 : 0 : }
390 : :
391 : : // XEventListener
392 : :
393 : 0 : void SAL_CALL ScDispatch::disposing( const ::com::sun::star::lang::EventObject& rSource )
394 : : throw (::com::sun::star::uno::RuntimeException)
395 : : {
396 [ # # ]: 0 : uno::Reference<view::XSelectionSupplier> xSupplier(rSource.Source, uno::UNO_QUERY);
397 [ # # ][ # # ]: 0 : xSupplier->removeSelectionChangeListener(this);
[ # # ]
398 : 0 : bListeningToView = false;
399 : :
400 [ # # ]: 0 : lang::EventObject aEvent;
401 [ # # ]: 0 : aEvent.Source.set(static_cast<cppu::OWeakObject*>(this));
402 [ # # ]: 0 : for ( sal_uInt16 n=0; n<aDataSourceListeners.size(); n++ )
403 [ # # ][ # # ]: 0 : aDataSourceListeners[n]->disposing( aEvent );
[ # # ]
404 : :
405 [ # # ]: 0 : pViewShell = NULL;
406 : 0 : }
407 : :
408 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|