xref: /AOO41X/main/dbaccess/source/ui/uno/dbinteraction.cxx (revision 96de54900b79e13b861fbc62cbf36018b54e21b7)
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