[Libreoffice-commits] .: 85 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Mon Dec 20 17:11:45 PST 2010


 sc/inc/addincol.hxx                         |    2 
 sc/inc/document.hxx                         |    7 
 sc/inc/scmatrix.hxx                         |  344 ++----
 sc/inc/token.hxx                            |    4 
 sc/inc/tokenarray.hxx                       |    3 
 sc/qa/unit/ucalc.cxx                        |  137 ++
 sc/source/core/data/cell.cxx                |   16 
 sc/source/core/data/cell2.cxx               |    4 
 sc/source/core/data/documen8.cxx            |    4 
 sc/source/core/data/validat.cxx             |   20 
 sc/source/core/inc/ddelink.hxx              |    4 
 sc/source/core/inc/interpre.hxx             |    8 
 sc/source/core/inc/jumpmatrix.hxx           |    4 
 sc/source/core/tool/addincol.cxx            |   15 
 sc/source/core/tool/compiler.cxx            |   15 
 sc/source/core/tool/ddelink.cxx             |   11 
 sc/source/core/tool/interpr1.cxx            |  291 +++--
 sc/source/core/tool/interpr3.cxx            |   28 
 sc/source/core/tool/interpr4.cxx            |   95 -
 sc/source/core/tool/interpr5.cxx            |  176 +--
 sc/source/core/tool/makefile.mk             |    2 
 sc/source/core/tool/rangeseq.cxx            |   13 
 sc/source/core/tool/scmatrix.cxx            | 1483 +++++++++++++++++-----------
 sc/source/core/tool/token.cxx               |    8 
 sc/source/filter/excel/excform.cxx          |    2 
 sc/source/filter/excel/xeformula.cxx        |   17 
 sc/source/filter/excel/xehelper.cxx         |   17 
 sc/source/filter/xml/XMLDDELinksContext.cxx |    2 
 sc/source/filter/xml/XMLExportDDELinks.cxx  |  124 --
 sc/source/filter/xml/XMLExportDDELinks.hxx  |    5 
 sc/source/filter/xml/xmlexprt.hxx           |    2 
 sc/source/ui/docshell/externalrefmgr.cxx    |   54 -
 sc/source/ui/unoobj/linkuno.cxx             |    2 
 33 files changed, 1690 insertions(+), 1229 deletions(-)

New commits:
commit bc24308db8385ddfdcd0f42b03e96b8820db84c0
Merge: 18922c4... be6a1d0...
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Dec 20 19:51:07 2010 -0500

    Merge branch 'feature/calc-matrix-rework'

commit be6a1d0c5bc0b744881fad61c0cb7cc06a2b3abc
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Dec 20 15:31:19 2010 -0500

    Fixed build breakage.

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index f3ea2a3..c3fc8d0 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -847,7 +847,6 @@ class MultiplyElements : public unary_function<void, MatrixImplType::element>
     bool mbTextAsZero;
 public:
     MultiplyElements(bool bTextAsZero) : maRes(0.0, 1.0, 0), mbTextAsZero(bTextAsZero) {}
-    MultiplyElements(const MultiplyElement& r) : maRes(r.maRes), mbTextAsZero(r.mbTextAsZero) {}
     ScMatrix::IterateResult getResult() const { return maRes; }
 
     void operator() (const MatrixImplType::element& elem)
commit 705c59eec3ba4351759e6d74feaeaad34428b088
Merge: 16fdac1... 6f94488...
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Dec 20 15:21:14 2010 -0500

    Merge branch 'master' into feature/calc-matrix-rework

diff --cc sc/qa/unit/ucalc.cxx
index 77e8d5f,92a7c70..ba0b787
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@@ -54,16 -62,7 +62,8 @@@
  #include <scdll.hxx>
  #include <document.hxx>
  #include <stringutil.hxx>
 +#include <scmatrix.hxx>
  
- #include "preextstl.h"
- #include <cppunit/TestSuite.h>
- #include <cppunit/TestFixture.h>
- #include <cppunit/TestCase.h>
- #include <cppunit/plugin/TestPlugIn.h>
- #include <cppunit/extensions/HelperMacros.h>
- #include "postextstl.h"
- 
  using namespace ::com::sun::star;
  
  namespace {
commit 16fdac1d2ba6defdb3ee8d67033a7ae205e113d0
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Dec 20 15:16:12 2010 -0500

    Use mixed_type_matrix::const_iterator for faster element iteration.
    
    This should speed up calculation of SUM, AVERAGE etc. on external
    ranges.

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 1d381b9..df744df 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -153,6 +153,28 @@ public:
         SPARSE_EMPTY
     };
 
+    /**
+     * When adding all numerical matrix elements for a scalar result such as
+     * summation, the interpreter wants to separate the first non-zero value
+     * with the rest of the summed values.
+     *
+     * TODO: Find out if we still need to do this.  If not, we can re-write
+     * ScInterpreter::IterateParameters() to make it simpler and remove this
+     * struct.
+     */
+    struct IterateResult
+    {
+        double mfFirst;
+        double mfRest;
+        size_t mnCount;
+
+        IterateResult(double fFirst, double fRest, size_t nCount) :
+            mfFirst(fFirst), mfRest(fRest), mnCount(nCount) {}
+
+        IterateResult(const IterateResult& r) :
+            mfFirst(r.mfFirst), mfRest(r.mfRest), mnCount(r.mnCount) {}
+    };
+
     /// The maximum number of elements a matrix may have at runtime.
     inline static size_t GetElementsMax()
     {
@@ -345,15 +367,11 @@ public:
     double And() const;       // logical AND of all matrix values, or NAN
     double Or() const;        // logical OR of all matrix values, or NAN
 
-    double Sum() const;
-    double SumSquare() const;
-    double Product() const;
-    double Average(bool bTextAsZero) const;
-    double Min() const;
-    double Max() const;
+    IterateResult Sum(bool bTextAsZero) const;
+    IterateResult SumSquare(bool bTextAsZero) const;
+    IterateResult Product(bool bTextAsZero) const;
     size_t Count(bool bCountStrings) const;
 
-
     // All other matrix functions  MatMult, MInv, ...  are in ScInterpreter
     // to be numerically safe.
 };
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 3d1b6e4..ab698a4 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -3101,54 +3101,51 @@ namespace {
 
 void IterateMatrix(
     const ScMatrixRef& pMat, ScIterFunc eFunc, BOOL bTextAsZero,
-    ULONG& rCount, short& rFuncFmtType, double& fVal, double& fRes, double& fMem, bool& bNull)
+    ULONG& rCount, short& rFuncFmtType, double& fRes, double& fMem, bool& bNull)
 {
     if (!pMat)
         return;
 
-    SCSIZE nC, nR;
     rFuncFmtType = NUMBERFORMAT_NUMBER;
-    pMat->GetDimensions(nC, nR);
-    if( eFunc == ifCOUNT2 )
+    switch (eFunc)
     {
-        // TODO: Count everything but empty.  Fix this.
-        rCount += (ULONG) nC * nR;
-    }
-    else
-    {
-        for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
+        case ifAVERAGE:
+        case ifSUM:
         {
-            for (SCSIZE nMatRow = 0; nMatRow < nR; nMatRow++)
+            ScMatrix::IterateResult aRes = pMat->Sum(bTextAsZero);
+            if (bNull)
             {
-                if (!pMat->IsString(nMatCol,nMatRow))
-                {
-                    rCount++;
-                    fVal = pMat->GetDouble(nMatCol,nMatRow);
-                    switch( eFunc )
-                    {
-                        case ifAVERAGE:
-                        case ifSUM:
-                            if ( bNull && fVal != 0.0 )
-                            {
-                                bNull = false;
-                                fMem = fVal;
-                            }
-                            else
-                                fRes += fVal;
-                            break;
-                        case ifSUMSQ:   fRes += fVal * fVal; break;
-                        case ifPRODUCT: fRes *= fVal; break;
-                        default: ; // nothing
-                    }
-                }
-                else if ( bTextAsZero )
-                {
-                    rCount++;
-                    if ( eFunc == ifPRODUCT )
-                        fRes = 0.0;
-                }
+                bNull = false;
+                fMem = aRes.mfFirst;
+                fRes += aRes.mfRest;
             }
+            else
+                fRes += aRes.mfFirst + aRes.mfRest;
+            rCount += aRes.mnCount;
         }
+        break;
+        case ifCOUNT:
+            rCount += pMat->Count(bTextAsZero);
+        break;
+        case ifCOUNT2:
+            rCount += pMat->Count(true);
+        break;
+        case ifPRODUCT:
+        {
+            ScMatrix::IterateResult aRes = pMat->Product(bTextAsZero);
+            fRes *= aRes.mfRest;
+            rCount += aRes.mnCount;
+        }
+        break;
+        case ifSUMSQ:
+        {
+            ScMatrix::IterateResult aRes = pMat->SumSquare(bTextAsZero);
+            fRes += aRes.mfRest;
+            rCount += aRes.mnCount;
+        }
+        break;
+        default:
+            ;
     }
 }
 
@@ -3452,13 +3449,13 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
                 if (nGlobalError)
                     break;
 
-                IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fVal, fMem, fRes, bNull);
+                IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fRes, fMem, bNull);
             }
             break;
             case svMatrix :
             {
                 ScMatrixRef pMat = PopMatrix();
-                IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fVal, fMem, fRes, bNull);
+                IterateMatrix(pMat, eFunc, bTextAsZero, nCount, nFuncFmtType, fRes, fMem, bNull);
             }
             break;
             case svError:
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index d426d08..f3ea2a3 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -46,6 +46,10 @@
 #include <mdds/mixed_type_matrix.hpp>
 
 using ::std::pair;
+using ::std::for_each;
+using ::std::count_if;
+using ::std::advance;
+using ::std::unary_function;
 using ::mdds::matrix_element_t;
 
 // ============================================================================
@@ -54,7 +58,7 @@ namespace {
 
 typedef ::mdds::mixed_type_matrix<String, sal_uInt8> MatrixImplType;
 
-struct ElemEqual : public ::std::unary_function<double, bool>
+struct ElemEqual : public unary_function<double, bool>
 {
     bool operator() (double val) const
     {
@@ -62,7 +66,7 @@ struct ElemEqual : public ::std::unary_function<double, bool>
     }
 };
 
-struct ElemNotEqual : public ::std::unary_function<double, bool>
+struct ElemNotEqual : public unary_function<double, bool>
 {
     bool operator() (double val) const
     {
@@ -70,7 +74,7 @@ struct ElemNotEqual : public ::std::unary_function<double, bool>
     }
 };
 
-struct ElemGreater : public ::std::unary_function<double, bool>
+struct ElemGreater : public unary_function<double, bool>
 {
     bool operator() (double val) const
     {
@@ -78,7 +82,7 @@ struct ElemGreater : public ::std::unary_function<double, bool>
     }
 };
 
-struct ElemLess : public ::std::unary_function<double, bool>
+struct ElemLess : public unary_function<double, bool>
 {
     bool operator() (double val) const
     {
@@ -86,7 +90,7 @@ struct ElemLess : public ::std::unary_function<double, bool>
     }
 };
 
-struct ElemGreaterEqual : public ::std::unary_function<double, bool>
+struct ElemGreaterEqual : public unary_function<double, bool>
 {
     bool operator() (double val) const
     {
@@ -94,7 +98,7 @@ struct ElemGreaterEqual : public ::std::unary_function<double, bool>
     }
 };
 
-struct ElemLessEqual : public ::std::unary_function<double, bool>
+struct ElemLessEqual : public unary_function<double, bool>
 {
     bool operator() (double val) const
     {
@@ -144,6 +148,23 @@ void compareMatrix(MatrixImplType& rMat)
     return mdds::matrix_density_filled_zero;
 }
 
+/**
+ * Return a numeric value from a matrix element no matter what its type is.
+ */
+double getNumericValue(const MatrixImplType::element& elem)
+{
+    switch (elem.m_type)
+    {
+        case mdds::element_boolean:
+            return static_cast<double>(elem.m_boolean);
+        case mdds::element_numeric:
+            return elem.m_numeric;
+        default:
+            ;
+    }
+    return 0.0;
+}
+
 }
 
 class ScMatrixImpl
@@ -211,12 +232,9 @@ public:
     double And() const;
     double Or() const;
 
-    double Sum() const;
-    double SumSquare() const;
-    double Product() const;
-    double Average(bool bTextAsZero) const;
-    double Min() const;
-    double Max() const;
+    ScMatrix::IterateResult Sum(bool bTextAsZero) const;
+    ScMatrix::IterateResult SumSquare(bool bTextAsZero) const;
+    ScMatrix::IterateResult Product(bool bTextAsZero) const;
     size_t Count(bool bCountStrings) const;
 
 private:
@@ -744,39 +762,155 @@ double ScMatrixImpl::Or() const
     return EvalMatrix<OrEvaluator>(maMat);
 }
 
-double ScMatrixImpl::Sum() const
+namespace {
+
+/**
+ * Function object to sum all numeric elements (including boolean).  It
+ * stores the first non-zero element value into maRes.mfFirst while the rest
+ * into maRes.mfRest.  This weird requirement comes from
+ * ScInterpreter::IterateParameters.
+ */
+class SumElements : public unary_function<void, MatrixImplType::element>
 {
-    return 0.0;
-}
+    ScMatrix::IterateResult maRes;
+    bool mbTextAsZero;
+public:
+    SumElements(bool bTextAsZero) : maRes(0.0, 0.0, 0), mbTextAsZero(bTextAsZero) {}
 
-double ScMatrixImpl::SumSquare() const
+    ScMatrix::IterateResult getResult() const { return maRes; }
+    void operator() (const MatrixImplType::element& elem)
+    {
+        switch (elem.m_type)
+        {
+            case mdds::element_boolean:
+                if (elem.m_boolean)
+                {
+                    if (maRes.mfFirst)
+                        maRes.mfFirst = 1.0;
+                    else
+                        maRes.mfRest += 1.0;
+                }
+                ++maRes.mnCount;
+            break;
+            case mdds::element_numeric:
+                if (elem.m_numeric != 0.0)
+                {
+                    if (maRes.mfFirst)
+                        maRes.mfFirst = elem.m_numeric;
+                    else
+                        maRes.mfRest += elem.m_numeric;
+                }
+                ++maRes.mnCount;
+            break;
+            case mdds::element_string:
+                if (mbTextAsZero)
+                    ++maRes.mnCount;
+            default:
+                ;
+        }
+    }
+};
+
+class SumSquareElements : public unary_function<void, MatrixImplType::element>
 {
-    return 0.0;
-}
+    ScMatrix::IterateResult maRes;
+    bool mbTextAsZero;
+public:
+    SumSquareElements(bool bTextAsZero) : maRes(0.0, 0.0, 0), mbTextAsZero(bTextAsZero) {}
+    ScMatrix::IterateResult getResult() const { return maRes; }
+    void operator() (const MatrixImplType::element& elem)
+    {
+        if (elem.m_type == ::mdds::element_empty)
+            return;
+
+        if (elem.m_type == ::mdds::element_string)
+        {
+            if (mbTextAsZero)
+                ++maRes.mnCount;
+            return;
+        }
+
+        double val = getNumericValue(elem);
+        maRes.mfRest += val*val;
+        ++maRes.mnCount;
+    }
+};
 
-double ScMatrixImpl::Product() const
+/**
+ * Multiply all boolean and numeric elements.  It skips empty elements, and 
+ * optionally string elements if specified.  When text as zero option is 
+ * specified, it treats string elements as if they have values of zero.
+ */
+class MultiplyElements : public unary_function<void, MatrixImplType::element>
 {
-    return 0.0;
+    ScMatrix::IterateResult maRes;
+    bool mbTextAsZero;
+public:
+    MultiplyElements(bool bTextAsZero) : maRes(0.0, 1.0, 0), mbTextAsZero(bTextAsZero) {}
+    MultiplyElements(const MultiplyElement& r) : maRes(r.maRes), mbTextAsZero(r.mbTextAsZero) {}
+    ScMatrix::IterateResult getResult() const { return maRes; }
+
+    void operator() (const MatrixImplType::element& elem)
+    {
+        if (elem.m_type == ::mdds::element_string)
+        {
+            ++maRes.mnCount;
+            if (mbTextAsZero)
+                maRes.mfRest = 0.0;
+        }
+        else if (elem.m_type != ::mdds::element_empty)
+        {
+            ++maRes.mnCount;
+            maRes.mfRest *= getNumericValue(elem);
+        }
+    }
+};
+
+/**
+ * Predicate for counting only boolean, numeric, and optionally string
+ * elements.
+ */
+class CountNonEmptyElements : public unary_function<bool, MatrixImplType::element>
+{
+    const bool mbCountString;
+public:
+    CountNonEmptyElements(bool bCountString) : mbCountString(bCountString) {}
+    bool operator() (const MatrixImplType::element& elem) const
+    {
+        switch (elem.m_type)
+        {
+            case mdds::element_boolean:
+            case mdds::element_numeric:
+                return true;
+            case mdds::element_string:
+                return mbCountString;
+            default:
+                ;
+        }
+        return false;
+    }
+};
+
 }
 
-double ScMatrixImpl::Average(bool bTextAsZero) const
+ScMatrix::IterateResult ScMatrixImpl::Sum(bool bTextAsZero) const
 {
-    return 0.0;
+    return for_each(maMat.begin(), maMat.end(), SumElements(bTextAsZero)).getResult();
 }
 
-double ScMatrixImpl::Min() const
+ScMatrix::IterateResult ScMatrixImpl::SumSquare(bool bTextAsZero) const
 {
-    return 0.0;
+    return for_each(maMat.begin(), maMat.end(), SumSquareElements(bTextAsZero)).getResult();
 }
 
-double ScMatrixImpl::Max() const
+ScMatrix::IterateResult ScMatrixImpl::Product(bool bTextAsZero) const
 {
-    return 0.0;
+    return for_each(maMat.begin(), maMat.end(), MultiplyElements(bTextAsZero)).getResult();
 }
 
 size_t ScMatrixImpl::Count(bool bCountStrings) const
 {
-    return 0;
+    return count_if(maMat.begin(), maMat.end(), CountNonEmptyElements(bCountStrings));
 }
 
 void ScMatrixImpl::CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const
@@ -1051,34 +1185,19 @@ double ScMatrix::Or() const
     return pImpl->Or();
 }
 
-double ScMatrix::Sum() const
-{
-    return pImpl->Sum();
-}
-
-double ScMatrix::SumSquare() const
-{
-    return pImpl->SumSquare();
-}
-
-double ScMatrix::Product() const
-{
-    return pImpl->Product();
-}
-
-double ScMatrix::Average(bool bTextAsZero) const
+ScMatrix::IterateResult ScMatrix::Sum(bool bTextAsZero) const
 {
-    return pImpl->Average(bTextAsZero);
+    return pImpl->Sum(bTextAsZero);
 }
 
-double ScMatrix::Min() const
+ScMatrix::IterateResult ScMatrix::SumSquare(bool bTextAsZero) const
 {
-    return pImpl->Min();
+    return pImpl->SumSquare(bTextAsZero);
 }
 
-double ScMatrix::Max() const
+ScMatrix::IterateResult ScMatrix::Product(bool bTextAsZero) const
 {
-    return pImpl->Max();
+    return pImpl->Product(bTextAsZero);
 }
 
 size_t ScMatrix::Count(bool bCountStrings) const
commit 5e856835e6b8a30220d6bcbdd0074503075190fc
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 17:30:33 2010 -0500

    Added skeleton methods for all sorts of iterative calculations.
    
    They are not yet implemented.

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 1407f56..1d381b9 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -342,8 +342,17 @@ public:
     void CompareLessEqual();
     void CompareGreaterEqual();
 
-    double And();       // logical AND of all matrix values, or NAN
-    double Or();        // logical OR of all matrix values, or NAN
+    double And() const;       // logical AND of all matrix values, or NAN
+    double Or() const;        // logical OR of all matrix values, or NAN
+
+    double Sum() const;
+    double SumSquare() const;
+    double Product() const;
+    double Average(bool bTextAsZero) const;
+    double Min() const;
+    double Max() const;
+    size_t Count(bool bCountStrings) const;
+
 
     // All other matrix functions  MatMult, MInv, ...  are in ScInterpreter
     // to be numerically safe.
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 1af02d7..d426d08 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -208,8 +208,16 @@ public:
     void CompareGreater();
     void CompareLessEqual();
     void CompareGreaterEqual();
-    double And();
-    double Or();
+    double And() const;
+    double Or() const;
+
+    double Sum() const;
+    double SumSquare() const;
+    double Product() const;
+    double Average(bool bTextAsZero) const;
+    double Min() const;
+    double Max() const;
+    size_t Count(bool bCountStrings) const;
 
 private:
     void CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const;
@@ -722,20 +730,55 @@ bool EvalMatrix(const MatrixImplType& rMat)
 
 }
 
-double ScMatrixImpl::And()
+double ScMatrixImpl::And() const
 {
     // All elements must be of value type.
     // True only if all the elements have non-zero values.
     return EvalMatrix<AndEvaluator>(maMat);
 }
 
-double ScMatrixImpl::Or()
+double ScMatrixImpl::Or() const
 {
     // All elements must be of value type.
     // True if at least one element has a non-zero value.
     return EvalMatrix<OrEvaluator>(maMat);
 }
 
+double ScMatrixImpl::Sum() const
+{
+    return 0.0;
+}
+
+double ScMatrixImpl::SumSquare() const
+{
+    return 0.0;
+}
+
+double ScMatrixImpl::Product() const
+{
+    return 0.0;
+}
+
+double ScMatrixImpl::Average(bool bTextAsZero) const
+{
+    return 0.0;
+}
+
+double ScMatrixImpl::Min() const
+{
+    return 0.0;
+}
+
+double ScMatrixImpl::Max() const
+{
+    return 0.0;
+}
+
+size_t ScMatrixImpl::Count(bool bCountStrings) const
+{
+    return 0;
+}
+
 void ScMatrixImpl::CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const
 {
     SCSIZE nRowSize = maMat.size().first;
@@ -998,14 +1041,49 @@ void ScMatrix::CompareGreaterEqual()
     pImpl->CompareGreaterEqual();
 }
 
-double ScMatrix::And()
+double ScMatrix::And() const
 {
     return pImpl->And();
 }
 
-double ScMatrix::Or()
+double ScMatrix::Or() const
 {
     return pImpl->Or();
 }
 
+double ScMatrix::Sum() const
+{
+    return pImpl->Sum();
+}
+
+double ScMatrix::SumSquare() const
+{
+    return pImpl->SumSquare();
+}
+
+double ScMatrix::Product() const
+{
+    return pImpl->Product();
+}
+
+double ScMatrix::Average(bool bTextAsZero) const
+{
+    return pImpl->Average(bTextAsZero);
+}
+
+double ScMatrix::Min() const
+{
+    return pImpl->Min();
+}
+
+double ScMatrix::Max() const
+{
+    return pImpl->Max();
+}
+
+size_t ScMatrix::Count(bool bCountStrings) const
+{
+    return pImpl->Count(bCountStrings);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit a46007cfa947260d532a2d2bbaeaa6e3d843d9f4
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 16:43:18 2010 -0500

    BOOL to bool, some comments.

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 67ef1cf..3d1b6e4 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -3101,7 +3101,7 @@ namespace {
 
 void IterateMatrix(
     const ScMatrixRef& pMat, ScIterFunc eFunc, BOOL bTextAsZero,
-    ULONG& rCount, short& rFuncFmtType, double& fVal, double& fRes, double& fMem, BOOL& bNull)
+    ULONG& rCount, short& rFuncFmtType, double& fVal, double& fRes, double& fMem, bool& bNull)
 {
     if (!pMat)
         return;
@@ -3110,7 +3110,10 @@ void IterateMatrix(
     rFuncFmtType = NUMBERFORMAT_NUMBER;
     pMat->GetDimensions(nC, nR);
     if( eFunc == ifCOUNT2 )
+    {
+        // TODO: Count everything but empty.  Fix this.
         rCount += (ULONG) nC * nR;
+    }
     else
     {
         for (SCSIZE nMatCol = 0; nMatCol < nC; nMatCol++)
@@ -3127,7 +3130,7 @@ void IterateMatrix(
                         case ifSUM:
                             if ( bNull && fVal != 0.0 )
                             {
-                                bNull = FALSE;
+                                bNull = false;
                                 fMem = fVal;
                             }
                             else
@@ -3157,8 +3160,8 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
     short nParamCount = GetByte();
     double fRes = ( eFunc == ifPRODUCT ) ? 1.0 : 0.0;
     double fVal = 0.0;
-    double fMem = 0.0;
-    BOOL bNull = TRUE;
+    double fMem = 0.0; // first numeric value.
+    bool bNull = true;
     ULONG nCount = 0;
     ScAddress aAdr;
     ScRange aRange;
@@ -3219,7 +3222,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
                     case ifSUM:
                         if ( bNull && fVal != 0.0 )
                         {
-                            bNull = FALSE;
+                            bNull = false;
                             fMem = fVal;
                         }
                         else
@@ -3270,7 +3273,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
                         case ifSUM:
                             if ( bNull && fVal != 0.0 )
                             {
-                                bNull = FALSE;
+                                bNull = false;
                                 fMem = fVal;
                             }
                             else
@@ -3328,7 +3331,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
                             case ifSUM:
                                 if ( bNull && fVal != 0.0 )
                                 {
-                                    bNull = FALSE;
+                                    bNull = false;
                                     fMem = fVal;
                                 }
                                 else
@@ -3400,7 +3403,7 @@ double ScInterpreter::IterateParameters( ScIterFunc eFunc, BOOL bTextAsZero )
                                         SetError(nErr);
                                         if ( bNull && fVal != 0.0 )
                                         {
-                                            bNull = FALSE;
+                                            bNull = false;
                                             fMem = fVal;
                                         }
                                         else
commit cb9594579083db2619336d7280ba93b2c899a6f4
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 16:24:39 2010 -0500

    Use sparse matrix when building an external range data.

diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index cbdff8f..ef514bb 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -585,11 +585,8 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
         }
 
         ScMatrixRef xMat = new ScMatrix(
-            static_cast<SCSIZE>(nDataCol2-nDataCol1+1), static_cast<SCSIZE>(nDataRow2-nDataRow1+1));
-
-#if 0
-        // TODO: Switch to this code block once we have support for sparsely-filled
-        // matrices in ScMatrix.
+            static_cast<SCSIZE>(nDataCol2-nDataCol1+1),
+            static_cast<SCSIZE>(nDataRow2-nDataRow1+1), ScMatrix::SPARSE_EMPTY);
 
         // Only fill non-empty cells, for better performance.
         vector<SCROW> aRows;
@@ -621,40 +618,6 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
                 }
             }
         }
-#else
-        vector<SCROW> aRows;
-        pTab->getAllRows(aRows, nDataRow1, nDataRow2);
-        if (aRows.empty())
-            // Cache is empty.
-            return TokenArrayRef();
-        else
-            // Trim the column below the last non-empty row.
-            nDataRow2 = aRows.back();
-
-        // Empty all matrix elements first, and fill only non-empty elements.
-        for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow)
-        {
-            for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol)
-            {
-                TokenRef pToken = pTab->getCell(nCol, nRow);
-                SCSIZE nC = nCol - nCol1, nR = nRow - nRow1;
-                if (!pToken)
-                    return TokenArrayRef();
-
-                switch (pToken->GetType())
-                {
-                    case svDouble:
-                        xMat->PutDouble(pToken->GetDouble(), nC, nR);
-                    break;
-                    case svString:
-                        xMat->PutString(pToken->GetString(), nC, nR);
-                    break;
-                    default:
-                        xMat->PutEmpty(nC, nR);
-                }
-            }
-        }
-#endif
 
         if (!bFirstTab)
             pArray->AddOpCode(ocSep);
commit 505caa5b84bbd5a8e9404929dda7084430ba63d5
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 15:42:21 2010 -0500

    Removed TODO comment as it's already been completed.

diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index fa915e9..cbdff8f 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -2048,10 +2048,6 @@ const ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId)
     {
         // document already loaded.
 
-        // TODO: Find out a way to access a document that's already open in
-        // memory and re-use that instance, instead of loading it from the
-        // disk again.
-
         SfxObjectShell* p = itr->second.maShell;
         itr->second.maLastAccess = Time();
         return static_cast<ScDocShell*>(p)->GetDocument();
commit e5df155b3a9445df94572304d42c39756bd5cc48
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 15:38:51 2010 -0500

    Template name change: quad_type_matrix -> mixed_type_matrix.

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 43cd50f..1af02d7 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -43,7 +43,7 @@
 #include <math.h>
 
 #define MDDS_HASH_CONTAINER_STLPORT 1
-#include <mdds/quad_type_matrix.hpp>
+#include <mdds/mixed_type_matrix.hpp>
 
 using ::std::pair;
 using ::mdds::matrix_element_t;
@@ -52,7 +52,7 @@ using ::mdds::matrix_element_t;
 
 namespace {
 
-typedef ::mdds::quad_type_matrix<String, sal_uInt8> MatrixImplType;
+typedef ::mdds::mixed_type_matrix<String, sal_uInt8> MatrixImplType;
 
 struct ElemEqual : public ::std::unary_function<double, bool>
 {
commit f390aab2bba4ebd1144ee8cb00155b4bccb2a5ae
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 02:20:46 2010 -0500

    Removed ScMatrix::Delete().

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 5f9b9c9..1407f56 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -225,22 +225,15 @@ public:
         MUST be at least of the size of the original matrix. */
     ScMatrix* CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows, DensityType eType) const;
 
-    inline  void    IncRef() const
+    inline void IncRef() const
     {
         ++nRefCnt;
     }
-    inline  void    DecRef() const
+    inline void DecRef() const
     {
-        if ( nRefCnt > 0 )
-            if ( --nRefCnt == 0 )
-                delete this;
-    }
-    inline  void    Delete()
-    {
-        if ( nRefCnt == 0 )
+        --nRefCnt;
+        if (nRefCnt == 0)
             delete this;
-        else
-            --nRefCnt;
     }
 
     DensityType GetDensityType() const;
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 780bdc0..f398985 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -333,7 +333,7 @@ void ScInterpreter:: ScLCM()
 ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR)
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::GetNewMat" );
-    ScMatrix* pMat = new ScMatrix( nC, nR);
+    ScMatrixRef pMat = new ScMatrix( nC, nR);
     pMat->SetErrorInterpreter( this);
     // A temporary matrix is mutable and ScMatrix::CloneIfConst() returns the 
     // very matrix.
@@ -343,8 +343,7 @@ ScMatrixRef ScInterpreter::GetNewMat(SCSIZE nC, SCSIZE nR)
     if ( nCols != nC || nRows != nR )
     {   // arbitray limit of elements exceeded
         SetError( errStackOverflow);
-        pMat->Delete();
-        pMat = NULL;
+        pMat.reset();
     }
     return pMat;
 }
commit bfb303dadd859fcde5170f77adff15f9c1a75504
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 01:59:24 2010 -0500

    Implemented ScMatrixRef using boost::intrusive_ptr.

diff --git a/sc/inc/addincol.hxx b/sc/inc/addincol.hxx
index 7055f70..d67df1e 100644
--- a/sc/inc/addincol.hxx
+++ b/sc/inc/addincol.hxx
@@ -231,7 +231,7 @@ public:
 
     USHORT				GetErrCode() const		{ return nErrCode; }
     BOOL				HasString() const		{ return bHasString; }
-    BOOL				HasMatrix() const		{ return ( xMatrix.Is() ); }
+    bool                HasMatrix() const       { return xMatrix.get(); }
     BOOL				HasVarRes() const		{ return ( xVarRes.is() ); }
     double				GetValue() const		{ return fValue; }
     const String&		GetString() const		{ return aString; }
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 0a0f4e2..c7d792e 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -35,8 +35,9 @@
 #include <com/sun/star/uno/Reference.hxx>
 #include <rtl/ref.hxx>
 #include "scdllapi.h"
-#include "table.hxx"		// FastGetRowHeight (inline)
 #include "rangelst.hxx"
+#include "table.hxx"
+#include "scmatrix.hxx"
 #include "brdcst.hxx"
 #include "tabopparams.hxx"
 #include "formula/grammar.hxx"
@@ -681,12 +682,12 @@ public:
     /** Tries to find a DDE link or creates a new, if not extant.
         @param pResults  If not 0, sets the matrix as as DDE link result matrix (also for existing links).
         @return  true = DDE link found; false = Unpredictable error occurred, no DDE link created. */
-    SC_DLLPUBLIC bool            CreateDdeLink( const String& rAppl, const String& rTopic, const String& rItem, BYTE nMode, ScMatrix* pResults = NULL );
+    SC_DLLPUBLIC bool            CreateDdeLink( const String& rAppl, const String& rTopic, const String& rItem, BYTE nMode, ScMatrixRef pResults );
     /** Sets a result matrix for the specified DDE link.
         @param nDdePos  Index of the DDE link (does not include other links from link manager).
         @param pResults  The array containing all results of the DDE link (intrusive-ref-counted, do not delete).
         @return  true = DDE link found and matrix set. */
-    bool            SetDdeLinkResultMatrix( USHORT nDdePos, ScMatrix* pResults );
+    bool            SetDdeLinkResultMatrix( USHORT nDdePos, ScMatrixRef pResults );
 
 
     SfxBindings*	GetViewBindings();
diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 6372c3c..5f9b9c9 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -30,11 +30,12 @@
 #define SC_MATRIX_HXX
 
 #include "global.hxx"
-#include "formula/intruref.hxx"
 #include "formula/errorcodes.hxx"
 #include <tools/string.hxx>
 #include "scdllapi.h"
 
+#include <boost/intrusive_ptr.hpp>
+
 class SvStream;
 class ScInterpreter;
 class SvNumberFormatter;
@@ -134,7 +135,7 @@ struct ScMatrixValue
 class SC_DLLPUBLIC ScMatrix
 {
     ScMatrixImpl*   pImpl;
-    mutable ULONG   nRefCnt;    // reference count
+    mutable size_t  nRefCnt;    // reference count
 
     // only delete via Delete()
     ~ScMatrix();
@@ -355,10 +356,18 @@ public:
     // to be numerically safe.
 };
 
+inline void intrusive_ptr_add_ref(const ScMatrix* p)
+{
+    p->IncRef();
+}
 
-typedef formula::SimpleIntrusiveReference< class ScMatrix > ScMatrixRef;
-typedef formula::SimpleIntrusiveReference< const class ScMatrix > ScConstMatrixRef;
+inline void intrusive_ptr_release(const ScMatrix* p)
+{
+    p->DecRef();
+}
 
+typedef ::boost::intrusive_ptr<ScMatrix> ScMatrixRef;
+typedef ::boost::intrusive_ptr<const ScMatrix> ScConstMatrixRef;
 
 #endif  // SC_MATRIX_HXX
 
diff --git a/sc/inc/token.hxx b/sc/inc/token.hxx
index 424e1e4..68ab308 100644
--- a/sc/inc/token.hxx
+++ b/sc/inc/token.hxx
@@ -175,7 +175,7 @@ class ScMatrixToken : public ScToken
 private:
             ScMatrixRef         pMatrix;
 public:
-                                ScMatrixToken( ScMatrix* p ) :
+                                ScMatrixToken( ScMatrixRef p ) :
                                     ScToken( formula::svMatrix ), pMatrix( p ) {}
                                 ScMatrixToken( const ScMatrixToken& r ) :
                                     ScToken( r ), pMatrix( r.pMatrix ) {}
@@ -327,7 +327,7 @@ protected:
             ScConstMatrixRef    xMatrix;
             formula::FormulaConstTokenRef     xUpperLeft;
 public:
-                                ScMatrixCellResultToken( ScMatrix* pMat, formula::FormulaToken* pUL ) :
+                                ScMatrixCellResultToken( const ScConstMatrixRef& pMat, formula::FormulaToken* pUL ) :
                                     ScToken( formula::svMatrixCell ),
                                     xMatrix( pMat), xUpperLeft( pUL) {}
                                 ScMatrixCellResultToken( const ScMatrixCellResultToken& r ) :
diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
index 62be11a..686ba41 100644
--- a/sc/inc/tokenarray.hxx
+++ b/sc/inc/tokenarray.hxx
@@ -30,6 +30,7 @@
 #define SC_TOKENARRAY_HXX
 
 #include "formula/token.hxx"
+#include "scmatrix.hxx"
 #include <tools/solar.h>
 #include "scdllapi.h"
 #include <formula/tokenarray.hxx>
@@ -74,7 +75,7 @@ public:
     formula::FormulaToken* AddExternalName( sal_uInt16 nFileId, const String& rName );
     formula::FormulaToken* AddExternalSingleReference( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef );
     formula::FormulaToken* AddExternalDoubleReference( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef );
-    formula::FormulaToken* AddMatrix( ScMatrix* p );
+    formula::FormulaToken* AddMatrix( const ScMatrixRef& p );
     /** ScSingleRefOpToken with ocColRowName. */
     formula::FormulaToken* AddColRowName( const ScSingleRefData& rRef );
     virtual formula::FormulaToken* MergeArray( );
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 2724df1..f5037c2 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1716,7 +1716,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
             bDirty = FALSE;
             bTableOpDirty = FALSE;
         }
-        if( aResult.GetMatrix().Is() )
+        if( aResult.GetMatrix() )
         {
             // If the formula wasn't entered as a matrix formula, live on with
             // the upper left corner and let reference counting delete the matrix.
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index a83a63f..82dd020 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -538,12 +538,12 @@ const ScMatrix* ScFormulaCell::GetMatrix()
     {
         // Was stored !bDirty but an accompanying matrix cell was bDirty?
         // => we need to get the matrix.
-        if (!bDirty && cMatrixFlag == MM_FORMULA && !aResult.GetMatrix().Is())
+        if (!bDirty && cMatrixFlag == MM_FORMULA && !aResult.GetMatrix())
             bDirty = TRUE;
         if ( IsDirtyOrInTableOpDirty() )
             Interpret();
     }
-    return aResult.GetMatrix();
+    return aResult.GetMatrix().get();
 }
 
 BOOL ScFormulaCell::GetMatrixOrigin( ScAddress& rPos ) const
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 1e9b4e1..ffc41b6 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -1286,7 +1286,7 @@ const ScMatrix* ScDocument::GetDdeLinkResultMatrix( USHORT nDdePos ) const
     return pDdeLink ? pDdeLink->GetResult() : NULL;
 }
 
-bool ScDocument::CreateDdeLink( const String& rAppl, const String& rTopic, const String& rItem, BYTE nMode, ScMatrix* pResults )
+bool ScDocument::CreateDdeLink( const String& rAppl, const String& rTopic, const String& rItem, BYTE nMode, ScMatrixRef pResults )
 {
     /*  Create a DDE link without updating it (i.e. for Excel import), to prevent
         unwanted connections. First try to find existing link. Set result array
@@ -1312,7 +1312,7 @@ bool ScDocument::CreateDdeLink( const String& rAppl, const String& rTopic, const
     return false;
 }
 
-bool ScDocument::SetDdeLinkResultMatrix( USHORT nDdePos, ScMatrix* pResults )
+bool ScDocument::SetDdeLinkResultMatrix( USHORT nDdePos, ScMatrixRef pResults )
 {
     if( ScDdeLink* pDdeLink = lclGetDdeLink( GetLinkManager(), nDdePos ) )
     {
diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx
index 26789aa..051a349 100644
--- a/sc/source/core/data/validat.cxx
+++ b/sc/source/core/data/validat.cxx
@@ -672,7 +672,7 @@ bool ScValidationData::GetSelectionFromFormula( TypedScStrCollection* pStrings,
             xMatRef->PutString( aStr, 0);
         }
 
-        pValues = xMatRef;
+        pValues = xMatRef.get();
     }
 
     // which index matched.  We will want it eventually to pre-select that item.
diff --git a/sc/source/core/inc/ddelink.hxx b/sc/source/core/inc/ddelink.hxx
index 48b9276..289fae7 100644
--- a/sc/source/core/inc/ddelink.hxx
+++ b/sc/source/core/inc/ddelink.hxx
@@ -76,8 +76,8 @@ public:
 
                                             // fuer Interpreter:
 
-    const ScMatrix* GetResult() const           { return pResult; }
-    void            SetResult( ScMatrix* pRes ) { pResult = pRes; }
+    const ScMatrix* GetResult() const           { return pResult.get(); }
+    void            SetResult( ScMatrixRef pRes ) { pResult = pRes; }
 
                                             // XML and Excel import after NewData()
     ScMatrixRef     GetModifiableResult()   { return pResult; }
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 07f95ba..91fcb31 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -340,7 +340,7 @@ void PushExternalSingleRef(sal_uInt16 nFileId, const String& rTabName,
 void PushExternalDoubleRef(sal_uInt16 nFileId, const String& rTabName,
                            SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
                            SCCOL nCol2, SCROW nRow2, SCTAB nTab2);
-void PushMatrix(ScMatrix* pMat);
+void PushMatrix(const ScMatrixRef& pMat);
 void PushError( USHORT nError );
 /// Raw stack type without default replacements.
 formula::StackVar GetRawStackType();
@@ -400,7 +400,7 @@ double Compare();
         NULL means case sensitivity document option is to be used!
  */
 ScMatrixRef CompareMat( ScCompareOptions* pOptions = NULL );
-ScMatrixRef QueryMat( ScMatrix* pMat, ScCompareOptions& rOptions );
+ScMatrixRef QueryMat( const ScMatrixRef& pMat, ScCompareOptions& rOptions );
 void ScEqual();
 void ScNotEqual();
 void ScLess();
@@ -663,14 +663,14 @@ void ScLCM();
 //-------------------------- Matrixfunktionen ---------------------------------
 
 void ScMatValue();
-void MEMat(ScMatrix* mM, SCSIZE n);
+void MEMat(const ScMatrixRef& mM, SCSIZE n);
 void ScMatDet();
 void ScMatInv();
 void ScMatMult();
 void ScMatTrans();
 void ScEMat();
 void ScMatRef();
-ScMatrixRef MatConcat(ScMatrix* pMat1, ScMatrix* pMat2);
+ScMatrixRef MatConcat(const ScMatrixRef& pMat1, const ScMatrixRef& pMat2);
 void ScSumProduct();
 void ScSumX2MY2();
 void ScSumX2DY2();
diff --git a/sc/source/core/inc/jumpmatrix.hxx b/sc/source/core/inc/jumpmatrix.hxx
index 351cbc6..46fe43f 100644
--- a/sc/source/core/inc/jumpmatrix.hxx
+++ b/sc/source/core/inc/jumpmatrix.hxx
@@ -162,7 +162,7 @@ public:
             void                SetJumpParameters( ScTokenVec* p )
                                     { pParams = p; }
             const ScTokenVec*   GetJumpParameters() const { return pParams; }
-            ScMatrix*           GetResultMatrix() const { return pMat; }
+            ScMatrix*           GetResultMatrix() const { return pMat.get(); }
             void                GetPos( SCSIZE& rCol, SCSIZE& rRow ) const
                                     {
                                         rCol = nCurCol;
diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx
index 16891aa..ed7eb29 100644
--- a/sc/source/core/tool/addincol.cxx
+++ b/sc/source/core/tool/addincol.cxx
@@ -1668,17 +1668,16 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
                         xMatrix = new ScMatrix(
                                 static_cast<SCSIZE>(nMaxColCount),
                                 static_cast<SCSIZE>(nRowCount) );
-                        ScMatrix* pMatrix = xMatrix;
                         for (nRow=0; nRow<nRowCount; nRow++)
                         {
                             long nColCount = pRowArr[nRow].getLength();
                             const INT32* pColArr = pRowArr[nRow].getConstArray();
                             for (nCol=0; nCol<nColCount; nCol++)
-                                pMatrix->PutDouble( pColArr[nCol],
+                                xMatrix->PutDouble( pColArr[nCol],
                                         static_cast<SCSIZE>(nCol),
                                         static_cast<SCSIZE>(nRow) );
                             for (nCol=nColCount; nCol<nMaxColCount; nCol++)
-                                pMatrix->PutDouble( 0.0,
+                                xMatrix->PutDouble( 0.0,
                                         static_cast<SCSIZE>(nCol),
                                         static_cast<SCSIZE>(nRow) );
                         }
@@ -1711,17 +1710,16 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
                         xMatrix = new ScMatrix(
                                 static_cast<SCSIZE>(nMaxColCount),
                                 static_cast<SCSIZE>(nRowCount) );
-                        ScMatrix* pMatrix = xMatrix;
                         for (nRow=0; nRow<nRowCount; nRow++)
                         {
                             long nColCount = pRowArr[nRow].getLength();
                             const double* pColArr = pRowArr[nRow].getConstArray();
                             for (nCol=0; nCol<nColCount; nCol++)
-                                pMatrix->PutDouble( pColArr[nCol],
+                                xMatrix->PutDouble( pColArr[nCol],
                                         static_cast<SCSIZE>(nCol),
                                         static_cast<SCSIZE>(nRow) );
                             for (nCol=nColCount; nCol<nMaxColCount; nCol++)
-                                pMatrix->PutDouble( 0.0,
+                                xMatrix->PutDouble( 0.0,
                                         static_cast<SCSIZE>(nCol),
                                         static_cast<SCSIZE>(nRow) );
                         }
@@ -1754,17 +1752,16 @@ void ScUnoAddInCall::SetResult( const uno::Any& rNewRes )
                         xMatrix = new ScMatrix(
                                 static_cast<SCSIZE>(nMaxColCount),
                                 static_cast<SCSIZE>(nRowCount) );
-                        ScMatrix* pMatrix = xMatrix;
                         for (nRow=0; nRow<nRowCount; nRow++)
                         {
                             long nColCount = pRowArr[nRow].getLength();
                             const rtl::OUString* pColArr = pRowArr[nRow].getConstArray();
                             for (nCol=0; nCol<nColCount; nCol++)
-                                pMatrix->PutString( String( pColArr[nCol] ),
+                                xMatrix->PutString( String( pColArr[nCol] ),
                                     static_cast<SCSIZE>(nCol),
                                     static_cast<SCSIZE>(nRow) );
                             for (nCol=nColCount; nCol<nMaxColCount; nCol++)
-                                pMatrix->PutString( EMPTY_STRING,
+                                xMatrix->PutString( EMPTY_STRING,
                                         static_cast<SCSIZE>(nCol),
                                         static_cast<SCSIZE>(nRow) );
                         }
diff --git a/sc/source/core/tool/ddelink.cxx b/sc/source/core/tool/ddelink.cxx
index c48b4c6..ad72372 100644
--- a/sc/source/core/tool/ddelink.cxx
+++ b/sc/source/core/tool/ddelink.cxx
@@ -166,7 +166,7 @@ void ScDdeLink::DataChanged( const String& rMimeType,
 
     if (!nRows || !nCols)				// keine Daten
     {
-        pResult.Clear();
+        pResult.reset();
     }
     else								// Daten aufteilen
     {
@@ -233,7 +233,7 @@ void ScDdeLink::DataChanged( const String& rMimeType,
 
 void ScDdeLink::ResetValue()
 {
-    pResult.Clear();
+    pResult.reset();
 
     //	Es hat sich was getan...
     //	Tracking, FID_DATACHANGED etc. passiert von aussen
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 52edb06..67ef1cf 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -957,7 +957,7 @@ ScMatrixRef ScInterpreter::CompareMat( ScCompareOptions* pOptions )
 }
 
 
-ScMatrixRef ScInterpreter::QueryMat( ScMatrix* pMat, ScCompareOptions& rOptions )
+ScMatrixRef ScInterpreter::QueryMat( const ScMatrixRef& pMat, ScCompareOptions& rOptions )
 {
     short nSaveCurFmtType = nCurFmtType;
     short nSaveFuncFmtType = nFuncFmtType;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 1772815..31e9854 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1917,7 +1917,7 @@ void ScInterpreter::PushExternalDoubleRef(
 }
 
 
-void ScInterpreter::PushMatrix(ScMatrix* pMat)
+void ScInterpreter::PushMatrix(const ScMatrixRef& pMat)
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PushMatrix" );
     pMat->SetErrorInterpreter( NULL);
@@ -2699,7 +2699,7 @@ void ScInterpreter::ScExternal()
                             }
                             break;
                         case svMatrix:
-                            if (!ScRangeToSequence::FillLongArray( aParam, PopMatrix() ))
+                            if (!ScRangeToSequence::FillLongArray( aParam, PopMatrix().get() ))
                                 SetError(errIllegalParameter);
                             break;
                         default:
@@ -2730,7 +2730,7 @@ void ScInterpreter::ScExternal()
                             }
                             break;
                         case svMatrix:
-                            if (!ScRangeToSequence::FillDoubleArray( aParam, PopMatrix() ))
+                            if (!ScRangeToSequence::FillDoubleArray( aParam, PopMatrix().get() ))
                                 SetError(errIllegalParameter);
                             break;
                         default:
@@ -2761,7 +2761,7 @@ void ScInterpreter::ScExternal()
                             }
                             break;
                         case svMatrix:
-                            if (!ScRangeToSequence::FillStringArray( aParam, PopMatrix(), pFormatter ))
+                            if (!ScRangeToSequence::FillStringArray( aParam, PopMatrix().get(), pFormatter ))
                                 SetError(errIllegalParameter);
                             break;
                         default:
@@ -2812,7 +2812,7 @@ void ScInterpreter::ScExternal()
                             }
                             break;
                         case svMatrix:
-                            if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() ))
+                            if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix().get() ))
                                 SetError(errIllegalParameter);
                             break;
                         default:
@@ -2858,7 +2858,7 @@ void ScInterpreter::ScExternal()
                             }
                             break;
                         case svMatrix:
-                            if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix() ))
+                            if (!ScRangeToSequence::FillMixedArray( aParam, PopMatrix().get() ))
                                 SetError(errIllegalParameter);
                             break;
                         case svMissing:
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index ce4e761..780bdc0 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -622,7 +622,7 @@ void ScInterpreter::ScMatValue()
             case svMatrix:
             {
                 ScMatrixRef pMat = PopMatrix();
-                CalculateMatrixValue(pMat,nC,nR);
+                CalculateMatrixValue(pMat.get(),nC,nR);
             }
             break;
             default:
@@ -678,7 +678,7 @@ void ScInterpreter::ScEMat()
     }
 }
 
-void ScInterpreter::MEMat(ScMatrix* mM, SCSIZE n)
+void ScInterpreter::MEMat(const ScMatrixRef& mM, SCSIZE n)
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MEMat" );
     mM->FillDouble(0.0, 0, 0, n-1, n-1);
@@ -875,7 +875,7 @@ void ScInterpreter::ScMatDet()
             else
             {
                 ::std::vector< SCSIZE> P(nR);
-                int nDetSign = lcl_LUP_decompose( xLU, nR, P);
+                int nDetSign = lcl_LUP_decompose( xLU.get(), nR, P);
                 if (!nDetSign)
                     PushInt(0);     // singular matrix
                 else
@@ -883,9 +883,8 @@ void ScInterpreter::ScMatDet()
                     // In an LU matrix the determinant is simply the product of
                     // all diagonal elements.
                     double fDet = nDetSign;
-                    ScMatrix* pLU = xLU;
                     for (SCSIZE i=0; i < nR; ++i)
-                        fDet *= pLU->GetDouble( i, i);
+                        fDet *= xLU->GetDouble( i, i);
                     PushDouble( fDet);
                 }
             }
@@ -924,13 +923,12 @@ void ScInterpreter::ScMatInv()
             else
             {
                 ::std::vector< SCSIZE> P(nR);
-                int nDetSign = lcl_LUP_decompose( xLU, nR, P);
+                int nDetSign = lcl_LUP_decompose( xLU.get(), nR, P);
                 if (!nDetSign)
                     PushIllegalArgument();
                 else
                 {
                     // Solve equation for each column.
-                    ScMatrix* pY = xY;
                     ::std::vector< double> B(nR);
                     ::std::vector< double> X(nR);
                     for (SCSIZE j=0; j < nR; ++j)
@@ -938,9 +936,9 @@ void ScInterpreter::ScMatInv()
                         for (SCSIZE i=0; i < nR; ++i)
                             B[i] = 0.0;
                         B[j] = 1.0;
-                        lcl_LUP_solve( xLU, nR, P, B, X);
+                        lcl_LUP_solve( xLU.get(), nR, P, B, X);
                         for (SCSIZE i=0; i < nR; ++i)
-                            pY->PutDouble( X[i], j, i);
+                            xY->PutDouble( X[i], j, i);
                     }
 #if OSL_DEBUG_LEVEL > 1
                     /* Possible checks for ill-condition:
@@ -964,7 +962,7 @@ void ScInterpreter::ScMatInv()
                     if (xR)
                     {
                         ScMatrix* pR = xR;
-                        lcl_MFastMult( pMat, pY, pR, nR, nR, nR);
+                        lcl_MFastMult( pMat, xY.get(), pR, nR, nR, nR);
                         fprintf( stderr, "\n%s\n", "ScMatInv(): mult-identity");
                         for (SCSIZE i=0; i < nR; ++i)
                         {
@@ -986,7 +984,7 @@ void ScInterpreter::ScMatInv()
                     if (nGlobalError)
                         PushError( nGlobalError);
                     else
-                        PushMatrix( pY);
+                        PushMatrix( xY);
                 }
             }
         }
@@ -1098,7 +1096,6 @@ ScMatrixRef lcl_MatrixCalculation(const _Function& _pOperation,ScMatrix* pMat1,
     ScMatrixRef xResMat = _pIterpreter->GetNewMat(nMinC, nMinR);
     if (xResMat)
     {
-        ScMatrix* pResMat = xResMat;
         for (i = 0; i < nMinC; i++)
         {
             for (j = 0; j < nMinR; j++)
@@ -1106,17 +1103,17 @@ ScMatrixRef lcl_MatrixCalculation(const _Function& _pOperation,ScMatrix* pMat1,
                 if (pMat1->IsValueOrEmpty(i,j) && pMat2->IsValueOrEmpty(i,j))
                 {
                     double d = _pOperation(pMat1->GetDouble(i,j),pMat2->GetDouble(i,j));
-                    pResMat->PutDouble( d, i, j);
+                    xResMat->PutDouble( d, i, j);
                 }
                 else
-                    pResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, j);
+                    xResMat->PutString(ScGlobal::GetRscString(STR_NO_VALUE), i, j);
             }
         }
     }
     return xResMat;
 }
 
-ScMatrixRef ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2)
+ScMatrixRef ScInterpreter::MatConcat(const ScMatrixRef& pMat1, const ScMatrixRef& pMat2)
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::MatConcat" );
     SCSIZE nC1, nC2, nMinC;
@@ -1129,7 +1126,6 @@ ScMatrixRef ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2)
     ScMatrixRef xResMat = GetNewMat(nMinC, nMinR);
     if (xResMat)
     {
-        ScMatrix* pResMat = xResMat;
         for (i = 0; i < nMinC; i++)
         {
             for (j = 0; j < nMinR; j++)
@@ -1138,12 +1134,12 @@ ScMatrixRef ScInterpreter::MatConcat(ScMatrix* pMat1, ScMatrix* pMat2)
                 if (!nErr)
                     nErr = pMat2->GetErrorIfNotString( i, j);
                 if (nErr)
-                    pResMat->PutError( nErr, i, j);
+                    xResMat->PutError( nErr, i, j);
                 else
                 {
                     String aTmp( pMat1->GetString( *pFormatter, i, j));
                     aTmp += pMat2->GetString( *pFormatter, i, j);
-                    pResMat->PutString( aTmp, i, j);
+                    xResMat->PutString( aTmp, i, j);
                 }
             }
         }
@@ -1244,12 +1240,12 @@ void ScInterpreter::CalculateAddSub(BOOL _bSub)
         if ( _bSub )
         {
             MatrixSub aSub;
-            pResMat = lcl_MatrixCalculation(aSub ,pMat1, pMat2,this);
+            pResMat = lcl_MatrixCalculation(aSub ,pMat1.get(), pMat2.get(),this);
         }
         else
         {
             MatrixAdd aAdd;
-            pResMat = lcl_MatrixCalculation(aAdd ,pMat1, pMat2,this);
+            pResMat = lcl_MatrixCalculation(aAdd ,pMat1.get(), pMat2.get(),this);
         }
 
         if (!pResMat)
@@ -1457,7 +1453,7 @@ void ScInterpreter::ScMul()
     if (pMat1 && pMat2)
     {
         MatrixMul aMul;
-        ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1, pMat2,this);
+        ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1.get(), pMat2.get(),this);
         if (!pResMat)
             PushNoValue();
         else
@@ -1532,7 +1528,7 @@ void ScInterpreter::ScDiv()
     if (pMat1 && pMat2)
     {
         MatrixDiv aDiv;
-        ScMatrixRef pResMat = lcl_MatrixCalculation(aDiv,pMat1, pMat2,this);
+        ScMatrixRef pResMat = lcl_MatrixCalculation(aDiv,pMat1.get(), pMat2.get(),this);
         if (!pResMat)
             PushNoValue();
         else
@@ -1614,7 +1610,7 @@ void ScInterpreter::ScPow()
     if (pMat1 && pMat2)
     {
         MatrixPow aPow;
-        ScMatrixRef pResMat = lcl_MatrixCalculation(aPow,pMat1, pMat2,this);
+        ScMatrixRef pResMat = lcl_MatrixCalculation(aPow,pMat1.get(), pMat2.get(),this);
         if (!pResMat)
             PushNoValue();
         else
@@ -1700,7 +1696,7 @@ void ScInterpreter::ScSumProduct()
             PushNoValue();
             return;
         }
-        ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1, pMat,this);
+        ScMatrixRef pResMat = lcl_MatrixCalculation(aMul,pMat1.get(), pMat.get(),this);
         if (!pResMat)
         {
             PushNoValue();
@@ -1796,7 +1792,7 @@ void ScInterpreter::ScSumXMY2()
         return;
     } // if (nC1 != nC2 || nR1 != nR2)
     MatrixSub aSub;
-    ScMatrixRef pResMat = lcl_MatrixCalculation(aSub,pMat1, pMat2,this);
+    ScMatrixRef pResMat = lcl_MatrixCalculation(aSub,pMat1.get(), pMat2.get(),this);
     if (!pResMat)
     {
         PushNoValue();
diff --git a/sc/source/core/tool/rangeseq.cxx b/sc/source/core/tool/rangeseq.cxx
index 95ccdc7..8548ee8 100644
--- a/sc/source/core/tool/rangeseq.cxx
+++ b/sc/source/core/tool/rangeseq.cxx
@@ -401,9 +401,8 @@ ScMatrixRef ScSequenceToMatrix::CreateMixedMatrix( const com::sun::star::uno::An
             xMatrix = new ScMatrix(
                     static_cast<SCSIZE>(nMaxColCount),
                     static_cast<SCSIZE>(nRowCount) );
-            ScMatrix* pMatrix = xMatrix;
             SCSIZE nCols, nRows;
-            pMatrix->GetDimensions( nCols, nRows);
+            xMatrix->GetDimensions( nCols, nRows);
             if (nCols != static_cast<SCSIZE>(nMaxColCount) || nRows != static_cast<SCSIZE>(nRowCount))
             {
                 DBG_ERRORFILE( "ScSequenceToMatrix::CreateMixedMatrix: matrix exceeded max size, returning NULL matrix");
@@ -420,11 +419,11 @@ ScMatrixRef ScSequenceToMatrix::CreateMixedMatrix( const com::sun::star::uno::An
                     if (ScApiTypeConversion::ConvertAnyToDouble( fVal, eClass, pColArr[nCol]))
                     {
                         if (eClass == uno::TypeClass_BOOLEAN)
-                            pMatrix->PutBoolean( (fVal ? true : false),
+                            xMatrix->PutBoolean( (fVal ? true : false),
                                     static_cast<SCSIZE>(nCol),
                                     static_cast<SCSIZE>(nRow) );
                         else
-                            pMatrix->PutDouble( fVal,
+                            xMatrix->PutDouble( fVal,
                                     static_cast<SCSIZE>(nCol),
                                     static_cast<SCSIZE>(nRow) );
                     }
@@ -435,18 +434,18 @@ ScMatrixRef ScSequenceToMatrix::CreateMixedMatrix( const com::sun::star::uno::An
                         //Reflection* pRefl = pColArr[nCol].getReflection();
                         //if ( pRefl->equals( *OUString_getReflection() ) )
                         if ( pColArr[nCol] >>= aUStr )
-                            pMatrix->PutString( String( aUStr ),
+                            xMatrix->PutString( String( aUStr ),
                                     static_cast<SCSIZE>(nCol),
                                     static_cast<SCSIZE>(nRow) );
                         else
-                            pMatrix->PutEmpty(
+                            xMatrix->PutEmpty(
                                     static_cast<SCSIZE>(nCol),
                                     static_cast<SCSIZE>(nRow) );
                     }
                 }
                 for (nCol=nColCount; nCol<nMaxColCount; nCol++)
                 {
-                    pMatrix->PutEmpty(
+                    xMatrix->PutEmpty(
                             static_cast<SCSIZE>(nCol),
                             static_cast<SCSIZE>(nRow) );
                 }
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 481194b..5dc7877 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -789,8 +789,8 @@ BOOL ScRefListToken::operator==( const FormulaToken& r ) const
 }
 
 
-const ScMatrix* ScMatrixToken::GetMatrix() const        { return pMatrix; }
-ScMatrix*       ScMatrixToken::GetMatrix()              { return pMatrix; }
+const ScMatrix* ScMatrixToken::GetMatrix() const        { return pMatrix.get(); }
+ScMatrix*       ScMatrixToken::GetMatrix()              { return pMatrix.get(); }
 BOOL ScMatrixToken::operator==( const FormulaToken& r ) const
 {
     return FormulaToken::operator==( r ) && pMatrix == static_cast<const ScToken&>(r).GetMatrix();
@@ -1027,7 +1027,7 @@ BOOL ScEmptyCellToken::operator==( const FormulaToken& r ) const
 
 double          ScMatrixCellResultToken::GetDouble() const  { return xUpperLeft->GetDouble(); }
 const String &  ScMatrixCellResultToken::GetString() const  { return xUpperLeft->GetString(); }
-const ScMatrix* ScMatrixCellResultToken::GetMatrix() const  { return xMatrix; }
+const ScMatrix* ScMatrixCellResultToken::GetMatrix() const  { return xMatrix.get(); }
 // Non-const GetMatrix() is private and unused but must be implemented to
 // satisfy vtable linkage.
 ScMatrix* ScMatrixCellResultToken::GetMatrix()
@@ -1580,7 +1580,7 @@ FormulaToken* ScTokenArray::AddDoubleReference( const ScComplexRefData& rRef )
     return Add( new ScDoubleRefToken( rRef ) );
 }
 
-FormulaToken* ScTokenArray::AddMatrix( ScMatrix* p )
+FormulaToken* ScTokenArray::AddMatrix( const ScMatrixRef& p )
 {
     return Add( new ScMatrixToken( p ) );
 }
diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx
index d064edd..5568b4c 100644
--- a/sc/source/filter/excel/excform.cxx
+++ b/sc/source/filter/excel/excform.cxx
@@ -696,7 +696,7 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s
                         aPool	<< ocDde << ocOpen << nPar1 << ocSep << nPar2 << ocSep
                                 << nMerk0 << ocClose;
 
-                        GetDoc().CreateDdeLink( aAppl, aExtDoc, pExtName->aName, SC_DDE_DEFAULT );
+                        GetDoc().CreateDdeLink( aAppl, aExtDoc, pExtName->aName, SC_DDE_DEFAULT, ScMatrixRef() );
                     }
                     else
                         aPool << ocBad;
diff --git a/sc/source/filter/xml/XMLDDELinksContext.cxx b/sc/source/filter/xml/XMLDDELinksContext.cxx
index 269861a..4651389 100644
--- a/sc/source/filter/xml/XMLDDELinksContext.cxx
+++ b/sc/source/filter/xml/XMLDDELinksContext.cxx
@@ -137,7 +137,7 @@ void ScXMLDDELinkContext::CreateDDELink()
         String sAppl(sApplication);
         String sTop(sTopic);
         String sIt(sItem);
-        GetScImport().GetDocument()->CreateDdeLink(sAppl, sTop, sIt, nMode);
+        GetScImport().GetDocument()->CreateDdeLink(sAppl, sTop, sIt, nMode, ScMatrixRef());
         sal_uInt16 nPos;
         if(GetScImport().GetDocument()->FindDdeLink(sAppl, sTop, sIt, nMode, nPos))
             nPosition = nPos;
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 85dbdbe..fa915e9 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -659,8 +659,7 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
         if (!bFirstTab)
             pArray->AddOpCode(ocSep);
 
-        ScMatrix* pMat2 = xMat;
-        ScMatrixToken aToken(pMat2);
+        ScMatrixToken aToken(xMat);
         if (!pArray)
             pArray.reset(new ScTokenArray);
         pArray->AddToken(aToken);
@@ -1464,8 +1463,7 @@ static ScTokenArray* lcl_convertToTokenArray(const ScDocument* pSrcDoc, ScRange&
         if (!bFirstTab)
             pArray->AddOpCode(ocSep);
 
-        ScMatrix* pMat2 = xMat;
-        ScMatrixToken aToken(pMat2);
+        ScMatrixToken aToken(xMat);
         pArray->AddToken(aToken);
 
         itrCache->mpRangeData = xMat;
@@ -1493,8 +1491,7 @@ static ScTokenArray* lcl_fillEmptyMatrix(const ScRange& rRange)
         for (SCSIZE j = 0; j < nR; ++j)
             xMat->PutEmpty(i, j);
 
-    ScMatrix* pMat2 = xMat;
-    ScMatrixToken aToken(pMat2);
+    ScMatrixToken aToken(xMat);
     auto_ptr<ScTokenArray> pArray(new ScTokenArray);
     pArray->AddToken(aToken);
     return pArray.release();
diff --git a/sc/source/ui/unoobj/linkuno.cxx b/sc/source/ui/unoobj/linkuno.cxx
index d4e30f4..a90817e 100644
--- a/sc/source/ui/unoobj/linkuno.cxx
+++ b/sc/source/ui/unoobj/linkuno.cxx
@@ -1474,7 +1474,7 @@ uno::Reference< sheet::XDDELink > ScDDELinksObj::addDDELink(
                     break;
             }
 
-            if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod ) )
+            if ( pDoc->CreateDdeLink( aApplication, aTopic, aItem, nMod, ScMatrixRef() ) )
             {
                 const ::rtl::OUString aName( lcl_BuildDDEName( aApplication, aTopic, aItem ) );
                 xLink.set( GetObjectByName_Impl( aName ) );
commit 7b83f1d178994d4a6afffd0e8e1c21751d0be2b2
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Dec 17 00:20:49 2010 -0500

    Removed the eternal ref bits, as no one uses it & we don't need it.

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index e50b821..6372c3c 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -224,23 +224,19 @@ public:
         MUST be at least of the size of the original matrix. */
     ScMatrix* CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows, DensityType eType) const;
 
-    /// Disable refcounting forever, may only be deleted via Delete() afterwards.
-    inline  void    SetEternalRef()         { nRefCnt = ULONG_MAX; }
-    inline  bool    IsEternalRef() const    { return nRefCnt == ULONG_MAX; }
     inline  void    IncRef() const
     {
-        if ( !IsEternalRef() )
-            ++nRefCnt;
+        ++nRefCnt;
     }
     inline  void    DecRef() const
     {
-        if ( nRefCnt > 0 && !IsEternalRef() )
+        if ( nRefCnt > 0 )
             if ( --nRefCnt == 0 )
                 delete this;
     }
     inline  void    Delete()
     {
-        if ( nRefCnt == 0 || IsEternalRef() )
+        if ( nRefCnt == 0 )
             delete this;
         else
             --nRefCnt;
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 9f778e6..43cd50f 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -772,7 +772,7 @@ ScMatrix* ScMatrix::Clone( DensityType eType) const
 
 ScMatrix* ScMatrix::CloneIfConst()
 {
-    return (pImpl->IsImmutable() || IsEternalRef()) ? Clone() : this;
+    return pImpl->IsImmutable() ? Clone() : this;
 }
 
 void ScMatrix::SetImmutable( bool bVal )
commit 221fb24c064579d090e57c14bedb2431b488c332
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 23:51:25 2010 -0500

    Removed parts of the comments that are no longer true.

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 8e822bc..e50b821 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -201,9 +201,6 @@ public:
         return (nType & SC_MATVAL_NONVALUE) == SC_MATVAL_EMPTYPATH;
     }
 
-    /** If nC*nR results in more than GetElementsMax() entries, a 1x1 matrix is
-        created instead and a double error value (errStackOverflow) is set.
-        Compare nC and nR with a GetDimensions() call to check. */
     ScMatrix( SCSIZE nC, SCSIZE nR, DensityType eType = FILLED_ZERO);
 
     /** Clone the matrix. */
@@ -219,8 +216,7 @@ public:
     void SetImmutable( bool bVal );
 
     /** 
-     * Resize the matrix to specified new dimension.  Note that this operation
-     * clears all stored values. 
+     * Resize the matrix to specified new dimension.
      */
     void Resize( SCSIZE nC, SCSIZE nR);
 
commit bcc1861be3fab35f34b74c27d531bfd57eee5739
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 23:34:38 2010 -0500

    Re-wrote header description for ScMatrix.

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 2d1de85..8e822bc 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -121,34 +121,15 @@ struct ScMatrixValue
     }
 };
 
-/** Matrix representation of double values and strings.
-
-    @ATTENTION: optimized for speed and double values.
-
-    <p> Matrix elements are NOT initialized after construction!
-
-    <p> All methods using an SCSIZE nIndex parameter and all Is...() methods do
-    NOT check the range for validity! However, the Put...() and Get...()
-    methods using nCol/nRow parameters do check the range.
-
-    <p> Methods using nCol/nRow parameters do replicate a single row vector if
-    nRow &gt; 0 and nCol &lt; nColCount, respectively a column vector if nCol
-    &gt; 0 and nRow &lt; nRowCount.
-
-    <p> GetString( SCSIZE nIndex ) does not check if there really is a string,
-    do this with IsString() first. GetString( SCSIZE nC, SCSIZE nR ) does check
-    it and returns and empty string if there is no string. Both GetDouble()
-    methods don't check for a string, do this with IsNumeric() or IsString() or
-    IsValue() first.
-
-    <p> The GetString( SvNumberFormatter&, ...) methods return the matrix
-    element's string if one is present, otherwise the numerical value is
-    formatted as a string, or in case of an error the error string is returned.
-
-    <p> PutDouble() does not reset an eventual string! Use
-    PutDoubleAndResetString() if that is wanted. Also the FillDouble...()
-    methods don't reset strings. As a consequence memory leaks may occur if
-    used wrong.
+/**
+ * Matrix data type that can store values of mixed types.  Each element can
+ * be one of the following types: numeric, string, boolean, empty, and empty
+ * path.
+ *
+ * This class also supports four different density types: filled zero,
+ * filled empty, sparse zero, and sparse empty.  The filled density type
+ * allocates memory for every single element at all times, whereas the
+ * sparse density types allocates memory only for non-default elements.
  */
 class SC_DLLPUBLIC ScMatrix
 {
commit 04e014bbf864e30576eb4e5c10bc87a4eafd2c10
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 21:55:48 2010 -0500

    Unit test for matrix's And and Or evaluations.

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index ce8b522..77e8d5f 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -291,6 +291,8 @@ void Test::testMatrix()
         pMat->Resize(4, 10);
         pMat->GetDimensions(nC, nR);
         CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 4 && nR == 10);
+        CPPUNIT_ASSERT_MESSAGE("both 'and' and 'or' should evaluate to false",
+                               !pMat->And() && !pMat->Or());
 
         // Resizing into a larger matrix should fill the void space with zeros.
         checkMatrixElements<AllZeroMatrix>(*pMat);
@@ -298,6 +300,11 @@ void Test::testMatrix()
         pMat->FillDouble(3.0, 1, 2, 2, 8);
         checkMatrixElements<PartiallyFilledZeroMatrix>(*pMat);
         CPPUNIT_ASSERT_MESSAGE("matrix is expected to be numeric", pMat->IsNumeric());
+        CPPUNIT_ASSERT_MESSAGE("partially non-zero matrix should evaluate false on 'and' and true on 'or",
+                               !pMat->And() && pMat->Or());
+        pMat->FillDouble(5.0, 0, 0, nC-1, nR-1);
+        CPPUNIT_ASSERT_MESSAGE("fully non-zero matrix should evaluate true both on 'and' and 'or",
+                               pMat->And() && pMat->Or());
     }
 
     // Now test the emtpy matrix types.
commit ce8a33e2f99049c4ec88bbcf3e378be35d7dbbab
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 21:48:30 2010 -0500

    Test for empty path element type.

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 9119420..ce8b522 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -261,6 +261,11 @@ struct PartiallyFilledEmptyMatrix
             CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_STRING);
             CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.pS->EqualsAscii("Test"));
         }
+        else if (nCol == 8 && nRow == 11)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of empty path type", rVal.nType == SC_MATVAL_EMPTYPATH);
+            CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
+        }
         else
         {
             CPPUNIT_ASSERT_MESSAGE("element is not of empty type", rVal.nType == SC_MATVAL_EMPTY);
@@ -310,6 +315,7 @@ void Test::testMatrix()
         pMat->PutDouble(-12.5, 4, 5);
         rtl::OUString aStr(RTL_CONSTASCII_USTRINGPARAM("Test"));
         pMat->PutString(aStr, 8, 2);
+        pMat->PutEmptyPath(8, 11);
         checkMatrixElements<PartiallyFilledEmptyMatrix>(*pMat);
     }
 }
commit 8ed18c28432bd451bee3c6fb0925191e2989c266
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 21:46:45 2010 -0500

    Removed code duplication with template.

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index efe1907..9f778e6 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -518,7 +518,7 @@ ScMatrixValue ScMatrixImpl::Get(SCSIZE nC, SCSIZE nR) const
             break;
             case mdds::element_empty:
                 // Empty path equals empty plus flag.
-                aVal.nType == maMat.get_flag(nR, nC) ? SC_MATVAL_EMPTYPATH : SC_MATVAL_EMPTY;
+                aVal.nType = maMat.get_flag(nR, nC) ? SC_MATVAL_EMPTYPATH : SC_MATVAL_EMPTY;
                 aVal.fVal = 0.0;
             default:
                 ;
@@ -677,58 +677,63 @@ void ScMatrixImpl::CompareGreaterEqual()
     compareMatrix<ElemGreaterEqual>(maMat);
 }
 
-double ScMatrixImpl::And()
+namespace {
+
+struct AndEvaluator
 {
-    // All elements must be of value type.
-    // True only if all the elements have non-zero values.
-    pair<size_t,size_t> aDim = maMat.size();
+    bool isBadElem(double fVal) const { return fVal == 0; }
+    bool returnOnElem() const { return false; }
+    bool returnOnAllElems() const { return true; }
+};
+
+struct OrEvaluator
+{
+    bool isBadElem(double fVal) const { return fVal != 0; }
+    bool returnOnElem() const { return true; }
+    bool returnOnAllElems() const { return false; }
+};
+
+template <typename _Evaluator>
+bool EvalMatrix(const MatrixImplType& rMat)
+{
+    _Evaluator aEval;
+    pair<size_t,size_t> aDim = rMat.size();
     size_t nRows = aDim.first, nCols = aDim.second;
     for (size_t i = 0; i < nRows; ++i)
     {
         for (size_t j = 0; j < nCols; ++j)
         {
-            matrix_element_t eType = maMat.get_type(i, j);
+            matrix_element_t eType = rMat.get_type(i, j);
             if (eType != mdds::element_numeric && eType == mdds::element_boolean)
                 // assuming a CompareMat this is an error
                 return CreateDoubleError(errIllegalArgument);
 
-            double fVal = maMat.get_numeric(i, j);
+            double fVal = rMat.get_numeric(i, j);
             if (!::rtl::math::isFinite(fVal))
                 // DoubleError
                 return fVal;
 
-            if (fVal == 0.0)
-                return false;
+            if (aEval.isBadElem(fVal))
+                return aEval.returnOnElem();
         }
     }
-    return true;
+    return aEval.returnOnAllElems();
+}
+
+}
+
+double ScMatrixImpl::And()
+{
+    // All elements must be of value type.
+    // True only if all the elements have non-zero values.
+    return EvalMatrix<AndEvaluator>(maMat);
 }
 
 double ScMatrixImpl::Or()
 {
     // All elements must be of value type.
     // True if at least one element has a non-zero value.
-    pair<size_t,size_t> aDim = maMat.size();
-    size_t nRows = aDim.first, nCols = aDim.second;
-    for (size_t i = 0; i < nRows; ++i)
-    {
-        for (size_t j = 0; j < nCols; ++j)
-        {
-            matrix_element_t eType = maMat.get_type(i, j);
-            if (eType != mdds::element_numeric && eType == mdds::element_boolean)
-                // assuming a CompareMat this is an error
-                return CreateDoubleError(errIllegalArgument);
-
-            double fVal = maMat.get_numeric(i, j);
-            if (!::rtl::math::isFinite(fVal))
-                // DoubleError
-                return fVal;
-
-            if (fVal != 0.0)
-                return true;
-        }
-    }
-    return false;
+    return EvalMatrix<OrEvaluator>(maMat);
 }
 
 void ScMatrixImpl::CalcPosition(SCSIZE nIndex, SCSIZE& rC, SCSIZE& rR) const
commit 53c9ef796519212a392a4cd12e89dc9b5704ad9b
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 21:24:02 2010 -0500

    Check the flag value for empty "path" element type.

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 9387bf5..efe1907 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -517,8 +517,8 @@ ScMatrixValue ScMatrixImpl::Get(SCSIZE nC, SCSIZE nR) const
                 aVal.pS = maMat.get_string(nR, nC);
             break;
             case mdds::element_empty:
-                // TODO: Check for the flag value to differentiate from empty path.
-                aVal.nType == SC_MATVAL_EMPTY;
+                // Empty path equals empty plus flag.
+                aVal.nType == maMat.get_flag(nR, nC) ? SC_MATVAL_EMPTYPATH : SC_MATVAL_EMPTY;
                 aVal.fVal = 0.0;
             default:
                 ;
commit bf787331f454820e136dca65addeb8154aabe872
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 21:13:43 2010 -0500

    Wrote basic unit test for new ScMatrix implementation.

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index a358409..9119420 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -54,6 +54,7 @@
 #include <scdll.hxx>
 #include <document.hxx>
 #include <stringutil.hxx>
+#include <scmatrix.hxx>
 
 #include "preextstl.h"
 #include <cppunit/TestSuite.h>
@@ -75,11 +76,13 @@ public:
     void testSUM();
     void testNamedRange();
     void testCSV();
+    void testMatrix();
 
     CPPUNIT_TEST_SUITE(Test);
     CPPUNIT_TEST(testSUM);
     CPPUNIT_TEST(testNamedRange);
     CPPUNIT_TEST(testCSV);
+    CPPUNIT_TEST(testMatrix);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -190,6 +193,127 @@ void Test::testCSV()
     }
 }
 
+template<typename Evaluator>
+void checkMatrixElements(const ScMatrix& rMat)
+{
+    SCSIZE nC, nR;
+    rMat.GetDimensions(nC, nR);
+    Evaluator aEval;
+    for (SCSIZE i = 0; i < nC; ++i)
+    {
+        for (SCSIZE j = 0; j < nR; ++j)
+        {
+            aEval(i, j, rMat.Get(i, j));
+        }
+    }
+}
+
+struct AllZeroMatrix
+{
+    void operator() (SCSIZE /*nCol*/, SCSIZE /*nRow*/, const ScMatrixValue& rVal) const
+    {
+        CPPUNIT_ASSERT_MESSAGE("element is not of numeric type", rVal.nType == SC_MATVAL_VALUE);
+        CPPUNIT_ASSERT_MESSAGE("element value must be zero", rVal.fVal == 0.0);
+    }
+};
+
+struct PartiallyFilledZeroMatrix
+{
+    void operator() (SCSIZE nCol, SCSIZE nRow, const ScMatrixValue& rVal) const
+    {
+        CPPUNIT_ASSERT_MESSAGE("element is not of numeric type", rVal.nType == SC_MATVAL_VALUE);
+        if (1 <= nCol && nCol <= 2 && 2 <= nRow && nRow <= 8)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element value must be 3.0", rVal.fVal == 3.0);
+        }
+        else
+        {
+            CPPUNIT_ASSERT_MESSAGE("element value must be zero", rVal.fVal == 0.0);
+        }
+    }
+};
+
+struct AllEmptyMatrix
+{
+    void operator() (SCSIZE /*nCol*/, SCSIZE /*nRow*/, const ScMatrixValue& rVal) const
+    {
+        CPPUNIT_ASSERT_MESSAGE("element is not of empty type", rVal.nType == SC_MATVAL_EMPTY);
+        CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
+    }
+};
+
+struct PartiallyFilledEmptyMatrix
+{
+    void operator() (SCSIZE nCol, SCSIZE nRow, const ScMatrixValue& rVal) const
+    {
+        if (nCol == 1 && nRow == 1)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of boolean type", rVal.nType == SC_MATVAL_BOOLEAN);
+            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.fVal == 1.0);
+        }
+        else if (nCol == 4 && nRow == 5)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_VALUE);
+            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.fVal == -12.5);
+        }
+        else if (nCol == 8 && nRow == 2)
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of value type", rVal.nType == SC_MATVAL_STRING);
+            CPPUNIT_ASSERT_MESSAGE("element value is not what is expected", rVal.pS->EqualsAscii("Test"));
+        }
+        else
+        {
+            CPPUNIT_ASSERT_MESSAGE("element is not of empty type", rVal.nType == SC_MATVAL_EMPTY);
+            CPPUNIT_ASSERT_MESSAGE("value of \"empty\" element is expected to be zero", rVal.fVal == 0.0);
+        }
+    }
+};
+
+void Test::testMatrix()
+{
+    ScMatrixRef pMat;
+    ScMatrix::DensityType eDT[2];
+
+    // First, test the zero matrix types.
+    eDT[0] = ScMatrix::FILLED_ZERO;
+    eDT[1] = ScMatrix::SPARSE_ZERO;
+    for (int i = 0; i < 2; ++i)
+    {
+        pMat = new ScMatrix(0, 0, eDT[i]);
+        SCSIZE nC, nR;
+        pMat->GetDimensions(nC, nR);
+        CPPUNIT_ASSERT_MESSAGE("matrix is not empty", nC == 0 && nR == 0);
+        pMat->Resize(4, 10);
+        pMat->GetDimensions(nC, nR);
+        CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 4 && nR == 10);
+
+        // Resizing into a larger matrix should fill the void space with zeros.
+        checkMatrixElements<AllZeroMatrix>(*pMat);
+
+        pMat->FillDouble(3.0, 1, 2, 2, 8);
+        checkMatrixElements<PartiallyFilledZeroMatrix>(*pMat);
+        CPPUNIT_ASSERT_MESSAGE("matrix is expected to be numeric", pMat->IsNumeric());
+    }
+
+    // Now test the emtpy matrix types.
+    eDT[0] = ScMatrix::FILLED_EMPTY;
+    eDT[1] = ScMatrix::SPARSE_EMPTY;
+    for (int i = 0; i < 2; ++i)
+    {
+        pMat = new ScMatrix(10, 20, eDT[i]);
+        SCSIZE nC, nR;
+        pMat->GetDimensions(nC, nR);
+        CPPUNIT_ASSERT_MESSAGE("matrix size is not as expected", nC == 10 && nR == 20);
+        checkMatrixElements<AllEmptyMatrix>(*pMat);
+
+        pMat->PutBoolean(true, 1, 1);
+        pMat->PutDouble(-12.5, 4, 5);
+        rtl::OUString aStr(RTL_CONSTASCII_USTRINGPARAM("Test"));
+        pMat->PutString(aStr, 8, 2);
+        checkMatrixElements<PartiallyFilledEmptyMatrix>(*pMat);
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
 
 }
commit c5b955edf2e8b6a6f3d0a492dbbeb5684e6a69bb
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 20:54:43 2010 -0500

    Empty element is expected to have a value of zero.

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index e67e067..9387bf5 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -517,8 +517,11 @@ ScMatrixValue ScMatrixImpl::Get(SCSIZE nC, SCSIZE nR) const
                 aVal.pS = maMat.get_string(nR, nC);
             break;
             case mdds::element_empty:
+                // TODO: Check for the flag value to differentiate from empty path.
+                aVal.nType == SC_MATVAL_EMPTY;
+                aVal.fVal = 0.0;
             default:
-                ; // no action is needed for an empty element.
+                ;
         }
     }
     else
commit e053bd2006b6e5d939426d02be26e35144c135f3
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 19:27:09 2010 -0500

    Fixed a silly bug with serious consequences.
    
    This was causing the calculation of LINEST to be totally incorrect.

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 652b26a..e67e067 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -634,8 +634,8 @@ void ScMatrixImpl::FillDouble( double fVal, SCSIZE nC1, SCSIZE nR1, SCSIZE nC2,
 {
     if (ValidColRow( nC1, nR1) && ValidColRow( nC2, nR2))
     {
-        for (SCSIZE i = nR1; i < nR2; ++i)
-            for (SCSIZE j = nC1; j < nC2; ++j)
+        for (SCSIZE i = nR1; i <= nR2; ++i)
+            for (SCSIZE j = nC1; j <= nC2; ++j)
                 maMat.set(i, j, fVal);
     }
     else
commit 8e9fdfa1315bc5af6cd7fd2731452dc5b4297efc
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 15:03:39 2010 -0500

    Don't call Clear() after resizing a matrix.

diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index d30eb3d..652b26a 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -245,7 +245,6 @@ bool ScMatrixImpl::IsImmutable() const
 void ScMatrixImpl::Resize(SCSIZE nC, SCSIZE nR)
 {
     maMat.resize(nR, nC);
-    Clear();
 }
 
 ScMatrix::DensityType ScMatrixImpl::GetDensityType() const
commit 00b72046166670628078f9f94a22897c90cf894f
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 11:53:53 2010 -0500

    Fixed build breakage.

diff --git a/sc/source/filter/xml/XMLExportDDELinks.cxx b/sc/source/filter/xml/XMLExportDDELinks.cxx
index 971f5d5..810edc3 100644
--- a/sc/source/filter/xml/XMLExportDDELinks.cxx
+++ b/sc/source/filter/xml/XMLExportDDELinks.cxx
@@ -73,7 +73,7 @@ sal_Bool ScXMLExportDDELinks::CellsEqual(const sal_Bool bPrevEmpty, const sal_Bo
         return sal_False;
 }
 
-void WriteCell(ScXMLExport& rExport, const ScMatrixValue& aVal, sal_Int32 nRepeat)
+void ScXMLExportDDELinks::WriteCell(const ScMatrixValue& aVal, sal_Int32 nRepeat)
 {
     bool bString = ScMatrix::IsNonValueType(aVal.nType);
     bool bEmpty = ScMatrix::IsEmptyType(aVal.nType);
@@ -103,8 +103,6 @@ void WriteCell(ScXMLExport& rExport, const ScMatrixValue& aVal, sal_Int32 nRepea
     SvXMLElementExport(rExport, XML_NAMESPACE_TABLE, XML_TABLE_CELL, sal_True, sal_True);
 }
 
-}
-
 void ScXMLExportDDELinks::WriteTable(const sal_Int32 nPos)
 {
     ScDocument* pDoc = rExport.GetDocument();
@@ -140,13 +138,13 @@ void ScXMLExportDDELinks::WriteTable(const sal_Int32 nPos)
             if (nCol > 0 && aVal != aPrevVal)
             {
                 // Cell value differs.  Flush the cell content.
-                WriteCell(rExport, aPrevVal, nRepeat);
+                WriteCell(aPrevVal, nRepeat);
                 nRepeat = 0;
             }
             aPrevVal = aVal;
         }
 
-        WriteCell(rExport, aPrevVal, nRepeat);
+        WriteCell(aPrevVal, nRepeat);
     }
 }
 
diff --git a/sc/source/filter/xml/XMLExportDDELinks.hxx b/sc/source/filter/xml/XMLExportDDELinks.hxx
index d913735..2dacb5a 100644
--- a/sc/source/filter/xml/XMLExportDDELinks.hxx
+++ b/sc/source/filter/xml/XMLExportDDELinks.hxx
@@ -33,6 +33,7 @@
 
 class String;
 class ScXMLExport;
+class ScMatrixValue;
 
 class ScXMLExportDDELinks
 {
@@ -40,7 +41,7 @@ class ScXMLExportDDELinks
 
     sal_Bool			CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
                                     const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue) const;
-    void 				WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat);
+    void 				WriteCell(const ScMatrixValue& aVal, sal_Int32 nRepeat);
     void				WriteTable(const sal_Int32 nPos);
 public:
     ScXMLExportDDELinks(ScXMLExport& rExport);
commit 4e876a04373ccbc376d330ee494f5a04d503a7b4
Merge: d5dd7ae... d28be24...
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Dec 16 11:11:45 2010 -0500

    Merge branch 'master' into feature/calc-matrix-rework
    
    Conflicts:
    	chart2/source/controller/dialogs/ChartTypeDialogController.cxx
    	chart2/source/controller/dialogs/TabPages.hrc
    	sc/inc/dpshttab.hxx
    	sc/inc/global.hxx
    	sc/source/core/data/dpobject.cxx
    	sc/source/core/data/dptablecache.cxx
    	sc/source/core/data/drwlayer.cxx
    	sc/source/filter/excel/xecontent.cxx
    	sc/source/filter/inc/ftools.hxx
    	sc/source/filter/inc/xehelper.hxx
    	sc/source/filter/inc/xihelper.hxx
    	sc/source/filter/inc/xistyle.hxx
    	sc/source/filter/xml/XMLExportDDELinks.cxx
    	sc/source/filter/xml/XMLExportDDELinks.hxx
    	sc/source/ui/docshell/docfunc.cxx
    	sc/source/ui/optdlg/opredlin.cxx
    	sc/source/ui/unoobj/styleuno.cxx

diff --cc sc/source/filter/xml/XMLExportDDELinks.cxx
index 4b4ff7a,e2a85ab..971f5d5
--- a/sc/source/filter/xml/XMLExportDDELinks.cxx
+++ b/sc/source/filter/xml/XMLExportDDELinks.cxx
@@@ -56,13 -57,26 +56,28 @@@ ScXMLExportDDELinks::~ScXMLExportDDELin
  {
  }
  
- namespace {
+ sal_Bool ScXMLExportDDELinks::CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
+                      const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue) const
+ {
+     if (bEmpty == bPrevEmpty)
+         if (bEmpty)
+             return sal_True;
+         else if (bString == bPrevString)
+             if (bString)
+                 return (sPrevValue == sValue);
+             else
+                 return (fPrevValue == fValue);
+         else
+             return sal_False;
+     else
+         return sal_False;
+ }
  
 -void ScXMLExportDDELinks::WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat)
 +void WriteCell(ScXMLExport& rExport, const ScMatrixValue& aVal, sal_Int32 nRepeat)
  {
 -    rtl::OUStringBuffer sBuffer;
 +    bool bString = ScMatrix::IsNonValueType(aVal.nType);
 +    bool bEmpty = ScMatrix::IsEmptyType(aVal.nType);
 +
      if (!bEmpty)
      {
          if (bString)
diff --cc sc/source/filter/xml/XMLExportDDELinks.hxx
index 8b94dba,25845f5..d913735
--- a/sc/source/filter/xml/XMLExportDDELinks.hxx
+++ b/sc/source/filter/xml/XMLExportDDELinks.hxx
@@@ -36,9 -36,12 +36,12 @@@ class ScXMLExport
  
  class ScXMLExportDDELinks
  {
 -    ScXMLExport&		rExport;
 +    ScXMLExport&        rExport;
  
-     void                WriteTable(const sal_Int32 nPos);
+     sal_Bool			CellsEqual(const sal_Bool bPrevEmpty, const sal_Bool bPrevString, const String& sPrevValue, const double& fPrevValue,
+                                     const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue) const;
+     void 				WriteCell(const sal_Bool bEmpty, const sal_Bool bString, const String& sValue, const double& fValue, const sal_Int32 nRepeat);
+     void				WriteTable(const sal_Int32 nPos);
  public:
      ScXMLExportDDELinks(ScXMLExport& rExport);
      ~ScXMLExportDDELinks();
diff --cc sc/source/filter/xml/xmlexprt.hxx
index e89deb8,b77a40a..797b8ee
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@@ -160,13 -161,14 +161,14 @@@ class ScXMLExport : public SvXMLExpor
      void ExportFormatRanges(const sal_Int32 nStartCol, const sal_Int32 nStartRow,
          const sal_Int32 nEndCol, const sal_Int32 nEndRow, const sal_Int32 nSheet);
      void WriteRowContent();
-     void WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nEmptyRows);
+     void WriteRowStartTag(sal_Int32 nRow, const sal_Int32 nIndex, const sal_Int32 nEmptyRows, bool bHidden, bool bFiltered);
      void OpenHeaderRows();
      void CloseHeaderRows();
-     void OpenNewRow(const sal_Int32 nIndex, const sal_Int8 nFlag, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows);
-     void OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int8 nFlag,
-         const sal_Int32 nStartRow, const sal_Int32 nEmptyRows);
-     void OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow);
+     void OpenNewRow(const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows,
+                     bool bHidden, bool bFiltered);
 -    void OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows, 
++    void OpenAndCloseRow(const sal_Int32 nIndex, const sal_Int32 nStartRow, const sal_Int32 nEmptyRows,
+                          bool bHidden, bool bFiltered);
+     void OpenRow(const sal_Int32 nTable, const sal_Int32 nStartRow, const sal_Int32 nRepeatRow, ScXMLCachedRowAttrAccess& rRowAttr);
      void CloseRow(const sal_Int32 nRow);
      void GetColumnRowHeader(sal_Bool& bHasColumnHeader, com::sun::star::table::CellRangeAddress& aColumnHeaderRange,
          sal_Bool& bHasRowHeader, com::sun::star::table::CellRangeAddress& aRowHeaderRange,
commit d5dd7ae1f00420668bf74e12fd5ea6a379a55574
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Nov 12 18:03:35 2010 -0500

    More cleanup, tab removal, bogus comments etc.

diff --git a/sc/inc/dptablecache.hxx b/sc/inc/dptablecache.hxx
index c6bec4b..b3bb082 100644
--- a/sc/inc/dptablecache.hxx
+++ b/sc/inc/dptablecache.hxx
@@ -41,30 +41,24 @@
 #include <com/sun/star/sdbc/XRow.hpp>
 #include <com/sun/star/sdbc/XRowSet.hpp>
 
-class ScDPTableDataCache;
-class TypedStrData;
 struct ScQueryParam;
 
-// --------------------------------------------------------------------
-//
-//	base class ScDPTableData to allow implementation with tabular data
-//	by deriving only of this
-//
-
 class SC_DLLPUBLIC ScDPTableDataCache
 {
-    long	mnID;
     ScDocument* mpDoc;
 
-    long						 mnColumnCount;		// Column count
+    long    mnID;
+    long    mnColumnCount;
+
+    std::vector<ScDPItemData*>* mpTableDataValues; //Data Pilot Table's index - value map
+    std::vector<SCROW>*         mpSourceData;      //Data Pilot Table's Source data
+    std::vector<SCROW>*         mpGlobalOrder;     //Sorted members index
+    std::vector<SCROW>*         mpIndexOrder;      //Index the sorted number
+    std::vector<ScDPItemData*>  mrLabelNames;      //Source Label data
+    std::vector<bool>           mbEmptyRow;        //If empty row?
+
+    mutable ScDPItemDataPool    maAdditionalDatas;
 
-    std::vector<ScDPItemData*>* 	 mpTableDataValues; //Data Pilot Table's index - value map
-    std::vector<SCROW>*			 mpSourceData;		//Data Pilot Table's Source data
-    std::vector<SCROW>*			 mpGlobalOrder;		//Sorted members index	
-    std::vector<SCROW>*			 mpIndexOrder;		//Index the sorted number
-    std::vector<ScDPItemData*>	 mrLabelNames;		//Source Label data
-    std::vector<bool>			 mbEmptyRow;		//If empty row?	
-    mutable ScDPItemDataPool	  			 maAdditionalDatas;
 public:
     SCROW GetOrder( long nDim, SCROW nIndex ) const;
     SCROW GetIdByItemData( long nDim,  String sItemData  ) const;
@@ -83,22 +77,22 @@ public:
 
     SCROW GetSortedItemDataId( SCCOL nDim, SCROW nOrder ) const;
     const std::vector<ScDPItemData*>& GetDimMemberValues( SCCOL nDim )const;
-    void	SetId( long nId ){ mnID = nId;}
-    void	AddRow( ScDPItemData* pRow, USHORT nCount );
-    bool	InitFromDoc(  ScDocument* pDoc, const ScRange& rRange );
+    void    SetId( long nId ){ mnID = nId;}
+    void    AddRow( ScDPItemData* pRow, USHORT nCount );
+    bool    InitFromDoc(  ScDocument* pDoc, const ScRange& rRange );
     bool InitFromDataBase (const  ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& xRowSet, const Date& rNullDate);
 
-    SCROW	GetRowCount() const;
-    SCROW	GetItemDataId( USHORT nDim, SCROW nRow, bool bRepeatIfEmpty ) const;
-    String	GetDimensionName( USHORT nColumn ) const;
-    bool	IsEmptyMember( SCROW nRow, USHORT nColumn ) const;
-    bool	IsRowEmpty( SCROW nRow ) const;
-    bool	IsValid() const;
-    bool	ValidQuery( SCROW nRow, const ScQueryParam& rQueryParam, bool* pSpecial );
+    SCROW   GetRowCount() const;
+    SCROW   GetItemDataId( USHORT nDim, SCROW nRow, bool bRepeatIfEmpty ) const;
+    String  GetDimensionName( USHORT nColumn ) const;
+    bool    IsEmptyMember( SCROW nRow, USHORT nColumn ) const;
+    bool    IsRowEmpty( SCROW nRow ) const;
+    bool    IsValid() const;
+    bool    ValidQuery( SCROW nRow, const ScQueryParam& rQueryParam, bool* pSpecial );
 
     ScDocument* GetDoc() const;//ms-cache-core
     long GetColumnCount() const;
-    long	GetId() const;
+    long    GetId() const;
 
     const ScDPItemData* GetItemDataById( long nDim, SCROW nId ) const;
 
@@ -107,12 +101,11 @@ public:
     ScDPTableDataCache( ScDocument* pDoc );
     virtual ~ScDPTableDataCache();
 
-protected:
 private:
-    void		AddLabel( ScDPItemData* pData);
-    bool	AddData( long nDim, ScDPItemData* itemData );
+    void    AddLabel( ScDPItemData* pData);
+    bool    AddData( long nDim, ScDPItemData* itemData );
 };
 
-#endif //DPTABLECACHE_HXX
+#endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx
index a8585df..028b8ea 100644
--- a/sc/source/core/data/dptablecache.cxx
+++ b/sc/source/core/data/dptablecache.cxx
@@ -399,13 +399,13 @@ bool ScDPTableDataCache::operator== ( const ScDPTableDataCache& r ) const
 
 ScDPTableDataCache::ScDPTableDataCache(  ScDocument* pDoc  ) :
     mpDoc( pDoc ),
+    mnID(-1),
     mnColumnCount ( 0 ),
     mpTableDataValues ( NULL ),
     mpSourceData ( NULL ),
     mpGlobalOrder( NULL ),
     mpIndexOrder( NULL)
 {
-    mnID = -1;
 }
 
 ScDPTableDataCache::~ScDPTableDataCache()
commit 8abe0590ec222baa617e4b2258e9cf4b817c352e
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Nov 12 16:49:01 2010 -0500

    Oops. My bad - removing my own printf silliness.

diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 3379152..adefdb9 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -194,7 +194,6 @@ static const sal_Char __FAR_DATA pFilterRtf[]		= "Rich Text Format (StarCalc)";
 
 SFX_IMPL_INTERFACE(ScDocShell,SfxObjectShell, ScResId(SCSTR_DOCSHELL))
 {
-    fprintf(stdout, "SFX_IMPL_INTERFACE:   SID_HYPERLINK_INSERT = %d\n", SID_HYPERLINK_INSERT);
     SFX_CHILDWINDOW_REGISTRATION( SID_HYPERLINK_INSERT );
 }
 
commit f4c065a03439b86cc2053664f54c20162ad65da2
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Nov 12 16:39:45 2010 -0500

    More cleanups - trailing whitespaces & more bogus comments.

diff --git a/sc/inc/dpglobal.hxx b/sc/inc/dpglobal.hxx
index 5a8652a..0541bd7 100644
--- a/sc/inc/dpglobal.hxx
+++ b/sc/inc/dpglobal.hxx

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list