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

Generated by: LCOV version 1.10