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 .
20 #include "dbinteraction.hxx"
21 #include <comphelper/diagnose_ex.hxx>
22 #include <osl/diagnose.h>
23 #include <connectivity/dbexception.hxx>
24 #include <sqlmessage.hxx>
25 #include <com/sun/star/task/InteractionHandler.hpp>
26 #include <com/sun/star/task/XInteractionApprove.hpp>
27 #include <com/sun/star/task/XInteractionDisapprove.hpp>
28 #include <com/sun/star/task/XInteractionRetry.hpp>
29 #include <com/sun/star/task/XInteractionAbort.hpp>
30 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
31 #include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
32 #include <sfx2/QuerySaveDocument.hxx>
33 #include <paramdialog.hxx>
34 #include <vcl/svapp.hxx>
35 #include <CollectionView.hxx>
36 #include <comphelper/sequenceashashmap.hxx>
38 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
39 com_sun_star_comp_dbaccess_DatabaseInteractionHandler_get_implementation(
40 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
42 return cppu::acquire(new ::dbaui::SQLExceptionInteractionHandler(context
));
45 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
46 com_sun_star_comp_dbaccess_LegacyInteractionHandler_get_implementation(
47 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
49 return cppu::acquire(new ::dbaui::LegacyInteractionHandler(context
));
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::ucb
;
56 using namespace ::com::sun::star::sdb
;
57 using namespace ::com::sun::star::lang
;
58 using namespace ::com::sun::star::task
;
59 using namespace ::com::sun::star::beans
;
60 using namespace ::dbtools
;
62 // BasicInteractionHandler
63 BasicInteractionHandler::BasicInteractionHandler( const Reference
< XComponentContext
>& rxContext
, const bool i_bFallbackToGeneric
)
64 :m_xContext( rxContext
)
65 ,m_bFallbackToGeneric( i_bFallbackToGeneric
)
67 OSL_ENSURE( !m_bFallbackToGeneric
,
68 "BasicInteractionHandler::BasicInteractionHandler: enabling legacy behavior, there should be no clients of this anymore!" );
71 void SAL_CALL
BasicInteractionHandler::initialize(const Sequence
<Any
>& rArgs
)
73 comphelper::SequenceAsHashMap
aMap(rArgs
);
74 m_xParentWindow
.set(aMap
.getValue("Parent"), UNO_QUERY
);
77 sal_Bool SAL_CALL
BasicInteractionHandler::handleInteractionRequest( const Reference
< XInteractionRequest
>& i_rRequest
)
79 return impl_handle_throw( i_rRequest
);
82 void SAL_CALL
BasicInteractionHandler::handle( const Reference
< XInteractionRequest
>& i_rRequest
)
84 impl_handle_throw( i_rRequest
);
87 bool BasicInteractionHandler::impl_handle_throw( const Reference
< XInteractionRequest
>& i_Request
)
89 Any
aRequest( i_Request
->getRequest() );
90 OSL_ENSURE(aRequest
.hasValue(), "BasicInteractionHandler::handle: invalid request!");
91 if ( !aRequest
.hasValue() )
92 // no request -> no handling
95 Sequence
< Reference
< XInteractionContinuation
> > aContinuations( i_Request
->getContinuations() );
97 // try to extract an SQLException (or one of its derived members
98 SQLExceptionInfo
aInfo( aRequest
);
99 if ( aInfo
.isValid() )
101 implHandle( aInfo
, aContinuations
);
105 ParametersRequest aParamRequest
;
106 if ( aRequest
>>= aParamRequest
)
108 implHandle( aParamRequest
, aContinuations
);
112 DocumentSaveRequest aDocuRequest
;
113 if ( aRequest
>>= aDocuRequest
)
115 implHandle( aDocuRequest
, aContinuations
);
119 if ( m_bFallbackToGeneric
)
120 return implHandleUnknown( i_Request
);
125 void BasicInteractionHandler::implHandle(const ParametersRequest
& _rParamRequest
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
127 SolarMutexGuard aGuard
;
128 // want to open a dialog...
130 sal_Int32 nAbortPos
= getContinuation(ABORT
, _rContinuations
);
131 sal_Int32 nParamPos
= getContinuation(SUPPLY_PARAMETERS
, _rContinuations
);
133 Reference
< XInteractionSupplyParameters
> xParamCallback
;
135 xParamCallback
.set(_rContinuations
[nParamPos
], UNO_QUERY
);
136 OSL_ENSURE(xParamCallback
.is(), "BasicInteractionHandler::implHandle(ParametersRequest): can't set the parameters without an appropriate interaction handler!s");
138 OParameterDialog
aDlg(Application::GetFrameWeld(m_xParentWindow
), _rParamRequest
.Parameters
, _rParamRequest
.Connection
, m_xContext
);
139 sal_Int16 nResult
= aDlg
.run();
145 if (xParamCallback
.is())
147 xParamCallback
->setParameters(aDlg
.getValues());
148 xParamCallback
->select();
153 _rContinuations
[nAbortPos
]->select();
157 catch( const Exception
& )
159 DBG_UNHANDLED_EXCEPTION("dbaccess");
163 void BasicInteractionHandler::implHandle(const SQLExceptionInfo
& _rSqlInfo
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
165 SolarMutexGuard aGuard
;
166 // want to open a dialog...
168 sal_Int32 nApprovePos
= getContinuation(APPROVE
, _rContinuations
);
169 sal_Int32 nDisapprovePos
= getContinuation(DISAPPROVE
, _rContinuations
);
170 sal_Int32 nAbortPos
= getContinuation(ABORT
, _rContinuations
);
171 sal_Int32 nRetryPos
= getContinuation(RETRY
, _rContinuations
);
173 // determine the style of the dialog, dependent on the present continuation types
174 MessBoxStyle nDialogStyle
= MessBoxStyle::NONE
;
175 bool bHaveCancel
= nAbortPos
!= -1;
176 // "approve" means "Yes", "disapprove" means "No"
177 // VCL only supports having both (which makes sense ...)
178 if ( ( nApprovePos
!= -1 ) || ( nDisapprovePos
!= -1 ) )
179 nDialogStyle
= ( bHaveCancel
? MessBoxStyle::YesNoCancel
: MessBoxStyle::YesNo
) | MessBoxStyle::DefaultYes
;
182 // if there's no yes/no, then use a default OK button
183 nDialogStyle
= ( bHaveCancel
? MessBoxStyle::OkCancel
: MessBoxStyle::Ok
) | MessBoxStyle::DefaultOk
;
186 // If there's a "Retry" continuation, have a "Retry" button
187 if ( nRetryPos
!= -1 )
189 nDialogStyle
= MessBoxStyle::RetryCancel
| MessBoxStyle::DefaultRetry
;
192 // execute the dialog
193 OSQLMessageBox
aDialog(nullptr, _rSqlInfo
, nDialogStyle
);
194 // TODO: need a way to specify the parent window
195 sal_Int16 nResult
= aDialog
.run();
202 if ( nApprovePos
!= -1 )
203 _rContinuations
[ nApprovePos
]->select();
205 OSL_ENSURE( nResult
!= RET_YES
, "BasicInteractionHandler::implHandle: no handler for YES!" );
209 if ( nDisapprovePos
!= -1 )
210 _rContinuations
[ nDisapprovePos
]->select();
212 OSL_FAIL( "BasicInteractionHandler::implHandle: no handler for NO!" );
216 if ( nAbortPos
!= -1 )
217 _rContinuations
[ nAbortPos
]->select();
218 else if ( nDisapprovePos
!= -1 )
219 _rContinuations
[ nDisapprovePos
]->select();
221 OSL_FAIL( "BasicInteractionHandler::implHandle: no handler for CANCEL!" );
224 if ( nRetryPos
!= -1 )
225 _rContinuations
[ nRetryPos
]->select();
227 OSL_FAIL( "BasicInteractionHandler::implHandle: where does the RETRY come from?" );
231 catch( const Exception
& )
233 DBG_UNHANDLED_EXCEPTION("dbaccess");
236 void BasicInteractionHandler::implHandle(const DocumentSaveRequest
& _rDocuRequest
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
238 SolarMutexGuard aGuard
;
239 // want to open a dialog...
241 sal_Int32 nApprovePos
= getContinuation(APPROVE
, _rContinuations
);
242 sal_Int32 nDisApprovePos
= getContinuation(DISAPPROVE
, _rContinuations
);
243 sal_Int32 nAbortPos
= getContinuation(ABORT
, _rContinuations
);
245 short nRet
= RET_YES
;
246 if ( -1 != nApprovePos
)
248 // ask whether it should be saved
249 nRet
= ExecuteQuerySaveDocument(Application::GetFrameWeld(m_xParentWindow
), _rDocuRequest
.Name
);
252 if ( RET_CANCEL
== nRet
)
255 _rContinuations
[nAbortPos
]->select();
258 else if ( RET_YES
== nRet
)
260 sal_Int32 nDocuPos
= getContinuation(SUPPLY_DOCUMENTSAVE
, _rContinuations
);
264 Reference
< XInteractionDocumentSave
> xCallback(_rContinuations
[nDocuPos
], UNO_QUERY
);
265 OSL_ENSURE(xCallback
.is(), "BasicInteractionHandler::implHandle(DocumentSaveRequest): can't save document without an appropriate interaction handler!s");
267 OCollectionView
aDlg(Application::GetFrameWeld(m_xParentWindow
), _rDocuRequest
.Content
, _rDocuRequest
.Name
, m_xContext
);
268 sal_Int16 nResult
= aDlg
.run();
276 xCallback
->setName(aDlg
.getName(), aDlg
.getSelectedFolder());
282 _rContinuations
[nAbortPos
]->select();
286 catch( const Exception
& )
288 DBG_UNHANDLED_EXCEPTION("dbaccess");
291 else if ( -1 != nApprovePos
)
292 _rContinuations
[nApprovePos
]->select();
294 else if ( -1 != nDisApprovePos
)
295 _rContinuations
[nDisApprovePos
]->select();
298 bool BasicInteractionHandler::implHandleUnknown( const Reference
< XInteractionRequest
>& _rxRequest
)
300 if ( m_xContext
.is() )
302 Reference
< XInteractionHandler2
> xFallbackHandler(
303 InteractionHandler::createWithParent(m_xContext
, nullptr) );
304 xFallbackHandler
->handle( _rxRequest
);
310 sal_Int32
BasicInteractionHandler::getContinuation(Continuation _eCont
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
312 const Reference
< XInteractionContinuation
>* pContinuations
= _rContinuations
.getConstArray();
313 for (sal_Int32 i
=0; i
<_rContinuations
.getLength(); ++i
, ++pContinuations
)
318 if (Reference
< XInteractionApprove
>(*pContinuations
, UNO_QUERY
).is())
322 if (Reference
< XInteractionDisapprove
>(*pContinuations
, UNO_QUERY
).is())
326 if (Reference
< XInteractionRetry
>(*pContinuations
, UNO_QUERY
).is())
330 if (Reference
< XInteractionAbort
>(*pContinuations
, UNO_QUERY
).is())
333 case SUPPLY_PARAMETERS
:
334 if (Reference
< XInteractionSupplyParameters
>(*pContinuations
, UNO_QUERY
).is())
337 case SUPPLY_DOCUMENTSAVE
:
338 if (Reference
< XInteractionDocumentSave
>(*pContinuations
, UNO_QUERY
).is())
347 // SQLExceptionInteractionHandler
348 OUString SAL_CALL
SQLExceptionInteractionHandler::getImplementationName()
350 return "com.sun.star.comp.dbaccess.DatabaseInteractionHandler";
352 sal_Bool SAL_CALL
SQLExceptionInteractionHandler::supportsService(const OUString
& _rServiceName
)
354 const css::uno::Sequence
< OUString
> aSupported(getSupportedServiceNames());
355 for (const OUString
& s
: aSupported
)
356 if (s
== _rServiceName
)
361 css::uno::Sequence
< OUString
> SAL_CALL
SQLExceptionInteractionHandler::getSupportedServiceNames()
363 return { "com.sun.star.sdb.DatabaseInteractionHandler" };
366 // LegacyInteractionHandler
367 OUString SAL_CALL
LegacyInteractionHandler::getImplementationName()
369 return "com.sun.star.comp.dbaccess.LegacyInteractionHandler";
371 sal_Bool SAL_CALL
LegacyInteractionHandler::supportsService(const OUString
& _rServiceName
)
373 const css::uno::Sequence
< OUString
> aSupported(getSupportedServiceNames());
374 for (const OUString
& s
: aSupported
)
375 if (s
== _rServiceName
)
380 css::uno::Sequence
< OUString
> SAL_CALL
LegacyInteractionHandler::getSupportedServiceNames()
382 return { "com.sun.star.sdb.InteractionHandler" };
387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */