Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include "intercept.hxx"
22 : #include "dbastrings.hrc"
23 :
24 : #include <com/sun/star/embed/EmbedStates.hpp>
25 : #include <com/sun/star/document/XEventBroadcaster.hpp>
26 : #include <com/sun/star/util/XModifiable.hpp>
27 : #include <cppuhelper/weak.hxx>
28 :
29 : #include <comphelper/types.hxx>
30 : #include <tools/debug.hxx>
31 : #include <tools/diagnose_ex.h>
32 :
33 :
34 : namespace dbaccess
35 : {
36 : using namespace ::com::sun::star::uno;
37 : using namespace ::com::sun::star::util;
38 : using namespace ::com::sun::star::ucb;
39 : using namespace ::com::sun::star::beans;
40 : using namespace ::com::sun::star::lang;
41 : using namespace ::com::sun::star::sdbc;
42 : using namespace ::com::sun::star::frame;
43 : using namespace ::com::sun::star::io;
44 : using namespace ::com::sun::star::embed;
45 : using namespace ::com::sun::star::container;
46 : using namespace ::comphelper;
47 : using namespace ::cppu;
48 :
49 : #define DISPATCH_SAVEAS 0
50 : #define DISPATCH_SAVE 1
51 : #define DISPATCH_CLOSEDOC 2
52 : #define DISPATCH_CLOSEWIN 3
53 : #define DISPATCH_CLOSEFRAME 4
54 : #define DISPATCH_RELOAD 5
55 : // the OSL_ENSURE in CTOR has to be changed too, when adding new defines
56 :
57 0 : void SAL_CALL OInterceptor::dispose()
58 : throw( RuntimeException )
59 : {
60 0 : EventObject aEvt( *this );
61 :
62 0 : osl::MutexGuard aGuard(m_aMutex);
63 :
64 0 : if ( m_pDisposeEventListeners && m_pDisposeEventListeners->getLength() )
65 0 : m_pDisposeEventListeners->disposeAndClear( aEvt );
66 :
67 0 : if ( m_pStatCL )
68 0 : m_pStatCL->disposeAndClear( aEvt );
69 :
70 0 : m_xSlaveDispatchProvider.clear();
71 0 : m_xMasterDispatchProvider.clear();
72 :
73 0 : m_pContentHolder = NULL;
74 0 : }
75 :
76 :
77 : DBG_NAME(OInterceptor)
78 :
79 0 : OInterceptor::OInterceptor( ODocumentDefinition* _pContentHolder )
80 : :m_pContentHolder( _pContentHolder )
81 : ,m_aInterceptedURL(7)
82 : ,m_pDisposeEventListeners(0)
83 0 : ,m_pStatCL(0)
84 : {
85 : DBG_CTOR(OInterceptor,NULL);
86 :
87 : OSL_ENSURE(DISPATCH_RELOAD < m_aInterceptedURL.getLength(),"Illegal size.");
88 :
89 0 : m_aInterceptedURL[DISPATCH_SAVEAS] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:SaveAs"));
90 0 : m_aInterceptedURL[DISPATCH_SAVE] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Save"));
91 0 : m_aInterceptedURL[DISPATCH_CLOSEDOC] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseDoc"));
92 0 : m_aInterceptedURL[DISPATCH_CLOSEWIN] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseWin"));
93 0 : m_aInterceptedURL[DISPATCH_CLOSEFRAME] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:CloseFrame"));
94 0 : m_aInterceptedURL[DISPATCH_RELOAD] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:Reload"));
95 0 : }
96 :
97 :
98 0 : OInterceptor::~OInterceptor()
99 : {
100 0 : if( m_pDisposeEventListeners )
101 0 : delete m_pDisposeEventListeners;
102 :
103 0 : if(m_pStatCL)
104 0 : delete m_pStatCL;
105 :
106 : DBG_DTOR(OInterceptor,NULL);
107 0 : }
108 :
109 0 : struct DispatchHelper
110 : {
111 : URL aURL;
112 : Sequence<PropertyValue > aArguments;
113 : };
114 :
115 : //XDispatch
116 0 : void SAL_CALL OInterceptor::dispatch( const URL& _URL,const Sequence<PropertyValue >& Arguments ) throw (RuntimeException)
117 : {
118 0 : ::osl::MutexGuard aGuard( m_aMutex );
119 0 : if ( !m_pContentHolder )
120 : return;
121 :
122 0 : if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVE ] )
123 : {
124 0 : m_pContentHolder->save( sal_False );
125 : return;
126 : }
127 :
128 0 : if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_RELOAD ] )
129 : {
130 : ODocumentDefinition::fillReportData(
131 0 : m_pContentHolder->getContext(),
132 0 : m_pContentHolder->getComponent(),
133 0 : m_pContentHolder->getConnection()
134 0 : );
135 : return;
136 : }
137 :
138 0 : if( _URL.Complete == m_aInterceptedURL[ DISPATCH_SAVEAS ] )
139 : {
140 0 : if ( m_pContentHolder->isNewReport() )
141 : {
142 0 : m_pContentHolder->saveAs();
143 : }
144 0 : else if ( m_xSlaveDispatchProvider.is() )
145 : {
146 0 : Sequence< PropertyValue > aNewArgs = Arguments;
147 0 : sal_Int32 nInd = 0;
148 :
149 0 : while( nInd < aNewArgs.getLength() )
150 : {
151 0 : if ( aNewArgs[nInd].Name == "SaveTo" )
152 : {
153 0 : aNewArgs[nInd].Value <<= sal_True;
154 0 : break;
155 : }
156 0 : nInd++;
157 : }
158 :
159 0 : if ( nInd == aNewArgs.getLength() )
160 : {
161 0 : aNewArgs.realloc( nInd + 1 );
162 0 : aNewArgs[nInd].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SaveTo"));
163 0 : aNewArgs[nInd].Value <<= sal_True;
164 : }
165 :
166 0 : Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
167 0 : _URL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")), 0 );
168 0 : if ( xDispatch.is() )
169 0 : xDispatch->dispatch( _URL, aNewArgs );
170 : }
171 : return;
172 : }
173 :
174 0 : if ( _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEDOC ]
175 0 : || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEWIN ]
176 0 : || _URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEFRAME ]
177 : )
178 : {
179 0 : DispatchHelper* pHelper = new DispatchHelper;
180 0 : pHelper->aArguments = Arguments;
181 0 : pHelper->aURL = _URL;
182 0 : Application::PostUserEvent( LINK( this, OInterceptor, OnDispatch ), reinterpret_cast< void* >( pHelper ) );
183 : return;
184 0 : }
185 : }
186 :
187 0 : IMPL_LINK( OInterceptor, OnDispatch, void*, _pDispatcher )
188 : {
189 0 : ::std::auto_ptr<DispatchHelper> pHelper( reinterpret_cast< DispatchHelper* >( _pDispatcher ) );
190 : try
191 : {
192 0 : if ( m_pContentHolder && m_pContentHolder->prepareClose() && m_xSlaveDispatchProvider.is() )
193 : {
194 0 : Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(
195 0 : pHelper->aURL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_self")), 0 );
196 0 : if ( xDispatch.is() )
197 : {
198 0 : Reference< ::com::sun::star::document::XEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY);
199 0 : if ( xEvtB.is() )
200 0 : xEvtB->removeEventListener(this);
201 :
202 0 : Reference< XInterface > xKeepContentHolderAlive( *m_pContentHolder );
203 0 : xDispatch->dispatch( pHelper->aURL,pHelper->aArguments);
204 0 : }
205 : }
206 : }
207 0 : catch ( const Exception& )
208 : {
209 : DBG_UNHANDLED_EXCEPTION();
210 : }
211 :
212 0 : return 0L;
213 : }
214 :
215 0 : void SAL_CALL OInterceptor::addStatusListener(
216 : const Reference<
217 : XStatusListener >& Control,
218 : const URL& _URL )
219 : throw (
220 : RuntimeException
221 : )
222 : {
223 0 : if(!Control.is())
224 0 : return;
225 :
226 0 : if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVEAS] )
227 : { // SaveAs
228 :
229 0 : if ( !m_pContentHolder->isNewReport() )
230 : {
231 0 : FeatureStateEvent aStateEvent;
232 0 : aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVEAS];
233 0 : aStateEvent.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SaveCopyTo"));
234 0 : aStateEvent.IsEnabled = sal_True;
235 0 : aStateEvent.Requery = sal_False;
236 0 : aStateEvent.State <<= (rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("($3)")));
237 0 : Control->statusChanged(aStateEvent);
238 : }
239 :
240 : {
241 0 : osl::MutexGuard aGuard(m_aMutex);
242 0 : if(!m_pStatCL)
243 0 : m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
244 : }
245 :
246 0 : m_pStatCL->addInterface(_URL.Complete,Control);
247 : }
248 0 : else if ( m_pContentHolder && _URL.Complete == m_aInterceptedURL[DISPATCH_SAVE] )
249 : { // Save
250 0 : FeatureStateEvent aStateEvent;
251 0 : aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE];
252 0 : aStateEvent.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update"));
253 0 : aStateEvent.IsEnabled = m_pContentHolder != NULL && m_pContentHolder->isModified();
254 0 : aStateEvent.Requery = sal_False;
255 :
256 0 : Control->statusChanged(aStateEvent);
257 : {
258 0 : osl::MutexGuard aGuard(m_aMutex);
259 0 : if(!m_pStatCL)
260 0 : m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
261 : }
262 :
263 0 : m_pStatCL->addInterface(_URL.Complete,Control);
264 0 : Reference< ::com::sun::star::document::XEventBroadcaster> xEvtB(m_pContentHolder->getComponent(),UNO_QUERY);
265 0 : if ( xEvtB.is() )
266 0 : xEvtB->addEventListener(this);
267 : }
268 : else
269 : {
270 0 : sal_Int32 i = 2;
271 0 : if(_URL.Complete == m_aInterceptedURL[i] ||
272 0 : _URL.Complete == m_aInterceptedURL[++i] ||
273 0 : _URL.Complete == m_aInterceptedURL[++i] ||
274 0 : _URL.Complete == m_aInterceptedURL[i = DISPATCH_RELOAD] )
275 : { // Close and return
276 0 : FeatureStateEvent aStateEvent;
277 0 : aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
278 : aStateEvent.FeatureDescriptor = rtl::OUString(
279 0 : RTL_CONSTASCII_USTRINGPARAM("Close and Return"));
280 0 : aStateEvent.IsEnabled = sal_True;
281 0 : aStateEvent.Requery = sal_False;
282 0 : Control->statusChanged(aStateEvent);
283 :
284 :
285 : {
286 0 : osl::MutexGuard aGuard(m_aMutex);
287 0 : if(!m_pStatCL)
288 0 : m_pStatCL = new PropertyChangeListenerContainer(m_aMutex);
289 : }
290 :
291 0 : m_pStatCL->addInterface(_URL.Complete,Control);
292 0 : return;
293 : }
294 : }
295 : }
296 :
297 :
298 0 : void SAL_CALL OInterceptor::removeStatusListener(
299 : const Reference<
300 : XStatusListener >& Control,
301 : const URL& _URL )
302 : throw (
303 : RuntimeException
304 : )
305 : {
306 0 : if(!(Control.is() && m_pStatCL))
307 0 : return;
308 : else
309 : {
310 0 : m_pStatCL->removeInterface(_URL.Complete,Control);
311 0 : return;
312 : }
313 : }
314 :
315 :
316 : //XInterceptorInfo
317 0 : Sequence< ::rtl::OUString > SAL_CALL OInterceptor::getInterceptedURLs( ) throw ( RuntimeException )
318 : {
319 : // now implemented as update
320 0 : return m_aInterceptedURL;
321 : }
322 :
323 :
324 : // XDispatchProvider
325 :
326 0 : Reference< XDispatch > SAL_CALL OInterceptor::queryDispatch( const URL& _URL,const ::rtl::OUString& TargetFrameName,sal_Int32 SearchFlags )
327 : throw (RuntimeException)
328 : {
329 0 : osl::MutexGuard aGuard(m_aMutex);
330 0 : const ::rtl::OUString* pIter = m_aInterceptedURL.getConstArray();
331 0 : const ::rtl::OUString* pEnd = pIter + m_aInterceptedURL.getLength();
332 0 : for(;pIter != pEnd;++pIter)
333 : {
334 0 : if ( _URL.Complete == *pIter )
335 0 : return (XDispatch*)this;
336 : }
337 :
338 0 : if(m_xSlaveDispatchProvider.is())
339 0 : return m_xSlaveDispatchProvider->queryDispatch(_URL,TargetFrameName,SearchFlags);
340 : else
341 0 : return Reference<XDispatch>();
342 : }
343 :
344 0 : Sequence< Reference< XDispatch > > SAL_CALL OInterceptor::queryDispatches( const Sequence<DispatchDescriptor >& Requests ) throw ( RuntimeException )
345 : {
346 0 : Sequence< Reference< XDispatch > > aRet;
347 0 : osl::MutexGuard aGuard(m_aMutex);
348 0 : if(m_xSlaveDispatchProvider.is())
349 0 : aRet = m_xSlaveDispatchProvider->queryDispatches(Requests);
350 : else
351 0 : aRet.realloc(Requests.getLength());
352 :
353 0 : for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
354 : {
355 0 : const ::rtl::OUString* pIter = m_aInterceptedURL.getConstArray();
356 0 : const ::rtl::OUString* pEnd = pIter + m_aInterceptedURL.getLength();
357 0 : for(;pIter != pEnd;++pIter)
358 : {
359 0 : if ( Requests[i].FeatureURL.Complete == *pIter )
360 : {
361 0 : aRet[i] = (XDispatch*) this;
362 0 : break;
363 : }
364 : }
365 : }
366 :
367 0 : return aRet;
368 : }
369 :
370 :
371 :
372 : //XDispatchProviderInterceptor
373 :
374 0 : Reference< XDispatchProvider > SAL_CALL OInterceptor::getSlaveDispatchProvider( ) throw ( RuntimeException )
375 : {
376 0 : osl::MutexGuard aGuard(m_aMutex);
377 0 : return m_xSlaveDispatchProvider;
378 : }
379 :
380 : void SAL_CALL
381 0 : OInterceptor::setSlaveDispatchProvider( const Reference< XDispatchProvider >& NewDispatchProvider )
382 : throw ( RuntimeException )
383 : {
384 0 : osl::MutexGuard aGuard(m_aMutex);
385 0 : m_xSlaveDispatchProvider = NewDispatchProvider;
386 0 : }
387 :
388 :
389 0 : Reference< XDispatchProvider > SAL_CALL OInterceptor::getMasterDispatchProvider( )
390 : throw (
391 : RuntimeException
392 : )
393 : {
394 0 : osl::MutexGuard aGuard(m_aMutex);
395 0 : return m_xMasterDispatchProvider;
396 : }
397 :
398 :
399 0 : void SAL_CALL OInterceptor::setMasterDispatchProvider(
400 : const Reference< XDispatchProvider >& NewSupplier )
401 : throw (
402 : RuntimeException
403 : )
404 : {
405 0 : osl::MutexGuard aGuard(m_aMutex);
406 0 : m_xMasterDispatchProvider = NewSupplier;
407 0 : }
408 :
409 0 : void SAL_CALL OInterceptor::notifyEvent( const ::com::sun::star::document::EventObject& Event ) throw (::com::sun::star::uno::RuntimeException)
410 : {
411 0 : osl::ResettableMutexGuard _rGuard(m_aMutex);
412 0 : if ( m_pStatCL && Event.EventName == ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("OnModifyChanged")) )
413 : {
414 0 : OInterfaceContainerHelper* pListener = m_pStatCL->getContainer(m_aInterceptedURL[DISPATCH_SAVE]);
415 0 : if ( pListener )
416 : {
417 0 : FeatureStateEvent aEvt;
418 0 : aEvt.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE];
419 0 : aEvt.FeatureDescriptor = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Update"));
420 0 : Reference<XModifiable> xModel(Event.Source,UNO_QUERY);
421 0 : aEvt.IsEnabled = xModel.is() && xModel->isModified();
422 0 : aEvt.Requery = sal_False;
423 :
424 0 : NOTIFY_LISTERNERS((*pListener),XStatusListener,statusChanged)
425 : }
426 0 : }
427 0 : }
428 :
429 0 : void SAL_CALL OInterceptor::disposing( const ::com::sun::star::lang::EventObject& /*Source*/ ) throw (::com::sun::star::uno::RuntimeException)
430 : {
431 0 : }
432 :
433 : } // namespace dbaccess
434 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|