/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_dbaccess.hxx" #ifndef _DBAUI_INTERACTION_HXX_ #include "dbinteraction.hxx" #endif #ifndef _DBU_REGHELPER_HXX_ #include "dbu_reghelper.hxx" #endif #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef TOOLS_DIAGNOSE_EX_H #include #endif #ifndef _SV_MSGBOX_HXX #include #endif #ifndef _DBHELPER_DBEXCEPTION_HXX_ #include #endif #ifndef _DBAUI_SQLMESSAGE_HXX_ #include "sqlmessage.hxx" #endif #ifndef _COM_SUN_STAR_TASK_XINTERACTIONAPPROVE_HPP_ #include #endif #ifndef _COM_SUN_STAR_TASK_XINTERACTIONDISAPPROVE_HPP_ #include #endif #ifndef _COM_SUN_STAR_TASK_XINTERACTIONRETRY_HPP_ #include #endif #ifndef _COM_SUN_STAR_TASK_XINTERACTIONABORT_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_XINTERACTIONSUPPLYPARAMETERS_HPP_ #include #endif #ifndef _COM_SUN_STAR_SDB_XINTERACTIONDOCUMENTSAVE_HPP_ #include #endif #ifndef SFX_QUERYSAVEDOCUMENT_HXX #include #endif #ifndef _DBU_UNO_HRC_ #include "dbu_uno.hrc" #endif #ifndef _DBAUI_PARAMDIALOG_HXX_ #include "paramdialog.hxx" #endif #ifndef _SV_SVAPP_HXX #include #endif #ifndef _VOS_MUTEX_HXX_ #include #endif #ifndef DBAUI_COLLECTIONVIEW_HXX #include "CollectionView.hxx" #endif #ifndef DBAUI_TOOLS_HXX #include "UITools.hxx" #endif //========================================================================== extern "C" void SAL_CALL createRegistryInfo_OInteractionHandler() { static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::SQLExceptionInteractionHandler > aSQLExceptionInteractionHandler_AutoRegistration; static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::LegacyInteractionHandler > aLegacyInteractionHandler_AutoRegistration; } //......................................................................... namespace dbaui { //......................................................................... using namespace ::com::sun::star::uno; using namespace ::com::sun::star::ucb; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::task; using namespace ::com::sun::star::beans; using namespace ::dbtools; //========================================================================= //= BasicInteractionHandler //========================================================================= //------------------------------------------------------------------------- BasicInteractionHandler::BasicInteractionHandler( const Reference< XMultiServiceFactory >& _rxORB, const bool i_bFallbackToGeneric ) :m_xORB( _rxORB ) ,m_bFallbackToGeneric( i_bFallbackToGeneric ) { OSL_ENSURE( !m_bFallbackToGeneric, "BasicInteractionHandler::BasicInteractionHandler: enabling legacy behavior, there should be no clients of this anymore!" ); } //------------------------------------------------------------------------- ::sal_Bool SAL_CALL BasicInteractionHandler::handleInteractionRequest( const Reference< XInteractionRequest >& i_rRequest ) throw (RuntimeException) { return impl_handle_throw( i_rRequest ); } //------------------------------------------------------------------------- void SAL_CALL BasicInteractionHandler::handle( const Reference< XInteractionRequest >& i_rRequest ) throw(RuntimeException) { impl_handle_throw( i_rRequest ); } //------------------------------------------------------------------------- sal_Bool BasicInteractionHandler::impl_handle_throw( const Reference< XInteractionRequest >& i_Request ) { Any aRequest( i_Request->getRequest() ); DBG_ASSERT(aRequest.hasValue(), "BasicInteractionHandler::handle: invalid request!"); if ( !aRequest.hasValue() ) // no request -> no handling return sal_False; Sequence< Reference< XInteractionContinuation > > aContinuations( i_Request->getContinuations() ); // try to extract an SQLException (or one of it's derived members SQLExceptionInfo aInfo( aRequest ); if ( aInfo.isValid() ) { implHandle( aInfo, aContinuations ); return sal_True; } ParametersRequest aParamRequest; if ( aRequest >>= aParamRequest ) { implHandle( aParamRequest, aContinuations ); return sal_True; } DocumentSaveRequest aDocuRequest; if ( aRequest >>= aDocuRequest ) { implHandle( aDocuRequest, aContinuations ); return sal_True; } if ( m_bFallbackToGeneric ) return implHandleUnknown( i_Request ); return sal_False; } //------------------------------------------------------------------------- void BasicInteractionHandler::implHandle(const ParametersRequest& _rParamRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations) { ::vos::OGuard aGuard(Application::GetSolarMutex()); // want to open a dialog .... sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations); sal_Int32 nParamPos = getContinuation(SUPPLY_PARAMETERS, _rContinuations); Reference< XInteractionSupplyParameters > xParamCallback; if (-1 != nParamPos) xParamCallback = Reference< XInteractionSupplyParameters >(_rContinuations[nParamPos], UNO_QUERY); DBG_ASSERT(xParamCallback.is(), "BasicInteractionHandler::implHandle(ParametersRequest): can't set the parameters without an appropriate interaction handler!s"); // determine the style of the dialog, dependent on the present continuation types WinBits nDialogStyle = WB_OK | WB_DEF_OK; if (-1 != nAbortPos) nDialogStyle = WB_OK_CANCEL; OParameterDialog aDlg(NULL, _rParamRequest.Parameters, _rParamRequest.Connection, m_xORB); sal_Int16 nResult = aDlg.Execute(); try { switch (nResult) { case RET_OK: if (xParamCallback.is()) { xParamCallback->setParameters(aDlg.getValues()); xParamCallback->select(); } break; default: if (-1 != nAbortPos) _rContinuations[nAbortPos]->select(); break; } } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } } //------------------------------------------------------------------------- void BasicInteractionHandler::implHandle(const SQLExceptionInfo& _rSqlInfo, const Sequence< Reference< XInteractionContinuation > >& _rContinuations) { ::vos::OGuard aGuard(Application::GetSolarMutex()); // want to open a dialog .... sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations); sal_Int32 nDisapprovePos = getContinuation(DISAPPROVE, _rContinuations); sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations); sal_Int32 nRetryPos = getContinuation(RETRY, _rContinuations); // determine the style of the dialog, dependent on the present continuation types WinBits nDialogStyle = 0; bool bHaveCancel = nAbortPos != -1; // "approve" means "Yes", "disapprove" means "No" // VCL only supports having both (which makes sense ...) if ( ( nApprovePos != -1 ) || ( nDisapprovePos != -1 ) ) nDialogStyle = ( bHaveCancel ? WB_YES_NO_CANCEL : WB_YES_NO ) | WB_DEF_YES; else { // if there's no yes/no, then use a default OK button nDialogStyle = ( bHaveCancel ? WB_OK_CANCEL : WB_OK ) | WB_DEF_OK; } // If there's a "Retry" continuation, have a "Retry" button if ( nRetryPos != -1 ) { nDialogStyle = WB_RETRY_CANCEL | WB_DEF_RETRY; } // excute the dialog OSQLMessageBox aDialog(NULL, _rSqlInfo, nDialogStyle); // TODO: need a way to specify the parent window sal_Int16 nResult = aDialog.Execute(); try { switch (nResult) { case RET_YES: case RET_OK: if ( nApprovePos != -1 ) _rContinuations[ nApprovePos ]->select(); else OSL_ENSURE( nResult != RET_YES, "BasicInteractionHandler::implHandle: no handler for YES!" ); break; case RET_NO: if ( nDisapprovePos != -1 ) _rContinuations[ nDisapprovePos ]->select(); else OSL_ENSURE( false, "BasicInteractionHandler::implHandle: no handler for NO!" ); break; case RET_CANCEL: if ( nAbortPos != -1 ) _rContinuations[ nAbortPos ]->select(); else if ( nDisapprovePos != -1 ) _rContinuations[ nDisapprovePos ]->select(); else OSL_ENSURE( false, "BasicInteractionHandler::implHandle: no handler for CANCEL!" ); break; case RET_RETRY: if ( nRetryPos != -1 ) _rContinuations[ nRetryPos ]->select(); else OSL_ENSURE( false, "BasicInteractionHandler::implHandle: where does the RETRY come from?" ); break; } } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } } //------------------------------------------------------------------------- void BasicInteractionHandler::implHandle(const DocumentSaveRequest& _rDocuRequest, const Sequence< Reference< XInteractionContinuation > >& _rContinuations) { ::vos::OGuard aGuard(Application::GetSolarMutex()); // want to open a dialog .... sal_Int32 nApprovePos = getContinuation(APPROVE, _rContinuations); sal_Int32 nDisApprovePos = getContinuation(DISAPPROVE, _rContinuations); sal_Int32 nAbortPos = getContinuation(ABORT, _rContinuations); short nRet = RET_YES; if ( -1 != nApprovePos ) { // fragen, ob gespeichert werden soll nRet = ExecuteQuerySaveDocument(NULL,_rDocuRequest.Name); } if ( RET_CANCEL == nRet ) { if (-1 != nAbortPos) _rContinuations[nAbortPos]->select(); return; } else if ( RET_YES == nRet ) { sal_Int32 nDocuPos = getContinuation(SUPPLY_DOCUMENTSAVE, _rContinuations); if (-1 != nDocuPos) { Reference< XInteractionDocumentSave > xCallback(_rContinuations[nDocuPos], UNO_QUERY); DBG_ASSERT(xCallback.is(), "BasicInteractionHandler::implHandle(DocumentSaveRequest): can't save document without an appropriate interaction handler!s"); // determine the style of the dialog, dependent on the present continuation types WinBits nDialogStyle = WB_OK | WB_DEF_OK; if (-1 != nAbortPos) nDialogStyle = WB_OK_CANCEL; OCollectionView aDlg(NULL,_rDocuRequest.Content,_rDocuRequest.Name,m_xORB); sal_Int16 nResult = aDlg.Execute(); try { switch (nResult) { case RET_OK: if (xCallback.is()) { xCallback->setName(aDlg.getName(),aDlg.getSelectedFolder()); xCallback->select(); } break; default: if (-1 != nAbortPos) _rContinuations[nAbortPos]->select(); break; } } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } } else if ( -1 != nApprovePos ) _rContinuations[nApprovePos]->select(); } else if ( -1 != nDisApprovePos ) _rContinuations[nDisApprovePos]->select(); } //------------------------------------------------------------------------- bool BasicInteractionHandler::implHandleUnknown( const Reference< XInteractionRequest >& _rxRequest ) { Reference< XInteractionHandler > xFallbackHandler; if ( m_xORB.is() ) xFallbackHandler = xFallbackHandler.query( m_xORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ) ); if ( xFallbackHandler.is() ) { xFallbackHandler->handle( _rxRequest ); return true; } return false; } //------------------------------------------------------------------------- sal_Int32 BasicInteractionHandler::getContinuation(Continuation _eCont, const Sequence< Reference< XInteractionContinuation > >& _rContinuations) { const Reference< XInteractionContinuation >* pContinuations = _rContinuations.getConstArray(); for (sal_Int32 i=0; i<_rContinuations.getLength(); ++i, ++pContinuations) { switch (_eCont) { case APPROVE: if (Reference< XInteractionApprove >(*pContinuations, UNO_QUERY).is()) return i; break; case DISAPPROVE: if (Reference< XInteractionDisapprove >(*pContinuations, UNO_QUERY).is()) return i; break; case RETRY: if (Reference< XInteractionRetry >(*pContinuations, UNO_QUERY).is()) return i; break; case ABORT: if (Reference< XInteractionAbort >(*pContinuations, UNO_QUERY).is()) return i; break; case SUPPLY_PARAMETERS: if (Reference< XInteractionSupplyParameters >(*pContinuations, UNO_QUERY).is()) return i; break; case SUPPLY_DOCUMENTSAVE: if (Reference< XInteractionDocumentSave >(*pContinuations, UNO_QUERY).is()) return i; break; } } return -1; } //========================================================================== //= SQLExceptionInteractionHandler //========================================================================== IMPLEMENT_SERVICE_INFO1_STATIC( SQLExceptionInteractionHandler, "com.sun.star.comp.dbaccess.DatabaseInteractionHandler", "com.sun.star.sdb.DatabaseInteractionHandler" ); //========================================================================== //= LegacyInteractionHandler //========================================================================== IMPLEMENT_SERVICE_INFO1_STATIC( LegacyInteractionHandler, "com.sun.star.comp.dbaccess.LegacyInteractionHandler", "com.sun.star.sdb.InteractionHandler" ); //......................................................................... } // namespace dbaui //.........................................................................