diff options
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/dbfld.hxx | 3 | ||||
-rw-r--r-- | sw/inc/dbmgr.hxx | 7 | ||||
-rw-r--r-- | sw/source/core/doc/DocumentFieldsManager.cxx | 9 | ||||
-rw-r--r-- | sw/source/core/fields/dbfld.cxx | 81 | ||||
-rw-r--r-- | sw/source/uibase/dbui/dbmgr.cxx | 100 |
5 files changed, 155 insertions, 45 deletions
diff --git a/sw/inc/dbfld.hxx b/sw/inc/dbfld.hxx index 8677265eda08..d9d92f0494a5 100644 --- a/sw/inc/dbfld.hxx +++ b/sw/inc/dbfld.hxx @@ -109,6 +109,9 @@ public: 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 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) diff --git a/sw/inc/dbmgr.hxx b/sw/inc/dbmgr.hxx index 6d9d7fe52562..29fa03b8b2fe 100644 --- a/sw/inc/dbmgr.hxx +++ b/sw/inc/dbmgr.hxx @@ -29,6 +29,7 @@ #include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/beans/PropertyValue.hpp> #include <boost/ptr_container/ptr_vector.hpp> + namespace com{namespace sun{namespace star{ namespace sdbc{ class XConnection; @@ -71,6 +72,7 @@ class SvNumberFormatter; class SwDbtoolsClient; class SwXMailMerge; class SwMailMergeConfigItem; +class SwCalc; enum DBManagerOptions { @@ -264,7 +266,6 @@ public: const OUString& rColNm ); inline bool IsInMerge() const { return bInMerge; } - void EndMerge(); void ExecuteFormLetter(SwWrtShell& rSh, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue>& rProperties, @@ -297,7 +298,9 @@ public: void CloseAll(bool bIncludingMerge = true); 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 ToNextRecord(const OUString& rDataSource, const OUString& rTableOrQuery, sal_Int32 nCommandType = -1); diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx index 95e51f852550..728f349be297 100644 --- a/sw/source/core/doc/DocumentFieldsManager.cxx +++ b/sw/source/core/doc/DocumentFieldsManager.cxx @@ -895,7 +895,12 @@ void DocumentFieldsManager::UpdateExpFlds( SwTxtFld* pUpdtFld, bool bUpdRefFlds // already set the current record number 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 // 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 #if HAVE_FEATURE_DBCONNECTIVITY { UpdateDBNumFlds( *(SwDBNameInfField*)pFld, aCalc ); + if( bCanFill ) + bCanFill = pMgr->FillCalcWithMergeData( m_rSwdoc.GetNumberFormatter(), nLang, true, aCalc ); } #endif break; diff --git a/sw/source/core/fields/dbfld.cxx b/sw/source/core/fields/dbfld.cxx index 9318e0927604..a7f9380118a6 100644 --- a/sw/source/core/fields/dbfld.cxx +++ b/sw/source/core/fields/dbfld.cxx @@ -263,6 +263,52 @@ SwFieldType* SwDBField::ChgTyp( SwFieldType* pNewType ) 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 void SwDBField::Evaluate() { @@ -287,40 +333,15 @@ void SwDBField::Evaluate() SetFormat( nFmt = pMgr->GetColumnFmt( aTmpData.sDataSource, aTmpData.sCommand, aColNm, pDocFormatter, GetLanguage() )); + sal_Int32 nColumnType; if( DBL_MAX != nValue ) - { - sal_Int32 nColumnType = pMgr->GetColumnType(aTmpData.sDataSource, aTmpData.sCommand, aColNm); - if( DataType::DATE == nColumnType || DataType::TIME == nColumnType || - DataType::TIMESTAMP == nColumnType) + nColumnType = pMgr->GetColumnType(aTmpData.sDataSource, aTmpData.sCommand, aColNm); - { - 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 ); + bValidValue = FormatValue( pDocFormatter, aContent, nFmt, nValue, nColumnType, this ); - if (aVal.IsNumeric()) - { - SetValue(aVal.GetDouble()); + if( DBL_MAX != nValue ) + aContent = ((SwValueFieldType*)GetTyp())->ExpandValue(nValue, GetFormat(), GetLanguage()); - 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; } diff --git a/sw/source/uibase/dbui/dbmgr.cxx b/sw/source/uibase/dbui/dbmgr.cxx index 9171bcd03055..fcb47c6c4b11 100644 --- a/sw/source/uibase/dbui/dbmgr.cxx +++ b/sw/source/uibase/dbui/dbmgr.cxx @@ -128,6 +128,10 @@ #include <unomid.h> #include <section.hxx> #include <rootfrm.hxx> +#include <fmtpdsc.hxx> +#include <ndtxt.hxx> +#include <calc.hxx> +#include <dbfld.hxx> #include <boost/scoped_ptr.hpp> @@ -442,7 +446,15 @@ bool SwDBManager::MergeNew(const SwMergeDescriptor& rMergeDesc ) 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; } @@ -1060,7 +1072,7 @@ bool SwDBManager::MergeMailFiles(SwWrtShell* pSourceShell, pWorkDoc->SetDBManager( this ); 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.CalcLayout(); rWorkShell.UnlockExpFlds(); @@ -1729,15 +1741,6 @@ OUString SwDBManager::GetDBField(uno::Reference<XPropertySet> xColumnProps, 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 bool SwDBManager::IsDataSourceOpen(const OUString& rDataSource, const OUString& rTableOrQuery, bool bMergeOnly) @@ -1849,6 +1852,79 @@ bool SwDBManager::ToNextMergeRecord() 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( const OUString& rDataSource, const OUString& rCommand, sal_Int32 /*nCommandType*/) { @@ -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(); // create a layout rWorkShell.CalcLayout(); |