commit subforms before moving in parent form
else, all pending changes in the subforms are lost Change-Id: I82b0967729c71a4f01eff9f823a1961fad999679
This commit is contained in:
@@ -45,11 +45,11 @@ namespace frm
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
OErrorBroadcaster::~OErrorBroadcaster( )
|
OErrorBroadcaster::~OErrorBroadcaster( )
|
||||||
{
|
{
|
||||||
SAL_WARN_IF( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose, "forms",
|
SAL_WARN_IF( !m_rBHelper.bDisposed && !m_rBHelper.bInDispose, "forms.component",
|
||||||
"OErrorBroadcaster::~OErrorBroadcaster: not disposed!" );
|
"OErrorBroadcaster::~OErrorBroadcaster: not disposed!" );
|
||||||
// herein, we don't have a chance to do the dispose ourself ....
|
// herein, we don't have a chance to do the dispose ourself ....
|
||||||
|
|
||||||
SAL_WARN_IF( m_aErrorListeners.getLength(), "forms",
|
SAL_WARN_IF( m_aErrorListeners.getLength(), "forms.component",
|
||||||
"OErrorBroadcaster::~OErrorBroadcaster: still have listeners!" );
|
"OErrorBroadcaster::~OErrorBroadcaster: still have listeners!" );
|
||||||
// either we're not disposed, or the derived class did not call our dispose from within their dispose
|
// either we're not disposed, or the derived class did not call our dispose from within their dispose
|
||||||
}
|
}
|
||||||
|
@@ -81,6 +81,7 @@ namespace frm
|
|||||||
using ::com::sun::star::sdbc::XRowSet;
|
using ::com::sun::star::sdbc::XRowSet;
|
||||||
using ::com::sun::star::sdbc::XResultSetUpdate;
|
using ::com::sun::star::sdbc::XResultSetUpdate;
|
||||||
using ::com::sun::star::form::runtime::XFormController;
|
using ::com::sun::star::form::runtime::XFormController;
|
||||||
|
using ::com::sun::star::form::runtime::XFormOperations;
|
||||||
using ::com::sun::star::form::runtime::XFeatureInvalidation;
|
using ::com::sun::star::form::runtime::XFeatureInvalidation;
|
||||||
using ::com::sun::star::form::runtime::FeatureState;
|
using ::com::sun::star::form::runtime::FeatureState;
|
||||||
using ::com::sun::star::lang::IllegalArgumentException;
|
using ::com::sun::star::lang::IllegalArgumentException;
|
||||||
@@ -452,8 +453,128 @@ namespace frm
|
|||||||
{
|
{
|
||||||
return ( _nFeature != FormFeature::TotalRecords );
|
return ( _nFeature != FormFeature::TotalRecords );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename TYPE >
|
||||||
|
TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const OUString& _rPropertyName, TYPE _Default )
|
||||||
|
{
|
||||||
|
TYPE value( _Default );
|
||||||
|
OSL_PRECOND( _rxProperties.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
|
||||||
|
if ( _rxProperties.is() )
|
||||||
|
OSL_VERIFY( _rxProperties->getPropertyValue( _rPropertyName ) >>= value );
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns false if parent should *abort* (user pressed cancel)
|
||||||
|
bool checkConfirmation(bool &needConfirmation, bool &shouldCommit)
|
||||||
|
{
|
||||||
|
if(needConfirmation)
|
||||||
|
{
|
||||||
|
// TODO: shouldn't this be done with an interaction handler?
|
||||||
|
QueryBox aQuery( NULL, WB_YES_NO_CANCEL | WB_DEF_YES, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW ) );
|
||||||
|
switch ( aQuery.Execute() )
|
||||||
|
{
|
||||||
|
case RET_NO:
|
||||||
|
shouldCommit = false;
|
||||||
|
// no break on purpose: don't ask again!
|
||||||
|
case RET_YES:
|
||||||
|
needConfirmation = false;
|
||||||
|
return true;
|
||||||
|
case RET_CANCEL:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool commit1Form(Reference< XFormController > xCntrl, bool &needConfirmation, bool &shouldCommit)
|
||||||
|
{
|
||||||
|
Reference< XFormOperations > xFrmOps(xCntrl->getFormOperations());
|
||||||
|
if (!xFrmOps->commitCurrentControl())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(xFrmOps->isModifiedRow())
|
||||||
|
{
|
||||||
|
if(!checkConfirmation(needConfirmation, shouldCommit))
|
||||||
|
return false;
|
||||||
|
sal_Bool _;
|
||||||
|
if (shouldCommit && !xFrmOps->commitCurrentRecord(_))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool commitFormAndSubforms(Reference< XFormController > xCntrl, bool needConfirmation)
|
||||||
|
{
|
||||||
|
bool shouldCommit(true);
|
||||||
|
assert(xCntrl.is());
|
||||||
|
Reference< XIndexAccess > xSubForms(xCntrl, UNO_QUERY);
|
||||||
|
assert(xSubForms.is());
|
||||||
|
if(xSubForms.is())
|
||||||
|
{
|
||||||
|
const sal_Int32 cnt = xSubForms->getCount();
|
||||||
|
for(int i=0; i < cnt; ++i)
|
||||||
|
{
|
||||||
|
Reference< XFormController > xSubForm(xSubForms->getByIndex(i), UNO_QUERY);
|
||||||
|
assert(xSubForm.is());
|
||||||
|
if (xSubForm.is())
|
||||||
|
{
|
||||||
|
if (!commit1Form(xSubForm, needConfirmation, shouldCommit))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!commit1Form(xCntrl, needConfirmation, shouldCommit))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool commit1Form(Reference< XForm > xFrm, bool &needConfirmation, bool &shouldCommit)
|
||||||
|
{
|
||||||
|
Reference< XPropertySet > xProps(xFrm, UNO_QUERY_THROW);
|
||||||
|
// nothing to do if the record is not modified
|
||||||
|
if(!lcl_safeGetPropertyValue_throw( xProps, PROPERTY_ISMODIFIED, false ))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(!checkConfirmation(needConfirmation, shouldCommit))
|
||||||
|
return false;
|
||||||
|
if(shouldCommit)
|
||||||
|
{
|
||||||
|
Reference< XResultSetUpdate > xUpd(xFrm, UNO_QUERY_THROW);
|
||||||
|
// insert respectively update the row
|
||||||
|
if ( lcl_safeGetPropertyValue_throw( xProps, PROPERTY_ISNEW, false ) )
|
||||||
|
xUpd->insertRow();
|
||||||
|
else
|
||||||
|
xUpd->updateRow();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool commitFormAndSubforms(Reference< XForm > xFrm, bool needConfirmation)
|
||||||
|
{
|
||||||
|
// No control... do what we can with the models
|
||||||
|
bool shouldCommit(true);
|
||||||
|
Reference< XIndexAccess > xFormComps(xFrm, UNO_QUERY_THROW);
|
||||||
|
assert( xFormComps.is() );
|
||||||
|
|
||||||
|
const sal_Int32 cnt = xFormComps->getCount();
|
||||||
|
for(int i=0; i < cnt; ++i)
|
||||||
|
{
|
||||||
|
Reference< XForm > xSubForm(xFormComps->getByIndex(i), UNO_QUERY);
|
||||||
|
if(xSubForm.is())
|
||||||
|
{
|
||||||
|
if(!commit1Form(xSubForm, needConfirmation, shouldCommit))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!commit1Form(xFrm, needConfirmation, shouldCommit))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
void SAL_CALL FormOperations::execute( ::sal_Int16 _nFeature ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException)
|
void SAL_CALL FormOperations::execute( ::sal_Int16 _nFeature ) throw (RuntimeException, IllegalArgumentException, SQLException, WrappedTargetException)
|
||||||
{
|
{
|
||||||
@@ -462,31 +583,25 @@ namespace frm
|
|||||||
|
|
||||||
if ( ( _nFeature != FormFeature::DeleteRecord ) && ( _nFeature != FormFeature::UndoRecordChanges ) )
|
if ( ( _nFeature != FormFeature::DeleteRecord ) && ( _nFeature != FormFeature::UndoRecordChanges ) )
|
||||||
{
|
{
|
||||||
// if we have a controller, commit the current control
|
|
||||||
|
|
||||||
if(m_xController.is())
|
if(m_xController.is())
|
||||||
if ( !impl_commitCurrentControl_throw() )
|
{
|
||||||
|
if(!commitFormAndSubforms(m_xController, lcl_needConfirmCommit( _nFeature )))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// commit the current record
|
|
||||||
bool bCommitCurrentRecord = true;
|
|
||||||
// (but before, let the user confirm if necessary)
|
|
||||||
if ( impl_isModifiedRow_throw() )
|
|
||||||
{
|
|
||||||
if ( lcl_needConfirmCommit( _nFeature ) )
|
|
||||||
{
|
|
||||||
// TODO: shouldn't this be done with an interaction handler?
|
|
||||||
QueryBox aQuery( NULL, WB_YES_NO_CANCEL | WB_DEF_YES, FRM_RES_STRING( RID_STR_QUERY_SAVE_MODIFIED_ROW ) );
|
|
||||||
switch ( aQuery.Execute() )
|
|
||||||
{
|
|
||||||
case RET_NO: bCommitCurrentRecord = false; break;
|
|
||||||
case RET_CANCEL: return;
|
|
||||||
}
|
}
|
||||||
}
|
else if(m_xCursor.is())
|
||||||
}
|
{
|
||||||
|
Reference< XForm > xForm(m_xCursor, UNO_QUERY);
|
||||||
if ( bCommitCurrentRecord && !impl_commitCurrentRecord_throw() )
|
assert(xForm.is());
|
||||||
|
if(!commitFormAndSubforms(xForm, lcl_needConfirmCommit( _nFeature )))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SAL_WARN( "forms.runtime", "No cursor, but trying to execute form operation " << _nFeature );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1229,20 +1344,6 @@ namespace frm
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
template < typename TYPE >
|
|
||||||
TYPE lcl_safeGetPropertyValue_throw( const Reference< XPropertySet >& _rxProperties, const OUString& _rPropertyName, TYPE _Default )
|
|
||||||
{
|
|
||||||
TYPE value( _Default );
|
|
||||||
OSL_PRECOND( _rxProperties.is(), "FormOperations::<foo>: no cursor (already disposed?)!" );
|
|
||||||
if ( _rxProperties.is() )
|
|
||||||
OSL_VERIFY( _rxProperties->getPropertyValue( _rPropertyName ) >>= value );
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
bool FormOperations::impl_isInsertionRow_throw() const
|
bool FormOperations::impl_isInsertionRow_throw() const
|
||||||
{
|
{
|
||||||
|
@@ -114,6 +114,11 @@ certain functionality.
|
|||||||
@li @c oox.storage - ZipStorage class
|
@li @c oox.storage - ZipStorage class
|
||||||
@li @c oox.ppt - pptx filter
|
@li @c oox.ppt - pptx filter
|
||||||
|
|
||||||
|
@section forms
|
||||||
|
|
||||||
|
@li @c forms.component
|
||||||
|
@li @c forms.runtime
|
||||||
|
|
||||||
@section formula
|
@section formula
|
||||||
|
|
||||||
@li @c formula.core
|
@li @c formula.core
|
||||||
@@ -339,7 +344,6 @@ certain functionality.
|
|||||||
@li @c cppcanvas.emf
|
@li @c cppcanvas.emf
|
||||||
@li @c cppuhelper
|
@li @c cppuhelper
|
||||||
@li @c cppu
|
@li @c cppu
|
||||||
@li @c forms
|
|
||||||
@li @c helpcompiler
|
@li @c helpcompiler
|
||||||
@li @c linguistic
|
@li @c linguistic
|
||||||
@li @c oox
|
@li @c oox
|
||||||
|
Reference in New Issue
Block a user