1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbaccess.hxx"
26
27 #ifndef _DBAUI_INTERACTION_HXX_
28 #include "dbinteraction.hxx"
29 #endif
30 #ifndef _DBU_REGHELPER_HXX_
31 #include "dbu_reghelper.hxx"
32 #endif
33 #ifndef _TOOLS_DEBUG_HXX
34 #include <tools/debug.hxx>
35 #endif
36 #ifndef TOOLS_DIAGNOSE_EX_H
37 #include <tools/diagnose_ex.h>
38 #endif
39 #ifndef _SV_MSGBOX_HXX
40 #include <vcl/msgbox.hxx>
41 #endif
42 #ifndef _DBHELPER_DBEXCEPTION_HXX_
43 #include <connectivity/dbexception.hxx>
44 #endif
45 #ifndef _DBAUI_SQLMESSAGE_HXX_
46 #include "sqlmessage.hxx"
47 #endif
48 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONAPPROVE_HPP_
49 #include <com/sun/star/task/XInteractionApprove.hpp>
50 #endif
51 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONDISAPPROVE_HPP_
52 #include <com/sun/star/task/XInteractionDisapprove.hpp>
53 #endif
54 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONRETRY_HPP_
55 #include <com/sun/star/task/XInteractionRetry.hpp>
56 #endif
57 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONABORT_HPP_
58 #include <com/sun/star/task/XInteractionAbort.hpp>
59 #endif
60 #ifndef _COM_SUN_STAR_SDB_XINTERACTIONSUPPLYPARAMETERS_HPP_
61 #include <com/sun/star/sdb/XInteractionSupplyParameters.hpp>
62 #endif
63 #ifndef _COM_SUN_STAR_SDB_XINTERACTIONDOCUMENTSAVE_HPP_
64 #include <com/sun/star/sdb/XInteractionDocumentSave.hpp>
65 #endif
66 #ifndef SFX_QUERYSAVEDOCUMENT_HXX
67 #include <sfx2/QuerySaveDocument.hxx>
68 #endif
69 #ifndef _DBU_UNO_HRC_
70 #include "dbu_uno.hrc"
71 #endif
72 #ifndef _DBAUI_PARAMDIALOG_HXX_
73 #include "paramdialog.hxx"
74 #endif
75 #ifndef _SV_SVAPP_HXX
76 #include <vcl/svapp.hxx>
77 #endif
78 #ifndef _VOS_MUTEX_HXX_
79 #include <vos/mutex.hxx>
80 #endif
81 #ifndef DBAUI_COLLECTIONVIEW_HXX
82 #include "CollectionView.hxx"
83 #endif
84 #ifndef DBAUI_TOOLS_HXX
85 #include "UITools.hxx"
86 #endif
87
88
89 //==========================================================================
90
createRegistryInfo_OInteractionHandler()91 extern "C" void SAL_CALL createRegistryInfo_OInteractionHandler()
92 {
93 static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::SQLExceptionInteractionHandler > aSQLExceptionInteractionHandler_AutoRegistration;
94 static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::LegacyInteractionHandler > aLegacyInteractionHandler_AutoRegistration;
95 }
96
97 //.........................................................................
98 namespace dbaui
99 {
100 //.........................................................................
101 using namespace ::com::sun::star::uno;
102 using namespace ::com::sun::star::ucb;
103 using namespace ::com::sun::star::sdb;
104 using namespace ::com::sun::star::lang;
105 using namespace ::com::sun::star::task;
106 using namespace ::com::sun::star::beans;
107 using namespace ::dbtools;
108
109 //=========================================================================
110 //= BasicInteractionHandler
111 //=========================================================================
112 //-------------------------------------------------------------------------
BasicInteractionHandler(const Reference<XMultiServiceFactory> & _rxORB,const bool i_bFallbackToGeneric)113 BasicInteractionHandler::BasicInteractionHandler( const Reference< XMultiServiceFactory >& _rxORB, const bool i_bFallbackToGeneric )
114 :m_xORB( _rxORB )
115 ,m_bFallbackToGeneric( i_bFallbackToGeneric )
116 {
117 OSL_ENSURE( !m_bFallbackToGeneric,
118 "BasicInteractionHandler::BasicInteractionHandler: enabling legacy behavior, there should be no clients of this anymore!" );
119 }
120
121 //-------------------------------------------------------------------------
handleInteractionRequest(const Reference<XInteractionRequest> & i_rRequest)122 ::sal_Bool SAL_CALL BasicInteractionHandler::handleInteractionRequest( const Reference< XInteractionRequest >& i_rRequest ) throw (RuntimeException)
123 {
124 return impl_handle_throw( i_rRequest );
125 }
126
127 //-------------------------------------------------------------------------
handle(const Reference<XInteractionRequest> & i_rRequest)128 void SAL_CALL BasicInteractionHandler::handle( const Reference< XInteractionRequest >& i_rRequest ) throw(RuntimeException)
129 {
130 impl_handle_throw( i_rRequest );
131 }
132
133 //-------------------------------------------------------------------------
impl_handle_throw(const Reference<XInteractionRequest> & i_Request)134 sal_Bool BasicInteractionHandler::impl_handle_throw( const Reference< XInteractionRequest >& i_Request )
135 {
136 Any aRequest( i_Request->getRequest() );
137 DBG_ASSERT(aRequest.hasValue(), "BasicInteractionHandler::handle: invalid request!");
138 if ( !aRequest.hasValue() )
139 // no request -> no handling
140 return sal_False;
141
142 Sequence< Reference< XInteractionContinuation > > aContinuations( i_Request->getContinuations() );
143
144 // try to extract an SQLException (or one of it's derived members
145 SQLExceptionInfo aInfo( aRequest );
146 if ( aInfo.isValid() )
147 {
148 implHandle( aInfo, aContinuations );
149 return sal_True;
150 }
151
152 ParametersRequest aParamRequest;
153 if ( aRequest >>= aParamRequest )
154 {
155 implHandle( aParamRequest, aContinuations );
156 return sal_True;
157 }
158
159 DocumentSaveRequest aDocuRequest;
160 if ( aRequest >>= aDocuRequest )
161 {
162 implHandle( aDocuRequest, aContinuations );
163 return sal_True;
164 }
165
166 if ( m_bFallbackToGeneric )
167 return implHandleUnknown( i_Request );
168
169 return sal_False;
170 }
171
172 //-------------------------------------------------------------------------
implHandle(const ParametersRequest & _rParamRequest,const Sequence<Reference<XInteractionContinuation>> & _rContinuations)173 void BasicInteractionHandler::implHandle(const ParametersRequest& _rParamRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
174 {
175 ::vos::OGuard aGuard(Application::GetSolarMutex());
176 // want to open a dialog ....
177
178 sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);
179 sal_Int32 nParamPos = getContinuation(SUPPLY_PARAMETERS, _rContinuations);
180
181 Reference< XInteractionSupplyParameters > xParamCallback;
182 if (-1 != nParamPos)
183 xParamCallback = Reference< XInteractionSupplyParameters >(_rContinuations[nParamPos], UNO_QUERY);
184 DBG_ASSERT(xParamCallback.is(), "BasicInteractionHandler::implHandle(ParametersRequest): can't set the parameters without an appropriate interaction handler!s");
185
186 // determine the style of the dialog, dependent on the present continuation types
187 WinBits nDialogStyle = WB_OK | WB_DEF_OK;
188 if (-1 != nAbortPos)
189 nDialogStyle = WB_OK_CANCEL;
190
191 OParameterDialog aDlg(NULL, _rParamRequest.Parameters, _rParamRequest.Connection, m_xORB);
192 sal_Int16 nResult = aDlg.Execute();
193 try
194 {
195 switch (nResult)
196 {
197 case RET_OK:
198 if (xParamCallback.is())
199 {
200 xParamCallback->setParameters(aDlg.getValues());
201 xParamCallback->select();
202 }
203 break;
204 default:
205 if (-1 != nAbortPos)
206 _rContinuations[nAbortPos]->select();
207 break;
208 }
209 }
210 catch( const Exception& )
211 {
212 DBG_UNHANDLED_EXCEPTION();
213 }
214 }
215
216 //-------------------------------------------------------------------------
implHandle(const SQLExceptionInfo & _rSqlInfo,const Sequence<Reference<XInteractionContinuation>> & _rContinuations)217 void BasicInteractionHandler::implHandle(const SQLExceptionInfo& _rSqlInfo, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
218 {
219 ::vos::OGuard aGuard(Application::GetSolarMutex());
220 // want to open a dialog ....
221
222 sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations);
223 sal_Int32 nDisapprovePos = getContinuation(DISAPPROVE, _rContinuations);
224 sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);
225 sal_Int32 nRetryPos = getContinuation(RETRY, _rContinuations);
226
227 // determine the style of the dialog, dependent on the present continuation types
228 WinBits nDialogStyle = 0;
229 bool bHaveCancel = nAbortPos != -1;
230 // "approve" means "Yes", "disapprove" means "No"
231 // VCL only supports having both (which makes sense ...)
232 if ( ( nApprovePos != -1 ) || ( nDisapprovePos != -1 ) )
233 nDialogStyle = ( bHaveCancel ? WB_YES_NO_CANCEL : WB_YES_NO ) | WB_DEF_YES;
234 else
235 {
236 // if there's no yes/no, then use a default OK button
237 nDialogStyle = ( bHaveCancel ? WB_OK_CANCEL : WB_OK ) | WB_DEF_OK;
238 }
239
240 // If there's a "Retry" continuation, have a "Retry" button
241 if ( nRetryPos != -1 )
242 {
243 nDialogStyle = WB_RETRY_CANCEL | WB_DEF_RETRY;
244 }
245
246 // excute the dialog
247 OSQLMessageBox aDialog(NULL, _rSqlInfo, nDialogStyle);
248 // TODO: need a way to specify the parent window
249 sal_Int16 nResult = aDialog.Execute();
250 try
251 {
252 switch (nResult)
253 {
254 case RET_YES:
255 case RET_OK:
256 if ( nApprovePos != -1 )
257 _rContinuations[ nApprovePos ]->select();
258 else
259 OSL_ENSURE( nResult != RET_YES, "BasicInteractionHandler::implHandle: no handler for YES!" );
260 break;
261
262 case RET_NO:
263 if ( nDisapprovePos != -1 )
264 _rContinuations[ nDisapprovePos ]->select();
265 else
266 OSL_ENSURE( false, "BasicInteractionHandler::implHandle: no handler for NO!" );
267 break;
268
269 case RET_CANCEL:
270 if ( nAbortPos != -1 )
271 _rContinuations[ nAbortPos ]->select();
272 else if ( nDisapprovePos != -1 )
273 _rContinuations[ nDisapprovePos ]->select();
274 else
275 OSL_ENSURE( false, "BasicInteractionHandler::implHandle: no handler for CANCEL!" );
276 break;
277 case RET_RETRY:
278 if ( nRetryPos != -1 )
279 _rContinuations[ nRetryPos ]->select();
280 else
281 OSL_ENSURE( false, "BasicInteractionHandler::implHandle: where does the RETRY come from?" );
282 break;
283 }
284 }
285 catch( const Exception& )
286 {
287 DBG_UNHANDLED_EXCEPTION();
288 }
289 }
290 //-------------------------------------------------------------------------
implHandle(const DocumentSaveRequest & _rDocuRequest,const Sequence<Reference<XInteractionContinuation>> & _rContinuations)291 void BasicInteractionHandler::implHandle(const DocumentSaveRequest& _rDocuRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
292 {
293 ::vos::OGuard aGuard(Application::GetSolarMutex());
294 // want to open a dialog ....
295
296 sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations);
297 sal_Int32 nDisApprovePos = getContinuation(DISAPPROVE, _rContinuations);
298 sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations);
299
300 short nRet = RET_YES;
301 if ( -1 != nApprovePos )
302 {
303 // fragen, ob gespeichert werden soll
304 nRet = ExecuteQuerySaveDocument(NULL,_rDocuRequest.Name);
305 }
306
307 if ( RET_CANCEL == nRet )
308 {
309 if (-1 != nAbortPos)
310 _rContinuations[nAbortPos]->select();
311 return;
312 }
313 else if ( RET_YES == nRet )
314 {
315 sal_Int32 nDocuPos = getContinuation(SUPPLY_DOCUMENTSAVE, _rContinuations);
316
317 if (-1 != nDocuPos)
318 {
319 Reference< XInteractionDocumentSave > xCallback(_rContinuations[nDocuPos], UNO_QUERY);
320 DBG_ASSERT(xCallback.is(), "BasicInteractionHandler::implHandle(DocumentSaveRequest): can't save document without an appropriate interaction handler!s");
321
322 // determine the style of the dialog, dependent on the present continuation types
323 WinBits nDialogStyle = WB_OK | WB_DEF_OK;
324 if (-1 != nAbortPos)
325 nDialogStyle = WB_OK_CANCEL;
326
327 OCollectionView aDlg(NULL,_rDocuRequest.Content,_rDocuRequest.Name,m_xORB);
328 sal_Int16 nResult = aDlg.Execute();
329 try
330 {
331 switch (nResult)
332 {
333 case RET_OK:
334 if (xCallback.is())
335 {
336 xCallback->setName(aDlg.getName(),aDlg.getSelectedFolder());
337 xCallback->select();
338 }
339 break;
340 default:
341 if (-1 != nAbortPos)
342 _rContinuations[nAbortPos]->select();
343 break;
344 }
345 }
346 catch( const Exception& )
347 {
348 DBG_UNHANDLED_EXCEPTION();
349 }
350 }
351 else if ( -1 != nApprovePos )
352 _rContinuations[nApprovePos]->select();
353 }
354 else if ( -1 != nDisApprovePos )
355 _rContinuations[nDisApprovePos]->select();
356 }
357
358 //-------------------------------------------------------------------------
implHandleUnknown(const Reference<XInteractionRequest> & _rxRequest)359 bool BasicInteractionHandler::implHandleUnknown( const Reference< XInteractionRequest >& _rxRequest )
360 {
361 Reference< XInteractionHandler > xFallbackHandler;
362 if ( m_xORB.is() )
363 xFallbackHandler = xFallbackHandler.query( m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ) );
364 if ( xFallbackHandler.is() )
365 {
366 xFallbackHandler->handle( _rxRequest );
367 return true;
368 }
369 return false;
370 }
371
372 //-------------------------------------------------------------------------
getContinuation(Continuation _eCont,const Sequence<Reference<XInteractionContinuation>> & _rContinuations)373 sal_Int32 BasicInteractionHandler::getContinuation(Continuation _eCont, const Sequence< Reference< XInteractionContinuation > >& _rContinuations)
374 {
375 const Reference< XInteractionContinuation >* pContinuations = _rContinuations.getConstArray();
376 for (sal_Int32 i=0; i<_rContinuations.getLength(); ++i, ++pContinuations)
377 {
378 switch (_eCont)
379 {
380 case APPROVE:
381 if (Reference< XInteractionApprove >(*pContinuations, UNO_QUERY).is())
382 return i;
383 break;
384 case DISAPPROVE:
385 if (Reference< XInteractionDisapprove >(*pContinuations, UNO_QUERY).is())
386 return i;
387 break;
388 case RETRY:
389 if (Reference< XInteractionRetry >(*pContinuations, UNO_QUERY).is())
390 return i;
391 break;
392 case ABORT:
393 if (Reference< XInteractionAbort >(*pContinuations, UNO_QUERY).is())
394 return i;
395 break;
396 case SUPPLY_PARAMETERS:
397 if (Reference< XInteractionSupplyParameters >(*pContinuations, UNO_QUERY).is())
398 return i;
399 break;
400 case SUPPLY_DOCUMENTSAVE:
401 if (Reference< XInteractionDocumentSave >(*pContinuations, UNO_QUERY).is())
402 return i;
403 break;
404 }
405 }
406
407 return -1;
408 }
409
410 //==========================================================================
411 //= SQLExceptionInteractionHandler
412 //==========================================================================
413 IMPLEMENT_SERVICE_INFO1_STATIC( SQLExceptionInteractionHandler, "com.sun.star.comp.dbaccess.DatabaseInteractionHandler", "com.sun.star.sdb.DatabaseInteractionHandler" );
414
415 //==========================================================================
416 //= LegacyInteractionHandler
417 //==========================================================================
418 IMPLEMENT_SERVICE_INFO1_STATIC( LegacyInteractionHandler, "com.sun.star.comp.dbaccess.LegacyInteractionHandler", "com.sun.star.sdb.InteractionHandler" );
419
420 //.........................................................................
421 } // namespace dbaui
422 //.........................................................................
423
424