Kaydet (Commit) 28cacb44 authored tarafından Lionel Elie Mamane's avatar Lionel Elie Mamane

commit subforms before moving in parent form

else, all pending changes in the subforms are lost

Change-Id: I82b0967729c71a4f01eff9f823a1961fad999679
üst 7fd1cc18
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment