LCOV - code coverage report
Current view: top level - forms/source/runtime - formoperations.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 111 779 14.2 %
Date: 2014-11-03 Functions: 23 74 31.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10