Kaydet (Commit) 4851cde7 authored tarafından Jan-Marek Glogowski's avatar Jan-Marek Glogowski Kaydeden (comit) Björn Michaelsen

fdo#70346 MM: add mail merge data to condition dict

Currently section hide conditions are just evaluated based on
document field data.

This adds the current mail merge dataset to the condition
dictionary, so this can be used in the condition evaluation.

The dataset values are named from their columns and added initially,
therefore DB fields with identical names will overwrite the values
in the dictionary!

Change-Id: I82a5f9f6962628a76c836e8e2a7c9e264fdc16e0
Reviewed-on: https://gerrit.libreoffice.org/10978Reviewed-by: 's avatarBjörn Michaelsen <bjoern.michaelsen@canonical.com>
Tested-by: 's avatarBjörn Michaelsen <bjoern.michaelsen@canonical.com>
üst 7dc81077
...@@ -109,6 +109,9 @@ public: ...@@ -109,6 +109,9 @@ public:
inline const SwDBData& GetDBData() const { return ((SwDBFieldType*)GetTyp())->GetDBData(); } inline const SwDBData& GetDBData() const { return ((SwDBFieldType*)GetTyp())->GetDBData(); }
virtual bool QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const SAL_OVERRIDE; virtual bool QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const SAL_OVERRIDE;
virtual bool PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) SAL_OVERRIDE; virtual bool PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) SAL_OVERRIDE;
static bool FormatValue( SvNumberFormatter* pDocFormatter, OUString &aString, sal_uInt32 nFmt,
double &aNumber, sal_Int32 nColumnType, SwDBField *pField = NULL );
}; };
inline void SwDBField::SetExpansion(const OUString& rStr) inline void SwDBField::SetExpansion(const OUString& rStr)
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/beans/PropertyValue.hpp>
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
namespace com{namespace sun{namespace star{ namespace com{namespace sun{namespace star{
namespace sdbc{ namespace sdbc{
class XConnection; class XConnection;
...@@ -71,6 +72,7 @@ class SvNumberFormatter; ...@@ -71,6 +72,7 @@ class SvNumberFormatter;
class SwDbtoolsClient; class SwDbtoolsClient;
class SwXMailMerge; class SwXMailMerge;
class SwMailMergeConfigItem; class SwMailMergeConfigItem;
class SwCalc;
enum DBManagerOptions enum DBManagerOptions
{ {
...@@ -264,7 +266,6 @@ public: ...@@ -264,7 +266,6 @@ public:
const OUString& rColNm ); const OUString& rColNm );
inline bool IsInMerge() const { return bInMerge; } inline bool IsInMerge() const { return bInMerge; }
void EndMerge();
void ExecuteFormLetter(SwWrtShell& rSh, void ExecuteFormLetter(SwWrtShell& rSh,
const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rProperties, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rProperties,
...@@ -297,7 +298,9 @@ public: ...@@ -297,7 +298,9 @@ public:
void CloseAll(bool bIncludingMerge = true); void CloseAll(bool bIncludingMerge = true);
bool GetMergeColumnCnt(const OUString& rColumnName, sal_uInt16 nLanguage, bool GetMergeColumnCnt(const OUString& rColumnName, sal_uInt16 nLanguage,
OUString &rResult, double *pNumber, sal_uInt32 *pFormat); OUString &rResult, double *pNumber, sal_uInt32 *pFormat);
bool FillCalcWithMergeData(SvNumberFormatter *pDocFormatter,
sal_uInt16 nLanguage, bool asString, SwCalc &aCalc);
bool ToNextMergeRecord(); bool ToNextMergeRecord();
bool ToNextRecord(const OUString& rDataSource, const OUString& rTableOrQuery, sal_Int32 nCommandType = -1); bool ToNextRecord(const OUString& rDataSource, const OUString& rTableOrQuery, sal_Int32 nCommandType = -1);
......
...@@ -895,7 +895,12 @@ void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds ...@@ -895,7 +895,12 @@ void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds
// already set the current record number // already set the current record number
SwDBManager* pMgr = m_rSwdoc.GetDBManager(); SwDBManager* pMgr = m_rSwdoc.GetDBManager();
pMgr->CloseAll(false); pMgr->CloseAll( false );
SvtSysLocale aSysLocale;
const LocaleDataWrapper* pLclData = aSysLocale.GetLocaleDataPtr();
const long nLang = pLclData->getLanguageTag().getLanguageType();
bool bCanFill = pMgr->FillCalcWithMergeData( m_rSwdoc.GetNumberFormatter(), nLang, true, aCalc );
#endif #endif
// Make sure we don't hide all sections, which would lead to a crash. First, count how many of them do we have. // Make sure we don't hide all sections, which would lead to a crash. First, count how many of them do we have.
...@@ -990,6 +995,8 @@ void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds ...@@ -990,6 +995,8 @@ void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds
#if HAVE_FEATURE_DBCONNECTIVITY #if HAVE_FEATURE_DBCONNECTIVITY
{ {
UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc ); UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc );
if( bCanFill )
bCanFill = pMgr->FillCalcWithMergeData( m_rSwdoc.GetNumberFormatter(), nLang, true, aCalc );
} }
#endif #endif
break; break;
......
...@@ -263,6 +263,52 @@ SwFieldType* SwDBField::ChgTyp( SwFieldType* pNewType ) ...@@ -263,6 +263,52 @@ SwFieldType* SwDBField::ChgTyp( SwFieldType* pNewType )
return pOld; return pOld;
} }
bool SwDBField::FormatValue( SvNumberFormatter* pDocFormatter, OUString &aString, sal_uInt32 nFmt,
double &aNumber, sal_Int32 nColumnType, SwDBField *pField )
{
bool bValidValue = false;
if( DBL_MAX != aNumber )
{
if( DataType::DATE == nColumnType || DataType::TIME == nColumnType ||
DataType::TIMESTAMP == nColumnType )
{
Date aStandard( 1, 1, 1900 );
if( *pDocFormatter->GetNullDate() != aStandard )
aNumber += (aStandard - *pDocFormatter->GetNullDate());
}
bValidValue = true;
if( pField )
pField->SetValue( aNumber );
}
else
{
SwSbxValue aVal;
aVal.PutString( aString );
if (aVal.IsNumeric())
{
if( pField )
pField->SetValue(aVal.GetDouble());
else
aNumber = aVal.GetDouble();
if (nFmt && nFmt != SAL_MAX_UINT32 && !pDocFormatter->IsTextFormat(nFmt))
bValidValue = true; // because of bug #60339 not for all strings
}
else
{
// if string length > 0 then true, else false
if( pField )
pField->SetValue(aString.isEmpty() ? 0 : 1);
else
aNumber = aString.isEmpty() ? 0 : 1;
}
}
return bValidValue;
}
/// get current field value and cache it /// get current field value and cache it
void SwDBField::Evaluate() void SwDBField::Evaluate()
{ {
...@@ -287,40 +333,15 @@ void SwDBField::Evaluate() ...@@ -287,40 +333,15 @@ void SwDBField::Evaluate()
SetFormat( nFmt = pMgr->GetColumnFmt( aTmpData.sDataSource, aTmpData.sCommand, SetFormat( nFmt = pMgr->GetColumnFmt( aTmpData.sDataSource, aTmpData.sCommand,
aColNm, pDocFormatter, GetLanguage() )); aColNm, pDocFormatter, GetLanguage() ));
sal_Int32 nColumnType;
if( DBL_MAX != nValue ) if( DBL_MAX != nValue )
{ nColumnType = pMgr->GetColumnType(aTmpData.sDataSource, aTmpData.sCommand, aColNm);
sal_Int32 nColumnType = pMgr->GetColumnType(aTmpData.sDataSource, aTmpData.sCommand, aColNm);
if( DataType::DATE == nColumnType || DataType::TIME == nColumnType ||
DataType::TIMESTAMP == nColumnType)
{ bValidValue = FormatValue( pDocFormatter, aContent, nFmt, nValue, nColumnType, this );
Date aStandard(1,1,1900);
if (*pDocFormatter->GetNullDate() != aStandard)
nValue += (aStandard - *pDocFormatter->GetNullDate());
}
bValidValue = true;
SetValue(nValue);
aContent = ((SwValueFieldType*)GetTyp())->ExpandValue(nValue, GetFormat(), GetLanguage());
}
else
{
SwSbxValue aVal;
aVal.PutString( aContent );
if (aVal.IsNumeric()) if( DBL_MAX != nValue )
{ aContent = ((SwValueFieldType*)GetTyp())->ExpandValue(nValue, GetFormat(), GetLanguage());
SetValue(aVal.GetDouble());
SvNumberFormatter* pFormatter = GetDoc()->GetNumberFormatter();
if (nFmt && nFmt != SAL_MAX_UINT32 && !pFormatter->IsTextFormat(nFmt))
bValidValue = true; // because of bug #60339 not for all strings
}
else
{
// if string length > 0 then true, else false
SetValue(aContent.isEmpty() ? 0 : 1);
}
}
bInitialized = true; bInitialized = true;
} }
......
...@@ -128,6 +128,10 @@ ...@@ -128,6 +128,10 @@
#include <unomid.h> #include <unomid.h>
#include <section.hxx> #include <section.hxx>
#include <rootfrm.hxx> #include <rootfrm.hxx>
#include <fmtpdsc.hxx>
#include <ndtxt.hxx>
#include <calc.hxx>
#include <dbfld.hxx>
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
...@@ -442,7 +446,15 @@ bool SwDBManager::MergeNew(const SwMergeDescriptor& rMergeDesc ) ...@@ -442,7 +446,15 @@ bool SwDBManager::MergeNew(const SwMergeDescriptor& rMergeDesc )
break; break;
} }
EndMerge(); DELETEZ( pImpl->pMergeData );
// Recalculate original section visibility states, as field changes aren't
// tracked (not undo-able). Has to be done, after pImpl->pMergeData is
// gone, otherwise merge data is used for calculation!
rMergeDesc.rSh.SwViewShell::UpdateFlds();
bInMerge = false;
return bRet; return bRet;
} }
...@@ -1060,7 +1072,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell, ...@@ -1060,7 +1072,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell,
pWorkDoc->SetDBManager( this ); pWorkDoc->SetDBManager( this );
pWorkDoc->getIDocumentLinksAdministration().EmbedAllLinks(); pWorkDoc->getIDocumentLinksAdministration().EmbedAllLinks();
// #i69485# lock fields to prevent access to the result set while calculating layout // #i69458# lock fields to prevent access to the result set while calculating layout
rWorkShell.LockExpFlds(); rWorkShell.LockExpFlds();
rWorkShell.CalcLayout(); rWorkShell.CalcLayout();
rWorkShell.UnlockExpFlds(); rWorkShell.UnlockExpFlds();
...@@ -1729,15 +1741,6 @@ OUString SwDBManager::GetDBField(uno::Reference<XPropertySet> xColumnProps, ...@@ -1729,15 +1741,6 @@ OUString SwDBManager::GetDBField(uno::Reference<XPropertySet> xColumnProps,
return sRet; return sRet;
} }
// releases the merge data source table or query after merge is completed
void SwDBManager::EndMerge()
{
OSL_ENSURE(bInMerge, "merge is not active");
bInMerge = false;
delete pImpl->pMergeData;
pImpl->pMergeData = 0;
}
// checks if a desired data source table or query is open // checks if a desired data source table or query is open
bool SwDBManager::IsDataSourceOpen(const OUString& rDataSource, bool SwDBManager::IsDataSourceOpen(const OUString& rDataSource,
const OUString& rTableOrQuery, bool bMergeOnly) const OUString& rTableOrQuery, bool bMergeOnly)
...@@ -1849,6 +1852,79 @@ bool SwDBManager::ToNextMergeRecord() ...@@ -1849,6 +1852,79 @@ bool SwDBManager::ToNextMergeRecord()
return ToNextRecord(pImpl->pMergeData); return ToNextRecord(pImpl->pMergeData);
} }
bool SwDBManager::FillCalcWithMergeData( SvNumberFormatter *pDocFormatter,
sal_uInt16 nLanguage, bool asString, SwCalc &rCalc )
{
if (!(pImpl->pMergeData && pImpl->pMergeData->xResultSet.is()))
return false;
uno::Reference< XColumnsSupplier > xColsSupp( pImpl->pMergeData->xResultSet, UNO_QUERY );
if(xColsSupp.is())
{
uno::Reference<XNameAccess> xCols = xColsSupp->getColumns();
const Sequence<OUString> aColNames = xCols->getElementNames();
const OUString* pColNames = aColNames.getConstArray();
OUString aString;
const bool bExistsNextRecord = ExistsNextRecord();
for( int nCol = 0; nCol < aColNames.getLength(); nCol++ )
{
const OUString &rColName = pColNames[nCol];
// empty variables, if no more records;
if( !bExistsNextRecord )
{
rCalc.VarChange( rColName, 0 );
continue;
}
double aNumber = DBL_MAX;
if( lcl_GetColumnCnt(pImpl->pMergeData, rColName, nLanguage, aString, &aNumber) )
{
// get the column type
sal_Int32 nColumnType;
Any aCol = xCols->getByName( pColNames[nCol] );
uno::Reference<XPropertySet> xCol;
aCol >>= xCol;
Any aType = xCol->getPropertyValue( "Type" );
aType >>= nColumnType;
sal_uInt32 nFmt;
if( !GetMergeColumnCnt(pColNames[nCol], nLanguage, aString, &aNumber, &nFmt) )
continue;
// aNumber is overwritten by SwDBField::FormatValue, so store initial status
bool colIsNumber = aNumber != DBL_MAX;
bool bValidValue = SwDBField::FormatValue( pDocFormatter, aString, nFmt,
aNumber, nColumnType, NULL );
if( colIsNumber )
{
if( bValidValue )
{
SwSbxValue aValue;
if( !asString )
aValue.PutDouble( aNumber );
else
aValue.PutString( aString );
SAL_INFO( "sw.dbmgr", "'" << pColNames[nCol] << "': " << aNumber << " / " << aString );
rCalc.VarChange( pColNames[nCol], aValue );
}
}
else
{
SwSbxValue aValue;
aValue.PutString( aString );
SAL_INFO( "sw.dbmgr", "'" << pColNames[nCol] << "': " << aString );
rCalc.VarChange( pColNames[nCol], aValue );
}
}
}
return bExistsNextRecord;
}
return false;
}
bool SwDBManager::ToNextRecord( bool SwDBManager::ToNextRecord(
const OUString& rDataSource, const OUString& rCommand, sal_Int32 /*nCommandType*/) const OUString& rDataSource, const OUString& rCommand, sal_Int32 /*nCommandType*/)
{ {
...@@ -2829,7 +2905,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig, ...@@ -2829,7 +2905,7 @@ sal_Int32 SwDBManager::MergeDocuments( SwMailMergeConfigItem& rMMConfig,
} }
} }
// #i69485# lock fields to prevent access to the result set while calculating layout // #i69458# lock fields to prevent access to the result set while calculating layout
rWorkShell.LockExpFlds(); rWorkShell.LockExpFlds();
// create a layout // create a layout
rWorkShell.CalcLayout(); rWorkShell.CalcLayout();
......
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