Bump version to 5.0-14
[LibreOffice.git] / dbaccess / source / core / dataaccess / intercept.cxx
blobd0560ab92c381a353c437676f1a04f956df2ca91
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 .
21 #include "intercept.hxx"
22 #include "dbastrings.hrc"
24 #include <com/sun/star/embed/EmbedStates.hpp>
25 #include <com/sun/star/document/XDocumentEventBroadcaster.hpp>
26 #include <com/sun/star/util/XModifiable.hpp>
27 #include <cppuhelper/weak.hxx>
29 #include <comphelper/types.hxx>
30 #include <tools/debug.hxx>
31 #include <tools/diagnose_ex.h>
33 #include <boost/scoped_ptr.hpp>
35 namespace dbaccess
37 using namespace ::com::sun::star::uno;
38 using namespace ::com::sun::star::util;
39 using namespace ::com::sun::star::ucb;
40 using namespace ::com::sun::star::beans;
41 using namespace ::com::sun::star::lang;
42 using namespace ::com::sun::star::sdbc;
43 using namespace ::com::sun::star::frame;
44 using namespace ::com::sun::star::io;
45 using namespace ::com::sun::star::embed;
46 using namespace ::com::sun::star::container;
47 using namespace ::comphelper;
48 using namespace ::cppu;
50 #define DISPATCH_SAVEAS 0
51 #define DISPATCH_SAVE 1
52 #define DISPATCH_CLOSEDOC 2
53 #define DISPATCH_CLOSEWIN 3
54 #define DISPATCH_CLOSEFRAME 4
55 #define DISPATCH_RELOAD 5
56 // the OSL_ENSURE in CTOR has to be changed too, when adding new defines
58 void SAL_CALL OInterceptor::dispose()
59 throw( RuntimeException )
61 EventObject aEvt( *this );
63 osl::MutexGuard aGuard(m_aMutex);
65 if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
66 m_pDisposeEventListeners->disposeAndClear( aEvt );
68 if ( m_pStatCL )
69 m_pStatCL->disposeAndClear( aEvt );
71 m_xSlaveDispatchProvider.clear();
72 m_xMasterDispatchProvider.clear();
74 m_pContentHolder = NULL;
79 OInterceptor::OInterceptor( ODocumentDefinition* _pContentHolder )
80 :m_pContentHolder( _pContentHolder )
81 ,m_aInterceptedURL(7)
82 ,m_pDisposeEventListeners(0)
83 ,m_pStatCL(0)
86 OSL_ENSURE(DISPATCH_RELOAD < m_aInterceptedURL.getLength(),"Illegal size.");
88 m_aInterceptedURL[DISPATCH_SAVEAS] = ".uno:SaveAs";
89 m_aInterceptedURL[DISPATCH_SAVE] = ".uno:Save";
90 m_aInterceptedURL[DISPATCH_CLOSEDOC] = ".uno:CloseDoc";
91 m_aInterceptedURL[DISPATCH_CLOSEWIN] = ".uno:CloseWin";
92 m_aInterceptedURL[DISPATCH_CLOSEFRAME] = ".uno:CloseFrame";
93 m_aInterceptedURL[DISPATCH_RELOAD] = ".uno:Reload";
97 OInterceptor::~OInterceptor()
99 if( m_pDisposeEventListeners )
100 delete m_pDisposeEventListeners;
102 if(m_pStatCL)
103 delete m_pStatCL;
107 struct DispatchHelper
109 URL aURL;
110 Sequence<PropertyValue > aArguments;
113 //XDispatch
114 void SAL_CALL OInterceptor::dispatch( const URL& _URL,const Sequence<PropertyValue >& Arguments ) throw (RuntimeException, std::exception)
116 ::osl::MutexGuard aGuard( m_aMutex );
117 if ( !m_pContentHolder )
118 return;
120 if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVE ] )
122 m_pContentHolder->save( false );
123 return;
126 if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_RELOAD ] )
128 ODocumentDefinition::fillReportData(
129 m_pContentHolder->getContext(),
130 m_pContentHolder->getComponent(),
131 m_pContentHolder->getConnection()
133 return;
136 if( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVEAS ] )
138 if ( m_pContentHolder->isNewReport() )
140 m_pContentHolder->saveAs();
142 else if ( m_xSlaveDispatchProvider.is() )
144 Sequence< PropertyValue > aNewArgs = Arguments;
145 sal_Int32 nInd = 0;
147 while( nInd < aNewArgs.getLength() )
149 if ( aNewArgs[nInd].Name == "SaveTo" )
151 aNewArgs[nInd].Value <<= sal_True;
152 break;
154 nInd++;
157 if ( nInd == aNewArgs.getLength() )
159 aNewArgs.realloc( nInd + 1 );
160 aNewArgs[nInd].Name = "SaveTo";
161 aNewArgs[nInd].Value <<= sal_True;
164 Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(_URL, "_self", 0 );
165 if ( xDispatch.is() )
166 xDispatch->dispatch( _URL, aNewArgs );
168 return;
171 if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEDOC ]
172 || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEWIN ]
173 || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEFRAME ]
176 DispatchHelper* pHelper = new DispatchHelper;
177 pHelper->aArguments = Arguments;
178 pHelper->aURL = _URL;
179 Application::PostUserEvent( LINK( this, OInterceptor, OnDispatch ), pHelper );
180 return;
184 IMPL_LINK( OInterceptor, OnDispatch, void*, _pDispatcher )
186 boost::scoped_ptr<DispatchHelper> pHelper( static_cast< DispatchHelper* >( _pDispatcher ) );
189 if ( m_pContentHolder && m_pContentHolder->prepareClose() && m_xSlaveDispatchProvider.is() )
191 Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(pHelper->aURL, "_self", 0 );
192 if ( xDispatch.is() )
194 Reference< ::com::sun::star::document::XDocumentEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY);
195 if ( xEvtB.is() )
196 xEvtB->removeDocumentEventListener(this);
198 Reference< XInterface > xKeepContentHolderAlive( *m_pContentHolder );
199 xDispatch->dispatch( pHelper->aURL,pHelper->aArguments);
203 catch ( const Exception& )
205 DBG_UNHANDLED_EXCEPTION();
208 return 0L;
211 void SAL_CALL OInterceptor::addStatusListener(
212 const Reference<
213 XStatusListener >& Control,
214 const URL& _URL )
215 throw (
216 RuntimeException, std::exception
219 if(!Control.is())
220 return;
222 if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVEAS] )
223 { // SaveAs
225 if ( !m_pContentHolder->isNewReport() )
227 FeatureStateEvent aStateEvent;
228 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVEAS];
229 aStateEvent.FeatureDescriptor = "SaveCopyTo";
230 aStateEvent.IsEnabled = sal_True;
231 aStateEvent.Requery = sal_False;
232 aStateEvent.State <<= OUString("($3)");
233 Control->statusChanged(aStateEvent);
237 osl::MutexGuard aGuard(m_aMutex);
238 if(!m_pStatCL)
239 m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
242 m_pStatCL->addInterface(_URL.Complete,Control);
244 else if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVE] )
245 { // Save
246 FeatureStateEvent aStateEvent;
247 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE];
248 aStateEvent.FeatureDescriptor = "Update";
249 aStateEvent.IsEnabled = m_pContentHolder != NULL && m_pContentHolder->isModified();
250 aStateEvent.Requery = sal_False;
252 Control->statusChanged(aStateEvent);
254 osl::MutexGuard aGuard(m_aMutex);
255 if(!m_pStatCL)
256 m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
259 m_pStatCL->addInterface(_URL.Complete,Control);
260 Reference< ::com::sun::star::document::XDocumentEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY);
261 if ( xEvtB.is() )
262 xEvtB->addDocumentEventListener(this);
264 else
266 sal_Int32 i = 2;
267 if(_URL.Complete == m_aInterceptedURL[i] ||
268 _URL.Complete == m_aInterceptedURL[++i] ||
269 _URL.Complete == m_aInterceptedURL[++i] ||
270 _URL.Complete == m_aInterceptedURL[i = DISPATCH_RELOAD] )
271 { // Close and return
272 FeatureStateEvent aStateEvent;
273 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
274 aStateEvent.FeatureDescriptor = "Close and Return";
275 aStateEvent.IsEnabled = sal_True;
276 aStateEvent.Requery = sal_False;
277 Control->statusChanged(aStateEvent);
281 osl::MutexGuard aGuard(m_aMutex);
282 if(!m_pStatCL)
283 m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
286 m_pStatCL->addInterface(_URL.Complete,Control);
287 return;
293 void SAL_CALL OInterceptor::removeStatusListener(
294 const Reference<
295 XStatusListener >& Control,
296 const URL& _URL )
297 throw (
298 RuntimeException, std::exception
301 if(!(Control.is() && m_pStatCL))
302 return;
303 else
305 m_pStatCL->removeInterface(_URL.Complete,Control);
306 return;
311 //XInterceptorInfo
312 Sequence< OUString > SAL_CALL OInterceptor::getInterceptedURLs( ) throw ( RuntimeException, std::exception )
314 // now implemented as update
315 return m_aInterceptedURL;
319 // XDispatchProvider
321 Reference< XDispatch > SAL_CALL OInterceptor::queryDispatch( const URL& _URL,const OUString& TargetFrameName,sal_Int32 SearchFlags )
322 throw (RuntimeException, std::exception)
324 osl::MutexGuard aGuard(m_aMutex);
325 const OUString* pIter = m_aInterceptedURL.getConstArray();
326 const OUString* pEnd = pIter + m_aInterceptedURL.getLength();
327 for(;pIter != pEnd;++pIter)
329 if ( _URL.Complete == *pIter )
330 return (XDispatch*)this;
333 if(m_xSlaveDispatchProvider.is())
334 return m_xSlaveDispatchProvider->queryDispatch(_URL,TargetFrameName,SearchFlags);
335 else
336 return Reference<XDispatch>();
339 Sequence< Reference< XDispatch > > SAL_CALL OInterceptor::queryDispatches( const Sequence<DispatchDescriptor >& Requests ) throw ( RuntimeException, std::exception )
341 Sequence< Reference< XDispatch > > aRet;
342 osl::MutexGuard aGuard(m_aMutex);
343 if(m_xSlaveDispatchProvider.is())
344 aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
345 else
346 aRet.realloc(Requests.getLength());
348 for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
350 const OUString* pIter = m_aInterceptedURL.getConstArray();
351 const OUString* pEnd = pIter + m_aInterceptedURL.getLength();
352 for(;pIter != pEnd;++pIter)
354 if ( Requests[i].FeatureURL.Complete == *pIter )
356 aRet[i] = (XDispatch*) this;
357 break;
362 return aRet;
367 //XDispatchProviderInterceptor
369 Reference< XDispatchProvider > SAL_CALL OInterceptor::getSlaveDispatchProvider( ) throw ( RuntimeException, std::exception )
371 osl::MutexGuard aGuard(m_aMutex);
372 return m_xSlaveDispatchProvider;
375 void SAL_CALL
376 OInterceptor::setSlaveDispatchProvider( const Reference< XDispatchProvider >& NewDispatchProvider )
377 throw ( RuntimeException, std::exception )
379 osl::MutexGuard aGuard(m_aMutex);
380 m_xSlaveDispatchProvider = NewDispatchProvider;
384 Reference< XDispatchProvider > SAL_CALL OInterceptor::getMasterDispatchProvider( )
385 throw (
386 RuntimeException, std::exception
389 osl::MutexGuard aGuard(m_aMutex);
390 return m_xMasterDispatchProvider;
394 void SAL_CALL OInterceptor::setMasterDispatchProvider(
395 const Reference< XDispatchProvider >& NewSupplier )
396 throw (
397 RuntimeException, std::exception
400 osl::MutexGuard aGuard(m_aMutex);
401 m_xMasterDispatchProvider = NewSupplier;
404 void SAL_CALL OInterceptor::documentEventOccured( const ::com::sun::star::document::DocumentEvent& Event ) throw (::com::sun::star::uno::RuntimeException, std::exception)
406 osl::ResettableMutexGuard _rGuard(m_aMutex);
407 if ( m_pStatCL && Event.EventName == "OnModifyChanged" )
409 OInterfaceContainerHelper* pListener = m_pStatCL->getContainer(m_aInterceptedURL[DISPATCH_SAVE]);
410 if ( pListener )
412 FeatureStateEvent aEvt;
413 aEvt.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE];
414 aEvt.FeatureDescriptor = "Update";
415 Reference<XModifiable> xModel(Event.Source,UNO_QUERY);
416 aEvt.IsEnabled = xModel.is() && xModel->isModified();
417 aEvt.Requery = sal_False;
419 NOTIFY_LISTERNERS((*pListener),XStatusListener,statusChanged)
424 void SAL_CALL OInterceptor::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException, std::exception)
428 } // namespace dbaccess
430 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */