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