/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_forms.hxx"

#include "formoperations.hxx"
#include "frm_strings.hxx"
#include "frm_resource.hxx"
#include "frm_resource.hrc"
#include "frm_module.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
#include <com/sun/star/util/XModifyBroadcaster.hpp>
#include <com/sun/star/form/runtime/FormFeature.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/awt/XControl.hpp>
#include <com/sun/star/form/XGrid.hpp>
#include <com/sun/star/form/XBoundControl.hpp>
#include <com/sun/star/form/XBoundComponent.hpp>
#include <com/sun/star/sdbcx/XRowLocate.hpp>
#include <com/sun/star/form/XConfirmDeleteListener.hpp>
#include <com/sun/star/sdb/RowChangeEvent.hpp>
#include <com/sun/star/sdb/RowChangeAction.hpp>
#include <com/sun/star/sdb/SQLFilterOperator.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/form/XReset.hpp>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/util/XRefreshable.hpp>
/** === end UNO includes === **/

#include <connectivity/dbtools.hxx>
#include <connectivity/dbexception.hxx>
#include <vcl/svapp.hxx>
#include <vcl/stdtext.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/waitobj.hxx>
#include <tools/diagnose_ex.h>
#include <comphelper/container.hxx>
#include <comphelper/property.hxx>
#include <comphelper/namedvaluecollection.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <vos/mutex.hxx>

//--------------------------------------------------------------------------
extern "C" void SAL_CALL createRegistryInfo_FormOperations()
{
	static ::frm::OMultiInstanceAutoRegistration< ::frm::FormOperations > aAutoRegistration;
}

//........................................................................
namespace frm
{
//........................................................................

    using ::dbtools::SQLExceptionInfo;
	/** === begin UNO using === **/
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::uno::XComponentContext;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::uno::Sequence;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::XInterface;
    using ::com::sun::star::sdbc::XRowSet;
    using ::com::sun::star::sdbc::XResultSetUpdate;
    using ::com::sun::star::form::runtime::XFormController;
    using ::com::sun::star::form::runtime::XFeatureInvalidation;
    using ::com::sun::star::form::runtime::FeatureState;
    using ::com::sun::star::lang::IllegalArgumentException;
    using ::com::sun::star::sdbc::SQLException;
    using namespace ::com::sun::star::sdbc;
    using ::com::sun::star::form::XForm;
    using ::com::sun::star::ucb::AlreadyInitializedException;
    using ::com::sun::star::util::XModifyBroadcaster;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::lang::EventObject;
    using ::com::sun::star::beans::PropertyChangeEvent;
    using ::com::sun::star::lang::XMultiServiceFactory;
    using ::com::sun::star::lang::DisposedException;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::awt::XControl;
    using ::com::sun::star::form::XGrid;
    using ::com::sun::star::container::XIndexAccess;
    using ::com::sun::star::uno::UNO_QUERY_THROW;
    using ::com::sun::star::form::XBoundControl;
    using ::com::sun::star::form::XBoundComponent;
    using ::com::sun::star::sdbcx::XRowLocate;
    using ::com::sun::star::form::XConfirmDeleteListener;
    using ::com::sun::star::sdb::RowChangeEvent;
    using namespace ::com::sun::star::sdb;
    using ::com::sun::star::form::XReset;
    using ::com::sun::star::beans::XMultiPropertySet;
    using ::com::sun::star::uno::makeAny;
    using ::com::sun::star::lang::WrappedTargetException;
    using ::com::sun::star::beans::PropertyValue;
    using ::com::sun::star::ui::dialogs::XExecutableDialog;
    using ::com::sun::star::beans::NamedValue;

    using ::com::sun::star::util::XRefreshable;
    using ::com::sun::star::awt::XControlModel;
	/** === end UNO using === **/
    namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
    namespace RowChangeAction = ::com::sun::star::sdb::RowChangeAction;

	//====================================================================
	//= FormOperations
	//====================================================================
	//--------------------------------------------------------------------
    FormOperations::FormOperations( const Reference< XMultiServiceFactory >& _rxContext )
        :FormOperations_Base( m_aMutex )
        ,m_aContext( _rxContext )
        ,m_bInitializedParser( false )
        ,m_bActiveControlModified( false )
        ,m_bConstructed( false )
    #ifdef DBG_UTIL
        ,m_nMethodNestingLevel( false )
    #endif
    {
    }

	//--------------------------------------------------------------------
    FormOperations::~FormOperations()
    {
    }

    //--------------------------------------------------------------------
    ::rtl::OUString FormOperations::getImplementationName_Static(  ) throw(RuntimeException)
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.forms.FormOperations" ) );
    }
    
    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > FormOperations::getSupportedServiceNames_Static(  ) throw(RuntimeException)
    {
        Sequence< ::rtl::OUString > aNames(1);
        aNames[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.runtime.FormOperations" ) );
        return aNames;
    }
    
    //--------------------------------------------------------------------
    Reference< XInterface > SAL_CALL FormOperations::Create(const Reference< XMultiServiceFactory >& _rxFactory )
    {
        return *new FormOperations( _rxFactory );
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException)
    {
        if ( m_bConstructed )
            throw AlreadyInitializedException();

        if ( _arguments.getLength() == 1 )
        {
            Reference< XFormController > xController;
            Reference< XForm > xForm;
            if ( _arguments[0] >>= xController )
                createWithFormController( xController );
            else if ( _arguments[0] >>= xForm )
                createWithForm( xForm );
            else
                throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
            return;
        }

        throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
    }
    
    //--------------------------------------------------------------------
    ::rtl::OUString SAL_CALL FormOperations::getImplementationName(  ) throw (RuntimeException)
    {
        return getImplementationName_Static();
    }
    
    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL FormOperations::supportsService( const ::rtl::OUString& _ServiceName ) throw (RuntimeException)
    {
        Sequence< ::rtl::OUString > aSupportedServiceNames( getSupportedServiceNames() );
        const ::rtl::OUString* pBegin = aSupportedServiceNames.getConstArray();
        const ::rtl::OUString* pEnd = aSupportedServiceNames.getConstArray() + aSupportedServiceNames.getLength();
        return ::std::find( pBegin, pEnd, _ServiceName ) != pEnd;
    }
    
    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL FormOperations::getSupportedServiceNames(  ) throw (RuntimeException)
    {
        return getSupportedServiceNames_Static();
    }

    //--------------------------------------------------------------------
    Reference< XRowSet > SAL_CALL FormOperations::getCursor() throw (RuntimeException)
    {
        MethodGuard aGuard( *this );
        return m_xCursor;
    }
    
    //--------------------------------------------------------------------
    Reference< XResultSetUpdate > SAL_CALL FormOperations::getUpdateCursor() throw (RuntimeException)
    {
        MethodGuard aGuard( *this );
        return m_xUpdateCursor;
    }
    
    //--------------------------------------------------------------------
    Reference< XFormController > SAL_CALL FormOperations::getController() throw (RuntimeException)
    {
        MethodGuard aGuard( *this );
        return m_xController;
    }
    
    //--------------------------------------------------------------------
    Reference< XFeatureInvalidation > SAL_CALL FormOperations::getFeatureInvalidation() throw (RuntimeException)
    {
        MethodGuard aGuard( *this );
        return m_xFeatureInvalidation;
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::setFeatureInvalidation( const Reference< XFeatureInvalidation > & _rxFeatureInvalidation ) throw (RuntimeException)
    {
        MethodGuard aGuard( *this );
        m_xFeatureInvalidation = _rxFeatureInvalidation;
    }
    
    //--------------------------------------------------------------------
    FeatureState SAL_CALL FormOperations::getState( ::sal_Int16 _nFeature ) throw (RuntimeException)
    {
        MethodGuard aGuard( *this );

        FeatureState aState;
        aState.Enabled = sal_False;

        try
        {
            // some checks for basic pre-requisites
            if	(	!m_xLoadableForm.is()
                ||  !m_xLoadableForm->isLoaded()
		        ||	!m_xCursorProperties.is()
		        )
            {
                return aState;
            }

            switch ( _nFeature )
            {
            case FormFeature::MoveToFirst:
            case FormFeature::MoveToPrevious:
                aState.Enabled = impl_canMoveLeft_throw( );
                break;

			case FormFeature::MoveToNext:
				aState.Enabled = impl_canMoveRight_throw();
                break;

            case FormFeature::MoveToLast:
				aState.Enabled = impl_getRowCount_throw() && ( !m_xCursor->isLast() || impl_isInsertionRow_throw() );
                break;

            case FormFeature::DeleteRecord:
				// already deleted ?
				if ( m_xCursor->rowDeleted() )
                    aState.Enabled = sal_False;
                else
				{
					// allowed to delete the row ?
                    aState.Enabled = !impl_isInsertionRow_throw() && ::dbtools::canDelete( m_xCursorProperties );
				}
                break;

            case FormFeature::MoveToInsertRow:
				// if we are inserting we can move to the next row if the current record or control is modified
				aState.Enabled =    impl_isInsertionRow_throw()
                                ?   impl_isModifiedRow_throw() || m_bActiveControlModified
                                :   ::dbtools::canInsert( m_xCursorProperties );
                break;

            case FormFeature::ReloadForm:
            {
                // there must be an active connection
                Reference< XRowSet > xCursorRowSet( m_xCursor, UNO_QUERY );
                aState.Enabled = ::dbtools::getConnection( xCursorRowSet ).is();

                // and an active command
                ::rtl::OUString sActiveCommand;
                m_xCursorProperties->getPropertyValue( PROPERTY_ACTIVECOMMAND ) >>= sActiveCommand;
                aState.Enabled &= sActiveCommand.getLength() > 0;
            }
            break;

            case FormFeature::RefreshCurrentControl:
            {
                Reference< XRefreshable > xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY );
                aState.Enabled = xControlModelRefresh.is();
            }
            break;

			case FormFeature::SaveRecordChanges:
			case FormFeature::UndoRecordChanges:
				aState.Enabled = impl_isModifiedRow_throw() || m_bActiveControlModified;
                break;

			case FormFeature::RemoveFilterAndSort:
				if ( impl_isParseable_throw() && impl_hasFilterOrOrder_throw() )
                    aState.Enabled = !impl_isInsertOnlyForm_throw();
				break;

            case FormFeature::SortAscending:
			case FormFeature::SortDescending:
			case FormFeature::AutoFilter:
				if ( m_xController.is() && impl_isParseable_throw() )
				{
					sal_Bool bIsDeleted = m_xCursor->rowDeleted();

					if ( !bIsDeleted && !impl_isInsertOnlyForm_throw() )
					{
						Reference< XPropertySet > xBoundField = impl_getCurrentBoundField_nothrow( );
						if ( xBoundField.is() )
                            xBoundField->getPropertyValue( PROPERTY_SEARCHABLE ) >>= aState.Enabled;
					}
				}
                break;

			case FormFeature::InteractiveSort:
            case FormFeature::InteractiveFilter:
				if ( impl_isParseable_throw() )
                    aState.Enabled = !impl_isInsertOnlyForm_throw();
                break;

			case FormFeature::ToggleApplyFilter:
			{
				::rtl::OUString sFilter;
                m_xCursorProperties->getPropertyValue( PROPERTY_FILTER ) >>= sFilter;
				if ( sFilter.getLength() )
				{
                    aState.State = m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER );
                    aState.Enabled = !impl_isInsertOnlyForm_throw();
				}
                else
                    aState.State <<= (sal_Bool)sal_False;
			}
            break;

			case FormFeature::MoveAbsolute:
			{
				sal_Int32 nPosition   = m_xCursor->getRow();
				sal_Bool  bIsNew      = impl_isInsertionRow_throw();
                sal_Int32 nCount      = impl_getRowCount_throw();
				sal_Bool  bFinalCount = impl_isRowCountFinal_throw();

                if ( ( nPosition >= 0 ) || bIsNew )
				{
					if ( bFinalCount )
					{
                        // special case: there are no records at all, and we
                        // can't insert records -> disabled
						if ( !nCount && !::dbtools::canInsert( m_xCursorProperties ) )
						{
							aState.Enabled = sal_False;
						}
						else
						{
							if ( bIsNew )
								nPosition = ++nCount;
                            aState.State <<= (sal_Int32)nPosition;
							aState.Enabled = sal_True;
						}
					}
					else
					{
                        aState.State <<= (sal_Int32)nPosition;
						aState.Enabled = sal_True;
					}
				}
			}
            break;

			case FormFeature::TotalRecords:
			{
				sal_Bool  bIsNew      = impl_isInsertionRow_throw();
                sal_Int32 nCount      = impl_getRowCount_throw();
				sal_Bool  bFinalCount = impl_isRowCountFinal_throw();

				if ( bIsNew )
					++nCount;

                ::rtl::OUString sValue = ::rtl::OUString::valueOf( sal_Int32( nCount ) );
				if ( !bFinalCount )
                    sValue += ::rtl::OUString::createFromAscii( " *" );

                aState.State <<= sValue;
                aState.Enabled = sal_True;
			}
            break;

            default:
                OSL_ENSURE( sal_False, "FormOperations::getState: unknown feature id!" );
                break;
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormOperations::getState: caught an exception!" );
        }

        return aState;
    }
    
    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL FormOperations::isEnabled( ::sal_Int16 _nFeature ) throw (RuntimeException)
    {
        MethodGuard aGuard( *this );

        FeatureState aState( getState( _nFeature ) );
        return aState.Enabled;
    }
    
    //--------------------------------------------------------------------
    namespace
    {
        static bool lcl_needConfirmCommit( sal_Int32 _nFeature )
        {
            return ( ( _nFeature == FormFeature::ReloadForm )
                  || ( _nFeature == FormFeature::RemoveFilterAndSort )
                  || ( _nFeature == FormFeature::ToggleApplyFilter )
                  || ( _nFeature == FormFeature::SortAscending )
                  || ( _nFeature == FormFeature::SortDescending )
                  || ( _nFeature == FormFeature::AutoFilter )
                  || ( _nFeature == FormFeature::InteractiveSort )
                  || ( _nFeature == FormFeature::InteractiveFilter )
                   );
        }
        static bool lcl_requiresArguments( sal_Int32 _nFeature )
        {
            return ( _nFeature == FormFeature::MoveAbsolute );
        }
        static bool lcl_isExecutableFeature( sal_Int32 _nFeature )
        {
            return ( _nFeature != FormFeature::TotalRecords );
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::execute( ::sal_Int16 _nFeature ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException)
    {
        ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
        MethodGuard aGuard( *this );

        if ( ( _nFeature != FormFeature::DeleteRecord ) && ( _nFeature != FormFeature::UndoRecordChanges ) )
        {
            // if we have a controller, commit the current control
            if ( m_xController.is() )
                if ( !impl_commitCurrentControl_throw() )
                    return;

            // commit the current record
            bool bCommitCurrentRecord = true;
            // (but before, let the user confirm if necessary)
            if ( impl_isModifiedRow_throw() )
            {
                if ( lcl_needConfirmCommit( _nFeature ) )
                {
                    // TODO: shouldn't this be done with an interaction handler?
				    QueryBox aQuery( NULL, WB_YES_NO_CANCEL | WB_DEF_YES, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW ) );
                    switch ( aQuery.Execute() )
                    {
                    case RET_NO: bCommitCurrentRecord = false; break;
                    case RET_CANCEL: return;
                    }
                }
            }

            if ( bCommitCurrentRecord && !impl_commitCurrentRecord_throw() )
                return;
        }

        try
        {
            switch ( _nFeature )
            {
	        case FormFeature::MoveToFirst:
                m_xCursor->first();
		        break;

            case FormFeature::MoveToNext:
                impl_moveRight_throw( );
                break;

            case FormFeature::MoveToPrevious:
    		    impl_moveLeft_throw( );
		        break;

	        case FormFeature::MoveToLast:
	        {
/*
                // TODO: re-implement this .....
		        // run in an own thread if ...
		        // ... the data source is thread safe ...
		        sal_Bool bAllowOwnThread = sal_False;
                if ( ::comphelper::hasProperty( PROPERTY_THREADSAFE, m_xCursorProperties ) )
                    m_xCursorProperties->getPropertyValue( PROPERTY_THREADSAFE ) >>= bAllowOwnThread;

                // ... the record count is unknown
		        sal_Bool bNeedOwnThread sal_False;
                if ( ::comphelper::hasProperty( PROPERTY_ROWCOUNTFINAL, m_xCursorProperties ) )
                    m_xCursorProperties->getPropertyValue( PROPERTY_ROWCOUNTFINAL ) >>= bNeedOwnThread;

		        if ( bNeedOwnThread && bAllowOwnThread )
			        ;
		        else
*/
			        m_xCursor->last();
	        }
	        break;

	        case FormFeature::ReloadForm:
                if ( m_xLoadableForm.is() )
                {
    			    WaitObject aWO( NULL );
                    m_xLoadableForm->reload();

                    // refresh all controls in the form (and sub forms) which can be refreshed
                    // #i90914# / 2008-07-02 / frank.schoenheit@sun.com
                    ::comphelper::IndexAccessIterator aIter( m_xLoadableForm );
                    Reference< XInterface > xElement( aIter.Next() );
                    while ( xElement.is() )
                    {
                        Reference< XRefreshable > xRefresh( xElement, UNO_QUERY );
                        if ( xRefresh.is() )
                            xRefresh->refresh();
                        xElement = aIter.Next();
                    }
                }
	            break;

            case FormFeature::RefreshCurrentControl:
            {
                Reference< XRefreshable > xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY );
                OSL_ENSURE( xControlModelRefresh.is(), "FormOperations::execute: how did you reach this?" );
                if ( xControlModelRefresh.is() )
                    xControlModelRefresh->refresh();
            }
            break;

            case FormFeature::DeleteRecord:
	        {
                sal_uInt32 nCount = impl_getRowCount_throw();

		        // next position
		        sal_Bool bLeft = m_xCursor->isLast() && ( nCount > 1 );
		        sal_Bool bRight= !m_xCursor->isLast();
		        sal_Bool bSuccess = sal_False;
		        try
		        {
			        // ask for confirmation
                    Reference< XConfirmDeleteListener > xConfirmDelete( m_xController, UNO_QUERY );

                    if ( xConfirmDelete.is() )
			        {
				        RowChangeEvent aEvent;
				        aEvent.Source = Reference< XInterface >( m_xCursor, UNO_QUERY );
				        aEvent.Action = RowChangeAction::DELETE;
				        aEvent.Rows = 1;
				        bSuccess = xConfirmDelete->confirmDelete( aEvent );
			        }

			        // delete it
			        if ( bSuccess )
				        m_xUpdateCursor->deleteRow();
		        }
		        catch( const Exception& )
		        {
			        bSuccess = sal_False;
		        }

		        if ( bSuccess )
		        {
			        if ( bLeft || bRight )
				        m_xCursor->relative( bRight ? 1 : -1 );
			        else
			        {
				        sal_Bool bCanInsert = ::dbtools::canInsert( m_xCursorProperties );
				        // is it possible to insert another record?
					    if ( bCanInsert )
						    m_xUpdateCursor->moveToInsertRow();
					    else
						    // move record to update stati
						    m_xCursor->first();
			        }
		        }
            }
            break;

	        case FormFeature::SaveRecordChanges:
            case FormFeature::UndoRecordChanges:
            {
			    sal_Bool bInserting = impl_isInsertionRow_throw();

                if ( FormFeature::UndoRecordChanges == _nFeature )
                {
    			    if ( !bInserting )
	    			    m_xUpdateCursor->cancelRowUpdates();

                    // reset all controls for this form
                    impl_resetAllControls_nothrow( );

			        if ( bInserting )   // back to insertion mode for this form
				        m_xUpdateCursor->moveToInsertRow();
                }
                else
                {
			        if  ( bInserting )
                    {
				        m_xUpdateCursor->insertRow();
                        m_xCursor->last();
                    }
			        else
				        m_xUpdateCursor->updateRow();
                }
            }
            break;

            case FormFeature::MoveToInsertRow:
		        // move to the last row before moving to the insert row
		        // 21.01.2002 - 96480 - fs@openoffice.org
                m_xCursor->last();
		        m_xUpdateCursor->moveToInsertRow();
    	        break;

            case FormFeature::RemoveFilterAndSort:
            {
				// simultaneously reset Filter and Order property
                Reference< XMultiPropertySet > xProperties( m_xCursorProperties, UNO_QUERY );
                OSL_ENSURE( xProperties.is(), "FormOperations::execute: no multi property access!" );
				if ( xProperties.is() )
				{
					Sequence< ::rtl::OUString > aNames( 2 );
                    aNames[0] = PROPERTY_FILTER;
                    aNames[1] = PROPERTY_SORT;

					Sequence< Any> aValues( 2 );
                    aValues[0] <<= ::rtl::OUString();
                    aValues[1] <<= ::rtl::OUString();

					WaitObject aWO( NULL );
					xProperties->setPropertyValues( aNames, aValues );

                    if ( m_xLoadableForm.is() )
					    m_xLoadableForm->reload();
				}
            }
            break;

            case FormFeature::ToggleApplyFilter:
                if ( impl_commitCurrentControl_throw() && impl_commitCurrentRecord_throw() )
			    {
                    // simply toggle the value
				    sal_Bool bApplied = sal_False;
                    m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER ) >>= bApplied;
				    m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( (sal_Bool)!bApplied ) );

                    // and reload
				    WaitObject aWO( NULL );
				    m_xLoadableForm->reload();
			    }
                break;

            case FormFeature::SortAscending:
                impl_executeAutoSort_throw( true );
                break;

            case FormFeature::SortDescending:
                impl_executeAutoSort_throw( false );
                break;

            case FormFeature::AutoFilter:
                impl_executeAutoFilter_throw();
                break;

            case FormFeature::InteractiveSort:
                impl_executeFilterOrSort_throw( false );
		        break;

            case FormFeature::InteractiveFilter:
                impl_executeFilterOrSort_throw( true );
                break;

            default:
            {
                sal_uInt16 nErrorResourceId = RID_STR_FEATURE_UNKNOWN;
                if ( lcl_requiresArguments( _nFeature ) )
                    nErrorResourceId = RID_STR_FEATURE_REQUIRES_PARAMETERS;
                else if ( !lcl_isExecutableFeature( _nFeature ) )
                    nErrorResourceId = RID_STR_FEATURE_NOT_EXECUTABLE;
                throw IllegalArgumentException( FRM_RES_STRING( nErrorResourceId ), *this, 1 );
            }
            }   // switch
        }
        catch( const RuntimeException& ) { throw; }
        catch( const SQLException& ) { throw; }
        catch( const IllegalArgumentException& ) { throw; }
        catch( const Exception& )
        {
            throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
        }

        impl_invalidateAllSupportedFeatures_nothrow( aGuard );
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::executeWithArguments( ::sal_Int16 _nFeature, const Sequence< NamedValue >& _rArguments ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException)
    {
        if ( !lcl_requiresArguments( _nFeature ) )
        {
            execute( _nFeature );
            return;
        }

        ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
        MethodGuard aGuard( *this );

        // at the moment we have only one feature which supports execution parameters
        if ( !lcl_isExecutableFeature( _nFeature ) )
            throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_NOT_EXECUTABLE ), *this, 1 );

        switch ( _nFeature )
        {
        case FormFeature::MoveAbsolute:
        {
            sal_Int32 nPosition = -1;

            ::comphelper::NamedValueCollection aArguments( _rArguments );
            aArguments.get_ensureType( "Position", nPosition );

            if ( nPosition < 1 )
                nPosition = 1;

            try
            {
                // commit before doing anything else
                if ( m_xController.is() && !impl_commitCurrentControl_throw() )
                    return;
			    if ( !impl_commitCurrentRecord_throw() )
                    return;

                sal_Int32 nCount      = impl_getRowCount_throw();
				sal_Bool  bFinalCount = impl_isRowCountFinal_throw();

				if ( bFinalCount && ( (sal_Int32)nPosition > nCount ) )
					nPosition = nCount;

                m_xCursor->absolute( nPosition );
            }
            catch( const RuntimeException& ) { throw; }
            catch( const SQLException& ) { throw; }
            catch( const Exception& )
            {
                throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
            }
        }
        break;
        default:
            throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_UNKNOWN ), *this, 1 );
        }   // switch
    }

    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL FormOperations::commitCurrentRecord( ::sal_Bool& _out_rRecordInserted ) throw (RuntimeException, SQLException)
    {
        MethodGuard aGuard( *this );
        _out_rRecordInserted = sal_False;

        return impl_commitCurrentRecord_throw( &_out_rRecordInserted );
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_commitCurrentRecord_throw( ::sal_Bool* _pRecordInserted ) const
    {
        DBG_ASSERT( m_nMethodNestingLevel, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );

        if ( !impl_hasCursor_nothrow() )
		    return false;

        // nothing to do if the record is not modified
	    sal_Bool bResult = !impl_isModifiedRow_throw();
	    if ( !bResult )
	    {
            // insert respectively update the row
            if ( impl_isInsertionRow_throw() )
            {
				m_xUpdateCursor->insertRow();
                if ( _pRecordInserted )
                    *_pRecordInserted = sal_True;
            }
			else
				m_xUpdateCursor->updateRow();
			bResult = true;
	    }
	    return bResult;
    }
    
    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL FormOperations::commitCurrentControl() throw (RuntimeException, SQLException)
    {
        MethodGuard aGuard( *this );
        return impl_commitCurrentControl_throw();
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_commitCurrentControl_throw() const
    {
        DBG_ASSERT( m_nMethodNestingLevel, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
        OSL_PRECOND( m_xController.is(), "FormOperations::commitCurrentControl: no controller!" );
        if ( !m_xController.is() )
            return false;

	    bool bSuccess = false;
        try
        {
            Reference< XControl > xCurrentControl( m_xController->getCurrentControl() );

            // check whether the control is locked
            Reference< XBoundControl > xCheckLock( xCurrentControl, UNO_QUERY );
	        sal_Bool bControlIsLocked = xCheckLock.is() && xCheckLock->getLock();

            // commit if necessary
            bSuccess = true;
	        if ( xCurrentControl.is() && !bControlIsLocked )
	        {
		        // both the control and it's model can be committable, so try both
		        Reference< XBoundComponent > xBound( xCurrentControl, UNO_QUERY );
		        if ( !xBound.is() )
			        xBound = xBound.query( xCurrentControl->getModel() );
                // and now really commit
                if ( xBound.is() )
			        bSuccess = xBound->commit();
	        }

        }
        catch( const RuntimeException& ) { throw; }
        catch( const SQLException& ) { throw; }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
            bSuccess = false;
        }

	    return bSuccess;
    }

    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL FormOperations::isInsertionRow() throw (RuntimeException, WrappedTargetException)
    {
        sal_Bool bIs = sal_False;
        try
        {
            bIs = impl_isInsertionRow_throw();
        }
        catch( const RuntimeException& ) { throw; }
        catch( const Exception& )
        {
            throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
        }
        return bIs;
    }
    
    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL FormOperations::isModifiedRow() throw (RuntimeException, WrappedTargetException)
    {
        sal_Bool bIs = sal_False;
        try
        {
            bIs = impl_isModifiedRow_throw();
        }
        catch( const RuntimeException& ) { throw; }
        catch( const Exception& )
        {
            throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() );
        }
        return bIs;
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::cursorMoved( const EventObject& /*_Event*/ ) throw (RuntimeException)
    {
        MethodGuard aGuard( *this );
	    m_bActiveControlModified = sal_False;

        impl_invalidateAllSupportedFeatures_nothrow( aGuard );
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::rowChanged( const EventObject& /*_Event*/ ) throw (RuntimeException)
    {
        // not interested in
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::rowSetChanged( const EventObject& /*_Event*/ ) throw (RuntimeException)
    {
        // not interested in
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::modified( const EventObject& /*_Source*/ ) throw( RuntimeException )
    {
        MethodGuard aGuard( *this );

        OSL_ENSURE( m_xCursor.is(), "FormOperations::modified: already disposed!" );
	    if ( !m_bActiveControlModified )
	    {
		    m_bActiveControlModified = sal_True;
            impl_invalidateModifyDependentFeatures_nothrow( aGuard );
	    }
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
    {
        MethodGuard aGuard( *this );

        if ( m_xCursor.is() && ( m_xCursor == _rEvent.Source ) )
        {
            sal_Bool bIs = sal_False;
        	if  ( ( _rEvent.PropertyName == PROPERTY_ISMODIFIED )
               || ( _rEvent.PropertyName == PROPERTY_ISNEW )
                )
	        {
		        if ( ( _rEvent.NewValue >>= bIs ) && !bIs )
			        m_bActiveControlModified = sal_False;
	        }
            impl_invalidateAllSupportedFeatures_nothrow( aGuard );
        }

        if ( m_xParser.is() && ( m_xCursor == _rEvent.Source ) )
	    {
		    try
		    {
                ::rtl::OUString sNewValue;
                _rEvent.NewValue >>= sNewValue;
			    if ( _rEvent.PropertyName == PROPERTY_ACTIVECOMMAND )
                {
				    m_xParser->setElementaryQuery( sNewValue );
                }
			    else if ( _rEvent.PropertyName == PROPERTY_FILTER )
			    {
				    if ( m_xParser->getFilter() != sNewValue )
					    m_xParser->setFilter( sNewValue );
			    }
			    else if ( _rEvent.PropertyName == PROPERTY_SORT )
			    {
                    _rEvent.NewValue >>= sNewValue;
				    if ( m_xParser->getOrder() != sNewValue )
					    m_xParser->setOrder( sNewValue );
			    }
		    }
		    catch( Exception& )
		    {
			    OSL_ENSURE( sal_False, "FormOperations::propertyChange: caught an exception while updating the parser!" );
		    }
            impl_invalidateAllSupportedFeatures_nothrow( aGuard );
	    }
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::disposing( const EventObject& /*_Source*/ ) throw (RuntimeException)
    {
        // TODO: should we react on this? Or is this the responsibility of our owner to dispose us?
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL FormOperations::disposing()
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        impl_disposeParser_nothrow();

        try
        {
            // revoke various listeners
            if ( m_xCursor.is() )
                m_xCursor->removeRowSetListener( this );

		    if ( m_xCursorProperties.is() )
		    {
			    m_xCursorProperties->removePropertyChangeListener( PROPERTY_ISMODIFIED,this );
			    m_xCursorProperties->removePropertyChangeListener( PROPERTY_ISNEW, this );
		    }

            Reference< XModifyBroadcaster > xBroadcaster( m_xController, UNO_QUERY );
		    if ( xBroadcaster.is() )
			    xBroadcaster->removeModifyListener( this );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }

        m_xController.clear();
        m_xCursor.clear();
        m_xUpdateCursor.clear();
        m_xCursorProperties.clear();
        m_xLoadableForm.clear();
        m_xFeatureInvalidation.clear();

        m_bActiveControlModified = true;
    }

    //--------------------------------------------------------------------
    void FormOperations::impl_checkDisposed_throw() const
    {
        if ( impl_isDisposed_nothrow() )
            throw DisposedException( ::rtl::OUString(), *const_cast< FormOperations* >( this ) );
    }

    //--------------------------------------------------------------------
    void FormOperations::impl_initFromController_throw()
    {
        OSL_PRECOND( m_xController.is(), "FormOperations::impl_initFromController_throw: invalid controller!" );
        m_xCursor = m_xCursor.query( m_xController->getModel() );
        if ( !m_xCursor.is() )
            throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );

        impl_initFromForm_throw();

        Reference< XModifyBroadcaster > xBroadcaster( m_xController, UNO_QUERY );
		if ( xBroadcaster.is() )
			xBroadcaster->addModifyListener( this );
    }

    //--------------------------------------------------------------------
    void FormOperations::impl_initFromForm_throw()
    {
        OSL_PRECOND( m_xCursor.is(), "FormOperations::impl_initFromForm_throw: invalid form!" );
        m_xCursorProperties = m_xCursorProperties.query ( m_xCursor );
        m_xUpdateCursor     = m_xUpdateCursor.query     ( m_xCursor );
        m_xLoadableForm     = m_xLoadableForm.query     ( m_xCursor );

        if ( !m_xCursor.is() || !m_xCursorProperties.is() || !m_xLoadableForm.is() )
            throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );

        m_xCursor->addRowSetListener( this );
		m_xCursorProperties->addPropertyChangeListener( PROPERTY_ISMODIFIED,this );
		m_xCursorProperties->addPropertyChangeListener( PROPERTY_ISNEW, this );
    }

    //--------------------------------------------------------------------
    void FormOperations::createWithFormController( const Reference< XFormController >& _rxController )
    {
        m_xController = _rxController;
        if ( !m_xController.is() )
            throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );

        impl_initFromController_throw();

        m_bConstructed = true;
    }

    //--------------------------------------------------------------------
    void FormOperations::createWithForm( const Reference< XForm >& _rxForm )
    {
        m_xCursor = m_xCursor.query( _rxForm );
        if ( !m_xCursor.is() )
            throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );

        impl_initFromForm_throw();

        m_bConstructed = true;
    }

    //------------------------------------------------------------------------------
    void FormOperations::impl_invalidateAllSupportedFeatures_nothrow( MethodGuard& _rClearForCallback ) const
    {
        if ( !m_xFeatureInvalidation.is() )
            // nobody's interested in ...
            return;

        Reference< XFeatureInvalidation > xInvalidation = m_xFeatureInvalidation;
        _rClearForCallback.clear();
        xInvalidation->invalidateAllFeatures();
    }

    //------------------------------------------------------------------------------
    void FormOperations::impl_invalidateModifyDependentFeatures_nothrow( MethodGuard& _rClearForCallback ) const
    {
        if ( !m_xFeatureInvalidation.is() )
            // nobody's interested in ...
            return;

        static Sequence< sal_Int16 > s_aModifyDependentFeatures;
        if ( s_aModifyDependentFeatures.getLength() == 0 )
        {
            sal_Int16 pModifyDependentFeatures[] =
            {
	            FormFeature::MoveToNext,
	            FormFeature::MoveToInsertRow,
	            FormFeature::SaveRecordChanges,
	            FormFeature::UndoRecordChanges
            };
            size_t nFeatureCount = sizeof( pModifyDependentFeatures ) / sizeof( pModifyDependentFeatures[ 0 ] );
            s_aModifyDependentFeatures = Sequence< sal_Int16 >( pModifyDependentFeatures, nFeatureCount );
        }

        Reference< XFeatureInvalidation > xInvalidation = m_xFeatureInvalidation;
        _rClearForCallback.clear();

        xInvalidation->invalidateFeatures( s_aModifyDependentFeatures );
    }

    //--------------------------------------------------------------------
    void FormOperations::impl_ensureInitializedParser_nothrow()
    {
        OSL_PRECOND( m_xCursorProperties.is(), "FormOperations::impl_ensureInitializedParser_nothrow: we're disposed!" );
        if ( m_bInitializedParser )
            return;

        try
        {
            sal_Bool bUseEscapeProcessing = sal_False;
            m_xCursorProperties->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bUseEscapeProcessing;
            if ( bUseEscapeProcessing )
            {
                Reference< XMultiServiceFactory > xFactory( ::dbtools::getConnection( m_xCursor ), UNO_QUERY );
	            if ( xFactory.is() )
                {
		            m_xParser.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.SingleSelectQueryComposer" ) ) ), UNO_QUERY );
                    OSL_ENSURE( m_xParser.is(), "FormOperations::impl_ensureInitializedParser_nothrow: factory did not create a parser for us!" );
                }
            }

		    if ( m_xParser.is() )
		    {
			    if ( m_xLoadableForm.is() && m_xLoadableForm->isLoaded() )
			    {
				    ::rtl::OUString sStatement;
				    ::rtl::OUString sFilter;
				    ::rtl::OUString sSort;

                    m_xCursorProperties->getPropertyValue( PROPERTY_ACTIVECOMMAND   ) >>= sStatement;
				    m_xCursorProperties->getPropertyValue( PROPERTY_FILTER          ) >>= sFilter;
				    m_xCursorProperties->getPropertyValue( PROPERTY_SORT            ) >>= sSort;

					m_xParser->setElementaryQuery( sStatement );
					m_xParser->setFilter         ( sFilter    );
					m_xParser->setOrder          ( sSort      );
			    }

                // start listening at the order/sort properties at the form, so
                // we can keep our parser in sync
				m_xCursorProperties->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );
				m_xCursorProperties->addPropertyChangeListener( PROPERTY_FILTER, this );
				m_xCursorProperties->addPropertyChangeListener( PROPERTY_SORT, this );
		    }
        }
        catch( const Exception& )
        {
	        OSL_ENSURE( sal_False, "FormOperations::impl_ensureInitializedParser_nothrow: caught an exception!" );
        }

        m_bInitializedParser = true;
    }

    //--------------------------------------------------------------------
    void FormOperations::impl_disposeParser_nothrow()
    {
        try
        {
            // if we have a parser (and a cursor), then we're listening at the cursor's
            // properties to keep the parser in sync with the cursor
		    if ( m_xParser.is() && m_xCursorProperties.is() )
		    {
			    m_xCursorProperties->removePropertyChangeListener( PROPERTY_FILTER, this );
			    m_xCursorProperties->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );
			    m_xCursorProperties->removePropertyChangeListener( PROPERTY_SORT, this );
		    }

            Reference< XComponent > xParserComp( m_xParser, UNO_QUERY );
            if ( xParserComp.is() )
                xParserComp->dispose();
            m_xParser.clear();

            m_bInitializedParser = false;
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormOperations::impl_disposeParser_nothrow: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_canMoveLeft_throw( ) const
    {
        if ( !impl_hasCursor_nothrow() )
            return false;

        return impl_getRowCount_throw() && ( !m_xCursor->isFirst() || impl_isInsertionRow_throw() );
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_canMoveRight_throw( ) const
    {
        if ( !impl_hasCursor_nothrow() )
            return false;

        bool bIsNew = impl_isInsertionRow_throw();

        if ( impl_getRowCount_throw() && !m_xCursor->isLast() && !bIsNew )
            return true;

        if ( ::dbtools::canInsert( m_xCursorProperties ) )
            if ( !bIsNew || impl_isModifiedRow_throw() )
                return true;

        if ( bIsNew && m_bActiveControlModified )
            return true;

        return false;
    }

    //--------------------------------------------------------------------
    namespace
    {
        template < typename TYPE >
        TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const ::rtl::OUString& _rPropertyName, TYPE _Default )
        {
            TYPE value( _Default );
            OSL_PRECOND( _rxProperties.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
            if ( _rxProperties.is() )
                OSL_VERIFY( _rxProperties->getPropertyValue( _rPropertyName ) >>= value );
            return value;
        }
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_isInsertionRow_throw() const
    {
        return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ISNEW, false );
    }

    //--------------------------------------------------------------------
    sal_Int32 FormOperations::impl_getRowCount_throw() const
    {
        return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ROWCOUNT, (sal_Int32)0 );
    }
    //--------------------------------------------------------------------
    bool FormOperations::impl_isRowCountFinal_throw() const
    {
        return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ROWCOUNTFINAL, false );
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_isModifiedRow_throw() const
    {
        return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ISMODIFIED, false );
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_isParseable_throw() const
    {
        const_cast< FormOperations* >( this )->impl_ensureInitializedParser_nothrow();
        return m_xParser.is() && m_xParser->getQuery().getLength();
    }

    //--------------------------------------------------------------------
	bool FormOperations::impl_hasFilterOrOrder_throw() const
    {
        return impl_isParseable_throw() && ( m_xParser->getFilter().getLength() || m_xParser->getOrder().getLength() );
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_isInsertOnlyForm_throw() const
    {
        return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_INSERTONLY, true );
    }

    //------------------------------------------------------------------------------
    Reference< XControlModel > FormOperations::impl_getCurrentControlModel_throw() const
    {
        Reference< XControl > xControl( m_xController->getCurrentControl() );

        // special handling for grid controls
        Reference< XGrid > xGrid( xControl, UNO_QUERY );
        Reference< XControlModel > xControlModel;

        if ( xGrid.is() )
        {
	        Reference< XIndexAccess > xColumns( xControl->getModel(), UNO_QUERY_THROW );
	        sal_Int16 nCurrentPos = xGrid->getCurrentColumnPosition();
	        nCurrentPos = impl_gridView2ModelPos_nothrow( xColumns, nCurrentPos );

            if ( nCurrentPos != (sal_Int16)-1 )
		        xColumns->getByIndex( nCurrentPos ) >>= xControlModel;
        }
        else if ( xControl.is() )
        {
	        xControlModel = xControl->getModel();
        }
        return xControlModel;
    }

    //------------------------------------------------------------------------------
    Reference< XPropertySet > FormOperations::impl_getCurrentBoundField_nothrow( ) const
    {
        OSL_PRECOND( m_xController.is(), "FormOperations::impl_getCurrentBoundField_nothrow: no controller -> no control!" );
        if ( !m_xController.is() )
            return NULL;

        Reference< XPropertySet > xField;
        try
        {
            Reference< XPropertySet > xControlModel( impl_getCurrentControlModel_throw(), UNO_QUERY );

	        if ( xControlModel.is() && ::comphelper::hasProperty( PROPERTY_BOUNDFIELD, xControlModel ) )
		        xControlModel->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= xField;

        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }

	    return xField;
    }

    //------------------------------------------------------------------------------
    sal_Int16 FormOperations::impl_gridView2ModelPos_nothrow( const Reference< XIndexAccess >& _rxColumns, sal_Int16 _nViewPos ) const
    {
        OSL_PRECOND( _rxColumns.is(), "FormOperations::impl_gridView2ModelPos_nothrow: invalid columns container!" );
        try
        {
            // loop through all columns
            sal_Int16 col = 0;
            Reference< XPropertySet > xCol;
            bool bHidden( false );
            for ( col = 0; col < _rxColumns->getCount(); ++col )
            {
                _rxColumns->getByIndex( col ) >>= xCol;
                OSL_VERIFY( xCol->getPropertyValue( PROPERTY_HIDDEN ) >>= bHidden );
                if ( bHidden )
                    continue;

                // for every visible col : if nViewPos is greater zero, decrement it, else we
                // have found the model position
                if ( !_nViewPos )
                    break;
                else
                    --_nViewPos;
            }
            if ( col < _rxColumns->getCount() )
                return col;
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return (sal_Int16)-1;
    }

    //------------------------------------------------------------------------------
    bool FormOperations::impl_moveLeft_throw( ) const
    {
        OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveLeft_throw: no cursor!" );
	    if ( !impl_hasCursor_nothrow() )
		    return false;

	    sal_Bool bRecordInserted = sal_False;
	    sal_Bool bSuccess = impl_commitCurrentRecord_throw( &bRecordInserted );

	    if ( !bSuccess )
            return false;

		if ( bRecordInserted )
		{
			// retrieve the bookmark of the new record and move to the record preceding this bookmark
			Reference< XRowLocate > xLocate( m_xCursor, UNO_QUERY );
            OSL_ENSURE( xLocate.is(), "FormOperations::impl_moveLeft_throw: no XRowLocate!" );
            if ( xLocate.is() )
                xLocate->moveRelativeToBookmark( xLocate->getBookmark(), -1 );
		}
		else
        {
            if ( impl_isInsertionRow_throw() )
			{
				// we assume that the inserted record is now the last record in the
				// result set
				m_xCursor->last();
			}
			else
				m_xCursor->previous();
        }

        return true;
    }

    //--------------------------------------------------------------------
    bool FormOperations::impl_moveRight_throw( ) const
    {
        OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveRight_throw: no cursor!" );
	    if ( !impl_hasCursor_nothrow() )
		    return false;

	    sal_Bool bRecordInserted = sal_False;
	    sal_Bool bSuccess = impl_commitCurrentRecord_throw( &bRecordInserted );

        if ( !bSuccess )
            return false;

		if ( bRecordInserted )
		{
			// go to insert row
			m_xUpdateCursor->moveToInsertRow();
		}
		else
		{
			if ( m_xCursor->isLast() )
				m_xUpdateCursor->moveToInsertRow();
			else
				m_xCursor->next();
		}

	    return true;
    }

    //--------------------------------------------------------------------
    void FormOperations::impl_resetAllControls_nothrow() const
    {
	    Reference< XIndexAccess > xContainer( m_xCursor, UNO_QUERY );
		if ( !xContainer.is() )
            return;

        try
        {
            Reference< XReset > xReset;
            sal_Int32 nCount( xContainer->getCount() );
		    for ( sal_Int32 i = 0; i < nCount; ++i )
		    {
			    if ( xContainer->getByIndex( i ) >>= xReset )
			    {
                    // no resets on sub forms
				    Reference< XForm > xAsForm( xReset, UNO_QUERY );
				    if ( !xAsForm.is() )
					    xReset->reset();
			    }
		    }
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //------------------------------------------------------------------------------
    void FormOperations::impl_executeAutoSort_throw( bool _bUp ) const
    {
        OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeAutoSort_throw: need a controller for this!" );
        OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoSort_throw: need a cursor for this!" );
        OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoSort_throw: need a parseable statement for this!" );
        if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
            return;

        try
        {
		    Reference< XControl > xControl = m_xController->getCurrentControl();
            if ( !xControl.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
                return;

            Reference< XPropertySet > xBoundField( impl_getCurrentBoundField_nothrow() );
			if ( !xBoundField.is() )
                return;

            ::rtl::OUString sOriginalSort;
			m_xCursorProperties->getPropertyValue( PROPERTY_SORT ) >>= sOriginalSort;

			// automatic sort by field is expected to always resets the previous sort order
    		m_xParser->setOrder( ::rtl::OUString() );

            param_appendOrderByColumn aParam;
            aParam.xField = xBoundField;
            aParam.bUp = _bUp;
			impl_doActionInSQLContext_throw(
                (Action)&FormOperations::impl_appendOrderByColumn_throw,
                static_cast< const void* >( &aParam ),
                (sal_uInt16)RID_STR_COULD_NOT_SET_ORDER
            );

			WaitObject aWO( NULL );
			try
			{
				m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
				m_xLoadableForm->reload();
			}
			catch( const Exception& )
			{
                OSL_ENSURE( sal_False, "FormOperations::impl_executeAutoSort_throw: caught an exception while setting the parser properties!" );
			}


			if ( !m_xLoadableForm->isLoaded() )
			{	// something went wrong -> restore the original state
				try
				{
					m_xParser->setOrder( sOriginalSort );
					m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
					m_xLoadableForm->reload();
				}
				catch( const Exception& )
				{
                    OSL_ENSURE( sal_False, "FormOperations::impl_executeAutoSort_throw: could not reset the form to it's original state!" );
				}

			}
        }
        catch( const RuntimeException& ) { throw; }
        catch( const SQLException& ) { throw; }
        catch( const Exception& )
        {
            throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
        }
    }

    //------------------------------------------------------------------------------
    void FormOperations::impl_executeAutoFilter_throw( ) const
    {
        OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeAutoFilter_throw: need a controller for this!" );
        OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoFilter_throw: need a cursor for this!" );
        OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoFilter_throw: need a parseable statement for this!" );
        if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
            return;

        try
        {
		    Reference< XControl > xControl = m_xController->getCurrentControl();
            if ( !xControl.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
                return;

            Reference< XPropertySet > xBoundField( impl_getCurrentBoundField_nothrow() );
		    if ( !xBoundField.is() )
                return;

		    ::rtl::OUString sOriginalFilter;
            m_xCursorProperties->getPropertyValue( PROPERTY_FILTER ) >>= sOriginalFilter;
		    sal_Bool bApplied = sal_True;
            m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER ) >>= bApplied;

		    // if we have a filter, but it's not applied, then we have to overwrite it, else append one
		    if ( !bApplied )
                m_xParser->setFilter( ::rtl::OUString() );

            param_appendFilterByColumn aParam;
            aParam.xField = xBoundField;
		    impl_doActionInSQLContext_throw(
                (Action)&FormOperations::impl_appendFilterByColumn_throw,
                static_cast< const void* >( &aParam ),
                (sal_uInt16)RID_STR_COULD_NOT_SET_FILTER
            );

            WaitObject aWO( NULL );
		    try
		    {
			    m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
			    m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( (sal_Bool)sal_True ) );

			    m_xLoadableForm->reload();
		    }
		    catch( const Exception& )
		    {
                OSL_ENSURE( sal_False, "FormOperations::impl_executeAutoFilter_throw: caught an exception while setting the parser properties!" );
		    }


		    if ( !m_xLoadableForm->isLoaded() )
		    {	// something went wrong -> restore the original state
			    try
			    {
				    m_xParser->setOrder( sOriginalFilter );
				    m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( (sal_Bool)bApplied ) );
				    m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
				    m_xLoadableForm->reload();
			    }
			    catch( const Exception& )
			    {
                    OSL_ENSURE( sal_False, "FormOperations::impl_executeAutoFilter_throw: could not reset the form to it's original state!" );
			    }

		    }
        }
        catch( const RuntimeException& ) { throw; }
        catch( const SQLException& ) { throw; }
        catch( const Exception& )
        {
            throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
        }
    }

    //--------------------------------------------------------------------
    void FormOperations::impl_executeFilterOrSort_throw( bool _bFilter ) const
    {
        OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeFilterOrSort_throw: need a controller for this!" );
        OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeFilterOrSort_throw: need a cursor for this!" );
        OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeFilterOrSort_throw: need a parseable statement for this!" );
        if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
            return;

        if ( !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
            return;
		try
		{
			PropertyValue aFirst;
			aFirst.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) );
			aFirst.Value <<= m_xParser;

			PropertyValue aSecond;
			aSecond.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) );
			aSecond.Value <<= m_xCursorProperties;

			Sequence<Any> aInit(2);
			aInit[0] <<= aFirst;
			aInit[1] <<= aSecond;

            ::rtl::OUString sDialogServiceName;
            if ( _bFilter )
                sDialogServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.FilterDialog" ) );
            else
                sDialogServiceName = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.OrderDialog" ) );

            Reference< XExecutableDialog> xDialog;
            m_aContext.createComponentWithArguments( sDialogServiceName, aInit, xDialog );

			if ( !xDialog.is() )
            {
    		    ShowServiceNotAvailableError( NULL, sDialogServiceName, sal_True );
                return;
            }

            if ( RET_OK == xDialog->execute() )
            {
        		WaitObject aWO( NULL );
                if ( _bFilter )
                    m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
                else
                    m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
		    	m_xLoadableForm->reload();
            }

		}
        catch( const RuntimeException& ) { throw; }
        catch( const SQLException& ) { throw; }
		catch( const Exception& )
		{
            throw WrappedTargetException( ::rtl::OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
		}
    }

    //------------------------------------------------------------------------------
    void FormOperations::impl_appendOrderByColumn_throw( const void* _pActionParam ) const
    {
        const param_appendOrderByColumn* pParam = static_cast< const param_appendOrderByColumn* >( _pActionParam );
        m_xParser->appendOrderByColumn( pParam->xField, pParam->bUp );
    }

    //------------------------------------------------------------------------------
    void FormOperations::impl_appendFilterByColumn_throw( const void* _pActionParam ) const
    {
        const param_appendFilterByColumn* pParam = static_cast< const param_appendFilterByColumn* >( _pActionParam );
        sal_Int32 nOp = SQLFilterOperator::EQUAL;
        if ( pParam->xField.is() )
        {
            sal_Int32 nType = 0;
            pParam->xField->getPropertyValue(PROPERTY_FIELDTYPE) >>= nType;
            switch(nType)
            {
                case DataType::VARCHAR:
	            case DataType::CHAR:
	            case DataType::LONGVARCHAR:
                    nOp = SQLFilterOperator::LIKE;
                    break;
                default:
                    nOp = SQLFilterOperator::EQUAL;
            }
        }
        m_xParser->appendFilterByColumn( pParam->xField, sal_True,nOp );
    }

    //------------------------------------------------------------------------------
    void FormOperations::impl_doActionInSQLContext_throw( Action _pAction, const void* _pParam, sal_uInt16 _nErrorResourceId ) const
    {
	    try
	    {
		    (this->*_pAction)( _pParam );
	    }
	    catch( const SQLException& e )
	    {
            (void)e;
            if ( !_nErrorResourceId )
                // no information to prepend
                throw;

            SQLExceptionInfo aInfo( ::cppu::getCaughtException() );
            ::rtl::OUString sAdditionalError( FRM_RES_STRING( _nErrorResourceId ) );
            aInfo.prepend( sAdditionalError );
            aInfo.doThrow();
	    }
        catch( const RuntimeException& ) { throw; }
	    catch( const Exception& )
	    {
            ::rtl::OUString sAdditionalError( FRM_RES_STRING( _nErrorResourceId ) );
            throw WrappedTargetException( sAdditionalError, *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
	    }
    }

//........................................................................
} // namespace frm
//........................................................................
