[Libreoffice-commits] .: 14 commits - sc/source

Jan Holesovsky kendy at kemper.freedesktop.org
Fri Jun 17 04:47:00 PDT 2011


 sc/source/core/tool/rangenam.cxx   |    3 +++
 sc/source/filter/ftools/ftools.cxx |    2 ++
 2 files changed, 5 insertions(+)

New commits:
commit 09983b2f0f90d0878cd92c14e30d97c40bfe64e1
Merge: 47bd148... 18eaab9...
Author: Jan Holesovsky <kendy at suse.cz>
Date:   Fri Jun 17 13:02:07 2011 +0200

    Merge remote-tracking branch 'origin/libreoffice-3-4'

commit 18eaab9989d02e05e6c11e707107ad0a90c596eb
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Wed Jun 15 20:56:17 2011 +0200

    give local range names higher priority than global ones
    
    Signed-off-by: Kohei Yoshida <kyoshida at novell.com>

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 7ebcb9f..b61b146 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -2892,18 +2892,17 @@ sal_Bool ScCompiler::IsNamedRange( const String& rUpperName )
 {
     // IsNamedRange is called only from NextNewToken, with an upper-case string
 
-    // Try global named ranges first, then sheet local next.  BTW does this
-    // order matter?
-    bool bGlobal = true;
-    ScRangeName* pRangeName = pDoc->GetRangeName();
+    // try local names first
+    bool bGlobal = false;
+    ScRangeName* pRangeName = pDoc->GetRangeName(aPos.Tab());
     const ScRangeData* pData = pRangeName->findByUpperName(rUpperName);
     if (!pData)
     {
-        pRangeName = pDoc->GetRangeName(aPos.Tab());
+        pRangeName = pDoc->GetRangeName();
         if (pRangeName)
             pData = pRangeName->findByUpperName(rUpperName);
         if (pData)
-            bGlobal = false;
+            bGlobal = true;
     }
 
     if (pData)
commit 3f6d02769c5f7dace9206e52d474f6b1dd3ef468
Author: Petr Mladek <pmladek at suse.cz>
Date:   Tue Jun 14 16:53:24 2011 +0200

    Version 3.4.1.1, tag libreoffice-3.4.1.1 (3.4.1-rc1)
commit 4fc6f57f47a3e43a90eeafa8f8057ead3fda29dc
Author: Takeshi Abe <tabe at fixedpoint.jp>
Date:   Sun Jun 12 12:04:30 2011 +0900

    fdo#37776
    
    VLOOKUP/HLOOKUP now allow a single reference as the second parameter.
    
    Signed-off-by: Kohei Yoshida <kyoshida at novell.com>

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 90eeeb6..8121344 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5805,6 +5805,12 @@ void ScInterpreter::CalculateLookup(sal_Bool HLookup)
                 return;
             }
         }
+        else if (eType == svSingleRef)
+        {
+            PopSingleRef(nCol1, nRow1, nTab1);
+            nCol2 = nCol1;
+            nRow2 = nRow1;
+        }
         else if (eType == svMatrix || eType == svExternalDoubleRef || eType == svExternalSingleRef)
         {
             pMat = GetMatrix();
commit 2d33162c409ed520b0befc063db3102c4f552f11
Author: Katarina Machalkova <kmachalkova at suse.cz>
Date:   Mon Jun 13 13:53:02 2011 +0200

    fdo#38154: convert split win Y coord to 16bit int before xls export
    
    Excel then won't complain about invalid xls file
    (this is some fallout from increasing Calc row limit above 65k lines)
    
    Signed-off-by: Kohei Yoshida <kyoshida at novell.com>

diff --git a/sc/source/filter/excel/xeview.cxx b/sc/source/filter/excel/xeview.cxx
index 92cc65c..437a953 100644
--- a/sc/source/filter/excel/xeview.cxx
+++ b/sc/source/filter/excel/xeview.cxx
@@ -207,7 +207,7 @@ void XclExpPane::SaveXml( XclExpXmlStream& rStrm )
 void XclExpPane::WriteBody( XclExpStream& rStrm )
 {
     rStrm   << mnSplitX
-            << mnSplitY
+            << static_cast<sal_uInt16>( mnSplitY )
             << maSecondXclPos
             << mnActivePane;
     if( rStrm.GetRoot().GetBiff() >= EXC_BIFF5 )
@@ -369,7 +369,7 @@ XclExpTabViewSettings::XclExpTabViewSettings( const XclExpRoot& rRoot, SCTAB nSc
         {
             // split window: position is in twips
             maData.mnSplitX = ulimit_cast< sal_uInt16 >( rTabSett.maSplitPos.X() );
-            maData.mnSplitY = ulimit_cast< sal_uInt16 >( rTabSett.maSplitPos.Y() );
+            maData.mnSplitY = ulimit_cast< sal_uInt32 >( rTabSett.maSplitPos.Y() );
         }
 
         // selection
diff --git a/sc/source/filter/excel/xiview.cxx b/sc/source/filter/excel/xiview.cxx
index ff1f94d..5882d56 100644
--- a/sc/source/filter/excel/xiview.cxx
+++ b/sc/source/filter/excel/xiview.cxx
@@ -198,9 +198,10 @@ void XclImpTabViewSettings::ReadScl( XclImpStream& rStrm )
 
 void XclImpTabViewSettings::ReadPane( XclImpStream& rStrm )
 {
-    rStrm   >> maData.mnSplitX
-            >> maData.mnSplitY
-            >> maData.maSecondXclPos
+    rStrm   >> maData.mnSplitX;
+    maData.mnSplitY = rStrm.ReaduInt16();
+
+    rStrm   >> maData.maSecondXclPos
             >> maData.mnActivePane;
 }
 
diff --git a/sc/source/filter/inc/xlview.hxx b/sc/source/filter/inc/xlview.hxx
index ff524b8..b3dff0a 100644
--- a/sc/source/filter/inc/xlview.hxx
+++ b/sc/source/filter/inc/xlview.hxx
@@ -137,7 +137,7 @@ struct XclTabViewData
     XclAddress          maFirstXclPos;      /// First visible cell.
     XclAddress          maSecondXclPos;     /// First visible cell in additional panes.
     sal_uInt16          mnSplitX;           /// Split X position, or number of frozen columns.
-    sal_uInt16          mnSplitY;           /// Split Y position, or number of frozen rows.
+    sal_uInt32          mnSplitY;           /// Split Y position, or number of frozen rows.
     sal_uInt16          mnNormalZoom;       /// Zoom factor for normal view.
     sal_uInt16          mnPageZoom;         /// Zoom factor for pagebreak preview.
     sal_uInt16          mnCurrentZoom;      /// Zoom factor for current view.
commit 7fc1ed9d96aecbd651537651be2fec787f5a8e6e
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Jun 10 14:32:26 2011 -0400

    Prevent a crash during multiple operations.
    
    Signed-off-by: Tor Lillqvist <tlillqvist at novell.com>

diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index bfe5b6b..8de2e38 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3397,6 +3397,20 @@ sal_Bool ScInterpreter::SetSbxVariable( SbxVariable* pVar, const ScAddress& rPos
     return bOk;
 }
 
+namespace {
+
+class FindByPointer : ::std::unary_function<ScInterpreterTableOpParams, bool>
+{
+    const ScInterpreterTableOpParams* mpTableOp;
+public:
+    FindByPointer(const ScInterpreterTableOpParams* p) : mpTableOp(p) {}
+    bool operator() (const ScInterpreterTableOpParams& val) const
+    {
+        return &val == mpTableOp;
+    }
+};
+
+}
 
 void ScInterpreter::ScTableOp()
 {
@@ -3456,7 +3470,11 @@ void ScInterpreter::ScTableOp()
         PushString( aCellString );
     }
 
-    pTableOp = pDok->aTableOpList.release( pDok->aTableOpList.end() ).release();
+    boost::ptr_vector< ScInterpreterTableOpParams >::iterator itr =
+        ::std::find_if(pDok->aTableOpList.begin(), pDok->aTableOpList.end(), FindByPointer(pTableOp));
+    if (itr != pDok->aTableOpList.end())
+        pTableOp = pDok->aTableOpList.release(itr).release();
+
     // set dirty again once more to be able to recalculate original
     for ( ::std::vector< ScFormulaCell* >::const_iterator iBroadcast(
                 pTableOp->aNotifiedFormulaCells.begin() );
commit 3ac8ae98cdcccfc778575bdee894a949a184cb75
Author: Norbert Thiebaud <nthiebaud at gmail.com>
Date:   Fri Jun 10 14:40:47 2011 -0500

    fdo#36719: Prevent crash on pivot table with invalid database connection.
    
    Check for NULL cache state to handle invalid database connection more
    gracefully (i.e. without crashing).
    
    Signed-off-by: Norbert Thiebaud <nthiebaud at gmail.com>

diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx
index 40d34ac..b7b8a64 100644
--- a/sc/source/core/data/dpcachetable.cxx
+++ b/sc/source/core/data/dpcachetable.cxx
@@ -180,12 +180,12 @@ ScDPCacheTable::~ScDPCacheTable()
 
 sal_Int32 ScDPCacheTable::getRowSize() const
 {
-    return getCache()->GetRowCount();
+    return mpCache ? getCache()->GetRowCount() : 0;
 }
 
 sal_Int32 ScDPCacheTable::getColSize() const
 {
-    return getCache()->GetColumnCount();
+    return mpCache ? getCache()->GetColumnCount() : 0;
 }
 
 void ScDPCacheTable::fillTable(
@@ -313,6 +313,9 @@ void ScDPCacheTable::filterByPageDimension(const vector<Criterion>& rCriteria, c
 
 const ScDPItemData* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const
 { 
+    if (!mpCache)
+        return NULL;
+
    SCROW nId= getCache()->GetItemDataId(nCol, nRow, bRepeatIfEmpty);
    return getCache()->GetItemDataById( nCol, nId );
 }
@@ -331,6 +334,8 @@ void  ScDPCacheTable::getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, boo
 }
 String ScDPCacheTable::getFieldName(SCCOL  nIndex) const
 {
+    if (!mpCache)
+        return String();
     return getCache()->GetDimensionName( nIndex );
 }
 
@@ -410,7 +415,7 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S
 
 SCROW ScDPCacheTable::getOrder(long nDim, SCROW nIndex) const
 {
-    return getCache()->GetOrder(nDim, nIndex);
+    return mpCache ? getCache()->GetOrder(nDim, nIndex) : 0;
 }
 
 void ScDPCacheTable::clear()
diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx
index 417c142..d16d03e 100644
--- a/sc/source/core/data/dpsdbtab.cxx
+++ b/sc/source/core/data/dpsdbtab.cxx
@@ -136,10 +136,18 @@ void ScDatabaseDPData::SetEmptyFlags( sal_Bool /* bIgnoreEmptyRows */, sal_Bool
 void ScDatabaseDPData::CreateCacheTable()
 {
     if (!aCacheTable.empty())
+        // cache table already created.
         return;
 
     if (!aCacheTable.hasCache())
-        aCacheTable.setCache(mrImport.CreateCache());
+    {
+        const ScDPCache* pCache = mrImport.CreateCache();
+        if (!pCache)
+            // Cache creation failed.  Perhaps invalid database connection.
+            return;
+
+        aCacheTable.setCache(pCache);
+    }
 
     aCacheTable.fillTable();
 }
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 30d3933..90fb0ba 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -2127,6 +2127,27 @@ void ScCellShell::ExecuteExternalSource(
         _rRequest.Ignore();
 }
 
+namespace {
+
+bool isDPSourceValid(const ScDPObject& rDPObj)
+{
+    if (rDPObj.IsImportData())
+    {
+        // If the data type is database, check if the database is still valid.
+        const ScImportSourceDesc* pDesc = rDPObj.GetImportSourceDesc();
+        if (!pDesc)
+            return false;
+
+        const ScDPCache* pCache = pDesc->CreateCache();
+        if (!pCache)
+            // cashe creation failed, probably due to invalid connection.
+            return false;
+    }
+    return true;
+}
+
+}
+
 void ScCellShell::ExecuteDataPilotDialog()
 {
     ScModule* pScMod = SC_MOD();
@@ -2142,7 +2163,8 @@ void ScCellShell::ExecuteDataPilotDialog()
                                 pData->GetTabNo() );
     if ( pDPObj )   // on an existing table?
     {
-        pNewDPObject.reset(new ScDPObject(*pDPObj));
+        if (isDPSourceValid(*pDPObj))
+            pNewDPObject.reset(new ScDPObject(*pDPObj));
     }
     else            // create new table
     {
commit fc7e9ce79a9cc518b26440fb3e37f832371d8422
Author: Markus Mohrhard <markus.mohrhard at googlemail.com>
Date:   Fri Jun 10 15:44:34 2011 +0200

    fix for fdo#37872: we don't allow points in range names any more
    
    Signed-off-by: Kohei Yoshida <kyoshida at novell.com>

diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 94d6797..efad9fe 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -476,6 +476,9 @@ sal_Bool ScRangeData::IsNameValid( const String& rName, ScDocument* pDoc )
 {
     /* XXX If changed, sc/source/filter/ftools/ftools.cxx 
      * ScfTools::ConvertToScDefinedName needs to be changed too. */
+    sal_Char a('.');
+    if (rName.Search(a, 0) != STRING_NOTFOUND)
+        return false;
     xub_StrLen nPos = 0;
     xub_StrLen nLen = rName.Len();
     if ( !nLen || !ScCompiler::IsCharFlagAllConventions( rName, nPos++, SC_COMPILER_C_CHAR_NAME ) )
diff --git a/sc/source/filter/ftools/ftools.cxx b/sc/source/filter/ftools/ftools.cxx
index ad9f185..96d0eea 100644
--- a/sc/source/filter/ftools/ftools.cxx
+++ b/sc/source/filter/ftools/ftools.cxx
@@ -162,6 +162,8 @@ Color ScfTools::GetMixedColor( const Color& rFore, const Color& rBack, sal_uInt8
 
 void ScfTools::ConvertToScDefinedName( String& rName )
 {
+    sal_Char a('.');
+    rName.SearchAndReplaceAllAscii(&a,'_'); //fdo#37872: we don't allow points in range names any more
     xub_StrLen nLen = rName.Len();
     if( nLen && !ScCompiler::IsCharFlagAllConventions( rName, 0, SC_COMPILER_C_CHAR_NAME ) )
         rName.SetChar( 0, '_' );
commit cb0fa8f3a5889c05b40a337aaa0f17c93468ff8a
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Fri Jun 10 01:07:24 2011 -0400

    fdo#37622: Fix incorrect font attribute lookup during XLS import.
    
    Font IDs in XF records are
    
    * 0-based when it's less than 4, but
    * 1-based when it's greater than 4.
    
    That's what the spec says.  And apparently the font ID of 4 is still
    used in BIFF5 format, but not in BIFF8.

diff --git a/sc/source/filter/excel/xistyle.cxx b/sc/source/filter/excel/xistyle.cxx
index 11381e5..1f6e680 100644
--- a/sc/source/filter/excel/xistyle.cxx
+++ b/sc/source/filter/excel/xistyle.cxx
@@ -549,10 +549,14 @@ const XclImpFont* XclImpFontBuffer::GetFont( sal_uInt16 nFontIndex ) const
     if (nFontIndex == 4)
         return &maFont4;
 
-    if (nFontIndex >= maFontList.size())
-        return NULL;
+    if (nFontIndex < 4)
+    {
+        // Font ID is zero-based when it's less than 4.
+        return nFontIndex >= maFontList.size() ? NULL : &maFontList[nFontIndex];
+    }
 
-    return (nFontIndex < 4) ? &(maFontList[nFontIndex]) : &(maFontList[nFontIndex - 1]);
+    // Font ID is greater than 4.  It is now 1-based.
+    return nFontIndex > maFontList.size() ? NULL : &maFontList[nFontIndex-1];
 }
 
 void XclImpFontBuffer::ReadFont( XclImpStream& rStrm )
commit 9551cd558375978ae9cd03353a1948397438d351
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Jun 9 22:30:54 2011 +0000

    fdo#37764: Get ISBLANK() to work correctly with external refs.
    
    Signed-off-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 2327e94..90eeeb6 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -1661,9 +1661,11 @@ void ScInterpreter::ScIsEmpty()
                 nRes = 1;
         }
         break;
+        case svExternalSingleRef:
+        case svExternalDoubleRef:
         case svMatrix:
         {
-            ScMatrixRef pMat = PopMatrix();
+            ScMatrixRef pMat = GetMatrix();
             if ( !pMat )
                 ;   // nothing
             else if ( !pJumpMatrix )
diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx
index 7f005e2..31b9f0e 100644
--- a/sc/source/core/tool/interpr5.cxx
+++ b/sc/source/core/tool/interpr5.cxx
@@ -572,11 +572,16 @@ ScMatrixRef ScInterpreter::GetMatrix()
                 pMat = new ScMatrix(1, 1);
                 pMat->PutDouble(pToken->GetDouble(), 0, 0);
             }
-            else
+            else if (pToken->GetType() == svString)
             {
                 pMat = new ScMatrix(1, 1);
                 pMat->PutString(pToken->GetString(), 0, 0);
             }
+            else
+            {
+                pMat = new ScMatrix(1, 1);
+                pMat->PutEmpty(0, 0);
+            }
         }
         break;
         case svExternalDoubleRef:
commit cf5849feb5c0f4338af8700cfe01d935dfbb2be9
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Jun 9 00:13:21 2011 -0400

    fdo#37673: Fix a crasher during HTML import on Windows.

diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx
index 7af88be..c7a79a1 100644
--- a/sc/source/filter/html/htmlpars.cxx
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -1832,7 +1832,7 @@ public:
         @param pTableMap  Pointer to the table map (is allowed to be NULL). */
     explicit            ScHTMLTableIterator( const ScHTMLTableMap* pTableMap );
 
-    inline bool         is() const { return maIter != maEnd; }
+    inline bool         is() const { return mpTableMap && maIter != maEnd; }
     inline ScHTMLTable* operator->() { return maIter->second.get(); }
     inline ScHTMLTable& operator*() { return *maIter->second; }
     inline ScHTMLTableIterator& operator++() { ++maIter; return *this; }
@@ -1840,9 +1840,11 @@ public:
 private:
     ScHTMLTableMap::const_iterator maIter;
     ScHTMLTableMap::const_iterator maEnd;
+    const ScHTMLTableMap* mpTableMap;
 };
 
-ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap )
+ScHTMLTableIterator::ScHTMLTableIterator( const ScHTMLTableMap* pTableMap ) :
+    mpTableMap(pTableMap)
 {
     if( pTableMap )
     {
commit d90ae9eb4072dc0cad8559074c776aa2cc7034ff
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Jun 8 12:53:21 2011 -0400

    fdo#33705: Fixed cell function N.
    
    Also added unit test for this built-in function.

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 7a6d46e..835f085 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -60,6 +60,7 @@
 #include "drwlayer.hxx"
 #include "scitems.hxx"
 #include "reffind.hxx"
+#include "markdata.hxx"
 
 #include "docsh.hxx"
 #include "funcdesc.hxx"
@@ -422,6 +423,69 @@ void Test::testCellFunctions()
     m_pDoc->GetValue(0, 4, 0, result);
     CPPUNIT_ASSERT_MESSAGE("Calculation of PRODUCT with inline array failed", result == 6.0);
 
+    {
+        // N
+
+        // Clear the area first.
+        ScMarkData aMarkData;
+        aMarkData.SetMarkArea(ScRange(0, 0, 0, 1, 20, 0));
+        m_pDoc->DeleteArea(0, 0, 1, 20, aMarkData, IDF_CONTENTS);
+
+        // Put values to reference.
+        val = 0;
+        m_pDoc->SetValue(0, 0, 0, val);
+        m_pDoc->SetString(0, 2, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("Text")));
+        val = 1;
+        m_pDoc->SetValue(0, 3, 0, val);
+        val = -1;
+        m_pDoc->SetValue(0, 4, 0, val);
+        val = 12.3;
+        m_pDoc->SetValue(0, 5, 0, val);
+        m_pDoc->SetString(0, 6, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("'12.3")));
+
+        // Cell references
+        m_pDoc->SetString(1, 0, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A1)")));
+        m_pDoc->SetString(1, 1, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A2)")));
+        m_pDoc->SetString(1, 2, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A3)")));
+        m_pDoc->SetString(1, 3, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A4)")));
+        m_pDoc->SetString(1, 4, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A5)")));
+        m_pDoc->SetString(1, 5, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A6)")));
+        m_pDoc->SetString(1, 6, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A9)")));
+
+        // In-line values
+        m_pDoc->SetString(1, 7, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(0)")));
+        m_pDoc->SetString(1, 8, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(1)")));
+        m_pDoc->SetString(1, 9, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(-1)")));
+        m_pDoc->SetString(1, 10, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(123)")));
+        m_pDoc->SetString(1, 11, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(\"\")")));
+        m_pDoc->SetString(1, 12, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(\"12\")")));
+        m_pDoc->SetString(1, 13, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(\"foo\")")));
+
+        // Range references
+        m_pDoc->SetString(1, 14, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A1:A8)")));
+        m_pDoc->SetString(1, 15, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A4:B8)")));
+        m_pDoc->SetString(1, 16, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A6:B8)")));
+        m_pDoc->SetString(1, 17, 0, OUString(RTL_CONSTASCII_USTRINGPARAM("=N(A2:B8)")));
+
+        // Calculate and check the results.
+        m_pDoc->CalcAll();
+        double checks[] = {
+            0, 0,  0,    1, -1, 12.3, 0, // cell reference
+            0, 1, -1, 123,  0,    0, 0, // in-line values
+            0, 1, 12.3, 0                // range references
+        };
+        for (size_t i = 0; i < SAL_N_ELEMENTS(checks); ++i)
+        {
+            m_pDoc->GetValue(1, i, 0, result);
+            bool bGood = result == checks[i];
+            if (!bGood)
+            {
+                cerr << "row " << (i+1) << ": expected=" << checks[i] << " actual=" << result << endl;
+                CPPUNIT_ASSERT_MESSAGE("Unexpected result for N", false);
+            }
+        }
+    }
+
     m_pDoc->DeleteTab(0);
 }
 
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 1999bff..2327e94 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -2509,26 +2509,44 @@ void ScInterpreter::ScIsOdd()
     PushInt( !IsEven() );
 }
 
-
 void ScInterpreter::ScN()
 {
-    RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScN" );
-    sal_uInt16 nErr = nGlobalError;
-    nGlobalError = 0;
-    // Temporarily override the ConvertStringToValue() error for
-    // GetCellValue() / GetCellValueOrZero()
-    sal_uInt16 nSErr = mnStringNoValueError;
-    mnStringNoValueError = errCellNoValue;
+    switch (GetRawStackType())
+    {
+        case svSingleRef:
+        case svDoubleRef:
+        case svMatrix:
+        case svExternalSingleRef:
+        case svExternalDoubleRef:
+        {
+            ScMatrixRef pMat = GetMatrix();
+            SCSIZE nC, nR;
+            pMat->GetDimensions(nC, nR);
+            if (!nC || !nR)
+                PushDouble(0);
+            else
+                PushDouble(pMat->GetDouble(0, 0));
+            return;
+        }
+        case svString:
+            PushDouble(0);
+            return;
+        default:
+            ;
+    }
+
+    // Default action
     double fVal = GetDouble();
-    mnStringNoValueError = nSErr;
-    if ( nGlobalError == NOTAVAILABLE || nGlobalError == errCellNoValue )
-        nGlobalError = 0;       // N(#NA) and N("text") are ok
-    if ( !nGlobalError && nErr != NOTAVAILABLE )
-        nGlobalError = nErr;
-    PushDouble( fVal );
+    if (nGlobalError)
+    {
+        // Don't propagate the error. Push 0 instead.
+        nGlobalError = 0;
+        PushDouble(0);
+        return;
+    }
+    PushDouble(fVal);
 }
 
-
 void ScInterpreter::ScTrim()
 {   // Doesn't only trim but writes out twice!
     String aVal( GetString() );
commit 64efccba4635fbe713cc5d78ae0fdc8494abe049
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Jun 8 18:18:45 2011 -0400

    fdo#37947: Correctly import sheet-local named ranges.
    
    The key is to temporarily store all sheet-local named range data,
    and insert them en masse after importing the sheet contents fully.
    
    Signed-off-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index e047ef6..83f599f 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -95,6 +95,8 @@
 #include <com/sun/star/io/XSeekable.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 
+#include <memory>
+
 #define SC_LOCALE			"Locale"
 #define SC_STANDARDFORMAT	"StandardFormat"
 #define SC_CURRENCYSYMBOL	"CurrencySymbol"
@@ -2036,6 +2038,25 @@ sal_Bool ScXMLImport::GetValidation(const rtl::OUString& sName, ScMyImportValida
     return false;
 }
 
+void ScXMLImport::AddNamedExpression(SCTAB nTab, ScMyNamedExpression* pNamedExp)
+{
+    ::std::auto_ptr<ScMyNamedExpression> p(pNamedExp);
+    SheetNamedExpMap::iterator itr = maSheetNamedExpressions.find(nTab);
+    if (itr == maSheetNamedExpressions.end())
+    {
+        // No chain exists for this sheet.  Create one.
+        ::std::auto_ptr<ScMyNamedExpressions> pNew(new ScMyNamedExpressions);
+        ::std::pair<SheetNamedExpMap::iterator, bool> r = maSheetNamedExpressions.insert(nTab, pNew);
+        if (!r.second)
+            // insertion failed.
+            return;
+
+        itr = r.first;
+    }
+    ScMyNamedExpressions& r = *itr->second;
+    r.push_back(p);
+}
+
 ScXMLChangeTrackingImportHelper* ScXMLImport::GetChangeTrackingImportHelper()
 {
     if (!pChangeTrackingImportHelper)
@@ -2850,6 +2871,66 @@ void ScXMLImport::SetNamedRanges()
     }
 }
 
+namespace {
+
+class SheetRangeNameInserter : public ::std::unary_function<ScMyNamedExpression, void>
+{
+    ScDocument* mpDoc;
+    ScRangeName& mrRangeName;
+public:
+    SheetRangeNameInserter(ScDocument* pDoc, ScRangeName& rRangeName) :
+        mpDoc(pDoc), mrRangeName(rRangeName) {}
+
+    void operator() (const ScMyNamedExpression& r) const
+    {
+        using namespace formula;
+
+        if (r.sRangeType.getLength() > 0)
+            // For now, we only accept normal named expressions.
+            return;
+
+        if (mpDoc && !mrRangeName.findByName(r.sName))
+        {
+            // Insert a new name.
+            ScAddress aPos;
+            sal_Int32 nOffset = 0;
+            bool bSuccess = ScRangeStringConverter::GetAddressFromString(
+                aPos, r.sBaseCellAddress, mpDoc, FormulaGrammar::CONV_OOO, nOffset);
+
+            if (bSuccess)
+            {
+                ::rtl::OUString aContent = r.sContent;
+                if (!r.bIsExpression)
+                    ScXMLConverter::ParseFormula(aContent, false);
+
+                ScRangeData* pData = new ScRangeData(
+                    mpDoc, r.sName, r.sContent, aPos, RT_NAME, r.eGrammar);
+                mrRangeName.insert(pData);
+            }
+        }
+    }
+};
+
+}
+
+void ScXMLImport::SetSheetNamedRanges()
+{
+    if (!pDoc)
+        return;
+
+    SheetNamedExpMap::const_iterator itr = maSheetNamedExpressions.begin(), itrEnd = maSheetNamedExpressions.end();
+    for (; itr != itrEnd; ++itr)
+    {
+        SCTAB nTab = itr->first;
+        ScRangeName* pRangeNames = pDoc->GetRangeName(nTab);
+        if (!pRangeNames)
+            continue;
+
+        const ScMyNamedExpressions& rNames = *itr->second;
+        ::std::for_each(rNames.begin(), rNames.end(), SheetRangeNameInserter(pDoc, *pRangeNames));
+    }
+}
+
 void SAL_CALL ScXMLImport::endDocument(void)
 throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeException )
 {
@@ -2891,6 +2972,7 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
             }
             SetLabelRanges();
             SetNamedRanges();
+            SetSheetNamedRanges();
         }
         GetProgressBarHelper()->End();  // make room for subsequent SfxProgressBars
         if (pDoc)
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index 28862bb..a1b737e 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -55,6 +55,7 @@
 #include <vector>
 #include <boost/unordered_map.hpp>
 #include <boost/ptr_container/ptr_list.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
 
 class ScRangeList;
 class ScMyStyleNumberFormats;
@@ -674,6 +675,8 @@ class ScMyStylesImportHelper;
 class ScXMLImport: public SvXMLImport
 {
     typedef ::boost::unordered_map< ::rtl::OUString, sal_Int16, ::rtl::OUStringHash >	CellTypeMap;
+    typedef ::boost::ptr_map<SCTAB, ScMyNamedExpressions> SheetNamedExpMap;
+
     CellTypeMap				aCellTypeMap;
 
     ScDocument*				pDoc;
@@ -763,6 +766,8 @@ class ScXMLImport: public SvXMLImport
     ScMyTables				aTables;
 
     ScMyNamedExpressions* 	pMyNamedExpressions;
+    SheetNamedExpMap maSheetNamedExpressions;
+
     ScMyLabelRanges*        pMyLabelRanges;
     ScMyImportValidations*	pValidations;
     ScMyImpDetectiveOpArray*	pDetectiveOpArray;
@@ -918,6 +923,8 @@ public:
 
     ScMyNamedExpressions* GetNamedExpressions() { return pMyNamedExpressions; }
 
+    void AddNamedExpression(SCTAB nTab, ScMyNamedExpression* pNamedExp);
+
     void    AddLabelRange(const ScMyLabelRange* pMyLabelRange) {
         if (!pMyLabelRanges)
             pMyLabelRanges = new ScMyLabelRanges();
@@ -1006,6 +1013,7 @@ public:
 
     sal_Int32 	GetRangeType(const rtl::OUString sRangeType) const;
     void SetNamedRanges();
+    void SetSheetNamedRanges();
     void SetLabelRanges();
     void AddDefaultNote( const com::sun::star::table::CellAddress& aCell );
 
diff --git a/sc/source/filter/xml/xmlnexpi.cxx b/sc/source/filter/xml/xmlnexpi.cxx
index ce33d78..fcb02bd 100644
--- a/sc/source/filter/xml/xmlnexpi.cxx
+++ b/sc/source/filter/xml/xmlnexpi.cxx
@@ -36,16 +36,11 @@
 #include "xmlimprt.hxx"
 #include "xmlcelli.hxx"
 #include "docuno.hxx"
-#include "global.hxx"
 #include "document.hxx"
-#include "XMLConverter.hxx"
-#include "rangeutl.hxx"
 
 #include <xmloff/xmltkmap.hxx>
 #include <xmloff/nmspmap.hxx>
 
-#include <boost/scoped_ptr.hpp>
-
 using namespace com::sun::star;
 
 //------------------------------------------------------------------
@@ -58,38 +53,12 @@ void ScXMLNamedExpressionsContext::GlobalInserter::insert(ScMyNamedExpression* p
         mrImport.AddNamedExpression(pExp);
 }
 
-ScXMLNamedExpressionsContext::SheetLocalInserter::SheetLocalInserter(
-    ScDocument* pDoc, ScRangeName& rRangeName) : mpDoc(pDoc), mrRangeName(rRangeName) {}
+ScXMLNamedExpressionsContext::SheetLocalInserter::SheetLocalInserter(ScXMLImport& rImport, SCTAB nTab) :
+    mrImport(rImport), mnTab(nTab) {}
 
 void ScXMLNamedExpressionsContext::SheetLocalInserter::insert(ScMyNamedExpression* pExp)
 {
-    using namespace formula;
-
-    ::boost::scoped_ptr<ScMyNamedExpression> p(pExp);
-
-    if (p->sRangeType.getLength() > 0)
-        // For now, we only accept normal named expressions.
-        return;
-
-    if (mpDoc && !mrRangeName.findByName(p->sName))
-    {
-        // Insert a new name.
-        ScAddress aPos;
-        sal_Int32 nOffset = 0;
-        bool bSuccess = ScRangeStringConverter::GetAddressFromString(
-            aPos, p->sBaseCellAddress, mpDoc, FormulaGrammar::CONV_OOO, nOffset);
-
-        if (bSuccess)
-        {
-            ::rtl::OUString aContent = p->sContent;
-            if (!p->bIsExpression)
-                ScXMLConverter::ParseFormula(aContent, false);
-
-            ScRangeData* pData = new ScRangeData(
-                mpDoc, p->sName, p->sContent, aPos, RT_NAME, p->eGrammar);
-            mrRangeName.insert(pData);
-        }
-    }
+    mrImport.AddNamedExpression(mnTab, pExp);
 }
 
 ScXMLNamedExpressionsContext::ScXMLNamedExpressionsContext(
diff --git a/sc/source/filter/xml/xmlnexpi.hxx b/sc/source/filter/xml/xmlnexpi.hxx
index d66881a..71355c2 100644
--- a/sc/source/filter/xml/xmlnexpi.hxx
+++ b/sc/source/filter/xml/xmlnexpi.hxx
@@ -30,6 +30,7 @@
 
 #include <xmloff/xmlictxt.hxx>
 #include <xmloff/xmlimp.hxx>
+#include "address.hxx"
 
 #include <boost/shared_ptr.hpp>
 
@@ -72,11 +73,11 @@ public:
     class SheetLocalInserter : public Inserter
     {
     public:
-        SheetLocalInserter(ScDocument* pDoc, ScRangeName& rRangeName);
+        SheetLocalInserter(ScXMLImport& rImport, SCTAB nTab);
         virtual void insert(ScMyNamedExpression* pExp);
     private:
-        ScDocument* mpDoc;
-        ScRangeName& mrRangeName;
+        ScXMLImport& mrImport;
+        SCTAB mnTab;
     };
 
     ScXMLNamedExpressionsContext(
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index 8c2f084..ada5f9c 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -282,18 +282,10 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( sal_uInt16 nPrefix,
     {
     case XML_TOK_TABLE_NAMED_EXPRESSIONS:
     {
-        ScDocument* pDoc = GetScImport().GetDocument();
-        if (pDoc)
-        {
-            sal_Int32 nTab = GetScImport().GetTables().GetCurrentSheet();
-            ScRangeName* pRN = pDoc->GetRangeName(static_cast<SCTAB>(nTab));
-            if (pRN)
-            {
-                pContext = new ScXMLNamedExpressionsContext( 
-                    GetScImport(), nPrefix, rLName, xAttrList,
-                    new ScXMLNamedExpressionsContext::SheetLocalInserter(pDoc, *pRN));
-            }
-        }
+        SCTAB nTab = GetScImport().GetTables().GetCurrentSheet();
+        pContext = new ScXMLNamedExpressionsContext(
+            GetScImport(), nPrefix, rLName, xAttrList,
+            new ScXMLNamedExpressionsContext::SheetLocalInserter(GetScImport(), nTab));
     }
         break;
     case XML_TOK_TABLE_COL_GROUP:
commit 34d52ccf69b15b5889a81422ea390b08914858c7
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Jun 8 20:28:18 2011 +0000

    fdo#37816: Fix a crasher in datapilot table when moving a field button.
    
    Signed-off-by: Markus Mohrhard <markus.mohrhard at googlemail.com>

diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index 23219e5..593fc25 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -967,7 +967,10 @@ void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew )
     {
         if (pDim == &(*it))
         {
-            aDimList.erase(it);
+            // Tell ptr_vector to give up ownership of this element.  Don't
+            // delete this instance as it is re-inserted into the container
+            // later.
+            aDimList.release(it).release();
             break;
         }
     }


More information about the Libreoffice-commits mailing list