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 "dbu_reghelper.hxx"
22 #include "uiservices.hxx"
23 #include <tools/diagnose_ex.h>
24 #include <osl/diagnose.h>
25 #include <vcl/msgbox.hxx>
26 #include <connectivity/dbexception.hxx>
27 #include "sqlmessage.hxx"
28 #include <com/sun/star/task/InteractionHandler.hpp>
29 #include <com/sun/star/task/XInteractionApprove.hpp>
30 #include <com/sun/star/task/XInteractionDisapprove.hpp>
31 #include <com/sun/star/task/XInteractionRetry.hpp>
32 #include <com/sun/star/task/XInteractionAbort.hpp>
33 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
34 #include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
35 #include <sfx2/QuerySaveDocument.hxx>
36 #include "dbu_uno.hrc"
37 #include "paramdialog.hxx"
38 #include <vcl/svapp.hxx>
39 #include <osl/mutex.hxx>
40 #include "CollectionView.hxx"
41 #include "UITools.hxx"
42 #include <comphelper/processfactory.hxx>
44 extern "C" void SAL_CALL
createRegistryInfo_OInteractionHandler()
46 static ::dbaui::OMultiInstanceAutoRegistration
< ::dbaui::SQLExceptionInteractionHandler
> aSQLExceptionInteractionHandler_AutoRegistration
;
47 static ::dbaui::OMultiInstanceAutoRegistration
< ::dbaui::LegacyInteractionHandler
> aLegacyInteractionHandler_AutoRegistration
;
52 using namespace ::com::sun::star::uno
;
53 using namespace ::com::sun::star::ucb
;
54 using namespace ::com::sun::star::sdb
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star::task
;
57 using namespace ::com::sun::star::beans
;
58 using namespace ::dbtools
;
60 // BasicInteractionHandler
61 BasicInteractionHandler::BasicInteractionHandler( const Reference
< XComponentContext
>& rxContext
, const bool i_bFallbackToGeneric
)
62 :m_xContext( rxContext
)
63 ,m_bFallbackToGeneric( i_bFallbackToGeneric
)
65 OSL_ENSURE( !m_bFallbackToGeneric
,
66 "BasicInteractionHandler::BasicInteractionHandler: enabling legacy behavior, there should be no clients of this anymore!" );
69 sal_Bool SAL_CALL
BasicInteractionHandler::handleInteractionRequest( const Reference
< XInteractionRequest
>& i_rRequest
) throw (RuntimeException
, std::exception
)
71 return impl_handle_throw( i_rRequest
);
74 void SAL_CALL
BasicInteractionHandler::handle( const Reference
< XInteractionRequest
>& i_rRequest
) throw(RuntimeException
, std::exception
)
76 impl_handle_throw( i_rRequest
);
79 bool BasicInteractionHandler::impl_handle_throw( const Reference
< XInteractionRequest
>& i_Request
)
81 Any
aRequest( i_Request
->getRequest() );
82 OSL_ENSURE(aRequest
.hasValue(), "BasicInteractionHandler::handle: invalid request!");
83 if ( !aRequest
.hasValue() )
84 // no request -> no handling
87 Sequence
< Reference
< XInteractionContinuation
> > aContinuations( i_Request
->getContinuations() );
89 // try to extract an SQLException (or one of it's derived members
90 SQLExceptionInfo
aInfo( aRequest
);
91 if ( aInfo
.isValid() )
93 implHandle( aInfo
, aContinuations
);
97 ParametersRequest aParamRequest
;
98 if ( aRequest
>>= aParamRequest
)
100 implHandle( aParamRequest
, aContinuations
);
104 DocumentSaveRequest aDocuRequest
;
105 if ( aRequest
>>= aDocuRequest
)
107 implHandle( aDocuRequest
, aContinuations
);
111 if ( m_bFallbackToGeneric
)
112 return implHandleUnknown( i_Request
);
117 void BasicInteractionHandler::implHandle(const ParametersRequest
& _rParamRequest
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
119 SolarMutexGuard aGuard
;
120 // want to open a dialog...
122 sal_Int32 nAbortPos
= getContinuation(ABORT
, _rContinuations
);
123 sal_Int32 nParamPos
= getContinuation(SUPPLY_PARAMETERS
, _rContinuations
);
125 Reference
< XInteractionSupplyParameters
> xParamCallback
;
127 xParamCallback
= Reference
< XInteractionSupplyParameters
>(_rContinuations
[nParamPos
], UNO_QUERY
);
128 OSL_ENSURE(xParamCallback
.is(), "BasicInteractionHandler::implHandle(ParametersRequest): can't set the parameters without an appropriate interaction handler!s");
130 ScopedVclPtrInstance
< OParameterDialog
> aDlg(nullptr, _rParamRequest
.Parameters
, _rParamRequest
.Connection
, m_xContext
);
131 sal_Int16 nResult
= aDlg
->Execute();
137 if (xParamCallback
.is())
139 xParamCallback
->setParameters(aDlg
->getValues());
140 xParamCallback
->select();
145 _rContinuations
[nAbortPos
]->select();
149 catch( const Exception
& )
151 DBG_UNHANDLED_EXCEPTION();
155 void BasicInteractionHandler::implHandle(const SQLExceptionInfo
& _rSqlInfo
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
157 SolarMutexGuard aGuard
;
158 // want to open a dialog...
160 sal_Int32 nApprovePos
= getContinuation(APPROVE
, _rContinuations
);
161 sal_Int32 nDisapprovePos
= getContinuation(DISAPPROVE
, _rContinuations
);
162 sal_Int32 nAbortPos
= getContinuation(ABORT
, _rContinuations
);
163 sal_Int32 nRetryPos
= getContinuation(RETRY
, _rContinuations
);
165 // determine the style of the dialog, dependent on the present continuation types
166 WinBits nDialogStyle
= 0;
167 bool bHaveCancel
= nAbortPos
!= -1;
168 // "approve" means "Yes", "disapprove" means "No"
169 // VCL only supports having both (which makes sense ...)
170 if ( ( nApprovePos
!= -1 ) || ( nDisapprovePos
!= -1 ) )
171 nDialogStyle
= ( bHaveCancel
? WB_YES_NO_CANCEL
: WB_YES_NO
) | WB_DEF_YES
;
174 // if there's no yes/no, then use a default OK button
175 nDialogStyle
= ( bHaveCancel
? WB_OK_CANCEL
: WB_OK
) | WB_DEF_OK
;
178 // If there's a "Retry" continuation, have a "Retry" button
179 if ( nRetryPos
!= -1 )
181 nDialogStyle
= WB_RETRY_CANCEL
| WB_DEF_RETRY
;
184 // execute the dialog
185 ScopedVclPtrInstance
< OSQLMessageBox
> aDialog(nullptr, _rSqlInfo
, nDialogStyle
);
186 // TODO: need a way to specify the parent window
187 sal_Int16 nResult
= aDialog
->Execute();
194 if ( nApprovePos
!= -1 )
195 _rContinuations
[ nApprovePos
]->select();
197 OSL_ENSURE( nResult
!= RET_YES
, "BasicInteractionHandler::implHandle: no handler for YES!" );
201 if ( nDisapprovePos
!= -1 )
202 _rContinuations
[ nDisapprovePos
]->select();
204 OSL_FAIL( "BasicInteractionHandler::implHandle: no handler for NO!" );
208 if ( nAbortPos
!= -1 )
209 _rContinuations
[ nAbortPos
]->select();
210 else if ( nDisapprovePos
!= -1 )
211 _rContinuations
[ nDisapprovePos
]->select();
213 OSL_FAIL( "BasicInteractionHandler::implHandle: no handler for CANCEL!" );
216 if ( nRetryPos
!= -1 )
217 _rContinuations
[ nRetryPos
]->select();
219 OSL_FAIL( "BasicInteractionHandler::implHandle: where does the RETRY come from?" );
223 catch( const Exception
& )
225 DBG_UNHANDLED_EXCEPTION();
228 void BasicInteractionHandler::implHandle(const DocumentSaveRequest
& _rDocuRequest
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
230 SolarMutexGuard aGuard
;
231 // want to open a dialog ....
233 sal_Int32 nApprovePos
= getContinuation(APPROVE
, _rContinuations
);
234 sal_Int32 nDisApprovePos
= getContinuation(DISAPPROVE
, _rContinuations
);
235 sal_Int32 nAbortPos
= getContinuation(ABORT
, _rContinuations
);
237 short nRet
= RET_YES
;
238 if ( -1 != nApprovePos
)
240 // ask whether it should be saved
241 nRet
= ExecuteQuerySaveDocument(NULL
,_rDocuRequest
.Name
);
244 if ( RET_CANCEL
== nRet
)
247 _rContinuations
[nAbortPos
]->select();
250 else if ( RET_YES
== nRet
)
252 sal_Int32 nDocuPos
= getContinuation(SUPPLY_DOCUMENTSAVE
, _rContinuations
);
256 Reference
< XInteractionDocumentSave
> xCallback(_rContinuations
[nDocuPos
], UNO_QUERY
);
257 OSL_ENSURE(xCallback
.is(), "BasicInteractionHandler::implHandle(DocumentSaveRequest): can't save document without an appropriate interaction handler!s");
259 ScopedVclPtrInstance
< OCollectionView
> aDlg(nullptr, _rDocuRequest
.Content
, _rDocuRequest
.Name
, m_xContext
);
260 sal_Int16 nResult
= aDlg
->Execute();
268 xCallback
->setName(aDlg
->getName(), aDlg
->getSelectedFolder());
274 _rContinuations
[nAbortPos
]->select();
278 catch( const Exception
& )
280 DBG_UNHANDLED_EXCEPTION();
283 else if ( -1 != nApprovePos
)
284 _rContinuations
[nApprovePos
]->select();
286 else if ( -1 != nDisApprovePos
)
287 _rContinuations
[nDisApprovePos
]->select();
290 bool BasicInteractionHandler::implHandleUnknown( const Reference
< XInteractionRequest
>& _rxRequest
)
292 if ( m_xContext
.is() )
294 Reference
< XInteractionHandler2
> xFallbackHandler(
295 InteractionHandler::createWithParent(m_xContext
, 0) );
296 xFallbackHandler
->handle( _rxRequest
);
302 sal_Int32
BasicInteractionHandler::getContinuation(Continuation _eCont
, const Sequence
< Reference
< XInteractionContinuation
> >& _rContinuations
)
304 const Reference
< XInteractionContinuation
>* pContinuations
= _rContinuations
.getConstArray();
305 for (sal_Int32 i
=0; i
<_rContinuations
.getLength(); ++i
, ++pContinuations
)
310 if (Reference
< XInteractionApprove
>(*pContinuations
, UNO_QUERY
).is())
314 if (Reference
< XInteractionDisapprove
>(*pContinuations
, UNO_QUERY
).is())
318 if (Reference
< XInteractionRetry
>(*pContinuations
, UNO_QUERY
).is())
322 if (Reference
< XInteractionAbort
>(*pContinuations
, UNO_QUERY
).is())
325 case SUPPLY_PARAMETERS
:
326 if (Reference
< XInteractionSupplyParameters
>(*pContinuations
, UNO_QUERY
).is())
329 case SUPPLY_DOCUMENTSAVE
:
330 if (Reference
< XInteractionDocumentSave
>(*pContinuations
, UNO_QUERY
).is())
339 // SQLExceptionInteractionHandler
340 IMPLEMENT_SERVICE_INFO_IMPLNAME_STATIC(SQLExceptionInteractionHandler
, "com.sun.star.comp.dbaccess.DatabaseInteractionHandler")
341 IMPLEMENT_SERVICE_INFO_SUPPORTS(SQLExceptionInteractionHandler
)
342 IMPLEMENT_SERVICE_INFO_GETSUPPORTED1_STATIC(SQLExceptionInteractionHandler
, "com.sun.star.sdb.DatabaseInteractionHandler")
344 Reference
< XInterface
>
345 SAL_CALL
SQLExceptionInteractionHandler::Create(const Reference
< XMultiServiceFactory
>& _rxORB
)
347 return static_cast< XServiceInfo
* >(new SQLExceptionInteractionHandler(comphelper::getComponentContext(_rxORB
)));
350 // LegacyInteractionHandler
351 IMPLEMENT_SERVICE_INFO_IMPLNAME_STATIC(LegacyInteractionHandler
, "com.sun.star.comp.dbaccess.LegacyInteractionHandler")
352 IMPLEMENT_SERVICE_INFO_SUPPORTS(LegacyInteractionHandler
)
353 IMPLEMENT_SERVICE_INFO_GETSUPPORTED1_STATIC(LegacyInteractionHandler
, "com.sun.star.sdb.InteractionHandler")
355 Reference
< XInterface
>
356 SAL_CALL
LegacyInteractionHandler::Create(const Reference
< XMultiServiceFactory
>& _rxORB
)
358 return static_cast< XServiceInfo
* >(new LegacyInteractionHandler(comphelper::getComponentContext(_rxORB
)));
363 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */