1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: intercept.cxx,v $
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_dbaccess.hxx"
34 #ifndef _COM_SUN_STAR_EMBED_EMBEDSTATES_HPP_
35 #include <com/sun/star/embed/EmbedStates.hpp>
37 #ifndef _COM_SUN_STAR_DOCUMENT_XEVENTBROADCASTER_HPP_
38 #include <com/sun/star/document/XEventBroadcaster.hpp>
40 #ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_
41 #include <com/sun/star/util/XModifiable.hpp>
43 #ifndef _CPPUHELPER_WEAK_HXX_
44 #include <cppuhelper/weak.hxx>
46 #ifndef _COMPHELPER_TYPES_HXX_
47 #include <comphelper/types.hxx>
49 #ifndef DBA_INTERCEPT_HXX
50 #include "intercept.hxx"
52 #include "dbastrings.hrc"
53 #ifndef _TOOLS_DEBUG_HXX
54 #include <tools/debug.hxx>
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::util
;
62 using namespace ::com::sun::star::ucb
;
63 using namespace ::com::sun::star::beans
;
64 using namespace ::com::sun::star::lang
;
65 using namespace ::com::sun::star::sdbc
;
66 using namespace ::com::sun::star::frame
;
67 using namespace ::com::sun::star::io
;
68 using namespace ::com::sun::star::embed
;
69 using namespace ::com::sun::star::container
;
70 using namespace ::comphelper
;
71 using namespace ::cppu
;
73 #define DISPATCH_SAVEAS 0
74 #define DISPATCH_SAVE 1
75 #define DISPATCH_CLOSEDOC 2
76 #define DISPATCH_CLOSEWIN 3
77 #define DISPATCH_CLOSEFRAME 4
78 #define DISPATCH_RELOAD 5
79 // the OSL_ENSURE in CTOR has to be changed too, when adding new defines
81 void SAL_CALL
OInterceptor::dispose()
82 throw( RuntimeException
)
84 EventObject
aEvt( *this );
86 osl::MutexGuard
aGuard(m_aMutex
);
88 if ( m_pDisposeEventListeners
&& m_pDisposeEventListeners
->getLength() )
89 m_pDisposeEventListeners
->disposeAndClear( aEvt
);
92 m_pStatCL
->disposeAndClear( aEvt
);
94 m_xSlaveDispatchProvider
.clear();
95 m_xMasterDispatchProvider
.clear();
97 m_pContentHolder
= NULL
;
101 DBG_NAME(OInterceptor
)
103 OInterceptor::OInterceptor( ODocumentDefinition
* _pContentHolder
,sal_Bool _bAllowEditDoc
)
104 :m_pContentHolder( _pContentHolder
)
105 ,m_aInterceptedURL(7)
106 ,m_pDisposeEventListeners(0)
108 ,m_bAllowEditDoc(_bAllowEditDoc
)
110 DBG_CTOR(OInterceptor
,NULL
);
112 OSL_ENSURE(DISPATCH_RELOAD
< m_aInterceptedURL
.getLength(),"Illegal size.");
114 m_aInterceptedURL
[DISPATCH_SAVEAS
] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
115 m_aInterceptedURL
[DISPATCH_SAVE
] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
116 m_aInterceptedURL
[DISPATCH_CLOSEDOC
] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
117 m_aInterceptedURL
[DISPATCH_CLOSEWIN
] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
118 m_aInterceptedURL
[DISPATCH_CLOSEFRAME
] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
119 m_aInterceptedURL
[DISPATCH_RELOAD
] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Reload"));
123 OInterceptor::~OInterceptor()
125 if( m_pDisposeEventListeners
)
126 delete m_pDisposeEventListeners
;
131 DBG_DTOR(OInterceptor
,NULL
);
134 struct DispatchHelper
137 Sequence
<PropertyValue
> aArguments
;
141 void SAL_CALL
OInterceptor::dispatch( const URL
& _URL
,const Sequence
<PropertyValue
>& Arguments
) throw (RuntimeException
)
143 osl::ClearableMutexGuard
aClearableGuard(m_aMutex
);
144 if( m_pContentHolder
)
146 if( _URL
.Complete
== m_aInterceptedURL
[DISPATCH_SAVE
] )
148 m_pContentHolder
->save(sal_False
);
150 else if( _URL
.Complete
== m_aInterceptedURL
[DISPATCH_RELOAD
] )
152 m_pContentHolder
->fillReportData(aClearableGuard
);
153 // IMPORTANT: m_aMutex is cleared!
155 else if( _URL
.Complete
== m_aInterceptedURL
[DISPATCH_SAVEAS
] )
157 if ( m_pContentHolder
->isNewReport() )
159 m_pContentHolder
->saveAs();
161 else if ( m_xSlaveDispatchProvider
.is() )
163 Sequence
< PropertyValue
> aNewArgs
= Arguments
;
166 while( nInd
< aNewArgs
.getLength() )
168 if ( aNewArgs
[nInd
].Name
.equalsAscii( "SaveTo" ) )
170 aNewArgs
[nInd
].Value
<<= sal_True
;
176 if ( nInd
== aNewArgs
.getLength() )
178 aNewArgs
.realloc( nInd
+ 1 );
179 aNewArgs
[nInd
].Name
= ::rtl::OUString::createFromAscii( "SaveTo" );
180 aNewArgs
[nInd
].Value
<<= sal_True
;
183 Reference
< XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(
184 _URL
, ::rtl::OUString::createFromAscii( "_self" ), 0 );
185 if ( xDispatch
.is() )
186 xDispatch
->dispatch( _URL
, aNewArgs
);
189 else if ( _URL
.Complete
== m_aInterceptedURL
[DISPATCH_CLOSEDOC
]
190 || _URL
.Complete
== m_aInterceptedURL
[DISPATCH_CLOSEWIN
]
191 || _URL
.Complete
== m_aInterceptedURL
[DISPATCH_CLOSEFRAME
])
193 DispatchHelper
* pHelper
= new DispatchHelper
;
194 pHelper
->aArguments
= Arguments
;
195 pHelper
->aURL
= _URL
;
196 Application::PostUserEvent(LINK(this, OInterceptor
, OnDispatch
),reinterpret_cast<void*>(pHelper
) );
200 IMPL_LINK( OInterceptor
, OnDispatch
, void*, _nId
)
202 ::std::auto_ptr
<DispatchHelper
> pHelper(reinterpret_cast<DispatchHelper
*>(_nId
));
205 if ( m_pContentHolder
&& m_pContentHolder
->prepareClose() && m_xSlaveDispatchProvider
.is() )
207 Reference
< XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(
208 pHelper
->aURL
, ::rtl::OUString::createFromAscii( "_self" ), 0 );
209 if ( xDispatch
.is() )
211 Reference
< ::com::sun::star::document::XEventBroadcaster
> xEvtB(m_pContentHolder
->getComponent(),UNO_QUERY
);
213 xEvtB
->removeEventListener(this);
215 Reference
< XInterface
> xKeepContentHolderAlive( *m_pContentHolder
);
216 xDispatch
->dispatch( pHelper
->aURL
,pHelper
->aArguments
);
220 catch(const Exception
&)
222 OSL_ENSURE(sal_False
, "caught an exception while starting the table wizard!");
227 void SAL_CALL
OInterceptor::addStatusListener(
229 XStatusListener
>& Control
,
238 if ( m_pContentHolder
&& _URL
.Complete
== m_aInterceptedURL
[DISPATCH_SAVEAS
] )
241 if ( !m_pContentHolder
->isNewReport() )
243 FeatureStateEvent aStateEvent
;
244 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[DISPATCH_SAVEAS
];
245 aStateEvent
.FeatureDescriptor
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
246 aStateEvent
.IsEnabled
= sal_True
;
247 aStateEvent
.Requery
= sal_False
;
248 aStateEvent
.State
<<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
249 Control
->statusChanged(aStateEvent
);
253 osl::MutexGuard
aGuard(m_aMutex
);
255 m_pStatCL
= new PropertyChangeListenerContainer(m_aMutex
);
258 m_pStatCL
->addInterface(_URL
.Complete
,Control
);
260 else if ( m_pContentHolder
&& _URL
.Complete
== m_aInterceptedURL
[DISPATCH_SAVE
] )
262 FeatureStateEvent aStateEvent
;
263 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[DISPATCH_SAVE
];
264 aStateEvent
.FeatureDescriptor
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update"));
265 aStateEvent
.IsEnabled
= m_pContentHolder
!= NULL
&& m_pContentHolder
->isModified();
266 aStateEvent
.Requery
= sal_False
;
268 Control
->statusChanged(aStateEvent
);
270 osl::MutexGuard
aGuard(m_aMutex
);
272 m_pStatCL
= new PropertyChangeListenerContainer(m_aMutex
);
275 m_pStatCL
->addInterface(_URL
.Complete
,Control
);
276 Reference
< ::com::sun::star::document::XEventBroadcaster
> xEvtB(m_pContentHolder
->getComponent(),UNO_QUERY
);
278 xEvtB
->addEventListener(this);
283 if(_URL
.Complete
== m_aInterceptedURL
[i
] ||
284 _URL
.Complete
== m_aInterceptedURL
[++i
] ||
285 _URL
.Complete
== m_aInterceptedURL
[++i
] ||
286 _URL
.Complete
== m_aInterceptedURL
[i
= DISPATCH_RELOAD
] )
287 { // Close and return
288 FeatureStateEvent aStateEvent
;
289 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
290 aStateEvent
.FeatureDescriptor
= rtl::OUString(
291 RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
292 aStateEvent
.IsEnabled
= sal_True
;
293 aStateEvent
.Requery
= sal_False
;
294 Control
->statusChanged(aStateEvent
);
298 osl::MutexGuard
aGuard(m_aMutex
);
300 m_pStatCL
= new PropertyChangeListenerContainer(m_aMutex
);
303 m_pStatCL
->addInterface(_URL
.Complete
,Control
);
310 void SAL_CALL
OInterceptor::removeStatusListener(
312 XStatusListener
>& Control
,
318 if(!(Control
.is() && m_pStatCL
))
322 m_pStatCL
->removeInterface(_URL
.Complete
,Control
);
329 Sequence
< ::rtl::OUString
> SAL_CALL
OInterceptor::getInterceptedURLs( ) throw ( RuntimeException
)
331 // now implemented as update
332 return m_aInterceptedURL
;
338 Reference
< XDispatch
> SAL_CALL
OInterceptor::queryDispatch( const URL
& _URL
,const ::rtl::OUString
& TargetFrameName
,sal_Int32 SearchFlags
)
339 throw (RuntimeException
)
341 osl::MutexGuard
aGuard(m_aMutex
);
342 const ::rtl::OUString
* pIter
= m_aInterceptedURL
.getConstArray();
343 const ::rtl::OUString
* pEnd
= pIter
+ m_aInterceptedURL
.getLength();
344 for(;pIter
!= pEnd
;++pIter
)
346 if ( _URL
.Complete
== *pIter
)
347 return (XDispatch
*)this;
350 if(m_xSlaveDispatchProvider
.is())
351 return m_xSlaveDispatchProvider
->queryDispatch(_URL
,TargetFrameName
,SearchFlags
);
353 return Reference
<XDispatch
>();
356 Sequence
< Reference
< XDispatch
> > SAL_CALL
OInterceptor::queryDispatches( const Sequence
<DispatchDescriptor
>& Requests
) throw ( RuntimeException
)
358 Sequence
< Reference
< XDispatch
> > aRet
;
359 osl::MutexGuard
aGuard(m_aMutex
);
360 if(m_xSlaveDispatchProvider
.is())
361 aRet
= m_xSlaveDispatchProvider
->queryDispatches(Requests
);
363 aRet
.realloc(Requests
.getLength());
365 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
367 const ::rtl::OUString
* pIter
= m_aInterceptedURL
.getConstArray();
368 const ::rtl::OUString
* pEnd
= pIter
+ m_aInterceptedURL
.getLength();
369 for(;pIter
!= pEnd
;++pIter
)
371 if ( Requests
[i
].FeatureURL
.Complete
== *pIter
)
373 aRet
[i
] = (XDispatch
*) this;
384 //XDispatchProviderInterceptor
386 Reference
< XDispatchProvider
> SAL_CALL
OInterceptor::getSlaveDispatchProvider( ) throw ( RuntimeException
)
388 osl::MutexGuard
aGuard(m_aMutex
);
389 return m_xSlaveDispatchProvider
;
393 OInterceptor::setSlaveDispatchProvider( const Reference
< XDispatchProvider
>& NewDispatchProvider
)
394 throw ( RuntimeException
)
396 osl::MutexGuard
aGuard(m_aMutex
);
397 m_xSlaveDispatchProvider
= NewDispatchProvider
;
401 Reference
< XDispatchProvider
> SAL_CALL
OInterceptor::getMasterDispatchProvider( )
406 osl::MutexGuard
aGuard(m_aMutex
);
407 return m_xMasterDispatchProvider
;
411 void SAL_CALL
OInterceptor::setMasterDispatchProvider(
412 const Reference
< XDispatchProvider
>& NewSupplier
)
417 osl::MutexGuard
aGuard(m_aMutex
);
418 m_xMasterDispatchProvider
= NewSupplier
;
420 // -----------------------------------------------------------------------------
421 void SAL_CALL
OInterceptor::notifyEvent( const ::com::sun::star::document::EventObject
& Event
) throw (::com::sun::star::uno::RuntimeException
)
423 osl::ResettableMutexGuard
_rGuard(m_aMutex
);
424 if ( m_pStatCL
&& Event
.EventName
== ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnModifyChanged")) )
426 OInterfaceContainerHelper
* pListener
= m_pStatCL
->getContainer(m_aInterceptedURL
[DISPATCH_SAVE
]);
429 FeatureStateEvent aEvt
;
430 aEvt
.FeatureURL
.Complete
= m_aInterceptedURL
[DISPATCH_SAVE
];
431 aEvt
.FeatureDescriptor
= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update"));
432 Reference
<XModifiable
> xModel(Event
.Source
,UNO_QUERY
);
433 aEvt
.IsEnabled
= xModel
.is() && xModel
->isModified();
434 aEvt
.Requery
= sal_False
;
436 NOTIFY_LISTERNERS((*pListener
),XStatusListener
,statusChanged
)
440 // -----------------------------------------------------------------------------
441 void SAL_CALL
OInterceptor::disposing( const ::com::sun::star::lang::EventObject
& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException
)
445 //........................................................................
446 } // namespace dbaccess
447 //........................................................................