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"
23 #include <comphelper/diagnose_ex.hxx>
29 using namespace ::com::sun::star::uno
;
30 using namespace ::com::sun::star::util
;
31 using namespace ::com::sun::star::beans
;
32 using namespace ::com::sun::star::lang
;
33 using namespace ::com::sun::star::sdbc
;
34 using namespace ::com::sun::star::frame
;
35 using namespace ::com::sun::star::io
;
36 using namespace ::com::sun::star::container
;
37 using namespace ::comphelper
;
38 using namespace ::cppu
;
40 #define DISPATCH_SAVEAS 0
41 #define DISPATCH_SAVE 1
42 #define DISPATCH_CLOSEDOC 2
43 #define DISPATCH_CLOSEWIN 3
44 #define DISPATCH_CLOSEFRAME 4
45 #define DISPATCH_RELOAD 5
46 // the OSL_ENSURE in CTOR has to be changed too, when adding new defines
48 void OInterceptor::dispose()
50 EventObject
aEvt( *this );
52 osl::MutexGuard
aGuard(m_aMutex
);
55 m_pStatCL
->disposeAndClear( aEvt
);
57 m_xSlaveDispatchProvider
.clear();
58 m_xMasterDispatchProvider
.clear();
60 m_pContentHolder
= nullptr;
64 OInterceptor::OInterceptor( ODocumentDefinition
* _pContentHolder
)
65 :m_pContentHolder( _pContentHolder
)
66 ,m_aInterceptedURL
{ /* DISPATCH_SAVEAS */ u
".uno:SaveAs"_ustr
,
67 /* DISPATCH_SAVE */ u
".uno:Save"_ustr
,
68 /* DISPATCH_CLOSEDOC */ u
".uno:CloseDoc"_ustr
,
69 /* DISPATCH_CLOSEWIN */ u
".uno:CloseWin"_ustr
,
70 /* DISPATCH_CLOSEFRAME */ u
".uno:CloseFrame"_ustr
,
71 /* DISPATCH_RELOAD */ u
".uno:Reload"_ustr
}
73 OSL_ENSURE(DISPATCH_RELOAD
< m_aInterceptedURL
.getLength(),"Illegal size.");
77 OInterceptor::~OInterceptor()
86 Sequence
<PropertyValue
> aArguments
;
92 void SAL_CALL
OInterceptor::dispatch( const URL
& URL
,const Sequence
<PropertyValue
>& Arguments
)
94 ::osl::MutexGuard
aGuard( m_aMutex
);
95 if ( !m_pContentHolder
)
98 if ( URL
.Complete
== m_aInterceptedURL
[ DISPATCH_SAVE
] )
100 m_pContentHolder
->save(false, css::uno::Reference
<css::awt::XTopWindow
>());
104 if ( URL
.Complete
== m_aInterceptedURL
[ DISPATCH_RELOAD
] )
106 ODocumentDefinition::fillReportData(
107 m_pContentHolder
->getContext(),
108 m_pContentHolder
->getComponent(),
109 m_pContentHolder
->getConnection()
114 if( URL
.Complete
== m_aInterceptedURL
[ DISPATCH_SAVEAS
] )
116 if ( m_pContentHolder
->isNewReport() )
118 m_pContentHolder
->saveAs();
120 else if ( m_xSlaveDispatchProvider
.is() )
122 Sequence
< PropertyValue
> aNewArgs
= Arguments
;
125 while( nInd
< aNewArgs
.getLength() )
127 if ( aNewArgs
[nInd
].Name
== "SaveTo" )
129 aNewArgs
.getArray()[nInd
].Value
<<= true;
135 if ( nInd
== aNewArgs
.getLength() )
137 aNewArgs
.realloc( nInd
+ 1 );
138 auto pNewArgs
= aNewArgs
.getArray();
139 pNewArgs
[nInd
].Name
= "SaveTo";
140 pNewArgs
[nInd
].Value
<<= true;
143 Reference
< XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(URL
, u
"_self"_ustr
, 0 );
144 if ( xDispatch
.is() )
145 xDispatch
->dispatch( URL
, aNewArgs
);
150 if ( URL
.Complete
== m_aInterceptedURL
[ DISPATCH_CLOSEDOC
]
151 || URL
.Complete
== m_aInterceptedURL
[ DISPATCH_CLOSEWIN
]
152 || URL
.Complete
== m_aInterceptedURL
[ DISPATCH_CLOSEFRAME
]
155 DispatchHelper
* pHelper
= new DispatchHelper
;
156 pHelper
->aArguments
= Arguments
;
158 Application::PostUserEvent( LINK( this, OInterceptor
, OnDispatch
), pHelper
);
163 IMPL_LINK( OInterceptor
, OnDispatch
, void*, _pDispatcher
, void )
165 std::unique_ptr
<DispatchHelper
> pHelper( static_cast< DispatchHelper
* >( _pDispatcher
) );
168 if ( m_pContentHolder
&& m_pContentHolder
->prepareClose() && m_xSlaveDispatchProvider
.is() )
170 Reference
< XDispatch
> xDispatch
= m_xSlaveDispatchProvider
->queryDispatch(pHelper
->aURL
, u
"_self"_ustr
, 0 );
171 if ( xDispatch
.is() )
173 Reference
< XInterface
> xKeepContentHolderAlive( *m_pContentHolder
);
174 xDispatch
->dispatch( pHelper
->aURL
,pHelper
->aArguments
);
178 catch ( const Exception
& )
180 DBG_UNHANDLED_EXCEPTION("dbaccess");
184 void SAL_CALL
OInterceptor::addStatusListener(
186 XStatusListener
>& Control
,
192 if ( m_pContentHolder
&& URL
.Complete
== m_aInterceptedURL
[DISPATCH_SAVEAS
] )
195 if ( !m_pContentHolder
->isNewReport() )
197 FeatureStateEvent aStateEvent
;
198 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[DISPATCH_SAVEAS
];
199 aStateEvent
.FeatureDescriptor
= "SaveCopyTo";
200 aStateEvent
.IsEnabled
= true;
201 aStateEvent
.Requery
= false;
202 aStateEvent
.State
<<= u
"($3)"_ustr
;
203 Control
->statusChanged(aStateEvent
);
207 osl::MutexGuard
aGuard(m_aMutex
);
209 m_pStatCL
.reset( new StatusListenerContainer(m_aMutex
) );
212 m_pStatCL
->addInterface(URL
.Complete
,Control
);
214 else if ( m_pContentHolder
&& URL
.Complete
== m_aInterceptedURL
[DISPATCH_SAVE
] )
216 FeatureStateEvent aStateEvent
;
217 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[DISPATCH_SAVE
];
218 aStateEvent
.FeatureDescriptor
= "Update";
219 aStateEvent
.IsEnabled
= true;
220 aStateEvent
.Requery
= false;
222 Control
->statusChanged(aStateEvent
);
224 osl::MutexGuard
aGuard(m_aMutex
);
226 m_pStatCL
.reset( new StatusListenerContainer(m_aMutex
) );
229 m_pStatCL
->addInterface(URL
.Complete
,Control
);
234 if(URL
.Complete
== m_aInterceptedURL
[i
] ||
235 URL
.Complete
== m_aInterceptedURL
[++i
] ||
236 URL
.Complete
== m_aInterceptedURL
[++i
] ||
237 URL
.Complete
== m_aInterceptedURL
[i
= DISPATCH_RELOAD
] )
238 { // Close and return
239 FeatureStateEvent aStateEvent
;
240 aStateEvent
.FeatureURL
.Complete
= m_aInterceptedURL
[i
];
241 aStateEvent
.FeatureDescriptor
= "Close and Return";
242 aStateEvent
.IsEnabled
= true;
243 aStateEvent
.Requery
= false;
244 Control
->statusChanged(aStateEvent
);
248 osl::MutexGuard
aGuard(m_aMutex
);
250 m_pStatCL
.reset( new StatusListenerContainer(m_aMutex
) );
253 m_pStatCL
->addInterface(URL
.Complete
,Control
);
260 void SAL_CALL
OInterceptor::removeStatusListener(
262 XStatusListener
>& Control
,
265 if(!(Control
.is() && m_pStatCL
))
269 m_pStatCL
->removeInterface(URL
.Complete
,Control
);
276 Sequence
< OUString
> SAL_CALL
OInterceptor::getInterceptedURLs( )
278 // now implemented as update
279 return m_aInterceptedURL
;
285 Reference
< XDispatch
> SAL_CALL
OInterceptor::queryDispatch( const URL
& URL
,const OUString
& TargetFrameName
,sal_Int32 SearchFlags
)
287 osl::MutexGuard
aGuard(m_aMutex
);
288 for (auto& interceptedUrl
: m_aInterceptedURL
)
289 if (URL
.Complete
== interceptedUrl
)
290 return static_cast<XDispatch
*>(this);
292 if(m_xSlaveDispatchProvider
.is())
293 return m_xSlaveDispatchProvider
->queryDispatch(URL
,TargetFrameName
,SearchFlags
);
295 return Reference
<XDispatch
>();
298 Sequence
< Reference
< XDispatch
> > SAL_CALL
OInterceptor::queryDispatches( const Sequence
<DispatchDescriptor
>& Requests
)
300 osl::MutexGuard
aGuard(m_aMutex
);
301 typedef Sequence
<Reference
<XDispatch
>> DispatchSeq
;
302 DispatchSeq aRet
= m_xSlaveDispatchProvider
.is() ?
303 m_xSlaveDispatchProvider
->queryDispatches(Requests
) :
304 DispatchSeq(Requests
.getLength());
306 auto aRetRange
= asNonConstRange(aRet
);
307 for(sal_Int32 i
= 0; i
< Requests
.getLength(); ++i
)
309 for (auto& interceptedUrl
: m_aInterceptedURL
)
311 if (Requests
[i
].FeatureURL
.Complete
== interceptedUrl
)
313 aRetRange
[i
] = static_cast<XDispatch
*>(this);
323 //XDispatchProviderInterceptor
325 Reference
< XDispatchProvider
> SAL_CALL
OInterceptor::getSlaveDispatchProvider( )
327 osl::MutexGuard
aGuard(m_aMutex
);
328 return m_xSlaveDispatchProvider
;
332 OInterceptor::setSlaveDispatchProvider( const Reference
< XDispatchProvider
>& NewDispatchProvider
)
334 osl::MutexGuard
aGuard(m_aMutex
);
335 m_xSlaveDispatchProvider
= NewDispatchProvider
;
339 Reference
< XDispatchProvider
> SAL_CALL
OInterceptor::getMasterDispatchProvider( )
341 osl::MutexGuard
aGuard(m_aMutex
);
342 return m_xMasterDispatchProvider
;
346 void SAL_CALL
OInterceptor::setMasterDispatchProvider(
347 const Reference
< XDispatchProvider
>& NewSupplier
)
349 osl::MutexGuard
aGuard(m_aMutex
);
350 m_xMasterDispatchProvider
= NewSupplier
;
353 } // namespace dbaccess
355 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */