commit subforms before moving in parent form
else, all pending changes in the subforms are lost Change-Id: I82b0967729c71a4f01eff9f823a1961fad999679
This commit is contained in:
parent
7fd1cc1813
commit
28cacb4400
@ -45,11 +45,11 @@ namespace frm
|
||||
//---------------------------------------------------------------------
|
||||
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!" );
|
||||
// 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!" );
|
||||
// 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::XResultSetUpdate;
|
||||
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::FeatureState;
|
||||
using ::com::sun::star::lang::IllegalArgumentException;
|
||||
@ -452,8 +453,128 @@ namespace frm
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -462,30 +583,24 @@ namespace frm
|
||||
|
||||
if ( ( _nFeature != FormFeature::DeleteRecord ) && ( _nFeature != FormFeature::UndoRecordChanges ) )
|
||||
{
|
||||
// if we have a controller, commit the current control
|
||||
if ( m_xController.is() )
|
||||
if ( !impl_commitCurrentControl_throw() )
|
||||
return;
|
||||
|
||||
// commit the current record
|
||||
bool bCommitCurrentRecord = true;
|
||||
// (but before, let the user confirm if necessary)
|
||||
if ( impl_isModifiedRow_throw() )
|
||||
|
||||
if(m_xController.is())
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
if(!commitFormAndSubforms(m_xController, lcl_needConfirmCommit( _nFeature )))
|
||||
return;
|
||||
}
|
||||
else if(m_xCursor.is())
|
||||
{
|
||||
Reference< XForm > xForm(m_xCursor, UNO_QUERY);
|
||||
assert(xForm.is());
|
||||
if(!commitFormAndSubforms(xForm, lcl_needConfirmCommit( _nFeature )))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SAL_WARN( "forms.runtime", "No cursor, but trying to execute form operation " << _nFeature );
|
||||
}
|
||||
|
||||
if ( bCommitCurrentRecord && !impl_commitCurrentRecord_throw() )
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
@ -1229,20 +1344,6 @@ namespace frm
|
||||
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
|
||||
{
|
||||
|
@ -114,6 +114,11 @@ certain functionality.
|
||||
@li @c oox.storage - ZipStorage class
|
||||
@li @c oox.ppt - pptx filter
|
||||
|
||||
@section forms
|
||||
|
||||
@li @c forms.component
|
||||
@li @c forms.runtime
|
||||
|
||||
@section formula
|
||||
|
||||
@li @c formula.core
|
||||
@ -339,7 +344,6 @@ certain functionality.
|
||||
@li @c cppcanvas.emf
|
||||
@li @c cppuhelper
|
||||
@li @c cppu
|
||||
@li @c forms
|
||||
@li @c helpcompiler
|
||||
@li @c linguistic
|
||||
@li @c oox
|
||||
|
Loading…
x
Reference in New Issue
Block a user