Index: source/filter/inc/xihelper.hxx =================================================================== RCS file: /cvs/sc/sc/source/filter/inc/xihelper.hxx,v retrieving revision 1.3 diff -u -r1.3 xihelper.hxx --- source/filter/inc/xihelper.hxx 21 May 2003 08:03:39 -0000 1.3 +++ source/filter/inc/xihelper.hxx 6 Aug 2003 15:28:30 -0000 @@ -75,6 +75,8 @@ #include "xiroot.hxx" #endif +class ScMatrix; + // Byte/Unicode strings ======================================================= @@ -273,10 +275,14 @@ double mfValue; /// Cached value is a double. ScTokenArrayPtr mpTokArr; /// Cached value is a formula or error code or Boolean. sal_uInt8 mnType; /// The type of the cached value (EXC_CACHEDVAL_*). + sal_uInt16 mnCol; /// Column index of the cached cell. + sal_uInt16 mnRow; /// Row index of the cached cell. public: - /** Creates a cached value and reads contents from stream. */ - XclImpCachedValue( XclImpStream& rStrm ); + /** Creates a cached value and reads contents from stream and stores it with its array address. */ + XclImpCachedValue( XclImpStream& rStrm, + sal_uInt16 nCol, + sal_uInt16 nRow); virtual ~XclImpCachedValue(); /** Returns the type of the cached value (EXC_CACHEDVAL_*). */ @@ -287,8 +293,34 @@ inline double GetValue() const { return mfValue; } /** Returns the token array if this is a Boolean value or error value. */ inline const ScTokenArray* GetTokArray() const { return mpTokArr.get(); } + + inline sal_uInt16 GetCol() const { return mnCol; } + inline sal_uInt16 GetRow() const { return mnRow; } }; + +class XclImpCachedMatrix +{ +protected: + typedef ScfDelList< XclImpCachedValue > XclImpValueList; + + XclImpValueList maValueList; /// List of cached cell values. + + sal_uInt16 mnColumns; /// Number of cached columns. + sal_uInt16 mnRows; /// Number of cached rows. + +public: + explicit XclImpCachedMatrix( sal_uInt16 nCols, sal_uInt16 nRows); + + /** Copies the contents of our cached matrix into the ScMatrix. */ + void FillMatrix(ScDocument &rDoc, ScMatrix *pMatrix) const ; + + /** Stores the contents of an external referenced cell in the Value list. */ + inline void AppendValue( XclImpCachedValue* pCachedValue ) { maValueList.Append( pCachedValue ); } + + inline sal_uInt16 GetColumns() const { return mnColumns; } + inline sal_uInt16 GetRows() const { return mnRows; } +}; // ============================================================================ Index: source/filter/inc/xilink.hxx =================================================================== RCS file: /cvs/sc/sc/source/filter/inc/xilink.hxx,v retrieving revision 1.3 diff -u -r1.3 xilink.hxx --- source/filter/inc/xilink.hxx 21 May 2003 08:03:54 -0000 1.3 +++ source/filter/inc/xilink.hxx 6 Aug 2003 15:28:42 -0000 @@ -71,7 +71,7 @@ class ScDocument; class ScTokenArray; class XclImpStream; - + /* ============================================================================ Classes for import of different kinds of internal/external references. @@ -126,15 +126,23 @@ class XclImpExtName { private: + typedef ::std::auto_ptr< XclImpCachedMatrix > XclImpCachedMatrixPtr; + + XclImpCachedMatrixPtr mpDdeMatrix; /// Cached results of the DDE link. String maName; /// The name of the external name. String maAddInName; /// The converted Calc add-in function name. sal_uInt32 mnStorageId; /// Storage ID for OLE object storages. XclImpExtNameType meType; /// Type of the external name. - + public: /** Reads the external name from the stream. */ explicit XclImpExtName( XclImpStream& rStrm ); + /** Create and apply the cached list of this DDE Link to the document. */ + void CreateDdeData( ScDocument& rDoc, + const String& rApplc, + const String& rExtDoc) const; + inline XclImpExtNameType GetType() const { return meType; } inline const String& GetName() const { return maName; } inline const String& GetAddInName() const { return maAddInName; } @@ -158,10 +166,6 @@ /** Contains the address and value of an external referenced cell. */ class XclImpCrn : public XclImpCachedValue { -private: - sal_uInt16 mnCol; /// Column index of the external cell. - sal_uInt16 mnRow; /// Row index of the external cell. - public: /** Reads a cached value and stores it with its cell address. */ explicit XclImpCrn( XclImpStream& rStrm, sal_uInt16 nCol, sal_uInt16 nRow ); Index: source/filter/excel/xihelper.cxx =================================================================== RCS file: /cvs/sc/sc/source/filter/excel/xihelper.cxx,v retrieving revision 1.5.48.1 diff -u -r1.5.48.1 xihelper.cxx --- source/filter/excel/xihelper.cxx 18 Jul 2003 17:09:19 -0000 1.5.48.1 +++ source/filter/excel/xihelper.cxx 6 Aug 2003 15:29:04 -0000 @@ -685,8 +685,11 @@ // Cached Values ============================================================== -XclImpCachedValue::XclImpCachedValue( XclImpStream& rStrm ) : - mfValue( 0.0 ) +XclImpCachedValue::XclImpCachedValue( XclImpStream& rStrm, sal_uInt16 nCol, sal_uInt16 nRow) : + mfValue( 0.0 ), + mnCol( nCol ), + mnRow( nRow ) + { rStrm >> mnType; switch( mnType ) @@ -726,6 +729,39 @@ { } +// Matrix Cached Values ============================================================== + +XclImpCachedMatrix::XclImpCachedMatrix(sal_uInt16 nColumns, sal_uInt16 nRows) : + mnColumns(nColumns), + mnRows(nRows) +{ +} + +XclImpCachedMatrix::~XclImpCachedMatrix() +{ +} + +void XclImpCachedMatrix::FillMatrix( ScDocument& rDoc, ScMatrix* pMatrix ) const +{ + bool bString = false; + bool bEmpty = false; + + for( const XclImpCachedValue* pCachedValue = maValueList.First(); pCachedValue; pCachedValue = maValueList.Next() ) + { + switch( pCachedValue->GetType() ) + { + case EXC_CACHEDVAL_DOUBLE: bString = bEmpty = false; break; + case EXC_CACHEDVAL_STRING: bString = true; bEmpty = false; break; + case EXC_CACHEDVAL_BOOL: bString = bEmpty = false; break; + case EXC_CACHEDVAL_ERROR: bString = bEmpty = false; break; + default: bString = false; bEmpty = true; break; + } + if(const String *pString = pCachedValue->GetString() ) + rDoc.SetDdeLinkResult(pMatrix,pCachedValue->GetCol(),pCachedValue->GetRow(), *pString ,pCachedValue->GetValue(), bString, bEmpty); + else + rDoc.SetDdeLinkResult(pMatrix,pCachedValue->GetCol(),pCachedValue->GetRow(), EMPTY_STRING ,pCachedValue->GetValue(), bString, bEmpty); + } +} // ============================================================================ Index: source/filter/excel/xilink.cxx =================================================================== RCS file: /cvs/sc/sc/source/filter/excel/xilink.cxx,v retrieving revision 1.4 diff -u -r1.4 xilink.cxx --- source/filter/excel/xilink.cxx 21 May 2003 07:58:57 -0000 1.4 +++ source/filter/excel/xilink.cxx 6 Aug 2003 15:29:24 -0000 @@ -123,9 +123,10 @@ { sal_uInt16 nFlags; sal_uInt8 nLen; - rStrm >> nFlags >> mnStorageId >> nLen; - rStrm.AppendUniString( maName, nLen ); + rStrm >> nFlags >> mnStorageId >> nLen ; + rStrm.AppendUniString( maName, nLen ); + if( ::get_flag( nFlags, EXC_EXTN_BUILTIN ) || !::get_flag( nFlags, EXC_EXTN_OLE_OR_DDE ) ) { meType = xlExtName; @@ -134,6 +135,40 @@ } else meType = ::get_flagvalue( nFlags, EXC_EXTN_OLE, xlExtOLE, xlExtDDE ); + + if(meType == xlExtDDE && (rStrm.GetRecLeft() > 1)) + { + sal_uInt8 nLastCol; + sal_uInt16 nLastRow; + rStrm >> nLastCol >> nLastRow; + + if( nLastRow <= MAXROW && nLastCol <= MAXCOL ) + { + mpDdeMatrix.reset( new XclImpCachedMatrix(nLastCol + 1, nLastRow + 1)); + + for( sal_uInt16 nRow = 0; nRow < nLastRow+1 && (rStrm.GetRecLeft() > 1); ++nRow ) + for( sal_uInt16 nCol = 0; nCol < nLastCol+1 && (rStrm.GetRecLeft() > 1); ++nCol ) + mpDdeMatrix->AppendValue( new XclImpCachedValue( rStrm, nCol, nRow )); + } + } +} + + +void XclImpExtName::CreateDdeData( ScDocument& rDoc, const String& rApplic,const String& rTopic )const +{ + rDoc.CreateDdeLink( rApplic, rTopic, GetName() ); + sal_uInt16 nPosition; + if(!rDoc.FindDdeLink(rApplic, rTopic, GetName(), SC_DDE_IGNOREMODE, nPosition)) + return ; + + if(!mpDdeMatrix.get()) + return ; + + ScMatrix* pMatrix = NULL; + if(!(rDoc.CreateDdeLinkResultDimension(nPosition, mpDdeMatrix->GetColumns(), mpDdeMatrix->GetRows(), pMatrix)) || !pMatrix) + return ; + + mpDdeMatrix->FillMatrix( rDoc, pMatrix); } @@ -149,9 +184,7 @@ // Cached external cells ====================================================== XclImpCrn::XclImpCrn( XclImpStream& rStrm, sal_uInt16 nCol, sal_uInt16 nRow ) : - XclImpCachedValue( rStrm ), - mnCol( nCol ), - mnRow( nRow ) + XclImpCachedValue( rStrm, nCol, nRow ) { } Index: source/filter/excel/excform8.cxx =================================================================== RCS file: /cvs/sc/sc/source/filter/excel/excform8.cxx,v retrieving revision 1.23.86.1 diff -u -r1.23.86.1 excform8.cxx --- source/filter/excel/excform8.cxx 15 Jul 2003 14:54:52 -0000 1.23.86.1 +++ source/filter/excel/excform8.cxx 6 Aug 2003 15:29:37 -0000 @@ -668,8 +668,7 @@ aPool << ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep << nMerk0 << ocClose; aPool >> aStack; - - pExcRoot->pDoc->CreateDdeLink( aAppl, aExtDoc, pExtName->GetName() ); + pExtName->CreateDdeData(*(pExcRoot->pDoc), aAppl, aExtDoc); } else if( (pExtName->GetType() == xlExtName) && pSupbook->IsAddIn() ) aStack << aPool.Store( ocNoName, pExtName->GetAddInName() );