diff options
Diffstat (limited to 'dbaccess/source/ui/browser')
22 files changed, 15515 insertions, 0 deletions
diff --git a/dbaccess/source/ui/browser/AsyncronousLink.cxx b/dbaccess/source/ui/browser/AsyncronousLink.cxx new file mode 100644 index 000000000000..157024f497f8 --- /dev/null +++ b/dbaccess/source/ui/browser/AsyncronousLink.cxx @@ -0,0 +1,112 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" +#ifndef DBAUI_ASYNCRONOUSLINK_HXX +#include "AsyncronousLink.hxx" +#endif +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +//================================================================== +//= OAsyncronousLink +//================================================================== +using namespace dbaui; +DBG_NAME(OAsyncronousLink) +//------------------------------------------------------------------ +OAsyncronousLink::OAsyncronousLink( const Link& _rHandler ) + :m_aHandler(_rHandler) + ,m_aEventSafety() + ,m_aDestructionSafety() + ,m_nEventId(0) +{ + DBG_CTOR(OAsyncronousLink,NULL); +} + +//------------------------------------------------------------------ +OAsyncronousLink::~OAsyncronousLink() +{ + { + ::osl::MutexGuard aEventGuard( m_aEventSafety ); + if ( m_nEventId ) + Application::RemoveUserEvent(m_nEventId); + m_nEventId = 0; + } + + { + ::osl::MutexGuard aDestructionGuard( m_aDestructionSafety ); + // this is just for the case we're deleted while another thread just handled the event : + // if this other thread called our link while we were deleting the event here, the + // link handler blocked. With leaving the above block it continued, but now we are prevented + // to leave this destructor 'til the link handler recognizes that nEvent == 0 and leaves. + } + DBG_DTOR(OAsyncronousLink,NULL); +} + + +//------------------------------------------------------------------ +void OAsyncronousLink::Call( void* _pArgument ) +{ + ::osl::MutexGuard aEventGuard( m_aEventSafety ); + if (m_nEventId) + Application::RemoveUserEvent(m_nEventId); + m_nEventId = Application::PostUserEvent( LINK( this, OAsyncronousLink, OnAsyncCall ), _pArgument ); +} + +//------------------------------------------------------------------ +void OAsyncronousLink::CancelCall() +{ + ::osl::MutexGuard aEventGuard( m_aEventSafety ); + if ( m_nEventId ) + Application::RemoveUserEvent( m_nEventId ); + m_nEventId = 0; +} + +//------------------------------------------------------------------ +IMPL_LINK(OAsyncronousLink, OnAsyncCall, void*, _pArg) +{ + { + ::osl::MutexGuard aDestructionGuard( m_aDestructionSafety ); + { + ::osl::MutexGuard aEventGuard( m_aEventSafety ); + if (!m_nEventId) + // our destructor deleted the event just while we we're waiting for m_aEventSafety + // -> get outta here + return 0; + m_nEventId = 0; + } + } + if (m_aHandler.IsSet()) + return m_aHandler.Call(_pArg); + + return 0L; +} diff --git a/dbaccess/source/ui/browser/bcommon.src b/dbaccess/source/ui/browser/bcommon.src new file mode 100644 index 000000000000..8c79179eda20 --- /dev/null +++ b/dbaccess/source/ui/browser/bcommon.src @@ -0,0 +1,35 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _DBU_RESOURCE_HRC_ +#include "dbu_resource.hrc" +#endif + +String RID_STR_TBL_TITLE +{ + Text [ en-US ] = "Table #" ; +}; + diff --git a/dbaccess/source/ui/browser/brwctrlr.cxx b/dbaccess/source/ui/browser/brwctrlr.cxx new file mode 100644 index 000000000000..6a2161b1c291 --- /dev/null +++ b/dbaccess/source/ui/browser/brwctrlr.cxx @@ -0,0 +1,3081 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + + + +#include "browserids.hxx" +#include "brwctrlr.hxx" +#include "brwview.hxx" +#include "dbu_brw.hrc" +#include "dbustrings.hrc" +#include "queryfilter.hxx" +#include "queryorder.hxx" +#include "sqlmessage.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/form/FormButtonType.hpp> +#include <com/sun/star/form/FormSubmitEncoding.hpp> +#include <com/sun/star/form/FormSubmitMethod.hpp> +#include <com/sun/star/form/XApproveActionBroadcaster.hpp> +#include <com/sun/star/form/XBoundControl.hpp> +#include <com/sun/star/form/XChangeBroadcaster.hpp> +#include <com/sun/star/form/XChangeListener.hpp> +#include <com/sun/star/form/XDatabaseParameterBroadcaster.hpp> +#include <com/sun/star/form/XLoadable.hpp> +#include <com/sun/star/form/XReset.hpp> +#include <com/sun/star/form/XResetListener.hpp> +#include <com/sun/star/form/XSubmit.hpp> +#include <com/sun/star/form/XSubmitListener.hpp> +#include <com/sun/star/form/runtime/XFormController.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdb/ErrorCondition.hpp> +#include <com/sun/star/sdb/ParametersRequest.hpp> +#include <com/sun/star/sdb/SQLContext.hpp> +#include <com/sun/star/sdb/XInteractionSupplyParameters.hpp> +#include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp> +#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> +#include <com/sun/star/sdb/SQLFilterOperator.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> +#include <com/sun/star/sdbc/XResultSetUpdate.hpp> +#include <com/sun/star/sdbc/XRowSetListener.hpp> +#include <com/sun/star/sdbc/XWarningsSupplier.hpp> +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbcx/XRowLocate.hpp> +#include <com/sun/star/task/XInteractionHandler.hpp> +#include <com/sun/star/uno/TypeClass.hpp> +#include <com/sun/star/util/XCancellable.hpp> +/** === end UNO includes === **/ + +#include <comphelper/enumhelper.hxx> +#include <comphelper/extract.hxx> +#include <comphelper/interaction.hxx> +#include <comphelper/sequence.hxx> +#include <connectivity/dbexception.hxx> +#include <connectivity/dbtools.hxx> +#include <connectivity/sqlerror.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <osl/mutex.hxx> +#include <rtl/logfile.hxx> +#include <sfx2/app.hxx> +#include <sfx2/sfx.hrc> +#include <svx/fmsearch.hxx> +#include <svx/svxdlg.hxx> +#include <tools/color.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/msgbox.hxx> +#include <vcl/waitobj.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::container; +using namespace ::dbtools; +using namespace ::comphelper; +using namespace ::svt; + +#define HANDLE_SQL_ERRORS( action, successflag, context, message ) \ + try \ + { \ + successflag = sal_False; \ + action; \ + successflag = sal_True; \ + } \ + catch(SQLException& e) \ + { \ + SQLException aError = ::dbtools::prependErrorInfo(e, *this, context); \ + ::com::sun::star::sdb::SQLErrorEvent aEvent; \ + aEvent.Reason <<= aError; \ + errorOccured(aEvent); \ + } \ + catch(Exception&) \ + { \ + DBG_UNHANDLED_EXCEPTION(); \ + } \ + +#define DO_SAFE( action, message ) try { action; } catch(Exception&) { DBG_ERROR(message); } ; + +//.................................................................. +namespace dbaui +{ +//.................................................................. + +//================================================================== +// OParameterContinuation +//================================================================== +class OParameterContinuation : public OInteraction< XInteractionSupplyParameters > +{ + Sequence< PropertyValue > m_aValues; + +public: + OParameterContinuation() { } + + Sequence< PropertyValue > getValues() const { return m_aValues; } + +// XInteractionSupplyParameters + virtual void SAL_CALL setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException); +}; + +//------------------------------------------------------------------ +void SAL_CALL OParameterContinuation::setParameters( const Sequence< PropertyValue >& _rValues ) throw(RuntimeException) +{ + m_aValues = _rValues; +} + + +//============================================================================== +// a helper class implementing a runtime::XFormController, will be aggregated by SbaXDataBrowserController +// (we can't derive from XFormController as it's base class is XTabController and the XTabController::getModel collides +// with the XController::getModel implemented in our base class SbaXDataBrowserController) +class SbaXDataBrowserController::FormControllerImpl + : public ::cppu::WeakAggImplHelper2< ::com::sun::star::form::runtime::XFormController, + ::com::sun::star::frame::XFrameActionListener > +{ + friend class SbaXDataBrowserController; + ::cppu::OInterfaceContainerHelper m_aActivateListeners; + SbaXDataBrowserController* m_pOwner; + +public: + FormControllerImpl(SbaXDataBrowserController* pOwner); + + // XFormController + virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormOperations > SAL_CALL getFormOperations() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > SAL_CALL getCurrentControl(void) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL addActivateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL removeActivateListener(const ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL addChildController( const ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormController >& _ChildController ) throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException ); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormControllerContext > SAL_CALL getContext() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setContext( const ::com::sun::star::uno::Reference< ::com::sun::star::form::runtime::XFormControllerContext >& _context ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler > SAL_CALL getInteractionHandler() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setInteractionHandler( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& _interactionHandler ) throw (::com::sun::star::uno::RuntimeException); + + // XChild, base of XFormController + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + + // XComponent, base of XFormController + virtual void SAL_CALL dispose( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XIndexAccess, base of XFormController + virtual ::sal_Int32 SAL_CALL getCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + + // XElementAccess, base of XIndexAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException); + + // XEnumerationAccess, base of XElementAccess + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XEnumeration > SAL_CALL createEnumeration( ) throw (::com::sun::star::uno::RuntimeException); + + // XModifyBroadcaster, base of XFormController + virtual void SAL_CALL addModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeModifyListener( const ::com::sun::star::uno::Reference< ::com::sun::star::util::XModifyListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XConfirmDeleteBroadcaster, base of XFormController + virtual void SAL_CALL addConfirmDeleteListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XConfirmDeleteListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeConfirmDeleteListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XConfirmDeleteListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XSQLErrorBroadcaster, base of XFormController + virtual void SAL_CALL addSQLErrorListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeSQLErrorListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XSQLErrorListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + + // XRowSetApproveBroadcaster, base of XFormController + virtual void SAL_CALL addRowSetApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener >& listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeRowSetApproveListener( const ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XRowSetApproveListener >& listener ) throw (::com::sun::star::uno::RuntimeException); + + // XDatabaseParameterBroadcaster2, base of XFormController + virtual void SAL_CALL addDatabaseParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeDatabaseParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XDatabaseParameterBroadcaster, base of XDatabaseParameterBroadcaster2 + virtual void SAL_CALL addParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeParameterListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener ) throw (::com::sun::star::uno::RuntimeException); + + // XModeSelector, base of XFormController + virtual void SAL_CALL setMode( const ::rtl::OUString& aMode ) throw (::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getMode( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedModes( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL supportsMode( const ::rtl::OUString& aMode ) throw (::com::sun::star::uno::RuntimeException); + + // XTabController, base of XFormController + virtual void SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel > & Model) throw( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTabControllerModel > SAL_CALL getModel(void) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL setContainer(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > & _Container) throw( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SAL_CALL getContainer(void) throw( ::com::sun::star::uno::RuntimeException ); + virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl > > SAL_CALL getControls(void) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL autoTabOrder(void) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL activateTabOrder(void) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL activateFirst(void) throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL activateLast(void) throw( ::com::sun::star::uno::RuntimeException ); + + // XFrameActionListener + virtual void SAL_CALL frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( ::com::sun::star::uno::RuntimeException ); + + // XEventListener + virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( ::com::sun::star::uno::RuntimeException ); + +protected: + ~FormControllerImpl(); +}; + + +DBG_NAME(FormControllerImpl) +//------------------------------------------------------------------ +SbaXDataBrowserController::FormControllerImpl::FormControllerImpl(SbaXDataBrowserController* _pOwner) + :m_aActivateListeners(_pOwner->getMutex()) + ,m_pOwner(_pOwner) +{ + DBG_CTOR(FormControllerImpl,NULL); + + OSL_ENSURE(m_pOwner, "SbaXDataBrowserController::FormControllerImpl::FormControllerImpl : invalid Owner !"); +} + +//------------------------------------------------------------------ +SbaXDataBrowserController::FormControllerImpl::~FormControllerImpl() +{ + + DBG_DTOR(FormControllerImpl,NULL); +} + +//------------------------------------------------------------------ +Reference< runtime::XFormOperations > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getFormOperations() throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::getFormOperations: not supported!" ); + return NULL; +} + +//------------------------------------------------------------------ +Reference< ::com::sun::star::awt::XControl > SbaXDataBrowserController::FormControllerImpl::getCurrentControl(void) throw( RuntimeException ) +{ + return m_pOwner->getBrowserView() ? m_pOwner->getBrowserView()->getGridControl() : Reference< ::com::sun::star::awt::XControl > (); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addActivateListener(const Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( RuntimeException ) +{ + m_aActivateListeners.addInterface(l); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeActivateListener(const Reference< ::com::sun::star::form::XFormControllerListener > & l) throw( RuntimeException ) +{ + m_aActivateListeners.removeInterface(l); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addChildController( const Reference< runtime::XFormController >& /*_ChildController*/ ) throw( RuntimeException, IllegalArgumentException ) +{ + // not supported + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); +} + +//------------------------------------------------------------------ +Reference< runtime::XFormControllerContext > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getContext() throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::getContext: no support!!" ); + return NULL; +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setContext( const Reference< runtime::XFormControllerContext >& /*_context*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::setContext: no support!!" ); +} + +//------------------------------------------------------------------ +Reference< XInteractionHandler > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getInteractionHandler() throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::getInteractionHandler: no support!!" ); + return NULL; +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setInteractionHandler( const Reference< XInteractionHandler >& /*_interactionHandler*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::setInteractionHandler: no support!!" ); +} + +//------------------------------------------------------------------ +Reference< XInterface > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getParent( ) throw (RuntimeException) +{ + // don't have any parent form controllers + return NULL; +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setParent( const Reference< XInterface >& /*Parent*/ ) throw (NoSupportException, RuntimeException) +{ + throw NoSupportException( ::rtl::OUString(), *this ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::dispose( ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::dispose: no, you do *not* want to do this!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addEventListener( const Reference< XEventListener >& /*xListener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addEventListener: no support!!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeEventListener( const Reference< XEventListener >& /*aListener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeEventListener: no support!!" ); +} + +//------------------------------------------------------------------ +::sal_Int32 SAL_CALL SbaXDataBrowserController::FormControllerImpl::getCount( ) throw (RuntimeException) +{ + // no sub controllers, never + return 0; +} + +//------------------------------------------------------------------ +Any SAL_CALL SbaXDataBrowserController::FormControllerImpl::getByIndex( ::sal_Int32 /*Index*/ ) throw (IndexOutOfBoundsException, WrappedTargetException, RuntimeException) +{ + // no sub controllers, never + throw IndexOutOfBoundsException( ::rtl::OUString(), *this ); +} + +//------------------------------------------------------------------ +Type SAL_CALL SbaXDataBrowserController::FormControllerImpl::getElementType( ) throw (RuntimeException) +{ + return ::cppu::UnoType< runtime::XFormController >::get(); +} + +//------------------------------------------------------------------ +::sal_Bool SAL_CALL SbaXDataBrowserController::FormControllerImpl::hasElements( ) throw (RuntimeException) +{ + // no sub controllers, never + return false; +} + +//------------------------------------------------------------------ +Reference< XEnumeration > SAL_CALL SbaXDataBrowserController::FormControllerImpl::createEnumeration( ) throw (RuntimeException) +{ + return new ::comphelper::OEnumerationByIndex( this ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addModifyListener( const Reference< XModifyListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addModifyListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeModifyListener( const Reference< XModifyListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeModifyListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addConfirmDeleteListener( const Reference< XConfirmDeleteListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addConfirmDeleteListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeConfirmDeleteListener( const Reference< XConfirmDeleteListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeConfirmDeleteListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addSQLErrorListener( const Reference< XSQLErrorListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addSQLErrorListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeSQLErrorListener( const Reference< XSQLErrorListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeSQLErrorListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addRowSetApproveListener( const Reference< XRowSetApproveListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addRowSetApproveListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeRowSetApproveListener( const Reference< XRowSetApproveListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeRowSetApproveListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addDatabaseParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addDatabaseParameterListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeDatabaseParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeDatabaseParameterListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::addParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::addParameterListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::removeParameterListener( const Reference< XDatabaseParameterListener >& /*_Listener*/ ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SbaXDataBrowserController::FormControllerImpl::removeParameterListener: no support!" ); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setMode( const ::rtl::OUString& _rMode ) throw (NoSupportException, RuntimeException) +{ + if ( !supportsMode( _rMode ) ) + throw NoSupportException(); +} + +//------------------------------------------------------------------ +::rtl::OUString SAL_CALL SbaXDataBrowserController::FormControllerImpl::getMode( ) throw (RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) ); +} + +//------------------------------------------------------------------ +Sequence< ::rtl::OUString > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getSupportedModes( ) throw (RuntimeException) +{ + Sequence< ::rtl::OUString > aModes(1); + aModes[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DataMode" ) ); + return aModes; +} + +//------------------------------------------------------------------ +::sal_Bool SAL_CALL SbaXDataBrowserController::FormControllerImpl::supportsMode( const ::rtl::OUString& aMode ) throw (RuntimeException) +{ + return aMode.compareToAscii( "DataMode" ) == 0; +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setModel(const Reference< ::com::sun::star::awt::XTabControllerModel > & /*Model*/) throw( RuntimeException ) +{ + OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::setModel : invalid call, can't change my model !"); +} + +//------------------------------------------------------------------ +Reference< ::com::sun::star::awt::XTabControllerModel > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getModel(void) throw( RuntimeException ) +{ + return Reference< XTabControllerModel >(m_pOwner->getRowSet(), UNO_QUERY); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::setContainer(const Reference< ::com::sun::star::awt::XControlContainer > & /*_Container*/) throw( RuntimeException ) +{ + OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::setContainer : invalid call, can't change my container !"); +} + +//------------------------------------------------------------------ +Reference< ::com::sun::star::awt::XControlContainer > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getContainer(void) throw( RuntimeException ) +{ + if (m_pOwner->getBrowserView()) + return m_pOwner->getBrowserView()->getContainer(); + return Reference< ::com::sun::star::awt::XControlContainer > (); +} + +//------------------------------------------------------------------ +Sequence< Reference< ::com::sun::star::awt::XControl > > SAL_CALL SbaXDataBrowserController::FormControllerImpl::getControls(void) throw( RuntimeException ) +{ + if (m_pOwner->getBrowserView()) + { + Reference< ::com::sun::star::awt::XControl > xGrid = m_pOwner->getBrowserView()->getGridControl(); + return Sequence< Reference< ::com::sun::star::awt::XControl > >(&xGrid, 1); + } + return Sequence< Reference< ::com::sun::star::awt::XControl > >(); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::autoTabOrder(void) throw( RuntimeException ) +{ + OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::autoTabOrder : nothing to do (always have only one control) !"); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateTabOrder(void) throw( RuntimeException ) +{ + OSL_ENSURE(sal_False, "SbaXDataBrowserController::FormControllerImpl::activateTabOrder : nothing to do (always have only one control) !"); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateFirst(void) throw( RuntimeException ) +{ + if (m_pOwner->getBrowserView()) + m_pOwner->getBrowserView()->getVclControl()->ActivateCell(); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::activateLast(void) throw( RuntimeException ) +{ + if (m_pOwner->getBrowserView()) + m_pOwner->getBrowserView()->getVclControl()->ActivateCell(); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::frameAction(const ::com::sun::star::frame::FrameActionEvent& /*aEvent*/) throw( RuntimeException ) +{ +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::FormControllerImpl::disposing(const ::com::sun::star::lang::EventObject& /*Source*/) throw( RuntimeException ) +{ + // nothing to do + // we don't add ourself as listener to any broadcasters, so we are not resposible for removing us +} + +//================================================================== +//= SbaXDataBrowserController +//================================================================== +//------------------------------------------------------------------ +Sequence< Type > SAL_CALL SbaXDataBrowserController::getTypes( ) throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getTypes" ); + return ::comphelper::concatSequences( + SbaXDataBrowserController_Base::getTypes(), + m_pFormControllerImpl->getTypes() + ); +} + +//------------------------------------------------------------------ +Sequence< sal_Int8 > SAL_CALL SbaXDataBrowserController::getImplementationId( ) throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getImplementationId" ); + static ::cppu::OImplementationId * pId = 0; + if (! pId) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pId) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +//------------------------------------------------------------------ +Any SAL_CALL SbaXDataBrowserController::queryInterface(const Type& _rType) throw (RuntimeException) +{ + // check for our additional interfaces + Any aRet = SbaXDataBrowserController_Base::queryInterface(_rType); + + // check for our aggregate (implementing the XFormController) + if (!aRet.hasValue()) + aRet = m_xFormControllerImpl->queryAggregation(_rType); + + // no more to offer + return aRet; +} + +DBG_NAME(SbaXDataBrowserController) +//------------------------------------------------------------------------------ +SbaXDataBrowserController::SbaXDataBrowserController(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM) + :SbaXDataBrowserController_Base(_rM) + ,m_nRowSetPrivileges(0) + ,m_pClipbordNotifier( NULL ) + ,m_aAsyncGetCellFocus(LINK(this, SbaXDataBrowserController, OnAsyncGetCellFocus)) + ,m_aAsyncDisplayError( LINK( this, SbaXDataBrowserController, OnAsyncDisplayError ) ) + ,m_sStateSaveRecord(ModuleRes(RID_STR_SAVE_CURRENT_RECORD)) + ,m_sStateUndoRecord(ModuleRes(RID_STR_UNDO_MODIFY_RECORD)) + ,m_sModuleIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DataSourceBrowser" ) ) ) + ,m_pFormControllerImpl(NULL) + ,m_nPendingLoadFinished(0) + ,m_nFormActionNestingLevel(0) + ,m_bLoadCanceled( sal_False ) + ,m_bClosingKillOpen( sal_False ) + ,m_bCannotSelectUnfiltered( true ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SbaXDataBrowserController" ); + DBG_CTOR(SbaXDataBrowserController,NULL); + + // create the form controller aggregate + ::comphelper::increment(m_refCount); + { + m_pFormControllerImpl = new FormControllerImpl(this); + m_xFormControllerImpl = m_pFormControllerImpl; + m_xFormControllerImpl->setDelegator(*this); + } + ::comphelper::decrement(m_refCount); + + m_aInvalidateClipboard.SetTimeoutHdl(LINK(this, SbaXDataBrowserController, OnInvalidateClipboard)); + m_aInvalidateClipboard.SetTimeout(300); +} + +//------------------------------------------------------------------------------ +SbaXDataBrowserController::~SbaXDataBrowserController() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::~SbaXDataBrowserController" ); + // deleteView(); + // release the aggregated form controller + if (m_xFormControllerImpl.is()) + { + Reference< XInterface > xEmpty; + m_xFormControllerImpl->setDelegator(xEmpty); + } + + DBG_DTOR(SbaXDataBrowserController,NULL); +} + +// ----------------------------------------------------------------------- +void SbaXDataBrowserController::startFrameListening( const Reference< XFrame >& _rxFrame ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::startFrameListening" ); + SbaXDataBrowserController_Base::startFrameListening( _rxFrame ); + + Reference< XFrameActionListener > xAggListener; + if ( m_xFormControllerImpl.is() ) + m_xFormControllerImpl->queryAggregation( XFrameActionListener::static_type() ) >>= xAggListener; + + if ( _rxFrame.is() && xAggListener.is() ) + _rxFrame->addFrameActionListener( xAggListener ); +} + +// ----------------------------------------------------------------------- +void SbaXDataBrowserController::stopFrameListening( const Reference< XFrame >& _rxFrame ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::stopFrameListening" ); + SbaXDataBrowserController_Base::stopFrameListening( _rxFrame ); + + Reference< XFrameActionListener > xAggListener; + if ( m_xFormControllerImpl.is() ) + m_xFormControllerImpl->queryAggregation( XFrameActionListener::static_type() ) >>= xAggListener; + + if ( _rxFrame.is() && xAggListener.is() ) + _rxFrame->removeFrameActionListener( xAggListener ); +} + +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::onStartLoading( const Reference< XLoadable >& _rxLoadable ) +{ + m_bLoadCanceled = sal_False; + m_bCannotSelectUnfiltered = false; + + Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY ); + if ( xWarnings.is() ) + xWarnings->clearWarnings(); +} + +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::impl_checkForCannotSelectUnfiltered( const SQLExceptionInfo& _rError ) +{ + ::connectivity::SQLError aError( getORB() ); + ::connectivity::ErrorCode nErrorCode( aError.getErrorCode( ErrorCondition::DATA_CANNOT_SELECT_UNFILTERED ) ); + if ( ((const SQLException*)_rError)->ErrorCode == nErrorCode ) + { + m_bCannotSelectUnfiltered = true; + InvalidateFeature( ID_BROWSER_FILTERCRIT ); + } +} + +// ----------------------------------------------------------------------------- +sal_Bool SbaXDataBrowserController::reloadForm( const Reference< XLoadable >& _rxLoadable ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloadForm" ); + WaitObject aWO(getBrowserView()); + + onStartLoading( _rxLoadable ); + + FormErrorHelper aReportError(this); + if (_rxLoadable->isLoaded()) + _rxLoadable->reload(); + else + _rxLoadable->load(); + + m_xParser.clear(); + const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING))) + xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser; + + Reference< XWarningsSupplier > xWarnings( _rxLoadable, UNO_QUERY ); + if ( xWarnings.is() ) + { + SQLExceptionInfo aInfo( xWarnings->getWarnings() ); + if ( aInfo.isValid() ) + { + showError( aInfo ); + impl_checkForCannotSelectUnfiltered( aInfo ); + } + } + + return _rxLoadable->isLoaded(); +} + +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::initFormatter() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::initFormatter" ); + // --------------------------------------------------------------- + // create a formatter working with the connections format supplier + Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier(::dbtools::getNumberFormats(::dbtools::getConnection(m_xRowSet), sal_True,getORB())); + + if(xSupplier.is()) + { + // create a new formatter + m_xFormatter = Reference< ::com::sun::star::util::XNumberFormatter > ( + getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.NumberFormatter")), UNO_QUERY); + if (m_xFormatter.is()) + m_xFormatter->attachNumberFormatsSupplier(xSupplier); + } + else // clear the formatter + m_xFormatter = NULL; +} +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::describeSupportedFeatures() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::describeSupportedFeatures" ); + SbaXDataBrowserController_Base::describeSupportedFeatures(); + implDescribeSupportedFeature( ".uno:FormSlots/undoRecord", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:FormController/undoRecord", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:RecUndo", ID_BROWSER_UNDORECORD, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:FormSlots/saveRecord", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:FormController/saveRecord", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:RecSave", ID_BROWSER_SAVERECORD, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:Save", ID_BROWSER_SAVERECORD, CommandGroup::DOCUMENT ); + implDescribeSupportedFeature( ".uno:RecSearch", SID_FM_SEARCH, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:AutoFilter", SID_FM_AUTOFILTER, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:Refresh", SID_FM_REFRESH, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:OrderCrit", SID_FM_ORDERCRIT, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:RemoveFilterSort", SID_FM_REMOVE_FILTER_SORT,CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:FormFiltered", SID_FM_FORM_FILTERED, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:FilterCrit", SID_FM_FILTERCRIT, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:Sortup", ID_BROWSER_SORTUP, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:SortDown", ID_BROWSER_SORTDOWN, CommandGroup::CONTROLS ); + implDescribeSupportedFeature( ".uno:FormSlots/deleteRecord", SID_FM_DELETEROWS, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:FormSlots/insertRecord", ID_BROWSER_INSERT_ROW, CommandGroup::INSERT ); +} +//------------------------------------------------------------------------------ +sal_Bool SbaXDataBrowserController::Construct(Window* pParent) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::Construct" ); + // --------------------------------------------- + // create/initialize the form and the grid model + m_xRowSet = CreateForm(); + if (!m_xRowSet.is()) + return sal_False; + + m_xColumnsSupplier.set(m_xRowSet,UNO_QUERY); + m_xLoadable.set(m_xRowSet,UNO_QUERY); + + if (!InitializeForm(m_xRowSet)) + return sal_False; + + m_xGridModel = CreateGridModel(); + if (!m_xGridModel.is()) + return sal_False; + + // set the formatter if available + initFormatter(); + // --------------------------------------------------------------- + + // we want to have a grid with a "flat" border + Reference< XPropertySet > xGridSet(m_xGridModel, UNO_QUERY); + if ( xGridSet.is() ) + xGridSet->setPropertyValue(PROPERTY_BORDER, makeAny((sal_Int16)2)); + + // ---------- + // marry them + Reference< ::com::sun::star::container::XNameContainer > xNameCont(m_xRowSet, UNO_QUERY); + { + String sText(ModuleRes(STR_DATASOURCE_GRIDCONTROL_NAME)); + xNameCont->insertByName(::rtl::OUString(sText), makeAny(m_xGridModel)); + } + + // --------------- + // create the view + setView( * new UnoDataBrowserView( pParent, *this, getORB() ) ); + if (!getBrowserView()) + return sal_False; + + // late construction + sal_Bool bSuccess = sal_False; + try + { + getBrowserView()->Construct(getControlModel()); + bSuccess = sal_True; + } + catch(SQLException&) + { + } + catch(Exception&) + { + DBG_ERROR("SbaXDataBrowserController::Construct : the construction of UnoDataBrowserView failed !"); + } + + if (!bSuccess) + { + // deleteView(); + return sal_False; + } + + // now that we have a view we can create the clipboard listener + m_aSystemClipboard = TransferableDataHelper::CreateFromSystemClipboard( getView() ); + m_aSystemClipboard.StartClipboardListening( ); + + m_pClipbordNotifier = new TransferableClipboardListener( LINK( this, SbaXDataBrowserController, OnClipboardChanged ) ); + m_pClipbordNotifier->acquire(); + m_pClipbordNotifier->AddRemoveListener( getView(), sal_True ); + + // this call create the toolbox + SbaXDataBrowserController_Base::Construct(pParent); + + getBrowserView()->Show(); + + // set the callbacks for the grid control + SbaGridControl* pVclGrid = getBrowserView()->getVclControl(); + DBG_ASSERT(pVclGrid, "SbaXDataBrowserController::Construct : have no VCL control !"); + pVclGrid->SetMasterListener(this); + + // -------------------------- + // add listeners ... + + // ... to the form model + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (xFormSet.is()) + { + xFormSet->addPropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this)); + xFormSet->addPropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this)); + xFormSet->addPropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this)); + xFormSet->addPropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this)); + xFormSet->addPropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this)); + xFormSet->addPropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this)); + xFormSet->addPropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this)); + xFormSet->addPropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this)); + } + Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY); + if (xFormError.is()) + xFormError->addSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this); + + if (m_xLoadable.is()) + m_xLoadable->addLoadListener(this); + + Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xFormParameter(getRowSet(), UNO_QUERY); + if (xFormParameter.is()) + xFormParameter->addParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this); + + addModelListeners(getControlModel()); + addControlListeners(getBrowserView()->getGridControl()); + + // ------------- + // load the form + return LoadForm(); +} + +//------------------------------------------------------------------------------ +sal_Bool SbaXDataBrowserController::LoadForm() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::LoadForm" ); + reloadForm( m_xLoadable ); + return sal_True; +} +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::AddColumnListener(const Reference< XPropertySet > & /*xCol*/) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::AddColumnListener" ); + // we're not interested in any column properties ... +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::RemoveColumnListener(const Reference< XPropertySet > & /*xCol*/) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::RemoveColumnListener" ); +} +//------------------------------------------------------------------------------ +Reference< XRowSet > SbaXDataBrowserController::CreateForm() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CreateForm" ); + return Reference< XRowSet > (getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.component.Form")), UNO_QUERY); +} + +//------------------------------------------------------------------------------ +Reference< ::com::sun::star::form::XFormComponent > SbaXDataBrowserController::CreateGridModel() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CreateGridModel" ); + return Reference< ::com::sun::star::form::XFormComponent > (getORB()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.form.component.GridControl")), UNO_QUERY); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addModelListeners" ); + // ... all the grid columns + addColumnListeners(_xGridControlModel); + + // (we are interested in all columns the grid has (and only in these) so we have to listen to the container, too) + Reference< ::com::sun::star::container::XContainer > xColContainer(_xGridControlModel, UNO_QUERY); + if (xColContainer.is()) + xColContainer->addContainerListener((::com::sun::star::container::XContainerListener*)this); + + Reference< ::com::sun::star::form::XReset > xReset(_xGridControlModel, UNO_QUERY); + if (xReset.is()) + xReset->addResetListener((::com::sun::star::form::XResetListener*)this); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::removeModelListeners(const Reference< XControlModel > & _xGridControlModel) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::removeModelListeners" ); + // every single column model + Reference< XIndexContainer > xColumns(_xGridControlModel, UNO_QUERY); + if (xColumns.is()) + { + sal_Int32 nCount = xColumns->getCount(); + for (sal_uInt16 i=0; i < nCount; ++i) + { + Reference< XPropertySet > xCol(xColumns->getByIndex(i),UNO_QUERY); + RemoveColumnListener(xCol); + } + } + + Reference< XContainer > xColContainer(_xGridControlModel, UNO_QUERY); + if (xColContainer.is()) + xColContainer->removeContainerListener( this ); + + Reference< XReset > xReset(_xGridControlModel, UNO_QUERY); + if (xReset.is()) + xReset->removeResetListener( this ); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::addControlListeners(const Reference< ::com::sun::star::awt::XControl > & _xGridControl) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addControlListeners" ); + // to ge the 'modified' for the current cell + Reference< XModifyBroadcaster > xBroadcaster(getBrowserView()->getGridControl(), UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->addModifyListener(static_cast<XModifyListener*>(this)); + + // introduce ourself as dispatch provider for the grid + Reference< XDispatchProviderInterception > xInterception(getBrowserView()->getGridControl(), UNO_QUERY); + if (xInterception.is()) + xInterception->registerDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this)); + + // add as focus listener to the control (needed for the form controller functionality) + Reference< XWindow > xWindow(_xGridControl, UNO_QUERY); + if (xWindow.is()) + xWindow->addFocusListener(this); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::removeControlListeners(const Reference< ::com::sun::star::awt::XControl > & _xGridControl) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::removeControlListeners" ); + Reference< XModifyBroadcaster > xBroadcaster(_xGridControl, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->removeModifyListener(static_cast<XModifyListener*>(this)); + + Reference< XDispatchProviderInterception > xInterception(_xGridControl, UNO_QUERY); + if (xInterception.is()) + xInterception->releaseDispatchProviderInterceptor(static_cast<XDispatchProviderInterceptor*>(this)); + + Reference< XWindow > xWindow(_xGridControl, UNO_QUERY); + if (xWindow.is()) + xWindow->removeFocusListener(this); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::focusGained(const FocusEvent& /*e*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::focusGained" ); + // notify our activate listeners (registered on the form controller aggregate) + EventObject aEvt(*this); + ::cppu::OInterfaceIteratorHelper aIter(m_pFormControllerImpl->m_aActivateListeners); + while (aIter.hasMoreElements()) + static_cast<XFormControllerListener*>(aIter.next())->formActivated(aEvt); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaXDataBrowserController::focusLost(const FocusEvent& e) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::focusLost" ); + // some general checks + if (!getBrowserView() || !getBrowserView()->getGridControl().is()) + return; + Reference< XVclWindowPeer > xMyGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY); + if (!xMyGridPeer.is()) + return; + Reference< XWindowPeer > xNextControlPeer(e.NextFocus, UNO_QUERY); + if (!xNextControlPeer.is()) + return; + + // don't do a notification if it remains in the family (i.e. a child of the grid control gets the focus) + if (xMyGridPeer->isChild(xNextControlPeer)) + return; + + if (xMyGridPeer == xNextControlPeer) + return; + + // notify the listeners that the "form" we represent has been deactivated + EventObject aEvt(*this); + ::cppu::OInterfaceIteratorHelper aIter(m_pFormControllerImpl->m_aActivateListeners); + while (aIter.hasMoreElements()) + static_cast<XFormControllerListener*>(aIter.next())->formDeactivated(aEvt); + + // commit the changes of the grid control (as we're deactivated) + Reference< XBoundComponent > xCommitable(getBrowserView()->getGridControl(), UNO_QUERY); + if (xCommitable.is()) + xCommitable->commit(); + else + OSL_ENSURE(sal_False, "SbaXDataBrowserController::focusLost : why is my control not commitable ?"); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::disposingGridControl(const ::com::sun::star::lang::EventObject& /*Source*/) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingGridControl" ); + removeControlListeners(getBrowserView()->getGridControl()); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::disposingGridModel(const ::com::sun::star::lang::EventObject& /*Source*/) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingGridModel" ); + removeModelListeners(getControlModel()); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::disposingFormModel(const ::com::sun::star::lang::EventObject& Source) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingFormModel" ); + Reference< XPropertySet > xSourceSet(Source.Source, UNO_QUERY); + if (xSourceSet.is()) + { + xSourceSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this)); + } + + Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(Source.Source, UNO_QUERY); + if (xFormError.is()) + xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this); + + if (m_xLoadable.is()) + m_xLoadable->removeLoadListener(this); + + Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xFormParameter(Source.Source, UNO_QUERY); + if (xFormParameter.is()) + xFormParameter->removeParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::disposingColumnModel(const ::com::sun::star::lang::EventObject& Source) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposingColumnModel" ); + RemoveColumnListener(Reference< XPropertySet > (Source.Source, UNO_QUERY)); +} + +// ------------------------------------------------------------------------- +void SbaXDataBrowserController::disposing(const EventObject& Source) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::disposing" ); + // if it's a component other than our aggregate, forward it to the aggregate + if ( m_xFormControllerImpl != Source.Source ) + { + Reference< XEventListener > xAggListener; + m_xFormControllerImpl->queryAggregation( ::getCppuType( &xAggListener ) ) >>= xAggListener; + if ( xAggListener.is( )) + xAggListener->disposing( Source ); + } + + // is it the grid control ? + if (getBrowserView()) + { + Reference< ::com::sun::star::awt::XControl > xSourceControl(Source.Source, UNO_QUERY); + if (xSourceControl == getBrowserView()->getGridControl()) + disposingGridControl(Source); + } + + // it's model (the container of the columns) ? + if (getControlModel() == Source.Source) + disposingGridModel(Source); + + // the form's model ? + if ((getRowSet() == Source.Source)) + disposingFormModel(Source); + + // from a single column model ? + Reference< XPropertySet > xSourceSet(Source.Source, UNO_QUERY); + if (xSourceSet.is()) + { + Reference< XPropertySetInfo > xInfo = xSourceSet->getPropertySetInfo(); + // we assume that columns have a Width property and all other sets we are listening to don't have + if (xInfo->hasPropertyByName(PROPERTY_WIDTH)) + disposingColumnModel(Source); + } + SbaXDataBrowserController_Base::OGenericUnoController::disposing( Source ); +} + +// ----------------------------------------------------------------------- +void SAL_CALL SbaXDataBrowserController::setIdentifier( const ::rtl::OUString& _Identifier ) throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setIdentifier" ); + ::osl::MutexGuard aGuard( getMutex() ); + m_sModuleIdentifier = _Identifier; +} + +// ----------------------------------------------------------------------- +::rtl::OUString SAL_CALL SbaXDataBrowserController::getIdentifier( ) throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getIdentifier" ); + ::osl::MutexGuard aGuard( getMutex() ); + return m_sModuleIdentifier; +} + +// ----------------------------------------------------------------------- +void SbaXDataBrowserController::propertyChange(const PropertyChangeEvent& evt) throw ( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::propertyChange" ); + Reference< XPropertySet > xSource(evt.Source, UNO_QUERY); + if (!xSource.is()) + return; + + ::vos::OGuard aGuard(Application::GetSolarMutex()); + // the IsModified changed to sal_False ? + if ( (evt.PropertyName.equals(PROPERTY_ISMODIFIED)) + && (::comphelper::getBOOL(evt.NewValue) == sal_False) + ) + { // -> the current field isn't modified anymore, too + setCurrentModified( sal_False ); + } + + // switching to a new record ? + if ( (evt.PropertyName.equals(PROPERTY_ISNEW)) + && (::comphelper::getBOOL(evt.NewValue) == sal_True) + ) + { + if (::comphelper::getINT32(xSource->getPropertyValue(PROPERTY_ROWCOUNT)) == 0) + // if we're switching to a new record and didn't have any records before we need to invalidate + // all slots (as the cursor was invalid before the mode change and so the slots were disabled) + InvalidateAll(); + } + + + // the filter or the sort criterias have changed ? -> update our parser + if (evt.PropertyName.equals(PROPERTY_ACTIVECOMMAND)) + { + // if (m_xParser.is()) + //DO_SAFE( m_xParser->setElementaryQuery(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new query to my parser !" ); + } + else if (evt.PropertyName.equals(PROPERTY_FILTER)) + { + // if ( m_xParser.is() && m_xParser->getFilter() != ::comphelper::getString(evt.NewValue)) + //{ + // DO_SAFE( m_xParser->setFilter(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" ); + //} + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + } + else if (evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE)) + { + //if ( m_xParser.is() && m_xParser->getHavingClause() != ::comphelper::getString(evt.NewValue)) + //{ + // DO_SAFE( m_xParser->setHavingClause(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new filter to my parser !" ); + //} + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + } + else if (evt.PropertyName.equals(PROPERTY_ORDER)) + { + //if ( m_xParser.is() && m_xParser->getOrder() != ::comphelper::getString(evt.NewValue)) + //{ + // DO_SAFE( m_xParser->setOrder(::comphelper::getString(evt.NewValue)), "SbaXDataBrowserController::propertyChange : could not forward the new order to my parser !" ); + //} + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + } + + // a new record count ? -> may be our search availability has changed + if (evt.PropertyName.equals(PROPERTY_ROWCOUNT)) + { + sal_Int32 nNewValue = 0, nOldValue = 0; + evt.NewValue >>= nNewValue; + evt.OldValue >>= nOldValue; + if((nOldValue == 0 && nNewValue != 0) || (nOldValue != 0 && nNewValue == 0)) + InvalidateAll(); + } +} + +//------------------------------------------------------------------------ +void SbaXDataBrowserController::modified(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::modified" ); + setCurrentModified( sal_True ); +} + +// ----------------------------------------------------------------------- +void SbaXDataBrowserController::elementInserted(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementInserted" ); + DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(), + "SbaXDataBrowserController::elementInserted: where did this come from (not from the grid model)?!"); + Reference< XPropertySet > xNewColumn(evt.Element,UNO_QUERY); + if ( xNewColumn.is() ) + AddColumnListener(xNewColumn); +} + +// ----------------------------------------------------------------------- +void SbaXDataBrowserController::elementRemoved(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementRemoved" ); + DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(), + "SbaXDataBrowserController::elementRemoved: where did this come from (not from the grid model)?!"); + Reference< XPropertySet > xOldColumn(evt.Element,UNO_QUERY); + if ( xOldColumn.is() ) + RemoveColumnListener(xOldColumn); +} + +// ----------------------------------------------------------------------- +void SbaXDataBrowserController::elementReplaced(const ::com::sun::star::container::ContainerEvent& evt) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::elementReplaced" ); + DBG_ASSERT(Reference< XInterface >(evt.Source, UNO_QUERY).get() == Reference< XInterface >(getControlModel(), UNO_QUERY).get(), + "SbaXDataBrowserController::elementReplaced: where did this come from (not from the grid model)?!"); + Reference< XPropertySet > xOldColumn(evt.ReplacedElement,UNO_QUERY); + if ( xOldColumn.is() ) + RemoveColumnListener(xOldColumn); + + Reference< XPropertySet > xNewColumn(evt.Element,UNO_QUERY); + if ( xNewColumn.is() ) + AddColumnListener(xNewColumn); +} + +// ----------------------------------------------------------------------- +sal_Bool SbaXDataBrowserController::suspend(sal_Bool /*bSuspend*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::suspend" ); + DBG_ASSERT(m_nPendingLoadFinished == 0, "SbaXDataBrowserController::suspend : there shouldn't be a pending load !"); + + m_aAsyncGetCellFocus.CancelCall(); + m_aAsyncDisplayError.CancelCall(); + m_aAsyncInvalidateAll.CancelCall(); + + sal_Bool bSuccess = SaveModified(); + return bSuccess; +} +// ----------------------------------------------------------------------- +void SbaXDataBrowserController::disposing() +{ + // the base class + SbaXDataBrowserController_Base::OGenericUnoController::disposing(); + + // the data source + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (xFormSet.is()) + { + xFormSet->removePropertyChangeListener(PROPERTY_ISNEW, static_cast<XPropertyChangeListener*>(this)); + xFormSet->removePropertyChangeListener(PROPERTY_ISMODIFIED, static_cast<XPropertyChangeListener*>(this)); + xFormSet->removePropertyChangeListener(PROPERTY_ROWCOUNT, static_cast<XPropertyChangeListener*>(this)); + xFormSet->removePropertyChangeListener(PROPERTY_ACTIVECOMMAND, static_cast<XPropertyChangeListener*>(this)); + xFormSet->removePropertyChangeListener(PROPERTY_ORDER, static_cast<XPropertyChangeListener*>(this)); + xFormSet->removePropertyChangeListener(PROPERTY_FILTER, static_cast<XPropertyChangeListener*>(this)); + xFormSet->removePropertyChangeListener(PROPERTY_HAVING_CLAUSE, static_cast<XPropertyChangeListener*>(this)); + xFormSet->removePropertyChangeListener(PROPERTY_APPLYFILTER, static_cast<XPropertyChangeListener*>(this)); + } + + Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY); + if (xFormError.is()) + xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this); + + if (m_xLoadable.is()) + m_xLoadable->removeLoadListener(this); + + Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xFormParameter(getRowSet(), UNO_QUERY); + if (xFormParameter.is()) + xFormParameter->removeParameterListener((::com::sun::star::form::XDatabaseParameterListener*)this); + + removeModelListeners(getControlModel()); + + if ( getView() && m_pClipbordNotifier ) + { + m_pClipbordNotifier->ClearCallbackLink(); + m_pClipbordNotifier->AddRemoveListener( getView(), sal_False ); + m_pClipbordNotifier->release(); + m_pClipbordNotifier = NULL; + } + + if (getBrowserView()) + { + removeControlListeners(getBrowserView()->getGridControl()); + // don't delete explicitly, this is done by the owner (and user) of this controller (me hopes ...) + clearView(); + } + + if(m_aInvalidateClipboard.IsActive()) + m_aInvalidateClipboard.Stop(); + + // dispose the row set + try + { + ::comphelper::disposeComponent(m_xRowSet); + + m_xRowSet = NULL; + m_xColumnsSupplier = NULL; + m_xLoadable = NULL; + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + m_xParser.clear(); + // don't dispose, just reset - it's owned by the RowSet +} +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::frameAction" ); + ::osl::MutexGuard aGuard( getMutex() ); + + SbaXDataBrowserController_Base::frameAction( aEvent ); + + if ( aEvent.Source == getFrame() ) + switch ( aEvent.Action ) + { + case FrameAction_FRAME_ACTIVATED: + case FrameAction_FRAME_UI_ACTIVATED: + // ensure that the active cell (if any) has the focus + m_aAsyncGetCellFocus.Call(); + // start the clipboard timer + if (getBrowserView() && getBrowserView()->getVclControl() && !m_aInvalidateClipboard.IsActive()) + { + m_aInvalidateClipboard.Start(); + OnInvalidateClipboard( NULL ); + } + break; + case FrameAction_FRAME_DEACTIVATING: + case FrameAction_FRAME_UI_DEACTIVATING: + // stop the clipboard invalidator + if (getBrowserView() && getBrowserView()->getVclControl() && m_aInvalidateClipboard.IsActive()) + { + m_aInvalidateClipboard.Stop(); + OnInvalidateClipboard( NULL ); + } + // remove the "get cell focus"-event + m_aAsyncGetCellFocus.CancelCall(); + break; + default: + break; + } +} + +//------------------------------------------------------------------------------ +IMPL_LINK( SbaXDataBrowserController, OnAsyncDisplayError, void*, /* _pNotInterestedIn */ ) +{ + if ( m_aCurrentError.isValid() ) + { + OSQLMessageBox aDlg( getBrowserView(), m_aCurrentError ); + aDlg.Execute(); + } + return 0L; +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::errorOccured(const ::com::sun::star::sdb::SQLErrorEvent& aEvent) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::errorOccured" ); + ::osl::MutexGuard aGuard( getMutex() ); + + SQLExceptionInfo aInfo( aEvent.Reason ); + if ( !aInfo.isValid() ) + return; + + if ( m_nFormActionNestingLevel ) + { + OSL_ENSURE( !m_aCurrentError.isValid(), "SbaXDataBrowserController::errorOccured: can handle one error per transaction only!" ); + m_aCurrentError = aInfo; + } + else + { + m_aCurrentError = aInfo; + m_aAsyncDisplayError.Call(); + } +} + +//------------------------------------------------------------------------------ +sal_Bool SbaXDataBrowserController::approveParameter(const ::com::sun::star::form::DatabaseParameterEvent& aEvent) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::approveParameter" ); + if (aEvent.Source != getRowSet()) + { + // not my data source -> allow anything + DBG_ERROR("SbaXDataBrowserController::approveParameter : invalid event source !"); + return sal_True; + } + + Reference< ::com::sun::star::container::XIndexAccess > xParameters = aEvent.Parameters; + ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); + // this may be executed in a non-main thread and we want to use vcl ... + Window* pParent = Application::GetDefDialogParent(); + // don't use the content as parent if it isn't visible + // (and don't use NULL as parent : this may be displayed in the beamer and really shouldn't be task-local) + // 69297 - FS - 25.10.99 + if (getBrowserView() && getBrowserView()->IsVisible()) + pParent = getBrowserView(); + + // default handling: instantiate an interaction handler and let it handle the parameter request + try + { + // two continuations allowed: OK and Cancel + OParameterContinuation* pParamValues = new OParameterContinuation; + OInteractionAbort* pAbort = new OInteractionAbort; + // the request + ParametersRequest aRequest; + aRequest.Parameters = xParameters; + aRequest.Connection = getConnection(Reference< XRowSet >(aEvent.Source, UNO_QUERY)); + OInteractionRequest* pParamRequest = new OInteractionRequest(makeAny(aRequest)); + Reference< XInteractionRequest > xParamRequest(pParamRequest); + // some knittings + pParamRequest->addContinuation(pParamValues); + pParamRequest->addContinuation(pAbort); + + // create the handler, let it handle the request + Reference< XInteractionHandler > xHandler(getORB()->createInstance(SERVICE_TASK_INTERACTION_HANDLER), UNO_QUERY); + if (xHandler.is()) + xHandler->handle(xParamRequest); + + if (!pParamValues->wasSelected()) + { // canceled + setLoadingCancelled(); + return sal_False; + } + + // transfer the values into the parameter supplier + Sequence< PropertyValue > aFinalValues = pParamValues->getValues(); + if (aFinalValues.getLength() != aRequest.Parameters->getCount()) + { + DBG_ERROR("SbaXDataBrowserController::approveParameter: the InteractionHandler returned nonsense!"); + setLoadingCancelled(); + return sal_False; + } + const PropertyValue* pFinalValues = aFinalValues.getConstArray(); + for (sal_Int32 i=0; i<aFinalValues.getLength(); ++i, ++pFinalValues) + { + Reference< XPropertySet > xParam; + ::cppu::extractInterface(xParam, aRequest.Parameters->getByIndex(i)); + DBG_ASSERT(xParam.is(), "SbaXDataBrowserController::approveParameter: one of the parameters is no property set!"); + if (xParam.is()) + { +#ifdef DBG_UTIL + ::rtl::OUString sName; + xParam->getPropertyValue(PROPERTY_NAME) >>= sName; + DBG_ASSERT(sName.equals(pFinalValues->Name), "SbaXDataBrowserController::approveParameter: suspicious value names!"); +#endif + try { xParam->setPropertyValue(PROPERTY_VALUE, pFinalValues->Value); } + catch(Exception&) + { + DBG_ERROR("SbaXDataBrowserController::approveParameter: setting one of the properties failed!"); + } + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return sal_True; +} + + +//------------------------------------------------------------------------------ +sal_Bool SbaXDataBrowserController::approveReset(const ::com::sun::star::lang::EventObject& /*rEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::approveReset" ); + return sal_True; +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::resetted(const ::com::sun::star::lang::EventObject& rEvent) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::resetted" ); + DBG_ASSERT(rEvent.Source == getControlModel(), "SbaXDataBrowserController::resetted : where did this come from ?"); + (void)rEvent; + setCurrentModified( sal_False ); +} + +//------------------------------------------------------------------------------ +sal_Bool SbaXDataBrowserController::confirmDelete(const ::com::sun::star::sdb::RowChangeEvent& /*aEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::confirmDelete" ); + if (QueryBox(getBrowserView(), ModuleRes(QUERY_BRW_DELETE_ROWS)).Execute() != RET_YES) + return sal_False; + + return sal_True; +} +//------------------------------------------------------------------------------ +FeatureState SbaXDataBrowserController::GetState(sal_uInt16 nId) const +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::GetState" ); + FeatureState aReturn; + // (disabled automatically) + + try + { + // no chance without a view + if (!getBrowserView() || !getBrowserView()->getVclControl()) + return aReturn; + + switch (nId) + { + case ID_BROWSER_REMOVEFILTER: + if (!m_xParser.is()) + { + aReturn.bEnabled = false; + return aReturn; + } + // any filter or sort order set ? + aReturn.bEnabled = m_xParser->getFilter().getLength() || m_xParser->getHavingClause().getLength() || m_xParser->getOrder().getLength(); + return aReturn; + } + // no chance without valid models + if (isValid() && !isValidCursor()) + return aReturn; + + switch (nId) + { + case ID_BROWSER_SEARCH: + { + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + sal_Int32 nCount = ::comphelper::getINT32(xFormSet->getPropertyValue(PROPERTY_ROWCOUNT)); + aReturn.bEnabled = nCount != 0; + } + break; + case ID_BROWSER_INSERT_ROW: + { + // check if it is available + sal_Bool bInsertPrivilege = ( m_nRowSetPrivileges & Privilege::INSERT) != 0; + sal_Bool bAllowInsertions = sal_True; + try + { + Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW ); + OSL_VERIFY( xRowSetProps->getPropertyValue( ::rtl::OUString::createFromAscii( "AllowInserts" ) ) >>= bAllowInsertions ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + aReturn.bEnabled = bInsertPrivilege && bAllowInsertions; + } + break; + case SID_FM_DELETEROWS: + { + // check if it is available + sal_Bool bDeletePrivilege = ( m_nRowSetPrivileges & Privilege::INSERT) != 0; + sal_Bool bAllowDeletions = sal_True; + sal_Int32 nRowCount = 0; + sal_Bool bInsertionRow = sal_False; + try + { + Reference< XPropertySet > xRowSetProps( getRowSet(), UNO_QUERY_THROW ); + OSL_VERIFY( xRowSetProps->getPropertyValue( ::rtl::OUString::createFromAscii( "AllowDeletes" ) ) >>= bAllowDeletions ); + OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ROWCOUNT ) >>= nRowCount ); + OSL_VERIFY( xRowSetProps->getPropertyValue( PROPERTY_ISNEW ) >>= bInsertionRow ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + aReturn.bEnabled = bDeletePrivilege && bAllowDeletions && ( nRowCount != 0 ) && !bInsertionRow; + } + break; + + case ID_BROWSER_COPY: + if ( getBrowserView()->getVclControl()->GetSelectRowCount() ) + { + aReturn.bEnabled = m_aCurrentFrame.isActive(); + break; + } + // run through + case ID_BROWSER_PASTE: + case ID_BROWSER_CUT: + { + CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller(); + if (xCurrentController.Is() && xCurrentController->ISA(EditCellController)) + { + Edit& rEdit = (Edit&)xCurrentController->GetWindow(); + sal_Bool bHasLen = (rEdit.GetSelection().Len() != 0); + sal_Bool bIsReadOnly = rEdit.IsReadOnly(); + switch (nId) + { + case ID_BROWSER_CUT: aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen && !bIsReadOnly; break; + case SID_COPY : aReturn.bEnabled = m_aCurrentFrame.isActive() && bHasLen; break; + case ID_BROWSER_PASTE: + aReturn.bEnabled = m_aCurrentFrame.isActive() && !bIsReadOnly; + if(aReturn.bEnabled) + { + aReturn.bEnabled = aReturn.bEnabled && IsFormatSupported( m_aSystemClipboard.GetDataFlavorExVector(), FORMAT_STRING ); + } + break; + } + } + } + break; + + case ID_BROWSER_SORTUP: + case ID_BROWSER_SORTDOWN: + case ID_BROWSER_AUTOFILTER: + { + // a native statement can't be filtered or sorted + const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || !m_xParser.is() ) + break; + + Reference< XPropertySet > xCurrentField = getBoundField(); + if (!xCurrentField.is()) + break; + + aReturn.bEnabled = ::comphelper::getBOOL(xCurrentField->getPropertyValue(PROPERTY_ISSEARCHABLE)); + const Reference< XRowSet > xRow = getRowSet(); + aReturn.bEnabled = aReturn.bEnabled + && xRow.is() + && !xRow->isBeforeFirst() + && !xRow->isAfterLast() + && !xRow->rowDeleted() + && ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 ); + } + break; + + case ID_BROWSER_FILTERCRIT: + if ( m_bCannotSelectUnfiltered && m_xParser.is() ) + { + aReturn.bEnabled = sal_True; + break; + } + // no break + case ID_BROWSER_ORDERCRIT: + { + const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if ( !::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || !m_xParser.is() ) + break; + + aReturn.bEnabled = getRowSet().is() + && ( ::comphelper::getINT32( xFormSet->getPropertyValue( PROPERTY_ROWCOUNT ) ) != 0 ); + } + break; + + case ID_BROWSER_REFRESH: + aReturn.bEnabled = sal_True; + break; + + case ID_BROWSER_REDO: + aReturn.bEnabled = sal_False; // simply forget it ;). no redo possible. + break; + + case ID_BROWSER_UNDORECORD: + case ID_BROWSER_SAVERECORD: + { + if (!m_bCurrentlyModified) + { + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (xFormSet.is()) + aReturn.bEnabled = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED)); + } + else + aReturn.bEnabled = sal_True; + + aReturn.sTitle = (ID_BROWSER_UNDORECORD == nId) ? m_sStateUndoRecord : m_sStateSaveRecord; + } + break; + case ID_BROWSER_EDITDOC: + { + // check if it is available + Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY); + if (!xDataSourceSet.is()) + break; // no datasource -> no edit mode + + sal_Int32 nDataSourcePrivileges = ::comphelper::getINT32(xDataSourceSet->getPropertyValue(PROPERTY_PRIVILEGES)); + sal_Bool bInsertAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::INSERT) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowInserts"))); + sal_Bool bUpdateAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::UPDATE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowUpdates"))); + sal_Bool bDeleteAllowedAndPossible = ((nDataSourcePrivileges & ::com::sun::star::sdbcx::Privilege::DELETE) != 0) && ::comphelper::getBOOL(xDataSourceSet->getPropertyValue(::rtl::OUString::createFromAscii("AllowDeletes"))); + if (!bInsertAllowedAndPossible && !bUpdateAllowedAndPossible && !bDeleteAllowedAndPossible) + break; // no insert/update/delete -> no edit mode + + if (!isValidCursor() || !isLoaded()) + break; // no cursor -> no edit mode + + aReturn.bEnabled = sal_True; + + sal_Int16 nGridMode = getBrowserView()->getVclControl()->GetOptions(); + aReturn.bChecked = nGridMode > DbGridControl::OPT_READONLY; + } + break; + case ID_BROWSER_FILTERED: + { + aReturn.bEnabled = sal_False; + Reference< XPropertySet > xActiveSet(getRowSet(), UNO_QUERY); + ::rtl::OUString aFilter = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_FILTER)); + ::rtl::OUString aHaving = ::comphelper::getString(xActiveSet->getPropertyValue(PROPERTY_HAVING_CLAUSE)); + if ( aFilter.getLength() || aHaving.getLength() ) + { + xActiveSet->getPropertyValue( PROPERTY_APPLYFILTER ) >>= aReturn.bChecked; + aReturn.bEnabled = sal_True; + } + else + { + aReturn.bChecked = sal_False; + aReturn.bEnabled = sal_False; + } + } + break; + default: + return SbaXDataBrowserController_Base::GetState(nId); + } + } + catch(const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return aReturn; +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::applyParserOrder(const ::rtl::OUString& _rOldOrder,const Reference< XSingleSelectQueryComposer >& _xParser) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserOrder" ); + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (!m_xLoadable.is()) + { + OSL_ENSURE(sal_False, "SbaXDataBrowserController::applyParserOrder: invalid row set!"); + return; + } + + sal_uInt16 nPos = getCurrentColumnPosition(); + sal_Bool bSuccess = sal_False; + try + { + xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_xParser->getOrder())); + bSuccess = reloadForm(m_xLoadable); + } + catch(Exception&) + { + } + + if (!bSuccess) + { + xFormSet->setPropertyValue(PROPERTY_ORDER, makeAny(_rOldOrder)); + //DO_SAFE( _xParser->setOrder(_rOldOrder), "SbaXDataBrowserController::applyParserOrder: could not restore the old order of my parser !" ); + + try + { + if (loadingCancelled() || !reloadForm(m_xLoadable)) + criticalFail(); + } + catch(Exception&) + { + criticalFail(); + } + InvalidateAll(); + } + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + + setCurrentColumnPosition(nPos); +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::applyParserFilter(const ::rtl::OUString& _rOldFilter, sal_Bool _bOldFilterApplied,const ::rtl::OUString& _sOldHaving,const Reference< XSingleSelectQueryComposer >& _xParser) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::applyParserFilter" ); + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (!m_xLoadable.is()) + { + OSL_ENSURE(sal_False, "SbaXDataBrowserController::applyParserFilter: invalid row set!"); + return; + } + + sal_uInt16 nPos = getCurrentColumnPosition(); + + sal_Bool bSuccess = sal_False; + try + { + FormErrorHelper aError(this); + xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_xParser->getFilter())); + xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_xParser->getHavingClause())); + xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(sal_Bool(sal_True))); + + bSuccess = reloadForm(m_xLoadable); + } + catch(Exception&) + { + } + + if (!bSuccess) + { + xFormSet->setPropertyValue(PROPERTY_FILTER, makeAny(_rOldFilter)); + xFormSet->setPropertyValue(PROPERTY_HAVING_CLAUSE, makeAny(_sOldHaving)); + xFormSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(_bOldFilterApplied)); + + try + { + if (loadingCancelled() || !reloadForm(m_xLoadable)) + criticalFail(); + } + catch(Exception&) + { + criticalFail(); + } + InvalidateAll(); + } + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + + setCurrentColumnPosition(nPos); +} +//------------------------------------------------------------------------------ +Reference< XSingleSelectQueryComposer > SbaXDataBrowserController::createParser_nothrow() +{ + Reference< XSingleSelectQueryComposer > xRet; + try + { + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY_THROW); + const Reference<XMultiServiceFactory> xFactory(::dbtools::getConnection(getRowSet()),UNO_QUERY_THROW); + xRet.set(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY_THROW); + xRet->setElementaryQuery(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ACTIVECOMMAND))); + xRet->setFilter(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_FILTER))); + xRet->setHavingClause(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_HAVING_CLAUSE))); + xRet->setOrder(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ORDER))); + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + return xRet; +} +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::ExecuteFilterSortCrit(sal_Bool bFilter) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ExecuteFilterSortCrit" ); + if (!SaveModified()) + return; + + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + + const ::rtl::OUString sOldVal = bFilter ? m_xParser->getFilter() : m_xParser->getOrder(); + const ::rtl::OUString sOldHaving = m_xParser->getHavingClause(); + Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow(); + try + { + Reference< ::com::sun::star::sdbcx::XColumnsSupplier> xSup = getColumnsSupplier(); + Reference< XConnection> xCon(xFormSet->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY); + if(bFilter) + { + DlgFilterCrit aDlg( getBrowserView(), getORB(), xCon, xParser, xSup->getColumns() ); + String aFilter; + if(!aDlg.Execute()) + { + //m_xParser->setFilter(sOldVal); + //m_xParser->setHavingClause(sOldHaving); + return; // if so we don't need to actualize the grid + } + aDlg.BuildWherePart(); + } + else + { + DlgOrderCrit aDlg( getBrowserView(),xCon,xParser,xSup->getColumns() ); + String aOrder; + if(!aDlg.Execute()) + { + //m_xParser->setOrder(sOldVal); + return; // if so we don't need to actualize the grid + } + aDlg.BuildOrderPart(); + } + } + catch(const SQLException& ) + { + SQLExceptionInfo aError( ::cppu::getCaughtException() ); + showError( aError ); + return; + } + catch(Exception&) + { + return; + } + + ::rtl::OUString sNewVal = bFilter ? xParser->getFilter() : xParser->getOrder(); + sal_Bool bOldFilterApplied(sal_False); + if (bFilter) + { + try { bOldFilterApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER)); } catch(Exception&) { } ; + } + + ::rtl::OUString sNewHaving = xParser->getHavingClause(); + if ( sOldVal.equals(sNewVal) && (!bFilter || sOldHaving.equals(sNewHaving)) ) + // nothing to be done + return; + + if (bFilter) + applyParserFilter(sOldVal, bOldFilterApplied,sOldHaving,xParser); + else + applyParserOrder(sOldVal,xParser); + + ::comphelper::disposeComponent(xParser); +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::ExecuteSearch() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ExecuteSearch" ); + // calculate the control source of the active field + Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY); + DBG_ASSERT(xGrid.is(), "SbaXDataBrowserController::ExecuteSearch : the control should have an ::com::sun::star::form::XGrid interface !"); + + Reference< ::com::sun::star::form::XGridPeer > xGridPeer(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY); + Reference< ::com::sun::star::container::XIndexContainer > xColumns = xGridPeer->getColumns(); + DBG_ASSERT(xGridPeer.is() && xColumns.is(), "SbaXDataBrowserController::ExecuteSearch : invalid peer !"); + + sal_Int16 nViewCol = xGrid->getCurrentColumnPosition(); + sal_Int16 nModelCol = getBrowserView()->View2ModelPos(nViewCol); + + Reference< XPropertySet > xCurrentCol(xColumns->getByIndex(nModelCol),UNO_QUERY); + String sActiveField = ::comphelper::getString(xCurrentCol->getPropertyValue(PROPERTY_CONTROLSOURCE)); + + // the text within the current cell + String sInitialText; + Reference< ::com::sun::star::container::XIndexAccess > xColControls(xGridPeer, UNO_QUERY); + Reference< XInterface > xCurControl(xColControls->getByIndex(nViewCol),UNO_QUERY); + ::rtl::OUString aInitialText; + if (IsSearchableControl(xCurControl, &aInitialText)) + sInitialText = (const sal_Unicode*)aInitialText; + + // prohibit the synchronization of the grid's display with the cursor's position + Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY); + DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::ExecuteSearch : no model set ?!"); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_False))); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("AlwaysShowCursor"), ::comphelper::makeBoolAny(sal_Bool(sal_True))); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("CursorColor"), makeAny(sal_Int32(COL_LIGHTRED))); + + Reference< ::com::sun::star::util::XNumberFormatsSupplier > xNFS(::dbtools::getNumberFormats(::dbtools::getConnection(m_xRowSet), sal_True,getORB())); + + SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); + AbstractFmSearchDialog* pDialog = NULL; + if ( pFact ) + { + ::std::vector< String > aContextNames; + aContextNames.push_back( String::CreateFromAscii("Standard") ); + pDialog = pFact->CreateFmSearchDialog(getBrowserView(), sInitialText, aContextNames, 0, LINK(this, SbaXDataBrowserController, OnSearchContextRequest)); + } + DBG_ASSERT( pDialog, "SbaXDataBrowserController::ExecuteSearch: could not get the search dialog!" ); + if ( pDialog ) + { + pDialog->SetActiveField( sActiveField ); + pDialog->SetFoundHandler( LINK( this, SbaXDataBrowserController, OnFoundData ) ); + pDialog->SetCanceledNotFoundHdl( LINK( this, SbaXDataBrowserController, OnCanceledNotFound ) ); + pDialog->Execute(); + delete pDialog; + } + + // restore the grid's normal operating state + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True))); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("AlwaysShowCursor"), ::comphelper::makeBoolAny(sal_Bool(sal_False))); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("CursorColor"), Any()); +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& _rArgs) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::Execute" ); + sal_Bool bSortUp = sal_True; + + switch (nId) + { + default: + SbaXDataBrowserController_Base::Execute( nId, _rArgs ); + return; + + case ID_BROWSER_INSERT_ROW: + try + { + if (SaveModified()) + { + getRowSet()->afterLast(); + // check if it is available + Reference< XResultSetUpdate > xUpdateCursor(getRowSet(), UNO_QUERY_THROW); + xUpdateCursor->moveToInsertRow(); + } + } + catch(Exception&) + { + OSL_ENSURE(0,"Exception caught!"); + } + break; + case SID_FM_DELETEROWS: + + if (SaveModified()) + { + SbaGridControl* pVclGrid = getBrowserView()->getVclControl(); + if ( pVclGrid ) + { + if( !pVclGrid->GetSelectRowCount() ) + { + pVclGrid->DeactivateCell(); + pVclGrid->SelectRow(pVclGrid->GetCurRow()); + } + pVclGrid->DeleteSelectedRows(); + } + } + break; + + case ID_BROWSER_FILTERED: + if (SaveModified()) + { + Reference< XPropertySet > xActiveSet(getRowSet(), UNO_QUERY); + sal_Bool bApplied = ::comphelper::getBOOL(xActiveSet->getPropertyValue(PROPERTY_APPLYFILTER)); + xActiveSet->setPropertyValue(PROPERTY_APPLYFILTER, ::comphelper::makeBoolAny(sal_Bool(!bApplied))); + reloadForm(m_xLoadable); + } + InvalidateFeature(ID_BROWSER_FILTERED); + break; + case ID_BROWSER_EDITDOC: + { + sal_Int16 nGridMode = getBrowserView()->getVclControl()->GetOptions(); + if (nGridMode == DbGridControl::OPT_READONLY) + getBrowserView()->getVclControl()->SetOptions(DbGridControl::OPT_UPDATE | DbGridControl::OPT_INSERT | DbGridControl::OPT_DELETE); + // the options not supported by the data source will be removed automatically + else + { + if ( !SaveModified( ) ) + // give the user a chance to save the current record (if neccessary) + break; + + // maybe the user wanted to reject the modified record ? + if (GetState(ID_BROWSER_UNDORECORD).bEnabled) + Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>()); + + getBrowserView()->getVclControl()->SetOptions(DbGridControl::OPT_READONLY); + } + InvalidateFeature(ID_BROWSER_EDITDOC); + } + break; + + case ID_BROWSER_SEARCH: + if ( SaveModified( ) ) + ExecuteSearch(); + break; + + case ID_BROWSER_COPY: + if ( getBrowserView()->getVclControl()->GetSelectRowCount() > 0 ) + { + getBrowserView()->getVclControl()->CopySelectedRowsToClipboard(); + break; + } + // run through + case ID_BROWSER_CUT: + case ID_BROWSER_PASTE: + { + CellControllerRef xCurrentController = getBrowserView()->getVclControl()->Controller(); + if (!xCurrentController.Is()) + // should be intercepted by GetState. Normally. + // Unfortunately ID_BROWSER_PASTE is a 'fast call' slot, which means it may be executed without checking if it is + // enabled. This would be really deadly herein if the current cell has no controller ... + // (FS - 13.04.99 - #64694#) + return; + + Edit& rEdit = (Edit&)xCurrentController->GetWindow(); + switch (nId) + { + case ID_BROWSER_CUT : rEdit.Cut(); break; + case SID_COPY : rEdit.Copy(); break; + case ID_BROWSER_PASTE : rEdit.Paste(); break; + } + if (ID_BROWSER_CUT == nId || ID_BROWSER_PASTE == nId) + { + xCurrentController->SetModified(); + rEdit.Modify(); + } + } + break; + + case ID_BROWSER_SORTDOWN: + bSortUp = sal_False; + // DON'T break + case ID_BROWSER_SORTUP: + { + if (!SaveModified()) + break; + + if (!isValidCursor()) + break; + + // only one sort order + Reference< XPropertySet > xField(getBoundField(), UNO_QUERY); + if (!xField.is()) + break; + + Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow(); + const ::rtl::OUString sOldSort = xParser->getOrder(); + sal_Bool bParserSuccess = sal_False; + HANDLE_SQL_ERRORS( + xParser->setOrder(::rtl::OUString()); xParser->appendOrderByColumn(xField, bSortUp), + bParserSuccess, + UniString(ModuleRes(SBA_BROWSER_SETTING_ORDER)), + "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !" + ) + + if (bParserSuccess) + applyParserOrder(sOldSort,xParser); + } + break; + + case ID_BROWSER_AUTOFILTER: + { + if (!SaveModified()) + break; + + if (!isValidCursor()) + break; + + Reference< XPropertySet > xField(getBoundField(), UNO_QUERY); + if (!xField.is()) + break; + + // check if the column is a aggregate function + sal_Bool bHaving = sal_False; + ::rtl::OUString sName; + xField->getPropertyValue(PROPERTY_NAME) >>= sName; + Reference< XColumnsSupplier > xColumnsSupplier(m_xParser, UNO_QUERY); + Reference< ::com::sun::star::container::XNameAccess > xCols = xColumnsSupplier.is() ? xColumnsSupplier->getColumns() : Reference< ::com::sun::star::container::XNameAccess > (); + if ( xCols.is() && xCols->hasByName(sName) ) + { + Reference<XPropertySet> xProp(xCols->getByName(sName),UNO_QUERY); + static ::rtl::OUString sAgg(RTL_CONSTASCII_USTRINGPARAM("AggregateFunction")); + if ( xProp->getPropertySetInfo()->hasPropertyByName(sAgg) ) + xProp->getPropertyValue(sAgg) >>= bHaving; + } + + Reference< XSingleSelectQueryComposer > xParser = createParser_nothrow(); + const ::rtl::OUString sOldFilter = xParser->getFilter(); + const ::rtl::OUString sOldHaving = xParser->getHavingClause(); + + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + sal_Bool bApplied = ::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_APPLYFILTER)); + // do we have a filter but it's not applied ? + // -> completely overwrite it, else append one + if (!bApplied) + { + DO_SAFE( (bHaving ? xParser->setHavingClause(::rtl::OUString()) : xParser->setFilter(::rtl::OUString())), "SbaXDataBrowserController::Execute : caught an exception while resetting the new filter !" ); + } + + sal_Bool bParserSuccess = sal_False; + + sal_Int32 nOp = SQLFilterOperator::EQUAL; + if ( xField.is() ) + { + sal_Int32 nType = 0; + xField->getPropertyValue(PROPERTY_TYPE) >>= nType; + switch(nType) + { + case DataType::VARCHAR: + case DataType::CHAR: + case DataType::LONGVARCHAR: + nOp = SQLFilterOperator::LIKE; + break; + default: + nOp = SQLFilterOperator::EQUAL; + } + } + + if ( bHaving ) + { + HANDLE_SQL_ERRORS( + xParser->appendHavingClauseByColumn(xField,sal_True,nOp), + bParserSuccess, + UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)), + "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !" + ) + } + else + { + HANDLE_SQL_ERRORS( + xParser->appendFilterByColumn(xField,sal_True,nOp), + bParserSuccess, + UniString(ModuleRes(SBA_BROWSER_SETTING_FILTER)), + "SbaXDataBrowserController::Execute : caught an exception while composing the new filter !" + ) + } + + if (bParserSuccess) + applyParserFilter(sOldFilter, bApplied,sOldHaving,xParser); + + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + InvalidateFeature(ID_BROWSER_FILTERED); + } + break; + + case ID_BROWSER_ORDERCRIT: + ExecuteFilterSortCrit(sal_False); + break; + + case ID_BROWSER_FILTERCRIT: + ExecuteFilterSortCrit(sal_True); + InvalidateFeature(ID_BROWSER_FILTERED); + break; + + case ID_BROWSER_REMOVEFILTER: + { + if (!SaveModified()) + break; + + sal_Bool bNeedPostReload = preReloadForm(); + // reset the filter and the sort property simutaneously so only _one_ new statement has to be + // sent + Reference< XPropertySet > xSet(getRowSet(), UNO_QUERY); + if ( xSet.is() ) + { + xSet->setPropertyValue(PROPERTY_FILTER,makeAny(::rtl::OUString())); + xSet->setPropertyValue(PROPERTY_HAVING_CLAUSE,makeAny(::rtl::OUString())); + xSet->setPropertyValue(PROPERTY_ORDER,makeAny(::rtl::OUString())); + } + try + { + reloadForm(m_xLoadable); + if ( bNeedPostReload ) + postReloadForm(); + } + catch(Exception&) + { + } + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + InvalidateFeature(ID_BROWSER_FILTERED); + } + break; + + case ID_BROWSER_REFRESH: + if ( SaveModified( ) ) + { + if (!reloadForm(m_xLoadable)) + criticalFail(); + } + break; + + case ID_BROWSER_SAVERECORD: + if ( SaveModified( sal_False ) ) + setCurrentModified( sal_False ); + break; + + case ID_BROWSER_UNDORECORD: + { + try + { + // restore the cursor state + Reference< XResultSetUpdate > xCursor(getRowSet(), UNO_QUERY); + Reference< XPropertySet > xSet(xCursor, UNO_QUERY); + Any aVal = xSet->getPropertyValue(PROPERTY_ISNEW); + if (aVal.hasValue() && ::comphelper::getBOOL(aVal)) + { + xCursor->moveToInsertRow(); + // no need to reset the grid model after we moved to the insert row, this is done implicitly by the + // form + // (and in some cases it may be deadly to do the reset explicitly after the form did it implicitly, + // cause the form's reset may be async, and this leads to some nice deadlock scenarios ....) + } + else + { + xCursor->cancelRowUpdates(); + + // restore the grids state + Reference< ::com::sun::star::form::XReset > xReset(getControlModel(), UNO_QUERY); + if (xReset.is()) + xReset->reset(); + } + } + catch(SQLException&) + { + } + + setCurrentModified( sal_False ); + } + } +} + +//------------------------------------------------------------------------------ +sal_Bool SbaXDataBrowserController::SaveModified(sal_Bool bAskFor) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SaveModified" ); + if ( bAskFor && GetState(ID_BROWSER_SAVERECORD).bEnabled ) + { + getBrowserView()->getVclControl()->GrabFocus(); + + QueryBox aQry(getBrowserView()->getVclControl(), ModuleRes(QUERY_BRW_SAVEMODIFIED)); + + switch (aQry.Execute()) + { + case RET_NO: + Execute(ID_BROWSER_UNDORECORD,Sequence<PropertyValue>()); + return sal_True; + case RET_CANCEL: + return sal_False; + } + } + + if ( !CommitCurrent() ) // das aktuelle Control committen lassen + return sal_False; + + Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + sal_Bool bResult = sal_False; + try + { + if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISMODIFIED))) + { + Reference< XResultSetUpdate > xCursor(getRowSet(), UNO_QUERY); + if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ISNEW))) + xCursor->insertRow(); + else + xCursor->updateRow(); + } + bResult = sal_True; + } + catch(SQLException&) + { + } + catch(Exception&) + { + DBG_ERROR("SbaXDataBrowserController::SaveModified : could not save the current record !"); + bResult = sal_False; + } + + InvalidateFeature(ID_BROWSER_SAVERECORD); + InvalidateFeature(ID_BROWSER_UNDORECORD); + return bResult; +} + +//------------------------------------------------------------------------------ +sal_Bool SbaXDataBrowserController::CommitCurrent() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CommitCurrent" ); + if (!getBrowserView()) + return sal_True; + + Reference< ::com::sun::star::awt::XControl > xActiveControl(getBrowserView()->getGridControl()); + Reference< ::com::sun::star::form::XBoundControl > xLockingTest(xActiveControl, UNO_QUERY); + sal_Bool bControlIsLocked = xLockingTest.is() && xLockingTest->getLock(); + if (xActiveControl.is() && !bControlIsLocked) + { + // zunaechst das Control fragen ob es das IFace unterstuetzt + Reference< ::com::sun::star::form::XBoundComponent > xBoundControl(xActiveControl, UNO_QUERY); + if (!xBoundControl.is()) + xBoundControl = Reference< ::com::sun::star::form::XBoundComponent > (xActiveControl->getModel(), UNO_QUERY); + if (xBoundControl.is() && !xBoundControl->commit()) + return sal_False; + } + return sal_True; +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::setCurrentModified( sal_Bool _bSet ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setCurrentModified" ); + m_bCurrentlyModified = _bSet; + InvalidateFeature( ID_BROWSER_SAVERECORD ); + InvalidateFeature( ID_BROWSER_UNDORECORD ); +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::RowChanged() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::RowChanged" ); + setCurrentModified( sal_False ); +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::ColumnChanged() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::ColumnChanged" ); + InvalidateFeature(ID_BROWSER_SORTUP); + InvalidateFeature(ID_BROWSER_SORTDOWN); + InvalidateFeature(ID_BROWSER_ORDERCRIT); + InvalidateFeature(ID_BROWSER_FILTERCRIT); + InvalidateFeature(ID_BROWSER_AUTOFILTER); + InvalidateFeature(ID_BROWSER_REMOVEFILTER); + + setCurrentModified( sal_False ); +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::SelectionChanged() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SelectionChanged" ); + // not interested in +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::CellActivated() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CellActivated" ); + m_aInvalidateClipboard.Start(); + OnInvalidateClipboard( NULL ); +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::CellDeactivated() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::CellDeactivated" ); + m_aInvalidateClipboard.Stop(); + OnInvalidateClipboard( NULL ); +} + +//------------------------------------------------------------------------------ +IMPL_LINK( SbaXDataBrowserController, OnClipboardChanged, void*, EMPTYARG ) +{ + ::vos::OGuard aGuard(Application::GetSolarMutex()); + return OnInvalidateClipboard( NULL ); +} + +//------------------------------------------------------------------------------ +IMPL_LINK(SbaXDataBrowserController, OnInvalidateClipboard, AutoTimer*, _pTimer) +{ + InvalidateFeature(ID_BROWSER_CUT); + InvalidateFeature(ID_BROWSER_COPY); + + // if the invalidation was triggered by the timer, we do not need to invalidate PASTE. + // The timer is only for checking the CUT/COPY slots regulariry, which depend on the + // selection state of the active cell + // TODO: get a callback at the Edit which allows to be notified when the selection + // changes. This would be much better than this cycle-eating polling mechanism here .... + if ( _pTimer != &m_aInvalidateClipboard ) + InvalidateFeature(ID_BROWSER_PASTE); + + return 0L; +} + +// ------------------------------------------------------------------------- +Reference< XPropertySet > SbaXDataBrowserController::getBoundField(sal_uInt16 nViewPos) const +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::SaveData" ); + Reference< XPropertySet > xEmptyReturn; + + // get the current column from the grid + if (nViewPos == (sal_uInt16)-1) + { + Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY); + if (!xGrid.is()) + return xEmptyReturn; + nViewPos = xGrid->getCurrentColumnPosition(); + } + sal_uInt16 nCurrentCol = getBrowserView()->View2ModelPos(nViewPos); + if (nCurrentCol == (sal_uInt16)-1) + return xEmptyReturn; + + // get the according column from the model + Reference< ::com::sun::star::container::XIndexContainer > xCols(getControlModel(), UNO_QUERY); + Reference< XPropertySet > xCurrentCol(xCols->getByIndex(nCurrentCol),UNO_QUERY); + if (!xCurrentCol.is()) + return xEmptyReturn; + + xEmptyReturn.set(xCurrentCol->getPropertyValue(PROPERTY_BOUNDFIELD) ,UNO_QUERY); + return xEmptyReturn; +} + +//------------------------------------------------------------------------------ +IMPL_LINK(SbaXDataBrowserController, OnSearchContextRequest, FmSearchContext*, pContext) +{ + Reference< ::com::sun::star::container::XIndexAccess > xPeerContainer(getBrowserView()->getGridControl(), UNO_QUERY); + + // check all grid columns for their control source + Reference< ::com::sun::star::container::XIndexAccess > xModelColumns(getFormComponent(), UNO_QUERY); + DBG_ASSERT(xModelColumns.is(), "SbaXDataBrowserController::OnSearchContextRequest : there is a grid control without columns !"); + // the case 'no columns' should be indicated with an empty container, I think ... + DBG_ASSERT(xModelColumns->getCount() >= xPeerContainer->getCount(), "SbaXDataBrowserController::OnSearchContextRequest : impossible : have more view than model columns !"); + + String sFieldList; + for (sal_Int32 nViewPos=0; nViewPos<xPeerContainer->getCount(); ++nViewPos) + { + Reference< XInterface > xCurrentColumn(xPeerContainer->getByIndex(nViewPos),UNO_QUERY); + if (!xCurrentColumn.is()) + continue; + + // can we use this column control fo searching ? + if (!IsSearchableControl(xCurrentColumn)) + continue; + + sal_uInt16 nModelPos = getBrowserView()->View2ModelPos((sal_uInt16)nViewPos); + Reference< XPropertySet > xCurrentColModel(xModelColumns->getByIndex(nModelPos),UNO_QUERY); + ::rtl::OUString aName = ::comphelper::getString(xCurrentColModel->getPropertyValue(PROPERTY_CONTROLSOURCE)); + + sFieldList += (const sal_Unicode*)aName; + sFieldList += ';'; + + pContext->arrFields.push_back(xCurrentColumn); + } + sFieldList.EraseTrailingChars(';'); + + pContext->xCursor.set(getRowSet(),UNO_QUERY); + pContext->strUsedFields = sFieldList; + + // if the cursor is in a mode other than STANDARD -> reset + Reference< XPropertySet > xCursorSet(pContext->xCursor, UNO_QUERY); + DBG_ASSERT(xCursorSet.is() && !::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISMODIFIED)), + "SbaXDataBrowserController::OnSearchContextRequest : please do not call for cursors with modified rows !"); + if (xCursorSet.is() && ::comphelper::getBOOL(xCursorSet->getPropertyValue(PROPERTY_ISNEW))) + { + Reference< XResultSetUpdate > xUpdateCursor(pContext->xCursor, UNO_QUERY); + xUpdateCursor->moveToCurrentRow(); + } + return pContext->arrFields.size(); +} + +//------------------------------------------------------------------------------ +IMPL_LINK(SbaXDataBrowserController, OnFoundData, FmFoundRecordInformation*, pInfo) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xCursor(getRowSet(), UNO_QUERY); + DBG_ASSERT(xCursor.is(), "SbaXDataBrowserController::OnFoundData : shit happens. sometimes. but this is simply impossible !"); + + // move the cursor + xCursor->moveToBookmark(pInfo->aPosition); + + // let the grid snyc it's display with the cursor + Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY); + DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::OnFoundData : no model set ?!"); + Any aOld = xModelSet->getPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron")); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True))); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), aOld); + + // and move to the field + Reference< ::com::sun::star::container::XIndexAccess > aColumnControls(getBrowserView()->getGridControl()->getPeer(), UNO_QUERY); + sal_uInt16 nViewPos; + + for ( nViewPos = 0; nViewPos < aColumnControls->getCount(); ++nViewPos ) + { + Reference< XInterface > xCurrent(aColumnControls->getByIndex(nViewPos),UNO_QUERY); + if (IsSearchableControl(xCurrent)) + { + if (pInfo->nFieldPos) + --pInfo->nFieldPos; + else + break; + } + } + + Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY); + xGrid->setCurrentColumnPosition(nViewPos); + + return 0; +} + +//------------------------------------------------------------------------------ +IMPL_LINK(SbaXDataBrowserController, OnCanceledNotFound, FmFoundRecordInformation*, pInfo) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xCursor(getRowSet(), UNO_QUERY); + + try + { + DBG_ASSERT(xCursor.is(), "SbaXDataBrowserController::OnCanceledNotFound : shit happens. sometimes. but this is simply impossible !"); + // move the cursor + xCursor->moveToBookmark(pInfo->aPosition); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + try + { + // let the grid snyc it's display with the cursor + Reference< XPropertySet > xModelSet(getControlModel(), UNO_QUERY); + DBG_ASSERT(xModelSet.is(), "SbaXDataBrowserController::OnCanceledNotFound : no model set ?!"); + Any aOld = xModelSet->getPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron")); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), ::comphelper::makeBoolAny(sal_Bool(sal_True))); + xModelSet->setPropertyValue(::rtl::OUString::createFromAscii("DisplayIsSynchron"), aOld); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return 0L; +} + +//------------------------------------------------------------------------------ +IMPL_LINK(SbaXDataBrowserController, OnAsyncGetCellFocus, void*, EMPTYARG) +{ + SbaGridControl* pVclGrid = getBrowserView() ? getBrowserView()->getVclControl() : NULL; + // if we have a controller, but the window for the controller doesn't have the focus, we correct this + if(pVclGrid) + { + if (!pVclGrid->IsEditing()) + return 0L; + + if (pVclGrid->HasChildPathFocus()) + pVclGrid->Controller()->GetWindow().GrabFocus(); + } + + return 0L; +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::criticalFail() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::criticalFail" ); + InvalidateAll(); + m_nRowSetPrivileges = 0; +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::LoadFinished(sal_Bool /*bWasSynch*/) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::LoadFinished" ); + m_nRowSetPrivileges = 0; + + if (isValid() && !loadingCancelled()) + { + // obtain cached values + try + { + Reference< XPropertySet > xFormProps( m_xLoadable, UNO_QUERY_THROW ); + OSL_VERIFY( xFormProps->getPropertyValue( PROPERTY_PRIVILEGES ) >>= m_nRowSetPrivileges ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + // -------------------------------- + // switch the control to alive mode + getBrowserView()->getGridControl()->setDesignMode(sal_False); + + // ------------------------------- + initializeParser(); + + // ------------------------------- + InvalidateAll(); + + m_aAsyncGetCellFocus.Call(); + } +} +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::initializeParser() const +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::initializeParser" ); + if ( !m_xParser.is() ) + { + // ---------------------------------------------- + // create a parser (needed for filtering/sorting) + try + { + const Reference< XPropertySet > xFormSet(getRowSet(), UNO_QUERY); + if (::comphelper::getBOOL(xFormSet->getPropertyValue(PROPERTY_ESCAPE_PROCESSING))) + { // (only if the statement isn't native) + // (it is allowed to use the PROPERTY_ISPASSTHROUGH : _after_ loading a form it is valid) + xFormSet->getPropertyValue(PROPERTY_SINGLESELECTQUERYCOMPOSER) >>= m_xParser; +/* + const Reference<XMultiServiceFactory> xFactory(::dbtools::getConnection(getRowSet()),UNO_QUERY); + if ( xFactory.is() ) + m_xParser.set(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY); +*/ + } +/* + // initialize the parser with the current sql-statement of the form + if ( m_xParser.is() ) + { + m_xParser->setElementaryQuery(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ACTIVECOMMAND))); + m_xParser->setFilter(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_FILTER))); + m_xParser->setHavingClause(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_HAVING_CLAUSE))); + m_xParser->setOrder(::comphelper::getString(xFormSet->getPropertyValue(PROPERTY_ORDER))); + } +*/ + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + m_xParser = NULL; + // no further handling, we ignore the error + } + } +} +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::loaded(const EventObject& /*aEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::loaded" ); + // not interested in + // we're loading within an separate thread and have a handling for it's "finished event" +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::unloading(const EventObject& /*aEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::unloading" ); + // not interested in +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::unloaded(const EventObject& /*aEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::unloaded" ); + m_xParser.clear(); + InvalidateAll(); + // do this asynchron, there are other listeners reacting on this message ... + // (it's a little hack : the grid columns are listening to this event, too, and their bound field may + // change as a reaction on that event. as we have no chance to be notified of this change (which is + // the one we're interested in) we give them time to do what they want to before invalidating our + // bound-field-dependent slots .... + /* + try + { + ::comphelper::disposeComponent(m_xParser); + } + catch(Exception&) + { + OSL_ENSURE(0,"Exception thrown by dispose"); + } + */ +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::reloading(const EventObject& /*aEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloading" ); + // not interested in +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::reloaded(const EventObject& /*aEvent*/) throw( RuntimeException ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::reloaded" ); + InvalidateAll(); + // do this asynchronously, there are other listeners reacting on this message ... + // (it's a little hack : the grid columns are listening to this event, too, and their bound field may + // change as a reaction on that event. as we have no chance to be notified of this change (which is + // the one we're interested in) we give them time to do what they want to before invalidating our + // bound-field-dependent slots .... +} +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::enterFormAction() +{ + if ( !m_nFormActionNestingLevel ) + // first action -> reset + m_aCurrentError.clear(); + + ++m_nFormActionNestingLevel; +} + +//------------------------------------------------------------------------------ +void SbaXDataBrowserController::leaveFormAction() +{ + DBG_ASSERT( m_nFormActionNestingLevel > 0, "SbaXDataBrowserController::leaveFormAction : invalid call !" ); + if ( --m_nFormActionNestingLevel > 0 ) + return; + + if ( !m_aCurrentError.isValid() ) + return; + + m_aAsyncDisplayError.Call(); +} + +// ------------------------------------------------------------------------- +sal_Bool SbaXDataBrowserController::isLoaded() const +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::isLoaded" ); + return m_xLoadable.is() && m_xLoadable->isLoaded(); +} + +// ------------------------------------------------------------------------- +sal_Bool SbaXDataBrowserController::isValidCursor() const +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::isValidCursor" ); + if (!m_xColumnsSupplier.is()) + return sal_False; + Reference< ::com::sun::star::container::XNameAccess > xCols = m_xColumnsSupplier->getColumns(); + if (!xCols.is() || !xCols->hasElements()) + return sal_False; + + sal_Bool bIsValid = !(m_xRowSet->isBeforeFirst() || m_xRowSet->isAfterLast()); + if ( !bIsValid ) + { + Reference<XPropertySet> xProp(m_xRowSet,UNO_QUERY); + bIsValid = ::cppu::any2bool(xProp->getPropertyValue(PROPERTY_ISNEW)); + if ( !bIsValid ) + { + bIsValid = m_xParser.is(); + } + } // if ( !bIsValid ) + return bIsValid; +} + +//================================================================== +// LoadFormHelper +//================================================================== + +class LoadFormHelper :public ::cppu::WeakImplHelper2< ::com::sun::star::form::XLoadListener, + XRowSetListener> +{ + enum STATE { STARTED, LOADED, POSITIONED, DISPOSED }; + STATE m_eState; + + Reference< XRowSet > m_xForm; + + ::osl::Mutex m_aAccessSafety; + +public: + LoadFormHelper(const Reference< XRowSet > & _rxForm); + + // ::com::sun::star::form::XLoadListener + virtual void SAL_CALL loaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException ); + virtual void SAL_CALL unloaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException ); + virtual void SAL_CALL unloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException ); + virtual void SAL_CALL reloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException ); + virtual void SAL_CALL reloaded(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException ); + + // XRowSetListener + virtual void SAL_CALL cursorMoved(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException ); + virtual void SAL_CALL rowChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException ); + virtual void SAL_CALL rowSetChanged(const ::com::sun::star::lang::EventObject& event) throw( RuntimeException ); + + // ::com::sun::star::lang::XEventListener + virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException ); + + + bool WaitUntilReallyLoaded(bool _bOnlyIfLoaded); + // waits 'til the first positioned event after the loaded event. returns true if successfull, + // false if the form was disposed or unloaded before or while waiting + // if _bOnlyIfLoaded is false and the form isn't loaded already loaded, false will be returned + // (without any wating) + + void cancel(); + +protected: + ~LoadFormHelper(); + + void implDispose(); +}; + +DBG_NAME(LoadFormHelper) +//------------------------------------------------------------------------------ +LoadFormHelper::LoadFormHelper(const Reference< XRowSet > & _rxForm) + :m_eState(STARTED) + ,m_xForm(_rxForm) +{ + DBG_CTOR(LoadFormHelper,NULL); + + Reference< ::com::sun::star::form::XLoadable > (m_xForm, UNO_QUERY)->addLoadListener(this); + m_xForm->addRowSetListener(this); +} + +//------------------------------------------------------------------------------ +LoadFormHelper::~LoadFormHelper() +{ + ::osl::MutexGuard aGuard(m_aAccessSafety); + implDispose(); + + DBG_DTOR(LoadFormHelper,NULL); +} + +//------------------------------------------------------------------------------ +void LoadFormHelper::implDispose() +{ + if (DISPOSED != m_eState) + { + + Reference< ::com::sun::star::form::XLoadable > (m_xForm, UNO_QUERY)->removeLoadListener(this); + m_xForm->removeRowSetListener(this); + m_xForm = NULL; + m_eState = DISPOSED; + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::loaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard(m_aAccessSafety); + DBG_ASSERT(m_eState == STARTED || m_eState == DISPOSED, "LoadFormHelper::loaded : wrong call !"); + if (m_eState == STARTED) + m_eState = LOADED; +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::unloaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard(m_aAccessSafety); + DBG_ERROR("LoadFormHelper::unloaded : shouldn't be called !"); + implDispose(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::unloading(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException ) +{ +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::reloading(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException ) +{ +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::reloaded(const ::com::sun::star::lang::EventObject& /*aEvent*/) throw( RuntimeException ) +{ +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::cursorMoved(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard(m_aAccessSafety); + if (m_eState == LOADED) + m_eState = POSITIONED; +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::rowChanged(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException ) +{ +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::rowSetChanged(const ::com::sun::star::lang::EventObject& /*event*/) throw( RuntimeException ) +{ +} + +//------------------------------------------------------------------------------ +void SAL_CALL LoadFormHelper::disposing(const ::com::sun::star::lang::EventObject& /*Source*/) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard(m_aAccessSafety); + implDispose(); +} + +//------------------------------------------------------------------------------ +void LoadFormHelper::cancel() +{ + implDispose(); +} + +//------------------------------------------------------------------------------ +bool LoadFormHelper::WaitUntilReallyLoaded(bool _bOnlyIfLoaded) +{ + ::osl::ResettableMutexGuard aGuard( m_aAccessSafety ); + if (DISPOSED == m_eState) + return false; + + if (_bOnlyIfLoaded && (STARTED == m_eState)) + // we did't get a "loaded" event .... + return false; + + sal_Bool bDone = (POSITIONED == m_eState); + aGuard.clear(); + + while (!bDone) + { + aGuard.reset(); + bDone = (POSITIONED == m_eState); + aGuard.clear(); + } + + aGuard.reset(); + implDispose(); + + return true; +} + +// ----------------------------------------------------------------------------- +sal_Int16 SbaXDataBrowserController::getCurrentColumnPosition() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::getCurrentColumnPosition" ); + Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY); + sal_Int16 nViewPos = -1; + try + { + if ( xGrid.is() ) + nViewPos = xGrid->getCurrentColumnPosition(); + } + catch(Exception&) {} + return nViewPos; +} +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::setCurrentColumnPosition( sal_Int16 _nPos ) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::setCurrentColumnPosition" ); + Reference< ::com::sun::star::form::XGrid > xGrid(getBrowserView()->getGridControl(), UNO_QUERY); + try + { + if ( -1 != _nPos ) + xGrid->setCurrentColumnPosition(_nPos); + } + catch(Exception&) {} +} +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::BeforeDrop() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::BeforeDrop" ); + Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY); + if (xFormError.is()) + xFormError->removeSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this); +} +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::AfterDrop() +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::AfterDrop" ); + Reference< ::com::sun::star::sdb::XSQLErrorBroadcaster > xFormError(getRowSet(), UNO_QUERY); + if (xFormError.is()) + xFormError->addSQLErrorListener((::com::sun::star::sdb::XSQLErrorListener*)this); +} +// ----------------------------------------------------------------------------- +void SbaXDataBrowserController::addColumnListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::addColumnListeners" ); +// ... all the grid columns + Reference< ::com::sun::star::container::XIndexContainer > xColumns(_xGridControlModel, UNO_QUERY); + if (xColumns.is()) + { + sal_Int32 nCount = xColumns->getCount(); + for (sal_uInt16 i=0; i < nCount; ++i) + { + Reference< XPropertySet > xCol(xColumns->getByIndex(i),UNO_QUERY); + AddColumnListener(xCol); + } + } +} +// ----------------------------------------------------------------------------- +sal_Bool SbaXDataBrowserController::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & /*xGrid*/) +{ + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaui", "Ocke.Janssen@sun.com", "SbaXDataBrowserController::InitializeGridModel" ); + return sal_True; +} +//.................................................................. +} // namespace dbaui +//.................................................................. diff --git a/dbaccess/source/ui/browser/brwview.cxx b/dbaccess/source/ui/browser/brwview.cxx new file mode 100644 index 000000000000..44a6b40e1f2f --- /dev/null +++ b/dbaccess/source/ui/browser/brwview.cxx @@ -0,0 +1,395 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef _SBA_BWRCTRLR_HXX +#include "brwctrlr.hxx" +#endif +#ifndef _SBX_BRWVIEW_HXX +#include "brwview.hxx" +#endif +#ifndef _SBA_GRID_HXX +#include "sbagrid.hxx" +#endif +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/helper/vclunohelper.hxx> +#endif +#ifndef _COMPHELPER_TYPES_HXX_ +#include <comphelper/types.hxx> +#endif +#ifndef _SV_SPLIT_HXX +#include <vcl/split.hxx> +#endif +#ifndef DBACCESS_UI_DBTREEVIEW_HXX +#include "dbtreeview.hxx" +#endif +#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC +#include "dbustrings.hrc" +#endif +#ifndef _DBU_BRW_HRC_ +#include "dbu_brw.hrc" +#endif +#ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_ +#include <com/sun/star/form/XLoadable.hpp> +#endif +#ifndef _COM_SUN_STAR_AWT_XCONTROLCONTAINER_HPP_ +#include <com/sun/star/awt/XControlContainer.hpp> +#endif +#ifndef DBAUI_TOOLS_HXX +#include "UITools.hxx" +#endif + + +using namespace dbaui; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::form; +// using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; + + +namespace +{ + sal_Bool isGrabVclControlFocusAllowed(const UnoDataBrowserView* _pView) + { + sal_Bool bGrabFocus = sal_False; + SbaGridControl* pVclControl = _pView->getVclControl(); + Reference< ::com::sun::star::awt::XControl > xGrid = _pView->getGridControl(); + if (pVclControl && xGrid.is()) + { + bGrabFocus = sal_True; + if(!pVclControl->HasChildPathFocus()) + { + Reference<XChild> xChild(xGrid->getModel(),UNO_QUERY); + Reference<XLoadable> xLoad; + if(xChild.is()) + xLoad.set(xChild->getParent(),UNO_QUERY); + bGrabFocus = xLoad.is() && xLoad->isLoaded(); + } + } + return bGrabFocus; + } +} +//================================================================== +//= UnoDataBrowserView +//================================================================== + +DBG_NAME(UnoDataBrowserView) +// ------------------------------------------------------------------------- +UnoDataBrowserView::UnoDataBrowserView( Window* pParent, + IController& _rController, + const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rFactory) + :ODataView(pParent,_rController,_rFactory) + ,m_pTreeView(NULL) + ,m_pSplitter(NULL) + ,m_pVclControl(NULL) + ,m_pStatus(NULL) +{ + DBG_CTOR(UnoDataBrowserView,NULL); + +} +// ------------------------------------------------------------------------- +void UnoDataBrowserView::Construct(const Reference< ::com::sun::star::awt::XControlModel >& xModel) +{ + try + { + ODataView::Construct(); + + // our UNO representation + m_xMe = VCLUnoHelper::CreateControlContainer(this); + + // create the (UNO-) control + m_xGrid = new SbaXGridControl(getORB()); + DBG_ASSERT(m_xGrid.is(), "UnoDataBrowserView::Construct : could not create a grid control !"); + // in design mode (for the moment) + m_xGrid->setDesignMode(sal_True); + + Reference< ::com::sun::star::awt::XWindow > xGridWindow(m_xGrid, UNO_QUERY); + xGridWindow->setVisible(sal_True); + xGridWindow->setEnable(sal_True); + + // introduce the model to the grid + m_xGrid->setModel(xModel); + // introduce the container (me) to the grid + Reference< ::com::sun::star::beans::XPropertySet > xModelSet(xModel, UNO_QUERY); + getContainer()->addControl(::comphelper::getString(xModelSet->getPropertyValue(PROPERTY_NAME)), m_xGrid); + + // get the VCL-control + m_pVclControl = NULL; + getVclControl(); + + DBG_ASSERT(m_pVclControl != NULL, "UnoDataBrowserView::Construct : no real grid control !"); + } + catch(Exception&) + { + ::comphelper::disposeComponent(m_xGrid); + throw; + } +} +// ------------------------------------------------------------------------- +UnoDataBrowserView::~UnoDataBrowserView() +{ + { + ::std::auto_ptr<Splitter> aTemp(m_pSplitter); + m_pSplitter = NULL; + } + setTreeView(NULL); + + if ( m_pStatus ) + { + delete m_pStatus; + m_pStatus = NULL; + } + + try + { + ::comphelper::disposeComponent(m_xGrid); + ::comphelper::disposeComponent(m_xMe); + } + catch(Exception) + {} + + DBG_DTOR(UnoDataBrowserView,NULL); +} +// ----------------------------------------------------------------------------- +IMPL_LINK( UnoDataBrowserView, SplitHdl, void*, /*NOINTERESTEDIN*/ ) +{ + long nYPos = m_pSplitter->GetPosPixel().Y(); + m_pSplitter->SetPosPixel( Point( m_pSplitter->GetSplitPosPixel(), nYPos ) ); + Resize(); + + return 0L; +} +// ------------------------------------------------------------------------- +void UnoDataBrowserView::setSplitter(Splitter* _pSplitter) +{ + m_pSplitter = _pSplitter; + m_pSplitter->SetSplitHdl( LINK( this, UnoDataBrowserView, SplitHdl ) ); + LINK( this, UnoDataBrowserView, SplitHdl ).Call(m_pSplitter); +} +// ------------------------------------------------------------------------- +void UnoDataBrowserView::setTreeView(DBTreeView* _pTreeView) +{ + if (m_pTreeView != _pTreeView) + { + if (m_pTreeView) + { + ::std::auto_ptr<Window> aTemp(m_pTreeView); + m_pTreeView = NULL; + } + m_pTreeView = _pTreeView; + } +} +// ------------------------------------------------------------------------- +void UnoDataBrowserView::showStatus( const String& _rStatus ) +{ + if (0 == _rStatus.Len()) + hideStatus(); + else + { + if (!m_pStatus) + m_pStatus = new FixedText(this); + m_pStatus->SetText(_rStatus); + m_pStatus->Show(); + Resize(); + Update(); + } +} + +// ------------------------------------------------------------------------- +void UnoDataBrowserView::hideStatus() +{ + if (!m_pStatus || !m_pStatus->IsVisible()) + // nothing to do + return; + m_pStatus->Hide(); + Resize(); + Update(); +} + +// ------------------------------------------------------------------------- +void UnoDataBrowserView::resizeDocumentView(Rectangle& _rPlayground) +{ + Point aSplitPos; + Size aSplitSize; + Point aPlaygroundPos( _rPlayground.TopLeft() ); + Size aPlaygroundSize( _rPlayground.GetSize() ); + + if (m_pTreeView && m_pTreeView->IsVisible() && m_pSplitter) + { + // calculate the splitter pos and size + aSplitPos = m_pSplitter->GetPosPixel(); + aSplitPos.Y() = aPlaygroundPos.Y(); + aSplitSize = m_pSplitter->GetOutputSizePixel(); + aSplitSize.Height() = aPlaygroundSize.Height(); + + if( ( aSplitPos.X() + aSplitSize.Width() ) > ( aPlaygroundSize.Width() )) + aSplitPos.X() = aPlaygroundSize.Width() - aSplitSize.Width(); + + if( aSplitPos.X() <= aPlaygroundPos.X() ) + aSplitPos.X() = aPlaygroundPos.X() + sal_Int32(aPlaygroundSize.Width() * 0.2); + + // the tree pos and size + Point aTreeViewPos( aPlaygroundPos ); + Size aTreeViewSize( aSplitPos.X(), aPlaygroundSize.Height() ); + + // the status pos and size + if (m_pStatus && m_pStatus->IsVisible()) + { + Size aStatusSize(aPlaygroundPos.X(), GetTextHeight() + 2); + aStatusSize = LogicToPixel(aStatusSize, MAP_APPFONT); + aStatusSize.Width() = aTreeViewSize.Width() - 2 - 2; + + Point aStatusPos( aPlaygroundPos.X() + 2, aTreeViewPos.Y() + aTreeViewSize.Height() - aStatusSize.Height() ); + m_pStatus->SetPosSizePixel( aStatusPos, aStatusSize ); + aTreeViewSize.Height() -= aStatusSize.Height(); + } + + // set the size of treelistbox + m_pTreeView->SetPosSizePixel( aTreeViewPos, aTreeViewSize ); + + //set the size of the splitter + m_pSplitter->SetPosSizePixel( aSplitPos, Size( aSplitSize.Width(), aPlaygroundSize.Height() ) ); + m_pSplitter->SetDragRectPixel( _rPlayground ); + } + + // set the size of grid control + Reference< ::com::sun::star::awt::XWindow > xGridAsWindow(m_xGrid, UNO_QUERY); + if (xGridAsWindow.is()) + xGridAsWindow->setPosSize( aSplitPos.X() + aSplitSize.Width(), aPlaygroundPos.Y(), + aPlaygroundSize.Width() - aSplitSize.Width() - aSplitPos.X(), aPlaygroundSize.Height(), ::com::sun::star::awt::PosSize::POSSIZE); + + // just for completeness: there is no space left, we occupied it all ... + _rPlayground.SetPos( _rPlayground.BottomRight() ); + _rPlayground.SetSize( Size( 0, 0 ) ); +} + +//------------------------------------------------------------------ +sal_uInt16 UnoDataBrowserView::View2ModelPos(sal_uInt16 nPos) const +{ + return m_pVclControl ? m_pVclControl->GetModelColumnPos(m_pVclControl->GetColumnIdFromViewPos(nPos)) : -1; +} + +// ----------------------------------------------------------------------------- +SbaGridControl* UnoDataBrowserView::getVclControl() const +{ + if ( !m_pVclControl ) + { + OSL_ENSURE(m_xGrid.is(),"Grid not set!"); + if ( m_xGrid.is() ) + { + Reference< ::com::sun::star::awt::XWindowPeer > xPeer = m_xGrid->getPeer(); + if ( xPeer.is() ) + { + SbaXGridPeer* pPeer = SbaXGridPeer::getImplementation(xPeer); + UnoDataBrowserView* pTHIS = const_cast<UnoDataBrowserView*>(this); + if ( pPeer ) + { + m_pVclControl = static_cast<SbaGridControl*>(pPeer->GetWindow()); + pTHIS->startComponentListening(Reference<XComponent>(VCLUnoHelper::GetInterface(m_pVclControl),UNO_QUERY)); + } + } + } + } + return m_pVclControl; +} +// ----------------------------------------------------------------------------- +void UnoDataBrowserView::GetFocus() +{ + ODataView::GetFocus(); + if( m_pTreeView && m_pTreeView->IsVisible() && !m_pTreeView->HasChildPathFocus()) + m_pTreeView->GrabFocus(); + else if (m_pVclControl && m_xGrid.is()) + { + sal_Bool bGrabFocus = sal_False; + if(!m_pVclControl->HasChildPathFocus()) + { + bGrabFocus = isGrabVclControlFocusAllowed(this); + if( bGrabFocus ) + m_pVclControl->GrabFocus(); + } + if(!bGrabFocus && m_pTreeView && m_pTreeView->IsVisible() ) + m_pTreeView->GrabFocus(); + } +} +// ----------------------------------------------------------------------------- +void UnoDataBrowserView::_disposing( const ::com::sun::star::lang::EventObject& /*_rSource*/ ) +{ + stopComponentListening(Reference<XComponent>(VCLUnoHelper::GetInterface(m_pVclControl),UNO_QUERY)); + m_pVclControl = NULL; +} +// ------------------------------------------------------------------------- +long UnoDataBrowserView::PreNotify( NotifyEvent& rNEvt ) +{ + long nDone = 0L; + if(rNEvt.GetType() == EVENT_KEYINPUT) + { + sal_Bool bGrabAllowed = isGrabVclControlFocusAllowed(this); + if ( bGrabAllowed ) + { + const KeyEvent* pKeyEvt = rNEvt.GetKeyEvent(); + const KeyCode& rKeyCode = pKeyEvt->GetKeyCode(); + if ( ( rKeyCode == KeyCode( KEY_E, TRUE, TRUE, FALSE, FALSE ) ) + || ( rKeyCode == KeyCode( KEY_TAB, TRUE, FALSE, FALSE, FALSE ) ) + ) + { + if ( m_pTreeView && m_pVclControl && m_pTreeView->HasChildPathFocus() ) + m_pVclControl->GrabFocus(); + else if ( m_pTreeView && m_pVclControl && m_pVclControl->HasChildPathFocus() ) + m_pTreeView->GrabFocus(); + + nDone = 1L; + } + } + } + return nDone ? nDone : ODataView::PreNotify(rNEvt); +} + +DBG_NAME(BrowserViewStatusDisplay) +// ----------------------------------------------------------------------------- +BrowserViewStatusDisplay::BrowserViewStatusDisplay( UnoDataBrowserView* _pView, const String& _rStatus ) + :m_pView(_pView) +{ + DBG_CTOR(BrowserViewStatusDisplay,NULL); + + if (m_pView) + m_pView->showStatus(_rStatus); +} + +// ----------------------------------------------------------------------------- +BrowserViewStatusDisplay::~BrowserViewStatusDisplay( ) +{ + if (m_pView) + m_pView->showStatus(String()); + + DBG_DTOR(BrowserViewStatusDisplay,NULL); +} +// ----------------------------------------------------------------------------- diff --git a/dbaccess/source/ui/browser/dataview.cxx b/dbaccess/source/ui/browser/dataview.cxx new file mode 100644 index 000000000000..382aac477727 --- /dev/null +++ b/dbaccess/source/ui/browser/dataview.cxx @@ -0,0 +1,268 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef DBAUI_DATAVIEW_HXX +#include "dataview.hxx" +#endif +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/unohlp.hxx> +#endif +#ifndef _COMPHELPER_TYPES_HXX_ +#include <comphelper/types.hxx> +#endif +#include <comphelper/namedvaluecollection.hxx> +#ifndef _SFXAPP_HXX //autogen wg. SFX_APP +#include <sfx2/app.hxx> +#endif +#ifndef _SFXIMGMGR_HXX +#include <sfx2/imgmgr.hxx> +#endif +#ifndef _SV_FIXED_HXX +#include <vcl/fixed.hxx> +#endif +#ifndef DBAUI_ICONTROLLER_HXX +#include "IController.hxx" +#endif +#ifndef DBAUI_TOOLS_HXX +#include "UITools.hxx" +#endif +#ifndef _SFX_HRC +#include <sfx2/sfx.hrc> +#endif +#ifndef _SVTOOLS_IMGDEF_HXX +#include <svtools/imgdef.hxx> +#endif +#include <tools/diagnose_ex.h> + +//......................................................................... +namespace dbaui +{ +//......................................................................... + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::frame; + + //===================================================================== + //= ColorChanger + //===================================================================== + class ColorChanger + { + protected: + OutputDevice* m_pDev; + + public: + ColorChanger( OutputDevice* _pDev, const Color& _rNewLineColor, const Color& _rNewFillColor ) + :m_pDev( _pDev ) + { + m_pDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR ); + m_pDev->SetLineColor( _rNewLineColor ); + m_pDev->SetFillColor( _rNewFillColor ); + } + + ~ColorChanger() + { + m_pDev->Pop(); + } + }; + + DBG_NAME(ODataView) + // ------------------------------------------------------------------------- + ODataView::ODataView( Window* pParent, + IController& _rController, + const Reference< XMultiServiceFactory >& _rFactory, + WinBits nStyle) + :Window(pParent,nStyle) + ,m_xServiceFactory(_rFactory) + ,m_rController( _rController ) + ,m_pSeparator( NULL ) + { + DBG_CTOR(ODataView,NULL); + m_rController.acquire(); + m_pAccel.reset(::svt::AcceleratorExecute::createAcceleratorHelper()); + } + + // ------------------------------------------------------------------------- + void ODataView::Construct() + { + } + + // ------------------------------------------------------------------------- + ODataView::~ODataView() + { + DBG_DTOR(ODataView,NULL); + + enableSeparator( sal_False ); + m_rController.release(); + } + + // ------------------------------------------------------------------------- + void ODataView::enableSeparator( const sal_Bool _bEnable ) + { + if ( _bEnable == isSeparatorEnabled() ) + // nothing to do + return; + + if ( _bEnable ) + { + m_pSeparator = new FixedLine( this ); + m_pSeparator->Show( ); + } + else + { + ::std::auto_ptr<FixedLine> aTemp(m_pSeparator); + m_pSeparator = NULL; + } + Resize(); + } + // ------------------------------------------------------------------------- + void ODataView::resizeDocumentView( Rectangle& /*_rPlayground*/ ) + { + } + + // ------------------------------------------------------------------------- + void ODataView::Paint( const Rectangle& _rRect ) + { + //................................................................. + // draw the background + { + ColorChanger aColors( this, COL_TRANSPARENT, GetSettings().GetStyleSettings().GetFaceColor() ); + DrawRect( _rRect ); + } + + // let the base class do anything it needs + Window::Paint( _rRect ); + } + + // ------------------------------------------------------------------------- + void ODataView::resizeAll( const Rectangle& _rPlayground ) + { + Rectangle aPlayground( _rPlayground ); + + // position thew separator + if ( m_pSeparator ) + { + Size aSeparatorSize = Size( aPlayground.GetWidth(), 2 ); + + m_pSeparator->SetPosSizePixel( aPlayground.TopLeft(), aSeparatorSize ); + + aPlayground.Top() += aSeparatorSize.Height() + 1; + } + + // position the controls of the document's view + resizeDocumentView( aPlayground ); + } + + // ------------------------------------------------------------------------- + void ODataView::Resize() + { + Window::Resize(); + resizeAll( Rectangle( Point( 0, 0), GetSizePixel() ) ); + } + // ----------------------------------------------------------------------------- + long ODataView::PreNotify( NotifyEvent& _rNEvt ) + { + bool bHandled = false; + switch ( _rNEvt.GetType() ) + { + case EVENT_KEYINPUT: + { + const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent(); + const KeyCode& aKeyCode = pKeyEvent->GetKeyCode(); + if ( m_pAccel.get() && m_pAccel->execute( aKeyCode ) ) + // the accelerator consumed the event + return 1L; + } + // NO break + case EVENT_KEYUP: + case EVENT_MOUSEBUTTONDOWN: + case EVENT_MOUSEBUTTONUP: + bHandled = m_rController.interceptUserInput( _rNEvt ); + break; + } + return bHandled ? 1L : Window::PreNotify( _rNEvt ); + } + // ----------------------------------------------------------------------------- + void ODataView::StateChanged( StateChangedType nType ) + { + Window::StateChanged( nType ); + + if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) + { + // Check if we need to get new images for normal/high contrast mode + m_rController.notifyHiContrastChanged(); + } + + if ( nType == STATE_CHANGE_INITSHOW ) + { + // now that there's a view which is finally visible, remove the "Hidden" value from the + // model's arguments. + try + { + Reference< XController > xController( m_rController.getXController(), UNO_SET_THROW ); + Reference< XModel > xModel( xController->getModel(), UNO_QUERY ); + if ( xModel.is() ) + { + ::comphelper::NamedValueCollection aArgs( xModel->getArgs() ); + aArgs.remove( "Hidden" ); + xModel->attachResource( xModel->getURL(), aArgs.getPropertyValues() ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + // ----------------------------------------------------------------------------- + void ODataView::DataChanged( const DataChangedEvent& rDCEvt ) + { + Window::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || + (rDCEvt.GetType() == DATACHANGED_DISPLAY) || + (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || + ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && + (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) + { + // Check if we need to get new images for normal/high contrast mode + m_rController.notifyHiContrastChanged(); + } + } + // ----------------------------------------------------------------------------- + void ODataView::attachFrame(const Reference< XFrame >& _xFrame) + { + m_pAccel->init(m_xServiceFactory,_xFrame); + } +//......................................................................... +} +// namespace dbaui +//......................................................................... diff --git a/dbaccess/source/ui/browser/dbexchange.cxx b/dbaccess/source/ui/browser/dbexchange.cxx new file mode 100644 index 000000000000..972f9be83934 --- /dev/null +++ b/dbaccess/source/ui/browser/dbexchange.cxx @@ -0,0 +1,263 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#include "dbexchange.hxx" +#include <sot/formats.hxx> +#include <sot/storage.hxx> +#include <osl/diagnose.h> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdb/XResultSetAccess.hpp> +#include "TokenWriter.hxx" +#include "dbustrings.hrc" +#include <comphelper/uno3.hxx> +#include <svx/dataaccessdescriptor.hxx> +#include "UITools.hxx" + + +namespace dbaui +{ + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::sdb; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::sdbc; + using namespace ::com::sun::star::datatransfer; + using namespace ::svx; + + namespace + { + template<class T > void lcl_setListener(const Reference<T>& _xComponent, const Reference< XEventListener >& i_rListener, const bool i_bAdd ) + { + if ( !_xComponent.is() ) + return; + + Reference< XComponent> xCom( _xComponent, UNO_QUERY ); + OSL_ENSURE( xCom.is(), "lcl_setListener: no component!" ); + if ( !xCom.is() ) + return; + + i_bAdd ? xCom->addEventListener( i_rListener ) : xCom->removeEventListener( i_rListener ); + } + } + + // ----------------------------------------------------------------------------- + ODataClipboard::ODataClipboard( + const ::rtl::OUString& _rDatasource, + const sal_Int32 _nCommandType, + const ::rtl::OUString& _rCommand, + const Reference< XConnection >& _rxConnection, + const Reference< XNumberFormatter >& _rxFormatter, + const Reference< XMultiServiceFactory >& _rxORB) + :ODataAccessObjectTransferable( _rDatasource,::rtl::OUString(), _nCommandType, _rCommand, _rxConnection ) + ,m_pHtml(NULL) + ,m_pRtf(NULL) + { + osl_incrementInterlockedCount( &m_refCount ); + lcl_setListener( _rxConnection, this, true ); + + m_pHtml.set( new OHTMLImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); + m_pRtf.set( new ORTFImportExport( getDescriptor(), _rxORB, _rxFormatter ) ); + + osl_decrementInterlockedCount( &m_refCount ); + } + + // ----------------------------------------------------------------------------- + ODataClipboard::ODataClipboard( + const ::rtl::OUString& _rDatasource, + const sal_Int32 _nCommandType, + const ::rtl::OUString& _rCommand, + const Reference< XNumberFormatter >& _rxFormatter, + const Reference< XMultiServiceFactory >& _rxORB) + :ODataAccessObjectTransferable( _rDatasource, ::rtl::OUString(),_nCommandType, _rCommand) + ,m_pHtml(NULL) + ,m_pRtf(NULL) + { + m_pHtml.set( new OHTMLImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); + m_pRtf.set( new ORTFImportExport( getDescriptor(),_rxORB, _rxFormatter ) ); + } + + // ----------------------------------------------------------------------------- + ODataClipboard::ODataClipboard( const Reference< XPropertySet >& i_rAliveForm, + const Sequence< Any >& i_rSelectedRows, + const sal_Bool i_bBookmarkSelection, + const Reference< XMultiServiceFactory >& i_rORB ) + :ODataAccessObjectTransferable( i_rAliveForm ) + ,m_pHtml(NULL) + ,m_pRtf(NULL) + { + OSL_PRECOND( i_rORB.is(), "ODataClipboard::ODataClipboard: having no factory is not good ..." ); + + osl_incrementInterlockedCount( &m_refCount ); + + Reference<XConnection> xConnection; + getDescriptor()[ daConnection ] >>= xConnection; + lcl_setListener( xConnection, this, true ); + + // do not pass the form itself as source result set, since the client might operate on the form, which + // might lead to undesired effects. Instead, use a clone. + Reference< XResultSet > xResultSetClone; + Reference< XResultSetAccess > xResultSetAccess( i_rAliveForm, UNO_QUERY ); + if ( xResultSetAccess.is() ) + xResultSetClone = xResultSetAccess->createResultSet(); + OSL_ENSURE( xResultSetClone.is(), "ODataClipboard::ODataClipboard: could not clone the form's result set" ); + lcl_setListener( xResultSetClone, this, true ); + + getDescriptor()[daCursor] <<= xResultSetClone; + getDescriptor()[daSelection] <<= i_rSelectedRows; + getDescriptor()[daBookmarkSelection]<<= i_bBookmarkSelection; + addCompatibleSelectionDescription( i_rSelectedRows ); + + if ( xConnection.is() && i_rORB.is() ) + { + Reference< XNumberFormatter > xFormatter( getNumberFormatter( xConnection, i_rORB ) ); + if ( xFormatter.is() ) + { + m_pHtml.set( new OHTMLImportExport( getDescriptor(), i_rORB, xFormatter ) ); + m_pRtf.set( new ORTFImportExport( getDescriptor(), i_rORB, xFormatter ) ); + } + } + + osl_decrementInterlockedCount( &m_refCount ); + } + + // ----------------------------------------------------------------------------- + sal_Bool ODataClipboard::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, sal_uInt32 nUserObjectId, const ::com::sun::star::datatransfer::DataFlavor& /*rFlavor*/ ) + { + if (nUserObjectId == SOT_FORMAT_RTF || nUserObjectId == SOT_FORMATSTR_ID_HTML ) + { + ODatabaseImportExport* pExport = reinterpret_cast<ODatabaseImportExport*>(pUserObject); + if ( pExport && rxOStm.Is() ) + { + pExport->setStream(&rxOStm); + return pExport->Write(); + } + } + return sal_False; + } + + // ----------------------------------------------------------------------------- + void ODataClipboard::AddSupportedFormats() + { + if ( m_pRtf.is() ) + AddFormat( SOT_FORMAT_RTF ); + + if ( m_pHtml.is() ) + AddFormat( SOT_FORMATSTR_ID_HTML ); + + ODataAccessObjectTransferable::AddSupportedFormats(); + } + + // ----------------------------------------------------------------------------- + sal_Bool ODataClipboard::GetData( const DataFlavor& rFlavor ) + { + const ULONG nFormat = SotExchange::GetFormat(rFlavor); + switch (nFormat) + { + case SOT_FORMAT_RTF: + if ( m_pRtf.is() ) + m_pRtf->initialize(getDescriptor()); + return m_pRtf.is() && SetObject( m_pRtf.get(), SOT_FORMAT_RTF, rFlavor ); + + case SOT_FORMATSTR_ID_HTML: + if ( m_pHtml.is() ) + m_pHtml->initialize(getDescriptor()); + return m_pHtml.is() && SetObject( m_pHtml.get(), SOT_FORMATSTR_ID_HTML, rFlavor ); + } + + return ODataAccessObjectTransferable::GetData( rFlavor ); + } + + // ----------------------------------------------------------------------------- + void ODataClipboard::ObjectReleased() + { + if ( m_pHtml.is() ) + { + m_pHtml->dispose(); + m_pHtml.clear(); + } + + if ( m_pRtf.is() ) + { + m_pRtf->dispose(); + m_pRtf.clear(); + } + + if ( getDescriptor().has( daConnection ) ) + { + Reference<XConnection> xConnection( getDescriptor()[daConnection], UNO_QUERY ); + lcl_setListener( xConnection, this, false ); + } + + if ( getDescriptor().has( daCursor ) ) + { + Reference< XResultSet > xResultSet( getDescriptor()[ daCursor ], UNO_QUERY ); + lcl_setListener( xResultSet, this, false ); + } + + ODataAccessObjectTransferable::ObjectReleased( ); + } + + // ----------------------------------------------------------------------------- + void SAL_CALL ODataClipboard::disposing( const ::com::sun::star::lang::EventObject& i_rSource ) throw (::com::sun::star::uno::RuntimeException) + { + ODataAccessDescriptor& rDescriptor( getDescriptor() ); + + if ( rDescriptor.has( daConnection ) ) + { + Reference< XConnection > xConnection( rDescriptor[daConnection], UNO_QUERY ); + if ( xConnection == i_rSource.Source ) + { + rDescriptor.erase( daConnection ); + } + } + + if ( rDescriptor.has( daCursor ) ) + { + Reference< XResultSet > xResultSet( rDescriptor[ daCursor ], UNO_QUERY ); + if ( xResultSet == i_rSource.Source ) + { + rDescriptor.erase( daCursor ); + // Selection and BookmarkSelection are meaningless without a result set + if ( rDescriptor.has( daSelection ) ) + rDescriptor.erase( daSelection ); + if ( rDescriptor.has( daBookmarkSelection ) ) + rDescriptor.erase( daBookmarkSelection ); + } + } + + // no matter whether it was the source connection or the source result set which died, + // we cannot provide the data anymore. + ClearFormats(); + } +} + + diff --git a/dbaccess/source/ui/browser/dbloader.cxx b/dbaccess/source/ui/browser/dbloader.cxx new file mode 100644 index 000000000000..69130da08609 --- /dev/null +++ b/dbaccess/source/ui/browser/dbloader.cxx @@ -0,0 +1,358 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#include "dbu_reghelper.hxx" +#include "dbustrings.hrc" +#include "UITools.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XSet.hpp> +#include <com/sun/star/document/XEventListener.hpp> +#include <com/sun/star/frame/XController2.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XFrameLoader.hpp> +#include <com/sun/star/frame/XLoadEventListener.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> +#include <com/sun/star/registry/XRegistryKey.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> +#include <com/sun/star/frame/XModule.hpp> +/** === end UNO includes === **/ + +#include <com/sun/star/sdbc/XDataSource.hpp> +#include <comphelper/namedvaluecollection.hxx> +#include <comphelper/componentcontext.hxx> +#include <cppuhelper/implbase2.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> +#include <tools/urlobj.hxx> +#include <vcl/svapp.hxx> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; +using ::com::sun::star::sdbc::XDataSource; +using namespace dbaui; + +class DBContentLoader : public ::cppu::WeakImplHelper2< XFrameLoader, XServiceInfo> +{ +private: + ::rtl::OUString m_aURL; + Sequence< PropertyValue> m_aArgs; + Reference< XLoadEventListener > m_xListener; + Reference< XFrame > m_xFrame; + Reference< XMultiServiceFactory > m_xServiceFactory; +public: + DBContentLoader(const Reference< XMultiServiceFactory >&); + ~DBContentLoader(); + + // XServiceInfo + ::rtl::OUString SAL_CALL getImplementationName() throw( ); + sal_Bool SAL_CALL supportsService(const ::rtl::OUString& ServiceName) throw( ); + Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ); + + // static methods + static ::rtl::OUString getImplementationName_Static() throw( ) + { + return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.DBContentLoader"); + } + static Sequence< ::rtl::OUString> getSupportedServiceNames_Static(void) throw( ); + static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + SAL_CALL Create(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >&); + + // XLoader + virtual void SAL_CALL load( const Reference< XFrame > & _rFrame, const ::rtl::OUString& _rURL, + const Sequence< PropertyValue >& _rArgs, + const Reference< XLoadEventListener > & _rListener) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL cancel(void) throw(); +}; +DBG_NAME(DBContentLoader) + +DBContentLoader::DBContentLoader(const Reference< XMultiServiceFactory >& _rxFactory) + :m_xServiceFactory(_rxFactory) +{ + DBG_CTOR(DBContentLoader,NULL); + +} +// ------------------------------------------------------------------------- + +DBContentLoader::~DBContentLoader() +{ + + DBG_DTOR(DBContentLoader,NULL); +} +// ------------------------------------------------------------------------- +// ------------------------------------------------------------------------- +extern "C" void SAL_CALL createRegistryInfo_DBContentLoader() +{ + static ::dbaui::OMultiInstanceAutoRegistration< DBContentLoader > aAutoRegistration; +} +// ------------------------------------------------------------------------- +Reference< XInterface > SAL_CALL DBContentLoader::Create( const Reference< XMultiServiceFactory > & rSMgr ) +{ + return *(new DBContentLoader(rSMgr)); +} +// ------------------------------------------------------------------------- +// XServiceInfo +::rtl::OUString SAL_CALL DBContentLoader::getImplementationName() throw( ) +{ + return getImplementationName_Static(); +} +// ------------------------------------------------------------------------- + +// XServiceInfo +sal_Bool SAL_CALL DBContentLoader::supportsService(const ::rtl::OUString& ServiceName) throw( ) +{ + Sequence< ::rtl::OUString > aSNL = getSupportedServiceNames(); + const ::rtl::OUString * pBegin = aSNL.getConstArray(); + const ::rtl::OUString * pEnd = pBegin + aSNL.getLength(); + for( ; pBegin != pEnd; ++pBegin) + if( *pBegin == ServiceName ) + return sal_True; + return sal_False; +} +// ------------------------------------------------------------------------- +// XServiceInfo +Sequence< ::rtl::OUString > SAL_CALL DBContentLoader::getSupportedServiceNames(void) throw( ) +{ + return getSupportedServiceNames_Static(); +} +// ------------------------------------------------------------------------- +// ORegistryServiceManager_Static +Sequence< ::rtl::OUString > DBContentLoader::getSupportedServiceNames_Static(void) throw( ) +{ + Sequence< ::rtl::OUString > aSNS( 2 ); + aSNS.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.frame.FrameLoader"); + aSNS.getArray()[1] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.ContentLoader"); + return aSNS; +} +// ------------------------------------------------------------------------- +extern "C" void SAL_CALL writeDBLoaderInfo(void* pRegistryKey) +{ + Reference< XRegistryKey> xKey(reinterpret_cast< XRegistryKey*>(pRegistryKey)); + + // register content loader for dispatch + ::rtl::OUString aImpl = ::rtl::OUString::createFromAscii("/"); + aImpl += DBContentLoader::getImplementationName_Static(); + + ::rtl::OUString aImpltwo = aImpl; + aImpltwo += ::rtl::OUString::createFromAscii("/UNO/Loader"); + Reference< XRegistryKey> xNewKey = xKey->createKey( aImpltwo ); + aImpltwo = aImpl; + aImpltwo += ::rtl::OUString::createFromAscii("/Loader"); + Reference< XRegistryKey > xLoaderKey = xKey->createKey( aImpltwo ); + xNewKey = xLoaderKey->createKey( ::rtl::OUString::createFromAscii("Pattern") ); + xNewKey->setAsciiValue( ::rtl::OUString::createFromAscii(".component:DB*") ); +} + +// ----------------------------------------------------------------------- +void SAL_CALL DBContentLoader::load(const Reference< XFrame > & rFrame, const ::rtl::OUString& rURL, + const Sequence< PropertyValue >& rArgs, + const Reference< XLoadEventListener > & rListener) throw(::com::sun::star::uno::RuntimeException) +{ + m_xFrame = rFrame; + m_xListener = rListener; + m_aURL = rURL; + m_aArgs = rArgs; + + ::comphelper::ComponentContext aContext( m_xServiceFactory ); + + struct ServiceNameToImplName + { + const sal_Char* pAsciiServiceName; + const sal_Char* pAsciiImplementationName; + ServiceNameToImplName( const sal_Char* _pService, const sal_Char* _pImpl ) + :pAsciiServiceName( _pService ) + ,pAsciiImplementationName( _pImpl ) + { + } + } aImplementations[] = { + ServiceNameToImplName( URL_COMPONENT_FORMGRIDVIEW, "org.openoffice.comp.dbu.OFormGridView" ), + ServiceNameToImplName( URL_COMPONENT_DATASOURCEBROWSER, "org.openoffice.comp.dbu.ODatasourceBrowser" ), + ServiceNameToImplName( URL_COMPONENT_QUERYDESIGN, "org.openoffice.comp.dbu.OQueryDesign" ), + ServiceNameToImplName( URL_COMPONENT_TABLEDESIGN, "org.openoffice.comp.dbu.OTableDesign" ), + ServiceNameToImplName( URL_COMPONENT_RELATIONDESIGN, "org.openoffice.comp.dbu.ORelationDesign" ), + ServiceNameToImplName( URL_COMPONENT_VIEWDESIGN, "org.openoffice.comp.dbu.OViewDesign" ) + }; + + INetURLObject aParser( rURL ); + Reference< XController2 > xController; + + const ::rtl::OUString sComponentURL( aParser.GetMainURL( INetURLObject::DECODE_TO_IURI ) ); + for ( size_t i=0; i < sizeof( aImplementations ) / sizeof( aImplementations[0] ); ++i ) + { + if ( sComponentURL.equalsAscii( aImplementations[i].pAsciiServiceName ) ) + { + aContext.createComponent( aImplementations[i].pAsciiImplementationName, xController ); + break; + } + } + + // if a data source browser is loaded without its tree pane, then we assume it to be a + // table data view, effectively. In this case, we need to adjust the module identifier. + // 2008-02-05 / i85879 / frank.schoenheit@sun.com + ::comphelper::NamedValueCollection aLoadArgs( rArgs ); + + if ( sComponentURL == URL_COMPONENT_DATASOURCEBROWSER ) + { + sal_Bool bDisableBrowser = ( sal_False == aLoadArgs.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name + || ( sal_False == aLoadArgs.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) ); + + if ( bDisableBrowser ) + { + try + { + Reference< XModule > xModule( xController, UNO_QUERY_THROW ); + xModule->setIdentifier( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TableDataView" ) ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + + if ( sComponentURL == URL_COMPONENT_REPORTDESIGN ) + { + sal_Bool bPreview = aLoadArgs.getOrDefault( "Preview", sal_False ); + if ( bPreview ) + { // report designs cannot be previewed + if ( rListener.is() ) + rListener->loadCancelled( this ); + return; + } + Reference< XModel > xReportModel( aLoadArgs.getOrDefault( "Model", Reference< XModel >() ) ); + if ( xReportModel.is() ) + { + xController.set( m_xServiceFactory->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.ReportDesign" ) ) ), UNO_QUERY ); + if ( xController.is() ) + { + xController->attachModel( xReportModel ); + xReportModel->connectController( xController.get() ); + xReportModel->setCurrentController( xController.get() ); + } + } + } + + sal_Bool bSuccess = xController.is(); + Reference< XModel > xDatabaseDocument; + if ( bSuccess ) + { + Reference< XDataSource > xDataSource ( aLoadArgs.getOrDefault( "DataSource", Reference< XDataSource >() ) ); + ::rtl::OUString sDataSourceName( aLoadArgs.getOrDefault( "DataSourceName", ::rtl::OUString() ) ); + Reference< XConnection > xConnection ( aLoadArgs.getOrDefault( "ActiveConnection", Reference< XConnection >() ) ); + if ( xDataSource.is() ) + { + xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY ); + } + else if ( sDataSourceName.getLength() ) + { + ::dbtools::SQLExceptionInfo aError; + xDataSource.set( getDataSourceByName( sDataSourceName, NULL, m_xServiceFactory, &aError ) ); + xDatabaseDocument.set( getDataSourceOrModel( xDataSource ), UNO_QUERY ); + } + else if ( xConnection.is() ) + { + Reference< XChild > xAsChild( xConnection, UNO_QUERY ); + if ( xAsChild.is() ) + { + OSL_ENSURE( Reference< XDataSource >( xAsChild->getParent(), UNO_QUERY ).is(), + "DBContentLoader::load: a connection whose parent is no data source?" ); + xDatabaseDocument.set( getDataSourceOrModel( xAsChild->getParent() ), UNO_QUERY ); + } + } + + // init controller + ::vos::OGuard aGuard(Application::GetSolarMutex()); + try + { + Reference<XInitialization > xIni(xController,UNO_QUERY); + PropertyValue aFrame(::rtl::OUString::createFromAscii("Frame"),0,makeAny(rFrame),PropertyState_DIRECT_VALUE); + Sequence< Any > aInitArgs(m_aArgs.getLength()+1); + + Any* pBegin = aInitArgs.getArray(); + Any* pEnd = pBegin + aInitArgs.getLength(); + *pBegin <<= aFrame; + const PropertyValue* pIter = m_aArgs.getConstArray(); + for(++pBegin;pBegin != pEnd;++pBegin,++pIter) + { + *pBegin <<= *pIter; + } + + xIni->initialize(aInitArgs); + } + catch(const Exception&) + { + // Does this need to be shown to the user? + bSuccess = false; + try + { + ::comphelper::disposeComponent( xController ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + + // assign controller and frame + if ( bSuccess ) + { + if ( xController.is() && rFrame.is() ) + { + rFrame->setComponent( xController->getComponentWindow(), xController.get() ); + xController->attachFrame(rFrame); + } + + if ( rListener.is() ) + rListener->loadFinished( this ); + } + else + if ( rListener.is() ) + rListener->loadCancelled( this ); +} + +// ----------------------------------------------------------------------- +void DBContentLoader::cancel(void) throw() +{ +} + diff --git a/dbaccess/source/ui/browser/dbtreemodel.cxx b/dbaccess/source/ui/browser/dbtreemodel.cxx new file mode 100644 index 000000000000..0c4942868d20 --- /dev/null +++ b/dbaccess/source/ui/browser/dbtreemodel.cxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef DBAUI_DBTREEMODEL_HXX +#include "dbtreemodel.hxx" +#endif +#ifndef _DBU_RESOURCE_HRC_ +#include "dbu_resource.hrc" +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +namespace dbaui +{ + DBG_NAME(DBTreeListUserData) + //------------------------------------------------------------------------ + DBTreeListUserData::DBTreeListUserData() + :eType(SbaTableQueryBrowser::etQuery) + { + DBG_CTOR(DBTreeListUserData,NULL); + } + //------------------------------------------------------------------------ + DBTreeListUserData::~DBTreeListUserData() + { + DBG_DTOR(DBTreeListUserData,NULL); + } +} diff --git a/dbaccess/source/ui/browser/dbtreemodel.hxx b/dbaccess/source/ui/browser/dbtreemodel.hxx new file mode 100644 index 000000000000..8894f85ce430 --- /dev/null +++ b/dbaccess/source/ui/browser/dbtreemodel.hxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef DBAUI_DBTREEMODEL_HXX +#define DBAUI_DBTREEMODEL_HXX + +#ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ +#include <com/sun/star/container/XNameAccess.hpp> +#endif +#ifndef _SVLBOX_HXX +#include <svtools/svlbox.hxx> +#endif +#ifndef _SVLBOXITM_HXX +#include <svtools/svlbitm.hxx> +#endif +#ifndef _SBA_UNODATBR_HXX_ +#include "unodatbr.hxx" +#endif +#ifndef _DBAUI_COMMON_TYPES_HXX_ +#include "commontypes.hxx" +#endif + +// syntax of the tree userdata +// datasource holds the connection +// queries holds the nameaccess for the queries +// query holds the query +// tables holds the nameaccess for the tables +// table holds the table + +#define CONTAINER_QUERIES ULONG( 0 ) +#define CONTAINER_TABLES ULONG( 1 ) + +namespace com { namespace sun { namespace star { namespace lang { class XMultiServiceFactory; } } } } + +namespace dbaui +{ + struct DBTreeListUserData + { + /// if the entry denotes a table or query, this is the respective UNO object + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > + xObjectProperties; + /// if the entry denotes a object container, this is the UNO interface for this container + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + xContainer; + /// if the entry denotes a data source, this is the connection for this data source (if already connection) + SharedConnection xConnection; + SbaTableQueryBrowser::EntryType eType; + String sAccessor; + + DBTreeListUserData(); + ~DBTreeListUserData(); + }; +} + +#endif // DBAUI_DBTREEMODEL_HXX diff --git a/dbaccess/source/ui/browser/dbtreeview.cxx b/dbaccess/source/ui/browser/dbtreeview.cxx new file mode 100644 index 000000000000..65185f9f3e73 --- /dev/null +++ b/dbaccess/source/ui/browser/dbtreeview.cxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef DBACCESS_UI_DBTREEVIEW_HXX +#include "dbtreeview.hxx" +#endif +#ifndef _SVTREEBOX_HXX +#include <svtools/svtreebx.hxx> +#endif +#ifndef DBAUI_DBTREELISTBOX_HXX +#include "dbtreelistbox.hxx" +#endif +#ifndef DBAUI_DBTREEMODEL_HXX +#include "dbtreemodel.hxx" +#endif +#include "dbaccess_helpid.hrc" + +// ......................................................................... +namespace dbaui +{ +// ......................................................................... + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +DBG_NAME(DBTreeView) +//======================================================================== +// class DBTreeView +//======================================================================== +DBTreeView::DBTreeView( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, WinBits nBits) + : Window( pParent, nBits ) + , m_pTreeListBox(NULL) +{ + DBG_CTOR(DBTreeView,NULL); + + m_pTreeListBox = new DBTreeListBox(this, _rxORB ,WB_HASLINES | WB_SORT | WB_HASBUTTONS | WB_HSCROLL |WB_HASBUTTONSATROOT,sal_True); + m_pTreeListBox->EnableCheckButton(NULL); + m_pTreeListBox->SetDragDropMode( 0 ); + m_pTreeListBox->EnableInplaceEditing( sal_True ); + m_pTreeListBox->SetHelpId(HID_TLB_TREELISTBOX); + m_pTreeListBox->Show(); +} + +// ----------------------------------------------------------------------------- + +DBTreeView::~DBTreeView() +{ + DBG_DTOR(DBTreeView,NULL); + if (m_pTreeListBox) + { + if (m_pTreeListBox->GetModel()) + { + m_pTreeListBox->GetModel()->RemoveView(m_pTreeListBox); + m_pTreeListBox->DisconnectFromModel(); + } + ::std::auto_ptr<Window> aTemp(m_pTreeListBox); + m_pTreeListBox = NULL; + } +} + +// ----------------------------------------------------------------------------- +void DBTreeView::SetPreExpandHandler(const Link& _rHdl) +{ + m_pTreeListBox->SetPreExpandHandler(_rHdl); +} + +// ----------------------------------------------------------------------------- +void DBTreeView::setCopyHandler(const Link& _rHdl) +{ + m_pTreeListBox->setCopyHandler(_rHdl); +} +// ----------------------------------------------------------------------------- +void DBTreeView::Resize() +{ + Window::Resize(); + m_pTreeListBox->SetPosSizePixel(Point(0,0),GetOutputSizePixel()); +} +// ------------------------------------------------------------------------- +void DBTreeView::setModel(SvLBoxTreeList* _pTreeModel) +{ + if (_pTreeModel) + _pTreeModel->InsertView(m_pTreeListBox); + m_pTreeListBox->SetModel(_pTreeModel); +} + +// ------------------------------------------------------------------------- +void DBTreeView::setSelChangeHdl( const Link& _rHdl ) +{ + m_pTreeListBox->SetSelChangeHdl( _rHdl ); +} +// ----------------------------------------------------------------------------- +void DBTreeView::GetFocus() +{ + Window::GetFocus(); + if ( m_pTreeListBox )//&& !m_pTreeListBox->HasChildPathFocus()) + m_pTreeListBox->GrabFocus(); +} + + +// ......................................................................... +} // namespace dbaui +// ......................................................................... + + diff --git a/dbaccess/source/ui/browser/dbtreeview.hxx b/dbaccess/source/ui/browser/dbtreeview.hxx new file mode 100644 index 000000000000..b008a79a4195 --- /dev/null +++ b/dbaccess/source/ui/browser/dbtreeview.hxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef DBACCESS_UI_DBTREEVIEW_HXX +#define DBACCESS_UI_DBTREEVIEW_HXX + +#ifndef _SV_WINDOW_HXX //autogen +#include <vcl/window.hxx> +#endif + +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif + +class SvTreeListBox; +class SvLBoxTreeList; +namespace dbaui +{ + class DBTreeListBox; + // ------------------ + // - DBTreeView - + // ------------------ + + class DBTreeView : public Window + { + private: + DBTreeListBox* m_pTreeListBox; + protected: + // window overridables + virtual void Resize(); + public: + + DBTreeView( Window* pParent, + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxORB, + WinBits nBits ); + ~DBTreeView(); + + /** sets a handler which is called when an list box entry is to be expanded. + <p>When calling the link, the parameter is an SvLBoxEntry marking the entry to be expanded. + </p> + */ + void SetPreExpandHandler(const Link& _rHdl); + /// gets the currently set NodeExpansionHandler + + void setCopyHandler(const Link& _rHdl); + + + void setModel(SvLBoxTreeList* _pTreeModel); + void setSelChangeHdl(const Link& _rHdl); + + DBTreeListBox& getListBox() const { return *m_pTreeListBox; } + + virtual void GetFocus(); + }; +} + +#endif // DBACCESS_UI_DBTREEVIEW_HXX + diff --git a/dbaccess/source/ui/browser/dsEntriesNoExp.cxx b/dbaccess/source/ui/browser/dsEntriesNoExp.cxx new file mode 100644 index 000000000000..5fb5b0f985c6 --- /dev/null +++ b/dbaccess/source/ui/browser/dsEntriesNoExp.cxx @@ -0,0 +1,291 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef _SBA_UNODATBR_HXX_ +#include "unodatbr.hxx" +#endif +#ifndef DBACCESS_UI_BROWSER_ID_HXX +#include "browserids.hxx" +#endif +#ifndef _DBAUI_LISTVIEWITEMS_HXX_ +#include "listviewitems.hxx" +#endif +#ifndef DBACCESS_IMAGEPROVIDER_HXX +#include "imageprovider.hxx" +#endif +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif +#ifndef DBACCESS_UI_DBTREEVIEW_HXX +#include "dbtreeview.hxx" +#endif +#ifndef DBAUI_DBTREELISTBOX_HXX +#include "dbtreelistbox.hxx" +#endif +#ifndef _DBU_BRW_HRC_ +#include "dbu_brw.hrc" +#endif +#ifndef DBAUI_DBTREEMODEL_HXX +#include "dbtreemodel.hxx" +#endif + +using namespace ::com::sun::star::frame; +using namespace ::dbtools; +using namespace ::svx; + +// ......................................................................... +namespace dbaui +{ +// ......................................................................... +// ----------------------------------------------------------------------------- +SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getChildType( SvLBoxEntry* _pEntry ) const +{ + DBG_ASSERT(isContainer(_pEntry), "SbaTableQueryBrowser::getChildType: invalid entry!"); + switch (getEntryType(_pEntry)) + { + case etTableContainer: + return etTableOrView; + case etQueryContainer: + return etQuery; + default: + break; + } + return etUnknown; +} + +// ----------------------------------------------------------------------------- +String SbaTableQueryBrowser::GetEntryText( SvLBoxEntry* _pEntry ) const +{ + return m_pTreeView->getListBox().GetEntryText(_pEntry); +} + +// ----------------------------------------------------------------------------- +SbaTableQueryBrowser::EntryType SbaTableQueryBrowser::getEntryType( SvLBoxEntry* _pEntry ) const +{ + if (!_pEntry) + return etUnknown; + + SvLBoxEntry* pRootEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry); + SvLBoxEntry* pEntryParent = m_pTreeView->getListBox().GetParent(_pEntry); + SvLBoxEntry* pTables = m_pTreeView->getListBox().GetEntry(pRootEntry, CONTAINER_TABLES); + SvLBoxEntry* pQueries = m_pTreeView->getListBox().GetEntry(pRootEntry, CONTAINER_QUERIES); + +#ifdef DBG_UTIL + String sTest; + if (pTables) sTest = m_pTreeView->getListBox().GetEntryText(pTables); + if (pQueries) sTest = m_pTreeView->getListBox().GetEntryText(pQueries); +#endif + + if (pRootEntry == _pEntry) + return etDatasource; + + if (pTables == _pEntry) + return etTableContainer; + + if (pQueries == _pEntry) + return etQueryContainer; + + if (pTables == pEntryParent) + return etTableOrView; + + if (pQueries == pEntryParent) + { + DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData()); + if ( pEntryData ) + return pEntryData->eType; + + return etQuery; + } + while( pEntryParent != pQueries ) + { + pEntryParent = m_pTreeView->getListBox().GetParent(pEntryParent); + if ( !pEntryParent ) + return etUnknown; + } + + return etQueryContainer; +} +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::select(SvLBoxEntry* _pEntry, sal_Bool _bSelect) +{ + SvLBoxItem* pTextItem = _pEntry ? _pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING) : NULL; + if (pTextItem) + { + static_cast<OBoldListboxString*>(pTextItem)->emphasize(_bSelect); + m_pTreeModel->InvalidateEntry(_pEntry); + } + else { + DBG_ERROR("SbaTableQueryBrowser::select: invalid entry!"); + } +} + +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::selectPath(SvLBoxEntry* _pEntry, sal_Bool _bSelect) +{ + while (_pEntry) + { + select(_pEntry, _bSelect); + _pEntry = m_pTreeModel->GetParent(_pEntry); + } +} +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::isSelected(SvLBoxEntry* _pEntry) const +{ + SvLBoxItem* pTextItem = _pEntry ? _pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING) : NULL; + if (pTextItem) + return static_cast<OBoldListboxString*>(pTextItem)->isEmphasized(); + else { + DBG_ERROR("SbaTableQueryBrowser::isSelected: invalid entry!"); + } + return sal_False; +} +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::SelectionChanged() +{ + if ( !m_bShowMenu ) + { + InvalidateFeature(ID_BROWSER_INSERTCOLUMNS); + InvalidateFeature(ID_BROWSER_INSERTCONTENT); + InvalidateFeature(ID_BROWSER_FORMLETTER); + } // if ( !m_bShowMenu ) + InvalidateFeature(ID_BROWSER_COPY); + InvalidateFeature(ID_BROWSER_CUT); +} +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::describeSupportedFeatures() +{ + SbaXDataBrowserController::describeSupportedFeatures(); + + implDescribeSupportedFeature( ".uno:Title", ID_BROWSER_TITLE ); + if ( !m_bShowMenu ) + { + implDescribeSupportedFeature( ".uno:DSBrowserExplorer", ID_BROWSER_EXPLORER, CommandGroup::VIEW ); + + implDescribeSupportedFeature( ".uno:DSBFormLetter", ID_BROWSER_FORMLETTER, CommandGroup::DOCUMENT ); + implDescribeSupportedFeature( ".uno:DSBInsertColumns", ID_BROWSER_INSERTCOLUMNS, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:DSBInsertContent", ID_BROWSER_INSERTCONTENT, CommandGroup::INSERT ); + implDescribeSupportedFeature( ".uno:DSBDocumentDataSource", ID_BROWSER_DOCUMENT_DATASOURCE, CommandGroup::VIEW ); + + implDescribeSupportedFeature( ".uno:DataSourceBrowser/FormLetter", ID_BROWSER_FORMLETTER ); + implDescribeSupportedFeature( ".uno:DataSourceBrowser/InsertColumns", ID_BROWSER_INSERTCOLUMNS ); + implDescribeSupportedFeature( ".uno:DataSourceBrowser/InsertContent", ID_BROWSER_INSERTCONTENT ); + implDescribeSupportedFeature( ".uno:DataSourceBrowser/DocumentDataSource", ID_BROWSER_DOCUMENT_DATASOURCE ); + } + + implDescribeSupportedFeature( ".uno:CloseWin", ID_BROWSER_CLOSE, CommandGroup::DOCUMENT ); + implDescribeSupportedFeature( ".uno:DBRebuildData", ID_BROWSER_REFRESH_REBUILD, CommandGroup::DATA ); +} + +// ----------------------------------------------------------------------------- +sal_Int32 SbaTableQueryBrowser::getDatabaseObjectType( EntryType _eType ) +{ + switch ( _eType ) + { + case etQuery: + case etQueryContainer: + return DatabaseObject::QUERY; + case etTableOrView: + case etTableContainer: + return DatabaseObject::TABLE; + default: + break; + } + OSL_ENSURE( false, "SbaTableQueryBrowser::getDatabaseObjectType: folder types and 'Unknown' not allowed here!" ); + return DatabaseObject::TABLE; +} + +// ----------------------------------------------------------------------------- +void SbaTableQueryBrowser::notifyHiContrastChanged() +{ + if ( m_pTreeView ) + { + // change all bitmap entries + SvLBoxEntry* pEntryLoop = m_pTreeModel->First(); + while ( pEntryLoop ) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pEntryLoop->GetUserData()); + if ( !pData ) + { + pEntryLoop = m_pTreeModel->Next(pEntryLoop); + continue; + } + + // the connection to which this entry belongs, if any + ::std::auto_ptr< ImageProvider > pImageProvider( getImageProviderFor( pEntryLoop ) ); + + // the images for this entry + Image aImage, aImageHC; + if ( pData->eType == etDatasource ) + { + aImage = pImageProvider->getDatabaseImage( false ); + aImageHC = pImageProvider->getDatabaseImage( true ); + } + else + { + bool bIsFolder = !isObject( pData->eType ); + if ( bIsFolder ) + { + sal_Int32 nObjectType( getDatabaseObjectType( pData->eType ) ); + aImage = pImageProvider->getFolderImage( nObjectType, false ); + aImageHC = pImageProvider->getFolderImage( nObjectType, true ); + } + else + { + sal_Int32 nObjectType( getDatabaseObjectType( pData->eType ) ); + pImageProvider->getImages( GetEntryText( pEntryLoop ), nObjectType, aImage, aImageHC ); + } + } + + // find the proper item, and set its icons + USHORT nCount = pEntryLoop->ItemCount(); + for (USHORT i=0;i<nCount;++i) + { + SvLBoxItem* pItem = pEntryLoop->GetItem(i); + if ( !pItem || ( pItem->IsA() != SV_ITEM_ID_LBOXCONTEXTBMP ) ) + continue; + + SvLBoxContextBmp* pContextBitmapItem = static_cast< SvLBoxContextBmp* >( pItem ); + + pContextBitmapItem->SetBitmap1( aImage, BMP_COLOR_NORMAL ); + pContextBitmapItem->SetBitmap2( aImage, BMP_COLOR_NORMAL ); + pContextBitmapItem->SetBitmap1( aImageHC, BMP_COLOR_HIGHCONTRAST ); + pContextBitmapItem->SetBitmap2( aImageHC, BMP_COLOR_HIGHCONTRAST ); + break; + } + + pEntryLoop = m_pTreeModel->Next(pEntryLoop); + } + } +} +// ----------------------------------------------------------------------------- +// ......................................................................... +} // namespace dbaui +// ......................................................................... + diff --git a/dbaccess/source/ui/browser/dsbrowserDnD.cxx b/dbaccess/source/ui/browser/dsbrowserDnD.cxx new file mode 100644 index 000000000000..093bd2f35854 --- /dev/null +++ b/dbaccess/source/ui/browser/dsbrowserDnD.cxx @@ -0,0 +1,295 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#include "dbexchange.hxx" +#include "dbtreelistbox.hxx" +#include "dbtreemodel.hxx" +#include "dbtreeview.hxx" +#include "dbu_brw.hrc" +#include "dbustrings.hrc" +#include "QEnumTypes.hxx" +#include "UITools.hxx" +#include "unodatbr.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/frame/XStorable.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdbc/XConnection.hpp> +/** === end UNO includes === **/ + +#include <connectivity/dbexception.hxx> +#include <connectivity/dbtools.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <svtools/treelist.hxx> +#include <svx/dataaccessdescriptor.hxx> +#include <tools/diagnose_ex.h> + +#include <functional> +// ......................................................................... +namespace dbaui +{ +// ......................................................................... + + using namespace ::com::sun::star::uno; + using namespace ::com::sun::star::sdb; + using namespace ::com::sun::star::sdbc; + using namespace ::com::sun::star::sdbcx; + using namespace ::com::sun::star::beans; + using namespace ::com::sun::star::util; + using namespace ::com::sun::star::frame; + using namespace ::com::sun::star::container; + using namespace ::com::sun::star::lang; + using namespace ::com::sun::star::form; + using namespace ::com::sun::star::io; + using namespace ::com::sun::star::i18n; + using namespace ::com::sun::star::task; + using namespace ::com::sun::star::datatransfer; + using namespace ::dbtools; + using namespace ::svx; + + // ----------------------------------------------------------------------------- + TransferableHelper* SbaTableQueryBrowser::implCopyObject( SvLBoxEntry* _pApplyTo, sal_Int32 _nCommandType, sal_Bool _bAllowConnection ) + { + try + { + ::rtl::OUString aName = GetEntryText( _pApplyTo ); + ::rtl::OUString aDSName = getDataSourceAcessor( m_pTreeView->getListBox().GetRootLevelParent( _pApplyTo ) ); + + ODataClipboard* pData = NULL; + SharedConnection xConnection; + if ( CommandType::QUERY != _nCommandType ) + { + if ( _bAllowConnection && !ensureConnection( _pApplyTo, xConnection) ) + return NULL; + pData = new ODataClipboard(aDSName, _nCommandType, aName, xConnection, getNumberFormatter(), getORB()); + } + else + pData = new ODataClipboard(aDSName, _nCommandType, aName, getNumberFormatter(), getORB()); + + // the owner ship goes to ODataClipboards + return pData; + } + catch(const SQLException& ) + { + showError( SQLExceptionInfo( ::cppu::getCaughtException() ) ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return NULL; + } + // ----------------------------------------------------------------------------- + sal_Int8 SbaTableQueryBrowser::queryDrop( const AcceptDropEvent& _rEvt, const DataFlavorExVector& _rFlavors ) + { + // check if we're a table or query container + SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel ); + + if ( pHitEntry ) // no drop if no entry was hit .... + { + // it must be a container + EntryType eEntryType = getEntryType( pHitEntry ); + SharedConnection xConnection; + if ( eEntryType == etTableContainer && ensureConnection( pHitEntry, xConnection ) && xConnection.is() ) + { + Reference<XChild> xChild(xConnection,UNO_QUERY); + Reference<XStorable> xStore(xChild.is() ? getDataSourceOrModel(xChild->getParent()) : Reference<XInterface>(),UNO_QUERY); + // check for the concrete type + if ( xStore.is() && !xStore->isReadonly() && ::std::find_if(_rFlavors.begin(),_rFlavors.end(),TAppSupportedSotFunctor(E_TABLE,sal_True)) != _rFlavors.end()) + return DND_ACTION_COPY; + } + } + + return DND_ACTION_NONE; + } + // ----------------------------------------------------------------------------- + sal_Int8 SbaTableQueryBrowser::executeDrop( const ExecuteDropEvent& _rEvt ) + { + SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rEvt.maPosPixel ); + EntryType eEntryType = getEntryType( pHitEntry ); + if (!isContainer(eEntryType)) + { + DBG_ERROR("SbaTableQueryBrowser::executeDrop: what the hell did queryDrop do?"); + // queryDrop shoud not have allowed us to reach this situation .... + return DND_ACTION_NONE; + } + // a TransferableDataHelper for accessing the dropped data + TransferableDataHelper aDroppedData(_rEvt.maDropEvent.Transferable); + + + // reset the data of the previous async drop (if any) + if ( m_nAsyncDrop ) + Application::RemoveUserEvent(m_nAsyncDrop); + + + m_nAsyncDrop = 0; + m_aAsyncDrop.aDroppedData.clear(); + m_aAsyncDrop.nType = E_TABLE; + m_aAsyncDrop.nAction = _rEvt.mnAction; + m_aAsyncDrop.bError = sal_False; + m_aAsyncDrop.bHtml = sal_False; + m_aAsyncDrop.pDroppedAt = NULL; + m_aAsyncDrop.aUrl = ::rtl::OUString(); + + + // loop through the available formats and see what we can do ... + // first we have to check if it is our own format, if not we have to copy the stream :-( + if ( ODataAccessObjectTransferable::canExtractObjectDescriptor(aDroppedData.GetDataFlavorExVector()) ) + { + m_aAsyncDrop.aDroppedData = ODataAccessObjectTransferable::extractObjectDescriptor(aDroppedData); + m_aAsyncDrop.pDroppedAt = pHitEntry; + + // asyncron because we some dialogs and we aren't allowed to show them while in D&D + m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop)); + return DND_ACTION_COPY; + } + else + { + SharedConnection xDestConnection; + if ( ensureConnection( pHitEntry, xDestConnection ) + && xDestConnection.is() + && m_aTableCopyHelper.copyTagTable( aDroppedData, m_aAsyncDrop, xDestConnection ) + ) + { + m_aAsyncDrop.pDroppedAt = pHitEntry; + + // asyncron because we some dialogs and we aren't allowed to show them while in D&D + m_nAsyncDrop = Application::PostUserEvent(LINK(this, SbaTableQueryBrowser, OnAsyncDrop)); + return DND_ACTION_COPY; + } + } + + return DND_ACTION_NONE; + } + + // ----------------------------------------------------------------------------- + sal_Bool SbaTableQueryBrowser::requestDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel ) + { + // get the affected list entry + // ensure that the entry which the user clicked at is selected + SvLBoxEntry* pHitEntry = m_pTreeView->getListBox().GetEntry( _rPosPixel ); + if (!pHitEntry) + // no drag of no entry was hit .... + return sal_False; + + // it must be a query/table + EntryType eEntryType = getEntryType( pHitEntry ); + if (!isObject(eEntryType)) + return DND_ACTION_NONE; + + TransferableHelper* pTransfer = implCopyObject( pHitEntry, ( etTableOrView == eEntryType ) ? CommandType::TABLE : CommandType::QUERY); + Reference< XTransferable> xEnsureDelete = pTransfer; + + if (pTransfer) + pTransfer->StartDrag( &m_pTreeView->getListBox(), DND_ACTION_COPY ); + + return NULL != pTransfer; + } + // ----------------------------------------------------------------------------- + IMPL_LINK(SbaTableQueryBrowser, OnCopyEntry, void*, /*NOTINTERESIN*/) + { + SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected(); + if( isEntryCopyAllowed( pSelected ) ) + copyEntry( pSelected ); + return 0; + } + // ----------------------------------------------------------------------------- + sal_Bool SbaTableQueryBrowser::isEntryCopyAllowed(SvLBoxEntry* _pEntry) const + { + EntryType eType = getEntryType(_pEntry); + return ( eType == etTableOrView || eType == etQuery ); + } + // ----------------------------------------------------------------------------- + void SbaTableQueryBrowser::copyEntry(SvLBoxEntry* _pEntry) + { + TransferableHelper* pTransfer = NULL; + Reference< XTransferable> aEnsureDelete; + EntryType eType = getEntryType(_pEntry); + pTransfer = implCopyObject( _pEntry, eType == etQuery ? CommandType::QUERY : CommandType::TABLE); + aEnsureDelete = pTransfer; + if (pTransfer) + pTransfer->CopyToClipboard(getView()); + } + // ----------------------------------------------------------------------------- + IMPL_LINK( SbaTableQueryBrowser, OnAsyncDrop, void*, /*NOTINTERESTEDIN*/ ) + { + m_nAsyncDrop = 0; + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( getMutex() ); + + if ( m_aAsyncDrop.nType == E_TABLE ) + { + SharedConnection xDestConnection; + if ( ensureConnection( m_aAsyncDrop.pDroppedAt, xDestConnection ) && xDestConnection.is() ) + { + SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(m_aAsyncDrop.pDroppedAt); + m_aTableCopyHelper.asyncCopyTagTable( m_aAsyncDrop, getDataSourceAcessor( pDataSourceEntry ), xDestConnection ); + } + } + + m_aAsyncDrop.aDroppedData.clear(); + + return 0L; + } + // ----------------------------------------------------------------------------- + void SbaTableQueryBrowser::clearTreeModel() + { + if (m_pTreeModel) + { + // clear the user data of the tree model + SvLBoxEntry* pEntryLoop = m_pTreeModel->First(); + while (pEntryLoop) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pEntryLoop->GetUserData()); + if(pData) + { + pEntryLoop->SetUserData(NULL); + Reference< XContainer > xContainer(pData->xContainer, UNO_QUERY); + if (xContainer.is()) + xContainer->removeContainerListener(this); + + if ( pData->xConnection.is() ) + { + DBG_ASSERT( impl_isDataSourceEntry( pEntryLoop ), "SbaTableQueryBrowser::clearTreeModel: no data source entry, but a connection?" ); + // connections are to be stored *only* at the data source entries + impl_releaseConnection( pData->xConnection ); + } + + delete pData; + } + pEntryLoop = m_pTreeModel->Next(pEntryLoop); + } + } + m_pCurrentlyDisplayed = NULL; + } +// ......................................................................... +} // namespace dbaui +// ......................................................................... + diff --git a/dbaccess/source/ui/browser/exsrcbrw.cxx b/dbaccess/source/ui/browser/exsrcbrw.cxx new file mode 100644 index 000000000000..41200c7625ec --- /dev/null +++ b/dbaccess/source/ui/browser/exsrcbrw.cxx @@ -0,0 +1,500 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef _SBA_EXTCTRLR_HXX +#include "exsrcbrw.hxx" +#endif +#ifndef _COM_SUN_STAR_FORM_FORMCOMPONENTTYPE_HPP_ +#include <com/sun/star/form/FormComponentType.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_XURLTRANSFORMER_HPP_ +#include <com/sun/star/util/XURLTransformer.hpp> +#endif +#ifndef _COM_SUN_STAR_FORM_XGRIDCOLUMNFACTORY_HPP_ +#include <com/sun/star/form/XGridColumnFactory.hpp> +#endif +#ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_ +#include <com/sun/star/form/XLoadable.hpp> +#endif +#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_ +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#endif +#ifndef _SBA_FORMADAPTER_HXX +#include "formadapter.hxx" +#endif +#ifndef _COMPHELPER_PROCESSFACTORY_HXX_ +#include <comphelper/processfactory.hxx> +#endif +#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC +#include "dbustrings.hrc" +#endif +#ifndef _DBU_REGHELPER_HXX_ +#include "dbu_reghelper.hxx" +#endif +#ifndef TOOLS_DIAGNOSE_EX_H +#include <tools/diagnose_ex.h> +#endif + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::frame; +using namespace dbaui; + +//============================================================================== +//= SbaExternalSourceBrowser +//============================================================================== +extern "C" void SAL_CALL createRegistryInfo_OFormGridView() +{ + static OMultiInstanceAutoRegistration< SbaExternalSourceBrowser > aAutoRegistration; +} +//------------------------------------------------------------------------------ +Any SAL_CALL SbaExternalSourceBrowser::queryInterface(const Type& _rType) throw (RuntimeException) +{ + Any aRet = SbaXDataBrowserController::queryInterface(_rType); + if(!aRet.hasValue()) + aRet = ::cppu::queryInterface(_rType, + (::com::sun::star::util::XModifyBroadcaster*)this, + (::com::sun::star::form::XLoadListener*)this); + + return aRet; +} +DBG_NAME(SbaExternalSourceBrowser) +//------------------------------------------------------------------------------ +SbaExternalSourceBrowser::SbaExternalSourceBrowser(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rM) + :SbaXDataBrowserController(_rM) + ,m_aModifyListeners(getMutex()) + ,m_pDataSourceImpl(NULL) + ,m_bInQueryDispatch( sal_False ) +{ + DBG_CTOR(SbaExternalSourceBrowser,NULL); + +} + +//------------------------------------------------------------------------------ +SbaExternalSourceBrowser::~SbaExternalSourceBrowser() +{ + + DBG_DTOR(SbaExternalSourceBrowser,NULL); +} + +//------------------------------------------------------------------------- +::comphelper::StringSequence SAL_CALL SbaExternalSourceBrowser::getSupportedServiceNames() throw(RuntimeException) +{ + return getSupportedServiceNames_Static(); +} +// ------------------------------------------------------------------------- +::rtl::OUString SbaExternalSourceBrowser::getImplementationName_Static() throw(RuntimeException) +{ + return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.comp.dbu.OFormGridView")); +} +//------------------------------------------------------------------------- +::comphelper::StringSequence SbaExternalSourceBrowser::getSupportedServiceNames_Static() throw(RuntimeException) +{ + ::comphelper::StringSequence aSupported(1); + aSupported.getArray()[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sdb.FormGridView")); + return aSupported; +} +//------------------------------------------------------------------------- +Reference< XInterface > SAL_CALL SbaExternalSourceBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory) +{ + return *(new SbaExternalSourceBrowser(_rxFactory)); +} +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL SbaExternalSourceBrowser::getImplementationName() throw(RuntimeException) +{ + return getImplementationName_Static(); +} +//------------------------------------------------------------------------------ +Reference< XRowSet > SbaExternalSourceBrowser::CreateForm() +{ + m_pDataSourceImpl = new SbaXFormAdapter(); + return m_pDataSourceImpl; +} + +//------------------------------------------------------------------------------ +sal_Bool SbaExternalSourceBrowser::InitializeForm(const Reference< XRowSet > & /*xForm*/) +{ + return sal_True; +} + +//------------------------------------------------------------------ +sal_Bool SbaExternalSourceBrowser::LoadForm() +{ + // as we don't have a main form (yet), we have nothing to do + // we don't call FormLoaded, because this expects a working data source + return sal_True; +} + + +//------------------------------------------------------------------ +void SbaExternalSourceBrowser::modified(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException ) +{ + SbaXDataBrowserController::modified(aEvent); + + // multiplex this event to all my listeners + ::com::sun::star::lang::EventObject aEvt(*this); + ::cppu::OInterfaceIteratorHelper aIt(m_aModifyListeners); + while (aIt.hasMoreElements()) + ((::com::sun::star::util::XModifyListener*)aIt.next())->modified(aEvt); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaExternalSourceBrowser::dispatch(const ::com::sun::star::util::URL& aURL, const Sequence< ::com::sun::star::beans::PropertyValue>& aArgs) throw(::com::sun::star::uno::RuntimeException) +{ + const ::com::sun::star::beans::PropertyValue* pArguments = aArgs.getConstArray(); + if (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AddGridColumn"))) + { + // search the argument describing the column to create + ::rtl::OUString sControlType; + sal_Int32 nControlPos = -1; + Sequence< ::com::sun::star::beans::PropertyValue> aControlProps; + sal_uInt16 i; + for ( i = 0; i < aArgs.getLength(); ++i, ++pArguments ) + { + if (pArguments->Name.equals(::rtl::OUString::createFromAscii("ColumnType"))) + { + sal_Bool bCorrectType = pArguments->Value.getValueType().equals(::getCppuType((const ::rtl::OUString*)0)); + OSL_ENSURE(bCorrectType, "invalid type for argument \"ColumnType\" !"); + if (bCorrectType) + sControlType = ::comphelper::getString(pArguments->Value); + } + else if (pArguments->Name.equals(::rtl::OUString::createFromAscii("ColumnPosition"))) + { + sal_Bool bCorrectType = pArguments->Value.getValueType().equals(::getCppuType((const sal_Int16*)0)); + OSL_ENSURE(bCorrectType, "invalid type for argument \"ColumnPosition\" !"); + if (bCorrectType) + nControlPos = ::comphelper::getINT16(pArguments->Value); + } + else if (pArguments->Name.equals(::rtl::OUString::createFromAscii("ColumnProperties"))) + { + sal_Bool bCorrectType = pArguments->Value.getValueType().equals(::getCppuType((const Sequence< ::com::sun::star::beans::PropertyValue>*)0)); + OSL_ENSURE(bCorrectType, "invalid type for argument \"ColumnProperties\" !"); + if (bCorrectType) + aControlProps = *(Sequence< ::com::sun::star::beans::PropertyValue>*)pArguments->Value.getValue(); + } + else + OSL_ENSURE(sal_False, ((ByteString("SbaExternalSourceBrowser::dispatch(AddGridColumn) : unknown argument (") += ByteString((const sal_Unicode*)pArguments->Name, gsl_getSystemTextEncoding()).GetBuffer()) += ") !").GetBuffer()); + } + if (!sControlType.getLength()) + { + OSL_ENSURE(sal_False, "SbaExternalSourceBrowser::dispatch(AddGridColumn) : missing argument (ColumnType) !"); + sControlType = ::rtl::OUString::createFromAscii("TextField"); + } + OSL_ENSURE(aControlProps.getLength(), "SbaExternalSourceBrowser::dispatch(AddGridColumn) : missing argument (ColumnProperties) !"); + + // create the col + Reference< ::com::sun::star::form::XGridColumnFactory > xColFactory(getControlModel(), UNO_QUERY); + Reference< ::com::sun::star::beans::XPropertySet > xNewCol = xColFactory->createColumn(sControlType); + Reference< XPropertySetInfo > xNewColProperties; + if (xNewCol.is()) + xNewColProperties = xNewCol->getPropertySetInfo(); + // set it's properties + if (xNewColProperties.is()) + { + const ::com::sun::star::beans::PropertyValue* pControlProps = aControlProps.getConstArray(); + for (i=0; i<aControlProps.getLength(); ++i, ++pControlProps) + { + try + { + if (xNewColProperties->hasPropertyByName(pControlProps->Name)) + xNewCol->setPropertyValue(pControlProps->Name, pControlProps->Value); + } + catch(Exception&) + { + OSL_ENSURE(sal_False, + ( ByteString("SbaExternalSourceBrowser::dispatch : could not set a column property (") + += ByteString(pControlProps->Name.getStr(), (sal_uInt16)pControlProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US) + += ByteString(")!")).GetBuffer()); + } + } + } + + // correct the position + Reference< ::com::sun::star::container::XIndexContainer > xColContainer(getControlModel(), UNO_QUERY); + + if (nControlPos > xColContainer->getCount()) + nControlPos = xColContainer->getCount(); + if (nControlPos < 0) + nControlPos = 0; + + // append the column + xColContainer->insertByIndex(nControlPos, makeAny(xNewCol)); + } + else if (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/ClearView"))) + { + ClearView(); + } + else if (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AttachToForm"))) + { + if (!m_pDataSourceImpl) + return; + + Reference< XRowSet > xMasterForm; + // search the arguments for he master form + for (sal_uInt16 i=0; i<aArgs.getLength(); ++i, ++pArguments) + { + if ((pArguments->Name.equals(::rtl::OUString::createFromAscii("MasterForm"))) && (pArguments->Value.getValueTypeClass() == TypeClass_INTERFACE)) + { + xMasterForm = Reference< XRowSet > (*(Reference< XInterface > *)pArguments->Value.getValue(), UNO_QUERY); + break; + } + } + if (!xMasterForm.is()) + { + OSL_ENSURE(sal_False, "SbaExternalSourceBrowser::dispatch(FormSlots/AttachToForm) : please specify a form to attach to as argument !"); + return; + } + + Attach(xMasterForm); + } + else + SbaXDataBrowserController::dispatch(aURL, aArgs); +} + +//------------------------------------------------------------------ +Reference< ::com::sun::star::frame::XDispatch > SAL_CALL SbaExternalSourceBrowser::queryDispatch(const ::com::sun::star::util::URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException ) +{ + Reference< ::com::sun::star::frame::XDispatch > xReturn; + if (m_bInQueryDispatch) + return xReturn; + + m_bInQueryDispatch = sal_True; + + if ( (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AttachToForm"))) + // attach a new external form + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/AddGridColumn"))) + // add a column to the grid + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/ClearView"))) + // clear the grid + ) + xReturn = (::com::sun::star::frame::XDispatch*)this; + + if ( !xReturn.is() + && ( (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToFirst"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToPrev"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToNext"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToLast"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/moveToNew"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:FormSlots/undoRecord"))) + ) + ) + { + OSL_ENSURE(aURL.Mark.getLength() == 0, "SbaExternalSourceBrowser::queryDispatch : the ::com::sun::star::util::URL shouldn't have a mark !"); + ::com::sun::star::util::URL aNewUrl = aURL; + + // split the ::com::sun::star::util::URL + OSL_ENSURE( m_xUrlTransformer.is(), "SbaExternalSourceBrowser::queryDispatch : could not create an URLTransformer !" ); + if ( m_xUrlTransformer.is() ) + m_xUrlTransformer->parseStrict( aNewUrl ); + + // set a new mark + aNewUrl.Mark = ::rtl::OUString::createFromAscii("DB/FormGridView"); + // this controller is instantiated when somebody dispatches the ".component:DB/FormGridView" in any + // frame, so we use "FormGridView" as mark that a dispatch request came from this view + + if (m_xUrlTransformer.is()) + m_xUrlTransformer->assemble(aNewUrl); + + Reference< XDispatchProvider > xFrameDispatcher( getFrame(), UNO_QUERY ); + if (xFrameDispatcher.is()) + xReturn = xFrameDispatcher->queryDispatch(aNewUrl, aTargetFrameName, FrameSearchFlag::PARENT); + + } + + if (!xReturn.is()) + xReturn = SbaXDataBrowserController::queryDispatch(aURL, aTargetFrameName, nSearchFlags); + + m_bInQueryDispatch = sal_False; + return xReturn; +} + +//------------------------------------------------------------------ +void SAL_CALL SbaExternalSourceBrowser::disposing() +{ + // say our modify listeners goodbye + ::com::sun::star::lang::EventObject aEvt; + aEvt.Source = (XWeak*) this; + m_aModifyListeners.disposeAndClear(aEvt); + + stopListening(); + + SbaXDataBrowserController::disposing(); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaExternalSourceBrowser::addModifyListener(const Reference< ::com::sun::star::util::XModifyListener > & aListener) throw( RuntimeException ) +{ + m_aModifyListeners.addInterface(aListener); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaExternalSourceBrowser::removeModifyListener(const Reference< ::com::sun::star::util::XModifyListener > & aListener) throw( RuntimeException ) +{ + m_aModifyListeners.removeInterface(aListener); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaExternalSourceBrowser::unloading(const ::com::sun::star::lang::EventObject& aEvent) throw( RuntimeException ) +{ + if (m_pDataSourceImpl && (m_pDataSourceImpl->getAttachedForm() == aEvent.Source)) + { + ClearView(); + } + + SbaXDataBrowserController::unloading(aEvent); +} + +//------------------------------------------------------------------ +void SbaExternalSourceBrowser::Attach(const Reference< XRowSet > & xMaster) +{ + Any aOldPos; + sal_Bool bWasInsertRow = sal_False; + sal_Bool bBeforeFirst = sal_True; + sal_Bool bAfterLast = sal_True; + Reference< XResultSet > xResultSet(xMaster, UNO_QUERY); + Reference< XRowLocate > xCursor(xMaster, UNO_QUERY); + Reference< XPropertySet > xMasterProps(xMaster, UNO_QUERY); + + try + { + // switch the control to design mode + if (getBrowserView() && getBrowserView()->getGridControl().is()) + getBrowserView()->getGridControl()->setDesignMode(sal_True); + + // the grid will move the form's cursor to the first record, but we want the form to remain unchanged + // restore the old position + if (xCursor.is() && xResultSet.is()) + { + bBeforeFirst = xResultSet->isBeforeFirst(); + bAfterLast = xResultSet->isAfterLast(); + if(!bBeforeFirst && !bAfterLast) + aOldPos = xCursor->getBookmark(); + } + + if (xMasterProps.is()) + xMasterProps->getPropertyValue(PROPERTY_ISNEW) >>= bWasInsertRow; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + onStartLoading( Reference< XLoadable >( xMaster, UNO_QUERY ) ); + + stopListening(); + m_pDataSourceImpl->AttachForm(xMaster); + startListening(); + + if (xMaster.is()) + { + // at this point we have to reset the formatter for the new form + initFormatter(); + // assume that the master form is already loaded +#if OSL_DEBUG_LEVEL > 0 + { + Reference< XLoadable > xLoadable( xMaster, UNO_QUERY ); + OSL_ENSURE( xLoadable.is() && xLoadable->isLoaded(), "SbaExternalSourceBrowser::Attach: master is not loaded!" ); + } +#endif + + LoadFinished(sal_True); + + Reference< XResultSetUpdate > xUpdate(xMaster, UNO_QUERY); + try + { + if (bWasInsertRow && xUpdate.is()) + xUpdate->moveToInsertRow(); + else if (xCursor.is() && aOldPos.hasValue()) + xCursor->moveToBookmark(aOldPos); + else if(bBeforeFirst && xResultSet.is()) + xResultSet->beforeFirst(); + else if(bAfterLast && xResultSet.is()) + xResultSet->afterLast(); + } + catch(Exception&) + { + OSL_ENSURE(sal_False, "SbaExternalSourceBrowser::Attach : couldn't restore the cursor position !"); + } + + } +} + +//------------------------------------------------------------------ +void SbaExternalSourceBrowser::ClearView() +{ + // set a new (empty) datasource + Attach(Reference< XRowSet > ()); + + + // clear all cols in the grid + Reference< ::com::sun::star::container::XIndexContainer > xColContainer(getControlModel(), UNO_QUERY); + while (xColContainer->getCount() > 0) + xColContainer->removeByIndex(0); +} + +//------------------------------------------------------------------ +void SAL_CALL SbaExternalSourceBrowser::disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException ) +{ + if (m_pDataSourceImpl && (m_pDataSourceImpl->getAttachedForm() == Source.Source)) + { + ClearView(); + } + + SbaXDataBrowserController::disposing(Source); +} + +//------------------------------------------------------------------ +void SbaExternalSourceBrowser::startListening() +{ + if (m_pDataSourceImpl && m_pDataSourceImpl->getAttachedForm().is()) + { + Reference< ::com::sun::star::form::XLoadable > xLoadable(m_pDataSourceImpl->getAttachedForm(), UNO_QUERY); + xLoadable->addLoadListener((::com::sun::star::form::XLoadListener*)this); + } +} + +//------------------------------------------------------------------ +void SbaExternalSourceBrowser::stopListening() +{ + if (m_pDataSourceImpl && m_pDataSourceImpl->getAttachedForm().is()) + { + Reference< ::com::sun::star::form::XLoadable > xLoadable(m_pDataSourceImpl->getAttachedForm(), UNO_QUERY); + xLoadable->removeLoadListener((::com::sun::star::form::XLoadListener*)this); + } +} + +//================================================================== +//================================================================== diff --git a/dbaccess/source/ui/browser/formadapter.cxx b/dbaccess/source/ui/browser/formadapter.cxx new file mode 100644 index 000000000000..2c0f5b978425 --- /dev/null +++ b/dbaccess/source/ui/browser/formadapter.cxx @@ -0,0 +1,1794 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef _SBA_FORMADAPTER_HXX +#include "formadapter.hxx" +#endif +#ifndef _TOOLS_DEBUG_HXX //autogen +#include <tools/debug.hxx> +#endif +#ifndef _COMPHELPER_TYPES_HXX_ +#include <comphelper/types.hxx> +#endif +#ifndef _COMPHELPER_ENUMHELPER_HXX_ +#include <comphelper/enumhelper.hxx> +#endif +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif +#ifndef _STRING_HXX +#include <tools/string.hxx> +#endif +#ifndef _DBU_BRW_HRC_ +#include "dbu_brw.hrc" +#endif +#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC +#include "dbustrings.hrc" +#endif +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif +#ifndef _COMPHELPER_SEQUENCE_HXX_ +#include <comphelper/sequence.hxx> +#endif + +using namespace dbaui; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; + +//================================================================== +// SbaXFormAdapter +//================================================================== + +DBG_NAME(SbaXFormAdapter) +// ------------------------------------------------------------------------- +SbaXFormAdapter::SbaXFormAdapter() + :m_aLoadListeners(*this, m_aMutex) + ,m_aRowSetListeners(*this, m_aMutex) + ,m_aRowSetApproveListeners(*this, m_aMutex) + ,m_aErrorListeners(*this, m_aMutex) + ,m_aParameterListeners(*this, m_aMutex) + ,m_aSubmitListeners(*this, m_aMutex) + ,m_aResetListeners(*this, m_aMutex) + ,m_aPropertyChangeListeners(*this, m_aMutex) + ,m_aVetoablePropertyChangeListeners(*this, m_aMutex) + ,m_aPropertiesChangeListeners(*this, m_aMutex) + ,m_aDisposeListeners(m_aMutex) + ,m_aContainerListeners(m_aMutex) + ,m_nNamePropHandle(-1) +{ + DBG_CTOR(SbaXFormAdapter,NULL); + +} + +// ------------------------------------------------------------------------- +SbaXFormAdapter::~SbaXFormAdapter() +{ + + DBG_DTOR(SbaXFormAdapter,NULL); +} + +// ------------------------------------------------------------------------- +Sequence< Type > SAL_CALL SbaXFormAdapter::getTypes( ) throw (RuntimeException) +{ + return ::comphelper::concatSequences( + SbaXFormAdapter_BASE1::getTypes(), + SbaXFormAdapter_BASE2::getTypes(), + SbaXFormAdapter_BASE3::getTypes() + ); +} + +// ------------------------------------------------------------------------- +Sequence< sal_Int8 > SAL_CALL SbaXFormAdapter::getImplementationId( ) throw (RuntimeException) +{ + static ::cppu::OImplementationId * pId = 0; + if (! pId) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pId) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::queryInterface(const Type& _rType) throw (RuntimeException) +{ + Any aReturn = SbaXFormAdapter_BASE1::queryInterface( _rType ); + + if (!aReturn.hasValue()) + aReturn = SbaXFormAdapter_BASE2::queryInterface( _rType ); + + if (!aReturn.hasValue()) + aReturn = SbaXFormAdapter_BASE3::queryInterface( _rType ); + + return aReturn; +} + +// ------------------------------------------------------------------------- +void SbaXFormAdapter::StopListening() +{ + // log off all our multiplexers + STOP_MULTIPLEXER_LISTENING(LoadListener, m_aLoadListeners, ::com::sun::star::form::XLoadable, m_xMainForm); + STOP_MULTIPLEXER_LISTENING(RowSetListener, m_aRowSetListeners, ::com::sun::star::sdbc::XRowSet, m_xMainForm); + STOP_MULTIPLEXER_LISTENING(RowSetApproveListener, m_aRowSetApproveListeners, ::com::sun::star::sdb::XRowSetApproveBroadcaster, m_xMainForm); + STOP_MULTIPLEXER_LISTENING(SQLErrorListener, m_aErrorListeners, ::com::sun::star::sdb::XSQLErrorBroadcaster, m_xMainForm); + STOP_MULTIPLEXER_LISTENING(SubmitListener, m_aSubmitListeners, ::com::sun::star::form::XSubmit, m_xMainForm); + STOP_MULTIPLEXER_LISTENING(ResetListener, m_aResetListeners, ::com::sun::star::form::XReset, m_xMainForm); + + if (m_aParameterListeners.getLength()) + { + Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xBroadcaster(m_xMainForm, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->removeParameterListener(&m_aParameterListeners); + } + + STOP_PROPERTY_MULTIPLEXER_LISTENING(PropertyChangeListener, m_aPropertyChangeListeners, ::com::sun::star::beans::XPropertySet, m_xMainForm); + STOP_PROPERTY_MULTIPLEXER_LISTENING(VetoableChangeListener, m_aVetoablePropertyChangeListeners, ::com::sun::star::beans::XPropertySet, m_xMainForm); + if (m_aPropertiesChangeListeners.getLength()) + { + Reference< ::com::sun::star::beans::XMultiPropertySet > xBroadcaster(m_xMainForm, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->removePropertiesChangeListener(&m_aPropertiesChangeListeners); + } + + // log off ourself + Reference< ::com::sun::star::lang::XComponent > xComp(m_xMainForm, UNO_QUERY); + if (xComp.is()) + xComp->removeEventListener((::com::sun::star::lang::XEventListener*)(::com::sun::star::beans::XPropertyChangeListener*)this); +} + +// ------------------------------------------------------------------------- +void SbaXFormAdapter::StartListening() +{ + // log off all our multiplexers + START_MULTIPLEXER_LISTENING(LoadListener, m_aLoadListeners, ::com::sun::star::form::XLoadable, m_xMainForm); + START_MULTIPLEXER_LISTENING(RowSetListener, m_aRowSetListeners, ::com::sun::star::sdbc::XRowSet, m_xMainForm); + START_MULTIPLEXER_LISTENING(RowSetApproveListener, m_aRowSetApproveListeners, ::com::sun::star::sdb::XRowSetApproveBroadcaster, m_xMainForm); + START_MULTIPLEXER_LISTENING(SQLErrorListener, m_aErrorListeners, ::com::sun::star::sdb::XSQLErrorBroadcaster, m_xMainForm); + START_MULTIPLEXER_LISTENING(SubmitListener, m_aSubmitListeners, ::com::sun::star::form::XSubmit, m_xMainForm); + START_MULTIPLEXER_LISTENING(ResetListener, m_aResetListeners, ::com::sun::star::form::XReset, m_xMainForm); + + if (m_aParameterListeners.getLength()) + { + Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xBroadcaster(m_xMainForm, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->addParameterListener(&m_aParameterListeners); + } + + START_PROPERTY_MULTIPLEXER_LISTENING(PropertyChangeListener, m_aPropertyChangeListeners, ::com::sun::star::beans::XPropertySet, m_xMainForm); + START_PROPERTY_MULTIPLEXER_LISTENING(VetoableChangeListener, m_aVetoablePropertyChangeListeners, ::com::sun::star::beans::XPropertySet, m_xMainForm); + if (m_aPropertiesChangeListeners.getLength()) + { + Reference< ::com::sun::star::beans::XMultiPropertySet > xBroadcaster(m_xMainForm, UNO_QUERY); + ::rtl::OUString sEmpty; + if (xBroadcaster.is()) + xBroadcaster->addPropertiesChangeListener(::comphelper::StringSequence(&sEmpty, 1), &m_aPropertiesChangeListeners); + } + + // log off ourself + Reference< ::com::sun::star::lang::XComponent > xComp(m_xMainForm, UNO_QUERY); + if (xComp.is()) + xComp->addEventListener((::com::sun::star::lang::XEventListener*)(::com::sun::star::beans::XPropertyChangeListener*)this); +} + +// ------------------------------------------------------------------------- +void SbaXFormAdapter::AttachForm(const Reference< ::com::sun::star::sdbc::XRowSet >& xNewMaster) +{ + if (xNewMaster == m_xMainForm) + return; + + DBG_ASSERT(xNewMaster.get() != static_cast< ::com::sun::star::sdbc::XRowSet* >(this), "SbaXFormAdapter::AttachForm : invalid argument !"); + + if (m_xMainForm.is()) + { + StopListening(); + + // if our old master is loaded we have to send an 'unloaded' event + Reference< ::com::sun::star::form::XLoadable > xLoadable(m_xMainForm, UNO_QUERY); + if (xLoadable->isLoaded()) + { + ::com::sun::star::lang::EventObject aEvt(*this); + ::cppu::OInterfaceIteratorHelper aIt(m_aLoadListeners); + while (aIt.hasMoreElements()) + ((::com::sun::star::form::XLoadListener*)aIt.next())->unloaded(aEvt); + } + } + + m_xMainForm = xNewMaster; + + if (m_xMainForm.is()) + { + StartListening(); + + // if our new master is loaded we have to send an 'loaded' event + Reference< ::com::sun::star::form::XLoadable > xLoadable(m_xMainForm, UNO_QUERY); + if (xLoadable->isLoaded()) + { + ::com::sun::star::lang::EventObject aEvt(*this); + ::cppu::OInterfaceIteratorHelper aIt(m_aLoadListeners); + while (aIt.hasMoreElements()) + ((::com::sun::star::form::XLoadListener*)aIt.next())->loaded(aEvt); + } + } + + // TODO : perhaps _all_ of our listeners should be notified about our new state + // (nearly every aspect of us may have changed with new master form) +} + +// ::com::sun::star::sdbc::XCloseable +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::close() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XCloseable > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->close(); +} + +// ::com::sun::star::sdbc::XResultSetMetaDataSupplier +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::sdbc::XResultSetMetaData > SAL_CALL SbaXFormAdapter::getMetaData() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XResultSetMetaDataSupplier > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getMetaData(); + return Reference< ::com::sun::star::sdbc::XResultSetMetaData > (); +} + +// ::com::sun::star::sdbc::XColumnLocate +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL SbaXFormAdapter::findColumn(const ::rtl::OUString& columnName) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XColumnLocate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->findColumn(columnName); + return 0; +} + +// ::com::sun::star::sdbcx::XColumnsSupplier +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::container::XNameAccess > SAL_CALL SbaXFormAdapter::getColumns() throw( RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XColumnsSupplier > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getColumns(); + return Reference< ::com::sun::star::container::XNameAccess > (); +} + +// ::com::sun::star::sdbc::XRow +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::wasNull() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->wasNull(); + return sal_True; +} +// ------------------------------------------------------------------------- +::rtl::OUString SAL_CALL SbaXFormAdapter::getString(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getString(columnIndex); + return ::rtl::OUString(); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::getBoolean(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getBoolean(columnIndex); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Int8 SAL_CALL SbaXFormAdapter::getByte(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getByte(columnIndex); + return 0; +} +// ------------------------------------------------------------------------- +sal_Int16 SAL_CALL SbaXFormAdapter::getShort(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getShort(columnIndex); + return 0; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL SbaXFormAdapter::getInt(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getInt(columnIndex); + return 0; +} +// ------------------------------------------------------------------------- +sal_Int64 SAL_CALL SbaXFormAdapter::getLong(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getLong(columnIndex); + return 0; +} +// ------------------------------------------------------------------------- +float SAL_CALL SbaXFormAdapter::getFloat(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getFloat(columnIndex); + return 0.0; +} +// ------------------------------------------------------------------------- +double SAL_CALL SbaXFormAdapter::getDouble(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getDouble(columnIndex); + return 0.0; +} +// ------------------------------------------------------------------------- +Sequence< sal_Int8 > SAL_CALL SbaXFormAdapter::getBytes(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getBytes(columnIndex); + return Sequence <sal_Int8> (); +} +// ------------------------------------------------------------------------- +::com::sun::star::util::Date SAL_CALL SbaXFormAdapter::getDate(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getDate(columnIndex); + return ::com::sun::star::util::Date(); +} +// ------------------------------------------------------------------------- +::com::sun::star::util::Time SAL_CALL SbaXFormAdapter::getTime(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getTime(columnIndex); + return ::com::sun::star::util::Time(); +} +// ------------------------------------------------------------------------- +::com::sun::star::util::DateTime SAL_CALL SbaXFormAdapter::getTimestamp(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getTimestamp(columnIndex); + return ::com::sun::star::util::DateTime(); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::io::XInputStream > SAL_CALL SbaXFormAdapter::getBinaryStream(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getBinaryStream(columnIndex); + return Reference< ::com::sun::star::io::XInputStream > (); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::io::XInputStream > SAL_CALL SbaXFormAdapter::getCharacterStream(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getCharacterStream(columnIndex); + return Reference< ::com::sun::star::io::XInputStream > (); +} +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getObject(sal_Int32 columnIndex, const Reference< ::com::sun::star::container::XNameAccess >& typeMap) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getObject(columnIndex, typeMap); + return Any(); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::sdbc::XRef > SAL_CALL SbaXFormAdapter::getRef(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getRef(columnIndex); + return Reference< ::com::sun::star::sdbc::XRef > (); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::sdbc::XBlob > SAL_CALL SbaXFormAdapter::getBlob(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getBlob(columnIndex); + return Reference< ::com::sun::star::sdbc::XBlob > (); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::sdbc::XClob > SAL_CALL SbaXFormAdapter::getClob(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getClob(columnIndex); + return Reference< ::com::sun::star::sdbc::XClob > (); +} +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::sdbc::XArray > SAL_CALL SbaXFormAdapter::getArray(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRow > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getArray(columnIndex); + return Reference< ::com::sun::star::sdbc::XArray > (); +} + +// ::com::sun::star::sdbcx::XRowLocate +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getBookmark() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getBookmark(); + return Any(); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::moveToBookmark(const Any& bookmark) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->moveToBookmark(bookmark); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::moveRelativeToBookmark(const Any& bookmark, sal_Int32 rows) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->moveRelativeToBookmark(bookmark,rows); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL SbaXFormAdapter::compareBookmarks(const Any& _first, const Any& _second) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->compareBookmarks(_first, _second); + return 0; +} + +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::hasOrderedBookmarks() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->hasOrderedBookmarks(); + return sal_False; +} + +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL SbaXFormAdapter::hashBookmark(const Any& bookmark) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XRowLocate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->hashBookmark(bookmark); + return 0; +} + +// ::com::sun::star::sdbc::XRowUpdate +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateNull(sal_Int32 columnIndex) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateNull(columnIndex); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateBoolean(sal_Int32 columnIndex, sal_Bool x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateBoolean(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateByte(sal_Int32 columnIndex, sal_Int8 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateByte(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateShort(sal_Int32 columnIndex, sal_Int16 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateShort(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateInt(sal_Int32 columnIndex, sal_Int32 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateInt(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateLong(sal_Int32 columnIndex, sal_Int64 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateLong(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateFloat(sal_Int32 columnIndex, float x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateFloat(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateDouble(sal_Int32 columnIndex, double x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateDouble(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateString(sal_Int32 columnIndex, const ::rtl::OUString& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateString(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateBytes(sal_Int32 columnIndex, const Sequence< sal_Int8 >& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateBytes(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateDate(sal_Int32 columnIndex, const ::com::sun::star::util::Date& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateDate(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateTime(sal_Int32 columnIndex, const ::com::sun::star::util::Time& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateTime(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateTimestamp(sal_Int32 columnIndex, const ::com::sun::star::util::DateTime& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateTimestamp(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateBinaryStream(sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateBinaryStream(columnIndex, x, length); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateCharacterStream(sal_Int32 columnIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateCharacterStream(columnIndex, x, length); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateObject(sal_Int32 columnIndex, const Any& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateObject(columnIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateNumericObject(sal_Int32 columnIndex, const Any& x, sal_Int32 scale) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XRowUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateNumericObject(columnIndex, x, scale); +} + +// ::com::sun::star::sdbc::XResultSet +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::next() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->next(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::isBeforeFirst() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->isBeforeFirst(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::isAfterLast() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->isAfterLast(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::isFirst() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->isFirst(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::isLast() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->isLast(); + return sal_False; +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::beforeFirst() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + m_xMainForm->beforeFirst(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::afterLast() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + m_xMainForm->afterLast(); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::first() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->first(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::last() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->last(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL SbaXFormAdapter::getRow() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->getRow(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::absolute(sal_Int32 row) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->absolute(row); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::relative(sal_Int32 rows) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->relative(rows); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::previous() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->previous(); + return sal_False; +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::refreshRow() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + m_xMainForm->refreshRow(); +} + +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::rowUpdated() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->rowUpdated(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::rowInserted() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->rowInserted(); + return sal_False; +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::rowDeleted() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->rowDeleted(); + return sal_False; +} +// ------------------------------------------------------------------------- +Reference< XInterface > SAL_CALL SbaXFormAdapter::getStatement() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + return m_xMainForm->getStatement(); + return NULL; +} + +// ::com::sun::star::sdbc::XResultSetUpdate +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::insertRow() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XResultSetUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->insertRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::updateRow() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XResultSetUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->updateRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::deleteRow() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XResultSetUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->deleteRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::cancelRowUpdates() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XResultSetUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->cancelRowUpdates(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::moveToInsertRow() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XResultSetUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->moveToInsertRow(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::moveToCurrentRow() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XResultSetUpdate > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->moveToCurrentRow(); +} + +// ::com::sun::star::sdbc::XRowSet +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::execute() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + if (m_xMainForm.is()) + m_xMainForm->execute(); +} +// ------------------------------------------------------------------------- +IMPLEMENT_LISTENER_ADMINISTRATION(SbaXFormAdapter, sdbc, RowSetListener, m_aRowSetListeners, ::com::sun::star::sdbc::XRowSet, m_xMainForm) + +// ::com::sun::star::sdbcx::XDeleteRows +// ------------------------------------------------------------------------- +Sequence<sal_Int32> SAL_CALL SbaXFormAdapter::deleteRows(const Sequence< Any >& rows) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbcx::XDeleteRows > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->deleteRows(rows); + return Sequence<sal_Int32>(); +} + +// ::com::sun::star::sdbc::XWarningsSupplier +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getWarnings() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XWarningsSupplier > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->getWarnings(); + return Any(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::clearWarnings() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XWarningsSupplier > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->clearWarnings(); +} + +// ::com::sun::star::sdb::XRowSetApproveBroadcaster +// ------------------------------------------------------------------------- +IMPLEMENT_LISTENER_ADMINISTRATION(SbaXFormAdapter, sdb, RowSetApproveListener, m_aRowSetApproveListeners, ::com::sun::star::sdb::XRowSetApproveBroadcaster, m_xMainForm) + +// com::sun::star::sdbc::XSQLErrorBroadcaster +// ------------------------------------------------------------------------- +IMPLEMENT_LISTENER_ADMINISTRATION(SbaXFormAdapter, sdb, SQLErrorListener, m_aErrorListeners, ::com::sun::star::sdb::XSQLErrorBroadcaster, m_xMainForm) + +// ::com::sun::star::sdb::XResultSetAccess +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::sdbc::XResultSet > SAL_CALL SbaXFormAdapter::createResultSet() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdb::XResultSetAccess > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->createResultSet(); + return Reference< ::com::sun::star::sdbc::XResultSet > (); +} + +// com::sun::star::form::XLoadable +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::load() throw( RuntimeException ) +{ + Reference< ::com::sun::star::form::XLoadable > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->load(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::unload() throw( RuntimeException ) +{ + Reference< ::com::sun::star::form::XLoadable > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->unload(); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::reload() throw( RuntimeException ) +{ + Reference< ::com::sun::star::form::XLoadable > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->reload(); +} +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::isLoaded() throw( RuntimeException ) +{ + Reference< ::com::sun::star::form::XLoadable > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + return xIface->isLoaded(); + return sal_False; +} +// ------------------------------------------------------------------------- +IMPLEMENT_LISTENER_ADMINISTRATION(SbaXFormAdapter, form, LoadListener, m_aLoadListeners, ::com::sun::star::form::XLoadable, m_xMainForm) + +// ::com::sun::star::sdbc::XParameters +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setNull(sal_Int32 parameterIndex, sal_Int32 sqlType) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setNull(parameterIndex, sqlType); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setObjectNull(sal_Int32 parameterIndex, sal_Int32 sqlType, const ::rtl::OUString& typeName) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setObjectNull(parameterIndex, sqlType, typeName); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setBoolean(sal_Int32 parameterIndex, sal_Bool x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setBoolean(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setByte(sal_Int32 parameterIndex, sal_Int8 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setByte(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setShort(sal_Int32 parameterIndex, sal_Int16 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setShort(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setInt(sal_Int32 parameterIndex, sal_Int32 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setInt(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setLong(sal_Int32 parameterIndex, sal_Int64 x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setLong(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setFloat(sal_Int32 parameterIndex, float x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setFloat(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setDouble(sal_Int32 parameterIndex, double x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setDouble(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setString(sal_Int32 parameterIndex, const ::rtl::OUString& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setString(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setBytes(sal_Int32 parameterIndex, const Sequence< sal_Int8 >& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setBytes(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setDate(sal_Int32 parameterIndex, const ::com::sun::star::util::Date& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setDate(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setTime(sal_Int32 parameterIndex, const ::com::sun::star::util::Time& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setTime(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setTimestamp(sal_Int32 parameterIndex, const ::com::sun::star::util::DateTime& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setTimestamp(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setBinaryStream(sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setBinaryStream(parameterIndex, x, length); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setCharacterStream(sal_Int32 parameterIndex, const Reference< ::com::sun::star::io::XInputStream >& x, sal_Int32 length) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setCharacterStream(parameterIndex, x, length); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setObject(sal_Int32 parameterIndex, const Any& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setObject(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setObjectWithInfo(sal_Int32 parameterIndex, const Any& x, sal_Int32 targetSqlType, sal_Int32 scale) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setObjectWithInfo(parameterIndex, x, targetSqlType, scale); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setRef(sal_Int32 parameterIndex, const Reference< ::com::sun::star::sdbc::XRef >& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setRef(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setBlob(sal_Int32 parameterIndex, const Reference< ::com::sun::star::sdbc::XBlob >& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setBlob(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setClob(sal_Int32 parameterIndex, const Reference< ::com::sun::star::sdbc::XClob >& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setClob(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setArray(sal_Int32 parameterIndex, const Reference< ::com::sun::star::sdbc::XArray >& x) throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->setArray(parameterIndex, x); +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::clearParameters() throw( ::com::sun::star::sdbc::SQLException, RuntimeException ) +{ + Reference< ::com::sun::star::sdbc::XParameters > xIface(m_xMainForm, UNO_QUERY); + if (xIface.is()) + xIface->clearParameters(); +} + +// ::com::sun::star::form::XDatabaseParameterBroadcaster +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::addParameterListener(const Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener) throw( RuntimeException ) +{ + m_aParameterListeners.addInterface(aListener); + if (m_aParameterListeners.getLength() == 1) + { + Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xBroadcaster(m_xMainForm, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->addParameterListener(&m_aParameterListeners); + } +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::removeParameterListener(const Reference< ::com::sun::star::form::XDatabaseParameterListener >& aListener) throw( RuntimeException ) +{ + if (m_aParameterListeners.getLength() == 1) + { + Reference< ::com::sun::star::form::XDatabaseParameterBroadcaster > xBroadcaster(m_xMainForm, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->removeParameterListener(&m_aParameterListeners); + } + m_aParameterListeners.removeInterface(aListener); +} + +// ::com::sun::star::container::XChild +// ------------------------------------------------------------------------- +Reference< XInterface > SAL_CALL SbaXFormAdapter::getParent() throw( RuntimeException ) +{ + return m_xParent; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setParent(const Reference< XInterface >& Parent) throw( ::com::sun::star::lang::NoSupportException, RuntimeException ) +{ + m_xParent = Parent; +} + +// ::com::sun::star::form::XSubmit +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::submit(const Reference< ::com::sun::star::awt::XControl >& aControl, const ::com::sun::star::awt::MouseEvent& aMouseEvt) throw( RuntimeException ) +{ + Reference< ::com::sun::star::form::XSubmit > xSubmit(m_xMainForm, UNO_QUERY); + if (xSubmit.is()) + xSubmit->submit(aControl, aMouseEvt); +} + +IMPLEMENT_LISTENER_ADMINISTRATION(SbaXFormAdapter, form, SubmitListener, m_aSubmitListeners, ::com::sun::star::form::XSubmit, m_xMainForm) + +// ::com::sun::star::awt::XTabControllerModel +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::getGroupControl() throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::getGroupControl : not supported !"); + return sal_False; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setGroupControl(sal_Bool /*GroupControl*/) throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::setGroupControl : not supported !"); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setControlModels(const Sequence< Reference< ::com::sun::star::awt::XControlModel > >& /*Controls*/) throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::setControlModels : not supported !"); +} + +// ------------------------------------------------------------------------- +Sequence< Reference< ::com::sun::star::awt::XControlModel > > SAL_CALL SbaXFormAdapter::getControlModels() throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::getControlModels : not supported !"); + return Sequence< Reference< ::com::sun::star::awt::XControlModel > >(); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setGroup(const Sequence< Reference< ::com::sun::star::awt::XControlModel > >& /*_rGroup*/, const ::rtl::OUString& /*GroupName*/) throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::setGroup : not supported !"); +} + +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL SbaXFormAdapter::getGroupCount() throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::getGroupCount : not supported !"); + return 0; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::getGroup(sal_Int32 /*nGroup*/, Sequence< Reference< ::com::sun::star::awt::XControlModel > >& /*_rGroup*/, ::rtl::OUString& /*Name*/) throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::getGroup : not supported !"); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::getGroupByName(const ::rtl::OUString& /*Name*/, Sequence< Reference< ::com::sun::star::awt::XControlModel > >& /*_rGroup*/) throw( RuntimeException ) +{ + DBG_ERROR("SAL_CALL SbaXFormAdapter::getGroupByName : not supported !"); +} + +// ::com::sun::star::lang::XComponent +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::dispose() throw( RuntimeException ) +{ + // log off all multiplexers + if (m_xMainForm.is()) + StopListening(); + + ::com::sun::star::lang::EventObject aEvt(*this); + m_aLoadListeners.disposeAndClear(aEvt); + m_aRowSetListeners.disposeAndClear(aEvt); + m_aRowSetApproveListeners.disposeAndClear(aEvt); + m_aErrorListeners.disposeAndClear(aEvt); + m_aParameterListeners.disposeAndClear(aEvt); + m_aSubmitListeners.disposeAndClear(aEvt); + m_aResetListeners.disposeAndClear(aEvt); + + m_aVetoablePropertyChangeListeners.disposeAndClear(); + m_aPropertyChangeListeners.disposeAndClear(); + m_aPropertiesChangeListeners.disposeAndClear(aEvt); + + m_aDisposeListeners.disposeAndClear(aEvt); + m_aContainerListeners.disposeAndClear(aEvt); + + // dispose all childs + for ( ::std::vector< Reference< ::com::sun::star::form::XFormComponent > >::iterator aIter = m_aChildren.begin(); + aIter != m_aChildren.end(); + ++aIter + ) + { + Reference< ::com::sun::star::beans::XPropertySet > xSet(*aIter, UNO_QUERY); + if (xSet.is()) + xSet->removePropertyChangeListener(PROPERTY_NAME, (::com::sun::star::beans::XPropertyChangeListener*)this); + + Reference< ::com::sun::star::container::XChild > xChild(*aIter, UNO_QUERY); + if (xChild.is()) + xChild->setParent(Reference< XInterface > ()); + + Reference< ::com::sun::star::lang::XComponent > xComp(*aIter, UNO_QUERY); + if (xComp.is()) + xComp->dispose(); + } + m_aChildren.clear(); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::addEventListener(const Reference< ::com::sun::star::lang::XEventListener >& xListener) throw( RuntimeException ) +{ + m_aDisposeListeners.addInterface(xListener); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::removeEventListener(const Reference< ::com::sun::star::lang::XEventListener >& aListener) throw( RuntimeException ) +{ + m_aDisposeListeners.removeInterface(aListener); +} + +// ::com::sun::star::beans::XFastPropertySet +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setFastPropertyValue(sal_Int32 nHandle, const Any& aValue) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XFastPropertySet > xSet(m_xMainForm, UNO_QUERY); + DBG_ASSERT(xSet.is(), "SAL_CALL SbaXFormAdapter::setFastPropertyValue : have no master form !"); + + if (m_nNamePropHandle == nHandle) + { + if (aValue.getValueType().getTypeClass() != TypeClass_STRING) + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + + // for notifying property listeners + ::com::sun::star::beans::PropertyChangeEvent aEvt; + aEvt.Source = *this; + aEvt.PropertyName = PROPERTY_NAME; + aEvt.PropertyHandle = m_nNamePropHandle; + aEvt.OldValue <<= m_sName; + aEvt.NewValue = aValue; + + aValue >>= m_sName; + + ::cppu::OInterfaceIteratorHelper aIt(*m_aPropertyChangeListeners.getContainer(PROPERTY_NAME)); + while (aIt.hasMoreElements()) + ((::com::sun::star::beans::XPropertyChangeListener*)aIt.next())->propertyChange(aEvt); + + return; + } + + xSet->setFastPropertyValue(nHandle, aValue); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getFastPropertyValue(sal_Int32 nHandle) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XFastPropertySet > xSet(m_xMainForm, UNO_QUERY); + DBG_ASSERT(xSet.is(), "SAL_CALL SbaXFormAdapter::getFastPropertyValue : have no master form !"); + + if (m_nNamePropHandle == nHandle) + return makeAny(m_sName); + + return xSet->getFastPropertyValue(nHandle); +} + +// ::com::sun::star::container::XNamed +// ------------------------------------------------------------------------- +::rtl::OUString SAL_CALL SbaXFormAdapter::getName() throw( RuntimeException ) +{ + return ::comphelper::getString(getPropertyValue(PROPERTY_NAME)); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setName(const ::rtl::OUString& aName) throw( RuntimeException ) +{ + setPropertyValue(PROPERTY_NAME, makeAny(aName)); +} + +// ::com::sun::star::io::XPersistObject +// ------------------------------------------------------------------------- +::rtl::OUString SAL_CALL SbaXFormAdapter::getServiceName() throw( RuntimeException ) +{ + Reference< ::com::sun::star::io::XPersistObject > xPersist(m_xMainForm, UNO_QUERY); + if (xPersist.is()) + return xPersist->getServiceName(); + return ::rtl::OUString(); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::write(const Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream) throw( ::com::sun::star::io::IOException, RuntimeException ) +{ + Reference< ::com::sun::star::io::XPersistObject > xPersist(m_xMainForm, UNO_QUERY); + if (xPersist.is()) + xPersist->write(_rxOutStream); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::read(const Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream) throw( ::com::sun::star::io::IOException, RuntimeException ) +{ + Reference< ::com::sun::star::io::XPersistObject > xPersist(m_xMainForm, UNO_QUERY); + if (xPersist.is()) + xPersist->read(_rxInStream); +} + +// ::com::sun::star::beans::XMultiPropertySet +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL SbaXFormAdapter::getPropertySetInfo() throw( RuntimeException ) +{ + Reference< ::com::sun::star::beans::XMultiPropertySet > xSet(m_xMainForm, UNO_QUERY); + if (!xSet.is()) + return Reference< ::com::sun::star::beans::XPropertySetInfo > (); + + Reference< ::com::sun::star::beans::XPropertySetInfo > xReturn = xSet->getPropertySetInfo(); + if (-1 == m_nNamePropHandle) + { + // we need to determine the handle for the NAME property + Sequence< ::com::sun::star::beans::Property> aProps = xReturn->getProperties(); + const ::com::sun::star::beans::Property* pProps = aProps.getConstArray(); + + for (sal_Int32 i=0; i<aProps.getLength(); ++i, ++pProps) + { + if (pProps->Name.equals(PROPERTY_NAME)) + { + ((SbaXFormAdapter*)this)->m_nNamePropHandle = pProps->Handle; + break; + } + } + } + return xReturn; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setPropertyValues(const Sequence< ::rtl::OUString >& PropertyNames, const Sequence< Any >& Values) throw( ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XMultiPropertySet > xSet(m_xMainForm, UNO_QUERY); + if (xSet.is()) + xSet->setPropertyValues(PropertyNames, Values); +} + +// ------------------------------------------------------------------------- +Sequence< Any > SAL_CALL SbaXFormAdapter::getPropertyValues(const Sequence< ::rtl::OUString >& aPropertyNames) throw( RuntimeException ) +{ + Reference< ::com::sun::star::beans::XMultiPropertySet > xSet(m_xMainForm, UNO_QUERY); + if (!xSet.is()) + return Sequence< Any>(aPropertyNames.getLength()); + + Sequence< Any> aReturn = xSet->getPropertyValues(aPropertyNames); + + // search for (and fake) the NAME property + const ::rtl::OUString* pNames = aPropertyNames.getConstArray(); + Any* pValues = aReturn.getArray(); + DBG_ASSERT(aReturn.getLength() == aPropertyNames.getLength(), "SAL_CALL SbaXFormAdapter::getPropertyValues : the main form returned an invalid-length sequence !"); + for (sal_Int32 i=0; i<aPropertyNames.getLength(); ++i, ++pNames, ++pValues) + if (pNames->equals(PROPERTY_NAME)) + { + (*pValues) <<= m_sName; + break; + } + + return aReturn; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::addPropertiesChangeListener(const Sequence< ::rtl::OUString>& /*aPropertyNames*/, const Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener) throw( RuntimeException ) +{ + // we completely ignore the property names, _all_ changes of _all_ properties will be forwarded to _all_ listeners + m_aPropertiesChangeListeners.addInterface(xListener); + if (m_aPropertiesChangeListeners.getLength() == 1) + { + Reference< ::com::sun::star::beans::XMultiPropertySet > xBroadcaster(m_xMainForm, UNO_QUERY); + ::rtl::OUString sEmpty; + if (xBroadcaster.is()) + xBroadcaster->addPropertiesChangeListener(Sequence< ::rtl::OUString>(&sEmpty, 1), &m_aPropertiesChangeListeners); + } +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::removePropertiesChangeListener(const Reference< ::com::sun::star::beans::XPropertiesChangeListener >& Listener) throw( RuntimeException ) +{ + if (m_aPropertiesChangeListeners.getLength() == 1) + { + Reference< ::com::sun::star::beans::XMultiPropertySet > xBroadcaster(m_xMainForm, UNO_QUERY); + if (xBroadcaster.is()) + xBroadcaster->removePropertiesChangeListener(&m_aPropertiesChangeListeners); + } + m_aPropertiesChangeListeners.removeInterface(Listener); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::firePropertiesChangeEvent(const Sequence< ::rtl::OUString >& aPropertyNames, const Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener) throw( RuntimeException ) +{ + Reference< ::com::sun::star::beans::XMultiPropertySet > xSet(m_xMainForm, UNO_QUERY); + if (xSet.is()) + xSet->firePropertiesChangeEvent(aPropertyNames, xListener); +} + + +// ::com::sun::star::beans::XPropertySet +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setPropertyValue(const ::rtl::OUString& aPropertyName, const Any& aValue) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XPropertySet > xSet(m_xMainForm, UNO_QUERY); + if (!xSet.is()) + return; + + // special handling for the "name" property + if (aPropertyName.equals(PROPERTY_NAME)) + setFastPropertyValue(m_nNamePropHandle, aValue); + + xSet->setPropertyValue(aPropertyName, aValue); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getPropertyValue(const ::rtl::OUString& PropertyName) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XPropertySet > xSet(m_xMainForm, UNO_QUERY); + if (!xSet.is()) + return Any(); + + // special handling for the "name" property + if (PropertyName.equals(PROPERTY_NAME)) + return getFastPropertyValue(m_nNamePropHandle); + + return xSet->getPropertyValue(PropertyName); +} + +IMPLEMENT_PROPERTY_LISTENER_ADMINISTRATION(SbaXFormAdapter, PropertyChangeListener, m_aPropertyChangeListeners, ::com::sun::star::beans::XPropertySet, m_xMainForm); +IMPLEMENT_PROPERTY_LISTENER_ADMINISTRATION(SbaXFormAdapter, VetoableChangeListener, m_aVetoablePropertyChangeListeners, ::com::sun::star::beans::XPropertySet, m_xMainForm); + +// ::com::sun::star::util::XCancellable +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::cancel() throw( RuntimeException ) +{ + Reference< ::com::sun::star::util::XCancellable > xCancel(m_xMainForm, UNO_QUERY); + if (xCancel.is()) + return; + xCancel->cancel(); +} + +// ::com::sun::star::beans::XPropertyState +// ------------------------------------------------------------------------- +::com::sun::star::beans::PropertyState SAL_CALL SbaXFormAdapter::getPropertyState(const ::rtl::OUString& PropertyName) throw( ::com::sun::star::beans::UnknownPropertyException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XPropertyState > xState(m_xMainForm, UNO_QUERY); + if (xState.is()) + return xState->getPropertyState(PropertyName); + return ::com::sun::star::beans::PropertyState_DEFAULT_VALUE; +} + +// ------------------------------------------------------------------------- +Sequence< ::com::sun::star::beans::PropertyState> SAL_CALL SbaXFormAdapter::getPropertyStates(const Sequence< ::rtl::OUString >& aPropertyName) throw( ::com::sun::star::beans::UnknownPropertyException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XPropertyState > xState(m_xMainForm, UNO_QUERY); + if (xState.is()) + return xState->getPropertyStates(aPropertyName); + + // set them all to DEFAULT + Sequence< ::com::sun::star::beans::PropertyState> aReturn(aPropertyName.getLength()); + ::com::sun::star::beans::PropertyState* pStates = aReturn.getArray(); + for (sal_uInt16 i=0; i<aPropertyName.getLength(); ++i, ++pStates) + *pStates = ::com::sun::star::beans::PropertyState_DEFAULT_VALUE; + return aReturn; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::setPropertyToDefault(const ::rtl::OUString& PropertyName) throw( ::com::sun::star::beans::UnknownPropertyException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XPropertyState > xState(m_xMainForm, UNO_QUERY); + if (xState.is()) + xState->setPropertyToDefault(PropertyName); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getPropertyDefault(const ::rtl::OUString& aPropertyName) throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + Reference< ::com::sun::star::beans::XPropertyState > xState(m_xMainForm, UNO_QUERY); + if (xState.is()) + return xState->getPropertyDefault(aPropertyName); + return Any(); +} + +// ::com::sun::star::form::XReset +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::reset() throw( RuntimeException ) +{ + Reference< ::com::sun::star::form::XReset > xReset(m_xMainForm, UNO_QUERY); + if (xReset.is()) + xReset->reset(); +} + +IMPLEMENT_LISTENER_ADMINISTRATION(SbaXFormAdapter, form, ResetListener, m_aResetListeners, ::com::sun::star::form::XReset, m_xMainForm) + +// ::com::sun::star::container::XNameContainer +// ------------------------------------------------------------------------- +void SbaXFormAdapter::implInsert(const Any& aElement, sal_Int32 nIndex, const ::rtl::OUString* pNewElName) throw( ::com::sun::star::lang::IllegalArgumentException ) +{ + // extract the form component + if (aElement.getValueType().getTypeClass() != TypeClass_INTERFACE) + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + + Reference< ::com::sun::star::form::XFormComponent > xElement(*(Reference< XInterface > *)aElement.getValue(), UNO_QUERY); + if (!xElement.is()) + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + + // for the name we need the propset + Reference< ::com::sun::star::beans::XPropertySet > xElementSet(xElement, UNO_QUERY); + if (!xElementSet.is()) + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + ::rtl::OUString sName; + try + { + if (pNewElName) + xElementSet->setPropertyValue(PROPERTY_NAME, makeAny(*pNewElName)); + + xElementSet->getPropertyValue(PROPERTY_NAME) >>= sName; + } + catch(Exception&) + { + // the set didn't support the name prop + throw ::com::sun::star::lang::IllegalArgumentException(); + } + + // check the index + OSL_ASSERT(nIndex >= 0); + if (sal::static_int_cast< sal_uInt32 >(nIndex) > m_aChildren.size()) + nIndex = m_aChildren.size(); + + DBG_ASSERT(m_aChildren.size() == m_aChildNames.size(), "SAL_CALL SbaXFormAdapter::implInsert : inconsistent container state !"); + m_aChildren.insert(m_aChildren.begin() + nIndex, xElement); + m_aChildNames.insert(m_aChildNames.begin() + nIndex, sName); + + // listen for a changes of the name + xElementSet->addPropertyChangeListener(PROPERTY_NAME, (::com::sun::star::beans::XPropertyChangeListener*)this); + + // we are now the parent of the new element + xElement->setParent((::com::sun::star::container::XContainer*)this); + + // notify the container listeners + ::com::sun::star::container::ContainerEvent aEvt; + aEvt.Source = *this; + aEvt.Accessor <<= nIndex; + aEvt.Element <<= xElement; + ::cppu::OInterfaceIteratorHelper aIt(m_aContainerListeners); + while (aIt.hasMoreElements()) + ((::com::sun::star::container::XContainerListener*)aIt.next())->elementInserted(aEvt); +} + +// ------------------------------------------------------------------------- +sal_Int32 SbaXFormAdapter::implGetPos(const ::rtl::OUString& rName) +{ + ::std::vector< ::rtl::OUString>::iterator aIter = ::std::find_if( m_aChildNames.begin(), + m_aChildNames.end(), + ::std::bind2nd(::std::equal_to< rtl::OUString>(),rName)); + + if(aIter != m_aChildNames.end()) + return aIter - m_aChildNames.begin(); + + return -1; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::insertByName(const ::rtl::OUString& aName, const Any& aElement) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + implInsert(aElement, m_aChildren.size(), &aName); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::removeByName(const ::rtl::OUString& Name) throw( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + sal_Int32 nPos = implGetPos(Name); + if (-1 == nPos) + { + throw ::com::sun::star::container::NoSuchElementException(); + } + removeByIndex(nPos); +} + +// ::com::sun::star::container::XNameReplace +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::replaceByName(const ::rtl::OUString& aName, const Any& aElement) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + sal_Int32 nPos = implGetPos(aName); + if (-1 == nPos) + { + throw ::com::sun::star::container::NoSuchElementException(); + } + replaceByIndex(nPos, aElement); +} + +// ::com::sun::star::container::XNameAccess +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getByName(const ::rtl::OUString& aName) throw( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + sal_Int32 nPos = implGetPos(aName); + if (-1 == nPos) + { + throw ::com::sun::star::container::NoSuchElementException(); + } + return makeAny(m_aChildren[nPos]); +} + +// ------------------------------------------------------------------------- +Sequence< ::rtl::OUString > SAL_CALL SbaXFormAdapter::getElementNames() throw( RuntimeException ) +{ + ::rtl::OUString *pChildNames = m_aChildNames.empty() ? 0 : &m_aChildNames[0]; + return Sequence< ::rtl::OUString >(pChildNames, m_aChildNames.size()); +} + +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::hasByName(const ::rtl::OUString& aName) throw( RuntimeException ) +{ + return (-1 != implGetPos(aName)); +} + +// ::com::sun::star::container::XElementAccess +// ------------------------------------------------------------------------- +Type SAL_CALL SbaXFormAdapter::getElementType() throw(RuntimeException) +{ + return ::getCppuType( + static_cast< Reference< ::com::sun::star::form::XFormComponent >* >(NULL)); +} + +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaXFormAdapter::hasElements() throw(RuntimeException) +{ + return m_aChildren.size() > 0; +} + + +// ::com::sun::star::container::XIndexContainer +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::insertByIndex(sal_Int32 _rIndex, const Any& Element) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + if ( ( _rIndex < 0 ) || ( (size_t)_rIndex >= m_aChildren.size() ) ) + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + implInsert(Element, _rIndex); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::removeByIndex(sal_Int32 _rIndex) throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + if ( ( _rIndex < 0 ) || ( (size_t)_rIndex >= m_aChildren.size() ) ) + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + + Reference< ::com::sun::star::form::XFormComponent > xAffected = *(m_aChildren.begin() + _rIndex); + + DBG_ASSERT(m_aChildren.size() == m_aChildNames.size(), "SAL_CALL SbaXFormAdapter::removeByIndex : inconsistent container state !"); + m_aChildren.erase(m_aChildren.begin() + _rIndex); + m_aChildNames.erase(m_aChildNames.begin() + _rIndex); + + // no need to listen anymore + Reference< ::com::sun::star::beans::XPropertySet > xAffectedSet(xAffected, UNO_QUERY); + xAffectedSet->removePropertyChangeListener(PROPERTY_NAME, (::com::sun::star::beans::XPropertyChangeListener*)this); + + // we are no longer the parent + xAffected->setParent(Reference< XInterface > ()); + + // notify container listeners + ::com::sun::star::container::ContainerEvent aEvt; + aEvt.Source = *this; + aEvt.Element <<= xAffected; + ::cppu::OInterfaceIteratorHelper aIt(m_aContainerListeners); + while (aIt.hasMoreElements()) + ((::com::sun::star::container::XContainerListener*)aIt.next())->elementRemoved(aEvt); + +} + +// ::com::sun::star::container::XIndexReplace +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::replaceByIndex(sal_Int32 _rIndex, const Any& Element) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + if ( ( _rIndex < 0 ) || ( (size_t)_rIndex >= m_aChildren.size() ) ) + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + + // extract the form component + if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE) + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + + Reference< ::com::sun::star::form::XFormComponent > xElement(*(Reference< XInterface > *)Element.getValue(), UNO_QUERY); + if (!xElement.is()) + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + + // for the name we need the propset + Reference< ::com::sun::star::beans::XPropertySet > xElementSet(xElement, UNO_QUERY); + if (!xElementSet.is()) + { + throw ::com::sun::star::lang::IllegalArgumentException(); + } + ::rtl::OUString sName; + try + { + xElementSet->getPropertyValue(PROPERTY_NAME) >>= sName; + } + catch(Exception&) + { + // the set didn't support the name prop + throw ::com::sun::star::lang::IllegalArgumentException(); + } + + Reference< ::com::sun::star::form::XFormComponent > xOld = *(m_aChildren.begin() + _rIndex); + + DBG_ASSERT(m_aChildren.size() == m_aChildNames.size(), "SAL_CALL SbaXFormAdapter::replaceByIndex : inconsistent container state !"); + *(m_aChildren.begin() + _rIndex) = xElement; + *(m_aChildNames.begin() + _rIndex) = sName; + + // correct property change listening + Reference< ::com::sun::star::beans::XPropertySet > xOldSet(xOld, UNO_QUERY); + xOldSet->removePropertyChangeListener(PROPERTY_NAME, (::com::sun::star::beans::XPropertyChangeListener*)this); + xElementSet->addPropertyChangeListener(PROPERTY_NAME, (::com::sun::star::beans::XPropertyChangeListener*)this); + + // parent reset + xOld->setParent(Reference< XInterface > ()); + xElement->setParent((::com::sun::star::container::XContainer*)this); + + // notify container listeners + ::com::sun::star::container::ContainerEvent aEvt; + aEvt.Source = *this; + aEvt.Accessor <<= (sal_Int32)_rIndex; + aEvt.Element <<= xElement; + aEvt.ReplacedElement <<= xOld; + + ::cppu::OInterfaceIteratorHelper aIt(m_aContainerListeners); + while (aIt.hasMoreElements()) + ((::com::sun::star::container::XContainerListener*)aIt.next())->elementReplaced(aEvt); +} + +// ::com::sun::star::container::XIndexAccess +// ------------------------------------------------------------------------- +sal_Int32 SAL_CALL SbaXFormAdapter::getCount() throw( RuntimeException ) +{ + return m_aChildren.size(); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL SbaXFormAdapter::getByIndex(sal_Int32 _rIndex) throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, RuntimeException ) +{ + if ( ( _rIndex < 0 ) || ( (size_t)_rIndex >= m_aChildren.size() ) ) + throw ::com::sun::star::lang::IndexOutOfBoundsException(); + + Reference< ::com::sun::star::form::XFormComponent > xElement = *(m_aChildren.begin() + _rIndex); + return makeAny(xElement); +} + +// ::com::sun::star::container::XContainer +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::addContainerListener(const Reference< ::com::sun::star::container::XContainerListener >& xListener) throw( RuntimeException ) +{ + m_aContainerListeners.addInterface(xListener); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::removeContainerListener(const Reference< ::com::sun::star::container::XContainerListener >& xListener) throw( RuntimeException ) +{ + m_aContainerListeners.removeInterface(xListener); +} + +// ::com::sun::star::container::XEnumerationAccess +// ------------------------------------------------------------------------- +Reference< ::com::sun::star::container::XEnumeration > SAL_CALL SbaXFormAdapter::createEnumeration() throw( RuntimeException ) +{ + return new ::comphelper::OEnumerationByName(this); +} + +// ::com::sun::star::beans::XPropertyChangeListener +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::propertyChange(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw( RuntimeException ) +{ + if (evt.PropertyName.equals(PROPERTY_NAME)) + { + ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent > >::iterator aIter = ::std::find_if( m_aChildren.begin(), + m_aChildren.end(), + ::std::bind2nd(::std::equal_to< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >(),evt.Source)); + + if(aIter != m_aChildren.end()) + { + sal_Int32 nPos = aIter - m_aChildren.begin(); + DBG_ASSERT(*(m_aChildNames.begin() + nPos) == ::comphelper::getString(evt.OldValue), "SAL_CALL SbaXFormAdapter::propertyChange : object has a wrong name !"); + *(m_aChildNames.begin() + nPos) = ::comphelper::getString(evt.NewValue); + } + } +} + +// ::com::sun::star::lang::XEventListener +// ------------------------------------------------------------------------- +void SAL_CALL SbaXFormAdapter::disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException ) +{ + // was it our main form ? + if (Source.Source == m_xMainForm) + dispose(); + + ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::form::XFormComponent > >::iterator aIter = ::std::find_if( m_aChildren.begin(), + m_aChildren.end(), + ::std::bind2nd(::std::equal_to< ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > >(),Source.Source)); + if(aIter != m_aChildren.end()) + removeByIndex(aIter - m_aChildren.begin()); +} +// ----------------------------------------------------------------------------- + + diff --git a/dbaccess/source/ui/browser/genericcontroller.cxx b/dbaccess/source/ui/browser/genericcontroller.cxx new file mode 100644 index 000000000000..b81b073a56bf --- /dev/null +++ b/dbaccess/source/ui/browser/genericcontroller.cxx @@ -0,0 +1,1682 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" +#ifndef DBAUI_GENERICCONTROLLER_HXX +#include "genericcontroller.hxx" +#endif +#ifndef _COMPHELPER_UNO3_HXX_ +#include <comphelper/uno3.hxx> +#endif +#ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_ +#include <toolkit/awt/vclxwindow.hxx> +#endif +#ifndef DBACCESS_UI_BROWSER_ID_HXX +#include "browserids.hxx" +#endif +#ifndef _SV_SVAPP_HXX //autogen +#include <vcl/svapp.hxx> +#endif +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/helper/vclunohelper.hxx> +#endif +#ifndef DBAUI_DATAVIEW_HXX +#include "dataview.hxx" +#endif +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif +#ifndef TOOLS_DIAGNOSE_EX_H +#include <tools/diagnose_ex.h> +#endif +#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC +#include "dbustrings.hrc" +#endif +#ifndef _VCL_STDTEXT_HXX +#include <vcl/stdtext.hxx> +#endif +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif +#include <framework/titlehelper.hxx> +#ifndef _COMPHELPER_SEQUENCE_HXX_ +#include <comphelper/sequence.hxx> +#endif +#ifndef _COMPHELPER_EXTRACT_HXX_ +#include <comphelper/extract.hxx> +#endif +#ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_ +#include <com/sun/star/sdbc/XDataSource.hpp> +#endif +#ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_ +#include <com/sun/star/sdb/SQLContext.hpp> +#endif +#ifndef _COM_SUN_STAR_SDB_XCOMPLETEDCONNECTION_HPP_ +#include <com/sun/star/sdb/XCompletedConnection.hpp> +#endif +#ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ +#include <com/sun/star/beans/XPropertySet.hpp> +#endif +#ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_ +#include <com/sun/star/task/XInteractionHandler.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_XCLOSEABLE_HPP_ +#include <com/sun/star/util/XCloseable.hpp> +#endif +#ifndef DBAUI_TOOLS_HXX +#include "UITools.hxx" +#endif +#ifndef _DBAUI_COMMON_TYPES_HXX_ +#include "commontypes.hxx" +#endif + +#ifndef _SV_WAITOBJ_HXX +#include <vcl/waitobj.hxx> +#endif +#ifndef _URLOBJ_HXX +#include <tools/urlobj.hxx> +#endif +#ifndef SVTOOLS_URIHELPER_HXX +#include <svl/urihelper.hxx> +#endif +#ifndef _DBAUI_DATASOURCECONNECTOR_HXX_ +#include "datasourceconnector.hxx" +#endif +#ifndef INCLUDED_SVTOOLS_MODULEOPTIONS_HXX +#include <unotools/moduleoptions.hxx> +#endif +#ifndef _COM_SUN_STAR_FRAME_FRAMESEARCHFLAG_HPP_ +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#endif +#ifndef _COM_SUN_STAR_FRAME_STATUS_VISIBILITY_HPP_ +#include <com/sun/star/frame/status/Visibility.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_XMODIFIABLE_HPP_ +#include <com/sun/star/util/XModifiable.hpp> +#endif +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif +#ifndef _RTL_LOGFILE_HXX_ +#include <rtl/logfile.hxx> +#endif +#include <algorithm> +#include <hash_map> +#include <cppuhelper/implbase1.hxx> +#include <limits> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::frame::status; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star; +using namespace ::dbtools; +using namespace ::comphelper; + +// ------------------------------------------------------------------------- +#define ALL_FEATURES -1 +#define FIRST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() - 1000 ) +#define LAST_USER_DEFINED_FEATURE ( ::std::numeric_limits< sal_uInt16 >::max() ) + +// ------------------------------------------------------------------------- +typedef ::std::hash_map< sal_Int16, sal_Int16 > CommandHashMap; +typedef ::std::list< DispatchInformation > DispatchInfoList; + + +// ------------------------------------------------------------------------- +const ::rtl::OUString& getConfirmDeletionURL() +{ + static const ::rtl::OUString sConfirmDeletionURL( RTL_CONSTASCII_USTRINGPARAM( ".uno:FormSlots/ConfirmDeletion" ) ); + return sConfirmDeletionURL; +} + +namespace dbaui +{ + +//========================================================================== +//= UserDefinedFeatures +//========================================================================== +class UserDefinedFeatures +{ +public: + UserDefinedFeatures( const Reference< XController >& _rxController ); + + FeatureState getState( const URL& _rFeatureURL ); + void execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs ); + +private: + ::com::sun::star::uno::WeakReference< XController > m_aController; +}; + +//-------------------------------------------------------------------------- +UserDefinedFeatures::UserDefinedFeatures( const Reference< XController >& _rxController ) + :m_aController( _rxController ) +{ +} + +//-------------------------------------------------------------------------- +FeatureState UserDefinedFeatures::getState( const URL& /*_rFeatureURL*/ ) +{ + // for now, enable all the time + // TODO: we should ask the dispatcher. However, this is laborious, since you cannot ask a dispatcher + // directly, but need to add a status listener. + FeatureState aState; + aState.bEnabled = sal_True; + return aState; +} + +//-------------------------------------------------------------------------- +void UserDefinedFeatures::execute( const URL& _rFeatureURL, const Sequence< PropertyValue>& _rArgs ) +{ + try + { + Reference< XController > xController( (Reference< XController >)m_aController, UNO_SET_THROW ); + Reference< XDispatchProvider > xDispatchProvider( xController->getFrame(), UNO_QUERY_THROW ); + Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( + _rFeatureURL, + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "_self" ) ), + FrameSearchFlag::AUTO + ) ); + + if ( xDispatch == xController ) + { + OSL_ENSURE( false, "UserDefinedFeatures::execute: the controller shouldn't be the dispatcher here!" ); + xDispatch.clear(); + } + + if ( xDispatch.is() ) + xDispatch->dispatch( _rFeatureURL, _rArgs ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +//========================================================================== +//= OGenericUnoController_Data +//========================================================================== +struct OGenericUnoController_Data +{ + ::sfx2::UserInputInterception m_aUserInputInterception; + UserDefinedFeatures m_aUserDefinedFeatures; + + OGenericUnoController_Data( OGenericUnoController& _rController, ::osl::Mutex& _rMutex ) + :m_aUserInputInterception( _rController, _rMutex ) + ,m_aUserDefinedFeatures( _rController.getXController() ) + { + } +}; + +//========================================================================== +//= OGenericUnoController +//========================================================================== +DBG_NAME(OGenericUnoController) +// ------------------------------------------------------------------------- +OGenericUnoController::OGenericUnoController(const Reference< XMultiServiceFactory >& _rM) + :OGenericUnoController_Base( getMutex() ) + ,m_pView(NULL) +#ifdef DBG_UTIL + ,m_bDescribingSupportedFeatures( false ) +#endif + ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll)) + ,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask)) + ,m_xServiceFactory(_rM) + ,m_aCurrentFrame( *this ) + ,m_bPreview(sal_False) + ,m_bReadOnly(sal_False) + ,m_bCurrentlyModified(sal_False) + ,m_bExternalTitle(sal_False) +{ + osl_incrementInterlockedCount( &m_refCount ); + { + m_pData.reset( new OGenericUnoController_Data( *this, getMutex() ) ); + } + osl_decrementInterlockedCount( &m_refCount ); + + DBG_CTOR(OGenericUnoController,NULL); + + try + { + m_xUrlTransformer = Reference< XURLTransformer > (_rM->createInstance(::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")), UNO_QUERY); + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +#ifdef WNT +// ----------------------------------------------------------------------------- +OGenericUnoController::OGenericUnoController() + :OGenericUnoController_Base( getMutex() ) + ,m_pView(NULL) +#ifdef DBG_UTIL + ,m_bDescribingSupportedFeatures( false ) +#endif + ,m_aAsyncInvalidateAll(LINK(this, OGenericUnoController, OnAsyncInvalidateAll)) + ,m_aAsyncCloseTask(LINK(this, OGenericUnoController, OnAsyncCloseTask)) + ,m_aCurrentFrame( *this ) + ,m_bPreview(sal_False) + ,m_bReadOnly(sal_False) + ,m_bCurrentlyModified(sal_False) +{ + OSL_ENSURE( false, "OGenericUnoController::OGenericUnoController: illegal call!" ); + // This ctor only exists because the MSVC compiler complained about an unresolved external + // symbol. It should not be used at all. Since using it yields strange runtime problems, + // we simply abort here. + abort(); +} +#endif + +// ----------------------------------------------------------------------------- +OGenericUnoController::~OGenericUnoController() +{ + + DBG_DTOR(OGenericUnoController,NULL); +} + +// ----------------------------------------------------------------------------- +sal_Bool OGenericUnoController::Construct(Window* /*pParent*/) +{ + OSL_ENSURE( getView(), "the view is NULL!" ); + + if ( getView() ) + { + getView()->Construct(); + getView()->Show(); + } + + m_aSupportedFeatures.clear(); + fillSupportedFeatures(); + + // create the database context + DBG_ASSERT(getORB().is(), "OGenericUnoController::Construct need a service factory!"); + try + { + m_xDatabaseContext = Reference< XNameAccess >(getORB()->createInstance(SERVICE_SDB_DATABASECONTEXT), UNO_QUERY); + } + catch(Exception&) + { + DBG_ERROR("OGenericUnoController::Construct: could not create (or start listening at) the database context!"); + } + + if (!m_xDatabaseContext.is()) + { // at least notify the user. Though the whole component does not make any sense without the database context ... + ShowServiceNotAvailableError(getView(), String(SERVICE_SDB_DATABASECONTEXT), sal_True); + } + return sal_True; +} +//------------------------------------------------------------------------------ +IMPL_LINK(OGenericUnoController, OnAsyncInvalidateAll, void*, EMPTYARG) +{ + if ( !OGenericUnoController_Base::rBHelper.bInDispose && !OGenericUnoController_Base::rBHelper.bDisposed ) + InvalidateFeature_Impl(); + return 0L; +} +// ----------------------------------------------------------------------------- +void OGenericUnoController::impl_initialize() +{ +} +// ------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::initialize( const Sequence< Any >& aArguments ) throw(Exception, RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( getMutex() ); + + Reference< XWindow > xParent; + Reference< XFrame > xFrame; + + PropertyValue aValue; + const Any* pIter = aArguments.getConstArray(); + const Any* pEnd = pIter + aArguments.getLength(); + + for ( ; pIter != pEnd; ++pIter ) + { + if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Frame" ) ) ) + { + xFrame.set(aValue.Value,UNO_QUERY_THROW); + } + /* #i42316# + else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "ReadOnly" ) ) ) + { + aValue.Value >>= m_bReadOnly; + } + */ + else if ( ( *pIter >>= aValue ) && ( 0 == aValue.Name.compareToAscii( "Preview" ) ) ) + { + aValue.Value >>= m_bPreview; + m_bReadOnly = sal_True; + } + } + try + { + if ( !xFrame.is() ) + throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "need a frame" ) ), *this, 1 ); + + xParent = xFrame->getContainerWindow(); + VCLXWindow* pParentComponent = VCLXWindow::GetImplementation(xParent); + Window* pParentWin = pParentComponent ? pParentComponent->GetWindow() : NULL; + if (!pParentWin) + { + throw IllegalArgumentException( ::rtl::OUString::createFromAscii( "Parent window is null" ), *this, 1 ); + } + + m_aInitParameters.assign( aArguments ); + Construct( pParentWin ); + + ODataView* pView = getView(); + if ( !pView ) + throw RuntimeException( ::rtl::OUString::createFromAscii( "unable to create a view" ), *this ); + + if ( m_bReadOnly || m_bPreview ) + pView->EnableInput( FALSE ); + + impl_initialize(); + } + catch(Exception& e) + { + // no one clears my view if I won't + ::std::auto_ptr<Window> aTemp(m_pView); + m_pView = NULL; + throw; + } +} + +//------------------------------------------------------------------------------ +void SAL_CALL OGenericUnoController::acquire( ) throw () +{ + OGenericUnoController_Base::acquire(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL OGenericUnoController::release( ) throw () +{ + OGenericUnoController_Base::release(); +} + +// ------------------------------------------------------------------------- +void OGenericUnoController::startFrameListening( const Reference< XFrame >& _rxFrame ) +{ + if ( _rxFrame.is() ) + _rxFrame->addFrameActionListener( this ); +} + +// ------------------------------------------------------------------------- +void OGenericUnoController::stopFrameListening( const Reference< XFrame >& _rxFrame ) +{ + if ( _rxFrame.is() ) + _rxFrame->removeFrameActionListener( this ); +} + +// ------------------------------------------------------------------------- +void OGenericUnoController::disposing(const EventObject& Source) throw( RuntimeException ) +{ + // our frame ? + if ( Source.Source == getFrame() ) + stopFrameListening( getFrame() ); +} +//------------------------------------------------------------------------ +void OGenericUnoController::modified(const EventObject& aEvent) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + if ( !isDataSourceReadOnly() ) + { + Reference<XModifiable> xModi(aEvent.Source,UNO_QUERY); + if ( xModi.is() ) + m_bCurrentlyModified = xModi->isModified(); // can only be reset by save + else + m_bCurrentlyModified = sal_True; + } + InvalidateFeature(ID_BROWSER_SAVEDOC); + InvalidateFeature(ID_BROWSER_UNDO); +} +// ----------------------------------------------------------------------- +Reference< XWindow > SAL_CALL OGenericUnoController::getComponentWindow() throw (RuntimeException) +{ + return VCLUnoHelper::GetInterface( getView() ); +} + +// ----------------------------------------------------------------------- +::rtl::OUString SAL_CALL OGenericUnoController::getViewControllerName() throw (::com::sun::star::uno::RuntimeException) +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Default" ) ); +} + +// ----------------------------------------------------------------------- +Sequence< PropertyValue > SAL_CALL OGenericUnoController::getCreationArguments() throw (RuntimeException) +{ + // currently we do not support any creation args, so anything passed to XModel2::createViewController would be + // lost, so we can equally return an empty sequence here + return Sequence< PropertyValue >(); +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::attachFrame( const Reference< XFrame >& _rxFrame ) throw( RuntimeException ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( getMutex() ); + + stopFrameListening( m_aCurrentFrame.getFrame() ); + Reference< XFrame > xFrame = m_aCurrentFrame.attachFrame( _rxFrame ); + startFrameListening( xFrame ); + + loadMenu( xFrame ); + + if ( getView() ) + getView()->attachFrame( xFrame ); +} + +// ----------------------------------------------------------------------------- +struct CommandCollector : public ::std::unary_function< SupportedFeatures::value_type, void> +{ + sal_uInt16 m_nFeature; + StringBag& m_rFeatureCommands; + CommandCollector( sal_uInt16 _nFeature, StringBag& _rFeatureCommands ) + :m_nFeature ( _nFeature ) + ,m_rFeatureCommands( _rFeatureCommands ) + { + } + + void operator() ( const SupportedFeatures::value_type& lhs ) + { + if ( lhs.second.nFeatureId == m_nFeature ) + m_rFeatureCommands.insert( lhs.first ); + } +}; + +// ----------------------------------------------------------------------- +namespace +{ + typedef ::std::vector< Any > States; + + // ................................................................... + void lcl_notifyMultipleStates( XStatusListener& _rListener, FeatureStateEvent& _rEvent, const States& _rStates ) + { + for ( States::const_iterator state = _rStates.begin(); + state != _rStates.end(); + ++state + ) + { + _rEvent.State = *state; + _rListener.statusChanged( _rEvent ); + } + } + + // ................................................................... + void lcl_collectStates( const FeatureState& _rFeatureState, States& _out_rStates ) + { + // order matters, due to a bug in framework which resets the check state when any non-boolean event + // arrives + // #i68215# is the bug to (re-)introduce this "ordered" notification here + // #i67882# is the bug which was caused by the real fix which we did in framework + // #i68216# is the bug which requests to fix the code in Draw which relies on + // framework's implementation details + // 2006-08-07 / frank.schoenheit@sun.com + if ( !!_rFeatureState.sTitle ) + _out_rStates.push_back( makeAny( *_rFeatureState.sTitle ) ); + if ( !!_rFeatureState.bChecked ) + _out_rStates.push_back( makeAny( (sal_Bool)*_rFeatureState.bChecked ) ); + if ( !!_rFeatureState.bInvisible ) + _out_rStates.push_back( makeAny( Visibility( !*_rFeatureState.bInvisible ) ) ); + if ( _rFeatureState.aValue.hasValue() ) + _out_rStates.push_back( _rFeatureState.aValue ); + if ( _out_rStates.empty() ) + _out_rStates.push_back( Any() ); + } +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::ImplBroadcastFeatureState(const ::rtl::OUString& _rFeature, const Reference< XStatusListener > & xListener, sal_Bool _bIgnoreCache) +{ + sal_uInt16 nFeat = m_aSupportedFeatures[ _rFeature ].nFeatureId; + FeatureState aFeatState( GetState( nFeat ) ); + + FeatureState& rCachedState = m_aStateCache[nFeat]; // creates if neccessary + if ( !_bIgnoreCache ) + { + // check if we really need to notify the listeners : this method may be called much more often than needed, so check + // the cached state of the feature + sal_Bool bAlreadyCached = ( m_aStateCache.find(nFeat) != m_aStateCache.end() ); + if ( bAlreadyCached ) + if ( ( rCachedState.bEnabled == aFeatState.bEnabled ) + && ( rCachedState.bChecked == aFeatState.bChecked ) + && ( rCachedState.bInvisible == aFeatState.bInvisible ) + && ( rCachedState.sTitle == aFeatState.sTitle ) + ) + return; + } + rCachedState = aFeatState; + + FeatureStateEvent aEvent; + aEvent.FeatureURL.Complete = _rFeature; + if (m_xUrlTransformer.is()) + m_xUrlTransformer->parseStrict(aEvent.FeatureURL); + aEvent.Source = (XDispatch*)this; + aEvent.IsEnabled = aFeatState.bEnabled; + + // collect all states to be notified + States aStates; + lcl_collectStates( aFeatState, aStates ); + + // a special listener ? + if ( xListener.is() ) + lcl_notifyMultipleStates( *xListener.get(), aEvent, aStates ); + else + { // no -> iterate through all listeners responsible for the URL + StringBag aFeatureCommands; + ::std::for_each( + m_aSupportedFeatures.begin(), + m_aSupportedFeatures.end(), + CommandCollector( nFeat, aFeatureCommands ) + ); + + // it is possible that listeners are registered or revoked while + // we are notifying them, so we must use a copy of m_arrStatusListener, not + // m_arrStatusListener itself + // #121276# / 2005-05-19 / frank.schoenheit@sun.com + Dispatch aNotifyLoop( m_arrStatusListener ); + DispatchIterator iterSearch = aNotifyLoop.begin(); + DispatchIterator iterEnd = aNotifyLoop.end(); + + while (iterSearch != iterEnd) + { + DispatchTarget& rCurrent = *iterSearch; + if ( aFeatureCommands.find( rCurrent.aURL.Complete ) != aFeatureCommands.end() ) + { + aEvent.FeatureURL = rCurrent.aURL; + lcl_notifyMultipleStates( *rCurrent.xListener.get(), aEvent, aStates ); + } + ++iterSearch; + } + } + +} + +//------------------------------------------------------------------------------ +sal_Bool OGenericUnoController::isFeatureSupported( sal_Int32 _nId ) +{ + SupportedFeatures::iterator aFeaturePos = ::std::find_if( + m_aSupportedFeatures.begin(), + m_aSupportedFeatures.end(), + ::std::bind2nd( CompareFeatureById(), _nId ) + ); + + return ( m_aSupportedFeatures.end() != aFeaturePos && aFeaturePos->first.getLength()); +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::InvalidateFeature(const ::rtl::OUString& _rURLPath, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast) +{ + ImplInvalidateFeature( m_aSupportedFeatures[ _rURLPath ].nFeatureId, _xListener, _bForceBroadcast ); +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::InvalidateFeature_Impl() +{ +#ifdef DBG_UTIL + static sal_Int32 s_nRecursions = 0; + ++s_nRecursions; +#endif + + sal_Bool bEmpty = sal_True; + FeatureListener aNextFeature; + { + ::osl::MutexGuard aGuard( m_aFeatureMutex); + bEmpty = m_aFeaturesToInvalidate.empty(); + if (!bEmpty) + aNextFeature = m_aFeaturesToInvalidate.front(); + } + while(!bEmpty) + { + if ( ALL_FEATURES == aNextFeature.nId ) + { + InvalidateAll_Impl(); + break; + } + else + { + SupportedFeatures::iterator aFeaturePos = ::std::find_if( + m_aSupportedFeatures.begin(), + m_aSupportedFeatures.end(), + ::std::bind2nd( CompareFeatureById(), aNextFeature.nId ) + ); + +#if OSL_DEBUG_LEVEL > 0 + if ( m_aSupportedFeatures.end() == aFeaturePos ) + { + ::rtl::OString sMessage( "OGenericUnoController::InvalidateFeature_Impl: feature id " ); + sMessage += ::rtl::OString::valueOf( aNextFeature.nId ); + sMessage += ::rtl::OString( " has been invalidated, but is not supported!" ); + OSL_ENSURE( false, sMessage.getStr() ); + } +#endif + if ( m_aSupportedFeatures.end() != aFeaturePos ) + // we really know this feature + ImplBroadcastFeatureState( aFeaturePos->first, aNextFeature.xListener, aNextFeature.bForceBroadcast ); + } + + ::osl::MutexGuard aGuard( m_aFeatureMutex); + m_aFeaturesToInvalidate.pop_front(); + bEmpty = m_aFeaturesToInvalidate.empty(); + if (!bEmpty) + aNextFeature = m_aFeaturesToInvalidate.front(); + } + +#ifdef DBG_UTIL + --s_nRecursions; +#endif +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::ImplInvalidateFeature( sal_Int32 _nId, const Reference< XStatusListener >& _xListener, sal_Bool _bForceBroadcast ) +{ + FeatureListener aListener; + aListener.nId = _nId; + aListener.xListener = _xListener; + aListener.bForceBroadcast = _bForceBroadcast; + + sal_Bool bWasEmpty; + { + ::osl::MutexGuard aGuard( m_aFeatureMutex ); + bWasEmpty = m_aFeaturesToInvalidate.empty(); + m_aFeaturesToInvalidate.push_back( aListener ); + } + + if ( bWasEmpty ) + m_aAsyncInvalidateAll.Call(); +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::InvalidateFeature(sal_uInt16 _nId, const Reference< XStatusListener > & _xListener, sal_Bool _bForceBroadcast) +{ + ImplInvalidateFeature( _nId, _xListener, _bForceBroadcast ); +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::InvalidateAll() +{ + ImplInvalidateFeature( ALL_FEATURES, NULL, sal_True ); +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::InvalidateAll_Impl() +{ + // --------------------------------- + // invalidate all aupported features + + for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin(); + aIter != m_aSupportedFeatures.end(); + ++aIter + ) + ImplBroadcastFeatureState( aIter->first, NULL, sal_True ); + + { + ::osl::MutexGuard aGuard( m_aFeatureMutex); + DBG_ASSERT(m_aFeaturesToInvalidate.size(), "OGenericUnoController::InvalidateAll_Impl: to be called from within InvalidateFeature_Impl only!"); + m_aFeaturesToInvalidate.pop_front(); + if(!m_aFeaturesToInvalidate.empty()) + m_aAsyncInvalidateAll.Call(); + } +} + +// ----------------------------------------------------------------------- +Reference< XDispatch > OGenericUnoController::queryDispatch(const URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException ) +{ + Reference< XDispatch > xReturn; + + OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::queryDispatch: shouldn't this be filled at construction time?" ); + if ( m_aSupportedFeatures.empty() ) + fillSupportedFeatures(); + + // URL's we can handle ourself? + if ( aURL.Complete.equals( getConfirmDeletionURL() ) + || ( ( m_aSupportedFeatures.find( aURL.Complete ) != m_aSupportedFeatures.end() ) + && !isUserDefinedFeature( aURL.Complete ) + ) + ) + { + xReturn = this; + } + // no? -> ask the slave dispatcher + else if ( m_xSlaveDispatcher.is() ) + { + xReturn = m_xSlaveDispatcher->queryDispatch(aURL, aTargetFrameName, nSearchFlags); + } + + // outta here + return xReturn; +} + +// ----------------------------------------------------------------------- +Sequence< Reference< XDispatch > > OGenericUnoController::queryDispatches(const Sequence< DispatchDescriptor >& aDescripts) throw( RuntimeException ) +{ + Sequence< Reference< XDispatch > > aReturn; + sal_Int32 nLen = aDescripts.getLength(); + if ( nLen ) + { + aReturn.realloc( nLen ); + Reference< XDispatch >* pReturn = aReturn.getArray(); + const Reference< XDispatch >* pReturnEnd = aReturn.getArray() + nLen; + const DispatchDescriptor* pDescripts = aDescripts.getConstArray(); + + for ( ; pReturn != pReturnEnd; ++ pReturn, ++pDescripts ) + { + *pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags ); + } + } + + return aReturn; +} + +// ----------------------------------------------------------------------- +Reference< XDispatchProvider > OGenericUnoController::getSlaveDispatchProvider(void) throw( RuntimeException ) +{ + return m_xSlaveDispatcher; +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::setSlaveDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException ) +{ + m_xSlaveDispatcher = _xNewProvider; +} + +// ----------------------------------------------------------------------- +Reference< XDispatchProvider > OGenericUnoController::getMasterDispatchProvider(void) throw( RuntimeException ) +{ + return m_xMasterDispatcher; +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::setMasterDispatchProvider(const Reference< XDispatchProvider > & _xNewProvider) throw( RuntimeException ) +{ + m_xMasterDispatcher = _xNewProvider; +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::dispatch(const URL& _aURL, const Sequence< PropertyValue >& aArgs) throw(RuntimeException) +{ + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // Since the fix for #123967#, the SolarMutex is not locked anymore when the framework calls into + // here. So, lock it ourself. The real solution would be to lock it only in the places + // where it's needed, but a) this might turn out difficult, since we then also need to care + // for locking in the proper order (SolarMutex and m_aMutex), and b) this would be too many places + // for the time frame of the fix. + // #i52602# / frank.schoenheit@sun.com / 2005-07-29 + +#ifdef TIMELOG + ::rtl::OString sLog( "OGenericUnoController::dispatch( '" ); + sLog += ::rtl::OString( _aURL.Main.getStr(), _aURL.Main.getLength(), osl_getThreadTextEncoding() ); + sLog += ::rtl::OString( "' )" ); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "dbaccess", "frank.schoenheit@sun.com", sLog.getStr() ); +#endif + + executeChecked(_aURL,aArgs); +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::addStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException) +{ + // parse the ULR now and here, this saves later parsing in each notification round + URL aParsedURL( _rURL ); + if ( m_xUrlTransformer.is() ) + m_xUrlTransformer->parseStrict( aParsedURL ); + + // remeber the listener together with the URL + m_arrStatusListener.insert( m_arrStatusListener.end(), DispatchTarget( aParsedURL, aListener ) ); + + // initially broadcast the state + ImplBroadcastFeatureState( aParsedURL.Complete, aListener, sal_True ); + // force the new state to be broadcasted to the new listener +} + +// ----------------------------------------------------------------------- +void OGenericUnoController::removeStatusListener(const Reference< XStatusListener > & aListener, const URL& _rURL) throw(RuntimeException) +{ + DispatchIterator iterSearch = m_arrStatusListener.begin(); + + sal_Bool bRemoveForAll = (_rURL.Complete.getLength() == 0); + while ( iterSearch != m_arrStatusListener.end() ) + { + DispatchTarget& rCurrent = *iterSearch; + if ( (rCurrent.xListener == aListener) + && ( bRemoveForAll + || (rCurrent.aURL.Complete.equals(_rURL.Complete)) + ) + ) + { + m_arrStatusListener.erase( iterSearch ); + if (!bRemoveForAll) + // remove the listener only for the given URL, so we can exit the loop after deletion + break; + } + else + ++iterSearch; + } + + OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::removeStatusListener: shouldn't this be filled at construction time?" ); + if ( m_aSupportedFeatures.empty() ) + fillSupportedFeatures(); + + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find(_rURL.Complete); + if (aIter != m_aSupportedFeatures.end()) + { // clear the cache for that feature + StateCacheIterator aCachePos = m_aStateCache.find( aIter->second.nFeatureId ); + if ( aCachePos != m_aStateCache.end() ) + m_aStateCache.erase( aCachePos ); + } + + // now remove the listener from the deque + ::osl::MutexGuard aGuard( m_aFeatureMutex ); + m_aFeaturesToInvalidate.erase( + ::std::remove_if( m_aFeaturesToInvalidate.begin(), + m_aFeaturesToInvalidate.end(), + ::std::bind2nd(FindFeatureListener(),aListener)) + ,m_aFeaturesToInvalidate.end()); +} +// ----------------------------------------------------------------------------- +void OGenericUnoController::releaseNumberForComponent() +{ + try + { + Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY ); + if ( xUntitledProvider.is() ) + xUntitledProvider->releaseNumberForComponent(static_cast<XWeak*>(this)); + } + catch( const Exception& ) + { + // NII + } +} +// ----------------------------------------------------------------------- +void OGenericUnoController::disposing() +{ + { + EventObject aDisposeEvent; + aDisposeEvent.Source = static_cast<XWeak*>(this); + Dispatch aStatusListener = m_arrStatusListener; + Dispatch::iterator aEnd = aStatusListener.end(); + for (Dispatch::iterator aIter = aStatusListener.begin(); aIter != aEnd; ++aIter) + { + aIter->xListener->disposing(aDisposeEvent); + } + m_arrStatusListener.clear(); + } + + m_xDatabaseContext = NULL; + { + ::osl::MutexGuard aGuard( m_aFeatureMutex); + m_aAsyncInvalidateAll.CancelCall(); + m_aFeaturesToInvalidate.clear(); + } + + releaseNumberForComponent(); + + // check out from all the objects we are listening + // the frame + stopFrameListening( m_aCurrentFrame.getFrame() ); + m_aCurrentFrame.attachFrame( NULL ); + + m_xMasterDispatcher = NULL; + m_xSlaveDispatcher = NULL; + m_xServiceFactory = NULL; +} + +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + // disambiguate + OGenericUnoController_Base::WeakComponentImplHelperBase::addEventListener( xListener ); +} + +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException) +{ + // disambiguate + OGenericUnoController_Base::WeakComponentImplHelperBase::removeEventListener( xListener ); +} + +//------------------------------------------------------------------------------ +void OGenericUnoController::frameAction(const FrameActionEvent& aEvent) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + if ( aEvent.Frame == m_aCurrentFrame.getFrame() ) + m_aCurrentFrame.frameAction( aEvent.Action ); +} + +//------------------------------------------------------------------------------ +void OGenericUnoController::implDescribeSupportedFeature( const sal_Char* _pAsciiCommandURL, + sal_uInt16 _nFeatureId, sal_Int16 _nCommandGroup ) +{ +#ifdef DBG_UTIL + DBG_ASSERT( m_bDescribingSupportedFeatures, "OGenericUnoController::implDescribeSupportedFeature: bad timing for this call!" ); +#endif + OSL_PRECOND( _nFeatureId < FIRST_USER_DEFINED_FEATURE, "OGenericUnoController::implDescribeSupportedFeature: invalid feature id!" ); + + ControllerFeature aFeature; + aFeature.Command = ::rtl::OUString::createFromAscii( _pAsciiCommandURL ); + aFeature.nFeatureId = _nFeatureId; + aFeature.GroupId = _nCommandGroup; + +#if OSL_DEBUG_LEVEL > 0 + OSL_ENSURE( m_aSupportedFeatures.find( aFeature.Command ) == m_aSupportedFeatures.end(), + "OGenericUnoController::implDescribeSupportedFeature: this feature is already there!" ); +#endif + m_aSupportedFeatures[ aFeature.Command ] = aFeature; +} + +//------------------------------------------------------------------------------ +void OGenericUnoController::describeSupportedFeatures() +{ + // add all supported features + implDescribeSupportedFeature( ".uno:Copy", ID_BROWSER_COPY, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:Cut", ID_BROWSER_CUT, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:Paste", ID_BROWSER_PASTE, CommandGroup::EDIT ); + implDescribeSupportedFeature( ".uno:ClipboardFormatItems", ID_BROWSER_CLIPBOARD_FORMAT_ITEMS ); + implDescribeSupportedFeature( ".uno:DSBEditDoc", ID_BROWSER_EDITDOC, CommandGroup::DOCUMENT ); +} + +//------------------------------------------------------------------------------ +FeatureState OGenericUnoController::GetState( sal_uInt16 _nId ) const +{ + FeatureState aReturn; + // (disabled automatically) + + switch ( _nId ) + { + case ID_BROWSER_UNDO: + case ID_BROWSER_SAVEDOC: + aReturn.bEnabled = sal_True; + break; + default: + aReturn = m_pData->m_aUserDefinedFeatures.getState( getURLForId( _nId ) ); + break; + } + + return aReturn; +} + +//------------------------------------------------------------------------------ +void OGenericUnoController::Execute( sal_uInt16 _nId, const Sequence< PropertyValue>& _rArgs ) +{ + OSL_ENSURE( isUserDefinedFeature( _nId ), + "OGenericUnoController::Execute: responsible for user defined features only!" ); + + // user defined features can be handled by dispatch interceptors resp. protocol handlers only. + // So, we need to do a queryDispatch, and dispatch the URL + m_pData->m_aUserDefinedFeatures.execute( getURLForId( _nId ), _rArgs ); +} + +//------------------------------------------------------------------------------ +URL OGenericUnoController::getURLForId(sal_Int32 _nId) const +{ + URL aReturn; + if ( m_xUrlTransformer.is() ) + { + SupportedFeatures::const_iterator aIter = ::std::find_if( + m_aSupportedFeatures.begin(), + m_aSupportedFeatures.end(), + ::std::bind2nd( CompareFeatureById(), _nId ) + ); + + if ( m_aSupportedFeatures.end() != aIter && aIter->first.getLength() ) + { + aReturn.Complete = aIter->first; + m_xUrlTransformer->parseStrict( aReturn ); + } + } + return aReturn; +} + +//------------------------------------------------------------------------- +bool OGenericUnoController::isUserDefinedFeature( const sal_uInt16 _nFeatureId ) const +{ + return ( _nFeatureId >= FIRST_USER_DEFINED_FEATURE ) && ( _nFeatureId < LAST_USER_DEFINED_FEATURE ); +} + +//------------------------------------------------------------------------- +bool OGenericUnoController::isUserDefinedFeature( const ::rtl::OUString& _rFeatureURL ) const +{ + SupportedFeatures::const_iterator pos = m_aSupportedFeatures.find( _rFeatureURL ); + OSL_PRECOND( pos != m_aSupportedFeatures.end(), + "OGenericUnoController::isUserDefinedFeature: this is no supported feature at all!" ); + + return ( pos != m_aSupportedFeatures.end() ) ? isUserDefinedFeature( pos->second.nFeatureId ) : false; +} + +//------------------------------------------------------------------------- +sal_Bool SAL_CALL OGenericUnoController::supportsService(const ::rtl::OUString& ServiceName) throw(RuntimeException) +{ + Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); + + const ::rtl::OUString* pArray = aSupported.getConstArray(); + const ::rtl::OUString* pArrayEnd = aSupported.getConstArray() + aSupported.getLength(); + + for ( ;( pArray != pArrayEnd ) && !pArray->equals( ServiceName ); ++pArray ) + ; + return pArray != pArrayEnd; +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::startConnectionListening(const Reference< XConnection >& _rxConnection) +{ + // we have to remove ourself before dispoing the connection + Reference< XComponent > xComponent(_rxConnection, UNO_QUERY); + if (xComponent.is()) + xComponent->addEventListener(static_cast<XFrameActionListener*>(this)); +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::stopConnectionListening(const Reference< XConnection >& _rxConnection) +{ + // we have to remove ourself before dispoing the connection + Reference< XComponent > xComponent(_rxConnection, UNO_QUERY); + if (xComponent.is()) + xComponent->removeEventListener(static_cast<XFrameActionListener*>(this)); +} +// ----------------------------------------------------------------------------- +Reference< XConnection > OGenericUnoController::connect( const Reference< XDataSource>& _xDataSource, + ::dbtools::SQLExceptionInfo* _pErrorInfo ) +{ + WaitObject aWaitCursor( getView() ); + + ODatasourceConnector aConnector( getORB(), getView(), ::rtl::OUString() ); + Reference< XConnection > xConnection = aConnector.connect( _xDataSource, _pErrorInfo ); + startConnectionListening( xConnection ); + + return xConnection; +} +// ----------------------------------------------------------------------------- +Reference< XConnection > OGenericUnoController::connect( const ::rtl::OUString& _rDataSourceName, + const ::rtl::OUString& _rContextInformation, ::dbtools::SQLExceptionInfo* _pErrorInfo ) +{ + WaitObject aWaitCursor( getView() ); + + ODatasourceConnector aConnector( getORB(), getView(), _rContextInformation ); + Reference<XConnection> xConnection = aConnector.connect( _rDataSourceName, _pErrorInfo ); + startConnectionListening( xConnection ); + + return xConnection; +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::showError(const SQLExceptionInfo& _rInfo) +{ + ::dbaui::showError(_rInfo,getView(),getORB()); +} +// ----------------------------------------------------------------------------- +Reference< XLayoutManager > OGenericUnoController::getLayoutManager(const Reference< XFrame >& _xFrame) const +{ + Reference< XPropertySet > xPropSet( _xFrame, UNO_QUERY ); + Reference< XLayoutManager > xLayoutManager; + if ( xPropSet.is() ) + { + try + { + xLayoutManager.set(xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ))),UNO_QUERY); + } + catch ( Exception& ) + { + } + } + return xLayoutManager; +} +// ----------------------------------------------------------------------------- +void OGenericUnoController::loadMenu(const Reference< XFrame >& _xFrame) +{ + Reference< XLayoutManager > xLayoutManager = getLayoutManager(_xFrame); + if ( xLayoutManager.is() ) + { + xLayoutManager->lock(); + xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/menubar/menubar" ))); + xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ))); + xLayoutManager->unlock(); + xLayoutManager->doLayout(); + } + + onLoadedMenu( xLayoutManager ); +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::onLoadedMenu(const Reference< XLayoutManager >& /*_xLayoutManager*/) +{ + // not interested in +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::closeTask() +{ + m_aAsyncCloseTask.Call(); +} +// ----------------------------------------------------------------------------- +IMPL_LINK(OGenericUnoController, OnAsyncCloseTask, void*, EMPTYARG) +{ + if ( !OGenericUnoController_Base::rBHelper.bInDispose ) + { + try + { + Reference< util::XCloseable > xCloseable( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW ); + xCloseable->close( sal_False ); // false - holds the owner ship for this frame inside this object! + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + return 0L; +} +// ----------------------------------------------------------------------------- +Any SAL_CALL OGenericUnoController::getViewData(void) throw( RuntimeException ) +{ + return Any(); +} +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::restoreViewData(const Any& /*Data*/) throw( RuntimeException ) +{ +} + +// ----------------------------------------------------------------------------- +Reference< XModel > SAL_CALL OGenericUnoController::getModel(void) throw( RuntimeException ) +{ + return Reference< XModel >(); +} + +// ----------------------------------------------------------------------------- +Reference< XFrame > SAL_CALL OGenericUnoController::getFrame(void) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard( getMutex() ); + return m_aCurrentFrame.getFrame(); +} + +// ----------------------------------------------------------------------------- +sal_Bool SAL_CALL OGenericUnoController::attachModel(const Reference< XModel > & /*xModel*/) throw( RuntimeException ) +{ + OSL_ENSURE( false, "OGenericUnoController::attachModel: not supported!" ); + return sal_False; +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::executeUnChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs) +{ + Execute(_nCommandId, aArgs); +} +// ----------------------------------------------------------------------------- +void OGenericUnoController::executeUnChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs) +{ + OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeUnChecked: shouldn't this be filled at construction time?" ); + if ( m_aSupportedFeatures.empty() ) + fillSupportedFeatures(); + + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete ); + if (aIter != m_aSupportedFeatures.end()) + Execute( aIter->second.nFeatureId, aArgs ); +} +// ----------------------------------------------------------------------------- +void OGenericUnoController::executeChecked(const util::URL& _rCommand, const Sequence< PropertyValue >& aArgs) +{ + OSL_PRECOND( !m_aSupportedFeatures.empty(), "OGenericUnoController::executeChecked: shouldn't this be filled at construction time?" ); + if ( m_aSupportedFeatures.empty() ) + fillSupportedFeatures(); + + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCommand.Complete ); + if ( aIter != m_aSupportedFeatures.end() ) + { + sal_uInt16 nFeatureId = aIter->second.nFeatureId; + if ( GetState( nFeatureId ).bEnabled ) + Execute( nFeatureId, aArgs ); + } +} +// ----------------------------------------------------------------------------- +//------------------------------------------------------------------------------ +namespace +{ + ::rtl::OUString lcl_getModuleHelpModuleName( const Reference< XFrame >& _rxFrame ) + { + const sal_Char* pReturn = NULL; + + try + { + // get the model of the document in the given frame + Reference< XController > xController; + if ( _rxFrame.is() ) + xController = _rxFrame->getController(); + Reference< XModel > xModel; + if ( xController.is() ) + xModel = xController->getModel(); + Reference< XServiceInfo > xSI( xModel, UNO_QUERY ); + + if ( !xSI.is() ) + { // try to go up the frame hierarchy + + Reference< XFrame > xParentFrame; + if ( _rxFrame.is() ) + xParentFrame = xParentFrame.query( _rxFrame->getCreator() ); + // did we find a parent frame? Which is no top-level frame? + if ( xParentFrame.is() && !_rxFrame->isTop() ) + // TODO: to prevent framework assertions, re-insert this "isTop" once 98303 is fixed + return lcl_getModuleHelpModuleName( xParentFrame ); + } + else + { +#if OSL_DEBUG_LEVEL > 0 + Sequence< ::rtl::OUString > sServiceNames = xSI->getSupportedServiceNames(); + const ::rtl::OUString* pLoop = sServiceNames.getConstArray(); + for ( sal_Int32 i=0; i<sServiceNames.getLength(); ++i, ++pLoop ) + { + sal_Int32 nDummy = 0; + (void)nDummy; + } +#endif + + // check which service we know .... + static const sal_Char* pTransTable[] = { + "com.sun.star.sdb.OfficeDatabaseDocument","sdatabase", + "com.sun.star.report.ReportDefinition","sdatabase", + "com.sun.star.text.TextDocument", "swriter", + "com.sun.star.sheet.SpreadsheetDocument", "scalc", + "com.sun.star.presentation.PresentationDocument", "simpress", + "com.sun.star.drawing.DrawingDocument", "sdraw", + "com.sun.star.formula.FormularProperties", "smath", + "com.sun.star.chart.ChartDocument", "schart" + }; + OSL_ENSURE( ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) % 2 == 0, + "lcl_getModuleHelpModuleName: odd size of translation table!" ); + + // loop through the table + sal_Int32 nTableEntries = ( sizeof( pTransTable ) / sizeof( pTransTable[0] ) ) / 2; + const sal_Char** pDocumentService = pTransTable; + const sal_Char** pHelpModuleName = pTransTable + 1; + for ( sal_Int32 j=0; j<nTableEntries; ++j ) + { + if ( xSI->supportsService( ::rtl::OUString::createFromAscii( *pDocumentService ) ) ) + { // found a table entry which matches the model's services + pReturn = *pHelpModuleName; + break; + } + + ++pDocumentService; ++pDocumentService; + ++pHelpModuleName; ++pHelpModuleName; + } + } + + if ( !pReturn ) + { + // could not determine the document type we're living in + // ->fallback + SvtModuleOptions aModOpt; + if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SWRITER ) ) + pReturn = "swriter"; + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) ) + pReturn = "sdatabase"; + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCALC ) ) + pReturn = "scalc"; + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SIMPRESS ) ) + pReturn = "simpress"; + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SDRAW ) ) + pReturn = "sdraw"; + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SMATH ) ) + pReturn = "smath"; + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SCHART ) ) + pReturn = "schart"; + else if ( aModOpt.IsModuleInstalled( SvtModuleOptions::E_SBASIC ) ) + pReturn = "sbasic"; + else + { + OSL_ENSURE( sal_False, "lcl_getModuleHelpModuleName: no installed module found" ); + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + if ( !pReturn ) + pReturn = "swriter"; + + return ::rtl::OUString::createFromAscii( pReturn ); + } +} + +// ----------------------------------------------------------------------------- + +void OGenericUnoController::openHelpAgent(rtl::OUString const& _suHelpStringURL ) +{ + rtl::OUString suURL(_suHelpStringURL); + rtl::OUString sLanguage = rtl::OUString::createFromAscii("Language="); + if (suURL.indexOf(sLanguage) == -1) + { + AppendConfigToken(suURL, sal_False /* sal_False := add '&' */ ); + } + URL aURL; + aURL.Complete = suURL; + + openHelpAgent( aURL ); +} + +void OGenericUnoController::openHelpAgent(const rtl::OString& _sHelpId) +{ + openHelpAgent( createHelpAgentURL( lcl_getModuleHelpModuleName( getFrame() ), _sHelpId ) ); +} + +void OGenericUnoController::openHelpAgent( const URL& _rURL ) +{ + try + { + URL aURL( _rURL ); + + if ( m_xUrlTransformer.is() ) + m_xUrlTransformer->parseStrict(aURL); + + Reference< XDispatchProvider > xDispProv( m_aCurrentFrame.getFrame(), UNO_QUERY ); + Reference< XDispatch > xHelpDispatch; + if ( xDispProv.is() ) + xHelpDispatch = xDispProv->queryDispatch(aURL, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_helpagent")), FrameSearchFlag::PARENT | FrameSearchFlag::SELF); + OSL_ENSURE(xHelpDispatch.is(), "SbaTableQueryBrowser::openHelpAgent: could not get a dispatcher!"); + if (xHelpDispatch.is()) + { + xHelpDispatch->dispatch(aURL, Sequence< PropertyValue >()); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} +// ----------------------------------------------------------------------------- +Reference< awt::XWindow> OGenericUnoController::getTopMostContainerWindow() const +{ + Reference< ::com::sun::star::awt::XWindow> xWindow; + + // get the top most window + Reference< XFrame > xFrame( m_aCurrentFrame.getFrame() ); + if ( xFrame.is() ) + { + xWindow = xFrame->getContainerWindow(); + + while ( xFrame.is() && !xFrame->isTop() ) + { + xFrame.set( xFrame->getCreator(), UNO_QUERY ); + } + if ( xFrame.is() ) + xWindow = xFrame->getContainerWindow(); + } + return xWindow; +} +// ----------------------------------------------------------------------------- +Reference< XTitle > OGenericUnoController::impl_getTitleHelper_throw() +{ + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( getMutex() ); + + if ( ! m_xTitleHelper.is ()) + { + Reference< XUntitledNumbers > xUntitledProvider(getPrivateModel(), UNO_QUERY ); + Reference< XController > xThis(static_cast< XController* >(this), UNO_QUERY_THROW); + + ::framework::TitleHelper* pHelper = new ::framework::TitleHelper(m_xServiceFactory); + m_xTitleHelper.set( static_cast< ::cppu::OWeakObject* >(pHelper), UNO_QUERY_THROW); + + pHelper->setOwner (xThis ); + pHelper->connectWithUntitledNumbers (xUntitledProvider); + } + + return m_xTitleHelper; +} + +//============================================================================= +// XTitle +::rtl::OUString SAL_CALL OGenericUnoController::getTitle() + throw (RuntimeException) +{ + ::osl::MutexGuard aGuard( getMutex() ); + if ( m_bExternalTitle ) + return impl_getTitleHelper_throw()->getTitle (); + return getPrivateTitle() + impl_getTitleHelper_throw()->getTitle (); +} + +//============================================================================= +// XTitle +void SAL_CALL OGenericUnoController::setTitle(const ::rtl::OUString& sTitle) + throw (RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( getMutex() ); + m_bExternalTitle = sal_True; + impl_getTitleHelper_throw()->setTitle (sTitle); +} + +//============================================================================= +// XTitleChangeBroadcaster +void SAL_CALL OGenericUnoController::addTitleChangeListener(const Reference< XTitleChangeListener >& xListener) + throw (RuntimeException) +{ + Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY); + if (xBroadcaster.is ()) + xBroadcaster->addTitleChangeListener (xListener); +} + +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::removeTitleChangeListener(const Reference< XTitleChangeListener >& xListener) + throw (RuntimeException) +{ + Reference< XTitleChangeBroadcaster > xBroadcaster(impl_getTitleHelper_throw(), UNO_QUERY); + if (xBroadcaster.is ()) + xBroadcaster->removeTitleChangeListener (xListener); +} + +// ============================================================================= +// XUserInputInterception +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::addKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) +{ + if ( _rxHandler.is() ) + m_pData->m_aUserInputInterception.addKeyHandler( _rxHandler ); +} + +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::removeKeyHandler( const Reference< XKeyHandler >& _rxHandler ) throw (RuntimeException) +{ + m_pData->m_aUserInputInterception.removeKeyHandler( _rxHandler ); +} + +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::addMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) +{ + if ( _rxHandler.is() ) + m_pData->m_aUserInputInterception.addMouseClickHandler( _rxHandler ); +} + +// ----------------------------------------------------------------------------- +void SAL_CALL OGenericUnoController::removeMouseClickHandler( const Reference< XMouseClickHandler >& _rxHandler ) throw (RuntimeException) +{ + m_pData->m_aUserInputInterception.removeMouseClickHandler( _rxHandler ); +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +void OGenericUnoController::executeChecked(sal_uInt16 _nCommandId, const Sequence< PropertyValue >& aArgs) +{ + if ( isCommandEnabled(_nCommandId) ) + Execute(_nCommandId, aArgs); +} + +// ----------------------------------------------------------------------------- +sal_Bool OGenericUnoController::isCommandEnabled(sal_uInt16 _nCommandId) const +{ + return GetState( _nCommandId ).bEnabled; +} + +// ----------------------------------------------------------------------------- +sal_uInt16 OGenericUnoController::registerCommandURL( const ::rtl::OUString& _rCompleteCommandURL ) +{ + if ( !_rCompleteCommandURL.getLength() ) + return 0; + + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL ); + if ( aIter != m_aSupportedFeatures.end() ) + return aIter->second.nFeatureId; + + // this is a previously unkwnon command + sal_uInt16 nFeatureId = FIRST_USER_DEFINED_FEATURE; + while ( isFeatureSupported( nFeatureId ) && ( nFeatureId < LAST_USER_DEFINED_FEATURE ) ) + ++nFeatureId; + if ( nFeatureId == LAST_USER_DEFINED_FEATURE ) + { + OSL_ENSURE( false, "OGenericUnoController::registerCommandURL: no more space for user defined features!" ); + return 0L; + } + + ControllerFeature aFeature; + aFeature.Command = _rCompleteCommandURL; + aFeature.nFeatureId = nFeatureId; + aFeature.GroupId = CommandGroup::INTERNAL; + m_aSupportedFeatures[ aFeature.Command ] = aFeature; + + return nFeatureId; +} + +// ----------------------------------------------------------------------------- +void OGenericUnoController::notifyHiContrastChanged() +{ +} + +// ----------------------------------------------------------------------------- +sal_Bool OGenericUnoController::isDataSourceReadOnly() const +{ + return sal_False; +} + +// ----------------------------------------------------------------------------- +Reference< XController > OGenericUnoController::getXController() throw( RuntimeException ) +{ + return this; +} + +// ----------------------------------------------------------------------------- +bool OGenericUnoController::interceptUserInput( const NotifyEvent& _rEvent ) +{ + return m_pData->m_aUserInputInterception.handleNotifyEvent( _rEvent ); +} + +// ----------------------------------------------------------------------------- +sal_Bool OGenericUnoController::isCommandChecked(sal_uInt16 _nCommandId) const +{ + FeatureState aState = GetState( _nCommandId ); + + return aState.bChecked && (sal_Bool)*aState.bChecked; +} +// ----------------------------------------------------------------------------- +sal_Bool OGenericUnoController::isCommandEnabled( const ::rtl::OUString& _rCompleteCommandURL ) const +{ + OSL_ENSURE( _rCompleteCommandURL.getLength(), "OGenericUnoController::isCommandEnabled: Empty command url!" ); + + sal_Bool bIsEnabled = sal_False; + SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.find( _rCompleteCommandURL ); + if ( aIter != m_aSupportedFeatures.end() ) + bIsEnabled = isCommandEnabled( aIter->second.nFeatureId ); + + return bIsEnabled; +} + +// ----------------------------------------------------------------------------- +Sequence< ::sal_Int16 > SAL_CALL OGenericUnoController::getSupportedCommandGroups() throw (RuntimeException) +{ + CommandHashMap aCmdHashMap; + for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin(); + aIter != m_aSupportedFeatures.end(); + ++aIter + ) + if ( aIter->second.GroupId != CommandGroup::INTERNAL ) + aCmdHashMap.insert( CommandHashMap::value_type( aIter->second.GroupId, 0 )); + + Sequence< sal_Int16 > aCommandGroups( aCmdHashMap.size() ); + ::std::transform( aCmdHashMap.begin(), + aCmdHashMap.end(), + aCommandGroups.getArray(), + ::std::select1st< CommandHashMap::value_type >() + ); + + return aCommandGroups; +} + +// ----------------------------------------------------------------------------- +Sequence< DispatchInformation > SAL_CALL OGenericUnoController::getConfigurableDispatchInformation( ::sal_Int16 CommandGroup ) throw (RuntimeException) +{ + DispatchInfoList aInformationList; + DispatchInformation aDispatchInfo; + for ( SupportedFeatures::const_iterator aIter = m_aSupportedFeatures.begin(); + aIter != m_aSupportedFeatures.end(); + ++aIter + ) + { + if ( sal_Int16( aIter->second.GroupId ) == CommandGroup ) + { + aDispatchInfo = aIter->second; + aInformationList.push_back( aDispatchInfo ); + } + } + + Sequence< DispatchInformation > aInformation( aInformationList.size() ); + ::std::transform( aInformationList.begin(), + aInformationList.end(), + aInformation.getArray(), + ::std::identity< DispatchInformation >() + ); + + return aInformation; +} +// ----------------------------------------------------------------------------- +void OGenericUnoController::fillSupportedFeatures() +{ +#ifdef DBG_UTIL + m_bDescribingSupportedFeatures = true; +#endif + describeSupportedFeatures(); +// ----------------------------------------------------------------------------- +#ifdef DBG_UTIL + m_bDescribingSupportedFeatures = false; +#endif +} + + +void SAL_CALL OGenericUnoController::dispose() throw(::com::sun::star::uno::RuntimeException) +{ + ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); + OGenericUnoController_Base::dispose(); +} +} // namespace dbaui + diff --git a/dbaccess/source/ui/browser/makefile.mk b/dbaccess/source/ui/browser/makefile.mk new file mode 100644 index 000000000000..a7dbd7413d78 --- /dev/null +++ b/dbaccess/source/ui/browser/makefile.mk @@ -0,0 +1,71 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJINC=$(PRJ)$/source +PRJNAME=dbaccess +TARGET=browser + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk +# --- Files -------------------------------------------------------- + +EXCEPTIONSFILES=\ + $(SLO)$/genericcontroller.obj \ + $(SLO)$/dsbrowserDnD.obj \ + $(SLO)$/dataview.obj \ + $(SLO)$/dbexchange.obj \ + $(SLO)$/dbloader.obj \ + $(SLO)$/sbagrid.obj \ + $(SLO)$/formadapter.obj \ + $(SLO)$/brwview.obj \ + $(SLO)$/brwctrlr.obj \ + $(SLO)$/unodatbr.obj \ + $(SLO)$/sbamultiplex.obj \ + $(SLO)$/exsrcbrw.obj \ + $(SLO)$/dbtreemodel.obj \ + $(SLO)$/dsEntriesNoExp.obj \ + $(SLO)$/dbtreeview.obj + +SLOFILES =\ + $(EXCEPTIONSFILES)\ + $(SLO)$/AsyncronousLink.obj + +SRS1NAME=$(TARGET) +SRC1FILES = sbabrw.src \ + sbagrid.src + +# --- Targets ------------------------------------------------------- + + +.INCLUDE : target.mk + +$(SRS)$/$(TARGET).srs: $(SOLARINCDIR)$/svx$/globlmn.hrc + + diff --git a/dbaccess/source/ui/browser/sbabrw.src b/dbaccess/source/ui/browser/sbabrw.src new file mode 100644 index 000000000000..476fcf683b3f --- /dev/null +++ b/dbaccess/source/ui/browser/sbabrw.src @@ -0,0 +1,203 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _DBA_DBACCESS_HELPID_HRC_ +#include "dbaccess_helpid.hrc" +#endif +#ifndef _DBU_BRW_HRC_ +#include "dbu_brw.hrc" +#endif +#ifndef DBACCESS_UI_BROWSER_ID_HXX +#include "browserids.hxx" +#endif +// #include <sfx2/sfx.hrc> +#ifndef _GLOBLMN_HRC +#include <svx/globlmn.hrc> +#endif +#include "toolbox.hrc" + +QueryBox QUERY_BRW_SAVEMODIFIED +{ + Buttons = WB_YES_NO_CANCEL ; + DefButton = WB_DEF_YES ; + /* ### ACHTUNG: Neuer Text in Resource? Soll der geänderte Datensatz gespeichert werden? : Soll der geänderte Datensatz gespeichert werden? */ + Message [ en-US ] = "The current record has been changed.\nDo you want to save the changes?" ; +}; + +QueryBox QUERY_BRW_DELETE_ROWS +{ + Buttons = WB_YES_NO ; + /* ### ACHTUNG: Neuer Text in Resource? Sollen die selektierten Daten gelöscht werden? : Sollen die selektierten Daten gel÷scht werden? */ + Message [ en-US ] = "Do you want to delete the selected data?" ; +}; + +String RID_STR_DATABROWSER_FILTERED +{ + Text [ en-US ] = "(filtered)" ; +}; + +String SBA_BROWSER_SETTING_ORDER +{ + Text [ en-US ] = "Error setting the sort criteria"; +}; +String SBA_BROWSER_SETTING_FILTER +{ + Text [ en-US ] = "Error setting the filter criteria"; +}; + +String RID_STR_CONNECTION_LOST +{ + Text [ en-US ] = "Connection lost"; +}; + +String RID_STR_QUERIES_CONTAINER +{ + Text [ en-US ] = "Queries"; +}; + +String RID_STR_TABLES_CONTAINER +{ + Text [ en-US ] = "Tables"; +}; + +#define MID_EDIT_DATABASE \ + Identifier = ID_TREE_EDIT_DATABASE ; \ + HelpId = HID_BROWSER_EDIT_DATABASE; \ + Text [ en-US ] = "Edit ~Database File..." ;\ + +#define MID_ADMINISTRATE \ + Identifier = ID_TREE_ADMINISTRATE ; \ + HelpId = HID_BROWSER_ADMINISTRATE; \ + Text [ en-US ] = "Registered databases ..." ;\ + +#define MID_CLOSECONN \ + Identifier = ID_TREE_CLOSE_CONN ; \ + HelpId = HID_BROWSER_CLOSECONN ; \ + Text [ en-US ] = "Disco~nnect" ; \ + +Menu MENU_BROWSER_DEFAULTCONTEXT +{ + ItemList = + { + MenuItem \ + { \ + MID_EDIT_DATABASE \ + }; \ + MenuItem \ + { \ + MID_CLOSECONN \ + }; \ + MenuItem \ + { \ + Separator = TRUE; \ + }; \ + MenuItem { ITEM_EDIT_COPY }; + MenuItem \ + { \ + Separator = TRUE; \ + }; \ + MenuItem \ + { \ + MID_ADMINISTRATE \ + }; + }; +}; + +String STR_TITLE_CONFIRM_DELETION +{ + Text [ en-US ] = "Confirm Deletion" ; +}; + +String STR_QUERY_DELETE_TABLE +{ + Text [ en-US ] = "Do you want to delete the table '%1'?" ; +}; + +QueryBox QUERY_BRW_DELETE_QUERY_CONFIRM +{ + Buttons = WB_YES_NO ; + Message [ en-US ] = "The query already exists. Do you want to delete it?" ; + }; + +QueryBox QUERY_CONNECTION_LOST +{ + Buttons = WB_YES_NO ; + Message [ en-US ] = "The connection to the database has been lost. Do you want to reconnect?" ; + }; + +String STR_OPENTABLES_WARNINGS +{ + Text [ en-US ] = "Warnings encountered"; +}; + +String STR_OPENTABLES_WARNINGS_DETAILS +{ + Text [ en-US ] = "While retrieving the tables, warnings were reported by the database connection."; +}; + +String STR_CONNECTING_DATASOURCE +{ + Text [ en-US ] = "Connecting to \"$name$\" ..."; + }; + +String STR_LOADING_QUERY +{ + Text [ en-US ] = "Loading query $name$ ..."; + }; + +String STR_LOADING_TABLE +{ + Text [ en-US ] = "Loading table $name$ ..."; + }; + +String STR_NO_TABLE_FORMAT_INSIDE +{ + Text [ en-US ] = "No table format could be found." ; + }; + +String STR_COULDNOTCONNECT_DATASOURCE +{ + Text [ en-US ] = "The connection to the data source \"$name$\" could not be established."; +}; + +Menu RID_MENU_REFRESH_DATA +{ + ItemList = + { + MenuItem + { + MID_SBA_QRY_REFRESH + Command = ".uno:Refresh"; + }; + MenuItem + { + Identifier = ID_BROWSER_REFRESH_REBUILD; + Command = ".uno:DBRebuildData"; + Text [ en-US ] = "Rebuild"; + }; + }; +}; + diff --git a/dbaccess/source/ui/browser/sbagrid.cxx b/dbaccess/source/ui/browser/sbagrid.cxx new file mode 100644 index 000000000000..bb0784c0ce53 --- /dev/null +++ b/dbaccess/source/ui/browser/sbagrid.cxx @@ -0,0 +1,1786 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef DBACCESS_SBA_GRID_HRC +#include "sbagrid.hrc" +#endif + +#ifndef _SVX_SVXIDS_HRC +#include <svx/svxids.hrc> +#endif + +#define ITEMID_HORJUSTIFY SID_ATTR_ALIGN_HOR_JUSTIFY +#define ITEMID_VERJUSTIFY SID_ATTR_ALIGN_VER_JUSTIFY +//#define ITEMID_ORIENTATION SID_ATTR_ALIGN_ORIENTATION +#define ITEMID_LINEBREAK SID_ATTR_ALIGN_LINEBREAK +#define ITEMID_MARGIN SID_ATTR_ALIGN_MARGIN +#define ITEMID_NUMBERINFO SID_ATTR_NUMBERFORMAT_INFO + + +#define _ZFORLIST_DECLARE_TABLE +#ifndef _SVX_NUMINF_HXX +#include <svx/numinf.hxx> +#endif +#ifndef _SVX_DBAEXCHANGE_HXX_ +#include <svx/dbaexchange.hxx> +#endif +#ifndef _COM_SUN_STAR_UI_DIALOGS_XEXECUTABLEDIALOG_HPP_ +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#endif + +#ifndef _SBA_GRID_HXX +#include "sbagrid.hxx" +#endif +#ifndef DBAUI_SBATTRDLG_HXX +#include "dlgattr.hxx" +#endif +#ifndef _DBAUI_DLGSIZE_HXX +#include "dlgsize.hxx" +#endif +#ifndef _COM_SUN_STAR_FORM_XLOADABLE_HPP_ +#include <com/sun/star/form/XLoadable.hpp> +#endif +#ifndef _COM_SUN_STAR_SDB_COMMANDTYPE_HPP_ +#include <com/sun/star/sdb/CommandType.hpp> +#endif +#ifndef _COM_SUN_STAR_SDB_XSQLQUERYCOMPOSERFACTORY_HPP_ +#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp> +#endif +#ifndef _COM_SUN_STAR_SDB_XRESULTSETACCESS_HPP_ +#include <com/sun/star/sdb/XResultSetAccess.hpp> +#endif +#ifndef _COM_SUN_STAR_FORM_XFORM_HPP_ +#include <com/sun/star/form/XForm.hpp> +#endif +#ifndef _COM_SUN_STAR_CONTAINER_XINDEXCONTAINER_HPP_ +#include <com/sun/star/container/XIndexContainer.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_NUMBERFORMAT_HPP_ +#include <com/sun/star/util/NumberFormat.hpp> +#endif + +#ifndef _COM_SUN_STAR_VIEW_XSELECTIONSUPPLIER_HPP_ +#include <com/sun/star/view/XSelectionSupplier.hpp> +#endif +#ifndef _COM_SUN_STAR_FORM_DATASELECTIONTYPE_HPP_ +#include <com/sun/star/form/DataSelectionType.hpp> +#endif +#ifndef _COM_SUN_STAR_AWT_TEXTALIGN_HPP_ +#include <com/sun/star/awt/TextAlign.hpp> +#endif +#ifndef _COM_SUN_STAR_AWT_XTEXTCOMPONENT_HPP_ +#include <com/sun/star/awt/XTextComponent.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_DATE_HPP_ +#include <com/sun/star/util/Date.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_TIME_HPP_ +#include <com/sun/star/util/Time.hpp> +#endif +#ifndef _COM_SUN_STAR_UTIL_DATETIME_HPP_ +#include <com/sun/star/util/DateTime.hpp> +#endif +#ifndef _COM_SUN_STAR_SDBC_XRESULTSETUPDATE_HPP_ +#include <com/sun/star/sdbc/XResultSetUpdate.hpp> +#endif +#ifndef _URLOBJ_HXX +#include <tools/urlobj.hxx> +#endif +#ifndef TOOLS_DIAGNOSE_EX_H +#include <tools/diagnose_ex.h> +#endif + +#ifndef _SFXINTITEM_HXX +#include <svl/intitem.hxx> +#endif + +#ifndef _SVX_ALGITEM_HXX //autogen +#include <svx/algitem.hxx> +#endif + +#ifndef _SV_MULTISEL_HXX //autogen +#include <tools/multisel.hxx> +#endif + +#ifndef _SVX_SVXIDS_HRC +#include <svx/svxids.hrc> +#endif + +#ifndef _NUMUNO_HXX +#include <svl/numuno.hxx> +#endif + +#ifndef _SFXITEMPOOL_HXX //autogen wg. SfxItemInfo +#include <svl/itempool.hxx> +#endif + +#ifndef _SFXITEMSET_HXX //autogen wg. SfxItemSet +#include <svl/itemset.hxx> +#endif + +#ifndef _SFXRNGITEM_HXX +#include <svl/rngitem.hxx> +#endif + +#ifndef _SV_WAITOBJ_HXX +#include <vcl/waitobj.hxx> +#endif +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/helper/vclunohelper.hxx> +#endif + +#ifndef _ZFORLIST_HXX +#include <svl/zforlist.hxx> +#endif +#ifndef _CPPUHELPER_QUERYINTERFACE_HXX_ +#include <cppuhelper/queryinterface.hxx> +#endif +#ifndef _CONNECTIVITY_DBTOOLS_HXX_ +#include <connectivity/dbtools.hxx> +#endif +#ifndef _DBHELPER_DBCONVERSION_HXX_ +#include <connectivity/dbconversion.hxx> +#endif +#ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ +#include <cppuhelper/typeprovider.hxx> +#endif +#ifndef _RTL_UUID_H_ +#include <rtl/uuid.h> +#endif +#ifndef _RTL_MEMORY_H_ +#include <rtl/memory.h> +#endif +#ifndef _COMPHELPER_EXTRACT_HXX_ +#include <comphelper/extract.hxx> +#endif +#ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_ +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +#endif +#ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_ +#include <com/sun/star/sdbc/DataType.hpp> +#endif +#ifndef _SV_MSGBOX_HXX +#include <vcl/msgbox.hxx> +#endif +#ifndef _SVX_DBEXCH_HRC +#include <svx/dbexch.hrc> +#endif +#ifndef _DBU_BRW_HRC_ +#include "dbu_brw.hrc" +#endif +#ifndef DBACCESS_UI_BROWSER_ID_HXX +#include "browserids.hxx" +#endif +#ifndef DBACCESS_SHARED_DBUSTRINGS_HRC +#include "dbustrings.hrc" +#endif +#ifndef _DBU_REGHELPER_HXX_ +#include "dbu_reghelper.hxx" +#endif +#ifndef DBAUI_DBEXCHANGE_HXX +#include "dbexchange.hxx" +#endif +#ifndef DBAUI_TABLEROW_EXCHANGE_HXX +#include "TableRowExchange.hxx" +#endif +#ifndef DBAUI_TABLEROW_HXX +#include "TableRow.hxx" +#endif +#ifndef DBAUI_FIELDDESCRIPTIONS_HXX +#include "FieldDescriptions.hxx" +#endif +#ifndef _SVTOOLS_STRINGTRANSFER_HXX_ +#include <svtools/stringtransfer.hxx> +#endif +#ifndef _VCL_STDTEXT_HXX +#include <vcl/stdtext.hxx> +#endif +#ifndef DBAUI_TOOLS_HXX +#include "UITools.hxx" +#endif +#ifndef DBAUI_TOKENWRITER_HXX +#include "TokenWriter.hxx" +#endif + +using namespace ::com::sun::star::ui::dialogs; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::view; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::util; +using namespace ::dbaui; +using namespace ::dbtools; +using namespace ::svx; +using namespace ::svt; + +extern "C" void SAL_CALL createRegistryInfo_SbaXGridControl() +{ + static OMultiInstanceAutoRegistration< SbaXGridControl > aAutoRegistration; +} +//------------------------------------------------------------------------- +::comphelper::StringSequence SAL_CALL SbaXGridControl::getSupportedServiceNames() throw() +{ + return getSupportedServiceNames_Static(); +} +// ------------------------------------------------------------------------- +Reference< XInterface > SAL_CALL SbaXGridControl::Create(const Reference<XMultiServiceFactory >& _rxFactory) +{ + return *(new SbaXGridControl(_rxFactory)); +} + +//------------------------------------------------------------------ + +//------------------------------------------------------------------ +//======================================================================================= +// SbaXGridControl +//======================================================================================= + +//------------------------------------------------------------------------------ +::rtl::OUString SAL_CALL SbaXGridControl::getImplementationName() throw() +{ + return getImplementationName_Static(); +} + +//------------------------------------------------------------------------------ +::rtl::OUString SbaXGridControl::getImplementationName_Static() throw( RuntimeException ) +{ + return ::rtl::OUString::createFromAscii("com.sun.star.comp.dbu.SbaXGridControl"); +} + +//------------------------------------------------------------------------------ +Sequence< ::rtl::OUString> SbaXGridControl::getSupportedServiceNames_Static(void) throw( RuntimeException ) +{ + Sequence< ::rtl::OUString> aSupported(3); + aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.form.control.InteractionGridControl"); + aSupported[1] = ::rtl::OUString::createFromAscii("com.sun.star.form.control.GridControl"); + aSupported[2] = ::rtl::OUString::createFromAscii("com.sun.star.awt.UnoControl"); + return aSupported; +} +DBG_NAME(SbaXGridControl ); +//--------------------------------------------------------------------------------------- +SbaXGridControl::SbaXGridControl(const Reference< XMultiServiceFactory >& _rM) + : FmXGridControl(_rM) +{ + DBG_CTOR(SbaXGridControl ,NULL); +} + +//--------------------------------------------------------------------------------------- +SbaXGridControl::~SbaXGridControl() +{ + DBG_DTOR(SbaXGridControl ,NULL); +} + +//--------------------------------------------------------------------------------------- +FmXGridPeer* SbaXGridControl::imp_CreatePeer(Window* pParent) +{ + FmXGridPeer* pReturn = new SbaXGridPeer(m_xServiceFactory); + + // translate properties into WinBits + WinBits nStyle = WB_TABSTOP; + Reference< XPropertySet > xModelSet(getModel(), UNO_QUERY); + if (xModelSet.is()) + { + try + { + if (::comphelper::getINT16(xModelSet->getPropertyValue(PROPERTY_BORDER))) + nStyle |= WB_BORDER; + } + catch(Exception&) + { + } + + } + + pReturn->Create(pParent, nStyle); + return pReturn; +} + +//------------------------------------------------------------------------------ +Any SAL_CALL SbaXGridControl::queryInterface(const Type& _rType) throw (RuntimeException) +{ + Any aRet = FmXGridControl::queryInterface(_rType); + return aRet.hasValue() ? aRet : ::cppu::queryInterface(_rType,(::com::sun::star::frame::XDispatch*)this); +} + +//------------------------------------------------------------------------------ +Sequence< Type > SAL_CALL SbaXGridControl::getTypes( ) throw (RuntimeException) +{ + Sequence< Type > aTypes = FmXGridControl::getTypes(); + + sal_Int32 nTypes = aTypes.getLength(); + aTypes.realloc(nTypes + 1); + aTypes[nTypes] = ::getCppuType(static_cast< Reference< ::com::sun::star::frame::XDispatch >* >(NULL)); + + return aTypes; +} + +//------------------------------------------------------------------------------ +Sequence< sal_Int8 > SAL_CALL SbaXGridControl::getImplementationId( ) throw (RuntimeException) +{ + static ::cppu::OImplementationId * pId = 0; + if (! pId) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pId) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridControl::createPeer(const Reference< ::com::sun::star::awt::XToolkit > & rToolkit, const Reference< ::com::sun::star::awt::XWindowPeer > & rParentPeer) throw( RuntimeException ) +{ + FmXGridControl::createPeer(rToolkit, rParentPeer); + + DBG_ASSERT(/*(0 == m_nPeerCreationLevel) && */!mbCreatingPeer, "FmXGridControl::createPeer : recursion!"); + // see the base class' createPeer for a comment on this + // 14.05.2001 - 86836 - frank.schoenheit@germany.sun.com + + // TODO: why the hell this whole class does not use any mutex? + +// if (0 == m_nPeerCreationLevel) + { + Reference< ::com::sun::star::frame::XDispatch > xDisp(getPeer(), UNO_QUERY); + for ( StatusMultiplexerArray::iterator aIter = m_aStatusMultiplexer.begin(); + aIter != m_aStatusMultiplexer.end(); + ++aIter) + { + if ((*aIter).second && (*aIter).second->getLength()) + xDisp->addStatusListener((*aIter).second, (*aIter).first); + } + } +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridControl::dispatch(const ::com::sun::star::util::URL& aURL, const Sequence< PropertyValue >& aArgs) throw( RuntimeException ) +{ + Reference< ::com::sun::star::frame::XDispatch > xDisp(getPeer(), UNO_QUERY); + if (xDisp.is()) + xDisp->dispatch(aURL, aArgs); +} +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridControl::addStatusListener( const Reference< XStatusListener > & _rxListener, const URL& _rURL ) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + if ( _rxListener.is() ) + { + SbaXStatusMultiplexer*& pMultiplexer = m_aStatusMultiplexer[ _rURL ]; + if ( !pMultiplexer ) + { + pMultiplexer = new SbaXStatusMultiplexer( *this, GetMutex() ); + pMultiplexer->acquire(); + } + + pMultiplexer->addInterface( _rxListener ); + if ( getPeer().is() ) + { + if ( 1 == pMultiplexer->getLength() ) + { // the first external listener for this URL + Reference< XDispatch > xDisp( getPeer(), UNO_QUERY ); + xDisp->addStatusListener( pMultiplexer, _rURL ); + } + else + { // already have other listeners for this URL + _rxListener->statusChanged( pMultiplexer->getLastEvent() ); + } + } + } +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridControl::removeStatusListener(const Reference< ::com::sun::star::frame::XStatusListener > & _rxListener, const ::com::sun::star::util::URL& _rURL) throw( RuntimeException ) +{ + ::osl::MutexGuard aGuard( GetMutex() ); + + SbaXStatusMultiplexer*& pMultiplexer = m_aStatusMultiplexer[_rURL]; + if (!pMultiplexer) + { + pMultiplexer = new SbaXStatusMultiplexer(*this,GetMutex()); + pMultiplexer->acquire(); + } + + if (getPeer().is() && pMultiplexer->getLength() == 1) + { + Reference< ::com::sun::star::frame::XDispatch > xDisp(getPeer(), UNO_QUERY); + xDisp->removeStatusListener(pMultiplexer, _rURL); + } + pMultiplexer->removeInterface( _rxListener ); +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridControl::dispose(void) throw( RuntimeException ) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + EventObject aEvt; + aEvt.Source = *this; + + for ( StatusMultiplexerArray::iterator aIter = m_aStatusMultiplexer.begin(); + aIter != m_aStatusMultiplexer.end(); + ++aIter) + { + if ((*aIter).second) + { + (*aIter).second->disposeAndClear(aEvt); + (*aIter).second->release(); + (*aIter).second = NULL; + } + } + StatusMultiplexerArray().swap(m_aStatusMultiplexer); + + FmXGridControl::dispose(); +} + +//======================================================================================= +// SbaXGridPeer +//======================================================================================= +DBG_NAME(SbaXGridPeer ) +//--------------------------------------------------------------------------------------- +SbaXGridPeer::SbaXGridPeer(const Reference< XMultiServiceFactory >& _rM) +: FmXGridPeer(_rM) +,m_aStatusListeners(m_aMutex) +{ + DBG_CTOR(SbaXGridPeer ,NULL); +} + +//--------------------------------------------------------------------------------------- +SbaXGridPeer::~SbaXGridPeer() +{ + DBG_DTOR(SbaXGridPeer ,NULL); +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridPeer::dispose(void) throw( RuntimeException ) +{ + EventObject aEvt(*this); + + m_aStatusListeners.disposeAndClear(aEvt); + + FmXGridPeer::dispose(); +} + +//--------------------------------------------------------------------------------------- +void SbaXGridPeer::NotifyStatusChanged(const ::com::sun::star::util::URL& _rUrl, const Reference< ::com::sun::star::frame::XStatusListener > & xControl) +{ + SbaGridControl* pGrid = (SbaGridControl*) GetWindow(); + if (!pGrid) + return; + + ::com::sun::star::frame::FeatureStateEvent aEvt; + aEvt.Source = *this; + aEvt.IsEnabled = !pGrid->IsReadOnlyDB(); + aEvt.FeatureURL = _rUrl; + + ConstMapDispatchToBoolIterator aURLStatePos = m_aDispatchStates.find( classifyDispatchURL( _rUrl ) ); + if ( m_aDispatchStates.end() != aURLStatePos ) + aEvt.State <<= aURLStatePos->second; + else + aEvt.State <<= sal_False; + + if (xControl.is()) + xControl->statusChanged(aEvt); + else + { + ::cppu::OInterfaceContainerHelper * pIter = m_aStatusListeners.getContainer(_rUrl); + + if (pIter) + { + ::cppu::OInterfaceIteratorHelper aListIter(*pIter); + while (aListIter.hasMoreElements()) + ((::com::sun::star::frame::XStatusListener*)aListIter.next())->statusChanged(aEvt); + } + } +} + +//------------------------------------------------------------------------------ +Any SAL_CALL SbaXGridPeer::queryInterface(const Type& _rType) throw (RuntimeException) +{ + Any aRet = ::cppu::queryInterface(_rType,(::com::sun::star::frame::XDispatch*)this); + if(aRet.hasValue()) + return aRet; + return FmXGridPeer::queryInterface(_rType); +} + +//--------------------------------------------------------------------------------------- +Reference< ::com::sun::star::frame::XDispatch > SAL_CALL SbaXGridPeer::queryDispatch(const ::com::sun::star::util::URL& aURL, const ::rtl::OUString& aTargetFrameName, sal_Int32 nSearchFlags) throw( RuntimeException ) +{ + if ( (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/BrowserAttribs"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/RowHeight"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/ColumnAttribs"))) + || (aURL.Complete.equals(::rtl::OUString::createFromAscii(".uno:GridSlots/ColumnWidth"))) + ) + { + return (::com::sun::star::frame::XDispatch*)this; + } + + return FmXGridPeer::queryDispatch(aURL, aTargetFrameName, nSearchFlags); +} + +//--------------------------------------------------------------------------------------- +IMPL_LINK( SbaXGridPeer, OnDispatchEvent, void*, /*NOTINTERESTEDIN*/ ) +{ + SbaGridControl* pGrid = static_cast< SbaGridControl* >( GetWindow() ); + if ( pGrid ) // if this fails, we were disposing before arriving here + { + if ( Application::GetMainThreadIdentifier() != ::vos::OThread::getCurrentIdentifier() ) + { + // still not in the main thread (see SbaXGridPeer::dispatch). post an event, again + // without moving the special even to the back of the queue + pGrid->PostUserEvent( LINK( this, SbaXGridPeer, OnDispatchEvent ) ); + } + else + { + DispatchArgs aArgs = m_aDispatchArgs.front(); + m_aDispatchArgs.pop(); + + SbaXGridPeer::dispatch( aArgs.aURL, aArgs.aArgs ); + } + } + + return 0; +} + +//--------------------------------------------------------------------------------------- +SbaXGridPeer::DispatchType SbaXGridPeer::classifyDispatchURL( const URL& _rURL ) +{ + DispatchType eURLType = dtUnknown; + if ( _rURL.Complete.equalsAscii( ".uno:GridSlots/BrowserAttribs" ) ) + eURLType = dtBrowserAttribs; + else if ( _rURL.Complete.equalsAscii( ".uno:GridSlots/RowHeight" ) ) + eURLType = dtRowHeight; + else if ( _rURL.Complete.equalsAscii( ".uno:GridSlots/ColumnAttribs" ) ) + eURLType = dtColumnAttribs; + else if ( _rURL.Complete.equalsAscii( ".uno:GridSlots/ColumnWidth" ) ) + eURLType = dtColumnWidth; + return eURLType; +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridPeer::dispatch(const URL& aURL, const Sequence< PropertyValue >& aArgs) throw( RuntimeException ) +{ + SbaGridControl* pGrid = (SbaGridControl*)GetWindow(); + if (!pGrid) + return; + + if ( Application::GetMainThreadIdentifier() != ::vos::OThread::getCurrentIdentifier() ) + { + // we're not in the main thread. This is bad, as we want to raise windows here, + // and VCL does not like windows to be opened in non-main threads (at least on Win32). + // Okay, do this async. No problem with this, as XDispatch::dispatch is defined to be + // a one-way method. + + // save the args + DispatchArgs aDispatchArgs; + aDispatchArgs.aURL = aURL; + aDispatchArgs.aArgs = aArgs; + m_aDispatchArgs.push( aDispatchArgs ); + + // post an event + // we use the Window::PostUserEvent here, instead of the application::PostUserEvent + // this saves us from keeping track of these events - as soon as the window dies, + // the events are deleted automatically. For the application way, we would need to + // do this ourself. + // As we use our grid as window, and the grid dies before we dy, this should be no problem. + pGrid->PostUserEvent( LINK( this, SbaXGridPeer, OnDispatchEvent ) ); + return; + } + + ::vos::OGuard aGuard(Application::GetSolarMutex()); + sal_Int16 nColId = -1; + const PropertyValue* pArgs = aArgs.getConstArray(); + for (sal_uInt16 i=0; i<aArgs.getLength(); ++i, ++pArgs) + { + if (pArgs->Name == ::rtl::OUString::createFromAscii("ColumnViewPos")) + { + nColId = pGrid->GetColumnIdFromViewPos(::comphelper::getINT16(pArgs->Value)); + break; + } + if (pArgs->Name == ::rtl::OUString::createFromAscii("ColumnModelPos")) + { + nColId = pGrid->GetColumnIdFromModelPos(::comphelper::getINT16(pArgs->Value)); + break; + } + if (pArgs->Name == ::rtl::OUString::createFromAscii("ColumnId")) + { + nColId = ::comphelper::getINT16(pArgs->Value); + break; + } + } + + DispatchType eURLType = classifyDispatchURL( aURL ); + + if ( dtUnknown != eURLType ) + { + // notify any status listeners that the dialog is now active (well, about to be active) + MapDispatchToBool::iterator aThisURLState = m_aDispatchStates.insert( MapDispatchToBool::value_type( eURLType, sal_True ) ).first; + NotifyStatusChanged( aURL, NULL ); + + // execute the dialog + switch ( eURLType ) + { + case dtBrowserAttribs: + pGrid->SetBrowserAttrs(); + break; + + case dtRowHeight: + pGrid->SetRowHeight(); + break; + + case dtColumnAttribs: + { + DBG_ASSERT(nColId != -1, "SbaXGridPeer::dispatch : invalid parameter !"); + if (nColId != -1) + break; + pGrid->SetColAttrs(nColId); + } + break; + + case dtColumnWidth: + { + DBG_ASSERT(nColId != -1, "SbaXGridPeer::dispatch : invalid parameter !"); + if (nColId != -1) + break; + pGrid->SetColWidth(nColId); + } + break; + + case dtUnknown: + break; + } + + // notify any status listeners that the dialog vanished + m_aDispatchStates.erase( aThisURLState ); + NotifyStatusChanged( aURL, NULL ); + } +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridPeer::addStatusListener(const Reference< ::com::sun::star::frame::XStatusListener > & xControl, const ::com::sun::star::util::URL& aURL) throw( RuntimeException ) +{ + ::cppu::OInterfaceContainerHelper* pCont = m_aStatusListeners.getContainer(aURL); + if (!pCont) + m_aStatusListeners.addInterface(aURL,xControl); + else + pCont->addInterface(xControl); + NotifyStatusChanged(aURL, xControl); +} + +//--------------------------------------------------------------------------------------- +void SAL_CALL SbaXGridPeer::removeStatusListener(const Reference< ::com::sun::star::frame::XStatusListener > & xControl, const ::com::sun::star::util::URL& aURL) throw( RuntimeException ) +{ + ::cppu::OInterfaceContainerHelper* pCont = m_aStatusListeners.getContainer(aURL); + if ( pCont ) + pCont->removeInterface(xControl); +} + +//--------------------------------------------------------------------------------------- +const Sequence< sal_Int8 > & SbaXGridPeer::getUnoTunnelId() +{ + static Sequence< sal_Int8 > * pSeq = 0; + if( !pSeq ) + { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0,sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +//--------------------------------------------------------------------------------------- +Sequence< Type > SAL_CALL SbaXGridPeer::getTypes() throw (RuntimeException) +{ + Sequence< Type > aTypes = FmXGridPeer::getTypes(); + sal_Int32 nOldLen = aTypes.getLength(); + aTypes.realloc(nOldLen + 1); + aTypes.getArray()[nOldLen] = ::getCppuType( reinterpret_cast< Reference< ::com::sun::star::frame::XDispatch >* >(NULL) ); + + return aTypes; +} + +// return implementation specific data +//------------------------------------------------------------------ +sal_Int64 SAL_CALL SbaXGridPeer::getSomething( const Sequence< sal_Int8 > & rId ) throw(::com::sun::star::uno::RuntimeException) +{ + if( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) + return reinterpret_cast< sal_Int64 >( this ); + + return FmXGridPeer::getSomething(rId); +} + +//--------------------------------------------------------------------------------------- +SbaXGridPeer* SbaXGridPeer::getImplementation(const Reference< XInterface >& _rxIFace) +{ + Reference< XUnoTunnel > xTunnel( + _rxIFace, UNO_QUERY); + if (xTunnel.is()) + return reinterpret_cast<SbaXGridPeer*>(xTunnel->getSomething(getUnoTunnelId())); + return NULL; +} + +//--------------------------------------------------------------------------------------- +FmGridControl* SbaXGridPeer::imp_CreateControl(Window* pParent, WinBits nStyle) +{ + return new SbaGridControl(m_xServiceFactory, pParent, this, nStyle); +} + +//================================================================== +// SbaGridHeader +//================================================================== + +//--------------------------------------------------------------------------------------- +SbaGridHeader::SbaGridHeader(BrowseBox* pParent, WinBits nWinBits) + :FmGridHeader(pParent, nWinBits) + ,DragSourceHelper(this) +{ +} + +//--------------------------------------------------------------------------------------- +void SbaGridHeader::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel ) +{ + ::vos::OGuard aGuard(Application::GetSolarMutex()); + // in the new DnD API, the solar mutex is not locked when StartDrag get's called + + ImplStartColumnDrag( _nAction, _rPosPixel ); +} + +//--------------------------------------------------------------------------------------- +void SbaGridHeader::MouseButtonDown( const MouseEvent& _rMEvt ) +{ + if (_rMEvt.IsLeft()) + if (_rMEvt.GetClicks() != 2) + { + // the base class will start a column move here, which we don't want to allow + // (at the moment. If we store relative positions with the columns, we can allow column moves ....) + +// sal_uInt16 nPos(0); +// sal_uInt16 nHitTest = ImplHitTest( _rMEvt.GetPosPixel(), mnMouseOff, nPos ); +// if (!nHitTest & HEAD_HITTEST_DIVIDER) +// return; + } + + FmGridHeader::MouseButtonDown(_rMEvt); +} + +//--------------------------------------------------------------------------------------- +sal_Bool SbaGridHeader::ImplStartColumnDrag(sal_Int8 _nAction, const Point& _rMousePos) +{ + sal_uInt16 nId = GetItemId(_rMousePos); + sal_Bool bResizingCol = sal_False; + if (HEADERBAR_ITEM_NOTFOUND != nId) + { + Rectangle aColRect = GetItemRect(nId); + aColRect.Left() += nId ? 3 : 0; // the handle col (nId == 0) does not have a left margin for resizing + aColRect.Right() -= 3; + bResizingCol = !aColRect.IsInside(_rMousePos); + } + if (!bResizingCol) + { + // force the the base class to end it's drag mode + EndTracking(ENDTRACK_CANCEL | ENDTRACK_END); + + // because we have 3d-buttons the select handler is called from MouseButtonUp, but StartDrag + // occures earlier (while the mouse button is down) + // so for optical reasons we select the column before really starting the drag operation. + notifyColumnSelect(nId); + + static_cast<SbaGridControl*>(GetParent())->StartDrag(_nAction, + Point( + _rMousePos.X() + GetPosPixel().X(), // we aren't left-justified with our parent, in contrast to the data window + _rMousePos.Y() - GetSizePixel().Height() + ) + ); + return sal_True; + } + + return sal_False; +} + +//--------------------------------------------------------------------------------------- +void SbaGridHeader::PreExecuteColumnContextMenu(sal_uInt16 nColId, PopupMenu& rMenu) +{ + FmGridHeader::PreExecuteColumnContextMenu(nColId, rMenu); + + // some items are valid only if the db isn't readonly + sal_Bool bDBIsReadOnly = ((SbaGridControl*)GetParent())->IsReadOnlyDB(); + + if (bDBIsReadOnly) + { + rMenu.EnableItem(SID_FM_HIDECOL, sal_False); + PopupMenu* pShowColsMenu = rMenu.GetPopupMenu(SID_FM_SHOWCOLS); + if (pShowColsMenu) + { + // at most 16 items which mean "show column <name>" + for (sal_uInt16 i=1; i<16; ++i) + pShowColsMenu->EnableItem(i, sal_False); + // "show cols/more..." and "show cols/all" + pShowColsMenu->EnableItem(SID_FM_SHOWCOLS_MORE, sal_False); + pShowColsMenu->EnableItem(SID_FM_SHOWALLCOLS, sal_False); + } + } + + // prepend some new items + sal_Bool bColAttrs = (nColId != (sal_uInt16)-1) && (nColId != 0); + if ( bColAttrs && !bDBIsReadOnly) + { + PopupMenu aNewItems(ModuleRes(RID_SBA_GRID_COLCTXMENU)); + sal_uInt16 nPos = 0; + sal_uInt16 nModelPos = ((SbaGridControl*)GetParent())->GetModelColumnPos(nColId); + Reference< XPropertySet > xField = ((SbaGridControl*)GetParent())->getField(nModelPos); + + if ( xField.is() ) + { + switch( ::comphelper::getINT32(xField->getPropertyValue(PROPERTY_TYPE)) ) + { + case DataType::BINARY: + case DataType::VARBINARY: + case DataType::LONGVARBINARY: + case DataType::SQLNULL: + case DataType::OBJECT: + case DataType::BLOB: + case DataType::CLOB: + case DataType::REF: + break; + default: + rMenu.InsertItem(ID_BROWSER_COLATTRSET, aNewItems.GetItemText(ID_BROWSER_COLATTRSET), 0, nPos++); + rMenu.SetHelpId(ID_BROWSER_COLATTRSET, aNewItems.GetHelpId(ID_BROWSER_COLATTRSET)); + rMenu.InsertSeparator(nPos++); + } + } + + rMenu.InsertItem(ID_BROWSER_COLWIDTH, aNewItems.GetItemText(ID_BROWSER_COLWIDTH), 0, nPos++); + rMenu.SetHelpId(ID_BROWSER_COLWIDTH, aNewItems.GetHelpId(ID_BROWSER_COLWIDTH)); + rMenu.InsertSeparator(nPos++); + } +} + +//--------------------------------------------------------------------------------------- +void SbaGridHeader::PostExecuteColumnContextMenu(sal_uInt16 nColId, const PopupMenu& rMenu, sal_uInt16 nExecutionResult) +{ + switch (nExecutionResult) + { + case ID_BROWSER_COLWIDTH: + ((SbaGridControl*)GetParent())->SetColWidth(nColId); + break; + + case ID_BROWSER_COLATTRSET: + ((SbaGridControl*)GetParent())->SetColAttrs(nColId); + break; + case ID_BROWSER_COLUMNINFO: + { + sal_uInt16 nModelPos = ((SbaGridControl*)GetParent())->GetModelColumnPos(nColId); + Reference< XPropertySet > xField = ((SbaGridControl*)GetParent())->getField(nModelPos); + + if(!xField.is()) + break; + ::std::vector< ::boost::shared_ptr<OTableRow> > vClipboardList; + // send it to the clipboard + vClipboardList.push_back(::boost::shared_ptr<OTableRow>(new OTableRow(xField))); + OTableRowExchange* pData = new OTableRowExchange(vClipboardList); + Reference< ::com::sun::star::datatransfer::XTransferable> xRef = pData; + pData->CopyToClipboard(GetParent()); + } + break; + + default: FmGridHeader::PostExecuteColumnContextMenu(nColId, rMenu, nExecutionResult); + } +} + +//================================================================== +// SbaGridControl +//================================================================== +DBG_NAME(SbaGridControl ); +//--------------------------------------------------------------------------------------- +SbaGridControl::SbaGridControl(Reference< XMultiServiceFactory > _rM, + Window* pParent, FmXGridPeer* _pPeer, WinBits nBits) + :FmGridControl(_rM,pParent, _pPeer, nBits) + ,m_pMasterListener(NULL) + ,m_nAsyncDropEvent(0) + ,m_nCurrentActionColId((USHORT)-1) + ,m_bActivatingForDrop(sal_False) +{ + DBG_CTOR(SbaGridControl ,NULL); +} + +//--------------------------------------------------------------------------------------- +SbaGridControl::~SbaGridControl() +{ + DBG_DTOR(SbaGridControl ,NULL); + if (m_nAsyncDropEvent) + Application::RemoveUserEvent(m_nAsyncDropEvent); +} + +//--------------------------------------------------------------------------------------- +BrowserHeader* SbaGridControl::imp_CreateHeaderBar(BrowseBox* pParent) +{ + return new SbaGridHeader(pParent); +} + +//--------------------------------------------------------------------------------------- +CellController* SbaGridControl::GetController(long nRow, sal_uInt16 nCol) +{ + if ( m_bActivatingForDrop ) + return NULL; + + return FmGridControl::GetController(nRow, nCol); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::PreExecuteRowContextMenu(sal_uInt16 nRow, PopupMenu& rMenu) +{ + FmGridControl::PreExecuteRowContextMenu(nRow, rMenu); + + PopupMenu aNewItems(ModuleRes(RID_SBA_GRID_ROWCTXMENU)); + sal_uInt16 nPos = 0; + + if (!IsReadOnlyDB()) + { + rMenu.InsertItem(ID_BROWSER_TABLEATTR, aNewItems.GetItemText(ID_BROWSER_TABLEATTR), 0, nPos++); + rMenu.SetHelpId(ID_BROWSER_TABLEATTR, aNewItems.GetHelpId(ID_BROWSER_TABLEATTR)); + + rMenu.InsertItem(ID_BROWSER_ROWHEIGHT, aNewItems.GetItemText(ID_BROWSER_ROWHEIGHT), 0, nPos++); + rMenu.SetHelpId(ID_BROWSER_ROWHEIGHT, aNewItems.GetHelpId(ID_BROWSER_ROWHEIGHT)); + rMenu.InsertSeparator(nPos++); + } // if (!IsReadOnlyDB()) + + if ( GetSelectRowCount() > 0 ) + { + rMenu.InsertItem(ID_BROWSER_COPY, aNewItems.GetItemText(SID_COPY), 0, nPos++); + rMenu.SetHelpId(ID_BROWSER_COPY, aNewItems.GetHelpId(SID_COPY)); + + rMenu.InsertSeparator(nPos++); + } +} + +//------------------------------------------------------------------------------ +SvNumberFormatter* SbaGridControl::GetDatasourceFormatter() +{ + Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = ::dbtools::getNumberFormats(::dbtools::getConnection(Reference< XRowSet > (getDataSource(),UNO_QUERY)), sal_True,getServiceManager()); + + SvNumberFormatsSupplierObj* pSupplierImpl = SvNumberFormatsSupplierObj::getImplementation( xSupplier ); + if ( !pSupplierImpl ) + return NULL; + + SvNumberFormatter* pFormatter = pSupplierImpl->GetNumberFormatter(); + return pFormatter; +} + +//------------------------------------------------------------------------------ +void SbaGridControl::SetColWidth(sal_uInt16 nColId) +{ + // get the (UNO) column model + sal_uInt16 nModelPos = GetModelColumnPos(nColId); + Reference< XIndexAccess > xCols(GetPeer()->getColumns(), UNO_QUERY); + Reference< XPropertySet > xAffectedCol; + if (xCols.is() && (nModelPos != (sal_uInt16)-1)) + ::cppu::extractInterface(xAffectedCol,xCols->getByIndex(nModelPos)); + + if (xAffectedCol.is()) + { + Any aWidth = xAffectedCol->getPropertyValue(PROPERTY_WIDTH); + sal_Int32 nCurWidth = aWidth.hasValue() ? ::comphelper::getINT32(aWidth) : -1; + + DlgSize aDlgColWidth(this, nCurWidth, sal_False); + if (aDlgColWidth.Execute()) + { + sal_Int32 nValue = aDlgColWidth.GetValue(); + Any aNewWidth; + if (-1 == nValue) + { // set to default + Reference< XPropertyState > xPropState(xAffectedCol, UNO_QUERY); + if (xPropState.is()) + { + try { aNewWidth = xPropState->getPropertyDefault(PROPERTY_WIDTH); } catch(Exception&) { } ; + } + } + else + aNewWidth <<= nValue; + try { xAffectedCol->setPropertyValue(PROPERTY_WIDTH, aNewWidth); } catch(Exception&) { } ; + } + } +} + +//------------------------------------------------------------------------------ +void SbaGridControl::SetRowHeight() +{ + Reference< XPropertySet > xCols(GetPeer()->getColumns(), UNO_QUERY); + if (!xCols.is()) + return; + + Any aHeight = xCols->getPropertyValue(PROPERTY_ROW_HEIGHT); + sal_Int32 nCurHeight = aHeight.hasValue() ? ::comphelper::getINT32(aHeight) : -1; + + DlgSize aDlgRowHeight(this, nCurHeight, sal_True); + if (aDlgRowHeight.Execute()) + { + sal_Int32 nValue = aDlgRowHeight.GetValue(); + Any aNewHeight; + if ((sal_Int16)-1 == nValue) + { // set to default + Reference< XPropertyState > xPropState(xCols, UNO_QUERY); + if (xPropState.is()) + { + try + { + aNewHeight = xPropState->getPropertyDefault(PROPERTY_ROW_HEIGHT); + } + catch(Exception&) + { } + } + } + else + aNewHeight <<= nValue; + try + { + xCols->setPropertyValue(PROPERTY_ROW_HEIGHT, aNewHeight); + } + catch(Exception&) + { + OSL_ENSURE(0,"setPropertyValue: PROPERTY_ROW_HEIGHT throws a exception"); + } + } +} + +//------------------------------------------------------------------------------ +void SbaGridControl::SetColAttrs(sal_uInt16 nColId) +{ + SvNumberFormatter* pFormatter = GetDatasourceFormatter(); + if (!pFormatter) + return; + + sal_uInt16 nModelPos = GetModelColumnPos(nColId); + + // get the (UNO) column model + Reference< XIndexAccess > xCols(GetPeer()->getColumns(), UNO_QUERY); + Reference< XPropertySet > xAffectedCol; + if (xCols.is() && (nModelPos != (sal_uInt16)-1)) + ::cppu::extractInterface(xAffectedCol,xCols->getByIndex(nModelPos)); + + // get the field the column is bound to + Reference< XPropertySet > xField = getField(nModelPos); + ::dbaui::callColumnFormatDialog(xAffectedCol,xField,pFormatter,this);//(Window::GetSettings().GetLanguage()); +} + + +//------------------------------------------------------------------------------ +void SbaGridControl::SetBrowserAttrs() +{ + Reference< XPropertySet > xGridModel(GetPeer()->getColumns(), UNO_QUERY); + if (!xGridModel.is()) + return; + + try + { + PropertyValue aArg; + aArg.Name = ::rtl::OUString::createFromAscii("IntrospectedObject"); + aArg.Value <<= xGridModel; + Sequence< Any > aDialogArgs(1); + aDialogArgs[0] <<= aArg; + + Reference< XInterface > xDialog = getServiceManager()->createInstanceWithArguments( + ::rtl::OUString::createFromAscii("com.sun.star.form.ControlFontDialog"), + aDialogArgs + ); + if (!xDialog.is()) + { + ShowServiceNotAvailableError(this, String::CreateFromAscii("com.sun.star.form.ControlFontDialog"), sal_True); + return; + } + + Reference< XExecutableDialog > xExecute(xDialog, UNO_QUERY); + OSL_ENSURE(xExecute.is(), "SbaGridControl::SetBrowserAttrs: missing an interface on the dialog!"); + if (xExecute.is()) + xExecute->execute(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::PostExecuteRowContextMenu(sal_uInt16 nRow, const PopupMenu& rMenu, sal_uInt16 nExecutionResult) +{ + switch (nExecutionResult) + { + case ID_BROWSER_TABLEATTR: + SetBrowserAttrs(); + break; + case ID_BROWSER_ROWHEIGHT: + SetRowHeight(); + break; + case ID_BROWSER_COPY: + CopySelectedRowsToClipboard(); + break; + + default: + FmGridControl::PostExecuteRowContextMenu(nRow, rMenu, nExecutionResult); + break; + } +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::Select() +{ + // irgendeine Selektion hat sich geaendert .... + FmGridControl::Select(); + + if (m_pMasterListener) + m_pMasterListener->SelectionChanged(); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::CursorMoved() +{ + FmGridControl::CursorMoved(); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::ActivateCell(long nRow, sal_uInt16 nCol, sal_Bool bSetCellFocus /*= sal_True*/ ) +{ + FmGridControl::ActivateCell(nRow, nCol, bSetCellFocus); + if (m_pMasterListener) + m_pMasterListener->CellActivated(); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::DeactivateCell(sal_Bool bUpdate /*= sal_True*/) +{ + FmGridControl::DeactivateCell(bUpdate); + if (m_pMasterListener) + m_pMasterListener->CellDeactivated(); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::onRowChange() +{ + if ( m_pMasterListener ) + m_pMasterListener->RowChanged(); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::onColumnChange() +{ + if ( m_pMasterListener ) + m_pMasterListener->ColumnChanged(); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::BeforeDrop() +{ + if (m_pMasterListener) + m_pMasterListener->BeforeDrop(); +} +//--------------------------------------------------------------------------------------- +void SbaGridControl::AfterDrop() +{ + if (m_pMasterListener) + m_pMasterListener->AfterDrop(); +} + + +//------------------------------------------------------------------------------ +Reference< XPropertySet > SbaGridControl::getField(sal_uInt16 nModelPos) +{ + Reference< XPropertySet > xEmptyReturn; + try + { + // first get the name of the column + Reference< XIndexAccess > xCols(GetPeer()->getColumns(), UNO_QUERY); + if ( xCols.is() && xCols->getCount() > nModelPos ) + { + Reference< XPropertySet > xCol(xCols->getByIndex(nModelPos),UNO_QUERY); + if ( xCol.is() ) + xEmptyReturn.set(xCol->getPropertyValue(PROPERTY_BOUNDFIELD),UNO_QUERY); + } + else + OSL_ENSURE(0,"SbaGridControl::getField getColumns returns NULL or ModelPos is > than count!"); + } + catch(Exception&) + { + OSL_ENSURE(0,"SbaGridControl::getField Exception occured!"); + } + + return xEmptyReturn; +} + +//--------------------------------------------------------------------------------------- +sal_Bool SbaGridControl::IsReadOnlyDB() const +{ + // assume yes if anything fails + sal_Bool bDBIsReadOnly = sal_True; + + // the db is the implemented by the parent of the grid control's model ... + Reference< XChild > xColumns(GetPeer()->getColumns(), UNO_QUERY); + if (xColumns.is()) + { + Reference< XRowSet > xDataSource(xColumns->getParent(), UNO_QUERY); + Reference< XChild > xConn(::dbtools::getConnection(xDataSource),UNO_QUERY); + if (xConn.is()) + { + // ... and the RO-flag simply is implemented by a property + Reference< XPropertySet > xDbProps(xConn->getParent(), UNO_QUERY); + if (xDbProps.is()) + { + Reference< XPropertySetInfo > xInfo = xDbProps->getPropertySetInfo(); + if (xInfo->hasPropertyByName(PROPERTY_ISREADONLY)) + bDBIsReadOnly = ::comphelper::getBOOL(xDbProps->getPropertyValue(PROPERTY_ISREADONLY)); + } + } + } + return bDBIsReadOnly; +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::MouseButtonDown( const BrowserMouseEvent& rMEvt) +{ + long nRow = GetRowAtYPosPixel(rMEvt.GetPosPixel().Y()); + sal_uInt16 nColPos = GetColumnAtXPosPixel(rMEvt.GetPosPixel().X()); + sal_uInt16 nViewPos = (nColPos == BROWSER_INVALIDID) ? (sal_uInt16)-1 : nColPos-1; + // 'the handle column' and 'no valid column' will both result in a view position of -1 ! + + sal_Bool bHitEmptySpace = (nRow > GetRowCount()) || (nViewPos == (sal_uInt16)-1); + + if (bHitEmptySpace && (rMEvt.GetClicks() == 2) && rMEvt.IsMod1()) + Control::MouseButtonDown(rMEvt); + else + FmGridControl::MouseButtonDown(rMEvt); +} + +//--------------------------------------------------------------------------------------- +void SbaGridControl::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel ) +{ + ::vos::OGuard aGuard(Application::GetSolarMutex()); + // in the new DnD API, the solar mutex is not locked when StartDrag get's called + + sal_Bool bHandled = sal_False; + + do + { + // determine if dragging is allowed + // (Yes, this is controller (not view) functionality. But collecting and evaluating all the + // informations necessary via UNO would be quite difficult (if not impossible) so + // my laziness says 'do it here' ...) + long nRow = GetRowAtYPosPixel(_rPosPixel.Y()); + sal_uInt16 nColPos = GetColumnAtXPosPixel(_rPosPixel.X()); + sal_uInt16 nViewPos = (nColPos == BROWSER_INVALIDID) ? (sal_uInt16)-1 : nColPos-1; + // 'the handle column' and 'no valid column' will both result in a view position of -1 ! + + sal_Bool bCurrentRowVirtual = IsCurrentAppending() && IsModified(); + // the current row doesn't really exist : the user's appendign a new one and already has entered some data, + // so the row contains data which has no counter part within the data source + + long nCorrectRowCount = GetRowCount(); + if (GetOptions() & OPT_INSERT) + --nCorrectRowCount; // there is a empty row for inserting records + if (bCurrentRowVirtual) + --nCorrectRowCount; + + if ((nColPos == BROWSER_INVALIDID) || (nRow >= nCorrectRowCount)) + break; + + sal_Bool bHitHandle = (nColPos == 0); + + // check which kind of dragging has to be initiated + if ( bHitHandle // the handle column + // AND + && ( GetSelectRowCount() // at least one row is selected + // OR + || ( (nRow >= 0) // a row below the header + && !bCurrentRowVirtual // we aren't appending a new record + && (nRow != GetCurrentPos()) // a row which is not the current one + ) // OR + || ( (0 == GetSelectRowCount()) // no rows selected + && (-1 == nRow) // hit the header + ) + ) + ) + { // => start dragging the row + if (GetDataWindow().IsMouseCaptured()) + GetDataWindow().ReleaseMouse(); + + if (0 == GetSelectRowCount()) + // no rows selected, but here in this branch + // -> the user started dragging the upper left corner, which symbolizes the whole table + SelectAll(); + + getMouseEvent().Clear(); + DoRowDrag((sal_Int16)nRow); + + bHandled = sal_True; + } + else if ( (nRow < 0) // the header + && (!bHitHandle) // non-handle column + && (nViewPos < GetViewColCount()) // valid (existing) column + ) + { // => start dragging the column + if (GetDataWindow().IsMouseCaptured()) + GetDataWindow().ReleaseMouse(); + + getMouseEvent().Clear(); + DoColumnDrag(nViewPos); + + bHandled = sal_True; + } + else if ( !bHitHandle // non-handle column + && (nRow >= 0) // non-header row + ) + { // => start dragging the field content + if (GetDataWindow().IsMouseCaptured()) + GetDataWindow().ReleaseMouse(); + + getMouseEvent().Clear(); + DoFieldDrag(nViewPos, (sal_Int16)nRow); + + bHandled = sal_True; + } + } + while (sal_False); + + if (!bHandled) + FmGridControl::StartDrag(_nAction, _rPosPixel); +} + +//------------------------------------------------------------------------------ +void SbaGridControl::Command(const CommandEvent& rEvt) +{ + FmGridControl::Command(rEvt); +} + +// ----------------------------------------------------------------------- +void SbaGridControl::DoColumnDrag(sal_uInt16 nColumnPos) +{ + Reference< XPropertySet > xDataSource(getDataSource(), UNO_QUERY); + DBG_ASSERT(xDataSource.is(), "SbaGridControl::DoColumnDrag : invalid data source !"); + + Reference< XPropertySet > xAffectedCol; + Reference< XPropertySet > xAffectedField; + Reference< XConnection > xActiveConnection; + + // determine the field to drag + ::rtl::OUString sField; + try + { + xActiveConnection = ::dbtools::getConnection(Reference< XRowSet >(getDataSource(),UNO_QUERY)); + + sal_uInt16 nModelPos = GetModelColumnPos(GetColumnIdFromViewPos(nColumnPos)); + Reference< XIndexContainer > xCols(GetPeer()->getColumns(), UNO_QUERY); + xAffectedCol.set(xCols->getByIndex(nModelPos),UNO_QUERY); + if (xAffectedCol.is()) + { + xAffectedCol->getPropertyValue(PROPERTY_CONTROLSOURCE) >>= sField; + xAffectedField.set(xAffectedCol->getPropertyValue(PROPERTY_BOUNDFIELD),UNO_QUERY); + } + } + catch(Exception&) + { + DBG_ERROR("SbaGridControl::DoColumnDrag : something went wrong while getting the column"); + } + if (0 == sField.getLength()) + return; + + OColumnTransferable* pDataTransfer = new OColumnTransferable(xDataSource, sField, xAffectedField, xActiveConnection, CTF_FIELD_DESCRIPTOR | CTF_COLUMN_DESCRIPTOR); + Reference< XTransferable > xEnsureDelete = pDataTransfer; + pDataTransfer->StartDrag(this, DND_ACTION_COPY | DND_ACTION_LINK); +} + +// ----------------------------------------------------------------------- +void SbaGridControl::CopySelectedRowsToClipboard() +{ + DBG_ASSERT( GetSelectRowCount() > 0, "SbaGridControl::CopySelectedRowsToClipboard: invalid call!" ); + implTransferSelectedRows( (sal_Int16)FirstSelectedRow(), true ); +} + +// ----------------------------------------------------------------------- +void SbaGridControl::DoRowDrag( sal_Int16 nRowPos ) +{ + implTransferSelectedRows( nRowPos, false ); +} + +// ----------------------------------------------------------------------- +void SbaGridControl::implTransferSelectedRows( sal_Int16 nRowPos, bool _bTrueIfClipboardFalseIfDrag ) +{ + Reference< XPropertySet > xForm( getDataSource(), UNO_QUERY ); + DBG_ASSERT( xForm.is(), "SbaGridControl::implTransferSelectedRows: invalid form!" ); + + // build the sequence of numbers of selected rows + Sequence< Any > aSelectedRows; + sal_Bool bSelectionBookmarks = sal_True; + + // collect the affected rows + if ((GetSelectRowCount() == 0) && (nRowPos >= 0)) + { + aSelectedRows.realloc( 1 ); + aSelectedRows[0] <<= (sal_Int32)(nRowPos + 1); + bSelectionBookmarks = sal_False; + } + else if ( !IsAllSelected() && GetSelectRowCount() ) + { + aSelectedRows = getSelectionBookmarks(); + bSelectionBookmarks = sal_True; + } + + Reference< XResultSet> xRowSetClone; + try + { + ODataClipboard* pTransfer = new ODataClipboard( xForm, aSelectedRows, bSelectionBookmarks, getServiceManager() ); + + Reference< XTransferable > xEnsureDelete = pTransfer; + if ( _bTrueIfClipboardFalseIfDrag ) + pTransfer->CopyToClipboard( this ); + else + pTransfer->StartDrag(this, DND_ACTION_COPY | DND_ACTION_LINK); + } + catch(Exception&) + { + } +} + +// ----------------------------------------------------------------------- +void SbaGridControl::DoFieldDrag(sal_uInt16 nColumnPos, sal_Int16 nRowPos) +{ + // the only thing to do here is dragging the pure cell text + // the old implementation copied a SBA_FIELDDATAEXCHANGE_FORMAT, too, (which was rather expensive to obtain), + // but we have no client for this DnD format anymore (the mail part of SO 5.2 was the only client) + + ::rtl::OUString sCellText; + try + { + Reference< XGridFieldDataSupplier > xFieldData(static_cast< XGridPeer* >(GetPeer()), UNO_QUERY); + Sequence<sal_Bool> aSupportingText = xFieldData->queryFieldDataType(::getCppuType(&sCellText)); + if (aSupportingText.getConstArray()[nColumnPos]) + { + Sequence< Any> aCellContents = xFieldData->queryFieldData(nRowPos, ::getCppuType(&sCellText)); + sCellText = ::comphelper::getString(aCellContents.getConstArray()[nColumnPos]); + ::svt::OStringTransfer::StartStringDrag(sCellText, this, DND_ACTION_COPY); + } + } + catch(Exception&) + { + DBG_ERROR("SbaGridControl::DoFieldDrag : could not retrieve the cell's contents !"); + return; + } + +} +/// unary_function Functor object for class ZZ returntype is void + struct SbaGridControlPrec : ::std::unary_function<DataFlavorExVector::value_type,bool> + { + sal_Bool bQueryDrop; + SbaGridControlPrec(sal_Bool _bQueryDrop) + : bQueryDrop(_bQueryDrop) + { + } + + inline bool operator()(const DataFlavorExVector::value_type& _aType) + { + switch (_aType.mnSotId) + { +// case SOT_FORMAT_RTF: // RTF data descriptions +// case SOT_FORMATSTR_ID_HTML: // HTML data descriptions + case SOT_FORMATSTR_ID_DBACCESS_TABLE: // table descriptor + case SOT_FORMATSTR_ID_DBACCESS_QUERY: // query descriptor + case SOT_FORMATSTR_ID_DBACCESS_COMMAND: // SQL command + return true; + } + return false; + } + }; +//------------------------------------------------------------------------------ +sal_Int8 SbaGridControl::AcceptDrop( const BrowserAcceptDropEvent& rEvt ) +{ + sal_Int8 nAction = DND_ACTION_NONE; + + // we need a valid connection + if (!::dbtools::getConnection(Reference< XRowSet > (getDataSource(),UNO_QUERY)).is()) + return nAction; + + if ( IsDropFormatSupported( FORMAT_STRING ) ) do + { // odd construction, but spares us a lot of (explicit ;) goto's + + if (!GetEmptyRow().Is()) + // without an empty row we're not in update mode + break; + + long nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), sal_False); + sal_uInt16 nCol = GetColumnAtXPosPixel(rEvt.maPosPixel.X(), sal_False); + + long nCorrectRowCount = GetRowCount(); + if (GetOptions() & OPT_INSERT) + --nCorrectRowCount; // there is a empty row for inserting records + if (IsCurrentAppending()) + --nCorrectRowCount; // the current data record doesn't really exist, we are appending a new one + + if ((nCol == BROWSER_INVALIDID) || (nRow >= nCorrectRowCount) || GetColumnId(nCol) == 0 ) + // no valid cell under the mouse cursor + break; + + Rectangle aRect = GetCellRect(nRow, nCol, sal_False); + if (!aRect.IsInside(rEvt.maPosPixel)) + // not dropped within a cell (a cell isn't as wide as the column - the are small spaces) + break; + + if ((IsModified() || (GetCurrentRow().Is() && GetCurrentRow()->IsModified())) && (GetCurrentPos() != nRow)) + // there is a current and modified row or cell and he text is to be dropped into another one + break; + + CellControllerRef xCurrentController = Controller(); + if (xCurrentController.Is() && xCurrentController->IsModified() && ((nRow != GetCurRow()) || (nCol != GetCurColumnId()))) + // the current controller is modified and the user wants to drop in another cell -> no chance + // (when leaving the modified cell a error may occur - this is deadly while dragging) + break; + + Reference< XPropertySet > xField = getField(GetModelColumnPos(nCol)); + if (!xField.is()) + // the column is not valid bound (for instance a binary field) + break; + + try + { + if (::comphelper::getBOOL(xField->getPropertyValue(PROPERTY_ISREADONLY))) + break; + } + catch (const Exception& e ) + { + (void)e; // make compiler happy + // assume RO + break; + } + + try + { + // assume that text can be dropped into a field if the column has a ::com::sun::star::awt::XTextComponent interface + Reference< XIndexAccess > xColumnControls((::com::sun::star::form::XGridPeer*)GetPeer(), UNO_QUERY); + if (xColumnControls.is()) + { + Reference< ::com::sun::star::awt::XTextComponent > xColControl; + ::cppu::extractInterface(xColControl,xColumnControls->getByIndex(GetViewColumnPos(nCol))); + if (xColControl.is()) + { + m_bActivatingForDrop = sal_True; + GoToRowColumnId(nRow, nCol); + m_bActivatingForDrop = sal_False; + + nAction = DND_ACTION_COPY; + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + } while (sal_False); + + if(nAction != DND_ACTION_COPY && GetEmptyRow().Is()) + { + const DataFlavorExVector& _rFlavors = GetDataFlavors(); + if(::std::find_if(_rFlavors.begin(),_rFlavors.end(),SbaGridControlPrec(sal_True)) != _rFlavors.end()) + nAction = DND_ACTION_COPY; + } + +/* + // check formats + SvDataObjectRef xDataObj = SvDataObject::PasteDragServer( rEvt ); + if (!xDataObj.Is()) + return sal_False; + + const SvDataTypeList& rTypeList = xDataObj->GetTypeList(); + if ((rTypeList.Get(Exchange::RegisterFormatName(String::CreateFromAscii(SBA_DATAEXCHANGE_FORMAT)))) ) + { + bAllow = (GetOptions() & OPT_INSERT) && rEvt.GetColumnId() > 0 && rEvt.GetRow() >= 0; + ((BrowserDropEvent&)rEvt).SetAction(DROP_COPY); + } + +*/ + return (DND_ACTION_NONE != nAction) ? nAction : FmGridControl::AcceptDrop(rEvt); +} + +//------------------------------------------------------------------------------ +sal_Int8 SbaGridControl::ExecuteDrop( const BrowserExecuteDropEvent& rEvt ) +{ + // we need some properties of our data source + Reference< XPropertySet > xDataSource = getDataSource(); + if (!xDataSource.is()) + return DND_ACTION_NONE; + + // we need a valid connection + if (!::dbtools::getConnection(Reference< XRowSet > (xDataSource,UNO_QUERY)).is()) + return DND_ACTION_NONE; + + if ( IsDropFormatSupported( FORMAT_STRING ) ) + { + long nRow = GetRowAtYPosPixel(rEvt.maPosPixel.Y(), sal_False); + sal_uInt16 nCol = GetColumnAtXPosPixel(rEvt.maPosPixel.X(), sal_False); + + long nCorrectRowCount = GetRowCount(); + if (GetOptions() & OPT_INSERT) + --nCorrectRowCount; // there is a empty row for inserting records + if (IsCurrentAppending()) + --nCorrectRowCount; // the current data record doesn't really exist, we are appending a new one + + DBG_ASSERT((nCol != BROWSER_INVALIDID) && (nRow < nCorrectRowCount), "SbaGridControl::Drop : dropped on an invalid position !"); + // AcceptDrop should have caught this + + // from now we work with ids instead of positions + nCol = GetColumnId(nCol); + + GoToRowColumnId(nRow, nCol); + if (!IsEditing()) + ActivateCell(); + + CellControllerRef xCurrentController = Controller(); + if (!xCurrentController.Is() || !xCurrentController->ISA(EditCellController)) + return DND_ACTION_NONE; + Edit& rEdit = (Edit&)xCurrentController->GetWindow(); + + // get the dropped string + TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable ); + String sDropped; + if ( !aDropped.GetString( FORMAT_STRING, sDropped ) ) + return DND_ACTION_NONE; + + rEdit.SetText( sDropped ); + xCurrentController->SetModified(); + rEdit.Modify(); + // SetText itself doesn't call a Modify as it isn't a user interaction + + return DND_ACTION_COPY; + } + + if(GetEmptyRow().Is()) + { + const DataFlavorExVector& _rFlavors = GetDataFlavors(); + DataFlavorExVector::const_iterator aFind = ::std::find_if(_rFlavors.begin(),_rFlavors.end(),SbaGridControlPrec(sal_True)); + if( aFind != _rFlavors.end()) + { + TransferableDataHelper aDropped( rEvt.maDropEvent.Transferable ); + m_aDataDescriptor = ODataAccessObjectTransferable::extractObjectDescriptor(aDropped); + if (m_nAsyncDropEvent) + Application::RemoveUserEvent(m_nAsyncDropEvent); + m_nAsyncDropEvent = Application::PostUserEvent(LINK(this, SbaGridControl, AsynchDropEvent)); + return DND_ACTION_COPY; + } + } + + return DND_ACTION_NONE; +} + +//------------------------------------------------------------------------------ +Reference< XPropertySet > SbaGridControl::getDataSource() const +{ + Reference< XPropertySet > xReturn; + + Reference< XChild > xColumns(GetPeer()->getColumns(), UNO_QUERY); + Reference< XPropertySet > xDataSource; + if (xColumns.is()) + xReturn = Reference< XPropertySet > (xColumns->getParent(), UNO_QUERY); + + return xReturn; +} +// ----------------------------------------------------------------------------- +IMPL_LINK(SbaGridControl, AsynchDropEvent, void*, /*EMPTY_ARG*/) +{ + m_nAsyncDropEvent = 0; + + Reference< XPropertySet > xDataSource = getDataSource(); + if ( xDataSource.is() ) + { + sal_Bool bCountFinal = sal_False; + xDataSource->getPropertyValue(PROPERTY_ISROWCOUNTFINAL) >>= bCountFinal; + if ( !bCountFinal ) + setDataSource(NULL); // deattach from grid control + Reference< XResultSetUpdate > xResultSetUpdate(xDataSource,UNO_QUERY); + ODatabaseImportExport* pImExport = new ORowSetImportExport(this,xResultSetUpdate,m_aDataDescriptor,getServiceManager()); + Reference<XEventListener> xHolder = pImExport; + Hide(); + try + { + pImExport->initialize(m_aDataDescriptor); + BeforeDrop(); + if(!pImExport->Read()) + { + String sError = String(ModuleRes(STR_NO_COLUMNNAME_MATCHING)); + throwGenericSQLException(sError,NULL); + } + AfterDrop(); + Show(); + } + catch(const SQLException& e) + { + AfterDrop(); + Show(); + ::dbaui::showError(::dbtools::SQLExceptionInfo(e),this,getServiceManager()); + } + catch(const Exception& ) + { + AfterDrop(); + Show(); + DBG_UNHANDLED_EXCEPTION(); + } + if ( !bCountFinal ) + setDataSource(Reference< XRowSet >(xDataSource,UNO_QUERY)); + } + m_aDataDescriptor.clear(); + + return 0L; +} +// ------------------------------------------------------------------------- +::rtl::OUString SbaGridControl::GetAccessibleObjectDescription( ::svt::AccessibleBrowseBoxObjType eObjType,sal_Int32 _nPosition) const +{ + ::rtl::OUString sRet; + if ( ::svt::BBTYPE_BROWSEBOX == eObjType ) + { + ::vos::OGuard aGuard(Application::GetSolarMutex()); + sRet = String(ModuleRes(STR_DATASOURCE_GRIDCONTROL_DESC)); + } + else + sRet = FmGridControl::GetAccessibleObjectDescription( eObjType,_nPosition); + return sRet; +} +// ----------------------------------------------------------------------------- +void SbaGridControl::DeleteSelectedRows() +{ + FmGridControl::DeleteSelectedRows(); +} + + diff --git a/dbaccess/source/ui/browser/sbagrid.src b/dbaccess/source/ui/browser/sbagrid.src new file mode 100644 index 000000000000..1362944d5847 --- /dev/null +++ b/dbaccess/source/ui/browser/sbagrid.src @@ -0,0 +1,139 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef _DBU_BRW_HRC_ +#include "dbu_brw.hrc" +#endif + +#ifndef _DBA_DBACCESS_HELPID_HRC_ +#include "dbaccess_helpid.hrc" +#endif +#ifndef DBACCESS_UI_BROWSER_ID_HXX +#include "browserids.hxx" +#endif +#ifndef DBAUI_TOOLBOX_HXX +#include "toolbox.hrc" +#endif +#ifndef _GLOBLMN_HRC +#include <svx/globlmn.hrc> +#endif + +Menu RID_SBA_GRID_COLCTXMENU +{ + ItemList = + { + MenuItem + { + Identifier = ID_BROWSER_COLATTRSET ; + HelpID = HID_BROWSER_COLUMNFORMAT ; + Text [ en-US ] = "Column ~Format..." ; + }; + MenuItem + { + MID_COLUMN_WIDTH + HelpID = HID_BROWSER_COLUMNWIDTH; + }; + MenuItem + { + Identifier = ID_BROWSER_COLUMNINFO ; + HelpID = HID_BROWSER_COLUMNINFO ; + Text [ en-US ] = "Copy Column D~escription"; + }; + }; +}; + +Menu RID_SBA_GRID_ROWCTXMENU +{ + ItemList = + { + MenuItem + { + Identifier = ID_BROWSER_TABLEATTR ; + HelpID = HID_BROWSER_TABLEFORMAT ; + Text [ en-US ] = "Table Format..." ; + }; + MenuItem + { + Identifier = ID_BROWSER_ROWHEIGHT ; + HelpID = HID_BROWSER_ROWHEIGHT ; + Text [ en-US ] = "Row Height..." ; + }; + MenuItem + { + ITEM_EDIT_COPY + }; + }; +}; + +String RID_STR_UNDO_MODIFY_RECORD +{ + Text [ en-US ] = "Undo: Data Input"; +}; + +String RID_STR_SAVE_CURRENT_RECORD +{ + Text [ en-US ] = "Save current record"; +}; + +String STR_QRY_TITLE +{ + Text [ en-US ] = "Query #" ; +}; +String STR_TBL_TITLE +{ + Text [ en-US ] = "Table #" ; +}; +String STR_VIEW_TITLE +{ + Text [ en-US ] = "View #" ; +}; + +String STR_NAME_ALREADY_EXISTS +{ + Text [ en-US ] = "The name \"#\" already exists."; +}; + + +String STR_NO_COLUMNNAME_MATCHING +{ + Text [ en-US ] = "No matching column names were found."; +}; + +String STR_ERROR_OCCURED_WHILE_COPYING +{ + Text [ en-US ] = "An error occurred. Do you want to continue copying?"; +}; + +String STR_DATASOURCE_GRIDCONTROL_NAME +{ + Text [ en-US ] = "Data source table view"; +}; + +String STR_DATASOURCE_GRIDCONTROL_DESC +{ + Text [ en-US ] = "Shows the selected table or query."; +}; + diff --git a/dbaccess/source/ui/browser/sbamultiplex.cxx b/dbaccess/source/ui/browser/sbamultiplex.cxx new file mode 100644 index 000000000000..de304ebbe1dd --- /dev/null +++ b/dbaccess/source/ui/browser/sbamultiplex.cxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#ifndef _SBA_MULTIPLEX_HXX +#include "sbamultiplex.hxx" +#endif +using namespace dbaui; + +//================================================================== +// the listener multiplexers +//================================================================== + +// XStatusListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXStatusMultiplexer, ::com::sun::star::frame::XStatusListener) + +void SAL_CALL SbaXStatusMultiplexer::statusChanged(const ::com::sun::star::frame::FeatureStateEvent& e) throw (::com::sun::star::uno::RuntimeException) +{ + m_aLastKnownStatus = e; + m_aLastKnownStatus.Source = &m_rParent; + ::cppu::OInterfaceIteratorHelper aIt( *this ); + while ( aIt.hasMoreElements() ) + static_cast< ::com::sun::star::frame::XStatusListener* >( aIt.next() )->statusChanged( m_aLastKnownStatus ); +} \ + +// LoadListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXLoadMultiplexer, ::com::sun::star::form::XLoadListener) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXLoadMultiplexer, ::com::sun::star::form::XLoadListener, loaded, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXLoadMultiplexer, ::com::sun::star::form::XLoadListener, unloaded, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXLoadMultiplexer, ::com::sun::star::form::XLoadListener, unloading, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXLoadMultiplexer, ::com::sun::star::form::XLoadListener, reloading, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXLoadMultiplexer, ::com::sun::star::form::XLoadListener, reloaded, ::com::sun::star::lang::EventObject) + +// ::com::sun::star::sdbc::XRowSetListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXRowSetMultiplexer, ::com::sun::star::sdbc::XRowSetListener) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXRowSetMultiplexer, ::com::sun::star::sdbc::XRowSetListener, cursorMoved, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXRowSetMultiplexer, ::com::sun::star::sdbc::XRowSetListener, rowChanged, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXRowSetMultiplexer, ::com::sun::star::sdbc::XRowSetListener, rowSetChanged, ::com::sun::star::lang::EventObject) + +// ::com::sun::star::sdb::XRowSetApproveListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXRowSetApproveMultiplexer, ::com::sun::star::sdb::XRowSetApproveListener) +IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(SbaXRowSetApproveMultiplexer, ::com::sun::star::sdb::XRowSetApproveListener, approveCursorMove, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(SbaXRowSetApproveMultiplexer, ::com::sun::star::sdb::XRowSetApproveListener, approveRowChange, ::com::sun::star::sdb::RowChangeEvent) +IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(SbaXRowSetApproveMultiplexer, ::com::sun::star::sdb::XRowSetApproveListener, approveRowSetChange, ::com::sun::star::lang::EventObject) + +// ::com::sun::star::sdb::XSQLErrorListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXSQLErrorMultiplexer, ::com::sun::star::sdb::XSQLErrorListener) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXSQLErrorMultiplexer, ::com::sun::star::sdb::XSQLErrorListener, errorOccured, ::com::sun::star::sdb::SQLErrorEvent) + +// ::com::sun::star::form::XDatabaseParameterListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXParameterMultiplexer, ::com::sun::star::form::XDatabaseParameterListener) +IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(SbaXParameterMultiplexer, ::com::sun::star::form::XDatabaseParameterListener, approveParameter, ::com::sun::star::form::DatabaseParameterEvent) + +// ::com::sun::star::form::XSubmitListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXSubmitMultiplexer, ::com::sun::star::form::XSubmitListener) +IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(SbaXSubmitMultiplexer, ::com::sun::star::form::XSubmitListener, approveSubmit, ::com::sun::star::lang::EventObject) + +// ::com::sun::star::form::XResetListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXResetMultiplexer, ::com::sun::star::form::XResetListener) +IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(SbaXResetMultiplexer, ::com::sun::star::form::XResetListener, approveReset, ::com::sun::star::lang::EventObject) +IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(SbaXResetMultiplexer, ::com::sun::star::form::XResetListener, resetted, ::com::sun::star::lang::EventObject) + +// ::com::sun::star::beans::XPropertyChangeListener +IMPLEMENT_PROPERTY_MULTIPLEXER(SbaXPropertyChangeMultiplexer, ::com::sun::star::beans::XPropertyChangeListener, propertyChange, ::com::sun::star::beans::PropertyChangeEvent, (::com::sun::star::uno::RuntimeException)) + +// ::com::sun::star::beans::XVetoableChangeListener +IMPLEMENT_PROPERTY_MULTIPLEXER(SbaXVetoableChangeMultiplexer, ::com::sun::star::beans::XVetoableChangeListener, vetoableChange, ::com::sun::star::beans::PropertyChangeEvent, (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)) + +// ::com::sun::star::beans::XPropertiesChangeListener +IMPLEMENT_LISTENER_MULTIPLEXER_CORE(SbaXPropertiesChangeMultiplexer, ::com::sun::star::beans::XPropertiesChangeListener); +void SbaXPropertiesChangeMultiplexer::propertiesChange(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent>& aEvts) throw(::com::sun::star::uno::RuntimeException) +{ + // the SbaXPropertiesChangeMultiplexer doesn't care about the property names a listener logs on for, it simply + // forwards _all_ changes to _all_ listeners + + ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent> aMulti(aEvts); + ::com::sun::star::beans::PropertyChangeEvent* pMulti = aMulti.getArray(); + for (sal_uInt16 i=0; i<aMulti.getLength(); ++i, ++pMulti) + pMulti->Source = &m_rParent; + + ::cppu::OInterfaceIteratorHelper aIt(*this); + while (aIt.hasMoreElements()) + ((::com::sun::star::beans::XPropertiesChangeListener*)aIt.next())->propertiesChange(aMulti); +} + diff --git a/dbaccess/source/ui/browser/unodatbr.cxx b/dbaccess/source/ui/browser/unodatbr.cxx new file mode 100644 index 000000000000..c65055c582fc --- /dev/null +++ b/dbaccess/source/ui/browser/unodatbr.cxx @@ -0,0 +1,3784 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_dbaccess.hxx" + +#include "browserids.hxx" +#include "dbaccess_helpid.hrc" +#include "dbexchange.hxx" +#include "dbtreelistbox.hxx" +#include "dbtreemodel.hxx" +#include "dbtreeview.hxx" +#include "dbu_brw.hrc" +#include "dbu_reghelper.hxx" +#include "dbustrings.hrc" +#include "dlgsave.hxx" +#include "HtmlReader.hxx" +#include "imageprovider.hxx" +#include "listviewitems.hxx" +#include "QEnumTypes.hxx" +#include "RtfReader.hxx" +#include "sbagrid.hrc" +#include "sbagrid.hxx" +#include "sqlmessage.hxx" +#include "TokenWriter.hxx" +#include "UITools.hxx" +#include "unodatbr.hxx" +#include "WColumnSelect.hxx" +#include "WCopyTable.hxx" +#include "WCPage.hxx" +#include "WExtendPages.hxx" +#include "WNameMatch.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/awt/LineEndFormat.hpp> +#include <com/sun/star/awt/MouseWheelBehavior.hpp> +#include <com/sun/star/awt/TextAlign.hpp> +#include <com/sun/star/awt/VisualEffect.hpp> +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/form/XForm.hpp> +#include <com/sun/star/form/XGridColumnFactory.hpp> +#include <com/sun/star/form/XLoadable.hpp> +#include <com/sun/star/frame/FrameSearchFlag.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/sdb/CommandType.hpp> +#include <com/sun/star/sdb/SQLContext.hpp> +#include <com/sun/star/sdb/XBookmarksSupplier.hpp> +#include <com/sun/star/sdb/XCompletedConnection.hpp> +#include <com/sun/star/sdb/XDatabaseRegistrations.hpp> +#include <com/sun/star/sdb/XDocumentDataSource.hpp> +#include <com/sun/star/sdb/XParametersSupplier.hpp> +#include <com/sun/star/sdb/XQueriesSupplier.hpp> +#include <com/sun/star/sdb/XQueryDefinitionsSupplier.hpp> +#include <com/sun/star/sdb/XResultSetAccess.hpp> +#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp> +#include <com/sun/star/sdb/application/NamedDatabaseObject.hpp> +#include <com/sun/star/sdbc/ColumnValue.hpp> +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/FetchDirection.hpp> +#include <com/sun/star/sdbc/SQLWarning.hpp> +#include <com/sun/star/sdbc/XDataSource.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +#include <com/sun/star/sdbc/XWarningsSupplier.hpp> +#include <com/sun/star/sdbcx/Privilege.hpp> +#include <com/sun/star/sdbcx/XColumnsSupplier.hpp> +#include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp> +#include <com/sun/star/sdbcx/XDrop.hpp> +#include <com/sun/star/sdbcx/XTablesSupplier.hpp> +#include <com/sun/star/sdbcx/XViewsSupplier.hpp> +#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> +#include <com/sun/star/util/XFlushable.hpp> +#include <com/sun/star/sdb/XDocumentDataSource.hpp> +#include <com/sun/star/document/MacroExecMode.hpp> +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/ui/XContextMenuInterceptor.hpp> +/** === end UNO includes === **/ + +#include <comphelper/extract.hxx> +#include <comphelper/sequence.hxx> +#include <comphelper/types.hxx> +#include <connectivity/dbexception.hxx> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase2.hxx> +#include <cppuhelper/typeprovider.hxx> +#include <sfx2/app.hxx> +#include <sfx2/dispatch.hxx> +#include <sot/storage.hxx> +#include <svl/filenotation.hxx> +#include <svl/intitem.hxx> +#include <unotools/moduleoptions.hxx> +#include <svtools/svlbitm.hxx> +#include <svtools/svtreebx.hxx> +#include <svx/algitem.hxx> +#include <svx/dataaccessdescriptor.hxx> +#include <svx/databaseregistrationui.hxx> +#include <svx/gridctrl.hxx> +#include <toolkit/unohlp.hxx> +#include <tools/diagnose_ex.h> +#include <tools/multisel.hxx> +#include <tools/urlobj.hxx> +#include <unotools/confignode.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/split.hxx> +#include <vcl/stdtext.hxx> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <vcl/waitobj.hxx> +#include <vcl/wrkwin.hxx> +#include <rtl/logfile.hxx> + +#include <memory> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdb::application; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::ui::dialogs; +using namespace ::com::sun::star::task; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::i18n; +using namespace ::com::sun::star::view; +using namespace ::com::sun::star::datatransfer; +using namespace ::com::sun::star::document; +using namespace ::com::sun::star::ui; +using namespace ::dbtools; +using namespace ::comphelper; +using namespace ::svx; + +// ......................................................................... +namespace dbaui +{ +// ......................................................................... + +namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject; +namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer; + +//================================================================== +//= SbaTableQueryBrowser +//================================================================== +// ------------------------------------------------------------------------- +extern "C" void SAL_CALL createRegistryInfo_OBrowser() +{ + static OMultiInstanceAutoRegistration< SbaTableQueryBrowser > aAutoRegistration; +} +// ------------------------------------------------------------------------- +void SafeAddPropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener) +{ + Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo(); + if (xInfo->hasPropertyByName(rPropName)) + xSet->addPropertyChangeListener(rPropName, pListener); +} + +// ------------------------------------------------------------------------- +void SafeRemovePropertyListener(const Reference< XPropertySet > & xSet, const ::rtl::OUString& rPropName, XPropertyChangeListener* pListener) +{ + Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo(); + if (xInfo->hasPropertyByName(rPropName)) + xSet->removePropertyChangeListener(rPropName, pListener); +} +//------------------------------------------------------------------------- +::rtl::OUString SAL_CALL SbaTableQueryBrowser::getImplementationName() throw(RuntimeException) +{ + return getImplementationName_Static(); +} +//------------------------------------------------------------------------- +::comphelper::StringSequence SAL_CALL SbaTableQueryBrowser::getSupportedServiceNames() throw(RuntimeException) +{ + return getSupportedServiceNames_Static(); +} +// ------------------------------------------------------------------------- +::rtl::OUString SbaTableQueryBrowser::getImplementationName_Static() throw(RuntimeException) +{ + return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.ODatasourceBrowser"); +} +//------------------------------------------------------------------------- +::comphelper::StringSequence SbaTableQueryBrowser::getSupportedServiceNames_Static() throw(RuntimeException) +{ + ::comphelper::StringSequence aSupported(1); + aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.DataSourceBrowser"); + return aSupported; +} +//------------------------------------------------------------------------- +Reference< XInterface > SAL_CALL SbaTableQueryBrowser::Create(const Reference<XMultiServiceFactory >& _rxFactory) +{ + ::vos::OGuard aGuard(Application::GetSolarMutex()); + return *(new SbaTableQueryBrowser(_rxFactory)); +} + +DBG_NAME(SbaTableQueryBrowser); +//------------------------------------------------------------------------------ +SbaTableQueryBrowser::SbaTableQueryBrowser(const Reference< XMultiServiceFactory >& _rM) + :SbaXDataBrowserController(_rM) + ,m_aSelectionListeners( getMutex() ) + ,m_aContextMenuInterceptors( getMutex() ) + ,m_aTableCopyHelper(this) + ,m_pTreeView(NULL) + ,m_pSplitter(NULL) + ,m_pTreeModel(NULL) + ,m_pCurrentlyDisplayed(NULL) + ,m_nAsyncDrop(0) + ,m_nBorder(1) + ,m_bQueryEscapeProcessing( sal_False ) + ,m_bShowMenu(sal_False) + ,m_bInSuspend(sal_False) + ,m_bEnableBrowser(sal_True) +{ + DBG_CTOR(SbaTableQueryBrowser,NULL); +} + +//------------------------------------------------------------------------------ +SbaTableQueryBrowser::~SbaTableQueryBrowser() +{ + DBG_DTOR(SbaTableQueryBrowser,NULL); + if ( !rBHelper.bDisposed && !rBHelper.bInDispose ) + { + OSL_ENSURE(0,"Please check who doesn't dispose this component!"); + // increment ref count to prevent double call of Dtor + osl_incrementInterlockedCount( &m_refCount ); + dispose(); + } +} + +//------------------------------------------------------------------------------ +Any SAL_CALL SbaTableQueryBrowser::queryInterface(const Type& _rType) throw (RuntimeException) +{ + if ( _rType.equals( XScriptInvocationContext::static_type() ) ) + { + OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::queryInterface: did not initialize this, yet!" ); + if ( !!m_aDocScriptSupport && *m_aDocScriptSupport ) + return makeAny( Reference< XScriptInvocationContext >( this ) ); + return Any(); + } + + Any aReturn = SbaXDataBrowserController::queryInterface(_rType); + if (!aReturn.hasValue()) + aReturn = SbaTableQueryBrowser_Base::queryInterface(_rType); + return aReturn; +} + +//------------------------------------------------------------------------------ +Sequence< Type > SAL_CALL SbaTableQueryBrowser::getTypes( ) throw (RuntimeException) +{ + Sequence< Type > aTypes( ::comphelper::concatSequences( + SbaXDataBrowserController::getTypes(), + SbaTableQueryBrowser_Base::getTypes() + ) ); + + OSL_PRECOND( !!m_aDocScriptSupport, "SbaTableQueryBrowser::getTypes: did not initialize this, yet!" ); + if ( !m_aDocScriptSupport || !*m_aDocScriptSupport ) + { + Sequence< Type > aStrippedTypes( aTypes.getLength() - 1 ); + ::std::remove_copy_if( + aTypes.getConstArray(), + aTypes.getConstArray() + aTypes.getLength(), + aStrippedTypes.getArray(), + ::std::bind2nd( ::std::equal_to< Type >(), XScriptInvocationContext::static_type() ) + ); + aTypes = aStrippedTypes; + } + return aTypes; +} + +//------------------------------------------------------------------------------ +Sequence< sal_Int8 > SAL_CALL SbaTableQueryBrowser::getImplementationId( ) throw (RuntimeException) +{ + static ::cppu::OImplementationId * pId = 0; + if (! pId) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! pId) + { + static ::cppu::OImplementationId aId; + pId = &aId; + } + } + return pId->getImplementationId(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL SbaTableQueryBrowser::disposing() +{ + ::vos::OGuard aGuard(Application::GetSolarMutex()); + // doin' a lot of VCL stuff here -> lock the SolarMutex + + // kiss our listeners goodbye + EventObject aEvt(*this); + m_aSelectionListeners.disposeAndClear(aEvt); + m_aContextMenuInterceptors.disposeAndClear(aEvt); + + // reset the content's tree view: it holds a reference to our model which is to be deleted immediately, + // and it will live longer than we do. + if (getBrowserView()) + getBrowserView()->setTreeView(NULL); + + clearTreeModel(); + // clear the tree model + { + ::std::auto_ptr<SvLBoxTreeList> aTemp(m_pTreeModel); + m_pTreeModel = NULL; + } + + // remove ourself as status listener + implRemoveStatusListeners(); + + // remove the container listener from the database context + try + { + Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW ); + xDatabaseRegistrations->removeDatabaseRegistrationsListener( this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + // check out from all the objects we are listening + // the frame + if (m_xCurrentFrameParent.is()) + m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); + SbaXDataBrowserController::disposing(); +} + +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::Construct(Window* pParent) +{ + if ( !SbaXDataBrowserController::Construct( pParent ) ) + return sal_False; + + try + { + Reference< XDatabaseRegistrations > xDatabaseRegistrations( m_xDatabaseContext, UNO_QUERY_THROW ); + xDatabaseRegistrations->addDatabaseRegistrationsListener( this ); + + // the collator for the string compares + m_xCollator = Reference< XCollator >( getORB()->createInstance(::rtl::OUString::createFromAscii( "com.sun.star.i18n.Collator" ) ), UNO_QUERY_THROW ); + m_xCollator->loadDefaultCollator( Application::GetSettings().GetLocale(), 0 ); + } + catch(Exception&) + { + DBG_ERROR("SbaTableQueryBrowser::Construct: could not create (or start listening at) the database context!"); + } + // some help ids + if (getBrowserView() && getBrowserView()->getVclControl()) + { + + // create controls and set sizes + const long nFrameWidth = getBrowserView()->LogicToPixel( ::Size( 3, 0 ), MAP_APPFONT ).Width(); + + m_pSplitter = new Splitter(getBrowserView(),WB_HSCROLL); + m_pSplitter->SetPosSizePixel( ::Point(0,0), ::Size(nFrameWidth,0) ); + m_pSplitter->SetBackground( Wallpaper( Application::GetSettings().GetStyleSettings().GetDialogColor() ) ); + + m_pTreeView = new DBTreeView(getBrowserView(),getORB(), WB_TABSTOP | WB_BORDER); + m_pTreeView->SetPreExpandHandler(LINK(this, SbaTableQueryBrowser, OnExpandEntry)); + + m_pTreeView->setCopyHandler(LINK(this, SbaTableQueryBrowser, OnCopyEntry)); + + m_pTreeView->getListBox().setContextMenuProvider( this ); + m_pTreeView->getListBox().setControlActionListener( this ); + m_pTreeView->SetHelpId(HID_CTL_TREEVIEW); + + // a default pos for the splitter, so that the listbox is about 80 (logical) pixels wide + m_pSplitter->SetSplitPosPixel( getBrowserView()->LogicToPixel( ::Size( 80, 0 ), MAP_APPFONT ).Width() ); + + getBrowserView()->setSplitter(m_pSplitter); + getBrowserView()->setTreeView(m_pTreeView); + + // fill view with data + m_pTreeModel = new SvLBoxTreeList; + m_pTreeModel->SetSortMode(SortAscending); + m_pTreeModel->SetCompareHdl(LINK(this, SbaTableQueryBrowser, OnTreeEntryCompare)); + m_pTreeView->setModel(m_pTreeModel); + m_pTreeView->setSelChangeHdl( LINK( this, SbaTableQueryBrowser, OnSelectionChange ) ); + + // TODO + getBrowserView()->getVclControl()->GetDataWindow().SetUniqueId(UID_DATABROWSE_DATAWINDOW); + getBrowserView()->getVclControl()->SetHelpId(HID_CTL_TABBROWSER); + getBrowserView()->SetUniqueId(UID_CTL_CONTENT); + if (getBrowserView()->getVclControl()->GetHeaderBar()) + getBrowserView()->getVclControl()->GetHeaderBar()->SetHelpId(HID_DATABROWSE_HEADER); + InvalidateFeature(ID_BROWSER_EXPLORER); + } + + return sal_True; +} +// ------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::InitializeForm(const Reference< ::com::sun::star::sdbc::XRowSet > & _rxForm) +{ + if(!m_pCurrentlyDisplayed) + return sal_True; + + // this method set all format settings from the orignal table or query + try + { + // we send all properties at once, maybe the implementation is clever enough to handle one big PropertiesChanged + // more effective than many small PropertyChanged ;) + Sequence< ::rtl::OUString> aProperties(3); + Sequence< Any> aValues(3); + + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); + OSL_ENSURE( pData, "SbaTableQueryBrowser::InitializeForm: No user data set at the currently displayed entry!" ); + OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeForm: No table available!" ); + + if ( pData->xObjectProperties.is() ) + { + sal_Int32 nPos = 0; + // is the filter intially applied ? + aProperties.getArray()[nPos] = PROPERTY_APPLYFILTER; + aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_APPLYFILTER); + + // the initial filter + aProperties.getArray()[nPos] = PROPERTY_FILTER; + aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_FILTER); + + if ( pData->xObjectProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_HAVING_CLAUSE) ) + { + aProperties.realloc(aProperties.getLength()+1); + aValues.realloc(aValues.getLength()+1); + // the initial having clause + aProperties.getArray()[nPos] = PROPERTY_HAVING_CLAUSE; + aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_HAVING_CLAUSE); + } + + // the initial ordering + aProperties.getArray()[nPos] = PROPERTY_ORDER; + aValues.getArray()[nPos++] = pData->xObjectProperties->getPropertyValue(PROPERTY_ORDER); + + Reference< XMultiPropertySet > xFormMultiSet(_rxForm, UNO_QUERY); + xFormMultiSet->setPropertyValues(aProperties, aValues); + } + } + catch(Exception&) + { + DBG_ERROR("SbaTableQueryBrowser::InitializeForm : something went wrong !"); + return sal_False; + } + + + return sal_True; +} + +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::initializePreviewMode() +{ + if ( getBrowserView() && getBrowserView()->getVclControl() ) + { + getBrowserView()->getVclControl()->AlwaysEnableInput( FALSE ); + getBrowserView()->getVclControl()->EnableInput( FALSE ); + getBrowserView()->getVclControl()->ForceHideScrollbars( sal_True ); + } + Reference< XPropertySet > xDataSourceSet(getRowSet(), UNO_QUERY); + if ( xDataSourceSet.is() ) + { + xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowInserts")),makeAny(sal_False)); + xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowUpdates")),makeAny(sal_False)); + xDataSourceSet->setPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AllowDeletes")),makeAny(sal_False)); + } +} + +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::InitializeGridModel(const Reference< ::com::sun::star::form::XFormComponent > & xGrid) +{ + try + { + Reference< ::com::sun::star::form::XGridColumnFactory > xColFactory(xGrid, UNO_QUERY); + Reference< XNameContainer > xColContainer(xGrid, UNO_QUERY); + clearGridColumns( xColContainer ); + + Reference< XChild > xGridAsChild(xGrid, UNO_QUERY); + Reference< XLoadable > xFormAsLoadable; + if (xGridAsChild.is()) + xFormAsLoadable = xFormAsLoadable.query(xGridAsChild->getParent()); + if (xFormAsLoadable.is() && xFormAsLoadable->isLoaded()) + { + // set the formats from the table + if(m_pCurrentlyDisplayed) + { + Sequence< ::rtl::OUString> aProperties(6 + ( m_bPreview ? 5 : 0 )); + Sequence< Any> aValues(7 + ( m_bPreview ? 5 : 0 )); + + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); + OSL_ENSURE( pData->xObjectProperties.is(), "SbaTableQueryBrowser::InitializeGridModel: No table available!" ); + if ( !pData->xObjectProperties.is() ) + return sal_False; + + ::rtl::OUString* pStringIter = aProperties.getArray(); + Any* pValueIter = aValues.getArray(); + if ( m_bPreview ) + { + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor")); + *pValueIter++ <<= sal_False; + *pStringIter++ = PROPERTY_BORDER; + *pValueIter++ <<= sal_Int16(0); + } + + *pStringIter++ = PROPERTY_FONT; + *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_FONT); + *pStringIter++ = PROPERTY_TEXTEMPHASIS; + *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTEMPHASIS); + *pStringIter++ = PROPERTY_TEXTRELIEF; + *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTRELIEF); + if ( m_bPreview ) + { + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar")); + *pValueIter++ <<= sal_False; + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker")); + *pValueIter++ <<= sal_False; + } + *pStringIter++ = PROPERTY_ROW_HEIGHT; + *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_ROW_HEIGHT); + if ( m_bPreview ) + { + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop")); + *pValueIter++ <<= sal_False; + } + *pStringIter++ = PROPERTY_TEXTCOLOR; + *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTCOLOR); + *pStringIter++ = PROPERTY_TEXTLINECOLOR; + *pValueIter++ = pData->xObjectProperties->getPropertyValue(PROPERTY_TEXTLINECOLOR); + + Reference< XMultiPropertySet > xFormMultiSet(xGrid, UNO_QUERY); + xFormMultiSet->setPropertyValues(aProperties, aValues); + } + + + // get the formats supplier of the database we're working with + Reference< ::com::sun::star::util::XNumberFormatsSupplier > xSupplier = getNumberFormatter()->getNumberFormatsSupplier(); + + Reference<XConnection> xConnection; + Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); + xRowSetProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection; + OSL_ENSURE(xConnection.is(),"A ActiveConnection should normaly exists!"); + + Reference<XChild> xChild(xConnection,UNO_QUERY); + Reference<XPropertySet> xDataSourceProp(xChild->getParent(),UNO_QUERY); + sal_Bool bSuppressVersionCol = sal_False; + OSL_VERIFY( xDataSourceProp->getPropertyValue( PROPERTY_SUPPRESSVERSIONCL ) >>= bSuppressVersionCol ); + + // insert the column into the gridcontrol so that we see something :-) + ::rtl::OUString aCurrentModelType; + Reference<XColumnsSupplier> xSupCols(getRowSet(),UNO_QUERY); + Reference<XNameAccess> xColumns = xSupCols->getColumns(); + Sequence< ::rtl::OUString> aNames = xColumns->getElementNames(); + const ::rtl::OUString* pIter = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aNames.getLength(); + + ::rtl::OUString sDefaultProperty; + Reference< XPropertySet > xColumn; + Reference< XPropertySetInfo > xColPSI; + for (sal_uInt16 i=0; pIter != pEnd; ++i,++pIter) + { + xColumn.set( xColumns->getByName( *pIter ), UNO_QUERY_THROW ); + xColPSI.set( xColumn->getPropertySetInfo(), UNO_SET_THROW ); + + // ignore the column when it is a rowversion one + if ( bSuppressVersionCol + && xColPSI->hasPropertyByName( PROPERTY_ISROWVERSION ) + && ::cppu::any2bool( xColumn->getPropertyValue( PROPERTY_ISROWVERSION ) ) + ) + continue; + + // use the result set column's type to determine the type of grid column to create + sal_Bool bFormattedIsNumeric = sal_True; + sal_Int32 nType = ::comphelper::getINT32( xColumn->getPropertyValue( PROPERTY_TYPE ) ); + + ::std::vector< NamedValue > aInitialValues; + ::std::vector< ::rtl::OUString > aCopyProperties; + + switch(nType) + { + case DataType::BIT: + case DataType::BOOLEAN: + { + aCurrentModelType = ::rtl::OUString::createFromAscii("CheckBox"); + aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "VisualEffect" ) ), makeAny( VisualEffect::FLAT ) ) ); + sDefaultProperty = PROPERTY_DEFAULTSTATE; + + sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN; + OSL_VERIFY( xColumn->getPropertyValue( PROPERTY_ISNULLABLE ) >>= nNullable ); + aInitialValues.push_back( NamedValue( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TriState" ) ), + makeAny( sal_Bool( ColumnValue::NO_NULLS != nNullable ) ) + ) ); + } + break; + + case DataType::LONGVARCHAR: + case DataType::CLOB: + aInitialValues.push_back( NamedValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MultiLine" ) ), makeAny( (sal_Bool)sal_True ) ) ); + // NO break! + case DataType::BINARY: + case DataType::VARBINARY: + case DataType::LONGVARBINARY: + aCurrentModelType = ::rtl::OUString::createFromAscii("TextField"); + sDefaultProperty = PROPERTY_DEFAULTTEXT; + break; + + case DataType::VARCHAR: + case DataType::CHAR: + bFormattedIsNumeric = sal_False; + // NO break! + default: + aCurrentModelType = ::rtl::OUString::createFromAscii("FormattedField"); + sDefaultProperty = PROPERTY_EFFECTIVEDEFAULT; + + if ( xSupplier.is() ) + aInitialValues.push_back( NamedValue( ::rtl::OUString::createFromAscii( "FormatsSupplier" ), makeAny( xSupplier ) ) ); + aInitialValues.push_back( NamedValue( ::rtl::OUString::createFromAscii( "TreatAsNumber" ), makeAny( (sal_Bool)bFormattedIsNumeric ) ) ); + aCopyProperties.push_back( PROPERTY_FORMATKEY ); + break; + } + + aInitialValues.push_back( NamedValue( PROPERTY_CONTROLSOURCE, makeAny( *pIter ) ) ); + ::rtl::OUString sLabel; + xColumn->getPropertyValue(PROPERTY_LABEL) >>= sLabel; + if ( sLabel.getLength() ) + aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( sLabel ) ) ); + else + aInitialValues.push_back( NamedValue( PROPERTY_LABEL, makeAny( *pIter ) ) ); + + Reference< XPropertySet > xGridCol( xColFactory->createColumn( aCurrentModelType ), UNO_SET_THROW ); + Reference< XPropertySetInfo > xGridColPSI( xGridCol->getPropertySetInfo(), UNO_SET_THROW ); + + // calculate the default + Any aDefault; + if ( xGridColPSI->hasPropertyByName( PROPERTY_CONTROLDEFAULT ) ) + aDefault = xColumn->getPropertyValue( PROPERTY_CONTROLDEFAULT ); + + // default value + if ( nType == DataType::BIT || nType == DataType::BOOLEAN ) + { + if ( aDefault.hasValue() ) + aDefault <<= (comphelper::getString(aDefault).toInt32() == 0) ? (sal_Int16)STATE_NOCHECK : (sal_Int16)STATE_CHECK; + else + aDefault <<= ((sal_Int16)STATE_DONTKNOW); + + } + + if ( aDefault.hasValue() ) + aInitialValues.push_back( NamedValue( sDefaultProperty, aDefault ) ); + + // transfer properties from the definition to the UNO-model : + aCopyProperties.push_back( PROPERTY_HIDDEN ); + aCopyProperties.push_back( PROPERTY_WIDTH ); + + // help text to display for the column + Any aDescription; + if ( xColPSI->hasPropertyByName( PROPERTY_HELPTEXT ) ) + aDescription = xColumn->getPropertyValue( PROPERTY_HELPTEXT ); + ::rtl::OUString sTemp; + aDescription >>= sTemp; + if ( !sTemp.getLength() ) + xColumn->getPropertyValue( PROPERTY_DESCRIPTION ) >>= sTemp; + + aDescription <<= sTemp; + aInitialValues.push_back( NamedValue( PROPERTY_HELPTEXT, aDescription ) ); + + // ... horizontal justify + Any aAlign; aAlign <<= sal_Int16( 0 ); + Any aColAlign( xColumn->getPropertyValue( PROPERTY_ALIGN ) ); + if ( aColAlign.hasValue() ) + aAlign <<= sal_Int16( ::comphelper::getINT32( aColAlign ) ); + aInitialValues.push_back( NamedValue( PROPERTY_ALIGN, aAlign ) ); + + // don't allow the mouse to scroll in the cells + if ( xGridColPSI->hasPropertyByName( PROPERTY_MOUSE_WHEEL_BEHAVIOR ) ) + aInitialValues.push_back( NamedValue( PROPERTY_MOUSE_WHEEL_BEHAVIOR, makeAny( MouseWheelBehavior::SCROLL_DISABLED ) ) ); + + // now set all those values + for ( ::std::vector< NamedValue >::const_iterator property = aInitialValues.begin(); + property != aInitialValues.end(); + ++property + ) + { + xGridCol->setPropertyValue( property->Name, property->Value ); + } + for ( ::std::vector< ::rtl::OUString >::const_iterator copyPropertyName = aCopyProperties.begin(); + copyPropertyName != aCopyProperties.end(); + ++copyPropertyName + ) + xGridCol->setPropertyValue( *copyPropertyName, xColumn->getPropertyValue( *copyPropertyName ) ); + + xColContainer->insertByName(*pIter, makeAny(xGridCol)); + } + } + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + return sal_False; + } + + return sal_True; +} +// ----------------------------------------------------------------------------- +Reference<XPropertySet> getColumnHelper(SvLBoxEntry* _pCurrentlyDisplayed,const Reference<XPropertySet>& _rxSource) +{ + Reference<XPropertySet> xRet; + if(_pCurrentlyDisplayed) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pCurrentlyDisplayed->GetUserData()); + Reference<XColumnsSupplier> xColumnsSup(pData->xObjectProperties,UNO_QUERY); + Reference<XNameAccess> xNames = xColumnsSup->getColumns(); + ::rtl::OUString aName; + _rxSource->getPropertyValue(PROPERTY_NAME) >>= aName; + if(xNames.is() && xNames->hasByName(aName)) + xRet.set(xNames->getByName(aName),UNO_QUERY); + } + return xRet; +} + +// ----------------------------------------------------------------------- +void SbaTableQueryBrowser::transferChangedControlProperty(const ::rtl::OUString& _rProperty, const Any& _rNewValue) +{ + if(m_pCurrentlyDisplayed) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); + Reference< XPropertySet > xObjectProps(pData->xObjectProperties, UNO_QUERY); + OSL_ENSURE(xObjectProps.is(),"SbaTableQueryBrowser::transferChangedControlProperty: no table/query object!"); + if (xObjectProps.is()) + xObjectProps->setPropertyValue(_rProperty, _rNewValue); + } +} + +// ----------------------------------------------------------------------- +void SbaTableQueryBrowser::propertyChange(const PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException) +{ + SbaXDataBrowserController::propertyChange(evt); + + try + { + Reference< XPropertySet > xSource(evt.Source, UNO_QUERY); + if (!xSource.is()) + return; + + // one of the many properties which require us to update the definition ? + // a column's width ? + else if (evt.PropertyName.equals(PROPERTY_WIDTH)) + { // a column width has changed -> update the model + // (the update of the view is done elsewhere) + Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); + if(xProp.is()) + { + if(!evt.NewValue.hasValue()) + xProp->setPropertyValue(PROPERTY_WIDTH,makeAny((sal_Int32)227)); + else + xProp->setPropertyValue(PROPERTY_WIDTH,evt.NewValue); + } + } + + // a column's 'visible' state ? + else if (evt.PropertyName.equals(PROPERTY_HIDDEN)) + { + Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); + if(xProp.is()) + xProp->setPropertyValue(PROPERTY_HIDDEN,evt.NewValue); + } + + // a columns alignment ? + else if (evt.PropertyName.equals(PROPERTY_ALIGN)) + { + Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); + try + { + if(xProp.is()) + { + if(evt.NewValue.hasValue()) + { + sal_Int16 nAlign = 0; + if(evt.NewValue >>= nAlign) + xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(sal_Int32(nAlign))); + else + xProp->setPropertyValue(PROPERTY_ALIGN,evt.NewValue); + } + else + xProp->setPropertyValue(PROPERTY_ALIGN,makeAny(::com::sun::star::awt::TextAlign::LEFT)); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + // a column's format ? + else if ( (evt.PropertyName.equals(PROPERTY_FORMATKEY)) + && (TypeClass_LONG == evt.NewValue.getValueTypeClass()) + ) + { + // update the model (means the definition object) + Reference<XPropertySet> xProp = getColumnHelper(m_pCurrentlyDisplayed,xSource); + if(xProp.is()) + xProp->setPropertyValue(PROPERTY_FORMATKEY,evt.NewValue); + } + + // some table definition properties ? + // the height of the rows in the grid ? + else if (evt.PropertyName.equals(PROPERTY_ROW_HEIGHT)) + { + if(m_pCurrentlyDisplayed) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(m_pCurrentlyDisplayed->GetUserData()); + OSL_ENSURE( pData->xObjectProperties.is(), "No table available!" ); + + sal_Bool bDefault = !evt.NewValue.hasValue(); + if (bDefault) + pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,makeAny((sal_Int32)45)); + else + pData->xObjectProperties->setPropertyValue(PROPERTY_ROW_HEIGHT,evt.NewValue); + } + } + + else if ( evt.PropertyName.equals(PROPERTY_FONT) // the font ? + || evt.PropertyName.equals(PROPERTY_TEXTCOLOR) // the text color ? + || evt.PropertyName.equals(PROPERTY_FILTER) // the filter ? + || evt.PropertyName.equals(PROPERTY_HAVING_CLAUSE) // the having clause ? + || evt.PropertyName.equals(PROPERTY_ORDER) // the sort ? + || evt.PropertyName.equals(PROPERTY_APPLYFILTER) // the appliance of the filter ? + || evt.PropertyName.equals(PROPERTY_TEXTLINECOLOR) // the text line color ? + || evt.PropertyName.equals(PROPERTY_TEXTEMPHASIS) // the text emphasis ? + || evt.PropertyName.equals(PROPERTY_TEXTRELIEF) // the text relief ? + ) + { + transferChangedControlProperty(evt.PropertyName, evt.NewValue); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +// ----------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::suspend(sal_Bool bSuspend) throw( RuntimeException ) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard( getMutex() ); + if ( getView() && getView()->IsInModalMode() ) + return sal_False; + sal_Bool bRet = sal_False; + if ( !m_bInSuspend ) + { + m_bInSuspend = sal_True; + if ( rBHelper.bDisposed ) + throw DisposedException( ::rtl::OUString(), *this ); + + bRet = SbaXDataBrowserController::suspend(bSuspend); + if ( bRet && getView() ) + getView()->Hide(); + + m_bInSuspend = sal_False; + } + + return bRet; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaTableQueryBrowser::statusChanged( const FeatureStateEvent& _rEvent ) throw(RuntimeException) +{ + // search the external dispatcher causing this call + Reference< XDispatch > xSource(_rEvent.Source, UNO_QUERY); + ExternalFeaturesMap::iterator aLoop; + for ( aLoop = m_aExternalFeatures.begin(); + aLoop != m_aExternalFeatures.end(); + ++aLoop + ) + { + if ( _rEvent.FeatureURL.Complete == aLoop->second.aURL.Complete) + { + DBG_ASSERT( xSource.get() == aLoop->second.xDispatcher.get(), "SbaTableQueryBrowser::statusChanged: inconsistent!" ); + // update the enabled state + aLoop->second.bEnabled = _rEvent.IsEnabled; + + switch ( aLoop->first ) + { + case ID_BROWSER_DOCUMENT_DATASOURCE: + { + // if it's the slot for the document data source, remember the state + Sequence< PropertyValue > aDescriptor; + #if OSL_DEBUG_LEVEL > 0 + sal_Bool bProperFormat = + #endif + _rEvent.State >>= aDescriptor; + OSL_ENSURE(bProperFormat, "SbaTableQueryBrowser::statusChanged: need a data access descriptor here!"); + m_aDocumentDataSource.initializeFrom(aDescriptor); + + OSL_ENSURE( ( m_aDocumentDataSource.has(daDataSource) + || m_aDocumentDataSource.has(daDatabaseLocation) + ) + && m_aDocumentDataSource.has(daCommand) + && m_aDocumentDataSource.has(daCommandType), + "SbaTableQueryBrowser::statusChanged: incomplete descriptor!"); + + // check if we know the object which is set as document data source + checkDocumentDataSource(); + } + break; + + default: + // update the toolbox + implCheckExternalSlot( aLoop->first ); + break; + } + break; + } + } + + DBG_ASSERT(aLoop != m_aExternalFeatures.end(), "SbaTableQueryBrowser::statusChanged: don't know who sent this!"); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::checkDocumentDataSource() +{ + SvLBoxEntry* pDataSourceEntry = NULL; + SvLBoxEntry* pContainerEntry = NULL; + SvLBoxEntry* pObjectEntry = getObjectEntry( m_aDocumentDataSource, &pDataSourceEntry, &pContainerEntry, sal_False ); + sal_Bool bKnownDocDataSource = (NULL != pObjectEntry); + if (!bKnownDocDataSource) + { + if (NULL != pDataSourceEntry) + { // at least the data source is know + if (NULL != pContainerEntry) + bKnownDocDataSource = sal_True; // assume we know it. + // TODO: should we expand the object container? This may be too expensive just for checking .... + else + { + if ((NULL == pObjectEntry) && m_aDocumentDataSource.has(daCommandType) && m_aDocumentDataSource.has(daCommand)) + { // maybe we have a command to be displayed ? + sal_Int32 nCommandType = CommandType::TABLE; + m_aDocumentDataSource[daCommandType] >>= nCommandType; + + ::rtl::OUString sCommand; + m_aDocumentDataSource[daCommand] >>= sCommand; + + bKnownDocDataSource = (CommandType::COMMAND == nCommandType) && (0 != sCommand.getLength()); + } + } + } + } + + if ( !bKnownDocDataSource ) + m_aExternalFeatures[ ID_BROWSER_DOCUMENT_DATASOURCE ].bEnabled = sal_False; + + // update the toolbox + implCheckExternalSlot(ID_BROWSER_DOCUMENT_DATASOURCE); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::extractDescriptorProps(const ::svx::ODataAccessDescriptor& _rDescriptor, ::rtl::OUString& _rDataSource, ::rtl::OUString& _rCommand, sal_Int32& _rCommandType, sal_Bool& _rEscapeProcessing) +{ + _rDataSource = _rDescriptor.getDataSource(); + if ( _rDescriptor.has(daCommand) ) + _rDescriptor[daCommand] >>= _rCommand; + if ( _rDescriptor.has(daCommandType) ) + _rDescriptor[daCommandType] >>= _rCommandType; + + // escape processing is the only one allowed not to be present + _rEscapeProcessing = sal_True; + if (_rDescriptor.has(daEscapeProcessing)) + _rEscapeProcessing = ::cppu::any2bool(_rDescriptor[daEscapeProcessing]); +} + +// ------------------------------------------------------------------------- +namespace +{ + bool getDataSourceDisplayName_isURL( const String& _rDS, String& _rDisplayName, String& _rUniqueId ) + { + INetURLObject aURL( _rDS ); + if ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) + { + _rDisplayName = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET); + // _rDisplayName = aURL.getName(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET); + _rUniqueId = aURL.GetMainURL( INetURLObject::NO_DECODE ); + return true; + } + _rDisplayName = _rDS; + _rUniqueId = String(); + return false; + } + + // ..................................................................... + struct FilterByEntryDataId : public IEntryFilter + { + String sId; + FilterByEntryDataId( const String& _rId ) : sId( _rId ) { } + + virtual ~FilterByEntryDataId() {} + + virtual bool includeEntry( SvLBoxEntry* _pEntry ) const; + }; + + bool FilterByEntryDataId::includeEntry( SvLBoxEntry* _pEntry ) const + { + DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() ); + return ( !pData || ( pData->sAccessor == sId ) ); + } +} + +// ------------------------------------------------------------------------- +String SbaTableQueryBrowser::getDataSourceAcessor( SvLBoxEntry* _pDataSourceEntry ) const +{ + DBG_ASSERT( _pDataSourceEntry, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry!" ); + + DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( _pDataSourceEntry->GetUserData() ); + DBG_ASSERT( pData, "SbaTableQueryBrowser::getDataSourceAcessor: invalid entry data!" ); + DBG_ASSERT( pData->eType == etDatasource, "SbaTableQueryBrowser::getDataSourceAcessor: entry does not denote a data source!" ); + return pData->sAccessor.Len() ? pData->sAccessor : GetEntryText( _pDataSourceEntry ); +} + +// ------------------------------------------------------------------------- +SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::rtl::OUString& _rDataSource, const ::rtl::OUString& _rCommand, sal_Int32 _nCommandType, + SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry, sal_Bool _bExpandAncestors, + const SharedConnection& _rxConnection ) +{ + if (_ppDataSourceEntry) + *_ppDataSourceEntry = NULL; + if (_ppContainerEntry) + *_ppContainerEntry = NULL; + + SvLBoxEntry* pObject = NULL; + if ( m_pTreeView ) + { + // look for the data source entry + String sDisplayName, sDataSourceId; + bool bIsDataSourceURL = getDataSourceDisplayName_isURL( _rDataSource, sDisplayName, sDataSourceId ); + // the display name may differ from the URL for readability reasons + // #i33699# - 2004-09-24 - fs@openoffice.org + + FilterByEntryDataId aFilter( sDataSourceId ); + SvLBoxEntry* pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter ); + if ( !pDataSource ) // check if the data source name is a file location + { + if ( bIsDataSourceURL ) + { + // special case, the data source is a URL + // add new entries to the list box model + implAddDatasource( _rDataSource, _rxConnection ); + pDataSource = m_pTreeView->getListBox().GetEntryPosByName( sDisplayName, NULL, &aFilter ); + DBG_ASSERT( pDataSource, "SbaTableQueryBrowser::getObjectEntry: hmm - did not find it again!" ); + } + } + if (_ppDataSourceEntry) + // (caller wants to have it ...) + *_ppDataSourceEntry = pDataSource; + + if (pDataSource) + { + // expand if required so + if (_bExpandAncestors) + m_pTreeView->getListBox().Expand(pDataSource); + + // look for the object container + SvLBoxEntry* pCommandType = NULL; + switch (_nCommandType) + { + case CommandType::TABLE: + pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_TABLES); + break; + + case CommandType::QUERY: + pCommandType = m_pTreeView->getListBox().GetModel()->GetEntry(pDataSource, CONTAINER_QUERIES); + break; + } + + if (_ppContainerEntry) + *_ppContainerEntry = pCommandType; + + if (pCommandType) + { + // expand if required so + if (_bExpandAncestors) + { + m_pTreeView->getListBox().Expand(pCommandType); + } + + // look for the object + ::rtl::OUString sCommand = _rCommand; + sal_Int32 nIndex = 0; + do + { + ::rtl::OUString sPath = sCommand.getToken( 0, '/', nIndex ); + pObject = m_pTreeView->getListBox().GetEntryPosByName(sPath, pCommandType); + pCommandType = pObject; + if ( nIndex >= 0 ) + { + if (ensureEntryObject(pObject)) + { + DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( pObject->GetUserData() ); + Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY ); + sal_Int32 nIndex2 = nIndex; + sPath = sCommand.getToken( 0, '/', nIndex2 ); + try + { + if ( xCollection->hasByName(sPath) ) + { + if(!m_pTreeView->getListBox().GetEntryPosByName(sPath,pObject)) + { + Reference<XNameAccess> xChild(xCollection->getByName(sPath),UNO_QUERY); + DBTreeListUserData* pEntryData = new DBTreeListUserData; + pEntryData->eType = etQuery; + if ( xChild.is() ) + { + pEntryData->eType = etQueryContainer; + } + implAppendEntry( pObject, sPath, pEntryData, pEntryData->eType ); + } + } + } + catch(Exception&) + { + DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree"); + } + } + } + // m_pTreeView->getListBox().Expand(pCommandType); + } + while ( nIndex >= 0 ); + } + } + } + return pObject; +} + +// ------------------------------------------------------------------------- +SvLBoxEntry* SbaTableQueryBrowser::getObjectEntry(const ::svx::ODataAccessDescriptor& _rDescriptor, + SvLBoxEntry** _ppDataSourceEntry, SvLBoxEntry** _ppContainerEntry, + sal_Bool _bExpandAncestors) +{ + // extract the props from the descriptor + ::rtl::OUString sDataSource; + ::rtl::OUString sCommand; + sal_Int32 nCommandType = CommandType::COMMAND; + sal_Bool bEscapeProcessing = sal_True; + extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing); + + return getObjectEntry( sDataSource, sCommand, nCommandType, _ppDataSourceEntry, _ppContainerEntry, _bExpandAncestors, SharedConnection() ); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::connectExternalDispatches() +{ + Reference< XDispatchProvider > xProvider( getFrame(), UNO_QUERY ); + DBG_ASSERT(xProvider.is(), "SbaTableQueryBrowser::connectExternalDispatches: no DispatchProvider !"); + if (xProvider.is()) + { + if ( m_aExternalFeatures.empty() ) + { + const sal_Char* pURLs[] = { + ".uno:DataSourceBrowser/DocumentDataSource", + ".uno:DataSourceBrowser/FormLetter", + ".uno:DataSourceBrowser/InsertColumns", + ".uno:DataSourceBrowser/InsertContent", + }; + const sal_uInt16 nIds[] = { + ID_BROWSER_DOCUMENT_DATASOURCE, + ID_BROWSER_FORMLETTER, + ID_BROWSER_INSERTCOLUMNS, + ID_BROWSER_INSERTCONTENT + }; + + for ( size_t i=0; i < sizeof( pURLs ) / sizeof( pURLs[0] ); ++i ) + { + URL aURL; + aURL.Complete = ::rtl::OUString::createFromAscii( pURLs[i] ); + if ( m_xUrlTransformer.is() ) + m_xUrlTransformer->parseStrict( aURL ); + m_aExternalFeatures[ nIds[ i ] ] = ExternalFeature( aURL ); + } + } + + for ( ExternalFeaturesMap::iterator feature = m_aExternalFeatures.begin(); + feature != m_aExternalFeatures.end(); + ++feature + ) + { + feature->second.xDispatcher = xProvider->queryDispatch( + feature->second.aURL, ::rtl::OUString::createFromAscii("_parent"), FrameSearchFlag::PARENT + ); + + if ( feature->second.xDispatcher.get() == static_cast< XDispatch* >( this ) ) + { + OSL_ENSURE( sal_False, "SbaTableQueryBrowser::connectExternalDispatches: this should not happen anymore!" ); + // (nowadays, the URLs aren't in our SupportedFeatures list anymore, so we should + // not supply a dispatcher for this) + feature->second.xDispatcher.clear(); + } + + if ( feature->second.xDispatcher.is() ) + { + try + { + feature->second.xDispatcher->addStatusListener( this, feature->second.aURL ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + implCheckExternalSlot( feature->first ); + } + } +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::implCheckExternalSlot( sal_uInt16 _nId ) +{ + if ( !m_xMainToolbar.is() ) + return; + + Window* pToolboxWindow = VCLUnoHelper::GetWindow( m_xMainToolbar ); + ToolBox* pToolbox = dynamic_cast< ToolBox* >( pToolboxWindow ); + OSL_ENSURE( pToolbox, "SbaTableQueryBrowser::implCheckExternalSlot: cannot obtain the toolbox window!" ); + + // check if we have to hide this item from the toolbox + if ( pToolbox ) + { + sal_Bool bHaveDispatcher = m_aExternalFeatures[ _nId ].xDispatcher.is(); + if ( bHaveDispatcher != pToolbox->IsItemVisible( _nId ) ) + bHaveDispatcher ? pToolbox->ShowItem( _nId ) : pToolbox->HideItem( _nId ); + } + + // and invalidate this feature in general + InvalidateFeature( _nId ); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaTableQueryBrowser::disposing( const EventObject& _rSource ) throw(RuntimeException) +{ + // our frame ? + Reference< ::com::sun::star::frame::XFrame > xSourceFrame(_rSource.Source, UNO_QUERY); + if (m_xCurrentFrameParent.is() && (xSourceFrame == m_xCurrentFrameParent)) + m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); + else + { + // search the external dispatcher causing this call in our map + Reference< XDispatch > xSource(_rSource.Source, UNO_QUERY); + if(xSource.is()) + { + for ( ExternalFeaturesMap::iterator aLoop = m_aExternalFeatures.begin(); + aLoop != m_aExternalFeatures.end(); + ++aLoop + ) + { + if ( aLoop->second.xDispatcher.get() == xSource.get() ) + { + ExternalFeaturesMap::iterator aPrevious = aLoop; + --aPrevious; + + // remove it + m_aExternalFeatures.erase( aLoop ); + + // maybe update the UI + implCheckExternalSlot(aLoop->first); + + // continue, the same XDispatch may be resposible for more than one URL + aLoop = aPrevious; + } + } + } + else + { + Reference<XConnection> xCon(_rSource.Source, UNO_QUERY); + if ( xCon.is() && m_pTreeView ) + { // our connection is in dispose so we have to find the entry equal with this connection + // and close it what means to collapse the entry + // get the top-level representing the removed data source + SvLBoxEntry* pDSLoop = m_pTreeView->getListBox().FirstChild(NULL); + while (pDSLoop) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pDSLoop->GetUserData()); + if ( pData && pData->xConnection == xCon ) + { + // we set the conenction to null to avoid a second disposing of the connection + pData->xConnection.clear(); + closeConnection(pDSLoop,sal_False); + break; + } + + pDSLoop = m_pTreeView->getListBox().NextSibling(pDSLoop); + } + } + else + SbaXDataBrowserController::disposing(_rSource); + } + } +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::implRemoveStatusListeners() +{ + // clear all old dispatches + for ( ExternalFeaturesMap::const_iterator aLoop = m_aExternalFeatures.begin(); + aLoop != m_aExternalFeatures.end(); + ++aLoop + ) + { + if ( aLoop->second.xDispatcher.is() ) + { + try + { + aLoop->second.xDispatcher->removeStatusListener( this, aLoop->second.aURL ); + } + catch (Exception&) + { + DBG_ERROR("SbaTableQueryBrowser::implRemoveStatusListeners: could not remove a status listener!"); + } + } + } + m_aExternalFeatures.clear(); +} + +// ------------------------------------------------------------------------- +sal_Bool SAL_CALL SbaTableQueryBrowser::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException) +{ + ::vos::OGuard aGuard(Application::GetSolarMutex()); + // doin' a lot of VCL stuff here -> lock the SolarMutex + + Sequence< PropertyValue > aDescriptorSequence; + if (!(_rSelection >>= aDescriptorSequence)) + throw IllegalArgumentException(::rtl::OUString(), *this, 1); + // TODO: error message + + ODataAccessDescriptor aDescriptor; + try + { + aDescriptor = ODataAccessDescriptor(aDescriptorSequence); + } + catch(const Exception&) + { + OSL_ENSURE(sal_False, "SbaTableQueryBrowser::select: could not extract the descriptor!"); + } + + // check the precense of the props we need + if ( !(aDescriptor.has(daDataSource) || aDescriptor.has(daDatabaseLocation)) || !aDescriptor.has(daCommand) || !aDescriptor.has(daCommandType)) + throw IllegalArgumentException(::rtl::OUString(), *this, 1); + // TODO: error message + + return implSelect(aDescriptor,sal_True); +} + +// ------------------------------------------------------------------------- +Any SAL_CALL SbaTableQueryBrowser::getSelection( ) throw (RuntimeException) +{ + Any aReturn; + + try + { + Reference< XLoadable > xLoadable(getRowSet(), UNO_QUERY); + if (xLoadable.is() && xLoadable->isLoaded()) + { + Reference< XPropertySet > aFormProps(getRowSet(), UNO_QUERY); + ODataAccessDescriptor aDescriptor(aFormProps); + // remove properties which are not part of our "selection" + aDescriptor.erase(daConnection); + aDescriptor.erase(daCursor); + + aReturn <<= aDescriptor.createPropertyValueSequence(); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return aReturn; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaTableQueryBrowser::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) +{ + m_aSelectionListeners.addInterface(_rxListener); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaTableQueryBrowser::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException) +{ + m_aSelectionListeners.removeInterface(_rxListener); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::attachFrame(const Reference< ::com::sun::star::frame::XFrame > & _xFrame) throw( RuntimeException ) +{ + implRemoveStatusListeners(); + + if (m_xCurrentFrameParent.is()) + m_xCurrentFrameParent->removeFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); + + SbaXDataBrowserController::attachFrame(_xFrame); + + Reference< XFrame > xCurrentFrame( getFrame() ); + if ( xCurrentFrame.is() ) + { + m_xCurrentFrameParent = xCurrentFrame->findFrame(::rtl::OUString::createFromAscii("_parent"),FrameSearchFlag::PARENT); + if ( m_xCurrentFrameParent.is() ) + m_xCurrentFrameParent->addFrameActionListener((::com::sun::star::frame::XFrameActionListener*)this); + + // obtain our toolbox + try + { + Reference< XPropertySet > xFrameProps( m_aCurrentFrame.getFrame(), UNO_QUERY_THROW ); + Reference< XLayoutManager > xLayouter( + xFrameProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) ) ), + UNO_QUERY ); + + if ( xLayouter.is() ) + { + Reference< XUIElement > xUI( + xLayouter->getElement( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ) ) ), + UNO_SET_THROW ); + m_xMainToolbar = m_xMainToolbar.query( xUI->getRealInterface() ); + OSL_ENSURE( m_xMainToolbar.is(), "SbaTableQueryBrowser::attachFrame: where's my toolbox?" ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + // get the dispatchers for the external slots + connectExternalDispatches(); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::addModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) +{ + SbaXDataBrowserController::addModelListeners(_xGridControlModel); + Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY); + if (xSourceSet.is()) + { + xSourceSet->addPropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->addPropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->addPropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->addPropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->addPropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->addPropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this)); + } + +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::removeModelListeners(const Reference< ::com::sun::star::awt::XControlModel > & _xGridControlModel) +{ + SbaXDataBrowserController::removeModelListeners(_xGridControlModel); + Reference< XPropertySet > xSourceSet(_xGridControlModel, UNO_QUERY); + if (xSourceSet.is()) + { + xSourceSet->removePropertyChangeListener(PROPERTY_ROW_HEIGHT, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_FONT, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_TEXTCOLOR, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_TEXTLINECOLOR, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_TEXTEMPHASIS, static_cast<XPropertyChangeListener*>(this)); + xSourceSet->removePropertyChangeListener(PROPERTY_TEXTRELIEF, static_cast<XPropertyChangeListener*>(this)); + } +} +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::RowChanged() +{ + if(getBrowserView()) + { + SbaGridControl* pControl = getBrowserView()->getVclControl(); + if (!pControl->IsEditing()) + InvalidateFeature(ID_BROWSER_COPY); + } + SbaXDataBrowserController::RowChanged(); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::ColumnChanged() +{ + if(getBrowserView()) + { + SbaGridControl* pControl = getBrowserView()->getVclControl(); + if (!pControl->IsEditing()) + InvalidateFeature(ID_BROWSER_COPY); + } + SbaXDataBrowserController::ColumnChanged(); +} +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::AddColumnListener(const Reference< XPropertySet > & xCol) +{ + SbaXDataBrowserController::AddColumnListener(xCol); + SafeAddPropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this)); + SafeAddPropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this)); + SafeAddPropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this)); + SafeAddPropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this)); +} + +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::RemoveColumnListener(const Reference< XPropertySet > & xCol) +{ + SbaXDataBrowserController::RemoveColumnListener(xCol); + SafeRemovePropertyListener(xCol, PROPERTY_WIDTH, static_cast<XPropertyChangeListener*>(this)); + SafeRemovePropertyListener(xCol, PROPERTY_HIDDEN, static_cast<XPropertyChangeListener*>(this)); + SafeRemovePropertyListener(xCol, PROPERTY_ALIGN, static_cast<XPropertyChangeListener*>(this)); + SafeRemovePropertyListener(xCol, PROPERTY_FORMATKEY, static_cast<XPropertyChangeListener*>(this)); +} + +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::criticalFail() +{ + SbaXDataBrowserController::criticalFail(); + unloadAndCleanup( sal_False ); +} + +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::LoadFinished(sal_Bool _bWasSynch) +{ + SbaXDataBrowserController::LoadFinished(_bWasSynch); + + m_sQueryCommand = ::rtl::OUString(); + m_bQueryEscapeProcessing = sal_False; + + if (isValid() && !loadingCancelled()) + { + // did we load a query? + sal_Bool bTemporary; // needed because we m_bQueryEscapeProcessing is only one bit wide (and we want to pass it by reference) + if ( implGetQuerySignature( m_sQueryCommand, bTemporary ) ) + m_bQueryEscapeProcessing = bTemporary; + } + + // if the form has been loaded, this means that our "selection" has changed + EventObject aEvent( *this ); + m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvent ); +} + +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::getExternalSlotState( sal_uInt16 _nId ) const +{ + sal_Bool bEnabled = sal_False; + ExternalFeaturesMap::const_iterator aPos = m_aExternalFeatures.find( _nId ); + if ( ( m_aExternalFeatures.end() != aPos ) && aPos->second.xDispatcher.is() ) + bEnabled = aPos->second.bEnabled; + return bEnabled; +} + +//------------------------------------------------------------------------------ +FeatureState SbaTableQueryBrowser::GetState(sal_uInt16 nId) const +{ + FeatureState aReturn; + // (disabled automatically) + + // no chance without a view + if (!getBrowserView() || !getBrowserView()->getVclControl()) + return aReturn; + + switch ( nId ) + { + case ID_TREE_ADMINISTRATE: + aReturn.bEnabled = true; + return aReturn; + + case ID_BROWSER_CLOSE: + // the close button should always be enabled + aReturn.bEnabled = !m_bEnableBrowser; + return aReturn; + + // "toggle explorer" is always enabled (if we have a explorer) + case ID_BROWSER_EXPLORER: + aReturn.bEnabled = m_bEnableBrowser; + aReturn.bChecked = haveExplorer(); + return aReturn; + + case ID_BROWSER_REMOVEFILTER: + return SbaXDataBrowserController::GetState( nId ); + + case ID_BROWSER_COPY: + if ( !m_pTreeView->HasChildPathFocus() ) + // handled below + break; + // NO break! + case ID_TREE_CLOSE_CONN: + case ID_TREE_EDIT_DATABASE: + { + SvLBoxEntry* pCurrentEntry( m_pTreeView->getListBox().GetCurEntry() ); + EntryType eType = getEntryType( pCurrentEntry ); + if ( eType == etUnknown ) + return aReturn; + + SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent( pCurrentEntry ); + DBTreeListUserData* pDSData + = pDataSourceEntry + ? static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() ) + : NULL; + + if ( nId == ID_TREE_CLOSE_CONN ) + { + aReturn.bEnabled = ( pDSData != NULL ) && pDSData->xConnection.is(); + } + else if ( nId == ID_TREE_EDIT_DATABASE ) + { + ::utl::OConfigurationTreeRoot aConfig( ::utl::OConfigurationTreeRoot::createWithServiceFactory( getORB(), + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.DataAccess/Policies/Features/Common" ) ) ) ); + sal_Bool bHaveEditDatabase( sal_True ); + OSL_VERIFY( aConfig.getNodeValue( "EditDatabaseFromDataSourceView" ) >>= bHaveEditDatabase ); + aReturn.bEnabled = getORB().is() && ( pDataSourceEntry != NULL ) && bHaveEditDatabase; + } + else if ( nId == ID_BROWSER_COPY ) + { + aReturn.bEnabled = isEntryCopyAllowed( pCurrentEntry ); + } + + return aReturn; + } + } + + // all slots not handled above are not available if no form is loaded + if (!isLoaded()) + return aReturn; + + try + { + sal_Bool bHandled = sal_False; + switch (nId) + { + case ID_BROWSER_DOCUMENT_DATASOURCE: + // the slot is enabled if we have an external dispatcher able to handle it, + // and the dispatcher must have enabled the slot in general + aReturn.bEnabled = getExternalSlotState( ID_BROWSER_DOCUMENT_DATASOURCE ); + bHandled = sal_True; + break; + case ID_BROWSER_REFRESH: + aReturn.bEnabled = sal_True; + bHandled = sal_True; + break; + } + + if (bHandled) + return aReturn; + + // no chance without valid models + if (isValid() && !isValidCursor() && nId != ID_BROWSER_CLOSE) + return aReturn; + + switch (nId) + { + case ID_BROWSER_INSERTCOLUMNS: + case ID_BROWSER_INSERTCONTENT: + case ID_BROWSER_FORMLETTER: + { + // the slot is enabled if we have an external dispatcher able to handle it, + // and the dispatcher must have enabled the slot in general + aReturn.bEnabled = getExternalSlotState( nId ); + + // for the Insert* slots, we need at least one selected row + if (ID_BROWSER_FORMLETTER != nId) + aReturn.bEnabled = aReturn.bEnabled && getBrowserView()->getVclControl()->GetSelectRowCount(); + + // disabled for native queries which are not saved within the database + // 67706 - 23.08.99 - FS + Reference< XPropertySet > xDataSource(getRowSet(), UNO_QUERY); + try + { + aReturn.bEnabled = aReturn.bEnabled && xDataSource.is(); + + if (xDataSource.is()) + { + sal_Int32 nType = ::comphelper::getINT32(xDataSource->getPropertyValue(PROPERTY_COMMAND_TYPE)); + aReturn.bEnabled = aReturn.bEnabled && ((::comphelper::getBOOL(xDataSource->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)) || (nType == ::com::sun::star::sdb::CommandType::QUERY))); + } + } + catch(DisposedException&) + { + OSL_ENSURE(sal_False, "SbaTableQueryBrowser::GetState: object already disposed!"); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + break; + + case ID_BROWSER_TITLE: + { + Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); + sal_Int32 nCommandType = CommandType::TABLE; + xProp->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nCommandType; + String sTitle; + switch (nCommandType) + { + case CommandType::TABLE: + sTitle = String(ModuleRes(STR_TBL_TITLE)); break; + case CommandType::QUERY: + case CommandType::COMMAND: + sTitle = String(ModuleRes(STR_QRY_TITLE)); break; + default: + DBG_ASSERT(sal_False, "SbaTableQueryBrowser::GetState: unknown command type!"); + } + ::rtl::OUString aName; + xProp->getPropertyValue(PROPERTY_COMMAND) >>= aName; + String sObject(aName.getStr()); + + sTitle.SearchAndReplace('#',sObject); + aReturn.sTitle = sTitle; + aReturn.bEnabled = sal_True; + } + break; + case ID_BROWSER_TABLEATTR: + case ID_BROWSER_ROWHEIGHT: + case ID_BROWSER_COLATTRSET: + case ID_BROWSER_COLWIDTH: + aReturn.bEnabled = getBrowserView() && getBrowserView()->getVclControl() && isValid() && isValidCursor(); + // aReturn.bEnabled &= getDefinition() && !getDefinition()->GetDatabase()->IsReadOnly(); + break; + + case ID_BROWSER_COPY: + OSL_ENSURE( !m_pTreeView->HasChildPathFocus(), "SbaTableQueryBrowser::GetState( ID_BROWSER_COPY ): this should have been handled above!" ); + if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing()) + { + SbaGridControl* pControl = getBrowserView()->getVclControl(); + if ( pControl->GetSelectRowCount() ) + { + aReturn.bEnabled = m_aCurrentFrame.isActive(); + break; + } // if ( getBrowserView()->getVclControl()->GetSelectRowCount() ) + else + aReturn.bEnabled = pControl->canCopyCellText(pControl->GetCurRow(), pControl->GetCurColumnId()); + break; + } + // NO break here + default: + return SbaXDataBrowserController::GetState(nId); + } + } + catch(const Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return aReturn; + +} + +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::Execute(sal_uInt16 nId, const Sequence< PropertyValue >& aArgs) +{ + switch (nId) + { + default: + SbaXDataBrowserController::Execute(nId,aArgs); + break; + + case ID_TREE_EDIT_DATABASE: + implAdministrate( m_pTreeView->getListBox().GetCurEntry() ); + break; + + case ID_TREE_CLOSE_CONN: + openHelpAgent( HID_DSBROWSER_DISCONNECTING ); + closeConnection( m_pTreeView->getListBox().GetRootLevelParent( m_pTreeView->getListBox().GetCurEntry() ) ); + break; + + case ID_TREE_ADMINISTRATE: + ::svx::administrateDatabaseRegistration( getView() ); + break; + + case ID_BROWSER_REFRESH: + { + if ( !SaveModified( ) ) + // nothing to do + break; + + sal_Bool bFullReinit = sal_False; + // check if the query signature (if the form is based on a query) has changed + if ( m_sQueryCommand.getLength() ) + { + ::rtl::OUString sNewQueryCommand; + sal_Bool bNewQueryEP; + +#if OSL_DEBUG_LEVEL > 0 + sal_Bool bIsQuery = +#endif + implGetQuerySignature( sNewQueryCommand, bNewQueryEP ); + OSL_ENSURE( bIsQuery, "SbaTableQueryBrowser::Execute: was a query before, but is not anymore?" ); + + bFullReinit = ( sNewQueryCommand != m_sQueryCommand ) || ( m_bQueryEscapeProcessing != bNewQueryEP ); + } + if ( !bFullReinit ) + { + // let the base class do a simple reload + SbaXDataBrowserController::Execute(nId,aArgs); + break; + } + // NO break here! + } + + case ID_BROWSER_REFRESH_REBUILD: + { + if ( !SaveModified() ) + // nothing to do + break; + + SvLBoxEntry* pSelected = m_pCurrentlyDisplayed; + // unload + unloadAndCleanup( sal_False ); + + // reselect the entry + if ( pSelected ) + { + implSelect( pSelected ); + } + else + { + Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); + implSelect(::svx::ODataAccessDescriptor(xProp)); + } + } + break; + + case ID_BROWSER_EXPLORER: + toggleExplorer(); + break; + + case ID_BROWSER_DOCUMENT_DATASOURCE: + implSelect(m_aDocumentDataSource); + break; + + case ID_BROWSER_INSERTCOLUMNS: + case ID_BROWSER_INSERTCONTENT: + case ID_BROWSER_FORMLETTER: + if (getBrowserView() && isValidCursor()) + { + // the URL the slot id is assigned to + OSL_ENSURE( m_aExternalFeatures.find( nId ) != m_aExternalFeatures.end(), + "SbaTableQueryBrowser::Execute( ID_BROWSER_?): how could this ever be enabled?" ); + URL aParentUrl = m_aExternalFeatures[ nId ].aURL; + + // let the dispatcher execute the slot + Reference< XDispatch > xDispatch( m_aExternalFeatures[ nId ].xDispatcher ); + if (xDispatch.is()) + { + // set the properties for the dispatch + + // first fill the selection + SbaGridControl* pGrid = getBrowserView()->getVclControl(); + MultiSelection* pSelection = (MultiSelection*)pGrid->GetSelection(); + Sequence< Any > aSelection; + if ( !pGrid->IsAllSelected() ) + { // transfer the selected rows only if not all rows are selected + // (all rows means the whole table) + // i3832 - 03.04.2002 - fs@openoffice.org + if (pSelection != NULL) + { + aSelection.realloc(pSelection->GetSelectCount()); + long nIdx = pSelection->FirstSelected(); + Any* pSelectionNos = aSelection.getArray(); + while (nIdx >= 0) + { + *pSelectionNos++ <<= (sal_Int32)(nIdx + 1); + nIdx = pSelection->NextSelected(); + } + } + } + + Reference< XResultSet > xCursorClone; + try + { + Reference< XResultSetAccess > xResultSetAccess(getRowSet(),UNO_QUERY); + if (xResultSetAccess.is()) + xCursorClone = xResultSetAccess->createResultSet(); + } + catch(DisposedException&) + { + OSL_ENSURE(0,"Object already disposed!"); + } + catch(Exception&) + { + DBG_ERROR("SbaTableQueryBrowser::Execute(ID_BROWSER_?): could not clone the cursor!"); + } + + Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); + + try + { + ODataAccessDescriptor aDescriptor; + ::rtl::OUString sDataSourceName; + xProp->getPropertyValue(PROPERTY_DATASOURCENAME) >>= sDataSourceName; + + aDescriptor.setDataSource(sDataSourceName); + aDescriptor[daCommand] = xProp->getPropertyValue(PROPERTY_COMMAND); + aDescriptor[daCommandType] = xProp->getPropertyValue(PROPERTY_COMMAND_TYPE); + aDescriptor[daConnection] = xProp->getPropertyValue(PROPERTY_ACTIVE_CONNECTION); + aDescriptor[daCursor] <<= xCursorClone; + if ( aSelection.getLength() ) + { + aDescriptor[daSelection] <<= aSelection; + aDescriptor[daBookmarkSelection] <<= sal_False; + // these are selection indicies + // before we change this, all clients have to be adjusted + // so that they recognize the new BookmarkSelection property! + } + + xDispatch->dispatch(aParentUrl, aDescriptor.createPropertyValueSequence()); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + break; + + case ID_BROWSER_CLOSE: + closeTask(); + // if it's not 0, such a async close is already pending + break; + + case ID_BROWSER_COPY: + if(m_pTreeView->HasChildPathFocus()) + { + copyEntry(m_pTreeView->getListBox().GetCurEntry()); + } + else if (getBrowserView() && getBrowserView()->getVclControl() && !getBrowserView()->getVclControl()->IsEditing() && getBrowserView()->getVclControl()->GetSelectRowCount() < 1) + { + SbaGridControl* pControl = getBrowserView()->getVclControl(); + pControl->copyCellText(pControl->GetCurRow(), pControl->GetCurColumnId()); + } + else + SbaXDataBrowserController::Execute(nId,aArgs); + break; + } +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::implAddDatasource( const String& _rDataSourceName, const SharedConnection& _rxConnection ) +{ + Image a, b, c; + String d, e; + implAddDatasource( _rDataSourceName, a, d, b, e, c, _rxConnection ); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::implAddDatasource(const String& _rDbName, Image& _rDbImage, + String& _rQueryName, Image& _rQueryImage, String& _rTableName, Image& _rTableImage, + const SharedConnection& _rxConnection) +{ + vos::OGuard aGuard( Application::GetSolarMutex() ); + // initialize the names/images if necessary + if (!_rQueryName.Len()) + _rQueryName = String(ModuleRes(RID_STR_QUERIES_CONTAINER)); + if (!_rTableName.Len()) + _rTableName = String(ModuleRes(RID_STR_TABLES_CONTAINER)); + + ImageProvider aImageProvider; + if (!_rQueryImage) + _rQueryImage = aImageProvider.getFolderImage( DatabaseObject::QUERY, isHiContrast() ); + if (!_rTableImage) + _rTableImage = aImageProvider.getFolderImage( DatabaseObject::TABLE, isHiContrast() ); + + if (!_rDbImage) + _rDbImage = aImageProvider.getDatabaseImage( isHiContrast() ); + + // add the entry for the data source + // special handling for data sources denoted by URLs - we do not want to display this ugly URL, do we? + // #i33699# - 2004-09-24 - fs@openoffice.org + String sDSDisplayName, sDataSourceId; + getDataSourceDisplayName_isURL( _rDbName, sDSDisplayName, sDataSourceId ); + + SvLBoxEntry* pDatasourceEntry = m_pTreeView->getListBox().InsertEntry( sDSDisplayName, _rDbImage, _rDbImage, NULL, sal_False ); + DBTreeListUserData* pDSData = new DBTreeListUserData; + pDSData->eType = etDatasource; + pDSData->sAccessor = sDataSourceId; + pDSData->xConnection = _rxConnection; + pDatasourceEntry->SetUserData(pDSData); + + // the child for the queries container + { + DBTreeListUserData* pQueriesData = new DBTreeListUserData; + pQueriesData->eType = etQueryContainer; + + m_pTreeView->getListBox().InsertEntry( + _rQueryName, _rQueryImage, _rQueryImage, pDatasourceEntry, + TRUE /*ChildsOnDemand*/, LIST_APPEND, pQueriesData ); + } + + // the child for the tables container + { + DBTreeListUserData* pTablesData = new DBTreeListUserData; + pTablesData->eType = etTableContainer; + + m_pTreeView->getListBox().InsertEntry( + _rTableName, _rTableImage, _rTableImage, pDatasourceEntry, + TRUE /*ChildsOnDemand*/, LIST_APPEND, pTablesData ); + } + +} +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::initializeTreeModel() +{ + if (m_xDatabaseContext.is()) + { + Image aDBImage, aQueriesImage, aTablesImage; + String sQueriesName, sTablesName; + + // fill the model with the names of the registered datasources + Sequence< ::rtl::OUString > aDatasources = m_xDatabaseContext->getElementNames(); + const ::rtl::OUString* pIter = aDatasources.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aDatasources.getLength(); + for (; pIter != pEnd; ++pIter) + implAddDatasource( *pIter, aDBImage, sQueriesName, aQueriesImage, sTablesName, aTablesImage, SharedConnection() ); + } +} +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::populateTree(const Reference<XNameAccess>& _xNameAccess, + SvLBoxEntry* _pParent, + EntryType _eEntryType) +{ + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pParent->GetUserData()); + if(pData) // don't ask if the nameaccess is already set see OnExpandEntry views and tables + pData->xContainer = _xNameAccess; + + try + { + Sequence< ::rtl::OUString > aNames = _xNameAccess->getElementNames(); + const ::rtl::OUString* pIter = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aNames.getLength(); + for (; pIter != pEnd; ++pIter) + { + if( !m_pTreeView->getListBox().GetEntryPosByName(*pIter,_pParent)) + { + Reference<XNameAccess> xChild(_xNameAccess->getByName(*pIter),UNO_QUERY); + DBTreeListUserData* pEntryData = new DBTreeListUserData; + pEntryData->eType = _eEntryType; + if ( _eEntryType == etQuery && xChild.is() ) + { + pEntryData->eType = etQueryContainer; + } + implAppendEntry( _pParent, *pIter, pEntryData, pEntryData->eType ); + } + } + } + catch(Exception&) + { + DBG_ERROR("SbaTableQueryBrowser::populateTree: could not fill the tree"); + } +} + +//------------------------------------------------------------------------------ +SvLBoxEntry* SbaTableQueryBrowser::implAppendEntry( SvLBoxEntry* _pParent, const String& _rName, void* _pUserData, EntryType _eEntryType ) +{ + ::std::auto_ptr< ImageProvider > pImageProvider( getImageProviderFor( _pParent ) ); + + Image aImage, aImageHC; + pImageProvider->getImages( _rName, getDatabaseObjectType( _eEntryType ), aImage, aImageHC ); + + SvLBoxEntry* pNewEntry = m_pTreeView->getListBox().InsertEntry( _rName, _pParent, _eEntryType == etQueryContainer , LIST_APPEND, _pUserData ); + + m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); + m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImage, BMP_COLOR_NORMAL ); + m_pTreeView->getListBox().SetExpandedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); + m_pTreeView->getListBox().SetCollapsedEntryBmp( pNewEntry, aImageHC, BMP_COLOR_HIGHCONTRAST ); + + return pNewEntry; +} + +//------------------------------------------------------------------------------ +IMPL_LINK(SbaTableQueryBrowser, OnExpandEntry, SvLBoxEntry*, _pParent) +{ + if (_pParent->HasChilds()) + // nothing to to ... + return 1L; + + SvLBoxEntry* pFirstParent = m_pTreeView->getListBox().GetRootLevelParent(_pParent); + OSL_ENSURE(pFirstParent,"SbaTableQueryBrowser::OnExpandEntry: No rootlevelparent!"); + + DBTreeListUserData* pData = static_cast< DBTreeListUserData* >(_pParent->GetUserData()); + OSL_ENSURE(pData,"SbaTableQueryBrowser::OnExpandEntry: No user data!"); +#if OSL_DEBUG_LEVEL > 0 + SvLBoxString* pString = static_cast<SvLBoxString*>(pFirstParent->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING)); + OSL_ENSURE(pString,"SbaTableQueryBrowser::OnExpandEntry: No string item!"); +#endif + + if (etTableContainer == pData->eType) + { + WaitObject aWaitCursor(getBrowserView()); + + // it could be that we already have a connection + SharedConnection xConnection; + ensureConnection( pFirstParent, xConnection ); + + if ( xConnection.is() ) + { + SQLExceptionInfo aInfo; + try + { + Reference< XWarningsSupplier > xWarnings(xConnection, UNO_QUERY); + if (xWarnings.is()) + xWarnings->clearWarnings(); + + // first insert the views because the tables can also include + // views but that time the bitmap is the wrong one + // the nameaccess will be overwriten in populateTree + Reference<XViewsSupplier> xViewSup(xConnection,UNO_QUERY); + if(xViewSup.is()) + populateTree( xViewSup->getViews(), _pParent, etTableOrView ); + + Reference<XTablesSupplier> xTabSup(xConnection,UNO_QUERY); + if(xTabSup.is()) + { + populateTree( xTabSup->getTables(), _pParent, etTableOrView ); + Reference<XContainer> xCont(xTabSup->getTables(),UNO_QUERY); + if(xCont.is()) + // add as listener to know when elements are inserted or removed + xCont->addContainerListener(this); + } + + if (xWarnings.is()) + { + SQLExceptionInfo aWarnings(xWarnings->getWarnings()); + if (aWarnings.isValid() && sal_False) + { + SQLContext aContext; + aContext.Message = String(ModuleRes(STR_OPENTABLES_WARNINGS)); + aContext.Details = String(ModuleRes(STR_OPENTABLES_WARNINGS_DETAILS)); + aContext.NextException = aWarnings.get(); + aWarnings = aContext; + showError(aWarnings); + } + // TODO: we need a better concept for these warnings: + // something like "don't show any warnings for this datasource, again" would be nice + // But this requires an extension of the InteractionHandler and an additional property on the data source + } + } + catch(const SQLContext& e) { aInfo = e; } + catch(const SQLWarning& e) { aInfo = e; } + catch(const SQLException& e) { aInfo = e; } + catch(const WrappedTargetException& e) + { + SQLException aSql; + if(e.TargetException >>= aSql) + aInfo = aSql; + else + OSL_ENSURE(sal_False, "SbaTableQueryBrowser::OnExpandEntry: something strange happended!"); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + if (aInfo.isValid()) + showError(aInfo); + } + else + return 0L; + // 0 indicates that an error occured + } + else + { // we have to expand the queries or bookmarks + if (ensureEntryObject(_pParent)) + { + DBTreeListUserData* pParentData = static_cast< DBTreeListUserData* >( _pParent->GetUserData() ); + Reference< XNameAccess > xCollection( pParentData->xContainer, UNO_QUERY ); + populateTree( xCollection, _pParent, etQuery ); + } + } + return 1L; +} + +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::ensureEntryObject( SvLBoxEntry* _pEntry ) +{ + DBG_ASSERT(_pEntry, "SbaTableQueryBrowser::ensureEntryObject: invalid argument!"); + if (!_pEntry) + return sal_False; + + EntryType eType = getEntryType( _pEntry ); + + // the user data of the entry + DBTreeListUserData* pEntryData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData()); + OSL_ENSURE(pEntryData,"ensureEntryObject: user data should already be set!"); + + SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().GetRootLevelParent(_pEntry); + + sal_Bool bSuccess = sal_False; + switch (eType) + { + case etQueryContainer: + if ( pEntryData->xContainer.is() ) + { + // nothing to do + bSuccess = sal_True; + break; + } + + { + SvLBoxEntry* pParent = m_pTreeView->getListBox().GetParent(_pEntry); + if ( pParent != pDataSourceEntry ) + { + SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); + OSL_ENSURE(pString,"There must be a string item!"); + ::rtl::OUString aName(pString->GetText()); + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pParent->GetUserData()); + try + { + Reference< XNameAccess > xNameAccess(pData->xContainer,UNO_QUERY); + if ( xNameAccess.is() ) + pEntryData->xContainer.set(xNameAccess->getByName(aName),UNO_QUERY); + } + catch(const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + bSuccess = pEntryData->xContainer.is(); + } + else + { + try + { + Reference< XQueryDefinitionsSupplier > xQuerySup; + m_xDatabaseContext->getByName( getDataSourceAcessor( pDataSourceEntry ) ) >>= xQuerySup; + if (xQuerySup.is()) + { + Reference< XNameAccess > xQueryDefs = xQuerySup->getQueryDefinitions(); + Reference< XContainer > xCont(xQueryDefs, UNO_QUERY); + if (xCont.is()) + // add as listener to get notified if elements are inserted or removed + xCont->addContainerListener(this); + + pEntryData->xContainer = xQueryDefs; + bSuccess = pEntryData->xContainer.is(); + } + else { + DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: no XQueryDefinitionsSupplier interface!"); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + break; + + default: + DBG_ERROR("SbaTableQueryBrowser::ensureEntryObject: ooops ... missing some implementation here!"); + // TODO ... + break; + } + + return bSuccess; +} +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::implSelect(const ::svx::ODataAccessDescriptor& _rDescriptor,sal_Bool _bSelectDirect) +{ + // extract the props + ::rtl::OUString sDataSource; + ::rtl::OUString sCommand; + sal_Int32 nCommandType = CommandType::COMMAND; + sal_Bool bEscapeProcessing = sal_True; + extractDescriptorProps(_rDescriptor, sDataSource, sCommand, nCommandType, bEscapeProcessing); + + // select it + return implSelect( sDataSource, sCommand, nCommandType, bEscapeProcessing, SharedConnection(), _bSelectDirect ); +} + +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::implLoadAnything(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand, + const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, const SharedConnection& _rxConnection) +{ + Reference<XPropertySet> xProp(getRowSet(),UNO_QUERY); + if(xProp.is()) + { + Reference< ::com::sun::star::form::XLoadable > xLoadable(xProp,UNO_QUERY); + try + { + // the values allowing the RowSet to re-execute + xProp->setPropertyValue(PROPERTY_DATASOURCENAME, makeAny(_rDataSourceName)); + if(_rxConnection.is()) + xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( _rxConnection.getTyped() ) ); + + // set this _before_ setting the connection, else the rowset would rebuild it ... + xProp->setPropertyValue(PROPERTY_COMMAND_TYPE, makeAny(_nCommandType)); + xProp->setPropertyValue(PROPERTY_COMMAND, makeAny(_rCommand)); + xProp->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, ::cppu::bool2any(_bEscapeProcessing)); + if ( m_bPreview ) + { + xProp->setPropertyValue(PROPERTY_FETCHDIRECTION, makeAny(FetchDirection::FORWARD)); + } + + // the formatter depends on the data source we're working on, so rebuild it here ... + initFormatter(); + + // switch the grid to design mode while loading + getBrowserView()->getGridControl()->setDesignMode(sal_True); + InitializeForm(getRowSet()); + + sal_Bool bSuccess = sal_True; + + { + { + Reference< XNameContainer > xColContainer(getFormComponent(), UNO_QUERY); + // first we have to clear the grid + clearGridColumns(xColContainer); + } + FormErrorHelper aHelper(this); + // load the form + bSuccess = reloadForm(xLoadable); + + // initialize the model + InitializeGridModel(getFormComponent()); + + if ( m_bPreview ) + initializePreviewMode(); + + LoadFinished(sal_True); + } + + InvalidateAll(); + return bSuccess; + } + catch( const SQLException& e ) + { + Any aException( ::cppu::getCaughtException() ); + showError( SQLExceptionInfo( aException ) ); + } + catch( const WrappedTargetException& e ) + { + SQLException aSql; + if ( e.TargetException.isExtractableTo( ::cppu::UnoType< SQLException >::get() ) ) + showError( SQLExceptionInfo( e.TargetException ) ); + else + { + DBG_UNHANDLED_EXCEPTION(); + } + } + catch(Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + InvalidateAll(); + return sal_False; +} + +//------------------------------------------------------------------------------ +sal_Bool SbaTableQueryBrowser::implSelect(const ::rtl::OUString& _rDataSourceName, const ::rtl::OUString& _rCommand, + const sal_Int32 _nCommandType, const sal_Bool _bEscapeProcessing, + const SharedConnection& _rxConnection + ,sal_Bool _bSelectDirect) +{ + if (_rDataSourceName.getLength() && _rCommand.getLength() && (-1 != _nCommandType)) + { + SvLBoxEntry* pDataSource = NULL; + SvLBoxEntry* pCommandType = NULL; + SvLBoxEntry* pCommand = getObjectEntry( _rDataSourceName, _rCommand, _nCommandType, &pDataSource, &pCommandType, sal_True, _rxConnection ); + + if (pCommand) + { + bool bSuccess = true; + if ( _bSelectDirect ) + { + bSuccess = implSelect( pCommand ); + } + else + { + m_pTreeView->getListBox().Select( pCommand ); + } + + if ( bSuccess ) + { + m_pTreeView->getListBox().MakeVisible(pCommand); + m_pTreeView->getListBox().SetCursor(pCommand); + } + } + else if (!pCommandType) + { + if ( m_pCurrentlyDisplayed ) + { // tell the old entry (if any) it has been deselected + selectPath(m_pCurrentlyDisplayed, sal_False); + m_pCurrentlyDisplayed = NULL; + } + + // we have a command and need to display this in the rowset + return implLoadAnything(_rDataSourceName, _rCommand, _nCommandType, _bEscapeProcessing, _rxConnection); + } + } + return sal_False; +} + +//------------------------------------------------------------------------------ +IMPL_LINK(SbaTableQueryBrowser, OnSelectionChange, void*, /*NOINTERESTEDIN*/) +{ + return implSelect( m_pTreeView->getListBox().FirstSelected() ) ? 1L : 0L; +} +//------------------------------------------------------------------------------ +SvLBoxEntry* SbaTableQueryBrowser::implGetConnectionEntry(SvLBoxEntry* _pEntry) const +{ + SvLBoxEntry* pCurrentEntry = _pEntry; + DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() ); + while(pEntryData->eType != etDatasource ) + { + pCurrentEntry = m_pTreeModel->GetParent(pCurrentEntry); + pEntryData = static_cast< DBTreeListUserData* >( pCurrentEntry->GetUserData() ); + } + return pCurrentEntry; +} +//------------------------------------------------------------------------------ +bool SbaTableQueryBrowser::implSelect( SvLBoxEntry* _pEntry ) +{ + if ( !_pEntry ) + return false; + + DBTreeListUserData* pEntryData = static_cast< DBTreeListUserData* >( _pEntry->GetUserData() ); + switch (pEntryData->eType) + { + case etTableOrView: + case etQuery: + break; + default: + // nothing to do + return false; + } + + OSL_ENSURE(m_pTreeModel->HasParent(_pEntry), "SbaTableQueryBrowser::implSelect: invalid entry (1)!"); + OSL_ENSURE(m_pTreeModel->HasParent(m_pTreeModel->GetParent(_pEntry)), "SbaTableQueryBrowser::implSelect: invalid entry (2)!"); + + // get the entry for the tables or queries + SvLBoxEntry* pContainer = m_pTreeModel->GetParent(_pEntry); + DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); + + // get the entry for the datasource + SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer); + DBTreeListUserData* pConData = static_cast<DBTreeListUserData*>(pConnection->GetUserData()); + + // reinitialize the rowset + // but first check if it is necessary + // get all old properties + Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); + ::rtl::OUString aOldName; + xRowSetProps->getPropertyValue(PROPERTY_COMMAND) >>= aOldName; + sal_Int32 nOldType = 0; + xRowSetProps->getPropertyValue(PROPERTY_COMMAND_TYPE) >>= nOldType; + Reference<XConnection> xOldConnection(xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION),UNO_QUERY); + + // the name of the table or query + SvLBoxString* pString = (SvLBoxString*)_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); + OSL_ENSURE(pString,"There must be a string item!"); + const ::rtl::OUString sSimpleName = pString->GetText(); + ::rtl::OUStringBuffer sNameBuffer(sSimpleName); + if ( etQueryContainer == pContainerData->eType ) + { + SvLBoxEntry* pTemp = pContainer; + while( m_pTreeModel->GetParent(pTemp) != pConnection ) + { + sNameBuffer.insert(0,sal_Unicode('/')); + pString = (SvLBoxString*)pTemp->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING); + OSL_ENSURE(pString,"There must be a string item!"); + sNameBuffer.insert(0,pString->GetText()); + pTemp = m_pTreeModel->GetParent(pTemp); + } + } + ::rtl::OUString aName = sNameBuffer.makeStringAndClear(); + + sal_Int32 nCommandType = ( etTableContainer == pContainerData->eType) + ? CommandType::TABLE + : CommandType::QUERY; + + // check if need to rebuild the rowset + sal_Bool bRebuild = ( xOldConnection != pConData->xConnection ) + || ( nOldType != nCommandType ) + || ( aName != aOldName ); + + Reference< ::com::sun::star::form::XLoadable > xLoadable = getLoadable(); + bRebuild |= !xLoadable->isLoaded(); + bool bSuccess = true; + if ( bRebuild ) + { + try + { + WaitObject aWaitCursor(getBrowserView()); + + // tell the old entry it has been deselected + selectPath(m_pCurrentlyDisplayed, sal_False); + m_pCurrentlyDisplayed = NULL; + + // not really loaded + m_pCurrentlyDisplayed = _pEntry; + // tell the new entry it has been selected + selectPath(m_pCurrentlyDisplayed, sal_True); + + // get the name of the data source currently selected + ensureConnection( m_pCurrentlyDisplayed, pConData->xConnection ); + + if ( !pConData->xConnection.is() ) + { + unloadAndCleanup( sal_False ); + return false; + } + + Reference<XNameAccess> xNameAccess; + switch(nCommandType) + { + case CommandType::TABLE: + { + // only for tables + if ( !pContainerData->xContainer.is() ) + { + Reference<XTablesSupplier> xSup( pConData->xConnection, UNO_QUERY ); + if(xSup.is()) + xNameAccess = xSup->getTables(); + + pContainerData->xContainer = xNameAccess; + } + else + xNameAccess.set( pContainerData->xContainer, UNO_QUERY ); + } + break; + case CommandType::QUERY: + { + if ( pContainerData->xContainer.is() ) + xNameAccess.set( pContainerData->xContainer, UNO_QUERY ); + else + { + Reference<XQueriesSupplier> xSup( pConData->xConnection, UNO_QUERY ); + if(xSup.is()) + xNameAccess = xSup->getQueries(); + } + } + break; + } + String sStatus(ModuleRes( CommandType::TABLE == nCommandType ? STR_LOADING_TABLE : STR_LOADING_QUERY )); + sStatus.SearchAndReplaceAscii("$name$", aName); + BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sStatus); + + if(xNameAccess.is() && xNameAccess->hasByName(sSimpleName)) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(_pEntry->GetUserData()); + if ( !pData->xObjectProperties.is() ) + { + Reference<XInterface> xObject; + if(xNameAccess->getByName(sSimpleName) >>= xObject) // remember the table or query object + { + pData->xObjectProperties = pData->xObjectProperties.query( xObject ); + // if the query contains a parameterized statement and preview is enabled we won't get any data. + if ( m_bPreview && nCommandType == CommandType::QUERY && xObject.is() ) + { + ::rtl::OUString sSql; + Reference<XPropertySet> xObjectProps(xObject,UNO_QUERY); + xObjectProps->getPropertyValue(PROPERTY_COMMAND) >>= sSql; + Reference< XMultiServiceFactory > xFactory( pConData->xConnection, UNO_QUERY ); + if (xFactory.is()) + { + try + { + Reference<XSingleSelectQueryAnalyzer> xAnalyzer(xFactory->createInstance(SERVICE_NAME_SINGLESELECTQUERYCOMPOSER),UNO_QUERY); + if ( xAnalyzer.is() ) + { + xAnalyzer->setQuery(sSql); + Reference<XParametersSupplier> xParSup(xAnalyzer,UNO_QUERY); + if ( xParSup->getParameters()->getCount() > 0 ) + { + String sFilter = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" WHERE ")); + sFilter = sFilter + xAnalyzer->getFilter(); + String sReplace(sSql); + sReplace.SearchAndReplace(sFilter,String()); + xAnalyzer->setQuery(sReplace); + Reference<XSingleSelectQueryComposer> xComposer(xAnalyzer,UNO_QUERY); + xComposer->setFilter(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0=1"))); + aName = xAnalyzer->getQuery(); + nCommandType = CommandType::COMMAND; + } + } + } + catch (Exception&) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + } + } + } + } + + String sDataSourceName( getDataSourceAcessor( pConnection ) ); + bSuccess = implLoadAnything( sDataSourceName, aName, nCommandType, sal_True, pConData->xConnection ); + if ( !bSuccess ) + { // clean up + criticalFail(); + } + } + catch(const SQLException& e) + { + showError(SQLExceptionInfo(e)); + // reset the values + xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); + xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); + } + catch(WrappedTargetException& e) + { + SQLException aSql; + if(e.TargetException >>= aSql) + showError(SQLExceptionInfo(aSql)); + else + OSL_ENSURE(sal_False, "SbaTableQueryBrowser::implSelect: something strange happended!"); + // reset the values + xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); + xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); + } + catch(Exception&) + { + // reset the values + xRowSetProps->setPropertyValue(PROPERTY_DATASOURCENAME,Any()); + xRowSetProps->setPropertyValue(PROPERTY_ACTIVE_CONNECTION,Any()); + } + } + return bSuccess; +} + +// ----------------------------------------------------------------------------- +SvLBoxEntry* SbaTableQueryBrowser::getEntryFromContainer(const Reference<XNameAccess>& _rxNameAccess) +{ + DBTreeListBox& rListBox = m_pTreeView->getListBox(); + SvLBoxEntry* pContainer = NULL; + SvLBoxEntry* pDSLoop = rListBox.FirstChild(NULL); + while (pDSLoop) + { + pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_QUERIES); + DBTreeListUserData* pQueriesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); + if ( pQueriesData && pQueriesData->xContainer == _rxNameAccess ) + break; + + pContainer = rListBox.GetEntry(pDSLoop, CONTAINER_TABLES); + DBTreeListUserData* pTablesData = static_cast<DBTreeListUserData*>(pContainer->GetUserData()); + if ( pTablesData && pTablesData->xContainer == _rxNameAccess ) + break; + + pDSLoop = rListBox.NextSibling(pDSLoop); + pContainer = NULL; + } + return pContainer; +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaTableQueryBrowser::elementInserted( const ContainerEvent& _rEvent ) throw(RuntimeException) +{ + vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); + // first search for a definition container where we can insert this element + + SvLBoxEntry* pEntry = getEntryFromContainer(xNames); + if(pEntry) // found one + { + // insert the new entry into the tree + DBTreeListUserData* pContainerData = static_cast<DBTreeListUserData*>(pEntry->GetUserData()); + OSL_ENSURE(pContainerData, "elementInserted: There must be user data for this type!"); + + DBTreeListUserData* pNewData = new DBTreeListUserData; + sal_Bool bIsTable = etTableContainer == pContainerData->eType; + if ( bIsTable ) + { + _rEvent.Element >>= pNewData->xObjectProperties;// remember the new element + pNewData->eType = etTableOrView; + } + else + { + if ((sal_Int32)m_pTreeView->getListBox().GetChildCount(pEntry) < ( xNames->getElementNames().getLength() - 1 ) ) + { + // the item inserts its children on demand, but it has not been expanded yet. So ensure here and + // now that it has all items + populateTree(xNames, pEntry, etQuery ); + } + pNewData->eType = etQuery; + } + implAppendEntry( pEntry, ::comphelper::getString( _rEvent.Accessor ), pNewData, pNewData->eType ); + } + else + SbaXDataBrowserController::elementInserted(_rEvent); +} +// ------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::isCurrentlyDisplayedChanged(const String& _sName,SvLBoxEntry* _pContainer) +{ + return m_pCurrentlyDisplayed + && getEntryType(m_pCurrentlyDisplayed) == getChildType(_pContainer) + && m_pTreeView->getListBox().GetParent(m_pCurrentlyDisplayed) == _pContainer + && m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed) == _sName; +} +// ------------------------------------------------------------------------- +void SAL_CALL SbaTableQueryBrowser::elementRemoved( const ContainerEvent& _rEvent ) throw(RuntimeException) +{ + ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); + + Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); + // get the top-level representing the removed data source + // and search for the queries and tables + SvLBoxEntry* pContainer = getEntryFromContainer(xNames); + if ( pContainer ) + { // a query or table has been removed + String aName = ::comphelper::getString(_rEvent.Accessor).getStr(); + + if ( isCurrentlyDisplayedChanged( aName, pContainer) ) + { // the element displayed currently has been replaced + + // we need to remember the old value + SvLBoxEntry* pTemp = m_pCurrentlyDisplayed; + + // unload + unloadAndCleanup( sal_False ); // don't dispose the connection + + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData()); + pTemp->SetUserData(NULL); + delete pData; + // the data could be null because we have a table which isn't correct + m_pTreeModel->Remove(pTemp); + } + else + { + // remove the entry from the model + SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer); + while(pChild) + { + if (m_pTreeView->getListBox().GetEntryText(pChild) == aName) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData()); + pChild->SetUserData(NULL); + delete pData; + m_pTreeModel->Remove(pChild); + break; + } + pChild = m_pTreeModel->NextSibling(pChild); + } + } + + // maybe the object which is part of the document data source has been removed + checkDocumentDataSource(); + } + else + SbaXDataBrowserController::elementRemoved(_rEvent); +} + +// ------------------------------------------------------------------------- +void SAL_CALL SbaTableQueryBrowser::elementReplaced( const ContainerEvent& _rEvent ) throw(RuntimeException) +{ + ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); + + Reference< XNameAccess > xNames(_rEvent.Source, UNO_QUERY); + SvLBoxEntry* pContainer = getEntryFromContainer(xNames); + if ( pContainer ) + { // a table or query as been replaced + String aName = ::comphelper::getString(_rEvent.Accessor).getStr(); + + if ( isCurrentlyDisplayedChanged( aName, pContainer) ) + { // the element displayed currently has been replaced + + // we need to remember the old value + SvLBoxEntry* pTemp = m_pCurrentlyDisplayed; + unloadAndCleanup( sal_False ); // don't dispose the connection + + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pTemp->GetUserData()); + if (pData) + { + if ( etTableOrView == pData->eType ) + { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query + _rEvent.Element >>= pData->xObjectProperties; // remember the new element + } + else + { + pTemp->SetUserData(NULL); + delete pData; + } + } + } + else + { + // find the entry for this name + SvLBoxEntry* pChild = m_pTreeModel->FirstChild(pContainer); + while(pChild) + { + if (m_pTreeView->getListBox().GetEntryText(pChild) == aName) + { + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pChild->GetUserData()); + if (pData) + { + if ( etTableOrView == pData->eType ) + { // only insert userdata when we have a table because the query is only a commanddefinition object and not a query + _rEvent.Element >>= pData->xObjectProperties; // remember the new element + } + else + { + pChild->SetUserData(NULL); + delete pData; + } + } + break; + } + pChild = m_pTreeModel->NextSibling(pChild); + } + } + + // maybe the object which is part of the document data source has been removed + checkDocumentDataSource(); + } + else if (xNames.get() == m_xDatabaseContext.get()) + { // a datasource has been replaced in the context + DBG_ERROR("SbaTableQueryBrowser::elementReplaced: no support for replaced data sources!"); + // very suspicious: the database context should not allow to replace data source, only to register + // and revoke them + } + else + SbaXDataBrowserController::elementReplaced(_rEvent); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::impl_releaseConnection( SharedConnection& _rxConnection ) +{ + // remove as event listener + Reference< XComponent > xComponent( _rxConnection, UNO_QUERY ); + if ( xComponent.is() ) + { + Reference< XEventListener > xListener( static_cast< ::cppu::OWeakObject* >( this ), UNO_QUERY ); + xComponent->removeEventListener( xListener ); + } + + try + { + // temporary (hopefully!) hack for #i55274# + Reference< XFlushable > xFlush( _rxConnection, UNO_QUERY ); + if ( xFlush.is() ) + xFlush->flush(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + // clear + _rxConnection.clear(); + // will implicitly dispose if we have the ownership, since xConnection is a SharedConnection +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::disposeConnection( SvLBoxEntry* _pDSEntry ) +{ + DBG_ASSERT( _pDSEntry, "SbaTableQueryBrowser::disposeConnection: invalid entry (NULL)!" ); + DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::disposeConnection: invalid entry (not top-level)!" ); + + if ( _pDSEntry ) + { + DBTreeListUserData* pTreeListData = static_cast< DBTreeListUserData* >( _pDSEntry->GetUserData() ); + if ( pTreeListData ) + impl_releaseConnection( pTreeListData->xConnection ); + } +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::closeConnection(SvLBoxEntry* _pDSEntry,sal_Bool _bDisposeConnection) +{ + DBG_ASSERT(_pDSEntry, "SbaTableQueryBrowser::closeConnection: invalid entry (NULL)!"); + DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::closeConnection: invalid entry (not top-level)!"); + + // if one of the entries of the given DS is displayed currently, unload the form + if (m_pCurrentlyDisplayed && (m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed) == _pDSEntry)) + unloadAndCleanup(_bDisposeConnection); + + // collapse the query/table container + for (SvLBoxEntry* pContainers = m_pTreeModel->FirstChild(_pDSEntry); pContainers; pContainers= m_pTreeModel->NextSibling(pContainers)) + { + SvLBoxEntry* pElements = m_pTreeModel->FirstChild(pContainers); + if ( pElements ) + m_pTreeView->getListBox().Collapse(pContainers); + m_pTreeView->getListBox().EnableExpandHandler(pContainers); + // and delete their children (they are connection-relative) + for (; pElements; ) + { + SvLBoxEntry* pRemove = pElements; + pElements= m_pTreeModel->NextSibling(pElements); + DBTreeListUserData* pData = static_cast<DBTreeListUserData*>(pRemove->GetUserData()); + pRemove->SetUserData(NULL); + delete pData; + m_pTreeModel->Remove(pRemove); + } + } + // collapse the entry itself + m_pTreeView->getListBox().Collapse(_pDSEntry); + + // dispose/reset the connection + if ( _bDisposeConnection ) + disposeConnection( _pDSEntry ); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::unloadAndCleanup( sal_Bool _bDisposeConnection ) +{ + if (!m_pCurrentlyDisplayed) + // nothing to do + return; + + SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(m_pCurrentlyDisplayed); + + // de-select the path for the currently displayed table/query + if (m_pCurrentlyDisplayed) + { + selectPath(m_pCurrentlyDisplayed, sal_False); + } + m_pCurrentlyDisplayed = NULL; + + try + { + // get the active connection. We need to dispose it. + Reference< XPropertySet > xRowSetProps(getRowSet(),UNO_QUERY); + Reference< XConnection > xConn; + xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION) >>= xConn; +#if OSL_DEBUG_LEVEL > 1 + { + Reference< XComponent > xComp; + ::cppu::extractInterface(xComp, xRowSetProps->getPropertyValue(PROPERTY_ACTIVE_CONNECTION)); + } +#endif + + // unload the form + Reference< XLoadable > xLoadable = getLoadable(); + if (xLoadable->isLoaded()) + xLoadable->unload(); + + // clear the grid control + Reference< XNameContainer > xConta(getControlModel(),UNO_QUERY); + clearGridColumns(xConta); + + // dispose the connection + if(_bDisposeConnection) + disposeConnection( pDSEntry ); + } + catch(SQLException& e) + { + showError(SQLExceptionInfo(e)); + } + catch(WrappedTargetException& e) + { + SQLException aSql; + if(e.TargetException >>= aSql) + showError(SQLExceptionInfo(aSql)); + else + OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: something strange happended!"); + } + catch(Exception&) + { + OSL_ENSURE(sal_False, "SbaTableQueryBrowser::unloadAndCleanup: could not reset the form"); + } +} + +// ------------------------------------------------------------------------- +namespace +{ + Reference< XInterface > lcl_getDataSource( const Reference< XNameAccess >& _rxDatabaseContext, + const ::rtl::OUString& _rDataSourceName, const Reference< XConnection >& _rxConnection ) + { + Reference< XDataSource > xDataSource; + try + { + if ( _rDataSourceName.getLength() && _rxDatabaseContext->hasByName( _rDataSourceName ) ) + xDataSource.set( _rxDatabaseContext->getByName( _rDataSourceName ), UNO_QUERY_THROW ); + + if ( !xDataSource.is() ) + { + Reference< XChild > xConnAsChild( _rxConnection, UNO_QUERY ); + if ( xConnAsChild.is() ) + xDataSource.set( xConnAsChild->getParent(), UNO_QUERY_THROW ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return xDataSource.get(); + } +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::impl_initialize() +{ + ::vos::OGuard aGuard(Application::GetSolarMutex()); + // doin' a lot of VCL stuff here -> lock the SolarMutex + + // first initialize the parent + SbaXDataBrowserController::impl_initialize(); + + Reference<XConnection> xForeignConnection; + Reference< XFrame > xFrame; + + ::rtl::OUString aTableName, aCatalogName, aSchemaName; + + sal_Bool bEsacpeProcessing = sal_True; + sal_Int32 nInitialDisplayCommandType = CommandType::COMMAND; + ::rtl::OUString sInitialDataSourceName; + ::rtl::OUString sInitialCommand; + + const NamedValueCollection& rArguments( getInitParams() ); + + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_DATASOURCENAME, sInitialDataSourceName ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND_TYPE, nInitialDisplayCommandType ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_COMMAND, sInitialCommand ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, xForeignConnection ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_CATALOGNAME, aCatalogName ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_SCHEMANAME, aSchemaName ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_UPDATE_TABLENAME, aTableName ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_ESCAPE_PROCESSING, bEsacpeProcessing ); + rArguments.get_ensureType( "Frame", xFrame ); + rArguments.get_ensureType( (::rtl::OUString)PROPERTY_SHOWMENU, m_bShowMenu ); + + // disable the browser if either of ShowTreeViewButton (compatibility name) or EnableBrowser + // is present and set to FALSE + sal_Bool bDisableBrowser = ( sal_False == rArguments.getOrDefault( "ShowTreeViewButton", sal_True ) ) // compatibility name + || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_ENABLE_BROWSER, sal_True ) ); + OSL_ENSURE( !rArguments.has( "ShowTreeViewButton" ), + "SbaTableQueryBrowser::impl_initialize: ShowTreeViewButton is superseded by EnableBrowser!" ); + m_bEnableBrowser = !bDisableBrowser; + + // hide the tree view it is disabled in general, or if the settings tell to hide it initially + sal_Bool bHideTreeView = ( !m_bEnableBrowser ) + || ( sal_False == rArguments.getOrDefault( "ShowTreeView", sal_True ) ) // compatibility name + || ( sal_False == rArguments.getOrDefault( (::rtl::OUString)PROPERTY_SHOW_BROWSER, sal_True ) ); + OSL_ENSURE( !rArguments.has( "ShowTreeView" ), + "SbaTableQueryBrowser::impl_initialize: ShowTreeView is superseded by ShowBrowser!" ); + + if ( bHideTreeView ) + hideExplorer(); + else + showExplorer(); + + if ( m_bPreview ) + { + try + { + Sequence< ::rtl::OUString> aProperties(5); + Sequence< Any> aValues(5); + + ::rtl::OUString* pStringIter = aProperties.getArray(); + Any* pValueIter = aValues.getArray(); + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AlwaysShowCursor")); + *pValueIter++ <<= sal_False; + *pStringIter++ = PROPERTY_BORDER; + *pValueIter++ <<= sal_Int16(0); + + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasNavigationBar")); + *pValueIter++ <<= sal_False; + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("HasRecordMarker")); + *pValueIter++ <<= sal_False; + + *pStringIter++ = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Tabstop")); + *pValueIter++ <<= sal_False; + + Reference< XMultiPropertySet > xFormMultiSet(getFormComponent(), UNO_QUERY); + if ( xFormMultiSet.is() ) + xFormMultiSet->setPropertyValues(aProperties, aValues); + } + catch(Exception) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + // are we loaded into a (sub)frame of an embedded document (i.e. a form belonging to a database + // document)? + sal_Bool bSubFrameOfEmbeddedDocument = sal_False; + if ( xFrame.is() ) + { + Reference<XFramesSupplier> xSup = xFrame->getCreator(); + Reference<XController> xCont = xSup.is() ? xSup->getController() : Reference<XController>(); + + bSubFrameOfEmbeddedDocument = xCont.is() && ::dbtools::isEmbeddedInDatabase( xCont->getModel(), xForeignConnection ); + } + + // if we have a connection at this point, it was either passed from outside, our + // determined from a outer DB document. In both cases, do not dispose it later on. + SharedConnection xConnection( xForeignConnection, SharedConnection::NoTakeOwnership ); + + // should we display all registered databases in the left hand side tree? + // or only *one* special? + sal_Bool bLimitedTreeEntries = sal_False; + // if we're part of a frame which is a secondary frame of a database document, then only + // display the database for this document, not all registered ones + bLimitedTreeEntries |= bSubFrameOfEmbeddedDocument; + // if the tree view is not to be displayed at all, then only display the data source + // which was given as initial selection + bLimitedTreeEntries |= ( m_bEnableBrowser != sal_True ); + + if ( bLimitedTreeEntries ) + { + if ( xConnection.is() ) + { + startConnectionListening( xConnection ); + + // if no initial name was given, try to obtain one from the data source + if ( !sInitialDataSourceName.getLength() ) + { + Reference< XChild > xChild( xConnection, UNO_QUERY ); + Reference< XPropertySet > xDataSourceProperties; + if ( xChild.is() ) + xDataSourceProperties = xDataSourceProperties.query( xChild->getParent() ); + if ( xDataSourceProperties.is() ) + { + try + { + OSL_VERIFY( xDataSourceProperties->getPropertyValue( PROPERTY_NAME ) >>= sInitialDataSourceName ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "SbaTableQueryBrowser::impl_initialize: a connection parent which does not have a 'Name'!??" ); + } + } + } + } + + implAddDatasource( sInitialDataSourceName, xConnection ); + m_pTreeView->getListBox().Expand( m_pTreeView->getListBox().First() ); + } + else + initializeTreeModel(); + + if ( m_bEnableBrowser ) + { + m_aDocScriptSupport = ::boost::optional< bool >( false ); + } + else + { + // we are not used as "browser", but as mere view for a single table/query/command. In particular, + // there is a specific database document which we belong to. + Reference< XOfficeDatabaseDocument > xDocument( getDataSourceOrModel( + lcl_getDataSource( m_xDatabaseContext, sInitialDataSourceName, xConnection ) ), UNO_QUERY ); + m_aDocScriptSupport = ::boost::optional< bool >( Reference< XEmbeddedScripts >( xDocument, UNO_QUERY ).is() ); + } + + if ( implSelect( sInitialDataSourceName, sInitialCommand, nInitialDisplayCommandType, bEsacpeProcessing, xConnection, sal_True ) ) + { + try + { + Reference< XPropertySet > xRowSetProps(getRowSet(), UNO_QUERY); + xRowSetProps->setPropertyValue(PROPERTY_UPDATE_CATALOGNAME,makeAny(aCatalogName)); + xRowSetProps->setPropertyValue(PROPERTY_UPDATE_SCHEMANAME,makeAny(aSchemaName)); + xRowSetProps->setPropertyValue(PROPERTY_UPDATE_TABLENAME,makeAny(aTableName)); + + } + catch(const Exception&) + { + OSL_ENSURE(sal_False, "SbaTableQueryBrowser::impl_initialize: could not set the update related names!"); + } + } + + InvalidateAll(); +} + +// ------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::haveExplorer() const +{ + return m_pTreeView && m_pTreeView->IsVisible(); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::hideExplorer() +{ + if (!haveExplorer()) + return; + if (!getBrowserView()) + return; + + m_pTreeView->Hide(); + m_pSplitter->Hide(); + getBrowserView()->Resize(); + + InvalidateFeature(ID_BROWSER_EXPLORER); +} + +// ------------------------------------------------------------------------- +void SbaTableQueryBrowser::showExplorer() +{ + if (haveExplorer()) + return; + + if (!getBrowserView()) + return; + + m_pTreeView->Show(); + m_pSplitter->Show(); + getBrowserView()->Resize(); + + InvalidateFeature(ID_BROWSER_EXPLORER); +} + +// ----------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::ensureConnection(SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection) +{ + SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent(_pAnyEntry); + DBTreeListUserData* pDSData = + pDSEntry + ? static_cast<DBTreeListUserData*>(pDSEntry->GetUserData()) + : NULL; + + return ensureConnection( pDSEntry, pDSData, _rConnection ); +} + +// ----------------------------------------------------------------------------- +::std::auto_ptr< ImageProvider > SbaTableQueryBrowser::getImageProviderFor( SvLBoxEntry* _pAnyEntry ) +{ + ::std::auto_ptr< ImageProvider > pImageProvider( new ImageProvider ); + SharedConnection xConnection; + if ( getExistentConnectionFor( _pAnyEntry, xConnection ) ) + pImageProvider.reset( new ImageProvider( xConnection ) ); + return pImageProvider; +} + +// ----------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::getExistentConnectionFor( SvLBoxEntry* _pAnyEntry, SharedConnection& _rConnection ) +{ + SvLBoxEntry* pDSEntry = m_pTreeView->getListBox().GetRootLevelParent( _pAnyEntry ); + DBTreeListUserData* pDSData = + pDSEntry + ? static_cast< DBTreeListUserData* >( pDSEntry->GetUserData() ) + : NULL; + if ( pDSData ) + _rConnection = pDSData->xConnection; + return _rConnection.is(); +} + +#ifdef DBG_UTIL +// ----------------------------------------------------------------------------- +bool SbaTableQueryBrowser::impl_isDataSourceEntry( SvLBoxEntry* _pEntry ) const +{ + return m_pTreeModel->GetRootLevelParent( _pEntry ) == _pEntry; +} +#endif + +// ----------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::ensureConnection( SvLBoxEntry* _pDSEntry, void* pDSData, SharedConnection& _rConnection ) +{ + DBG_ASSERT( impl_isDataSourceEntry( _pDSEntry ), "SbaTableQueryBrowser::ensureConnection: this entry does not denote a data source!" ); + if(_pDSEntry) + { + DBTreeListUserData* pTreeListData = static_cast<DBTreeListUserData*>(pDSData); + ::rtl::OUString aDSName = GetEntryText(_pDSEntry); + + if ( pTreeListData ) + _rConnection = pTreeListData->xConnection; + + if ( !_rConnection.is() && pTreeListData ) + { + // show the "connecting to ..." status + String sConnecting(ModuleRes(STR_CONNECTING_DATASOURCE)); + sConnecting.SearchAndReplaceAscii("$name$", aDSName); + BrowserViewStatusDisplay aShowStatus(static_cast<UnoDataBrowserView*>(getView()), sConnecting); + + // build a string showing context information in case of error + String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) ); + sConnectingContext.SearchAndReplaceAscii("$name$", aDSName); + + // connect + _rConnection.reset( + connect( getDataSourceAcessor( _pDSEntry ), sConnectingContext, NULL ), + SharedConnection::TakeOwnership + ); + + // remember the connection + pTreeListData->xConnection = _rConnection; + } + } + + return _rConnection.is(); +} + +// ----------------------------------------------------------------------------- +IMPL_LINK( SbaTableQueryBrowser, OnTreeEntryCompare, const SvSortData*, _pSortData ) +{ + SvLBoxEntry* pLHS = static_cast<SvLBoxEntry*>(_pSortData->pLeft); + SvLBoxEntry* pRHS = static_cast<SvLBoxEntry*>(_pSortData->pRight); + DBG_ASSERT(pLHS && pRHS, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid tree entries!"); + // we want the table entry and the end so we have to do a check + + if (isContainer(pRHS)) + { + // don't use getEntryType (directly or indirecly) for the LHS: + // LHS is currently beeing inserted, so it is not "completely valid" at the moment + + const EntryType eRight = getEntryType(pRHS); + if (etTableContainer == eRight) + // every other container should be placed _before_ the bookmark container + return -1; + + const String sLeft = m_pTreeView->getListBox().GetEntryText(pLHS); + + EntryType eLeft = etTableContainer; + if (String(ModuleRes(RID_STR_TABLES_CONTAINER)) == sLeft) + eLeft = etTableContainer; + else if (String(ModuleRes(RID_STR_QUERIES_CONTAINER)) == sLeft) + eLeft = etQueryContainer; + + if ( eLeft == eRight ) + return COMPARE_EQUAL; + + if ( ( eLeft == etTableContainer ) && ( eRight == etQueryContainer ) ) + return COMPARE_GREATER; + + if ( ( eLeft == etQueryContainer ) && ( eRight == etTableContainer ) ) + return COMPARE_LESS; + + OSL_ENSURE( false, "SbaTableQueryBrowser::OnTreeEntryCompare: unexpected case!" ); + return COMPARE_EQUAL; + } + + SvLBoxString* pLeftTextItem = static_cast<SvLBoxString*>(pLHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); + SvLBoxString* pRightTextItem = static_cast<SvLBoxString*>(pRHS->GetFirstItem(SV_ITEM_ID_LBOXSTRING)); + DBG_ASSERT(pLeftTextItem && pRightTextItem, "SbaTableQueryBrowser::OnTreeEntryCompare: invalid text items!"); + + String sLeftText = pLeftTextItem->GetText(); + String sRightText = pRightTextItem->GetText(); + + sal_Int32 nCompareResult = 0; // equal by default + + if (m_xCollator.is()) + { + try + { + nCompareResult = m_xCollator->compareString(sLeftText, sRightText); + } + catch(Exception&) + { + } + } + else + // default behaviour if we do not have a collator -> do the simple string compare + nCompareResult = sLeftText.CompareTo(sRightText); + + return nCompareResult; +} + +// ----------------------------------------------------------------------------- +void SbaTableQueryBrowser::implAdministrate( SvLBoxEntry* _pApplyTo ) +{ + OSL_PRECOND( _pApplyTo, "SbaTableQueryBrowser::implAdministrate: illegal entry!" ); + if ( !_pApplyTo ) + return; + + try + { + // get the desktop object + sal_Int32 nFrameSearchFlag = FrameSearchFlag::ALL | FrameSearchFlag::GLOBAL ; + Reference< XComponentLoader > xFrameLoader(getORB()->createInstance(SERVICE_FRAME_DESKTOP),UNO_QUERY); + + if ( xFrameLoader.is() ) + { + // the initial selection + SvLBoxEntry* pTopLevelSelected = _pApplyTo; + while (pTopLevelSelected && m_pTreeView->getListBox().GetParent(pTopLevelSelected)) + pTopLevelSelected = m_pTreeView->getListBox().GetParent(pTopLevelSelected); + ::rtl::OUString sInitialSelection; + if (pTopLevelSelected) + sInitialSelection = getDataSourceAcessor( pTopLevelSelected ); + + Reference< XDataSource > xDataSource( getDataSourceByName( sInitialSelection, getView(), getORB(), NULL ) ); + Reference< XModel > xDocumentModel( getDataSourceOrModel( xDataSource ), UNO_QUERY ); + + if ( xDocumentModel.is() ) + { + Reference< XInteractionHandler > xInteractionHandler( + getORB()->createInstance( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), + UNO_QUERY ); + OSL_ENSURE( xInteractionHandler.is(), "SbaTableQueryBrowser::implAdministrate: no interaction handler available!" ); + + ::comphelper::NamedValueCollection aLoadArgs; + aLoadArgs.put( "Model", xDocumentModel ); + aLoadArgs.put( "InteractionHandler", xInteractionHandler ); + aLoadArgs.put( "MacroExecutionMode", MacroExecMode::USE_CONFIG ); + + Sequence< PropertyValue > aLoadArgPV; + aLoadArgs >>= aLoadArgPV; + + xFrameLoader->loadComponentFromURL( + xDocumentModel->getURL(), + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_default")), + nFrameSearchFlag, + aLoadArgPV + ); + } + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} + +// ----------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::requestQuickHelp( const SvLBoxEntry* _pEntry, String& _rText ) const +{ + const DBTreeListUserData* pData = static_cast< const DBTreeListUserData* >( _pEntry->GetUserData() ); + if ( ( pData->eType == etDatasource ) && pData->sAccessor.Len() ) + { + _rText = ::svt::OFileNotation( pData->sAccessor ).get( ::svt::OFileNotation::N_SYSTEM ); + return sal_True; + } + return sal_False; +} + +// ----------------------------------------------------------------------------- +PopupMenu* SbaTableQueryBrowser::getContextMenu( Control& _rControl ) const +{ + OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl, + "SbaTableQueryBrowser::getContextMenu: where does this come from?" ); + if ( &m_pTreeView->getListBox() != &_rControl ) + return NULL; + + return new PopupMenu( ModuleRes( MENU_BROWSER_DEFAULTCONTEXT ) ); +} + +// ----------------------------------------------------------------------------- +IController& SbaTableQueryBrowser::getCommandController() +{ + return *this; +} + +// ----------------------------------------------------------------------------- +::cppu::OInterfaceContainerHelper* SbaTableQueryBrowser::getContextMenuInterceptors() +{ + return &m_aContextMenuInterceptors; +} + +// ----------------------------------------------------------------------------- +Any SbaTableQueryBrowser::getCurrentSelection( Control& _rControl ) const +{ + OSL_PRECOND( &m_pTreeView->getListBox() == &_rControl, + "SbaTableQueryBrowser::getCurrentSelection: where does this come from?" ); + + if ( &m_pTreeView->getListBox() != &_rControl ) + return Any(); + + SvLBoxEntry* pSelected = m_pTreeView->getListBox().FirstSelected(); + if ( !pSelected ) + return Any(); + + OSL_ENSURE( m_pTreeView->getListBox().NextSelected( pSelected ) == NULL, + "SbaTableQueryBrowser::getCurrentSelection: single-selection is expected here!" ); + + NamedDatabaseObject aSelectedObject; + DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pSelected->GetUserData() ); + aSelectedObject.Type = static_cast< sal_Int32 >( pData->eType ); + + switch ( aSelectedObject.Type ) + { + case DatabaseObject::QUERY: + case DatabaseObject::TABLE: + aSelectedObject.Name = m_pTreeView->getListBox().GetEntryText( pSelected ); + break; + + case DatabaseObjectContainer::DATA_SOURCE: + case DatabaseObjectContainer::QUERIES: + case DatabaseObjectContainer::TABLES: + aSelectedObject.Name = getDataSourceAcessor( pSelected ); + break; + + default: + OSL_ENSURE( false, "SbaTableQueryBrowser::getCurrentSelection: invalid (unexpected) object type!" ); + break; + } + + return makeAny( aSelectedObject ); +} + +// ----------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::implGetQuerySignature( ::rtl::OUString& _rCommand, sal_Bool& _bEscapeProcessing ) +{ + _rCommand = ::rtl::OUString(); + _bEscapeProcessing = sal_False; + + try + { + // ontain the dss (data source signature) of the form + ::rtl::OUString sDataSourceName; + ::rtl::OUString sCommand; + sal_Int32 nCommandType = CommandType::COMMAND; + Reference< XPropertySet > xRowsetProps( getRowSet(), UNO_QUERY ); + ODataAccessDescriptor aDesc( xRowsetProps ); + sDataSourceName = aDesc.getDataSource(); + aDesc[ daCommand ] >>= sCommand; + aDesc[ daCommandType ] >>= nCommandType; + + // do we need to do anything? + if ( CommandType::QUERY != nCommandType ) + return sal_False; + + // get the query object + Reference< XQueryDefinitionsSupplier > xSuppQueries; + Reference< XNameAccess > xQueries; + Reference< XPropertySet > xQuery; + m_xDatabaseContext->getByName( sDataSourceName ) >>= xSuppQueries; + if ( xSuppQueries.is() ) + xQueries = xSuppQueries->getQueryDefinitions(); + if ( xQueries.is() ) + xQueries->getByName( sCommand ) >>= xQuery; + OSL_ENSURE( xQuery.is(), "SbaTableQueryBrowser::implGetQuerySignature: could not retrieve the query object!" ); + + // get the two properties we need + if ( xQuery.is() ) + { + xQuery->getPropertyValue( PROPERTY_COMMAND ) >>= _rCommand; + _bEscapeProcessing = ::cppu::any2bool( xQuery->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) ); + return sal_True; + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + return sal_False; +} +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::frameAction(const ::com::sun::star::frame::FrameActionEvent& aEvent) throw( RuntimeException ) +{ + if (aEvent.Frame == m_xCurrentFrameParent) + { + if(aEvent.Action == FrameAction_COMPONENT_DETACHING) + implRemoveStatusListeners(); + else if (aEvent.Action == FrameAction_COMPONENT_REATTACHED) + connectExternalDispatches(); + } + else + SbaXDataBrowserController::frameAction(aEvent); + +} +// ----------------------------------------------------------------------------- +void SbaTableQueryBrowser::clearGridColumns(const Reference< XNameContainer >& _xColContainer) +{ + // first we have to clear the grid + Sequence< ::rtl::OUString > aNames = _xColContainer->getElementNames(); + const ::rtl::OUString* pIter = aNames.getConstArray(); + const ::rtl::OUString* pEnd = pIter + aNames.getLength(); + Reference< XInterface > xColumn; + for (; pIter != pEnd;++pIter) + { + _xColContainer->getByName(*pIter) >>= xColumn; + _xColContainer->removeByName(*pIter); + ::comphelper::disposeComponent(xColumn); + } +} +// ----------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::isHiContrast() const +{ + sal_Bool bRet = sal_False; + if ( m_pTreeView ) + bRet = m_pTreeView->getListBox().GetSettings().GetStyleSettings().GetHighContrastMode(); + return bRet; +} +// ----------------------------------------------------------------------------- +void SbaTableQueryBrowser::loadMenu(const Reference< XFrame >& _xFrame) +{ + if ( m_bShowMenu ) + { + OGenericUnoController::loadMenu(_xFrame); + } + else if ( !m_bPreview ) + { + Reference< ::com::sun::star::frame::XLayoutManager > xLayoutManager = getLayoutManager(_xFrame); + + if ( xLayoutManager.is() ) + { + xLayoutManager->lock(); + xLayoutManager->createElement( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/toolbar" ))); + xLayoutManager->unlock(); + xLayoutManager->doLayout(); + } + onLoadedMenu( xLayoutManager ); + } +} +// ----------------------------------------------------------------------------- +::rtl::OUString SbaTableQueryBrowser::getPrivateTitle() const +{ + ::rtl::OUString sTitle; + if ( m_pCurrentlyDisplayed ) + { + SvLBoxEntry* pContainer = m_pTreeModel->GetParent(m_pCurrentlyDisplayed); + // get the entry for the datasource + SvLBoxEntry* pConnection = implGetConnectionEntry(pContainer); + ::rtl::OUString sName = m_pTreeView->getListBox().GetEntryText(m_pCurrentlyDisplayed); + sTitle = GetEntryText( pConnection ); + INetURLObject aURL(sTitle); + if ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) + sTitle = aURL.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DECODE_WITH_CHARSET); + if ( sName.getLength() ) + { + sName += ::rtl::OUString::createFromAscii(" - "); + sName += sTitle; + sTitle = sName; + } + } + + return sTitle; +} +// ----------------------------------------------------------------------------- +sal_Bool SbaTableQueryBrowser::preReloadForm() +{ + sal_Bool bIni = sal_False; + if ( !m_pCurrentlyDisplayed ) + { + // switch the grid to design mode while loading + getBrowserView()->getGridControl()->setDesignMode(sal_True); + // we had an invalid statement so we need to connect the column models + Reference<XPropertySet> xRowSetProps(getRowSet(),UNO_QUERY); + ::svx::ODataAccessDescriptor aDesc(xRowSetProps); + // extract the props + ::rtl::OUString sDataSource; + ::rtl::OUString sCommand; + sal_Int32 nCommandType = CommandType::COMMAND; + sal_Bool bEscapeProcessing = sal_True; + extractDescriptorProps(aDesc, sDataSource, sCommand, nCommandType, bEscapeProcessing); + if ( sDataSource.getLength() && sCommand.getLength() && (-1 != nCommandType) ) + { + SvLBoxEntry* pDataSource = NULL; + SvLBoxEntry* pCommandType = NULL; + m_pCurrentlyDisplayed = getObjectEntry( sDataSource, sCommand, nCommandType, &pDataSource, &pCommandType, sal_True, SharedConnection() ); + bIni = sal_True; + } + } + return bIni; +} + +// ----------------------------------------------------------------------------- +void SbaTableQueryBrowser::postReloadForm() +{ + InitializeGridModel(getFormComponent()); + LoadFinished(sal_True); + //updateTitle(); +} + +//------------------------------------------------------------------------------ +Reference< XEmbeddedScripts > SAL_CALL SbaTableQueryBrowser::getScriptContainer() throw (RuntimeException) +{ + // update our database document + Reference< XModel > xDocument; + try + { + Reference< XPropertySet > xCursorProps( getRowSet(), UNO_QUERY_THROW ); + Reference< XConnection > xConnection( xCursorProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ), UNO_QUERY ); + if ( xConnection.is() ) + { + Reference< XChild > xChild( xConnection, UNO_QUERY_THROW ); + Reference< XDocumentDataSource > xDataSource( xChild->getParent(), UNO_QUERY_THROW ); + xDocument.set( xDataSource->getDatabaseDocument(), UNO_QUERY_THROW ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + Reference< XEmbeddedScripts > xScripts( xDocument, UNO_QUERY ); + OSL_ENSURE( xScripts.is() || !xDocument.is(), + "SbaTableQueryBrowser::getScriptContainer: invalid database document!" ); + return xScripts; +} + +//------------------------------------------------------------------------------ +void SAL_CALL SbaTableQueryBrowser::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) +{ + if ( _Interceptor.is() ) + m_aContextMenuInterceptors.addInterface( _Interceptor ); +} + +//------------------------------------------------------------------------------ +void SAL_CALL SbaTableQueryBrowser::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) +{ + if ( _Interceptor.is() ) + m_aContextMenuInterceptors.removeInterface( _Interceptor ); +} + +//------------------------------------------------------------------------------ +void SAL_CALL SbaTableQueryBrowser::registeredDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + implAddDatasource( _Event.Name, SharedConnection() ); +} + +//------------------------------------------------------------------------------ +void SbaTableQueryBrowser::impl_cleanupDataSourceEntry( const String& _rDataSourceName ) +{ + // get the top-level representing the removed data source + SvLBoxEntry* pDataSourceEntry = m_pTreeView->getListBox().FirstChild( NULL ); + while ( pDataSourceEntry ) + { + if ( m_pTreeView->getListBox().GetEntryText( pDataSourceEntry ) == _rDataSourceName ) + break; + + pDataSourceEntry = m_pTreeView->getListBox().NextSibling( pDataSourceEntry ); + } + + OSL_ENSURE( pDataSourceEntry, "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: do not know this data source!" ); + if ( !pDataSourceEntry ) + return; + + if ( isSelected( pDataSourceEntry ) ) + { // a table or query belonging to the deleted data source is currently beeing displayed. + OSL_ENSURE( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) == pDataSourceEntry, + "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (1)!" ); + unloadAndCleanup( sal_True ); + } + else + OSL_ENSURE( + ( NULL == m_pCurrentlyDisplayed ) + || ( m_pTreeView->getListBox().GetRootLevelParent( m_pCurrentlyDisplayed ) != pDataSourceEntry ), + "SbaTableQueryBrowser::impl_cleanupDataSourceEntry: inconsistence (2)!"); + + // delete any user data of the child entries of the to-be-removed entry + SvTreeEntryList* pList = m_pTreeModel->GetChildList( pDataSourceEntry ); + if ( pList ) + { + SvLBoxEntry* pEntryLoop = static_cast<SvLBoxEntry*>( pList->First() ); + while ( pEntryLoop ) + { + DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pEntryLoop->GetUserData() ); + pEntryLoop->SetUserData( NULL ); + delete pData; + pEntryLoop = static_cast< SvLBoxEntry* >( pList->Next() ); + } + } + + // remove the entry + DBTreeListUserData* pData = static_cast< DBTreeListUserData* >( pDataSourceEntry->GetUserData() ); + pDataSourceEntry->SetUserData( NULL ); + delete pData; + m_pTreeModel->Remove( pDataSourceEntry ); +} + +//------------------------------------------------------------------------------ +void SAL_CALL SbaTableQueryBrowser::revokedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + impl_cleanupDataSourceEntry( _Event.Name ); + + // maybe the object which is part of the document data source has been removed + checkDocumentDataSource(); +} + +//------------------------------------------------------------------------------ +void SAL_CALL SbaTableQueryBrowser::changedDatabaseLocation( const DatabaseRegistrationEvent& _Event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + // in case the data source was expanded, and connected, we need to clean it up + // for simplicity, just do as if the data source were completely removed and re-added + impl_cleanupDataSourceEntry( _Event.Name ); + implAddDatasource( _Event.Name, SharedConnection() ); +} + + +// ......................................................................... +} // namespace dbaui +// ......................................................................... + + |