LCOV - code coverage report
Current view: top level - forms/source/runtime - formoperations.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 101 775 13.0 %
Date: 2015-06-13 12:38:46 Functions: 18 71 25.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : 
      22             : #include "formoperations.hxx"
      23             : #include "frm_strings.hxx"
      24             : #include "frm_resource.hxx"
      25             : #include "frm_resource.hrc"
      26             : #include "services.hxx"
      27             : 
      28             : #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
      29             : #include <com/sun/star/util/XModifyBroadcaster.hpp>
      30             : #include <com/sun/star/form/runtime/FormFeature.hpp>
      31             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      32             : #include <com/sun/star/lang/DisposedException.hpp>
      33             : #include <com/sun/star/awt/XControl.hpp>
      34             : #include <com/sun/star/form/XGrid.hpp>
      35             : #include <com/sun/star/form/XBoundControl.hpp>
      36             : #include <com/sun/star/form/XBoundComponent.hpp>
      37             : #include <com/sun/star/sdbcx/XRowLocate.hpp>
      38             : #include <com/sun/star/form/XConfirmDeleteListener.hpp>
      39             : #include <com/sun/star/sdb/RowChangeEvent.hpp>
      40             : #include <com/sun/star/sdb/RowChangeAction.hpp>
      41             : #include <com/sun/star/sdb/OrderDialog.hpp>
      42             : #include <com/sun/star/sdb/FilterDialog.hpp>
      43             : #include <com/sun/star/sdbc/DataType.hpp>
      44             : #include <com/sun/star/form/XReset.hpp>
      45             : #include <com/sun/star/beans/XMultiPropertySet.hpp>
      46             : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
      47             : #include <com/sun/star/util/XRefreshable.hpp>
      48             : 
      49             : #include <connectivity/dbtools.hxx>
      50             : #include <connectivity/dbexception.hxx>
      51             : #include <vcl/svapp.hxx>
      52             : #include <vcl/stdtext.hxx>
      53             : #include <vcl/msgbox.hxx>
      54             : #include <vcl/waitobj.hxx>
      55             : #include <tools/diagnose_ex.h>
      56             : #include <comphelper/container.hxx>
      57             : #include <comphelper/property.hxx>
      58             : #include <comphelper/namedvaluecollection.hxx>
      59             : #include <comphelper/processfactory.hxx>
      60             : #include <cppuhelper/exc_hlp.hxx>
      61             : #include <cppuhelper/supportsservice.hxx>
      62             : #include <osl/mutex.hxx>
      63             : #include <sal/macros.h>
      64             : 
      65             : 
      66             : namespace frm
      67             : {
      68             : 
      69             : 
      70             :     using ::dbtools::SQLExceptionInfo;
      71             :     using ::com::sun::star::uno::Reference;
      72             :     using ::com::sun::star::uno::XComponentContext;
      73             :     using ::com::sun::star::uno::RuntimeException;
      74             :     using ::com::sun::star::uno::Sequence;
      75             :     using ::com::sun::star::uno::Exception;
      76             :     using ::com::sun::star::uno::Any;
      77             :     using ::com::sun::star::uno::XInterface;
      78             :     using ::com::sun::star::sdbc::XRowSet;
      79             :     using ::com::sun::star::sdbc::XResultSetUpdate;
      80             :     using ::com::sun::star::form::runtime::XFormController;
      81             :     using ::com::sun::star::form::runtime::XFormOperations;
      82             :     using ::com::sun::star::form::runtime::XFeatureInvalidation;
      83             :     using ::com::sun::star::form::runtime::FeatureState;
      84             :     using ::com::sun::star::lang::IllegalArgumentException;
      85             :     using ::com::sun::star::sdbc::SQLException;
      86             :     using namespace ::com::sun::star::sdbc;
      87             :     using ::com::sun::star::form::XForm;
      88             :     using ::com::sun::star::ucb::AlreadyInitializedException;
      89             :     using ::com::sun::star::util::XModifyBroadcaster;
      90             :     using ::com::sun::star::uno::UNO_QUERY;
      91             :     using ::com::sun::star::lang::EventObject;
      92             :     using ::com::sun::star::beans::PropertyChangeEvent;
      93             :     using ::com::sun::star::lang::XMultiServiceFactory;
      94             :     using ::com::sun::star::lang::DisposedException;
      95             :     using ::com::sun::star::beans::XPropertySet;
      96             :     using ::com::sun::star::awt::XControl;
      97             :     using ::com::sun::star::form::XGrid;
      98             :     using ::com::sun::star::container::XIndexAccess;
      99             :     using ::com::sun::star::uno::UNO_QUERY_THROW;
     100             :     using ::com::sun::star::form::XBoundControl;
     101             :     using ::com::sun::star::form::XBoundComponent;
     102             :     using ::com::sun::star::sdbcx::XRowLocate;
     103             :     using ::com::sun::star::form::XConfirmDeleteListener;
     104             :     using ::com::sun::star::sdb::RowChangeEvent;
     105             :     using namespace ::com::sun::star::sdb;
     106             :     using ::com::sun::star::form::XReset;
     107             :     using ::com::sun::star::beans::XMultiPropertySet;
     108             :     using ::com::sun::star::uno::makeAny;
     109             :     using ::com::sun::star::lang::WrappedTargetException;
     110             :     using ::com::sun::star::beans::PropertyValue;
     111             :     using ::com::sun::star::ui::dialogs::XExecutableDialog;
     112             :     using ::com::sun::star::beans::NamedValue;
     113             :     using ::com::sun::star::util::XRefreshable;
     114             :     using ::com::sun::star::awt::XControlModel;
     115             : 
     116             :     namespace FormFeature = ::com::sun::star::form::runtime::FormFeature;
     117             :     namespace RowChangeAction = ::com::sun::star::sdb::RowChangeAction;
     118             : 
     119          96 :     FormOperations::FormOperations( const Reference< XComponentContext >& _rxContext )
     120             :         :FormOperations_Base( m_aMutex )
     121             :         ,m_xContext( _rxContext )
     122             :         ,m_bInitializedParser( false )
     123             :         ,m_bActiveControlModified( false )
     124          96 :         ,m_bConstructed( false )
     125             :     #ifdef DBG_UTIL
     126             :         ,m_nMethodNestingLevel( 0 )
     127             :     #endif
     128             :     {
     129          96 :     }
     130             : 
     131         192 :     FormOperations::~FormOperations()
     132             :     {
     133         192 :     }
     134             : 
     135           0 :     OUString FormOperations::getImplementationName_Static(  ) throw(RuntimeException)
     136             :     {
     137           0 :         return OUString( "com.sun.star.comp.forms.FormOperations" );
     138             :     }
     139             : 
     140           0 :     Sequence< OUString > FormOperations::getSupportedServiceNames_Static(  ) throw(RuntimeException)
     141             :     {
     142           0 :         Sequence< OUString > aNames(1);
     143           0 :         aNames[0] = "com.sun.star.form.runtime.FormOperations";
     144           0 :         return aNames;
     145             :     }
     146             : 
     147          96 :     void SAL_CALL FormOperations::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException, std::exception)
     148             :     {
     149          96 :         if ( m_bConstructed )
     150           0 :             throw AlreadyInitializedException();
     151             : 
     152          96 :         if ( _arguments.getLength() == 1 )
     153             :         {
     154          96 :             Reference< XFormController > xController;
     155         192 :             Reference< XForm > xForm;
     156          96 :             if ( _arguments[0] >>= xController )
     157          96 :                 createWithFormController( xController );
     158           0 :             else if ( _arguments[0] >>= xForm )
     159           0 :                 createWithForm( xForm );
     160             :             else
     161           0 :                 throw IllegalArgumentException( OUString(), *this, 1 );
     162         288 :             return;
     163             :         }
     164             : 
     165           0 :         throw IllegalArgumentException( OUString(), *this, 0 );
     166             :     }
     167             : 
     168           0 :     OUString SAL_CALL FormOperations::getImplementationName(  ) throw (RuntimeException, std::exception)
     169             :     {
     170           0 :         return getImplementationName_Static();
     171             :     }
     172             : 
     173           0 :     sal_Bool SAL_CALL FormOperations::supportsService( const OUString& _ServiceName ) throw (RuntimeException, std::exception)
     174             :     {
     175           0 :         return cppu::supportsService(this, _ServiceName);
     176             :     }
     177             : 
     178           0 :     Sequence< OUString > SAL_CALL FormOperations::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
     179             :     {
     180           0 :         return getSupportedServiceNames_Static();
     181             :     }
     182             : 
     183           0 :     Reference< XRowSet > SAL_CALL FormOperations::getCursor() throw (RuntimeException, std::exception)
     184             :     {
     185           0 :         MethodGuard aGuard( *this );
     186           0 :         return m_xCursor;
     187             :     }
     188             : 
     189           0 :     Reference< XResultSetUpdate > SAL_CALL FormOperations::getUpdateCursor() throw (RuntimeException, std::exception)
     190             :     {
     191           0 :         MethodGuard aGuard( *this );
     192           0 :         return m_xUpdateCursor;
     193             :     }
     194             : 
     195             : 
     196           0 :     Reference< XFormController > SAL_CALL FormOperations::getController() throw (RuntimeException, std::exception)
     197             :     {
     198           0 :         MethodGuard aGuard( *this );
     199           0 :         return m_xController;
     200             :     }
     201             : 
     202             : 
     203           0 :     Reference< XFeatureInvalidation > SAL_CALL FormOperations::getFeatureInvalidation() throw (RuntimeException, std::exception)
     204             :     {
     205           0 :         MethodGuard aGuard( *this );
     206           0 :         return m_xFeatureInvalidation;
     207             :     }
     208             : 
     209             : 
     210          96 :     void SAL_CALL FormOperations::setFeatureInvalidation( const Reference< XFeatureInvalidation > & _rxFeatureInvalidation ) throw (RuntimeException, std::exception)
     211             :     {
     212          96 :         MethodGuard aGuard( *this );
     213          96 :         m_xFeatureInvalidation = _rxFeatureInvalidation;
     214          96 :     }
     215             : 
     216             : 
     217           0 :     FeatureState SAL_CALL FormOperations::getState( ::sal_Int16 _nFeature ) throw (RuntimeException, std::exception)
     218             :     {
     219           0 :         MethodGuard aGuard( *this );
     220             : 
     221           0 :         FeatureState aState;
     222           0 :         aState.Enabled = sal_False;
     223             : 
     224             :         try
     225             :         {
     226             :             // some checks for basic pre-requisites
     227           0 :             if  (   !m_xLoadableForm.is()
     228           0 :                 ||  !m_xLoadableForm->isLoaded()
     229           0 :                 ||  !m_xCursorProperties.is()
     230             :                 )
     231             :             {
     232           0 :                 return aState;
     233             :             }
     234             : 
     235           0 :             switch ( _nFeature )
     236             :             {
     237             :             case FormFeature::MoveToFirst:
     238             :             case FormFeature::MoveToPrevious:
     239           0 :                 aState.Enabled = impl_canMoveLeft_throw( );
     240           0 :                 break;
     241             : 
     242             :             case FormFeature::MoveToNext:
     243           0 :                 aState.Enabled = impl_canMoveRight_throw();
     244           0 :                 break;
     245             : 
     246             :             case FormFeature::MoveToLast:
     247           0 :                 aState.Enabled = impl_getRowCount_throw() && ( !m_xCursor->isLast() || impl_isInsertionRow_throw() );
     248           0 :                 break;
     249             : 
     250             :             case FormFeature::DeleteRecord:
     251             :                 // already deleted ?
     252           0 :                 if ( m_xCursor->rowDeleted() )
     253           0 :                     aState.Enabled = sal_False;
     254             :                 else
     255             :                 {
     256             :                     // allowed to delete the row ?
     257           0 :                     aState.Enabled = !impl_isInsertionRow_throw() && ::dbtools::canDelete( m_xCursorProperties );
     258             :                 }
     259           0 :                 break;
     260             : 
     261             :             case FormFeature::MoveToInsertRow:
     262             :                 // if we are inserting we can move to the next row if the current record or control is modified
     263           0 :                 aState.Enabled =    impl_isInsertionRow_throw()
     264           0 :                                 ?   impl_isModifiedRow_throw() || m_bActiveControlModified
     265           0 :                                 :   ::dbtools::canInsert( m_xCursorProperties );
     266           0 :                 break;
     267             : 
     268             :             case FormFeature::ReloadForm:
     269             :             {
     270             :                 // there must be an active connection
     271           0 :                 Reference< XRowSet > xCursorRowSet( m_xCursor, UNO_QUERY );
     272           0 :                 aState.Enabled = ::dbtools::getConnection( xCursorRowSet ).is();
     273             : 
     274             :                 // and an active command
     275           0 :                 OUString sActiveCommand;
     276           0 :                 m_xCursorProperties->getPropertyValue( PROPERTY_ACTIVECOMMAND ) >>= sActiveCommand;
     277           0 :                 aState.Enabled = aState.Enabled && !sActiveCommand.isEmpty();
     278             :             }
     279           0 :             break;
     280             : 
     281             :             case FormFeature::RefreshCurrentControl:
     282             :             {
     283           0 :                 Reference< XRefreshable > xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY );
     284           0 :                 aState.Enabled = xControlModelRefresh.is();
     285             :             }
     286           0 :             break;
     287             : 
     288             :             case FormFeature::SaveRecordChanges:
     289             :             case FormFeature::UndoRecordChanges:
     290           0 :                 aState.Enabled = impl_isModifiedRow_throw() || m_bActiveControlModified;
     291           0 :                 break;
     292             : 
     293             :             case FormFeature::RemoveFilterAndSort:
     294           0 :                 if ( impl_isParseable_throw() && impl_hasFilterOrOrder_throw() )
     295           0 :                     aState.Enabled = !impl_isInsertOnlyForm_throw();
     296           0 :                 break;
     297             : 
     298             :             case FormFeature::SortAscending:
     299             :             case FormFeature::SortDescending:
     300             :             case FormFeature::AutoFilter:
     301           0 :                 if ( m_xController.is() && impl_isParseable_throw() )
     302             :                 {
     303           0 :                     bool bIsDeleted = m_xCursor->rowDeleted();
     304             : 
     305           0 :                     if ( !bIsDeleted && !impl_isInsertOnlyForm_throw() )
     306             :                     {
     307           0 :                         Reference< XPropertySet > xBoundField = impl_getCurrentBoundField_nothrow( );
     308           0 :                         if ( xBoundField.is() )
     309           0 :                             xBoundField->getPropertyValue( PROPERTY_SEARCHABLE ) >>= aState.Enabled;
     310             :                     }
     311             :                 }
     312           0 :                 break;
     313             : 
     314             :             case FormFeature::InteractiveSort:
     315             :             case FormFeature::InteractiveFilter:
     316           0 :                 if ( impl_isParseable_throw() )
     317           0 :                     aState.Enabled = !impl_isInsertOnlyForm_throw();
     318           0 :                 break;
     319             : 
     320             :             case FormFeature::ToggleApplyFilter:
     321             :             {
     322           0 :                 OUString sFilter;
     323           0 :                 m_xCursorProperties->getPropertyValue( PROPERTY_FILTER ) >>= sFilter;
     324           0 :                 if ( !sFilter.isEmpty() )
     325             :                 {
     326           0 :                     aState.State = m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER );
     327           0 :                     aState.Enabled = !impl_isInsertOnlyForm_throw();
     328             :                 }
     329             :                 else
     330           0 :                     aState.State <<= false;
     331             :             }
     332           0 :             break;
     333             : 
     334             :             case FormFeature::MoveAbsolute:
     335             :             {
     336           0 :                 sal_Int32 nPosition   = m_xCursor->getRow();
     337           0 :                 bool  bIsNew      = impl_isInsertionRow_throw();
     338           0 :                 sal_Int32 nCount      = impl_getRowCount_throw();
     339           0 :                 bool  bFinalCount = impl_isRowCountFinal_throw();
     340             : 
     341           0 :                 if ( ( nPosition >= 0 ) || bIsNew )
     342             :                 {
     343           0 :                     if ( bFinalCount )
     344             :                     {
     345             :                         // special case: there are no records at all, and we
     346             :                         // can't insert records -> disabled
     347           0 :                         if ( !nCount && !::dbtools::canInsert( m_xCursorProperties ) )
     348             :                         {
     349           0 :                             aState.Enabled = sal_False;
     350             :                         }
     351             :                         else
     352             :                         {
     353           0 :                             if ( bIsNew )
     354           0 :                                 nPosition = ++nCount;
     355           0 :                             aState.State <<= (sal_Int32)nPosition;
     356           0 :                             aState.Enabled = sal_True;
     357             :                         }
     358             :                     }
     359             :                     else
     360             :                     {
     361           0 :                         aState.State <<= (sal_Int32)nPosition;
     362           0 :                         aState.Enabled = sal_True;
     363             :                     }
     364             :                 }
     365             :             }
     366           0 :             break;
     367             : 
     368             :             case FormFeature::TotalRecords:
     369             :             {
     370           0 :                 bool  bIsNew      = impl_isInsertionRow_throw();
     371           0 :                 sal_Int32 nCount      = impl_getRowCount_throw();
     372           0 :                 bool  bFinalCount = impl_isRowCountFinal_throw();
     373             : 
     374           0 :                 if ( bIsNew )
     375           0 :                     ++nCount;
     376             : 
     377           0 :                 OUString sValue = OUString::number( nCount );
     378           0 :                 if ( !bFinalCount )
     379           0 :                     sValue += " *";
     380             : 
     381           0 :                 aState.State <<= sValue;
     382           0 :                 aState.Enabled = sal_True;
     383             :             }
     384           0 :             break;
     385             : 
     386             :             default:
     387             :                 OSL_FAIL( "FormOperations::getState: unknown feature id!" );
     388           0 :                 break;
     389             :             }
     390             :         }
     391           0 :         catch( const Exception& )
     392             :         {
     393             :             OSL_FAIL( "FormOperations::getState: caught an exception!" );
     394             :         }
     395             : 
     396           0 :         return aState;
     397             :     }
     398             : 
     399             : 
     400           0 :     sal_Bool SAL_CALL FormOperations::isEnabled( ::sal_Int16 _nFeature ) throw (RuntimeException, std::exception)
     401             :     {
     402           0 :         MethodGuard aGuard( *this );
     403             : 
     404           0 :         FeatureState aState( getState( _nFeature ) );
     405           0 :         return aState.Enabled;
     406             :     }
     407             : 
     408             : 
     409             :     namespace
     410             :     {
     411           0 :         static bool lcl_needConfirmCommit( sal_Int32 _nFeature )
     412             :         {
     413             :             return ( ( _nFeature == FormFeature::ReloadForm )
     414           0 :                   || ( _nFeature == FormFeature::RemoveFilterAndSort )
     415           0 :                   || ( _nFeature == FormFeature::ToggleApplyFilter )
     416           0 :                   || ( _nFeature == FormFeature::SortAscending )
     417           0 :                   || ( _nFeature == FormFeature::SortDescending )
     418           0 :                   || ( _nFeature == FormFeature::AutoFilter )
     419           0 :                   || ( _nFeature == FormFeature::InteractiveSort )
     420           0 :                   || ( _nFeature == FormFeature::InteractiveFilter )
     421           0 :                    );
     422             :         }
     423           0 :         static bool lcl_requiresArguments( sal_Int32 _nFeature )
     424             :         {
     425           0 :             return ( _nFeature == FormFeature::MoveAbsolute );
     426             :         }
     427           0 :         static bool lcl_isExecutableFeature( sal_Int32 _nFeature )
     428             :         {
     429           0 :             return ( _nFeature != FormFeature::TotalRecords );
     430             :         }
     431             : 
     432             :         template < typename TYPE >
     433           3 :         TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const OUString& _rPropertyName, TYPE _Default )
     434             :         {
     435           3 :             TYPE value( _Default );
     436             :             OSL_PRECOND( _rxProperties.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
     437           3 :             if ( _rxProperties.is() )
     438           3 :                 OSL_VERIFY( _rxProperties->getPropertyValue( _rPropertyName ) >>= value );
     439           3 :             return value;
     440             :         }
     441             : 
     442             :         // returns false if parent should *abort* (user pressed cancel)
     443           0 :         bool checkConfirmation(bool &needConfirmation, bool &shouldCommit)
     444             :         {
     445           0 :             if(needConfirmation)
     446             :             {
     447             :                 // TODO: shouldn't this be done with an interaction handler?
     448           0 :                 ScopedVclPtrInstance< QueryBox > aQuery( nullptr, WB_YES_NO_CANCEL | WB_DEF_YES, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW ) );
     449           0 :                 switch ( aQuery->Execute() )
     450             :                 {
     451             :                 case RET_NO:
     452           0 :                     shouldCommit = false;
     453             :                     // no break on purpose: don't ask again!
     454             :                 case RET_YES:
     455           0 :                     needConfirmation = false;
     456           0 :                     return true;
     457             :                 case RET_CANCEL:
     458           0 :                     return false;
     459           0 :                 }
     460             :             }
     461           0 :             return true;
     462             :         }
     463             : 
     464           0 :         bool commit1Form(Reference< XFormController > xCntrl, bool &needConfirmation, bool &shouldCommit)
     465             :         {
     466           0 :             Reference< XFormOperations > xFrmOps(xCntrl->getFormOperations());
     467           0 :             if (!xFrmOps->commitCurrentControl())
     468           0 :                 return false;
     469             : 
     470           0 :             if(xFrmOps->isModifiedRow())
     471             :             {
     472           0 :                 if(!checkConfirmation(needConfirmation, shouldCommit))
     473           0 :                     return false;
     474             :                 sal_Bool bTmp;
     475           0 :                 if (shouldCommit && !xFrmOps->commitCurrentRecord(bTmp))
     476           0 :                     return false;
     477             :             }
     478           0 :             return true;
     479             :         }
     480             : 
     481           0 :         bool commitFormAndSubforms(Reference< XFormController > xCntrl, bool needConfirmation)
     482             :         {
     483           0 :             bool shouldCommit(true);
     484             :             assert(xCntrl.is());
     485           0 :             Reference< XIndexAccess > xSubForms(xCntrl, UNO_QUERY);
     486             :             assert(xSubForms.is());
     487           0 :             if(xSubForms.is())
     488             :             {
     489           0 :                 const sal_Int32 cnt = xSubForms->getCount();
     490           0 :                 for(int i=0; i < cnt; ++i)
     491             :                 {
     492           0 :                     Reference< XFormController > xSubForm(xSubForms->getByIndex(i), UNO_QUERY);
     493             :                     assert(xSubForm.is());
     494           0 :                     if (xSubForm.is())
     495             :                     {
     496           0 :                         if (!commit1Form(xSubForm, needConfirmation, shouldCommit))
     497           0 :                             return false;
     498             :                     }
     499           0 :                 }
     500             :             }
     501             : 
     502           0 :             if(!commit1Form(xCntrl, needConfirmation, shouldCommit))
     503           0 :                 return false;
     504             : 
     505           0 :             return true;
     506             :         }
     507             : 
     508           0 :         bool commit1Form(Reference< XForm > xFrm, bool &needConfirmation, bool &shouldCommit)
     509             :         {
     510           0 :             Reference< XPropertySet > xProps(xFrm, UNO_QUERY_THROW);
     511             :             // nothing to do if the record is not modified
     512           0 :             if(!lcl_safeGetPropertyValue_throw( xProps, PROPERTY_ISMODIFIED, false ))
     513           0 :                 return true;
     514             : 
     515           0 :             if(!checkConfirmation(needConfirmation, shouldCommit))
     516           0 :                 return false;
     517           0 :             if(shouldCommit)
     518             :             {
     519           0 :                 Reference< XResultSetUpdate > xUpd(xFrm, UNO_QUERY_THROW);
     520             :                 // insert respectively update the row
     521           0 :                 if ( lcl_safeGetPropertyValue_throw( xProps, PROPERTY_ISNEW, false ) )
     522           0 :                     xUpd->insertRow();
     523             :                 else
     524           0 :                     xUpd->updateRow();
     525             :             }
     526           0 :             return true;
     527             :         }
     528             : 
     529           0 :         bool commitFormAndSubforms(Reference< XForm > xFrm, bool needConfirmation)
     530             :         {
     531             :             // No control...  do what we can with the models
     532           0 :             bool shouldCommit(true);
     533           0 :             Reference< XIndexAccess > xFormComps(xFrm, UNO_QUERY_THROW);
     534             :             assert( xFormComps.is() );
     535             : 
     536           0 :             const sal_Int32 cnt = xFormComps->getCount();
     537           0 :             for(int i=0; i < cnt; ++i)
     538             :             {
     539           0 :                 Reference< XForm > xSubForm(xFormComps->getByIndex(i), UNO_QUERY);
     540           0 :                 if(xSubForm.is())
     541             :                 {
     542           0 :                     if(!commit1Form(xSubForm, needConfirmation, shouldCommit))
     543           0 :                         return false;
     544             :                 }
     545           0 :             }
     546             : 
     547           0 :             if(!commit1Form(xFrm, needConfirmation, shouldCommit))
     548           0 :                 return false;
     549             : 
     550           0 :             return true;
     551             :         }
     552             :     }
     553             : 
     554           0 :     void SAL_CALL FormOperations::execute( ::sal_Int16 _nFeature ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException, std::exception)
     555             :     {
     556           0 :         SolarMutexGuard aSolarGuard;
     557           0 :         MethodGuard aGuard( *this );
     558             : 
     559           0 :         if ( ( _nFeature != FormFeature::DeleteRecord ) && ( _nFeature != FormFeature::UndoRecordChanges ) )
     560             :         {
     561             : 
     562             : 
     563           0 :             if(m_xController.is())
     564             :             {
     565           0 :                 if(!commitFormAndSubforms(m_xController, lcl_needConfirmCommit( _nFeature )))
     566           0 :                     return;
     567             :             }
     568           0 :             else if(m_xCursor.is())
     569             :             {
     570           0 :                 Reference< XForm > xForm(m_xCursor, UNO_QUERY);
     571             :                 assert(xForm.is());
     572           0 :                 if(!commitFormAndSubforms(xForm, lcl_needConfirmCommit( _nFeature )))
     573           0 :                     return;
     574             :             }
     575             :             else
     576             :             {
     577             :                 SAL_WARN( "forms.runtime", "No cursor, but trying to execute form operation " << _nFeature );
     578             :             }
     579             :         }
     580             : 
     581             :         try
     582             :         {
     583           0 :             switch ( _nFeature )
     584             :             {
     585             :             case FormFeature::MoveToFirst:
     586           0 :                 m_xCursor->first();
     587           0 :                 break;
     588             : 
     589             :             case FormFeature::MoveToNext:
     590           0 :                 impl_moveRight_throw( );
     591           0 :                 break;
     592             : 
     593             :             case FormFeature::MoveToPrevious:
     594           0 :                 impl_moveLeft_throw( );
     595           0 :                 break;
     596             : 
     597             :             case FormFeature::MoveToLast:
     598             :             {
     599             : /*
     600             :                 // TODO: re-implement this .....
     601             :                 // run in an own thread if ...
     602             :                 // ... the data source is thread safe ...
     603             :                 sal_Bool bAllowOwnThread = sal_False;
     604             :                 if ( ::comphelper::hasProperty( PROPERTY_THREADSAFE, m_xCursorProperties ) )
     605             :                     m_xCursorProperties->getPropertyValue( PROPERTY_THREADSAFE ) >>= bAllowOwnThread;
     606             : 
     607             :                 // ... the record count is unknown
     608             :                 sal_Bool bNeedOwnThread sal_False;
     609             :                 if ( ::comphelper::hasProperty( PROPERTY_ROWCOUNTFINAL, m_xCursorProperties ) )
     610             :                     m_xCursorProperties->getPropertyValue( PROPERTY_ROWCOUNTFINAL ) >>= bNeedOwnThread;
     611             : 
     612             :                 if ( bNeedOwnThread && bAllowOwnThread )
     613             :                     ;
     614             :                 else
     615             : */
     616           0 :                     m_xCursor->last();
     617             :             }
     618           0 :             break;
     619             : 
     620             :             case FormFeature::ReloadForm:
     621           0 :                 if ( m_xLoadableForm.is() )
     622             :                 {
     623           0 :                     WaitObject aWO( NULL );
     624           0 :                     m_xLoadableForm->reload();
     625             : 
     626             :                     // refresh all controls in the form (and sub forms) which can be refreshed
     627             :                     // #i90914#
     628           0 :                     ::comphelper::IndexAccessIterator aIter( m_xLoadableForm );
     629           0 :                     Reference< XInterface > xElement( aIter.Next() );
     630           0 :                     while ( xElement.is() )
     631             :                     {
     632           0 :                         Reference< XRefreshable > xRefresh( xElement, UNO_QUERY );
     633           0 :                         if ( xRefresh.is() )
     634           0 :                             xRefresh->refresh();
     635           0 :                         xElement = aIter.Next();
     636           0 :                     }
     637             :                 }
     638           0 :                 break;
     639             : 
     640             :             case FormFeature::RefreshCurrentControl:
     641             :             {
     642           0 :                 Reference< XRefreshable > xControlModelRefresh( impl_getCurrentControlModel_throw(), UNO_QUERY );
     643             :                 OSL_ENSURE( xControlModelRefresh.is(), "FormOperations::execute: how did you reach this?" );
     644           0 :                 if ( xControlModelRefresh.is() )
     645           0 :                     xControlModelRefresh->refresh();
     646             :             }
     647           0 :             break;
     648             : 
     649             :             case FormFeature::DeleteRecord:
     650             :             {
     651           0 :                 sal_uInt32 nCount = impl_getRowCount_throw();
     652             : 
     653             :                 // next position
     654           0 :                 bool bLeft = m_xCursor->isLast() && ( nCount > 1 );
     655           0 :                 bool bRight= !m_xCursor->isLast();
     656           0 :                 bool bSuccess = false;
     657             :                 try
     658             :                 {
     659             :                     // ask for confirmation
     660           0 :                     Reference< XConfirmDeleteListener > xConfirmDelete( m_xController, UNO_QUERY );
     661             : 
     662           0 :                     if ( xConfirmDelete.is() )
     663             :                     {
     664           0 :                         RowChangeEvent aEvent;
     665           0 :                         aEvent.Source = Reference< XInterface >( m_xCursor, UNO_QUERY );
     666           0 :                         aEvent.Action = RowChangeAction::DELETE;
     667           0 :                         aEvent.Rows = 1;
     668           0 :                         bSuccess = xConfirmDelete->confirmDelete( aEvent );
     669             :                     }
     670             : 
     671             :                     // delete it
     672           0 :                     if ( bSuccess )
     673           0 :                         m_xUpdateCursor->deleteRow();
     674             :                 }
     675           0 :                 catch( const Exception& )
     676             :                 {
     677           0 :                     bSuccess = false;
     678             :                 }
     679             : 
     680           0 :                 if ( bSuccess )
     681             :                 {
     682           0 :                     if ( bLeft || bRight )
     683           0 :                         m_xCursor->relative( bRight ? 1 : -1 );
     684             :                     else
     685             :                     {
     686           0 :                         bool bCanInsert = ::dbtools::canInsert( m_xCursorProperties );
     687             :                         // is it possible to insert another record?
     688           0 :                         if ( bCanInsert )
     689           0 :                             m_xUpdateCursor->moveToInsertRow();
     690             :                         else
     691             :                             // move record to update status
     692           0 :                             m_xCursor->first();
     693             :                     }
     694             :                 }
     695             :             }
     696           0 :             break;
     697             : 
     698             :             case FormFeature::SaveRecordChanges:
     699             :             case FormFeature::UndoRecordChanges:
     700             :             {
     701           0 :                 bool bInserting = impl_isInsertionRow_throw();
     702             : 
     703           0 :                 if ( FormFeature::UndoRecordChanges == _nFeature )
     704             :                 {
     705           0 :                     if ( !bInserting )
     706           0 :                         m_xUpdateCursor->cancelRowUpdates();
     707             : 
     708             :                     // reset all controls for this form
     709           0 :                     impl_resetAllControls_nothrow( );
     710             : 
     711           0 :                     if ( bInserting )   // back to insertion mode for this form
     712           0 :                         m_xUpdateCursor->moveToInsertRow();
     713             :                 }
     714             :                 else
     715             :                 {
     716           0 :                     if  ( bInserting )
     717             :                     {
     718           0 :                         m_xUpdateCursor->insertRow();
     719           0 :                         m_xCursor->last();
     720             :                     }
     721             :                     else
     722           0 :                         m_xUpdateCursor->updateRow();
     723             :                 }
     724             :             }
     725           0 :             break;
     726             : 
     727             :             case FormFeature::MoveToInsertRow:
     728             :                 // move to the last row before moving to the insert row
     729           0 :                 m_xCursor->last();
     730           0 :                 m_xUpdateCursor->moveToInsertRow();
     731           0 :                 break;
     732             : 
     733             :             case FormFeature::RemoveFilterAndSort:
     734             :             {
     735             :                 // simultaneously reset Filter and Order property
     736           0 :                 Reference< XMultiPropertySet > xProperties( m_xCursorProperties, UNO_QUERY );
     737             :                 OSL_ENSURE( xProperties.is(), "FormOperations::execute: no multi property access!" );
     738           0 :                 if ( xProperties.is() )
     739             :                 {
     740           0 :                     Sequence< OUString > aNames( 2 );
     741           0 :                     aNames[0] = PROPERTY_FILTER;
     742           0 :                     aNames[1] = PROPERTY_SORT;
     743             : 
     744           0 :                     Sequence< Any> aValues( 2 );
     745           0 :                     aValues[0] <<= OUString();
     746           0 :                     aValues[1] <<= OUString();
     747             : 
     748           0 :                     WaitObject aWO( NULL );
     749           0 :                     xProperties->setPropertyValues( aNames, aValues );
     750             : 
     751           0 :                     if ( m_xLoadableForm.is() )
     752           0 :                         m_xLoadableForm->reload();
     753           0 :                 }
     754             :             }
     755           0 :             break;
     756             : 
     757             :             case FormFeature::ToggleApplyFilter:
     758           0 :                 if ( impl_commitCurrentControl_throw() && impl_commitCurrentRecord_throw() )
     759             :                 {
     760             :                     // simply toggle the value
     761           0 :                     bool bApplied = false;
     762           0 :                     m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER ) >>= bApplied;
     763           0 :                     m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( !bApplied ) );
     764             : 
     765             :                     // and reload
     766           0 :                     WaitObject aWO( NULL );
     767           0 :                     m_xLoadableForm->reload();
     768             :                 }
     769           0 :                 break;
     770             : 
     771             :             case FormFeature::SortAscending:
     772           0 :                 impl_executeAutoSort_throw( true );
     773           0 :                 break;
     774             : 
     775             :             case FormFeature::SortDescending:
     776           0 :                 impl_executeAutoSort_throw( false );
     777           0 :                 break;
     778             : 
     779             :             case FormFeature::AutoFilter:
     780           0 :                 impl_executeAutoFilter_throw();
     781           0 :                 break;
     782             : 
     783             :             case FormFeature::InteractiveSort:
     784           0 :                 impl_executeFilterOrSort_throw( false );
     785           0 :                 break;
     786             : 
     787             :             case FormFeature::InteractiveFilter:
     788           0 :                 impl_executeFilterOrSort_throw( true );
     789           0 :                 break;
     790             : 
     791             :             default:
     792             :             {
     793           0 :                 sal_uInt16 nErrorResourceId = RID_STR_FEATURE_UNKNOWN;
     794           0 :                 if ( lcl_requiresArguments( _nFeature ) )
     795           0 :                     nErrorResourceId = RID_STR_FEATURE_REQUIRES_PARAMETERS;
     796           0 :                 else if ( !lcl_isExecutableFeature( _nFeature ) )
     797           0 :                     nErrorResourceId = RID_STR_FEATURE_NOT_EXECUTABLE;
     798           0 :                 throw IllegalArgumentException( FRM_RES_STRING( nErrorResourceId ), *this, 1 );
     799             :             }
     800             :             }   // switch
     801             :         }
     802           0 :         catch( const RuntimeException& ) { throw; }
     803           0 :         catch( const SQLException& ) { throw; }
     804           0 :         catch( const Exception& )
     805             :         {
     806           0 :             throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
     807             :         }
     808             : 
     809           0 :         impl_invalidateAllSupportedFeatures_nothrow( aGuard );
     810             :     }
     811             : 
     812             : 
     813           0 :     void SAL_CALL FormOperations::executeWithArguments( ::sal_Int16 _nFeature, const Sequence< NamedValue >& _rArguments ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException, std::exception)
     814             :     {
     815           0 :         if ( !lcl_requiresArguments( _nFeature ) )
     816             :         {
     817           0 :             execute( _nFeature );
     818           0 :             return;
     819             :         }
     820             : 
     821           0 :         SolarMutexGuard aSolarGuard;
     822           0 :         MethodGuard aGuard( *this );
     823             : 
     824             :         // at the moment we have only one feature which supports execution parameters
     825           0 :         if ( !lcl_isExecutableFeature( _nFeature ) )
     826           0 :             throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_NOT_EXECUTABLE ), *this, 1 );
     827             : 
     828           0 :         switch ( _nFeature )
     829             :         {
     830             :         case FormFeature::MoveAbsolute:
     831             :         {
     832           0 :             sal_Int32 nPosition = -1;
     833             : 
     834           0 :             ::comphelper::NamedValueCollection aArguments( _rArguments );
     835           0 :             aArguments.get_ensureType( "Position", nPosition );
     836             : 
     837           0 :             if ( nPosition < 1 )
     838           0 :                 nPosition = 1;
     839             : 
     840             :             try
     841             :             {
     842             :                 // commit before doing anything else
     843           0 :                 if ( m_xController.is() && !impl_commitCurrentControl_throw() )
     844           0 :                     return;
     845           0 :                 if ( !impl_commitCurrentRecord_throw() )
     846           0 :                     return;
     847             : 
     848           0 :                 sal_Int32 nCount      = impl_getRowCount_throw();
     849           0 :                 bool  bFinalCount = impl_isRowCountFinal_throw();
     850             : 
     851           0 :                 if ( bFinalCount && ( (sal_Int32)nPosition > nCount ) )
     852           0 :                     nPosition = nCount;
     853             : 
     854           0 :                 m_xCursor->absolute( nPosition );
     855             :             }
     856           0 :             catch( const RuntimeException& ) { throw; }
     857           0 :             catch( const SQLException& ) { throw; }
     858           0 :             catch( const Exception& )
     859             :             {
     860           0 :                 throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
     861           0 :             }
     862             :         }
     863           0 :         break;
     864             :         default:
     865           0 :             throw IllegalArgumentException( FRM_RES_STRING( RID_STR_FEATURE_UNKNOWN ), *this, 1 );
     866           0 :         }   // switch
     867             :     }
     868             : 
     869             : 
     870           0 :     sal_Bool SAL_CALL FormOperations::commitCurrentRecord( sal_Bool& _out_rRecordInserted ) throw (RuntimeException, SQLException, std::exception)
     871             :     {
     872           0 :         MethodGuard aGuard( *this );
     873           0 :         _out_rRecordInserted = sal_False;
     874             : 
     875           0 :         return impl_commitCurrentRecord_throw( &_out_rRecordInserted );
     876             :     }
     877             : 
     878             : 
     879           0 :     bool FormOperations::impl_commitCurrentRecord_throw( sal_Bool* _pRecordInserted ) const
     880             :     {
     881             :         DBG_ASSERT( m_nMethodNestingLevel, "FormOperations::impl_commitCurrentRecord_throw: to be called within a MethodGuard'ed section only!" );
     882             : 
     883           0 :         if ( !impl_hasCursor_nothrow() )
     884           0 :             return false;
     885             : 
     886             :         // nothing to do if the record is not modified
     887           0 :         bool bResult = !impl_isModifiedRow_throw();
     888           0 :         if ( !bResult )
     889             :         {
     890             :             // insert respectively update the row
     891           0 :             if ( impl_isInsertionRow_throw() )
     892             :             {
     893           0 :                 m_xUpdateCursor->insertRow();
     894           0 :                 if ( _pRecordInserted )
     895           0 :                     *_pRecordInserted = sal_True;
     896             :             }
     897             :             else
     898           0 :                 m_xUpdateCursor->updateRow();
     899           0 :             bResult = true;
     900             :         }
     901           0 :         return bResult;
     902             :     }
     903             : 
     904             : 
     905           3 :     sal_Bool SAL_CALL FormOperations::commitCurrentControl() throw (RuntimeException, SQLException, std::exception)
     906             :     {
     907           3 :         MethodGuard aGuard( *this );
     908           3 :         return impl_commitCurrentControl_throw();
     909             :     }
     910             : 
     911             : 
     912           3 :     bool FormOperations::impl_commitCurrentControl_throw() const
     913             :     {
     914             :         DBG_ASSERT( m_nMethodNestingLevel, "FormOperations::impl_commitCurrentControl_throw: to be called within a MethodGuard'ed section only!" );
     915             :         OSL_PRECOND( m_xController.is(), "FormOperations::commitCurrentControl: no controller!" );
     916           3 :         if ( !m_xController.is() )
     917           0 :             return false;
     918             : 
     919           3 :         bool bSuccess = false;
     920             :         try
     921             :         {
     922           3 :             Reference< XControl > xCurrentControl( m_xController->getCurrentControl() );
     923             : 
     924             :             // check whether the control is locked
     925           6 :             Reference< XBoundControl > xCheckLock( xCurrentControl, UNO_QUERY );
     926           3 :             bool bControlIsLocked = xCheckLock.is() && xCheckLock->getLock();
     927             : 
     928             :             // commit if necessary
     929           3 :             bSuccess = true;
     930           3 :             if ( xCurrentControl.is() && !bControlIsLocked )
     931             :             {
     932             :                 // both the control and its model can be committable, so try both
     933           3 :                 Reference< XBoundComponent > xBound( xCurrentControl, UNO_QUERY );
     934           3 :                 if ( !xBound.is() )
     935           3 :                     xBound.set(xCurrentControl->getModel(), css::uno::UNO_QUERY);
     936             :                 // and now really commit
     937           3 :                 if ( xBound.is() )
     938           0 :                     bSuccess = xBound->commit();
     939           3 :             }
     940             : 
     941             :         }
     942           0 :         catch( const RuntimeException& ) { throw; }
     943           0 :         catch( const SQLException& ) { throw; }
     944           0 :         catch( const Exception& )
     945             :         {
     946             :             DBG_UNHANDLED_EXCEPTION();
     947           0 :             bSuccess = false;
     948             :         }
     949             : 
     950           3 :         return bSuccess;
     951             :     }
     952             : 
     953             : 
     954           0 :     sal_Bool SAL_CALL FormOperations::isInsertionRow() throw (RuntimeException, WrappedTargetException, std::exception)
     955             :     {
     956           0 :         bool bIs = false;
     957             :         try
     958             :         {
     959           0 :             bIs = impl_isInsertionRow_throw();
     960             :         }
     961           0 :         catch( const RuntimeException& ) { throw; }
     962           0 :         catch( const Exception& )
     963             :         {
     964           0 :             throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
     965             :         }
     966           0 :         return bIs;
     967             :     }
     968             : 
     969             : 
     970           3 :     sal_Bool SAL_CALL FormOperations::isModifiedRow() throw (RuntimeException, WrappedTargetException, std::exception)
     971             :     {
     972           3 :         bool bIs = false;
     973             :         try
     974             :         {
     975           3 :             bIs = impl_isModifiedRow_throw();
     976             :         }
     977           0 :         catch( const RuntimeException& ) { throw; }
     978           0 :         catch( const Exception& )
     979             :         {
     980           0 :             throw WrappedTargetException( OUString(), *this, ::cppu::getCaughtException() );
     981             :         }
     982           3 :         return bIs;
     983             :     }
     984             : 
     985             : 
     986           0 :     void SAL_CALL FormOperations::cursorMoved( const EventObject& /*_Event*/ ) throw (RuntimeException, std::exception)
     987             :     {
     988           0 :         MethodGuard aGuard( *this );
     989           0 :         m_bActiveControlModified = false;
     990             : 
     991           0 :         impl_invalidateAllSupportedFeatures_nothrow( aGuard );
     992           0 :     }
     993             : 
     994             : 
     995           0 :     void SAL_CALL FormOperations::rowChanged( const EventObject& /*_Event*/ ) throw (RuntimeException, std::exception)
     996             :     {
     997             :         // not interested in
     998           0 :     }
     999             : 
    1000             : 
    1001           0 :     void SAL_CALL FormOperations::rowSetChanged( const EventObject& /*_Event*/ ) throw (RuntimeException, std::exception)
    1002             :     {
    1003             :         // not interested in
    1004           0 :     }
    1005             : 
    1006             : 
    1007           0 :     void SAL_CALL FormOperations::modified( const EventObject& /*_Source*/ ) throw( RuntimeException, std::exception )
    1008             :     {
    1009           0 :         MethodGuard aGuard( *this );
    1010             : 
    1011             :         OSL_ENSURE( m_xCursor.is(), "FormOperations::modified: already disposed!" );
    1012           0 :         if ( !m_bActiveControlModified )
    1013             :         {
    1014           0 :             m_bActiveControlModified = true;
    1015           0 :             impl_invalidateModifyDependentFeatures_nothrow( aGuard );
    1016           0 :         }
    1017           0 :     }
    1018             : 
    1019             : 
    1020           0 :     void SAL_CALL FormOperations::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException, std::exception)
    1021             :     {
    1022           0 :         MethodGuard aGuard( *this );
    1023             : 
    1024           0 :         if ( m_xCursor.is() && ( m_xCursor == _rEvent.Source ) )
    1025             :         {
    1026           0 :             if  ( ( _rEvent.PropertyName == PROPERTY_ISMODIFIED )
    1027           0 :                || ( _rEvent.PropertyName == PROPERTY_ISNEW )
    1028             :                 )
    1029             :             {
    1030           0 :                 bool bIs = false;
    1031           0 :                 if ( ( _rEvent.NewValue >>= bIs ) && !bIs )
    1032           0 :                     m_bActiveControlModified = false;
    1033             :             }
    1034           0 :             impl_invalidateAllSupportedFeatures_nothrow( aGuard );
    1035             :         }
    1036             : 
    1037           0 :         if ( m_xParser.is() && ( m_xCursor == _rEvent.Source ) )
    1038             :         {
    1039             :             try
    1040             :             {
    1041           0 :                 OUString sNewValue;
    1042           0 :                 _rEvent.NewValue >>= sNewValue;
    1043           0 :                 if ( _rEvent.PropertyName == PROPERTY_ACTIVECOMMAND )
    1044             :                 {
    1045           0 :                     m_xParser->setElementaryQuery( sNewValue );
    1046             :                 }
    1047           0 :                 else if ( _rEvent.PropertyName == PROPERTY_FILTER )
    1048             :                 {
    1049           0 :                     if ( m_xParser->getFilter() != sNewValue )
    1050           0 :                         m_xParser->setFilter( sNewValue );
    1051             :                 }
    1052           0 :                 else if ( _rEvent.PropertyName == PROPERTY_SORT )
    1053             :                 {
    1054           0 :                     _rEvent.NewValue >>= sNewValue;
    1055           0 :                     if ( m_xParser->getOrder() != sNewValue )
    1056           0 :                         m_xParser->setOrder( sNewValue );
    1057           0 :                 }
    1058             :             }
    1059           0 :             catch( const Exception& )
    1060             :             {
    1061             :                 OSL_FAIL( "FormOperations::propertyChange: caught an exception while updating the parser!" );
    1062             :             }
    1063           0 :             impl_invalidateAllSupportedFeatures_nothrow( aGuard );
    1064           0 :         }
    1065           0 :     }
    1066             : 
    1067             : 
    1068          95 :     void SAL_CALL FormOperations::disposing( const EventObject& /*_Source*/ ) throw (RuntimeException, std::exception)
    1069             :     {
    1070             :         // TODO: should we react on this? Or is this the responsibility of our owner to dispose us?
    1071          95 :     }
    1072             : 
    1073             : 
    1074          96 :     void SAL_CALL FormOperations::disposing()
    1075             :     {
    1076          96 :         ::osl::MutexGuard aGuard( m_aMutex );
    1077             : 
    1078          96 :         impl_disposeParser_nothrow();
    1079             : 
    1080             :         try
    1081             :         {
    1082             :             // revoke various listeners
    1083          96 :             if ( m_xCursor.is() )
    1084          96 :                 m_xCursor->removeRowSetListener( this );
    1085             : 
    1086          96 :             if ( m_xCursorProperties.is() )
    1087             :             {
    1088          96 :                 m_xCursorProperties->removePropertyChangeListener( PROPERTY_ISMODIFIED,this );
    1089          96 :                 m_xCursorProperties->removePropertyChangeListener( PROPERTY_ISNEW, this );
    1090             :             }
    1091             : 
    1092          96 :             Reference< XModifyBroadcaster > xBroadcaster( m_xController, UNO_QUERY );
    1093          96 :             if ( xBroadcaster.is() )
    1094          96 :                 xBroadcaster->removeModifyListener( this );
    1095             :         }
    1096           0 :         catch( const Exception& )
    1097             :         {
    1098             :             DBG_UNHANDLED_EXCEPTION();
    1099             :         }
    1100             : 
    1101          96 :         m_xController.clear();
    1102          96 :         m_xCursor.clear();
    1103          96 :         m_xUpdateCursor.clear();
    1104          96 :         m_xCursorProperties.clear();
    1105          96 :         m_xLoadableForm.clear();
    1106          96 :         m_xFeatureInvalidation.clear();
    1107             : 
    1108          96 :         m_bActiveControlModified = true;
    1109          96 :     }
    1110             : 
    1111             : 
    1112          99 :     void FormOperations::impl_checkDisposed_throw() const
    1113             :     {
    1114          99 :         if ( impl_isDisposed_nothrow() )
    1115           0 :             throw DisposedException( OUString(), *const_cast< FormOperations* >( this ) );
    1116          99 :     }
    1117             : 
    1118             : 
    1119          96 :     void FormOperations::impl_initFromController_throw()
    1120             :     {
    1121             :         OSL_PRECOND( m_xController.is(), "FormOperations::impl_initFromController_throw: invalid controller!" );
    1122          96 :         m_xCursor.set(m_xController->getModel(), css::uno::UNO_QUERY);
    1123          96 :         if ( !m_xCursor.is() )
    1124           0 :             throw IllegalArgumentException( OUString(), *this, 0 );
    1125             : 
    1126          96 :         impl_initFromForm_throw();
    1127             : 
    1128          96 :         Reference< XModifyBroadcaster > xBroadcaster( m_xController, UNO_QUERY );
    1129          96 :         if ( xBroadcaster.is() )
    1130          96 :             xBroadcaster->addModifyListener( this );
    1131          96 :     }
    1132             : 
    1133             : 
    1134          96 :     void FormOperations::impl_initFromForm_throw()
    1135             :     {
    1136             :         OSL_PRECOND( m_xCursor.is(), "FormOperations::impl_initFromForm_throw: invalid form!" );
    1137          96 :         m_xCursorProperties.set(m_xCursor, css::uno::UNO_QUERY);
    1138          96 :         m_xUpdateCursor.set(m_xCursor, css::uno::UNO_QUERY);
    1139          96 :         m_xLoadableForm.set(m_xCursor, css::uno::UNO_QUERY);
    1140             : 
    1141          96 :         if ( !m_xCursor.is() || !m_xCursorProperties.is() || !m_xLoadableForm.is() )
    1142           0 :             throw IllegalArgumentException( OUString(), *this, 0 );
    1143             : 
    1144          96 :         m_xCursor->addRowSetListener( this );
    1145          96 :         m_xCursorProperties->addPropertyChangeListener( PROPERTY_ISMODIFIED,this );
    1146          96 :         m_xCursorProperties->addPropertyChangeListener( PROPERTY_ISNEW, this );
    1147          96 :     }
    1148             : 
    1149             : 
    1150          96 :     void FormOperations::createWithFormController( const Reference< XFormController >& _rxController )
    1151             :     {
    1152          96 :         m_xController = _rxController;
    1153          96 :         if ( !m_xController.is() )
    1154           0 :             throw IllegalArgumentException( OUString(), *this, 0 );
    1155             : 
    1156          96 :         impl_initFromController_throw();
    1157             : 
    1158          96 :         m_bConstructed = true;
    1159          96 :     }
    1160             : 
    1161             : 
    1162           0 :     void FormOperations::createWithForm( const Reference< XForm >& _rxForm )
    1163             :     {
    1164           0 :         m_xCursor.set(_rxForm, css::uno::UNO_QUERY);
    1165           0 :         if ( !m_xCursor.is() )
    1166           0 :             throw IllegalArgumentException( OUString(), *this, 0 );
    1167             : 
    1168           0 :         impl_initFromForm_throw();
    1169             : 
    1170           0 :         m_bConstructed = true;
    1171           0 :     }
    1172             : 
    1173             : 
    1174           0 :     void FormOperations::impl_invalidateAllSupportedFeatures_nothrow( MethodGuard& _rClearForCallback ) const
    1175             :     {
    1176           0 :         if ( !m_xFeatureInvalidation.is() )
    1177             :             // nobody's interested in ...
    1178           0 :             return;
    1179             : 
    1180           0 :         Reference< XFeatureInvalidation > xInvalidation = m_xFeatureInvalidation;
    1181           0 :         _rClearForCallback.clear();
    1182           0 :         xInvalidation->invalidateAllFeatures();
    1183             :     }
    1184             : 
    1185             : 
    1186           0 :     void FormOperations::impl_invalidateModifyDependentFeatures_nothrow( MethodGuard& _rClearForCallback ) const
    1187             :     {
    1188           0 :         if ( !m_xFeatureInvalidation.is() )
    1189             :             // nobody's interested in ...
    1190           0 :             return;
    1191             : 
    1192           0 :         static Sequence< sal_Int16 > s_aModifyDependentFeatures;
    1193           0 :         if ( s_aModifyDependentFeatures.getLength() == 0 )
    1194             :         {
    1195             :             sal_Int16 pModifyDependentFeatures[] =
    1196             :             {
    1197             :                 FormFeature::MoveToNext,
    1198             :                 FormFeature::MoveToInsertRow,
    1199             :                 FormFeature::SaveRecordChanges,
    1200             :                 FormFeature::UndoRecordChanges
    1201           0 :             };
    1202           0 :             size_t nFeatureCount = SAL_N_ELEMENTS( pModifyDependentFeatures );
    1203           0 :             s_aModifyDependentFeatures = Sequence< sal_Int16 >( pModifyDependentFeatures, nFeatureCount );
    1204             :         }
    1205             : 
    1206           0 :         Reference< XFeatureInvalidation > xInvalidation = m_xFeatureInvalidation;
    1207           0 :         _rClearForCallback.clear();
    1208             : 
    1209           0 :         xInvalidation->invalidateFeatures( s_aModifyDependentFeatures );
    1210             :     }
    1211             : 
    1212             : 
    1213           0 :     void FormOperations::impl_ensureInitializedParser_nothrow()
    1214             :     {
    1215             :         OSL_PRECOND( m_xCursorProperties.is(), "FormOperations::impl_ensureInitializedParser_nothrow: we're disposed!" );
    1216           0 :         if ( m_bInitializedParser )
    1217           0 :             return;
    1218             : 
    1219             :         try
    1220             :         {
    1221           0 :             bool bUseEscapeProcessing = false;
    1222           0 :             m_xCursorProperties->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bUseEscapeProcessing;
    1223           0 :             if ( bUseEscapeProcessing )
    1224             :             {
    1225           0 :                 Reference< XMultiServiceFactory > xFactory( ::dbtools::getConnection( m_xCursor ), UNO_QUERY );
    1226           0 :                 if ( xFactory.is() )
    1227             :                 {
    1228           0 :                     m_xParser.set( xFactory->createInstance("com.sun.star.sdb.SingleSelectQueryComposer"), UNO_QUERY );
    1229             :                     OSL_ENSURE( m_xParser.is(), "FormOperations::impl_ensureInitializedParser_nothrow: factory did not create a parser for us!" );
    1230           0 :                 }
    1231             :             }
    1232             : 
    1233           0 :             if ( m_xParser.is() )
    1234             :             {
    1235           0 :                 if ( m_xLoadableForm.is() && m_xLoadableForm->isLoaded() )
    1236             :                 {
    1237           0 :                     OUString sStatement;
    1238           0 :                     OUString sFilter;
    1239           0 :                     OUString sSort;
    1240             : 
    1241           0 :                     m_xCursorProperties->getPropertyValue( PROPERTY_ACTIVECOMMAND   ) >>= sStatement;
    1242           0 :                     m_xCursorProperties->getPropertyValue( PROPERTY_FILTER          ) >>= sFilter;
    1243           0 :                     m_xCursorProperties->getPropertyValue( PROPERTY_SORT            ) >>= sSort;
    1244             : 
    1245           0 :                     m_xParser->setElementaryQuery( sStatement );
    1246           0 :                     m_xParser->setFilter         ( sFilter    );
    1247           0 :                     m_xParser->setOrder          ( sSort      );
    1248             :                 }
    1249             : 
    1250             :                 // start listening at the order/sort properties at the form, so
    1251             :                 // we can keep our parser in sync
    1252           0 :                 m_xCursorProperties->addPropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );
    1253           0 :                 m_xCursorProperties->addPropertyChangeListener( PROPERTY_FILTER, this );
    1254           0 :                 m_xCursorProperties->addPropertyChangeListener( PROPERTY_SORT, this );
    1255             :             }
    1256             :         }
    1257           0 :         catch( const Exception& )
    1258             :         {
    1259             :             OSL_FAIL( "FormOperations::impl_ensureInitializedParser_nothrow: caught an exception!" );
    1260             :         }
    1261             : 
    1262           0 :         m_bInitializedParser = true;
    1263             :     }
    1264             : 
    1265             : 
    1266          96 :     void FormOperations::impl_disposeParser_nothrow()
    1267             :     {
    1268             :         try
    1269             :         {
    1270             :             // if we have a parser (and a cursor), then we're listening at the cursor's
    1271             :             // properties to keep the parser in sync with the cursor
    1272          96 :             if ( m_xParser.is() && m_xCursorProperties.is() )
    1273             :             {
    1274           0 :                 m_xCursorProperties->removePropertyChangeListener( PROPERTY_FILTER, this );
    1275           0 :                 m_xCursorProperties->removePropertyChangeListener( PROPERTY_ACTIVECOMMAND, this );
    1276           0 :                 m_xCursorProperties->removePropertyChangeListener( PROPERTY_SORT, this );
    1277             :             }
    1278             : 
    1279          96 :             Reference< XComponent > xParserComp( m_xParser, UNO_QUERY );
    1280          96 :             if ( xParserComp.is() )
    1281           0 :                 xParserComp->dispose();
    1282          96 :             m_xParser.clear();
    1283             : 
    1284          96 :             m_bInitializedParser = false;
    1285             :         }
    1286           0 :         catch( const Exception& )
    1287             :         {
    1288             :             OSL_FAIL( "FormOperations::impl_disposeParser_nothrow: caught an exception!" );
    1289             :         }
    1290          96 :     }
    1291             : 
    1292             : 
    1293           0 :     bool FormOperations::impl_canMoveLeft_throw( ) const
    1294             :     {
    1295           0 :         if ( !impl_hasCursor_nothrow() )
    1296           0 :             return false;
    1297             : 
    1298           0 :         return impl_getRowCount_throw() && ( !m_xCursor->isFirst() || impl_isInsertionRow_throw() );
    1299             :     }
    1300             : 
    1301             : 
    1302           0 :     bool FormOperations::impl_canMoveRight_throw( ) const
    1303             :     {
    1304           0 :         if ( !impl_hasCursor_nothrow() )
    1305           0 :             return false;
    1306             : 
    1307           0 :         bool bIsNew = impl_isInsertionRow_throw();
    1308             : 
    1309           0 :         if ( impl_getRowCount_throw() && !m_xCursor->isLast() && !bIsNew )
    1310           0 :             return true;
    1311             : 
    1312           0 :         if ( ::dbtools::canInsert( m_xCursorProperties ) )
    1313           0 :             if ( !bIsNew || impl_isModifiedRow_throw() )
    1314           0 :                 return true;
    1315             : 
    1316           0 :         if ( bIsNew && m_bActiveControlModified )
    1317           0 :             return true;
    1318             : 
    1319           0 :         return false;
    1320             :     }
    1321             : 
    1322             : 
    1323           0 :     bool FormOperations::impl_isInsertionRow_throw() const
    1324             :     {
    1325           0 :         return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ISNEW, false );
    1326             :     }
    1327             : 
    1328             : 
    1329           0 :     sal_Int32 FormOperations::impl_getRowCount_throw() const
    1330             :     {
    1331           0 :         return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ROWCOUNT, (sal_Int32)0 );
    1332             :     }
    1333             : 
    1334           0 :     bool FormOperations::impl_isRowCountFinal_throw() const
    1335             :     {
    1336           0 :         return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ROWCOUNTFINAL, false );
    1337             :     }
    1338             : 
    1339             : 
    1340           3 :     bool FormOperations::impl_isModifiedRow_throw() const
    1341             :     {
    1342           3 :         return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_ISMODIFIED, false );
    1343             :     }
    1344             : 
    1345             : 
    1346           0 :     bool FormOperations::impl_isParseable_throw() const
    1347             :     {
    1348           0 :         const_cast< FormOperations* >( this )->impl_ensureInitializedParser_nothrow();
    1349           0 :         return m_xParser.is() && !m_xParser->getQuery().isEmpty();
    1350             :     }
    1351             : 
    1352             : 
    1353           0 :     bool FormOperations::impl_hasFilterOrOrder_throw() const
    1354             :     {
    1355           0 :         return impl_isParseable_throw() && ( !m_xParser->getFilter().isEmpty() || !m_xParser->getOrder().isEmpty() );
    1356             :     }
    1357             : 
    1358             : 
    1359           0 :     bool FormOperations::impl_isInsertOnlyForm_throw() const
    1360             :     {
    1361           0 :         return lcl_safeGetPropertyValue_throw( m_xCursorProperties, PROPERTY_INSERTONLY, true );
    1362             :     }
    1363             : 
    1364             : 
    1365           0 :     Reference< XControlModel > FormOperations::impl_getCurrentControlModel_throw() const
    1366             :     {
    1367           0 :         Reference< XControl > xControl( m_xController->getCurrentControl() );
    1368             : 
    1369             :         // special handling for grid controls
    1370           0 :         Reference< XGrid > xGrid( xControl, UNO_QUERY );
    1371           0 :         Reference< XControlModel > xControlModel;
    1372             : 
    1373           0 :         if ( xGrid.is() )
    1374             :         {
    1375           0 :             Reference< XIndexAccess > xColumns( xControl->getModel(), UNO_QUERY_THROW );
    1376           0 :             sal_Int16 nCurrentPos = xGrid->getCurrentColumnPosition();
    1377           0 :             nCurrentPos = impl_gridView2ModelPos_nothrow( xColumns, nCurrentPos );
    1378             : 
    1379           0 :             if ( nCurrentPos != (sal_Int16)-1 )
    1380           0 :                 xColumns->getByIndex( nCurrentPos ) >>= xControlModel;
    1381             :         }
    1382           0 :         else if ( xControl.is() )
    1383             :         {
    1384           0 :             xControlModel = xControl->getModel();
    1385             :         }
    1386           0 :         return xControlModel;
    1387             :     }
    1388             : 
    1389             : 
    1390           0 :     Reference< XPropertySet > FormOperations::impl_getCurrentBoundField_nothrow( ) const
    1391             :     {
    1392             :         OSL_PRECOND( m_xController.is(), "FormOperations::impl_getCurrentBoundField_nothrow: no controller -> no control!" );
    1393           0 :         if ( !m_xController.is() )
    1394           0 :             return NULL;
    1395             : 
    1396           0 :         Reference< XPropertySet > xField;
    1397             :         try
    1398             :         {
    1399           0 :             Reference< XPropertySet > xControlModel( impl_getCurrentControlModel_throw(), UNO_QUERY );
    1400             : 
    1401           0 :             if ( xControlModel.is() && ::comphelper::hasProperty( PROPERTY_BOUNDFIELD, xControlModel ) )
    1402           0 :                 xControlModel->getPropertyValue( PROPERTY_BOUNDFIELD ) >>= xField;
    1403             : 
    1404             :         }
    1405           0 :         catch( const Exception& )
    1406             :         {
    1407             :             DBG_UNHANDLED_EXCEPTION();
    1408             :         }
    1409             : 
    1410           0 :         return xField;
    1411             :     }
    1412             : 
    1413             : 
    1414           0 :     sal_Int16 FormOperations::impl_gridView2ModelPos_nothrow( const Reference< XIndexAccess >& _rxColumns, sal_Int16 _nViewPos )
    1415             :     {
    1416             :         OSL_PRECOND( _rxColumns.is(), "FormOperations::impl_gridView2ModelPos_nothrow: invalid columns container!" );
    1417             :         try
    1418             :         {
    1419             :             // loop through all columns
    1420           0 :             sal_Int16 col = 0;
    1421           0 :             Reference< XPropertySet > xCol;
    1422           0 :             bool bHidden( false );
    1423           0 :             for ( col = 0; col < _rxColumns->getCount(); ++col )
    1424             :             {
    1425           0 :                 _rxColumns->getByIndex( col ) >>= xCol;
    1426           0 :                 OSL_VERIFY( xCol->getPropertyValue( PROPERTY_HIDDEN ) >>= bHidden );
    1427           0 :                 if ( bHidden )
    1428           0 :                     continue;
    1429             : 
    1430             :                 // for every visible col : if nViewPos is greater zero, decrement it, else we
    1431             :                 // have found the model position
    1432           0 :                 if ( !_nViewPos )
    1433           0 :                     break;
    1434             :                 else
    1435           0 :                     --_nViewPos;
    1436             :             }
    1437           0 :             if ( col < _rxColumns->getCount() )
    1438           0 :                 return col;
    1439             :         }
    1440           0 :         catch( const Exception& )
    1441             :         {
    1442             :             DBG_UNHANDLED_EXCEPTION();
    1443             :         }
    1444           0 :         return (sal_Int16)-1;
    1445             :     }
    1446             : 
    1447             : 
    1448           0 :     bool FormOperations::impl_moveLeft_throw( ) const
    1449             :     {
    1450             :         OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveLeft_throw: no cursor!" );
    1451           0 :         if ( !impl_hasCursor_nothrow() )
    1452           0 :             return false;
    1453             : 
    1454           0 :         sal_Bool bRecordInserted = sal_False;
    1455           0 :         bool bSuccess = impl_commitCurrentRecord_throw( &bRecordInserted );
    1456             : 
    1457           0 :         if ( !bSuccess )
    1458           0 :             return false;
    1459             : 
    1460           0 :         if ( bRecordInserted )
    1461             :         {
    1462             :             // retrieve the bookmark of the new record and move to the record preceding this bookmark
    1463           0 :             Reference< XRowLocate > xLocate( m_xCursor, UNO_QUERY );
    1464             :             OSL_ENSURE( xLocate.is(), "FormOperations::impl_moveLeft_throw: no XRowLocate!" );
    1465           0 :             if ( xLocate.is() )
    1466           0 :                 xLocate->moveRelativeToBookmark( xLocate->getBookmark(), -1 );
    1467             :         }
    1468             :         else
    1469             :         {
    1470           0 :             if ( impl_isInsertionRow_throw() )
    1471             :             {
    1472             :                 // we assume that the inserted record is now the last record in the
    1473             :                 // result set
    1474           0 :                 m_xCursor->last();
    1475             :             }
    1476             :             else
    1477           0 :                 m_xCursor->previous();
    1478             :         }
    1479             : 
    1480           0 :         return true;
    1481             :     }
    1482             : 
    1483             : 
    1484           0 :     bool FormOperations::impl_moveRight_throw( ) const
    1485             :     {
    1486             :         OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_moveRight_throw: no cursor!" );
    1487           0 :         if ( !impl_hasCursor_nothrow() )
    1488           0 :             return false;
    1489             : 
    1490           0 :         sal_Bool bRecordInserted = sal_False;
    1491           0 :         bool bSuccess = impl_commitCurrentRecord_throw( &bRecordInserted );
    1492             : 
    1493           0 :         if ( !bSuccess )
    1494           0 :             return false;
    1495             : 
    1496           0 :         if ( bRecordInserted )
    1497             :         {
    1498             :             // go to insert row
    1499           0 :             m_xUpdateCursor->moveToInsertRow();
    1500             :         }
    1501             :         else
    1502             :         {
    1503           0 :             if ( m_xCursor->isLast() )
    1504           0 :                 m_xUpdateCursor->moveToInsertRow();
    1505             :             else
    1506           0 :                 (void)m_xCursor->next();
    1507             :         }
    1508             : 
    1509           0 :         return true;
    1510             :     }
    1511             : 
    1512             : 
    1513           0 :     void FormOperations::impl_resetAllControls_nothrow() const
    1514             :     {
    1515           0 :         Reference< XIndexAccess > xContainer( m_xCursor, UNO_QUERY );
    1516           0 :         if ( !xContainer.is() )
    1517           0 :             return;
    1518             : 
    1519             :         try
    1520             :         {
    1521           0 :             Reference< XReset > xReset;
    1522           0 :             sal_Int32 nCount( xContainer->getCount() );
    1523           0 :             for ( sal_Int32 i = 0; i < nCount; ++i )
    1524             :             {
    1525           0 :                 if ( xContainer->getByIndex( i ) >>= xReset )
    1526             :                 {
    1527             :                     // no resets on sub forms
    1528           0 :                     Reference< XForm > xAsForm( xReset, UNO_QUERY );
    1529           0 :                     if ( !xAsForm.is() )
    1530           0 :                         xReset->reset();
    1531             :                 }
    1532           0 :             }
    1533             :         }
    1534           0 :         catch( const Exception& )
    1535             :         {
    1536             :             DBG_UNHANDLED_EXCEPTION();
    1537           0 :         }
    1538             :     }
    1539             : 
    1540             : 
    1541           0 :     void FormOperations::impl_executeAutoSort_throw( bool _bUp ) const
    1542             :     {
    1543             :         OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeAutoSort_throw: need a controller for this!" );
    1544             :         OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoSort_throw: need a cursor for this!" );
    1545             :         OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoSort_throw: need a parseable statement for this!" );
    1546           0 :         if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
    1547           0 :             return;
    1548             : 
    1549             :         try
    1550             :         {
    1551           0 :             Reference< XControl > xControl = m_xController->getCurrentControl();
    1552           0 :             if ( !xControl.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
    1553           0 :                 return;
    1554             : 
    1555           0 :             Reference< XPropertySet > xBoundField( impl_getCurrentBoundField_nothrow() );
    1556           0 :             if ( !xBoundField.is() )
    1557           0 :                 return;
    1558             : 
    1559           0 :             OUString sOriginalSort;
    1560           0 :             m_xCursorProperties->getPropertyValue( PROPERTY_SORT ) >>= sOriginalSort;
    1561             : 
    1562             :             // automatic sort by field is expected to always resets the previous sort order
    1563           0 :             m_xParser->setOrder( OUString() );
    1564             : 
    1565           0 :             impl_appendOrderByColumn_throw aAction(this, xBoundField, _bUp);
    1566           0 :             impl_doActionInSQLContext_throw(aAction, RID_STR_COULD_NOT_SET_ORDER );
    1567             : 
    1568           0 :             WaitObject aWO( NULL );
    1569             :             try
    1570             :             {
    1571           0 :                 m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
    1572           0 :                 m_xLoadableForm->reload();
    1573             :             }
    1574           0 :             catch( const Exception& )
    1575             :             {
    1576             :                 OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: caught an exception while setting the parser properties!" );
    1577             :             }
    1578             : 
    1579             : 
    1580           0 :             if ( !m_xLoadableForm->isLoaded() )
    1581             :             {   // something went wrong -> restore the original state
    1582             :                 try
    1583             :                 {
    1584           0 :                     m_xParser->setOrder( sOriginalSort );
    1585           0 :                     m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
    1586           0 :                     m_xLoadableForm->reload();
    1587             :                 }
    1588           0 :                 catch( const Exception& )
    1589             :                 {
    1590             :                     OSL_FAIL( "FormOperations::impl_executeAutoSort_throw: could not reset the form to it's original state!" );
    1591             :                 }
    1592             : 
    1593           0 :             }
    1594             :         }
    1595           0 :         catch( const RuntimeException& ) { throw; }
    1596           0 :         catch( const SQLException& ) { throw; }
    1597           0 :         catch( const Exception& )
    1598             :         {
    1599           0 :             throw WrappedTargetException( OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
    1600             :         }
    1601             :     }
    1602             : 
    1603             : 
    1604           0 :     void FormOperations::impl_executeAutoFilter_throw( ) const
    1605             :     {
    1606             :         OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeAutoFilter_throw: need a controller for this!" );
    1607             :         OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeAutoFilter_throw: need a cursor for this!" );
    1608             :         OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeAutoFilter_throw: need a parseable statement for this!" );
    1609           0 :         if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
    1610           0 :             return;
    1611             : 
    1612             :         try
    1613             :         {
    1614           0 :             Reference< XControl > xControl = m_xController->getCurrentControl();
    1615           0 :             if ( !xControl.is() || !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
    1616           0 :                 return;
    1617             : 
    1618           0 :             Reference< XPropertySet > xBoundField( impl_getCurrentBoundField_nothrow() );
    1619           0 :             if ( !xBoundField.is() )
    1620           0 :                 return;
    1621             : 
    1622           0 :             OUString sOriginalFilter;
    1623           0 :             m_xCursorProperties->getPropertyValue( PROPERTY_FILTER ) >>= sOriginalFilter;
    1624           0 :             bool bApplied = true;
    1625           0 :             m_xCursorProperties->getPropertyValue( PROPERTY_APPLYFILTER ) >>= bApplied;
    1626             : 
    1627             :             // if we have a filter, but it's not applied, then we have to overwrite it, else append one
    1628           0 :             if ( !bApplied )
    1629           0 :                 m_xParser->setFilter( OUString() );
    1630             : 
    1631           0 :             impl_appendFilterByColumn_throw aAction(this, xBoundField);
    1632           0 :             impl_doActionInSQLContext_throw( aAction, RID_STR_COULD_NOT_SET_FILTER );
    1633             : 
    1634           0 :             WaitObject aWO( NULL );
    1635             :             try
    1636             :             {
    1637           0 :                 m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
    1638           0 :                 m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( true ) );
    1639             : 
    1640           0 :                 m_xLoadableForm->reload();
    1641             :             }
    1642           0 :             catch( const Exception& )
    1643             :             {
    1644             :                 OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: caught an exception while setting the parser properties!" );
    1645             :             }
    1646             : 
    1647             : 
    1648           0 :             if ( !m_xLoadableForm->isLoaded() )
    1649             :             {   // something went wrong -> restore the original state
    1650             :                 try
    1651             :                 {
    1652           0 :                     m_xParser->setOrder( sOriginalFilter );
    1653           0 :                     m_xCursorProperties->setPropertyValue( PROPERTY_APPLYFILTER, makeAny( bApplied ) );
    1654           0 :                     m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
    1655           0 :                     m_xLoadableForm->reload();
    1656             :                 }
    1657           0 :                 catch( const Exception& )
    1658             :                 {
    1659             :                     OSL_FAIL( "FormOperations::impl_executeAutoFilter_throw: could not reset the form to it's original state!" );
    1660             :                 }
    1661             : 
    1662           0 :             }
    1663             :         }
    1664           0 :         catch( const RuntimeException& ) { throw; }
    1665           0 :         catch( const SQLException& ) { throw; }
    1666           0 :         catch( const Exception& )
    1667             :         {
    1668           0 :             throw WrappedTargetException( OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
    1669             :         }
    1670             :     }
    1671             : 
    1672             : 
    1673           0 :     void FormOperations::impl_executeFilterOrSort_throw( bool _bFilter ) const
    1674             :     {
    1675             :         OSL_PRECOND( m_xController.is(), "FormOperations::impl_executeFilterOrSort_throw: need a controller for this!" );
    1676             :         OSL_PRECOND( impl_hasCursor_nothrow(), "FormOperations::impl_executeFilterOrSort_throw: need a cursor for this!" );
    1677             :         OSL_PRECOND( impl_isParseable_throw(), "FormOperations::impl_executeFilterOrSort_throw: need a parseable statement for this!" );
    1678           0 :         if ( !m_xController.is() || !impl_hasCursor_nothrow() || !impl_isParseable_throw() )
    1679           0 :             return;
    1680             : 
    1681           0 :         if ( !impl_commitCurrentControl_throw() || !impl_commitCurrentRecord_throw() )
    1682           0 :             return;
    1683             :         try
    1684             :         {
    1685           0 :             Reference< XExecutableDialog> xDialog;
    1686           0 :             if ( _bFilter )
    1687             :             {
    1688           0 :                 xDialog = com::sun::star::sdb::FilterDialog::createWithQuery(m_xContext, m_xParser, m_xCursor,
    1689           0 :                               Reference<com::sun::star::awt::XWindow>());
    1690             :             }
    1691             :             else
    1692             :             {
    1693           0 :                 xDialog = com::sun::star::sdb::OrderDialog::createWithQuery(m_xContext, m_xParser, m_xCursorProperties);
    1694             :             }
    1695             : 
    1696             : 
    1697           0 :             if ( RET_OK == xDialog->execute() )
    1698             :             {
    1699           0 :                 WaitObject aWO( NULL );
    1700           0 :                 if ( _bFilter )
    1701           0 :                     m_xCursorProperties->setPropertyValue( PROPERTY_FILTER, makeAny( m_xParser->getFilter() ) );
    1702             :                 else
    1703           0 :                     m_xCursorProperties->setPropertyValue( PROPERTY_SORT, makeAny( m_xParser->getOrder() ) );
    1704           0 :                 m_xLoadableForm->reload();
    1705           0 :             }
    1706             : 
    1707             :         }
    1708           0 :         catch( const RuntimeException& ) { throw; }
    1709           0 :         catch( const SQLException& ) { throw; }
    1710           0 :         catch( const Exception& )
    1711             :         {
    1712           0 :             throw WrappedTargetException( OUString(), *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
    1713             :         }
    1714             :     }
    1715             : 
    1716             : 
    1717             :     template < typename FunctObj >
    1718           0 :     void FormOperations::impl_doActionInSQLContext_throw( FunctObj f, sal_uInt16 _nErrorResourceId ) const
    1719             :     {
    1720             :         try
    1721             :         {
    1722           0 :             f();
    1723             :         }
    1724             : #if HAVE_FEATURE_DBCONNECTIVITY
    1725           0 :         catch( const SQLException& e )
    1726             :         {
    1727             :             (void)e;
    1728           0 :             if ( !_nErrorResourceId )
    1729             :                 // no information to prepend
    1730           0 :                 throw;
    1731             : 
    1732           0 :             SQLExceptionInfo aInfo( ::cppu::getCaughtException() );
    1733           0 :             OUString sAdditionalError( FRM_RES_STRING( _nErrorResourceId ) );
    1734           0 :             aInfo.prepend( sAdditionalError );
    1735           0 :             aInfo.doThrow();
    1736             :         }
    1737             : #endif
    1738           0 :         catch( const RuntimeException& ) { throw; }
    1739           0 :         catch( const Exception& )
    1740             :         {
    1741           0 :             OUString sAdditionalError( FRM_RES_STRING( _nErrorResourceId ) );
    1742           0 :             throw WrappedTargetException( sAdditionalError, *const_cast< FormOperations* >( this ), ::cppu::getCaughtException() );
    1743             :         }
    1744           0 :     }
    1745             : 
    1746             : 
    1747             : } // namespace frm
    1748             : 
    1749             : 
    1750             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
    1751          96 : com_sun_star_comp_forms_FormOperations_get_implementation(css::uno::XComponentContext* context,
    1752             :                                                           css::uno::Sequence<css::uno::Any> const &)
    1753             : {
    1754          96 :     return cppu::acquire(new frm::FormOperations(context));
    1755             : }
    1756             : 
    1757             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11