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 .
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>
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
);
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
)
82 ,m_pDisposeEventListeners(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
;
107 struct DispatchHelper
110 Sequence
<PropertyValue
> aArguments
;
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
)
120 if ( _URL
.Complete
== m_aInterceptedURL
[ DISPATCH_SAVE
] )
122 m_pContentHolder
->save( false );
126 if ( _URL
.Complete
== m_aInterceptedURL
[ DISPATCH_RELOAD
] )
128 ODocumentDefinition::fillReportData(
129 m_pContentHolder
->getContext(),
130 m_pContentHolder
->getComponent(),
131 m_pContentHolder
->getConnection()
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
;
147 while( nInd
< aNewArgs
.getLength() )
149 if ( aNewArgs
[nInd
].Name
== "SaveTo" )
151 aNewArgs
[nInd
].Value
<<= sal_True
;
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
);
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
);
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
);
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();
211 void SAL_CALL
OInterceptor::addStatusListener(
213 XStatusListener
>& Control
,
216 RuntimeException
, std::exception
222 if ( m_pContentHolder
&& _URL
.Complete
== m_aInterceptedURL
[DISPATCH_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
);
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
] )
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
);
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
);
262 xEvtB
->addDocumentEventListener(this);
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
);
283 m_pStatCL
= new PropertyChangeListenerContainer(m_aMutex
);
286 m_pStatCL
->addInterface(_URL
.Complete
,Control
);
293 void SAL_CALL
OInterceptor::removeStatusListener(
295 XStatusListener
>& Control
,
298 RuntimeException
, std::exception
301 if(!(Control
.is() && m_pStatCL
))
305 m_pStatCL
->removeInterface(_URL
.Complete
,Control
);
312 Sequence
< OUString
> SAL_CALL
OInterceptor::getInterceptedURLs( ) throw ( RuntimeException
, std::exception
)
314 // now implemented as update
315 return m_aInterceptedURL
;
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
);
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
);
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;
367 //XDispatchProviderInterceptor
369 Reference
< XDispatchProvider
> SAL_CALL
OInterceptor::getSlaveDispatchProvider( ) throw ( RuntimeException
, std::exception
)
371 osl::MutexGuard
aGuard(m_aMutex
);
372 return m_xSlaveDispatchProvider
;
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( )
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
)
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
]);
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: */