[Libreoffice-commits] core.git: 10 commits - sc/inc sc/qa sc/source

Kohei Yoshida kohei.yoshida at gmail.com
Fri Mar 15 19:14:41 PDT 2013


 sc/inc/cell.hxx                   |    4 -
 sc/inc/column.hxx                 |   10 ++++
 sc/inc/document.hxx               |    6 +-
 sc/qa/unit/ucalc.cxx              |   16 +++++++
 sc/source/core/data/cell.cxx      |   14 ++----
 sc/source/core/data/column.cxx    |   41 +++++++++++++++++++
 sc/source/core/data/column2.cxx   |   78 +++++++++++++++++++++++++++++++++++---
 sc/source/core/data/column3.cxx   |   14 +++++-
 sc/source/core/data/documen6.cxx  |   21 +++-------
 sc/source/core/data/document.cxx  |   24 +++++++----
 sc/source/core/data/table1.cxx    |    2 
 sc/source/core/data/table5.cxx    |    4 -
 sc/source/filter/xml/xmlcelli.cxx |    5 +-
 sc/source/ui/view/output2.cxx     |    3 -
 14 files changed, 193 insertions(+), 49 deletions(-)

New commits:
commit d02f456d02e1c92f6fa0a5402c18cd2409e43f91
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 22:12:04 2013 -0400

    Remove incorrect comment.
    
    Change-Id: I2b6773e0b8203d7781ac8037b5d51ebb5bba5047

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index a4a2fc3..f5a7802 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -98,10 +98,9 @@ class ScColumn
     // values; either the reall text widths or TEXTWIDTH_DIRTY.
     TextWidthType maTextWidths;
 
-    // Empty elements represent unknown script types. For now, we store script
-    // type values as unsigned shorts. Once multi_type_vector supports char
-    // and unsigned char (due in 0.7.2), we can switch to that to save storage
-    // space.
+    // For now, we store script type values as unsigned shorts. Once
+    // multi_type_vector supports char and unsigned char (due in 0.7.2), we
+    // can switch to that to save storage space.
     ScriptType maScriptTypes;
 
     SCCOL           nCol;
commit e595fb27c6ba64fd5112d4fd919067f0205ccffa
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 21:22:02 2013 -0400

    Actually unknown script type doesn't equal empty script type (0).
    
    Let's differentiate the two types.  A new cell starts with an unknown
    script type, whereas empty cells have a script type of 0 (empty).
    
    Change-Id: Id66857100ed213c5cfc37e48789448d94e97a5d2

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 404dc48..e8a39ad 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -61,23 +61,23 @@ ScNeededSizeOptions::ScNeededSizeOptions() :
 
 void ScColumn::SwapScriptTypes( ScriptType& rSrc, SCROW nSrcRow, ScriptType& rDest, SCROW nDestRow )
 {
-    unsigned short nSrcVal = SC_SCRIPTTYPE_UNKNOWN;
-    unsigned short nDestVal = SC_SCRIPTTYPE_UNKNOWN;
+    unsigned short nSrcVal = 0;
+    unsigned short nDestVal = 0;
 
     if (!rSrc.is_empty(nSrcRow))
         nSrcVal = rSrc.get<unsigned short>(nSrcRow);
     if (!rDest.is_empty(nDestRow))
         nDestVal = rDest.get<unsigned short>(nDestRow);
 
-    if (nDestVal == SC_SCRIPTTYPE_UNKNOWN)
-        rSrc.set_empty(nSrcRow, nSrcRow);
-    else
+    if (nDestVal)
         rSrc.set(nSrcRow, nDestVal);
-
-    if (nSrcVal == SC_SCRIPTTYPE_UNKNOWN)
-        rDest.set_empty(nDestRow, nDestRow);
     else
+        rSrc.set_empty(nSrcRow, nSrcRow);
+
+    if (nSrcVal)
         rDest.set(nDestRow, nSrcVal);
+    else
+        rDest.set_empty(nDestRow, nDestRow);
 }
 
 ScColumn::ScColumn() :
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 92263af..3301542 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1509,7 +1509,7 @@ void ScColumn::SetTextWidth(SCROW nRow, unsigned short nWidth)
 sal_uInt8 ScColumn::GetScriptType( SCROW nRow ) const
 {
     if (!ValidRow(nRow) || maScriptTypes.is_empty(nRow))
-        return SC_SCRIPTTYPE_UNKNOWN;
+        return 0;
 
     return maScriptTypes.get<unsigned short>(nRow);
 }
@@ -1519,8 +1519,7 @@ void ScColumn::SetScriptType( SCROW nRow, sal_uInt8 nType )
     if (!ValidRow(nRow))
         return;
 
-    if (nType == SC_SCRIPTTYPE_UNKNOWN)
-        // empty element represents unknown script type.
+    if (!nType)
         maScriptTypes.set_empty(nRow, nRow);
     else
         maScriptTypes.set<unsigned short>(nRow, nType);
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 3c1dc96..28340a2 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -97,7 +97,7 @@ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
         }
 
         maTextWidths.set<unsigned short>(nRow, TEXTWIDTH_DIRTY);
-        maScriptTypes.set_empty(nRow, nRow); // empty element represents unknown script state.
+        maScriptTypes.set<unsigned short>(nRow, SC_SCRIPTTYPE_UNKNOWN);
         CellStorageModified();
     }
     // When we insert from the Clipboard we still have wrong (old) References!
@@ -143,7 +143,7 @@ void ScColumn::Append( SCROW nRow, ScBaseCell* pCell )
     maItems.back().nRow  = nRow;
 
     maTextWidths.set<unsigned short>(nRow, TEXTWIDTH_DIRTY);
-    maScriptTypes.set_empty(nRow, nRow); // empty element represents unknown script state.
+    maScriptTypes.set<unsigned short>(nRow, SC_SCRIPTTYPE_UNKNOWN);
     CellStorageModified();
 }
 
@@ -1447,7 +1447,7 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                 pOldCell->Delete();
                 maItems[i].pCell = pNewCell; // Replace
                 maTextWidths.set<unsigned short>(nRow, TEXTWIDTH_DIRTY);
-                maScriptTypes.set_empty(nRow, nRow); // empty element represents unknown script state.
+                maScriptTypes.set<unsigned short>(nRow, SC_SCRIPTTYPE_UNKNOWN);
                 CellStorageModified();
 
                 if ( pNewCell->GetCellType() == CELLTYPE_FORMULA )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 1d75d56..16d4277 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5717,7 +5717,7 @@ sal_uInt8 ScDocument::GetScriptType( const ScAddress& rPos ) const
     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
         return maTabs[nTab]->GetScriptType(rPos.Col(), rPos.Row());
 
-    return SC_SCRIPTTYPE_UNKNOWN;
+    return 0;
 }
 
 void ScDocument::SetScriptType( const ScAddress& rPos, sal_uInt8 nType )
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index cfe0e57..38d705c 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -2083,7 +2083,7 @@ sal_uLong ScTable::AddCondFormat( ScConditionalFormat* pNew )
 sal_uInt8 ScTable::GetScriptType( SCCOL nCol, SCROW nRow ) const
 {
     if (!ValidCol(nCol))
-        return SC_SCRIPTTYPE_UNKNOWN;
+        return 0;
 
     return aCol[nCol].GetScriptType(nRow);
 }
commit e022d9eb46f5de13306da4a61b9899c79cf6170b
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 20:51:17 2013 -0400

    ScBaseCell::nScriptType is no more.
    
    Change-Id: Ic523bc5f8bf2c678cb7cf2115848d16845d2eeeb

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index 214fa2d..4f09baa 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -100,9 +100,6 @@ public:
         Returns false for formula cells returning nothing, use HasEmptyData() for that. */
     bool            IsBlank() const;
 
-    inline sal_uInt8     GetScriptType() const { return nScriptType; }
-    inline void     SetScriptType( sal_uInt8 nNew ) { nScriptType = nNew; }
-
     /** Returns true, if the cell contains a broadcaster. */
     inline bool     HasBroadcaster() const { return mpBroadcaster != 0; }
     /** Returns the pointer to the cell broadcaster. */
@@ -144,7 +141,6 @@ private:
 
 protected:
     sal_uInt8            eCellType;      // enum CellType - sal_uInt8 spart Speicher
-    sal_uInt8            nScriptType;
 };
 
 // ============================================================================
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index d4425d5..175bf14 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1176,9 +1176,8 @@ public:
     SC_DLLPUBLIC const ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator >& GetBreakIterator();
     bool            HasStringWeakCharacters( const rtl::OUString& rString );
     SC_DLLPUBLIC sal_uInt8          GetStringScriptType( const rtl::OUString& rString );
-    SC_DLLPUBLIC sal_uInt8          GetCellScriptType( ScBaseCell* pCell, sal_uLong nNumberFormat );
+    SC_DLLPUBLIC sal_uInt8 GetCellScriptType( const ScAddress& rPos, ScBaseCell* pCell, sal_uLong nNumberFormat );
     SC_DLLPUBLIC sal_uInt8 GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell );
-    sal_uInt8 GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab ) const;
 
     bool            HasDetectiveOperations() const;
     void            AddDetectiveOperation( const ScDetOpData& rData );
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 0b990a8..e37fbd2 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -70,15 +70,13 @@ IMPL_FIXEDMEMPOOL_NEWDEL( ScNoteCell )
 
 ScBaseCell::ScBaseCell( CellType eNewType ) :
     mpBroadcaster( 0 ),
-    eCellType( sal::static_int_cast<sal_uInt8>(eNewType) ),
-    nScriptType( SC_SCRIPTTYPE_UNKNOWN )
+    eCellType( sal::static_int_cast<sal_uInt8>(eNewType) )
 {
 }
 
 ScBaseCell::ScBaseCell( const ScBaseCell& rCell ) :
     mpBroadcaster( 0 ),
-    eCellType( rCell.eCellType ),
-    nScriptType( SC_SCRIPTTYPE_UNKNOWN )
+    eCellType( rCell.eCellType )
 {
 }
 
@@ -1002,7 +1000,7 @@ void ScFormulaCell::Compile( const rtl::OUString& rFormula, bool bNoListening,
     {
         bChanged = true;
         pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
-        SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+        pDocument->SetScriptType(aPos, SC_SCRIPTTYPE_UNKNOWN);
     }
     if ( bWasInFormulaTree )
         pDocument->PutInFormulaTree( this );
@@ -1096,7 +1094,7 @@ void ScFormulaCell::CompileXML( ScProgress& rProgress )
     {
         bChanged = true;
         pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
-        SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+        pDocument->SetScriptType(aPos, SC_SCRIPTTYPE_UNKNOWN);
     }
 
     //  Same as in Load: after loading, it must be known if ocMacro is in any formula
@@ -1367,7 +1365,7 @@ void ScFormulaCell::Interpret()
                             pIterCell->aResult.SetResultError( errNoConvergence);
                             pIterCell->bChanged = true;
                             pDocument->SetTextWidth(pIterCell->aPos, TEXTWIDTH_DIRTY);
-                            pIterCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN);
+                            pDocument->SetScriptType(pIterCell->aPos, SC_SCRIPTTYPE_UNKNOWN);
                         }
                     }
                     // End this iteration and remove entries.
@@ -1662,7 +1660,7 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
         if( bChanged )
         {
             pDocument->SetTextWidth(aPos, TEXTWIDTH_DIRTY);
-            SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+            pDocument->SetScriptType(aPos, SC_SCRIPTTYPE_UNKNOWN);
         }
         if (bContentChanged && pDocument->IsStreamValid(aPos.Tab()))
         {
diff --git a/sc/source/core/data/documen6.cxx b/sc/source/core/data/documen6.cxx
index d0b5aa2..507f7f9 100644
--- a/sc/source/core/data/documen6.cxx
+++ b/sc/source/core/data/documen6.cxx
@@ -114,12 +114,12 @@ sal_uInt8 ScDocument::GetStringScriptType( const rtl::OUString& rString )
     return nRet;
 }
 
-sal_uInt8 ScDocument::GetCellScriptType( ScBaseCell* pCell, sal_uLong nNumberFormat )
+sal_uInt8 ScDocument::GetCellScriptType( const ScAddress& rPos, ScBaseCell* pCell, sal_uLong nNumberFormat )
 {
     if ( !pCell )
         return 0;       // empty
 
-    sal_uInt8 nStored = pCell->GetScriptType();
+    sal_uInt8 nStored = GetScriptType(rPos);
     if ( nStored != SC_SCRIPTTYPE_UNKNOWN )         // stored value valid?
         return nStored;                             // use stored value
 
@@ -129,25 +129,17 @@ sal_uInt8 ScDocument::GetCellScriptType( ScBaseCell* pCell, sal_uLong nNumberFor
 
     sal_uInt8 nRet = GetStringScriptType( aStr );
 
-    pCell->SetScriptType( nRet );       // store for later calls
+    SetScriptType(rPos, nRet);       // store for later calls
 
     return nRet;
 }
 
 sal_uInt8 ScDocument::GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell )
 {
-    // if cell is not passed, take from document
-
-    if (!pCell)
-    {
-        pCell = GetCell( ScAddress( nCol, nRow, nTab ) );
-        if ( !pCell )
-            return 0;       // empty
-    }
-
     // if script type is set, don't have to get number formats
 
-    sal_uInt8 nStored = pCell->GetScriptType();
+    ScAddress aPos(nCol, nRow, nTab);
+    sal_uInt8 nStored = GetScriptType(aPos);
     if ( nStored != SC_SCRIPTTYPE_UNKNOWN )         // stored value valid?
         return nStored;                             // use stored value
 
@@ -160,7 +152,8 @@ sal_uInt8 ScDocument::GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseC
         pCondSet = GetCondResult( nCol, nRow, nTab );
 
     sal_uLong nFormat = pPattern->GetNumberFormat( xPoolHelper->GetFormTable(), pCondSet );
-    return GetCellScriptType( pCell, nFormat );
+
+    return GetCellScriptType(aPos, pCell, nFormat);
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index b366aa4..1d75d56 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5784,12 +5784,4 @@ void ScDocument::SetAutoNameCache(  ScAutoNameCache* pCache )
     pAutoNameCache = pCache;
 }
 
-sal_uInt8 ScDocument::GetScriptType( SCCOL nCol, SCROW nRow, SCTAB nTab ) const
-{
-    if (!ValidTab(nTab) || nTab >= static_cast<SCTAB>(maTabs.size()) || !maTabs[nTab])
-        return SC_SCRIPTTYPE_UNKNOWN;
-
-    return maTabs[nTab]->GetScriptType(nCol, nRow);
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 264bba8..474cc19 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -1159,7 +1159,7 @@ void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* p
         rCol.SetTextWidth(nRow, TEXTWIDTH_DIRTY);
 
         if ( bNumFormatChanged )
-            pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+            rCol.SetScriptType(nRow, SC_SCRIPTTYPE_UNKNOWN);
 
         if ( bBroadcast )
         {   // nur bei CalcAsShown
@@ -1201,7 +1201,7 @@ void ScTable::InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* p
             }
 
             if ( bNumFormatChanged )
-                pCell->SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
+                aCol[nCol].SetScriptType(nRow, SC_SCRIPTTYPE_UNKNOWN);
 
             if ( bBroadcast )
             {   // nur bei CalcAsShown
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index e7464af..7126f14 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -1093,9 +1093,10 @@ void ScXMLTableRowCellContext::PutValueCell( const ScAddress& rCurrentPos )
         // will be reset when the style is applied.
 
         ScBaseCell* pNewCell = new ScValueCell(fValue);
+        ScDocument* pDoc = rXMLImport.GetDocument();
         if ( rXMLImport.IsLatinDefaultStyle() )
-            pNewCell->SetScriptType( SCRIPTTYPE_LATIN );
-        rXMLImport.GetDocument()->PutCell(
+            pDoc->SetScriptType(rCurrentPos, SCRIPTTYPE_LATIN);
+        pDoc->PutCell(
             rCurrentPos.Col(), rCurrentPos.Row(),
             rCurrentPos.Tab(), pNewCell );
     }
diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx
index 5f537df..2f53d18 100644
--- a/sc/source/ui/view/output2.cxx
+++ b/sc/source/ui/view/output2.cxx
@@ -1598,7 +1598,8 @@ void ScOutputData::DrawStrings( sal_Bool bPixelToLogic )
                     }
 
                     sal_uInt8 nScript = mpDoc->GetCellScriptType(
-                        pCell, pPattern->GetNumberFormat(mpDoc->GetFormatTable(), pCondSet));
+                        ScAddress(nCellX, nCellY, nTab), pCell,
+                        pPattern->GetNumberFormat(mpDoc->GetFormatTable(), pCondSet));
 
                     if (nScript == 0)
                         nScript = ScGlobal::GetDefaultScriptType();
commit 083c0a26ee765cb4753249178559ae84e12a7227
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 20:14:57 2013 -0400

    Accessor methods in ScDocument for cell text's script types.
    
    Change-Id: I23349ba6411bd74247e150f871f363b0eacda0a2

diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index cb8aac7..d4425d5 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1849,6 +1849,9 @@ public:
     sal_uInt16 GetTextWidth( const ScAddress& rPos ) const;
     void SetTextWidth( const ScAddress& rPos, sal_uInt16 nWidth );
 
+    sal_uInt8 GetScriptType( const ScAddress& rPos ) const;
+    void SetScriptType( const ScAddress& rPos, sal_uInt8 nType );
+
 private: // CLOOK-Impl-methods
 
     /**
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index ec9c7c6..b366aa4 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5711,6 +5711,22 @@ void ScDocument::SetTextWidth( const ScAddress& rPos, sal_uInt16 nWidth )
         maTabs[nTab]->SetTextWidth(rPos.Col(), rPos.Row(), nWidth);
 }
 
+sal_uInt8 ScDocument::GetScriptType( const ScAddress& rPos ) const
+{
+    SCTAB nTab = rPos.Tab();
+    if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
+        return maTabs[nTab]->GetScriptType(rPos.Col(), rPos.Row());
+
+    return SC_SCRIPTTYPE_UNKNOWN;
+}
+
+void ScDocument::SetScriptType( const ScAddress& rPos, sal_uInt8 nType )
+{
+    SCTAB nTab = rPos.Tab();
+    if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()) && maTabs[nTab])
+        maTabs[nTab]->SetScriptType(rPos.Col(), rPos.Row(), nType);
+}
+
 void ScDocument::EnableUndo( bool bVal )
 {
     // The undo manager increases lock count every time undo is disabled.
commit 61dc77d7ecfdd72770d5b20db39e6c46cfdbd4a8
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 17:55:55 2013 -0400

    More script type handling.
    
    Basically I'm just following maTextWidths' call sites. Some things are
    handled differently though for script types, since empty elements may
    correspond with either empty or non-empty cells (unlike the text width
    array).
    
    Change-Id: If98bcb81e9048b24d75b2bc9fc972a7d74cbbf89

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1b01787..a4a2fc3 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -128,6 +128,8 @@ friend class ScColumnTextWidthIterator;
     ScColumn(const ScColumn&); // disabled
     ScColumn& operator= (const ScColumn&); // disabled
 
+    static void SwapScriptTypes( ScriptType& rSrc, SCROW nSrcRow, ScriptType& rDest, SCROW nDestRow );
+
 public:
                 ScColumn();
                 ~ScColumn();
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index c73fa94..404dc48 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -59,6 +59,27 @@ ScNeededSizeOptions::ScNeededSizeOptions() :
 {
 }
 
+void ScColumn::SwapScriptTypes( ScriptType& rSrc, SCROW nSrcRow, ScriptType& rDest, SCROW nDestRow )
+{
+    unsigned short nSrcVal = SC_SCRIPTTYPE_UNKNOWN;
+    unsigned short nDestVal = SC_SCRIPTTYPE_UNKNOWN;
+
+    if (!rSrc.is_empty(nSrcRow))
+        nSrcVal = rSrc.get<unsigned short>(nSrcRow);
+    if (!rDest.is_empty(nDestRow))
+        nDestVal = rDest.get<unsigned short>(nDestRow);
+
+    if (nDestVal == SC_SCRIPTTYPE_UNKNOWN)
+        rSrc.set_empty(nSrcRow, nSrcRow);
+    else
+        rSrc.set(nSrcRow, nDestVal);
+
+    if (nSrcVal == SC_SCRIPTTYPE_UNKNOWN)
+        rDest.set_empty(nDestRow, nDestRow);
+    else
+        rDest.set(nDestRow, nSrcVal);
+}
+
 ScColumn::ScColumn() :
     maTextWidths(MAXROWCOUNT),
     maScriptTypes(MAXROWCOUNT),
@@ -865,10 +886,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             maTextWidths.set<unsigned short>(nRow2, nVal1);
 
             // Swap script types.
-            nVal1 = maScriptTypes.get<unsigned short>(nRow1);
-            nVal2 = maScriptTypes.get<unsigned short>(nRow2);
-            maScriptTypes.set(nRow1, nVal2);
-            maScriptTypes.set(nRow2, nVal1);
+            SwapScriptTypes(maScriptTypes, nRow1, maScriptTypes, nRow2);
 
             CellStorageModified();
         }
@@ -1028,10 +1046,7 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
         rCol.maTextWidths.set<unsigned short>(nRow, nVal1);
 
         // Swap script types.
-        nVal1 = maScriptTypes.get<unsigned short>(nRow);
-        nVal2 = rCol.maScriptTypes.get<unsigned short>(nRow);
-        maScriptTypes.set(nRow, nVal2);
-        rCol.maScriptTypes.set(nRow, nVal1);
+        SwapScriptTypes(maScriptTypes, nRow, rCol.maScriptTypes, nRow);
 
         CellStorageModified();
         rCol.CellStorageModified();
@@ -1206,7 +1221,10 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
     pDocument->SetAutoCalc( bOldAutoCalc );
 
     maTextWidths.insert_empty(nStartRow, nSize);
+    maTextWidths.resize(MAXROWCOUNT);
     maScriptTypes.insert_empty(nStartRow, nSize);
+    maScriptTypes.resize(MAXROWCOUNT);
+
     CellStorageModified();
 }
 
@@ -1615,6 +1633,7 @@ void ScColumn::SwapCol(ScColumn& rCol)
 {
     maItems.swap(rCol.maItems);
     maTextWidths.swap(rCol.maTextWidths);
+    maScriptTypes.swap(rCol.maScriptTypes);
 
     CellStorageModified();
     rCol.CellStorageModified();
@@ -1718,6 +1737,7 @@ void ScColumn::MoveTo(SCROW nStartRow, SCROW nEndRow, ScColumn& rCol)
         if (bErased)
         {
             maTextWidths.set_empty(nStartRow, nEndRow);
+            maScriptTypes.set_empty(nStartRow, nEndRow);
             CellStorageModified();
         }
     }
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 9537bf6..3c1dc96 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -97,6 +97,7 @@ void ScColumn::Insert( SCROW nRow, ScBaseCell* pNewCell )
         }
 
         maTextWidths.set<unsigned short>(nRow, TEXTWIDTH_DIRTY);
+        maScriptTypes.set_empty(nRow, nRow); // empty element represents unknown script state.
         CellStorageModified();
     }
     // When we insert from the Clipboard we still have wrong (old) References!
@@ -142,6 +143,7 @@ void ScColumn::Append( SCROW nRow, ScBaseCell* pCell )
     maItems.back().nRow  = nRow;
 
     maTextWidths.set<unsigned short>(nRow, TEXTWIDTH_DIRTY);
+    maScriptTypes.set_empty(nRow, nRow); // empty element represents unknown script state.
     CellStorageModified();
 }
 
@@ -166,6 +168,7 @@ void ScColumn::Delete( SCROW nRow )
             pNoteCell->Delete();
             maItems.erase( maItems.begin() + nIndex);
             maTextWidths.set_empty(nRow, nRow);
+            maScriptTypes.set_empty(nRow, nRow);
             // Should we free memory here (delta)? It'll be slower!
         }
         pCell->EndListeningTo( pDocument );
@@ -190,6 +193,7 @@ void ScColumn::DeleteAtIndex( SCSIZE nIndex )
     pCell->Delete();
 
     maTextWidths.set_empty(nRow, nRow);
+    maScriptTypes.set_empty(nRow, nRow);
     CellStorageModified();
 }
 
@@ -203,6 +207,8 @@ void ScColumn::FreeAll()
     // Text width should keep a logical empty range of 0-MAXROW when the cell array is empty.
     maTextWidths.clear();
     maTextWidths.resize(MAXROWCOUNT);
+    maScriptTypes.clear();
+    maScriptTypes.resize(MAXROWCOUNT);
     CellStorageModified();
 }
 
@@ -264,6 +270,8 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
     // Shift the text width array too (before the broadcast).
     maTextWidths.erase(nStartRow, nEndRow);
     maTextWidths.resize(MAXROWCOUNT);
+    maScriptTypes.erase(nStartRow, nEndRow);
+    maScriptTypes.resize(MAXROWCOUNT);
 
     ScAddress aAdr( nCol, 0, nTab );
     ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL ); // only areas (ScBaseCell* == NULL)
@@ -508,6 +516,7 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, sal_uInt16 nDe
             maItems.erase(itErase, itEraseEnd);
 
             maTextWidths.set_empty(nStartRow, nEndRow);
+            maScriptTypes.set_empty(nStartRow, nEndRow);
 
             nEndSegment = nStartSegment;
         }
@@ -1438,6 +1447,7 @@ bool ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                 pOldCell->Delete();
                 maItems[i].pCell = pNewCell; // Replace
                 maTextWidths.set<unsigned short>(nRow, TEXTWIDTH_DIRTY);
+                maScriptTypes.set_empty(nRow, nRow); // empty element represents unknown script state.
                 CellStorageModified();
 
                 if ( pNewCell->GetCellType() == CELLTYPE_FORMULA )
commit 86f704a2e984073c217dd549836bec9265afad58
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 16:46:36 2013 -0400

    Started handling the cell text script types. Still work in progress.
    
    Change-Id: I6af668894d61d33de6697fe45fce1515520d4bfa

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 2469a6c..1b01787 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -418,6 +418,8 @@ private:
      * Call this only from those methods where maItems is modified directly.
      */
     void CellStorageModified();
+
+    void CopyScriptTypesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) const;
 };
 
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index b472e9e..c73fa94 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -863,6 +863,13 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
             unsigned short nVal2 = maTextWidths.get<unsigned short>(nRow2);
             maTextWidths.set<unsigned short>(nRow1, nVal2);
             maTextWidths.set<unsigned short>(nRow2, nVal1);
+
+            // Swap script types.
+            nVal1 = maScriptTypes.get<unsigned short>(nRow1);
+            nVal2 = maScriptTypes.get<unsigned short>(nRow2);
+            maScriptTypes.set(nRow1, nVal2);
+            maScriptTypes.set(nRow2, nVal1);
+
             CellStorageModified();
         }
         else
@@ -881,6 +888,7 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2)
                 // remove ColEntry at old position
                 maItems.erase( maItems.begin() + nIndex1 );
                 maTextWidths.set_empty(nRow1, nRow1);
+                maScriptTypes.set_empty(nRow1, nRow1);
             }
 
             // Empty text width at the cell 1 position.  For now, we don't
@@ -1019,6 +1027,12 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
         maTextWidths.set<unsigned short>(nRow, nVal2);
         rCol.maTextWidths.set<unsigned short>(nRow, nVal1);
 
+        // Swap script types.
+        nVal1 = maScriptTypes.get<unsigned short>(nRow);
+        nVal2 = rCol.maScriptTypes.get<unsigned short>(nRow);
+        maScriptTypes.set(nRow, nVal2);
+        rCol.maScriptTypes.set(nRow, nVal1);
+
         CellStorageModified();
         rCol.CellStorageModified();
     }
@@ -1038,6 +1052,7 @@ void ScColumn::SwapCell( SCROW nRow, ScColumn& rCol)
         }
 
         maTextWidths.set_empty(nRow, nRow);
+        maScriptTypes.set_empty(nRow, nRow);
         CellStorageModified();
 
         // We don't transfer the text width to the destination column because
@@ -1191,6 +1206,7 @@ void ScColumn::InsertRow( SCROW nStartRow, SCSIZE nSize )
     pDocument->SetAutoCalc( bOldAutoCalc );
 
     maTextWidths.insert_empty(nStartRow, nSize);
+    maScriptTypes.insert_empty(nStartRow, nSize);
     CellStorageModified();
 }
 
@@ -1276,6 +1292,8 @@ void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol
     if (nRow1 > nRow2)
         return;
 
+    CopyScriptTypesToDocument(nRow1, nRow2, rDestCol);
+
     // First, clear the destination column for the row range specified.
     std::vector<ColEntry>::iterator it, itEnd;
 
@@ -1353,6 +1371,8 @@ void ScColumn::CopyStaticToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol
     // destination column shouldn't have any cells within the specified range.
     it = std::find_if(rDestCol.maItems.begin(), rDestCol.maItems.end(), FindAboveRow(nRow2));
     rDestCol.maItems.insert(it, aCopied.begin(), aCopied.end());
+
+    // Set text width values dirty for all non-empty cell positions.
     it = aCopied.begin();
     itEnd = aCopied.end();
     for (; it != itEnd; ++it)
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 2715fb9..92263af 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1433,6 +1433,69 @@ void ScColumn::CellStorageModified()
 #endif
 }
 
+void ScColumn::CopyScriptTypesToDocument(SCROW nRow1, SCROW nRow2, ScColumn& rDestCol) const
+{
+    rDestCol.maScriptTypes.set_empty(nRow1, nRow2); // Empty the destination range first.
+
+    ScriptType::const_iterator itBlk = maScriptTypes.begin(), itBlkEnd = maScriptTypes.end();
+
+    // Locate the top row position.
+    size_t nOffsetInBlock = 0;
+    size_t nBlockStart = 0, nBlockEnd = 0, nRowPos = static_cast<size_t>(nRow1);
+    for (; itBlk != itBlkEnd; ++itBlk)
+    {
+        nBlockEnd = nBlockStart + itBlk->size;
+        if (nBlockStart <= nRowPos && nRowPos <= nBlockEnd)
+        {
+            // Found.
+            nOffsetInBlock = nRowPos - nBlockStart;
+            break;
+        }
+    }
+
+    if (itBlk == itBlkEnd)
+        // Specified range not found. Bail out.
+        return;
+
+    nRowPos = static_cast<size_t>(nRow2); // End row position.
+
+    // Keep copying until we hit the end row position.
+    mdds::mtv::ushort_element_block::const_iterator itData, itDataEnd;
+    for (; itBlk != itBlkEnd; ++itBlk, nBlockStart = nBlockEnd, nOffsetInBlock = 0)
+    {
+        nBlockEnd = nBlockStart + itBlk->size;
+        if (!itBlk->data)
+        {
+            // Empty block.
+            if (nBlockStart <= nRowPos && nRowPos <= nBlockEnd)
+                // This block contains the end row.
+                rDestCol.maScriptTypes.set_empty(nBlockStart + nOffsetInBlock, nRowPos);
+            else
+                rDestCol.maScriptTypes.set_empty(nBlockStart + nOffsetInBlock, nBlockEnd-1);
+
+            continue;
+        }
+
+        // Non-empty block.
+        itData = mdds::mtv::ushort_element_block::begin(*itBlk->data);
+        itDataEnd = mdds::mtv::ushort_element_block::end(*itBlk->data);
+        std::advance(itData, nOffsetInBlock);
+
+        if (nBlockStart <= nRowPos && nRowPos <= nBlockEnd)
+        {
+            // This block contains the end row. Only copy partially.
+            size_t nOffset = nRowPos - nBlockStart + 1;
+            itDataEnd = mdds::mtv::ushort_element_block::begin(*itBlk->data);
+            std::advance(itDataEnd, nOffset);
+
+            rDestCol.maScriptTypes.set(nBlockStart + nOffsetInBlock, itData, itDataEnd);
+            break;
+        }
+
+        rDestCol.maScriptTypes.set(nBlockStart + nOffsetInBlock, itData, itDataEnd);
+    }
+}
+
 unsigned short ScColumn::GetTextWidth(SCROW nRow) const
 {
     return maTextWidths.get<unsigned short>(nRow);
commit a9ec5f51e13adef2cc2d03e8073e9b6013598309
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 15:15:57 2013 -0400

    Unit test to catch the out-of-sync text width bug I just fixed today.
    
    Change-Id: I82d4199d7f8b7ba2dadb734a808dac53e845538f

diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index f34dfb5..ec94652 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -6102,6 +6102,22 @@ void Test::testCellTextWidth()
         CPPUNIT_ASSERT_MESSAGE("Iterator should have ended.", !pIter->hasCell());
     }
 
+    // Delete row 2 which shifts all cells below row 2 upward. After this, we
+    // should only have cells at rows 0 and 17.
+    m_pDoc->DeleteRow(0, 0, MAXCOL, MAXTAB, 2, 1);
+    {
+        // Full range again.
+        pIter.reset(new ScColumnTextWidthIterator(*m_pDoc, aTopCell, MAXROW));
+        SCROW aRows[] = { 0, 17 };
+        size_t n = SAL_N_ELEMENTS(aRows);
+        for (size_t i = 0; i < n; ++i, pIter->next())
+        {
+            CPPUNIT_ASSERT_MESSAGE("Cell expected, but not there.", pIter->hasCell());
+            CPPUNIT_ASSERT_EQUAL(aRows[i], pIter->getPos());
+        }
+        CPPUNIT_ASSERT_MESSAGE("Iterator should have ended.", !pIter->hasCell());
+    }
+
     m_pDoc->DeleteTab(0);
 }
 
commit 6b51a4e7a3f511fc1dce0b21fe7926d303e9afbf
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 15:06:25 2013 -0400

    Set up new container to store cell text's script type.
    
    Change-Id: I0330dea1b2f85a8ba12cb232ab8b4263607ba225

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index dd14b6a..2469a6c 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -91,12 +91,19 @@ struct ColEntry
 class ScColumn
 {
     typedef mdds::multi_type_vector<mdds::mtv::element_block_func> TextWidthType;
+    typedef mdds::multi_type_vector<mdds::mtv::element_block_func> ScriptType;
 
     // Only stores empty or unsigned short values.  Empty values correspond
     // with empty cells. All non-empty cell positions must have unsigned short
     // values; either the reall text widths or TEXTWIDTH_DIRTY.
     TextWidthType maTextWidths;
 
+    // Empty elements represent unknown script types. For now, we store script
+    // type values as unsigned shorts. Once multi_type_vector supports char
+    // and unsigned char (due in 0.7.2), we can switch to that to save storage
+    // space.
+    ScriptType maScriptTypes;
+
     SCCOL           nCol;
     SCTAB           nTab;
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index a53c8a8..b472e9e 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -61,6 +61,7 @@ ScNeededSizeOptions::ScNeededSizeOptions() :
 
 ScColumn::ScColumn() :
     maTextWidths(MAXROWCOUNT),
+    maScriptTypes(MAXROWCOUNT),
     nCol( 0 ),
     pAttrArray( NULL ),
     pDocument( NULL )
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 84cc89d..2715fb9 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1445,18 +1445,22 @@ void ScColumn::SetTextWidth(SCROW nRow, unsigned short nWidth)
 
 sal_uInt8 ScColumn::GetScriptType( SCROW nRow ) const
 {
-    if (!ValidRow(nRow))
+    if (!ValidRow(nRow) || maScriptTypes.is_empty(nRow))
         return SC_SCRIPTTYPE_UNKNOWN;
 
-    return SC_SCRIPTTYPE_UNKNOWN;
+    return maScriptTypes.get<unsigned short>(nRow);
 }
 
-void ScColumn::SetScriptType( SCROW nRow, sal_uInt8 /*nType*/ )
+void ScColumn::SetScriptType( SCROW nRow, sal_uInt8 nType )
 {
     if (!ValidRow(nRow))
         return;
 
-    // TODO: Implement this.
+    if (nType == SC_SCRIPTTYPE_UNKNOWN)
+        // empty element represents unknown script type.
+        maScriptTypes.set_empty(nRow, nRow);
+    else
+        maScriptTypes.set<unsigned short>(nRow, nType);
 }
 
 void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const
commit e7c6d50cbe5f4b78294d046299c153f2e4b50498
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 14:32:02 2013 -0400

    Actually these should be MAXROWCOUNT; MAXROW would be one element too short.
    
    Change-Id: Id0be194bef04a5f32e1624c6c6910db7ec3ddb36

diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 0ba6f01..9537bf6 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -202,7 +202,7 @@ void ScColumn::FreeAll()
 
     // Text width should keep a logical empty range of 0-MAXROW when the cell array is empty.
     maTextWidths.clear();
-    maTextWidths.resize(MAXROW);
+    maTextWidths.resize(MAXROWCOUNT);
     CellStorageModified();
 }
 
@@ -263,7 +263,7 @@ void ScColumn::DeleteRow( SCROW nStartRow, SCSIZE nSize )
 
     // Shift the text width array too (before the broadcast).
     maTextWidths.erase(nStartRow, nEndRow);
-    maTextWidths.resize(MAXROW);
+    maTextWidths.resize(MAXROWCOUNT);
 
     ScAddress aAdr( nCol, 0, nTab );
     ScHint aHint( SC_HINT_DATACHANGED, aAdr, NULL ); // only areas (ScBaseCell* == NULL)
commit 4adcb80e0a69e2d1724ecd7aad521c994e2303dc
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Fri Mar 15 12:39:59 2013 -0400

    Flush buffer before aborting; else we may not see the output at all.
    
    Change-Id: Iae5e604d6f947c8ab7853ef5cc2cfbe9566fea0c

diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index a1a84bb..84cc89d 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1397,12 +1397,14 @@ void ScColumn::CellStorageModified()
         if (maTextWidths.empty())
         {
             cout << "ScColumn::CellStorageModified: Text width array is empty, but shouldn't." << endl;
+            cout.flush();
             abort();
         }
 
         if (maTextWidths.block_size() != 1 || maTextWidths.begin()->type != mdds::mtv::element_type_empty)
         {
             cout << "ScColumn::CellStorageModified: When the cell array is empty, the text with array should consist of one empty block." << endl;
+            cout.flush();
             abort();
         }
 


More information about the Libreoffice-commits mailing list