LibreOffice Module dbaccess (master) 1
intercept.cxx
Go to the documentation of this file.
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
24
25#include <memory>
26
27namespace dbaccess
28{
29using namespace ::com::sun::star::uno;
30using namespace ::com::sun::star::util;
31using namespace ::com::sun::star::ucb;
32using namespace ::com::sun::star::beans;
33using namespace ::com::sun::star::lang;
34using namespace ::com::sun::star::sdbc;
35using namespace ::com::sun::star::frame;
36using namespace ::com::sun::star::io;
37using namespace ::com::sun::star::embed;
38using namespace ::com::sun::star::container;
39using namespace ::comphelper;
40using namespace ::cppu;
41
42#define DISPATCH_SAVEAS 0
43#define DISPATCH_SAVE 1
44#define DISPATCH_CLOSEDOC 2
45#define DISPATCH_CLOSEWIN 3
46#define DISPATCH_CLOSEFRAME 4
47#define DISPATCH_RELOAD 5
48// the OSL_ENSURE in CTOR has to be changed too, when adding new defines
49
51{
52 EventObject aEvt( *this );
53
54 osl::MutexGuard aGuard(m_aMutex);
55
56 if ( m_pStatCL )
57 m_pStatCL->disposeAndClear( aEvt );
58
61
62 m_pContentHolder = nullptr;
63}
64
65
67 :m_pContentHolder( _pContentHolder )
68 ,m_aInterceptedURL{ /* DISPATCH_SAVEAS */ ".uno:SaveAs",
69 /* DISPATCH_SAVE */ ".uno:Save",
70 /* DISPATCH_CLOSEDOC */ ".uno:CloseDoc",
71 /* DISPATCH_CLOSEWIN */ ".uno:CloseWin",
72 /* DISPATCH_CLOSEFRAME */ ".uno:CloseFrame",
73 /* DISPATCH_RELOAD */ ".uno:Reload" }
74{
75 OSL_ENSURE(DISPATCH_RELOAD < m_aInterceptedURL.getLength(),"Illegal size.");
76}
77
78
80{
81}
82
83namespace {
84
85struct DispatchHelper
86{
88 Sequence<PropertyValue > aArguments;
89};
90
91}
92
93//XDispatch
94void SAL_CALL OInterceptor::dispatch( const URL& URL,const Sequence<PropertyValue >& Arguments )
95{
96 ::osl::MutexGuard aGuard( m_aMutex );
97 if ( !m_pContentHolder )
98 return;
99
100 if ( URL.Complete == m_aInterceptedURL[ DISPATCH_SAVE ] )
101 {
102 m_pContentHolder->save(false, css::uno::Reference<css::awt::XTopWindow>());
103 return;
104 }
105
106 if ( URL.Complete == m_aInterceptedURL[ DISPATCH_RELOAD ] )
107 {
112 );
113 return;
114 }
115
116 if( URL.Complete == m_aInterceptedURL[ DISPATCH_SAVEAS ] )
117 {
119 {
121 }
122 else if ( m_xSlaveDispatchProvider.is() )
123 {
124 Sequence< PropertyValue > aNewArgs = Arguments;
125 sal_Int32 nInd = 0;
126
127 while( nInd < aNewArgs.getLength() )
128 {
129 if ( aNewArgs[nInd].Name == "SaveTo" )
130 {
131 aNewArgs.getArray()[nInd].Value <<= true;
132 break;
133 }
134 nInd++;
135 }
136
137 if ( nInd == aNewArgs.getLength() )
138 {
139 aNewArgs.realloc( nInd + 1 );
140 auto pNewArgs = aNewArgs.getArray();
141 pNewArgs[nInd].Name = "SaveTo";
142 pNewArgs[nInd].Value <<= true;
143 }
144
145 Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(URL, "_self", 0 );
146 if ( xDispatch.is() )
147 xDispatch->dispatch( URL, aNewArgs );
148 }
149 return;
150 }
151
152 if ( URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEDOC ]
153 || URL.Complete == m_aInterceptedURL[ DISPATCH_CLOSEWIN ]
155 )
156 {
157 DispatchHelper* pHelper = new DispatchHelper;
158 pHelper->aArguments = Arguments;
159 pHelper->aURL = URL;
160 Application::PostUserEvent( LINK( this, OInterceptor, OnDispatch ), pHelper );
161 return;
162 }
163}
164
165IMPL_LINK( OInterceptor, OnDispatch, void*, _pDispatcher, void )
166{
167 std::unique_ptr<DispatchHelper> pHelper( static_cast< DispatchHelper* >( _pDispatcher ) );
168 try
169 {
170 if ( m_pContentHolder && m_pContentHolder->prepareClose() && m_xSlaveDispatchProvider.is() )
171 {
172 Reference< XDispatch > xDispatch = m_xSlaveDispatchProvider->queryDispatch(pHelper->aURL, "_self", 0 );
173 if ( xDispatch.is() )
174 {
175 Reference< XInterface > xKeepContentHolderAlive( *m_pContentHolder );
176 xDispatch->dispatch( pHelper->aURL,pHelper->aArguments);
177 }
178 }
179 }
180 catch ( const Exception& )
181 {
182 DBG_UNHANDLED_EXCEPTION("dbaccess");
183 }
184}
185
187 const Reference<
188 XStatusListener >& Control,
189 const URL& URL )
190{
191 if(!Control.is())
192 return;
193
195 { // SaveAs
196
198 {
199 FeatureStateEvent aStateEvent;
200 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVEAS];
201 aStateEvent.FeatureDescriptor = "SaveCopyTo";
202 aStateEvent.IsEnabled = true;
203 aStateEvent.Requery = false;
204 aStateEvent.State <<= OUString("($3)");
205 Control->statusChanged(aStateEvent);
206 }
207
208 {
209 osl::MutexGuard aGuard(m_aMutex);
210 if(!m_pStatCL)
212 }
213
214 m_pStatCL->addInterface(URL.Complete,Control);
215 }
216 else if ( m_pContentHolder && URL.Complete == m_aInterceptedURL[DISPATCH_SAVE] )
217 { // Save
218 FeatureStateEvent aStateEvent;
219 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[DISPATCH_SAVE];
220 aStateEvent.FeatureDescriptor = "Update";
221 aStateEvent.IsEnabled = true;
222 aStateEvent.Requery = false;
223
224 Control->statusChanged(aStateEvent);
225 {
226 osl::MutexGuard aGuard(m_aMutex);
227 if(!m_pStatCL)
229 }
230
231 m_pStatCL->addInterface(URL.Complete,Control);
232 }
233 else
234 {
235 sal_Int32 i = 2;
236 if(URL.Complete == m_aInterceptedURL[i] ||
237 URL.Complete == m_aInterceptedURL[++i] ||
238 URL.Complete == m_aInterceptedURL[++i] ||
239 URL.Complete == m_aInterceptedURL[i = DISPATCH_RELOAD] )
240 { // Close and return
241 FeatureStateEvent aStateEvent;
242 aStateEvent.FeatureURL.Complete = m_aInterceptedURL[i];
243 aStateEvent.FeatureDescriptor = "Close and Return";
244 aStateEvent.IsEnabled = true;
245 aStateEvent.Requery = false;
246 Control->statusChanged(aStateEvent);
247
248
249 {
250 osl::MutexGuard aGuard(m_aMutex);
251 if(!m_pStatCL)
253 }
254
255 m_pStatCL->addInterface(URL.Complete,Control);
256 return;
257 }
258 }
259}
260
261
263 const Reference<
264 XStatusListener >& Control,
265 const URL& URL )
266{
267 if(!(Control.is() && m_pStatCL))
268 return;
269 else
270 {
271 m_pStatCL->removeInterface(URL.Complete,Control);
272 return;
273 }
274}
275
276
277//XInterceptorInfo
278Sequence< OUString > SAL_CALL OInterceptor::getInterceptedURLs( )
279{
280 // now implemented as update
281 return m_aInterceptedURL;
282}
283
284
285// XDispatchProvider
286
287Reference< XDispatch > SAL_CALL OInterceptor::queryDispatch( const URL& URL,const OUString& TargetFrameName,sal_Int32 SearchFlags )
288{
289 osl::MutexGuard aGuard(m_aMutex);
290 const OUString* pIter = m_aInterceptedURL.getConstArray();
291 const OUString* pEnd = pIter + m_aInterceptedURL.getLength();
292 for(;pIter != pEnd;++pIter)
293 {
294 if ( URL.Complete == *pIter )
295 return static_cast<XDispatch*>(this);
296 }
297
299 return m_xSlaveDispatchProvider->queryDispatch(URL,TargetFrameName,SearchFlags);
300 else
301 return Reference<XDispatch>();
302}
303
304Sequence< Reference< XDispatch > > SAL_CALL OInterceptor::queryDispatches( const Sequence<DispatchDescriptor >& Requests )
305{
306 osl::MutexGuard aGuard(m_aMutex);
307 typedef Sequence<Reference<XDispatch>> DispatchSeq;
308 DispatchSeq aRet = m_xSlaveDispatchProvider.is() ?
309 m_xSlaveDispatchProvider->queryDispatches(Requests) :
310 DispatchSeq(Requests.getLength());
311
312 auto aRetRange = asNonConstRange(aRet);
313 for(sal_Int32 i = 0; i < Requests.getLength(); ++i)
314 {
315 const OUString* pIter = m_aInterceptedURL.getConstArray();
316 const OUString* pEnd = pIter + m_aInterceptedURL.getLength();
317 for(;pIter != pEnd;++pIter)
318 {
319 if ( Requests[i].FeatureURL.Complete == *pIter )
320 {
321 aRetRange[i] = static_cast<XDispatch*>(this);
322 break;
323 }
324 }
325 }
326
327 return aRet;
328}
329
330
331//XDispatchProviderInterceptor
332
333Reference< XDispatchProvider > SAL_CALL OInterceptor::getSlaveDispatchProvider( )
334{
335 osl::MutexGuard aGuard(m_aMutex);
337}
338
339void SAL_CALL
340OInterceptor::setSlaveDispatchProvider( const Reference< XDispatchProvider >& NewDispatchProvider )
341{
342 osl::MutexGuard aGuard(m_aMutex);
343 m_xSlaveDispatchProvider = NewDispatchProvider;
344}
345
346
347Reference< XDispatchProvider > SAL_CALL OInterceptor::getMasterDispatchProvider( )
348{
349 osl::MutexGuard aGuard(m_aMutex);
351}
352
353
355 const Reference< XDispatchProvider >& NewSupplier )
356{
357 osl::MutexGuard aGuard(m_aMutex);
358 m_xMasterDispatchProvider = NewSupplier;
359}
360
361} // namespace dbaccess
362
363/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
const css::uno::Reference< css::uno::XComponentContext > & getContext() const
virtual css::uno::Reference< css::util::XCloseable > SAL_CALL getComponent() override
const css::uno::Reference< css::sdbc::XConnection > & getConnection() const
static void fillReportData(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const css::uno::Reference< css::util::XCloseable > &_rxComponent, const css::uno::Reference< css::sdbc::XConnection > &_rxActiveConnection)
bool save(bool _bApprove, const css::uno::Reference< css::awt::XTopWindow > &rDialogParent)
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &Control, const css::util::URL &URL) override
Definition: intercept.cxx:186
virtual void SAL_CALL dispatch(const css::util::URL &URL, const css::uno::Sequence< css::beans::PropertyValue > &Arguments) override
Definition: intercept.cxx:94
OInterceptor(ODocumentDefinition *_pContentHolder)
Definition: intercept.cxx:66
virtual ~OInterceptor() override
Definition: intercept.cxx:79
virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches(const css::uno::Sequence< css::frame::DispatchDescriptor > &Requests) override
Definition: intercept.cxx:304
css::uno::Reference< css::frame::XDispatchProvider > m_xMasterDispatchProvider
Definition: intercept.hxx:102
virtual void SAL_CALL setSlaveDispatchProvider(const css::uno::Reference< css::frame::XDispatchProvider > &NewDispatchProvider) override
Definition: intercept.cxx:340
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getMasterDispatchProvider() override
Definition: intercept.cxx:347
virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(const css::util::URL &URL, const OUString &TargetFrameName, sal_Int32 SearchFlags) override
Definition: intercept.cxx:287
css::uno::Reference< css::frame::XDispatchProvider > m_xSlaveDispatchProvider
Definition: intercept.hxx:101
virtual css::uno::Sequence< OUString > SAL_CALL getInterceptedURLs() override
Definition: intercept.cxx:278
css::uno::Sequence< OUString > m_aInterceptedURL
Definition: intercept.hxx:104
ODocumentDefinition * m_pContentHolder
Definition: intercept.hxx:99
comphelper::OMultiTypeInterfaceContainerHelperVar3< css::frame::XStatusListener, OUString > StatusListenerContainer
Definition: intercept.hxx:107
virtual void SAL_CALL setMasterDispatchProvider(const css::uno::Reference< css::frame::XDispatchProvider > &NewSupplier) override
Definition: intercept.cxx:354
virtual css::uno::Reference< css::frame::XDispatchProvider > SAL_CALL getSlaveDispatchProvider() override
Definition: intercept.cxx:333
std::unique_ptr< StatusListenerContainer > m_pStatCL
Definition: intercept.hxx:108
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &Control, const css::util::URL &URL) override
Definition: intercept.cxx:262
#define DBG_UNHANDLED_EXCEPTION(...)
Reference< XDispatch > xDispatch
#define DISPATCH_RELOAD
Definition: intercept.cxx:47
#define DISPATCH_CLOSEFRAME
Definition: intercept.cxx:46
#define DISPATCH_CLOSEWIN
Definition: intercept.cxx:45
#define DISPATCH_SAVE
Definition: intercept.cxx:43
#define DISPATCH_CLOSEDOC
Definition: intercept.cxx:44
URL aURL
Definition: intercept.cxx:87
#define DISPATCH_SAVEAS
Definition: intercept.cxx:42
Sequence< PropertyValue > aArguments
Definition: intercept.cxx:88
@ Exception
IMPL_LINK(OInterceptor, OnDispatch, void *, _pDispatcher, void)
Definition: intercept.cxx:165
int i
OUString Name