[ooo-build-commit] .: patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Wed Mar 3 20:37:10 PST 2010


 patches/dev300/apply                                |    1 
 patches/dev300/calc-perf-ods-import-cellstyles.diff | 1103 ++++++++++++++++++++
 2 files changed, 1104 insertions(+)

New commits:
commit 167c538af9d84f9ba61eabff11dddb6b40a275f2
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Wed Mar 3 23:19:15 2010 -0500

    Speed up the import of ods documents.
    
    * patches/dev300/apply:
    * patches/dev300/calc-perf-ods-import-cellstyles.diff: perform a light-weight
      joining of cell style ranges, which reduces the import time significantly
      especially for large ods documents. (n#582693)

diff --git a/patches/dev300/apply b/patches/dev300/apply
index 8379181..061c481 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3533,6 +3533,7 @@ calc-perf-import-dbf-sc.diff,           n#558505, kohei
 
 # Speed up row height data import from ods documents.
 calc-perf-ods-import-row-height.diff, n#582693, kohei
+calc-perf-ods-import-cellstyles.diff, n#582693, kohei
 
 [ CalcFixes ]
 
diff --git a/patches/dev300/calc-perf-ods-import-cellstyles.diff b/patches/dev300/calc-perf-ods-import-cellstyles.diff
new file mode 100644
index 0000000..95e78eb
--- /dev/null
+++ b/patches/dev300/calc-perf-ods-import-cellstyles.diff
@@ -0,0 +1,1103 @@
+diff --git sc/inc/mdds/flatsegmenttree.hxx sc/inc/mdds/flatsegmenttree.hxx
+index 3128888..71e9f97 100644
+--- sc/inc/mdds/flatsegmenttree.hxx
++++ sc/inc/mdds/flatsegmenttree.hxx
+@@ -72,6 +72,21 @@ public:
+         {
+         }
+ 
++        node(const node& r) :
++            node_base(r)
++        {
++            if (is_leaf)
++            {
++                value_leaf.key = r.value_leaf.key;
++                value_leaf.value = r.value_leaf.value;
++            }
++            else
++            {
++                value_nonleaf.low = r.value_nonleaf.low;
++                value_nonleaf.high = r.value_nonleaf.high;
++            }
++        }
++
+         virtual ~node()
+         {
+         }
+@@ -148,6 +163,11 @@ public:
+         {
+             return new node(leaf);
+         }
++
++        virtual node_base* clone() const
++        {
++            return new node(*this);
++        }
+     };
+ 
+ private:
+@@ -306,43 +326,19 @@ public:
+         return static_cast<node*>(base_node.get());
+     }
+ 
+-    flat_segment_tree(key_type min_val, key_type max_val, value_type init_val) :
+-        m_root_node(static_cast<node*>(NULL)),
+-        m_left_leaf(new node(true)),
+-        m_right_leaf(new node(true)),
+-        m_init_val(init_val),
+-        m_valid_tree(false)
++    static node* get_node(const node_base* base_node)
+     {
+-        // we need to create two end nodes during initialization.
+-        get_node(m_left_leaf)->value_leaf.key = min_val;
+-        get_node(m_left_leaf)->value_leaf.value = init_val;
+-        m_left_leaf->right = m_right_leaf;
+-
+-        get_node(m_right_leaf)->value_leaf.key = max_val;
+-        m_right_leaf->left = m_left_leaf;
+-
+-        // We don't ever use the value of the right leaf node, but we need the
+-        // value to be always the same, to make it easier to check for
+-        // equality.
+-        get_node(m_right_leaf)->value_leaf.value = ::std::numeric_limits<value_type>::max();
++        return static_cast<node*>(base_node);
+     }
+ 
+-    ~flat_segment_tree()
+-    {
+-        // Go through all leaf nodes, and disconnect their links.
+-        node_base* cur_node = m_left_leaf.get();
+-        do
+-        {
+-            node_base* next_node = cur_node->right.get();
+-            disconnect_node(cur_node);
+-            cur_node = next_node;
+-        }
+-        while (cur_node != m_right_leaf.get());
++    flat_segment_tree(key_type min_val, key_type max_val, value_type init_val);
+ 
+-        disconnect_node(m_right_leaf.get());
+-        clear_tree(m_root_node);
+-        disconnect_node(m_root_node.get());
+-    }
++    /** 
++     * Copy constructor only copies the leaf nodes.  
++     */
++    flat_segment_tree(const flat_segment_tree<key_type, value_type>& r);
++
++    ~flat_segment_tree();
+ 
+     /** 
+      * Insert a new segment into the tree.  It searches for the point of 
+@@ -413,6 +409,11 @@ public:
+     }
+ 
+ #ifdef UNIT_TEST
++    node_base_ptr get_root_node() const
++    {
++        return m_root_node;
++    }
++
+     void dump_tree() const
+     {
+         using ::std::cout;
+@@ -513,7 +514,7 @@ public:
+ #endif
+ 
+ private:
+-    flat_segment_tree();
++    flat_segment_tree(); // default constructor is not allowed.
+ 
+     void append_new_segment(key_type start_key)
+     {
+@@ -601,6 +602,79 @@ private:
+ };
+ 
+ template<typename _Key, typename _Value>
++flat_segment_tree<_Key, _Value>::flat_segment_tree(key_type min_val, key_type max_val, value_type init_val) :
++    m_root_node(static_cast<node*>(NULL)),
++    m_left_leaf(new node(true)),
++    m_right_leaf(new node(true)),
++    m_init_val(init_val),
++    m_valid_tree(false)
++{
++    // we need to create two end nodes during initialization.
++    get_node(m_left_leaf)->value_leaf.key = min_val;
++    get_node(m_left_leaf)->value_leaf.value = init_val;
++    m_left_leaf->right = m_right_leaf;
++
++    get_node(m_right_leaf)->value_leaf.key = max_val;
++    m_right_leaf->left = m_left_leaf;
++
++    // We don't ever use the value of the right leaf node, but we need the
++    // value to be always the same, to make it easier to check for
++    // equality.
++    get_node(m_right_leaf)->value_leaf.value = ::std::numeric_limits<value_type>::max();
++}
++
++template<typename _Key, typename _Value>
++flat_segment_tree<_Key, _Value>::flat_segment_tree(const flat_segment_tree<_Key, _Value>& r) :
++    m_root_node(static_cast<node*>(NULL)),
++    m_left_leaf(new node(static_cast<const node&>(*r.m_left_leaf))),
++    m_right_leaf(static_cast<node*>(NULL)),
++    m_init_val(r.m_init_val),
++    m_valid_tree(false) // tree is invalid because we only copy the leaf nodes.
++{
++    // Copy all the leaf nodes from the original instance.
++    node_base* src_node = r.m_left_leaf.get();
++    node_base_ptr dest_node = m_left_leaf;
++    while (true)
++    {
++        dest_node->right.reset(src_node->right->clone());
++
++        // Move on to the next source node.
++        src_node = src_node->right.get();
++
++        // Move on to the next destination node, and have the next node point
++        // back to the previous node.
++        node_base_ptr old_node = dest_node;
++        dest_node = dest_node->right;
++        dest_node->left = old_node;
++
++        if (src_node == r.m_right_leaf.get())
++        {
++            // Reached the right most leaf node.  We can stop here.
++            m_right_leaf = dest_node;
++            break;
++        }
++    }
++}
++
++template<typename _Key, typename _Value>
++flat_segment_tree<_Key, _Value>::~flat_segment_tree()
++{
++    // Go through all leaf nodes, and disconnect their links.
++    node_base* cur_node = m_left_leaf.get();
++    do
++    {
++        node_base* next_node = cur_node->right.get();
++        disconnect_node(cur_node);
++        cur_node = next_node;
++    }
++    while (cur_node != m_right_leaf.get());
++
++    disconnect_node(m_right_leaf.get());
++    clear_tree(m_root_node);
++    disconnect_node(m_root_node.get());
++}
++
++template<typename _Key, typename _Value>
+ void flat_segment_tree<_Key, _Value>::insert_segment_impl(key_type start_key, key_type end_key, value_type val, bool forward)
+ {
+     if (end_key < get_node(m_left_leaf)->value_leaf.key || start_key > get_node(m_right_leaf)->value_leaf.key)
+diff --git sc/inc/mdds/node.hxx sc/inc/mdds/node.hxx
+index 04da08c..f7865cf 100644
+--- sc/inc/mdds/node.hxx
++++ sc/inc/mdds/node.hxx
+@@ -107,6 +107,35 @@ struct node_base : public intrusive_ref_base
+ #endif
+     }
+ 
++    /** 
++     * When copying node, only the stored values should be copied. 
++     * Connections to the parent, left and right nodes must not be copied. 
++     */
++    node_base(const node_base& r) :
++        intrusive_ref_base(),
++        parent(static_cast<node_base*>(NULL)),
++        left(static_cast<node_base*>(NULL)),
++        right(static_cast<node_base*>(NULL)),
++        is_leaf(r.is_leaf)
++    {
++#ifdef DEBUG_NODE_BASE
++        ++node_instance_count;
++#endif
++    }
++
++    /** 
++     * Like the copy constructor, only the stored values should be copied. 
++     */
++    node_base& operator=(const node_base& r)
++    {
++        if (this == &r)
++            // assignment to self.
++            return *this;
++
++        is_leaf = r.is_leaf;
++        return *this;
++    }
++
+     virtual ~node_base()
+     {
+ #ifdef DEBUG_NODE_BASE
+@@ -119,6 +148,7 @@ struct node_base : public intrusive_ref_base
+     virtual void fill_nonleaf_value(const node_base_ptr& left_node, const node_base_ptr& right_node) = 0;
+     virtual void dump_value() const = 0;
+     virtual node_base* create_new(bool leaf) const = 0;
++    virtual node_base* clone() const = 0;
+ };
+ 
+ template<typename _NodePtr>
+diff --git sc/inc/segmenttree.hxx sc/inc/segmenttree.hxx
+index b946f6c..4b45d20 100644
+--- sc/inc/segmenttree.hxx
++++ sc/inc/segmenttree.hxx
+@@ -74,6 +74,7 @@ public:
+     };
+ 
+     ScFlatBoolRowSegments();
++    ScFlatBoolRowSegments(const ScFlatBoolRowSegments& r);
+     ~ScFlatBoolRowSegments();
+ 
+     void setTrue(SCROW nRow1, SCROW nRow2);
+@@ -85,6 +86,9 @@ public:
+ 
+     SCROW findLastNotOf(bool bValue) const;
+ 
++    void enableTreeSearch(bool bEnable);
++    void setInsertFromBack(bool bInsertFromBack);
++
+ private:
+     ::std::auto_ptr<ScFlatBoolSegmentsImpl> mpImpl;
+ };
+@@ -101,6 +105,7 @@ public:
+         bool    mbValue;
+     };
+     ScFlatBoolColSegments();
++    ScFlatBoolColSegments(const ScFlatBoolColSegments& r);
+     ~ScFlatBoolColSegments();
+ 
+     void setTrue(SCCOL nCol1, SCCOL nCol2);
+@@ -145,6 +150,7 @@ public:
+     };
+ 
+     ScFlatUInt16RowSegments(sal_uInt16 nDefault);
++    ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments& r);
+     ~ScFlatUInt16RowSegments();
+ 
+     void setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue);
+diff --git sc/inc/simplerangelist.hxx sc/inc/simplerangelist.hxx
+new file mode 100644
+index 0000000..359f01f
+--- /dev/null
++++ sc/inc/simplerangelist.hxx
+@@ -0,0 +1,82 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: rangelst.hxx,v $
++ * $Revision: 1.9.32.3 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++#ifndef __SC_SIMPLERANGELIST_HXX__
++#define __SC_SIMPLERANGELIST_HXX__
++
++#include <boost/shared_ptr.hpp>
++
++#include "address.hxx"
++
++#include <map>
++#include <list>
++
++class ScAddress;
++class ScRange;
++class ScRangeList;
++
++/** 
++ * This container is optimized for use in the ods import filter, to store 
++ * ranges for cell styles.  We may change the name of this class once we 
++ * have a better name for what it does.  Using this is way more efficient 
++ * than ScRangeList. 
++ */
++class ScSimpleRangeList
++{
++public:
++    struct Range
++    {
++        SCCOL mnCol1;
++        SCROW mnRow1;
++        SCCOL mnCol2;
++        SCROW mnRow2;
++        explicit Range(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2);
++
++        bool contains(const Range& r) const;
++    };
++    typedef ::boost::shared_ptr< ::std::list<Range> > RangeListRef;
++    typedef ::std::map<SCTAB, RangeListRef> TabType;
++
++    ScSimpleRangeList();
++
++    void addRange(const ScRange& rRange);
++    void insertCol(SCCOL nCol, SCTAB nTab);
++    void insertRow(SCROW nRow, SCTAB nTab);
++    void getRangeList(::std::list<ScRange>& rList) const;
++    void clear();
++
++private:
++    RangeListRef findTab(SCTAB nTab);
++
++private:
++    TabType maTabs;
++};
++
++#endif
+diff --git sc/source/core/data/segmenttree.cxx sc/source/core/data/segmenttree.cxx
+index 8c4740d..b0ac112 100644
+--- sc/source/core/data/segmenttree.cxx
++++ sc/source/core/data/segmenttree.cxx
+@@ -54,7 +54,8 @@ public:
+         ValueType   mnValue;
+     };
+ 
+-    inline ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault);
++    ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault);
++    ScFlatSegmentsImpl(const ScFlatSegmentsImpl& r);
+     ~ScFlatSegmentsImpl();
+ 
+     void setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue);
+@@ -98,6 +99,14 @@ ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(SCCOLROW nMax,
+ }
+ 
+ template<typename _ValueType, typename _ExtValueType>
++ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(const ScFlatSegmentsImpl<_ValueType, _ExtValueType>& r) :
++    maSegments(r.maSegments),
++    mbTreeSearchEnabled(r.mbTreeSearchEnabled),
++    mbInsertFromBack(r.mbInsertFromBack)
++{
++}
++
++template<typename _ValueType, typename _ExtValueType>
+ ScFlatSegmentsImpl<_ValueType, _ExtValueType>::~ScFlatSegmentsImpl()
+ {
+ }
+@@ -345,6 +354,11 @@ ScFlatBoolRowSegments::ScFlatBoolRowSegments() :
+ {
+ }
+ 
++ScFlatBoolRowSegments::ScFlatBoolRowSegments(const ScFlatBoolRowSegments& r) :
++    mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
++{
++}
++
+ ScFlatBoolRowSegments::~ScFlatBoolRowSegments()
+ {
+ }
+@@ -391,6 +405,16 @@ SCROW ScFlatBoolRowSegments::findLastNotOf(bool bValue) const
+     return static_cast<SCROW>(mpImpl->findLastNotOf(bValue));
+ }
+ 
++void ScFlatBoolRowSegments::enableTreeSearch(bool bEnable)
++{
++    mpImpl->enableTreeSearch(bEnable);
++}
++
++void ScFlatBoolRowSegments::setInsertFromBack(bool bInsertFromBack)
++{
++    mpImpl->setInsertFromBack(bInsertFromBack);
++}
++
+ // ============================================================================
+ 
+ ScFlatBoolColSegments::ScFlatBoolColSegments() :
+@@ -398,6 +422,11 @@ ScFlatBoolColSegments::ScFlatBoolColSegments() :
+ {
+ }
+ 
++ScFlatBoolColSegments::ScFlatBoolColSegments(const ScFlatBoolColSegments& r) :
++    mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl))
++{
++}
++
+ ScFlatBoolColSegments::~ScFlatBoolColSegments()
+ {
+ }
+@@ -482,6 +511,11 @@ ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(sal_uInt16 nDefault) :
+ {
+ }
+ 
++ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments& r) :
++    mpImpl(new ScFlatUInt16SegmentsImpl(*r.mpImpl))
++{
++}
++
+ ScFlatUInt16RowSegments::~ScFlatUInt16RowSegments()
+ {
+ }
+diff --git sc/source/core/tool/makefile.mk sc/source/core/tool/makefile.mk
+index bd9f56c..24283c0 100644
+--- sc/source/core/tool/makefile.mk
++++ sc/source/core/tool/makefile.mk
+@@ -109,6 +109,7 @@ SLOFILES =  \
+         $(SLO)$/refupdat.obj \
+         $(SLO)$/scmatrix.obj \
+         $(SLO)$/sctictac.obj \
++        $(SLO)$/simplerangelist.obj \
+ 		$(SLO)$/stringutil.obj \
+         $(SLO)$/subtotal.obj \
+         $(SLO)$/token.obj \
+@@ -137,6 +138,7 @@ EXCEPTIONSFILES= \
+         $(SLO)$/prnsave.obj \
+ 		$(SLO)$/queryparam.obj \
+         $(SLO)$/reftokenhelper.obj \
++        $(SLO)$/simplerangelist.obj \
+ 		$(SLO)$/stringutil.obj \
+         $(SLO)$/token.obj
+ 
+diff --git sc/source/core/tool/simplerangelist.cxx sc/source/core/tool/simplerangelist.cxx
+new file mode 100644
+index 0000000..fcddbca
+--- /dev/null
++++ sc/source/core/tool/simplerangelist.cxx
+@@ -0,0 +1,243 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: rangelst.hxx,v $
++ * $Revision: 1.9.32.3 $
++ *
++ * This file is part of OpenOffice.org.
++ *
++ * OpenOffice.org is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU Lesser General Public License version 3
++ * only, as published by the Free Software Foundation.
++ *
++ * OpenOffice.org is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU Lesser General Public License version 3 for more details
++ * (a copy is included in the LICENSE file that accompanied this code).
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * version 3 along with OpenOffice.org.  If not, see
++ * <http://www.openoffice.org/license.html>
++ * for a copy of the LGPLv3 License.
++ *
++ ************************************************************************/
++
++// MARKER(update_precomp.py): autogen include statement, do not remove
++#include "precompiled_sc.hxx"
++
++
++//------------------------------------------------------------------------
++
++#include "simplerangelist.hxx"
++#include "rangelst.hxx"
++
++using ::std::list;
++using ::std::pair;
++using ::std::max;
++
++// ============================================================================
++
++ScSimpleRangeList::Range::Range(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) :
++    mnCol1(nCol1), mnRow1(nRow1), mnCol2(nCol2), mnRow2(nRow2) {}
++
++bool ScSimpleRangeList::Range::contains(const Range& r) const
++{
++    return mnCol1 <= r.mnCol1 && mnRow1 <= r.mnRow1 && r.mnCol2 <= mnCol2 && r.mnRow2 <= mnRow2;
++}
++
++// ----------------------------------------------------------------------------
++
++ScSimpleRangeList::ScSimpleRangeList()
++{
++}
++
++namespace {
++
++bool maybeJoin(ScSimpleRangeList::Range& rOld, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
++{
++    if (rOld.mnRow1 == nRow1 && rOld.mnRow2 == nRow2)
++    {
++        // Check their column spans to see if they overlap.
++        if (rOld.mnCol1 == nCol1)
++        {
++            // Their share the start column position.
++            rOld.mnCol2 = max(rOld.mnCol2, nCol2);
++            return true;
++        }
++        else if (rOld.mnCol1 < nCol1)
++        {
++            // Old range sits on the left.
++            if (nCol1 - rOld.mnCol2 <= 1)
++            {
++                rOld.mnCol2 = max(rOld.mnCol2, nCol2);
++                return true;
++            }
++        }
++        else if (nCol1 < rOld.mnCol1)
++        {
++            // New range sits on the left.
++            if (nCol1 - rOld.mnCol2 <= 1)
++            {
++                rOld.mnCol1 = nCol1;
++                rOld.mnCol2 = max(rOld.mnCol2, nCol2);
++                return true;
++            }
++        }
++    }
++
++    if (rOld.mnCol1 == nCol1 && rOld.mnCol2 == nCol2)
++    {
++        if (rOld.mnRow1 == nRow1)
++        {
++            // Their share the start row position.
++            rOld.mnRow2 = max(rOld.mnRow2, nRow2);
++            return true;
++        }
++        else if (rOld.mnRow1 < nRow1)
++        {
++            // Old range sits above.
++            if (nRow1 - rOld.mnRow2 <= 1)
++            {
++                rOld.mnRow2 = max(rOld.mnRow2, nRow2);
++                return true;
++            }
++        }
++        else if (nRow1 < rOld.mnRow1)
++        {
++            // New range sits above.
++            if (nRow1 - rOld.mnRow2 <= 1)
++            {
++                rOld.mnRow1 = nRow1;
++                rOld.mnRow2 = max(rOld.mnRow2, nRow2);
++                return true;
++            }
++        }
++    }
++
++    return false;
++}
++
++}
++
++void ScSimpleRangeList::addRange(const ScRange& rRange)
++{
++    SCCOL nCol1 = rRange.aStart.Col();
++    SCROW nRow1 = rRange.aStart.Row();
++    SCTAB nTab1 = rRange.aStart.Tab();
++    SCCOL nCol2 = rRange.aEnd.Col();
++    SCROW nRow2 = rRange.aEnd.Row();
++    SCTAB nTab2 = rRange.aEnd.Tab();
++
++    for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
++    {
++        RangeListRef pRef = findTab(nTab);
++        if (!pRef)
++            // This should never happen!
++            return;
++
++        if (pRef->empty() || !maybeJoin(pRef->back(), nCol1, nRow1, nCol2, nRow2))
++            // Not joinable.  Append it to the list.
++            pRef->push_back(Range(nCol1, nRow1, nCol2, nRow2));
++    }
++}
++
++void ScSimpleRangeList::insertCol(SCCOL nCol, SCTAB nTab)
++{
++    RangeListRef pRef = findTab(nTab);
++    if (!pRef)
++        // This should never happen!
++        return;
++
++    list<Range>::iterator itr = pRef->begin(), itrEnd = pRef->end();
++    for (; itr != itrEnd; ++itr)
++    {
++        Range& r = *itr;
++        if (r.mnCol2 < nCol)
++            // insertion point to the right of the range.
++            continue;
++
++        if (nCol <= r.mnCol1)
++        {   
++            // insertion point to the left of the range.
++            ++r.mnCol1;
++            ++r.mnCol2;
++        }
++        else if (nCol <= r.mnCol2)
++        {
++            // insertion point cuts through the range.
++            ++r.mnCol2;
++        }
++    }
++}
++
++void ScSimpleRangeList::insertRow(SCROW nRow, SCTAB nTab)
++{
++    RangeListRef pRef = findTab(nTab);
++    if (!pRef)
++        // This should never happen!
++        return;
++
++    list<Range>::iterator itr = pRef->begin(), itrEnd = pRef->end();
++    for (; itr != itrEnd; ++itr)
++    {
++        Range& r = *itr;
++        if (r.mnRow2 < nRow)
++            // insertion point is below the range.
++            continue;
++
++        if (nRow <= r.mnRow1)
++        {   
++            // insertion point is above the range.
++            ++r.mnRow1;
++            ++r.mnRow2;
++        }
++        else if (nRow <= r.mnRow2)
++        {
++            // insertion point cuts through the range.
++            ++r.mnRow2;
++        }
++    }
++}
++
++void ScSimpleRangeList::getRangeList(list<ScRange>& rList) const
++{
++    list<ScRange> aList;
++    for (TabType::const_iterator itrTab = maTabs.begin(), itrTabEnd = maTabs.end(); itrTab != itrTabEnd; ++itrTab)
++    {
++        SCTAB nTab = itrTab->first;
++        const RangeListRef& pRanges = itrTab->second;
++        list<Range>::const_iterator itr = pRanges->begin(), itrEnd = pRanges->end();
++        for (; itr != itrEnd; ++itr)
++        {
++            const Range& r = *itr;
++            aList.push_back(ScRange(r.mnCol1, r.mnRow1, nTab, r.mnCol2, r.mnRow2, nTab));
++        }
++    }
++    rList.swap(aList);
++}
++
++void ScSimpleRangeList::clear()
++{
++    maTabs.clear();
++}
++
++ScSimpleRangeList::RangeListRef ScSimpleRangeList::findTab(SCTAB nTab)
++{
++    TabType::iterator itr = maTabs.find(nTab);
++    if (itr == maTabs.end())
++    {
++        RangeListRef p(new list<Range>);
++        pair<TabType::iterator, bool> r = maTabs.insert(TabType::value_type(nTab, p));
++        if (!r.second)
++            return RangeListRef();
++        itr = r.first;
++    }
++
++    return itr->second;
++}
+diff --git sc/source/filter/xml/XMLStylesImportHelper.cxx sc/source/filter/xml/XMLStylesImportHelper.cxx
+index e1c608e..2805546 100644
+--- sc/source/filter/xml/XMLStylesImportHelper.cxx
++++ sc/source/filter/xml/XMLStylesImportHelper.cxx
+@@ -40,6 +40,7 @@
+ #include <com/sun/star/util/NumberFormat.hpp>
+ 
+ using namespace com::sun::star;
++using ::std::list;
+ 
+ void ScMyStyleNumberFormats::AddStyleNumberFormat(const rtl::OUString& rStyleName, const sal_Int32 nNumberFormat)
+ {
+@@ -56,37 +57,14 @@ sal_Int32 ScMyStyleNumberFormats::GetStyleNumberFormat(const rtl::OUString& rSty
+         return aItr->nNumberFormat;
+ }
+ 
+-ScMyStyleRanges::ScMyStyleRanges()
+-    :
+-    pTextList(NULL),
+-    pNumberList(NULL),
+-    pTimeList(NULL),
+-    pDateTimeList(NULL),
+-    pPercentList(NULL),
+-    pLogicalList(NULL),
+-    pUndefinedList(NULL),
++ScMyStyleRanges::ScMyStyleRanges() :
+     pCurrencyList(NULL)
+ {
+ }
+ 
+ ScMyStyleRanges::~ScMyStyleRanges()
+ {
+-    if (pTextList)
+-        delete pTextList;
+-    if (pNumberList)
+-        delete pNumberList;
+-    if (pTimeList)
+-        delete pTimeList;
+-    if (pDateTimeList)
+-        delete pDateTimeList;
+-    if (pPercentList)
+-        delete pPercentList;
+-    if (pLogicalList)
+-        delete pLogicalList;
+-    if (pUndefinedList)
+-        delete pUndefinedList;
+-    if (pCurrencyList)
+-        delete pCurrencyList;
++    delete pCurrencyList;
+ }
+ 
+ void ScMyStyleRanges::AddRange(const ScRange& rRange, ScRangeList* pList,
+@@ -138,58 +116,58 @@ void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange, ScRangeListRef xLi
+ }
+ 
+ void ScMyStyleRanges::AddRange(const ScRange& rRange,
+-    const rtl::OUString* pStyleName, const sal_Int16 nType,
+-    ScXMLImport& rImport, const sal_uInt32 nMaxRanges)
++    const rtl::OUString* /*pStyleName*/, const sal_Int16 nType,
++    ScXMLImport& /*rImport*/, const sal_uInt32 /*nMaxRanges*/)
+ {
+     switch (nType)
+     {
+         case util::NumberFormat::NUMBER:
+         {
+-            if (!pNumberList)
+-                pNumberList = new ScRangeList();
+-            AddRange(rRange, pNumberList, pStyleName, nType, rImport, nMaxRanges);
++            if (!mpNumberList)
++                mpNumberList.reset(new ScSimpleRangeList);
++            mpNumberList->addRange(rRange);
+         }
+         break;
+         case util::NumberFormat::TEXT:
+         {
+-            if (!pTextList)
+-                pTextList = new ScRangeList();
+-            AddRange(rRange, pTextList, pStyleName, nType, rImport, nMaxRanges);
++            if (!mpTextList)
++                mpTextList.reset(new ScSimpleRangeList);
++            mpTextList->addRange(rRange);
+         }
+         break;
+         case util::NumberFormat::TIME:
+         {
+-            if (!pTimeList)
+-                pTimeList = new ScRangeList();
+-            AddRange(rRange, pTimeList, pStyleName, nType, rImport, nMaxRanges);
++            if (!mpTimeList)
++                mpTimeList.reset(new ScSimpleRangeList);
++            mpTimeList->addRange(rRange);
+         }
+         break;
+         case util::NumberFormat::DATETIME:
+         {
+-            if (!pDateTimeList)
+-                pDateTimeList = new ScRangeList();
+-            AddRange(rRange, pDateTimeList, pStyleName, nType, rImport, nMaxRanges);
++            if (!mpDateTimeList)
++                mpDateTimeList.reset(new ScSimpleRangeList);
++            mpDateTimeList->addRange(rRange);
+         }
+         break;
+         case util::NumberFormat::PERCENT:
+         {
+-            if (!pPercentList)
+-                pPercentList = new ScRangeList();
+-            AddRange(rRange, pPercentList, pStyleName, nType, rImport, nMaxRanges);
++            if (!mpPercentList)
++                mpPercentList.reset(new ScSimpleRangeList);
++            mpPercentList->addRange(rRange);
+         }
+         break;
+         case util::NumberFormat::LOGICAL:
+         {
+-            if (!pLogicalList)
+-                pLogicalList = new ScRangeList();
+-            AddRange(rRange, pLogicalList, pStyleName, nType, rImport, nMaxRanges);
++            if (!mpLogicalList)
++                mpLogicalList.reset(new ScSimpleRangeList);
++            mpLogicalList->addRange(rRange);
+         }
+         break;
+         case util::NumberFormat::UNDEFINED:
+         {
+-            if (!pUndefinedList)
+-                pUndefinedList = new ScRangeList();
+-            AddRange(rRange, pUndefinedList, pStyleName, nType, rImport, nMaxRanges);
++            if (!mpUndefinedList)
++                mpUndefinedList.reset(new ScSimpleRangeList);
++            mpUndefinedList->addRange(rRange);
+         }
+         break;
+         default:
+@@ -216,53 +194,78 @@ void ScMyStyleRanges::AddCurrencyRange(const ScRange& rRange,
+         if (aPair.second)
+         {
+             aItr = aPair.first;
+-            AddCurrencyRange(rRange, aItr->xRanges, pStyleName, pCurrency, rImport, nMaxRanges);
++            aItr->mpRanges->addRange(rRange);
+         }
+     }
+     else
+-        aItr->xRanges->Join(rRange);
++        aItr->mpRanges->addRange(rRange);
+ }
+ 
+-void ScMyStyleRanges::InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy,
+-        const SCsTAB nDz, ScDocument* pDoc)
++void ScMyStyleRanges::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc)
+ {
+-    UpdateRefMode aRefMode(URM_INSDEL);
+-    if (pNumberList)
+-        pNumberList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+-    if (pTextList)
+-        pTextList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+-    if (pTimeList)
+-        pTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+-    if (pDateTimeList)
+-        pDateTimeList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+-    if (pPercentList)
+-        pPercentList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+-    if (pLogicalList)
+-        pLogicalList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
+-    if (pUndefinedList)
+-        pUndefinedList->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
++    if (mpTextList)
++        mpTextList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
++    if (mpNumberList)
++        mpNumberList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
++    if (mpTimeList)
++        mpTimeList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
++    if (mpDateTimeList)
++        mpDateTimeList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
++    if (mpPercentList)
++        mpPercentList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
++    if (mpLogicalList)
++        mpLogicalList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
++    if (mpUndefinedList)
++        mpUndefinedList->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
++
+     if (pCurrencyList)
+     {
+         ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+         ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+         while (aItr != aEndItr)
+         {
+-            aItr->xRanges->UpdateReference(aRefMode, pDoc, rRange, nDx, nDy, nDz);
++            aItr->mpRanges->insertRow(static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab));
+             ++aItr;
+         }
+     }
+ }
+ 
+-void ScMyStyleRanges::InsertRow(const sal_Int32 nRow, const sal_Int32 nTab, ScDocument* pDoc)
++void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc)
+ {
+-    InsertColRow(ScRange(0, static_cast<SCROW>(nRow), static_cast<SCTAB>(nTab),
+-        MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 0, 1, 0, pDoc);
++    if (mpTextList)
++        mpTextList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++    if (mpNumberList)
++        mpNumberList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++    if (mpTimeList)
++        mpTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++    if (mpDateTimeList)
++        mpDateTimeList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++    if (mpPercentList)
++        mpPercentList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++    if (mpLogicalList)
++        mpLogicalList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++    if (mpUndefinedList)
++        mpUndefinedList->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++
++    if (pCurrencyList)
++    {
++        ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
++        ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
++        while (aItr != aEndItr)
++        {
++            aItr->mpRanges->insertCol(static_cast<SCCOL>(nCol), static_cast<SCTAB>(nTab));
++            ++aItr;
++        }
++    }
+ }
+ 
+-void ScMyStyleRanges::InsertCol(const sal_Int32 nCol, const sal_Int32 nTab, ScDocument* pDoc)
++void ScMyStyleRanges::SetStylesToRanges(const list<ScRange>& rRanges,
++    const rtl::OUString* pStyleName, const sal_Int16 nCellType,
++    const rtl::OUString* pCurrency, ScXMLImport& rImport)
+ {
+-    InsertColRow(ScRange(static_cast<SCCOL>(nCol), 0, static_cast<SCTAB>(nTab),
+-        MAXCOL, MAXROW, static_cast<SCTAB>(nTab)), 1, 0, 0, pDoc);
++    list<ScRange>::const_iterator itr = rRanges.begin(), itrEnd = rRanges.end();
++    for (; itr != itrEnd; ++itr)
++        rImport.SetStyleToRange(*itr, pStyleName, nCellType, pCurrency);
+ }
+ 
+ void ScMyStyleRanges::SetStylesToRanges(ScRangeList* pList,
+@@ -285,27 +288,64 @@ void ScMyStyleRanges::SetStylesToRanges(ScRangeListRef xList,
+ 
+ void ScMyStyleRanges::SetStylesToRanges(const rtl::OUString* pStyleName, ScXMLImport& rImport)
+ {
+-    if (pNumberList)
+-        SetStylesToRanges(pNumberList, pStyleName, util::NumberFormat::NUMBER, NULL, rImport);
+-    if (pTextList)
+-        SetStylesToRanges(pTextList, pStyleName, util::NumberFormat::TEXT, NULL, rImport);
+-    if (pTimeList)
+-        SetStylesToRanges(pTimeList, pStyleName, util::NumberFormat::TIME, NULL, rImport);
+-    if (pDateTimeList)
+-        SetStylesToRanges(pDateTimeList, pStyleName, util::NumberFormat::DATETIME, NULL, rImport);
+-    if (pPercentList)
+-        SetStylesToRanges(pPercentList, pStyleName, util::NumberFormat::PERCENT, NULL, rImport);
+-    if (pLogicalList)
+-        SetStylesToRanges(pLogicalList, pStyleName, util::NumberFormat::LOGICAL, NULL, rImport);
+-    if (pUndefinedList)
+-        SetStylesToRanges(pUndefinedList, pStyleName, util::NumberFormat::UNDEFINED, NULL, rImport);
++    if (mpNumberList)
++    {
++        list<ScRange> aList;
++        mpNumberList->getRangeList(aList);
++        SetStylesToRanges(aList, pStyleName, util::NumberFormat::NUMBER, NULL, rImport);
++        mpNumberList->clear();
++    }
++    if (mpTextList)
++    {
++        list<ScRange> aList;
++        mpTextList->getRangeList(aList);
++        SetStylesToRanges(aList, pStyleName, util::NumberFormat::TEXT, NULL, rImport);
++        mpTextList->clear();
++    }
++    if (mpTimeList)
++    {
++        list<ScRange> aList;
++        mpTimeList->getRangeList(aList);
++        SetStylesToRanges(aList, pStyleName, util::NumberFormat::TIME, NULL, rImport);
++        mpTimeList->clear();
++    }
++    if (mpDateTimeList)
++    {
++        list<ScRange> aList;
++        mpDateTimeList->getRangeList(aList);
++        SetStylesToRanges(aList, pStyleName, util::NumberFormat::DATETIME, NULL, rImport);
++        mpDateTimeList->clear();
++    }
++    if (mpPercentList)
++    {
++        list<ScRange> aList;
++        mpPercentList->getRangeList(aList);
++        SetStylesToRanges(aList, pStyleName, util::NumberFormat::PERCENT, NULL, rImport);
++        mpPercentList->clear();
++    }
++    if (mpLogicalList)
++    {
++        list<ScRange> aList;
++        mpLogicalList->getRangeList(aList);
++        SetStylesToRanges(aList, pStyleName, util::NumberFormat::LOGICAL, NULL, rImport);
++        mpLogicalList->clear();
++    }
++    if (mpUndefinedList)
++    {
++        list<ScRange> aList;
++        mpUndefinedList->getRangeList(aList);
++        SetStylesToRanges(aList, pStyleName, util::NumberFormat::UNDEFINED, NULL, rImport);
++        mpUndefinedList->clear();
++    }
+     if (pCurrencyList)
+     {
+         ScMyCurrencyStylesSet::iterator aItr(pCurrencyList->begin());
+         ScMyCurrencyStylesSet::iterator aEndItr(pCurrencyList->end());
+         while (aItr != aEndItr)
+         {
+-            SetStylesToRanges(aItr->xRanges, pStyleName, util::NumberFormat::CURRENCY, &aItr->sCurrency, rImport);
++            list<ScRange> aList;
++            aItr->mpRanges->getRangeList(aList);
++            SetStylesToRanges(aList, pStyleName, util::NumberFormat::CURRENCY, &aItr->sCurrency, rImport);
+             ++aItr;
+         }
+     }
+diff --git sc/source/filter/xml/XMLStylesImportHelper.hxx sc/source/filter/xml/XMLStylesImportHelper.hxx
+index ca5a62a..0e2b760 100644
+--- sc/source/filter/xml/XMLStylesImportHelper.hxx
++++ sc/source/filter/xml/XMLStylesImportHelper.hxx
+@@ -32,12 +32,15 @@
+ #define SC_XMLSTYLESIMPORTHELPER_HXX
+ 
+ #include "rangelst.hxx"
++#include "simplerangelist.hxx"
+ #include <rtl/ustring.hxx>
+ #include <com/sun/star/table/CellRangeAddress.hpp>
+ #include <com/sun/star/table/CellAddress.hpp>
+ 
+ #include <set>
+ #include <vector>
++#include <list>
++#include <boost/shared_ptr.hpp>
+ 
+ class ScXMLImport;
+ 
+@@ -75,9 +78,11 @@ public:
+ struct ScMyCurrencyStyle
+ {
+     rtl::OUString		sCurrency;
+-    ScRangeListRef		xRanges;
++    ::boost::shared_ptr<ScSimpleRangeList> mpRanges;
+ 
+-    ScMyCurrencyStyle() : xRanges(new ScRangeList()) {}
++    ScMyCurrencyStyle() : 
++        mpRanges(new ScSimpleRangeList)
++    {}
+     ~ScMyCurrencyStyle() {}
+ };
+ 
+@@ -93,13 +98,13 @@ typedef std::set<ScMyCurrencyStyle, LessCurrencyStyle>	ScMyCurrencyStylesSet;
+ 
+ class ScMyStyleRanges : public SvRefBase
+ {
+-    ScRangeList*			pTextList;
+-    ScRangeList*			pNumberList;
+-    ScRangeList*			pTimeList;
+-    ScRangeList*			pDateTimeList;
+-    ScRangeList*			pPercentList;
+-    ScRangeList*			pLogicalList;
+-    ScRangeList*			pUndefinedList;
++    ::boost::shared_ptr<ScSimpleRangeList> mpTextList;
++    ::boost::shared_ptr<ScSimpleRangeList> mpNumberList;
++    ::boost::shared_ptr<ScSimpleRangeList> mpTimeList;
++    ::boost::shared_ptr<ScSimpleRangeList> mpDateTimeList;
++    ::boost::shared_ptr<ScSimpleRangeList> mpPercentList;
++    ::boost::shared_ptr<ScSimpleRangeList> mpLogicalList;
++    ::boost::shared_ptr<ScSimpleRangeList> mpUndefinedList;
+     ScMyCurrencyStylesSet*	pCurrencyList;
+ 
+     void AddRange(const ScRange& rRange, ScRangeList* pList,
+@@ -108,8 +113,9 @@ class ScMyStyleRanges : public SvRefBase
+     void AddCurrencyRange(const ScRange& rRange, ScRangeListRef xList,
+         const rtl::OUString* pStyleName, const rtl::OUString* pCurrency,
+         ScXMLImport& rImport, const sal_uInt32 nMaxRanges);
+-    void InsertColRow(const ScRange& rRange, const SCsCOL nDx, const SCsROW nDy,
+-        const SCsTAB nDz, ScDocument* pDoc);
++    void SetStylesToRanges(const ::std::list<ScRange>& rList,
++        const rtl::OUString* pStyleName, const sal_Int16 nCellType,
++        const rtl::OUString* pCurrency, ScXMLImport& rImport);
+     void SetStylesToRanges(ScRangeList* pList,
+         const rtl::OUString* pStyleName, const sal_Int16 nCellType,
+         const rtl::OUString* pCurrency, ScXMLImport& rImport);


More information about the ooo-build-commit mailing list