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