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

Generated by: LCOV version 1.10